All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Updated cel-rust from 0.12.0 to 0.13.0.
Context.set_variable_resolver(callback)exposes cel 0.13'sVariableResolvertrait to Python. The callback receives a variable name and returns the value (orNoneto fall through to variables registered withadd_variable). Useful for backing a CEL context with on-demand sources (database lookups, lazily-loaded config files, etc.) without materializing the full set of variables upfront. Exceptions raised by the resolver are logged and treated as "not handled".- Idiomatic Python exception mapping for several CEL runtime errors that previously fell through to
ValueError:- Arithmetic overflow →
OverflowError(e.g.9223372036854775807 + 1, including the new overflow-safe int math in cel 0.13). - Division by zero / modulo by zero →
ZeroDivisionError. - List index out of bounds →
IndexError. - Missing map key (e.g.
{"a": 1}.b) →KeyError.
- Arithmetic overflow →
- Behaviour change (cel 0.13): bytes concatenation with
+now works per the CEL spec (b'hello' + b'world'returnsb'helloworld'). Previously raisedTypeError. - Behaviour change (cel 0.13): logical
&&and||are now "err-resilient" per CEL spec —X && falseshort-circuits tofalseandX || trueshort-circuits totrueeven whenXis not a boolean. Conversely,false || Xandtrue && Xnow raiseTypeErrorwhenXis not boolean (previouslyfalse || XreturnedX). - Error mapping: more operations now route through CEL's
NoSuchOverload(e.g.1 + 2u,1 * 2u, indexing into a string). These map toTypeErrorwith a generic message listing common causes and conversion functions (int(x),uint(x),double(x)). The previous type-specific messages (e.g. "Cannot mix signed and unsigned integers") are still produced for the operand orderings cel-rust dispatches viaUnsupportedBinaryOperator. Tests asserting on specific message text may need updating. - Behaviour change (cel 0.13): no implicit type coercion on map index access; indexing into a string now raises
TypeError(NoSuchOverload) per CEL spec. - Behaviour change (cel 0.13): integer arithmetic overflow now raises
OverflowErrorinstead of silently wrapping. Affects+,-,*on bothintanduintat the type's bounds.
-
Microbenchmarks comparing cel 0.13 vs 0.12 (release build, taking the min of 3 runs per scenario):
Scenario compile compiled execute evaluate x + y * 2+2.8% +8.4% +3.3% greet + ' ' + name+23.0% +4.3% +0.5% size(items)(1k)~0% +63.4% +53.2% map field access −7.1% +8.3% +6.5% custom Python fn +1.4% +6.7% −1.9% Most scenarios are within ~10% of 0.12; the
size(items)regression on a 1000-element list is cel 0.13's dyn-Val refactor adding per-element boxing overhead at the Python→CEL boundary. Smaller lists are not noticeably affected.
- Mapping conversion now respects dict subclasses and custom
Mappingimplementations, preserving__getitem__behavior for member access (issue #22)
compile()API andProgram.execute()for reuse and performanceOptionalValuewrapper to expose CEL optional values in Python- Compile vs execute benchmark script (
examples/performance/compile_execute_benchmark.py)
- Updated cel-rust from 0.11.6 to 0.12.0
- Documentation: pre-compilation guidance and OptionalValue examples
- Updated cel-rust from 0.11.4 to 0.11.6
- Updated PyO3 from 0.25.1 to 0.27.1
- Reduced logging verbosity
- Added new
cel.stdlibmodule with Python implementations of CEL functions missing from upstream cel-rust. - CLI automatically includes all stdlib functions
- Minor removed warning level logging in cel crate
- Python evaluation mode removed: The library now operates exclusively in strict CEL mode
- Removed:
EvaluationMode.PYTHONand all automatic integer-to-float promotion - Removed:
modeparameter fromevaluate()function - Removed:
--modeCLI option - Behavior change: Mixed arithmetic like
1 + 2.5now raisesTypeErrorinstead of automatically promoting to3.5 - Migration: Use explicit type conversion (e.g.,
double(1) + 2.5) for mixed arithmetic - Rationale: Eliminates complex AST preprocessing that was breaking
has()short-circuiting and other CEL functions
- Removed:
- CEL function short-circuiting: Fixed issue where
has()and other CEL functions failed due to AST preprocessing interference - String literal corruption: Eliminated string literal modification that occurred during integer promotion preprocessing
- Updated cel crate from v0.11.0 to v0.11.1
- Updated documentation to reflect strict CEL mode operation
- Updated tests to work with strict CEL mode only
- Removed complex preprocessing logic
- EvaluationMode enum: Control type handling behavior in CEL expressions (deprecated and removed in later version)
EvaluationMode.PYTHON(default for Python API): Python-friendly type promotions (removed)EvaluationMode.STRICT(default for CLI): Strict CEL type rules with no coercion (now the only mode)
- Type checking support: Added complete type stub files (
.pyi) for PyO3 extension
- Upgraded
celcrate (formerlycel-interpreter) 0.10.0 → 0.11.0:- Function registration now uses
IntoFunctiontrait. - Python integration updated to use
Argumentsextractor for variadic args. - Imports renamed from
cel_interpreter::tocel::. - No changes to Python API – all existing code continues to work.
- Function registration now uses
- Internal: Refactored Python integration to match new CEL API.
- Updated dependencies:
- pyo3: 0.25.0 → 0.25.1
- pyo3-log: 0.12.1 → 0.12.4
- Prepared for upcoming CEL Rust features:
- Enhanced type system & introspection
type()function support- Optional value handling
- Automatic type coercion for mixed int/float arithmetic (deprecated and removed in later version):
- Float literals automatically promote integer literals to floats.
- Context variables containing floats trigger int → float promotion.
- Preserves array indexing with integers (e.g.,
list[2]stays integer).
- Enhanced error handling:
- Parser panics now caught with
std::panic::catch_unwind. - Invalid expressions return a
ValueErrorinstead of crashing Python.
- Parser panics now caught with
- Mixed-type arithmetic now works in expressions like:
3.14 * 22 + 3.14value * 2(wherevalueis float)
- Parser panics from
cel-interpreterhandled gracefully with proper error messages. - Updated to latest PyO3 APIs to remove deprecation warnings.
- Bytes concatenation (
b'hello' + b'world') unsupported in cel-interpreter 0.10.0.- Spec requires: should work.
- Current: returns
"Unsupported binary operator 'add'". - Workaround:
bytes(string(part1) + string(part2)). - Status: Missing feature in cel-interpreter, not in our wrapper.
- cel-interpreter: 0.9.0 → 0.10.0 (breaking changes internally)
- log: 0.4.22 → 0.4.27
- chrono: 0.4.38 → 0.4.41
- pyo3: 0.22.6 → 0.25.0 (major API upgrade to
IntoPyObject) - pyo3-log: 0.11.0 → 0.12.1 (compatible with PyO3 0.25.0)
- PyO3 migration: moved from deprecated
IntoPyto newIntoPyObjectAPI. - New conversion system improves error handling and type safety.
- All 120 tests pass on current dependency set.