Releases: hardbyte/python-common-expression-language
Release list
v0.7.0
Python CEL 0.7.0 gives you a much bigger built-in toolbox, lets you call your own functions as methods, and can tell you what an expression uses before you run it β on top of a refreshed, more secure Rust core.
β¨ What's new
An extended standard library β dozens of functions matching Google's cel-go, opt-in via cel.stdlib:
import cel
from cel.stdlib import add_stdlib_to_context
ctx = cel.Context()
add_stdlib_to_context(ctx)
cel.evaluate('"Hello World".lowerAscii()', ctx) # 'hello world'
cel.evaluate("math.greatest([3, 1, 2])", ctx) # 3
cel.evaluate("[1, 1, 2, 3].distinct()", ctx) # [1, 2, 3]
cel.evaluate('base64.encode(b"hi")', ctx) # 'aGk='Covers strings, math, sets, encoders and lists helpers (plus bool/dyn/type/min/max). The cel command-line tool enables them automatically.
Call custom functions as methods β a function you register works as both f(x) and x.f(y):
ctx = cel.Context()
ctx.add_function("shout", lambda s: s.upper() + "!")
cel.evaluate('"hi".shout()', ctx) # 'HI!'Inspect an expression before running it β see which variables and functions it references:
program = cel.compile("user.age >= min_age && size(roles) > 0")
program.variables() # ['min_age', 'roles', 'user']
program.functions() # ['_&&_', '_>=_', '_>_', 'size']Handy for validating that your context supplies everything an expression needs, or restricting which names an expression may touch.
β‘ Under the hood
- Upgraded to cel-rust 0.14 β faster and more spec-compliant.
- Upgraded to PyO3 0.29, which pulls in upstream security fixes.
- Clearer, more Pythonic error messages (e.g.
TypeError: Unsupported operation: string + int).
β οΈ Heads up β behaviour changes
These come from cel 0.14 and may affect existing expressions:
containsis now string-only. Use theinoperator for membership β2 in [1, 2, 3],"key" in myMapβ or enable thelistsextension to get.contains()back for lists and maps.min/maxmoved into the opt-incel.stdlibcoreextension (they used to be always available).- Built-in functions take precedence over a custom function registered with the same name.
π¦ Install / upgrade
pip install --upgrade common-expression-languageSee the CHANGELOG for the complete list of changes, and the docs for the new standard-library and introspection reference.
v0.5.6
v0.5.5
Highlights
- Upgrade to celβrust 0.12.0 (bytes feature enabled)
- New compile() API + Program.execute() for fast repeated evaluation
- New OptionalValue wrapper to represent CEL optional values in Python (preserves optional.none() vs optional.of(null))
Added
- Compile/execute performance benchmark: examples/performance/compile_execute_benchmark.py
- OptionalValue docs and examples
Notes
- Optional values now surface as cel.OptionalValue instead of debug strings.
- Performance guidance updated with compile/execute examples.
New Contributors
Full Changelog: v0.5.3...v0.5.5
v0.5.3: Add substring() function to stdlib and improve logging (#21)
- Added stdlib in Python to add functions before they land upstream. Added
substring - removed warning level logging in cel crate
v0.5.1
β¨ Added
- EvaluationMode enum: Control type handling behavior in CEL expressions
EvaluationMode.PYTHON(default for Python API): Python-friendly type promotionsEvaluationMode.STRICT(default for CLI): Strict CEL type rules with no coercion
- Type checking support: Added complete type stub files (
.pyi) for PyO3 extension
v0.5.0: Release/0.5.0 (#8)
π¨ Breaking Changes (Rust API only)
- 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
β¨ Changed
- 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
π Maintainer Notes
- Prepared for upcoming CEL Rust features:
- Enhanced type system & introspection
type()function support- Optional value handling
v0.4.1
v0.4.0
π CLI Interface
- Command-line tool: cel command now available after installation
- Interactive REPL: Enhanced terminal experience with syntax highlighting, auto-completion, and command history
- Multiple output formats: JSON, pretty tables, Python repr, and auto-detection
- File processing: Batch evaluation of expressions from files
- Context loading: JSON context files for complex evaluations
Command-line usage
$ cel '1 + 2' # β 3
$ cel --interactive # Launch REPL
$ cel 'age >= 21' --context user.json # Context from file
π§ͺ Testing
- 200+ tests: Complete coverage of all CEL features and edge cases
- 35 new CLI tests: Formatter, REPL, file operations, and integration testing
- Performance verification: Microsecond-level evaluation benchmarks
- Error handling tests: Parser errors, type errors, and edge cases
π§ Technical Improvements
CEL Interpreter Update
- cel-interpreter: 0.9.0 β 0.10.0 (enhanced CEL specification compliance)
PyO3 0.25.0 Migration
- Modern API: Migrated from deprecated IntoPy to IntoPyObject<'py> trait
- Better error handling: Improved type conversion with proper lifetime management
- Enhanced type safety: New conversion system with comprehensive error propagation
- Graceful degradation: Parser panics converted to proper PyValueError exceptions
Documentation
- Comprehensive Python-facing documentation with examples and type hints
- Context class: Detailed docstrings for all methods with usage examples
π¦ Dependencies
- pyo3: 0.22.6 β 0.25.0
- cel-interpreter: 0.9.0 β 0.10.0
- log: 0.4.22 β 0.4.27
- chrono: 0.4.38 β 0.4.41
- pyo3-log: 0.11.0 β 0.12.1
Full Changelog: v0.3.1...v0.4.0
v0.3.1
v0.3.0
Adds supports for CEL expressions to use user defined Python Functions.
from cel import evaluate
def is_adult(age):
return age > 21
evaluate("is_adult(age)", {'is_adult': is_adult, 'age': 18})
# FalseAlso updates pyo3 and cel-interpreter to latest stable versions.