Skip to content

Upgrade to cel-rust 0.14, extended stdlib, and prepare 0.7.0#37

Merged
hardbyte merged 2 commits into
mainfrom
feat/cel-0.14-major-release
Jul 4, 2026
Merged

Upgrade to cel-rust 0.14, extended stdlib, and prepare 0.7.0#37
hardbyte merged 2 commits into
mainfrom
feat/cel-0.14-major-release

Conversation

@hardbyte

@hardbyte hardbyte commented Jul 4, 2026

Copy link
Copy Markdown
Owner

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 behaviour
changes.

Draft for maintainer review before release. A 1.0 release is deferred until the upstream cel crate supports the protobuf AST (cel.expr.Expr / CheckedExpr), enabling cross-implementation portability.

What changed

Upgrade to cel-rust 0.14 (src/lib.rs)

  • Bumped cel 0.13 → 0.14.
  • Shared standard-library Env built once (LazyLock<Arc<Env>> + Context::with_env) instead of rebuilt on every call — a small perf win for repeated evaluate()/Program.execute().
  • Reworked error mapping for the 0.14 ExecutionError variants: canonical CEL type names in messages (Unsupported operation: string + int) and more variants mapped to idiomatic Python exceptions (UnsupportedIndex, ValuesNotComparable, UnexpectedType, InvalidArgumentCountTypeError).
  • add_variable_from_value (infallible) replaces the fallible add_variable call.

Custom functions callable as methods (src/lib.rs)

The custom-function bridge now reads the FunctionContext directly and prepends the method receiver, so a registered function works as both f(x, y) and x.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 with add_stdlib_to_context(ctx) or extensions=[...]; the CLI enables them automatically.

Expression static analysis (src/lib.rs)

Program.variables(), .functions(), .references() and the .source property report what an expression uses without evaluating it.

Behaviour changes (cel 0.14)

  • contains is string-only; use in for list/map membership (or the lists extension).
  • min/max moved out of core into the core stdlib extension.
  • Built-in functions take precedence over same-named user functions.

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; use Program.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 warnings clean; ruff/mypy clean; doc code blocks execute.

@hardbyte hardbyte force-pushed the feat/cel-0.14-major-release branch from 50bb9cc to 0621a26 Compare July 4, 2026 03:05

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread python/cel/stdlib.py
Comment on lines +180 to +181
if offset < 0 or offset > len(s):
raise IndexError(f"indexOf: offset {offset} out of range for string of length {len(s)}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment thread python/cel/stdlib.py

def math_abs(x: Any) -> Any:
"""Return the absolute value of ``x``, preserving int/double."""
return abs(x)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Raise on int64-min math.abs

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 👍 / 👎.

Comment thread python/cel/stdlib.py
return 1.0
if x < 0:
return -1.0
return 0.0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve NaN in math.sign

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.
@hardbyte hardbyte force-pushed the feat/cel-0.14-major-release branch from 0621a26 to fbe42fd Compare July 4, 2026 03:11
@hardbyte hardbyte changed the title Upgrade to cel-rust 0.14, extended stdlib, and prepare 1.0.0 Upgrade to cel-rust 0.14, extended stdlib, and prepare 0.7.0 Jul 4, 2026
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).
@hardbyte hardbyte merged commit bc21129 into main Jul 4, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant