Upgrade to cel-rust 0.14, extended stdlib, and prepare 0.7.0#37
Conversation
50bb9cc to
0621a26
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 50bb9ccd31
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if offset < 0 or offset > len(s): | ||
| raise IndexError(f"indexOf: offset {offset} out of range for string of length {len(s)}") |
There was a problem hiding this comment.
Return -1 for overlarge search offsets
When the strings extension is enabled, calls like 'hello mellow'.indexOf('ello', 20) should behave like cel-go and return -1 because the search starts past the end and finds no match; this check instead raises, and lastIndexOf has the same positive-offset problem. That turns valid CEL expressions with a too-large user-supplied offset into runtime errors rather than a no-match result.
Useful? React with 👍 / 👎.
|
|
||
| def math_abs(x: Any) -> Any: | ||
| """Return the absolute value of ``x``, preserving int/double.""" | ||
| return abs(x) |
There was a problem hiding this comment.
For math.abs(-9223372036854775808), cel-go defines an overflow error because the absolute value cannot be represented as a signed CEL int, but Python's abs() returns 9223372036854775808; the bridge will then convert that to a CEL uint and the expression succeeds with the wrong type/value instead of failing.
Useful? React with 👍 / 👎.
| return 1.0 | ||
| if x < 0: | ||
| return -1.0 | ||
| return 0.0 |
There was a problem hiding this comment.
For a double NaN input, both comparisons are false, so math.sign(0.0 / 0.0) falls through to 0.0. The cel-go math extension specifies that math.sign(NaN) returns NaN, so expressions that use math.isNaN(math.sign(x)) to propagate invalid numeric data will silently see zero instead.
Useful? React with 👍 / 👎.
Upgrade the underlying cel crate from 0.13 to 0.14, add an opt-in extended standard library, expose expression static analysis, and bump to 0.7.0. A 1.0 release is deferred until the upstream cel crate supports the CEL protobuf AST (cel.expr.Expr / CheckedExpr) so cross-implementation portability can be offered. cel 0.14 upgrade (src/lib.rs): - Share the standard-library Env across evaluations (LazyLock<Arc<Env>> + Context::with_env) instead of rebuilding it on every call. - Map the 0.14 ExecutionError variants to idiomatic Python exceptions with canonical CEL type names, and stop leaking Debug wrappers into messages. - Use the infallible add_variable_from_value. Custom functions callable as methods (src/lib.rs): - Bridge via FunctionContext and prepend the method receiver, so a registered function works as both f(x, y) and x.f(y). Extended standard library (python/cel/stdlib.py): - Opt-in libraries mirroring cel-go: core (bool/dyn/type/min/max), strings, math, sets, encoders (base64) and lists. Enable with add_stdlib_to_context; the CLI enables them automatically. Expression static analysis (src/lib.rs): - Program.variables(), .functions(), .references() and the .source property. Behaviour changes (cel 0.14): contains is string-only (use `in` for list/map membership), min/max moved to the core stdlib extension, and built-in functions take precedence over same-named user functions. Cross-implementation portability is documented as out of scope for now: CEL has no bytecode, ecosystem interchange uses the protobuf AST, and upstream cel-rust cannot yet produce/consume it. Tests: 463 passing (was 380); adds test_stdlib_extensions.py, test_introspection.py and test_cel_014_behaviour.py.
0621a26 to
fbe42fd
Compare
Update PyO3 0.27 -> 0.29, which resolves two upstream advisories affecting earlier versions (out-of-bounds read in PyList/PyTuple nth/nth_back iterators; missing Sync bound on PyCFunction::new_closure). Switch pyo3-log from a git fork pinned to a 0.27 branch to the released 0.13.4 crate, removing the git dependency. Refresh transitive deps (chrono 0.4.45, log 0.4.33, regex 1.12.4, serde_json 1.0.150, arc-swap 1.9.2).
Summary
Prepares a 0.7.0 release: upgrades to cel-rust 0.14, ships an
opt-in extended standard library that mirrors cel-go, and exposes
expression static analysis. Fully backward compatible for the common API
(
evaluate,compile,Context) apart from the documented cel 0.14 behaviourchanges.
What changed
Upgrade to cel-rust 0.14 (
src/lib.rs)cel0.13 → 0.14.Envbuilt once (LazyLock<Arc<Env>>+Context::with_env) instead of rebuilt on every call — a small perf win for repeatedevaluate()/Program.execute().ExecutionErrorvariants: canonical CEL type names in messages (Unsupported operation: string + int) and more variants mapped to idiomatic Python exceptions (UnsupportedIndex,ValuesNotComparable,UnexpectedType,InvalidArgumentCount→TypeError).add_variable_from_value(infallible) replaces the fallibleadd_variablecall.Custom functions callable as methods (
src/lib.rs)The custom-function bridge now reads the
FunctionContextdirectly and prepends the method receiver, so a registered function works as bothf(x, y)andx.f(y). This is what lets the standard-library extensions be written as members ("s".charAt(i),[1,2].contains(x)).Extended standard library (
python/cel/stdlib.py)New opt-in libraries mirroring cel-go:
core(bool/dyn/type/min/max),strings,math,sets,encoders(base64),lists. Enable withadd_stdlib_to_context(ctx)orextensions=[...]; the CLI enables them automatically.Expression static analysis (
src/lib.rs)Program.variables(),.functions(),.references()and the.sourceproperty report what an expression uses without evaluating it.Behaviour changes (cel 0.14)
containsis string-only; useinfor list/map membership (or thelistsextension).min/maxmoved out of core into thecorestdlib extension.Portability / "bytecode"
Out of scope and documented as such: CEL has no bytecode; ecosystem interchange uses the protobuf AST (
cel.expr.Expr/CheckedExpr), which upstream cel-rust cannot yet produce/consume (no protobuf, no type checker). The portable artifact is the CEL source string; useProgram.references()for analysis.Tests
455 passing (was 380). New:
test_stdlib_extensions.py,test_introspection.py,test_cel_014_behaviour.py.cargo fmt/clippy -D warningsclean;ruff/mypyclean; doc code blocks execute.