Expose the parsed expression tree from Program (for explain/trace tooling, linting and sub-expression evaluation)
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 45/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Active
- Domain
- developer-experience, tooling
Research direction
Start by inspecting the Python Program wrapper and cel::Program::expression(), then compare its IdedExpr and Expr variants with the proposed JSON-serialisable tree. Done means Program.ast() exposes literals, identifiers, selects, calls, lists, maps, structs and expanded comprehensions, with provisional documentation tied to the cel-rust version.
Written by the indexing model from the issue text.
Description
Motivation
Program.references() answers "which names does this expression use", but several things people ask for need the structure of the expression, not just its leaves:
- #30 wants to know which element or clause made an
exists/&&chain true or false. cel-rust has no evaluation hooks, so a wrapper-sideexplain()would have to walk the tree and re-evaluate sub-expressions. - Policy linting beyond name lists: "no
matches()on untrusted input", "no more than N nested comprehensions", "field access only underrequest.". - Pretty-printing / normalising expressions stored by users.
What upstream gives us
cel::Program::expression() returns the parsed Expression (IdedExpr: an id plus an Expr enum covering literals, identifiers, selects, calls, lists, maps, structs and the expanded comprehensions). No protobuf AST, but the shape is close to cel.expr.Expr and would be straightforward to mirror as nested dicts or small dataclasses.
Proposal
Program.ast() returning a plain, JSON-serialisable tree, e.g. {"kind": "call", "function": "_&&_", "args": [...]}, with comprehension macros shown in their expanded form (that is what cel-rust holds after parsing; the original macro call is not retained). Ship it as provisional, tied to the cel-rust version, and note that the node shapes may change when cel-rust changes its AST.
A Python-side cel.explain(program, context) built on it could then evaluate each boolean sub-expression and report the first failing clause, which covers the exists/all case in #30 without upstream changes, at the cost of re-evaluation (custom functions run again).
- Dominant language
- Python
- Stars
- 43
- Forks
- 4
- Avg merge
- 9h 57m
- Merged PRs (30d)
- 14
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from hardbyte/python-common-expression-language
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
enhancement
Difficulty 4/5 3-5 days Newbie friendliness 45/100
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
-
enhancement
Difficulty 4/5 3-5 days Newbie friendliness 48/100
-
enhancement
Difficulty 4/5 3-5 days Newbie friendliness 48/100
All issues in hardbyte/python-common-expression-language
Similar issues
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
canonical/paas-charm#368 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
tech debt
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
StevenBlack/hosts#3256 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
qualcomm/qai-appbuilder#275 ·