Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 48 additions & 53 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,68 +7,63 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed
- **BREAKING**: Updated `cel` crate (formerly `cel-interpreter`) from 0.10.0 to 0.11.0
- Crate renamed from `cel-interpreter` to `cel` upstream
- API changes to function registration system using `IntoFunction` trait
- Python function integration now uses `Arguments` extractor for variadic argument handling
- All imports updated from `cel_interpreter::` to `::cel::`

### Dependencies Updated
- cel-interpreter β†’ cel: 0.10.0 β†’ 0.11.0 (crate renamed, major API breaking changes)
- New function registration system using `IntoFunction` trait
- Improved extractors system with `Arguments`, `This`, and `Identifier`
- Better error handling and performance improvements
- pyo3: 0.25.0 β†’ 0.25.1 (latest stable)
- pyo3-log: 0.12.1 β†’ 0.12.4 (latest compatible version)
## [0.5.0] - 2025-08-08

### Notes
- **CEL v0.11.0 Integration**: Updated to new `IntoFunction` trait system while maintaining full Python API compatibility
- All Python functions still work identically from user perspective
- Internal implementation now uses `Arguments` extractor for better performance
- No breaking changes to Python API - all existing code continues to work
- **Future-Proofing**: Analysis of upcoming cel-rust changes shows exciting developments:
- Enhanced type system infrastructure for better type introspection
- Foundation for `type()` function (currently missing from CEL spec compliance)
- Optional value infrastructure for safer null handling
- All future changes maintain backward compatibility with our wrapper
### 🚨 Breaking Changes (Rust API only)
- Upgraded `cel` crate (formerly `cel-interpreter`) 0.10.0 β†’ 0.11.0:
- Function registration now uses `IntoFunction` trait.
- Python integration updated to use `Arguments` extractor for variadic args.
- Imports renamed from `cel_interpreter::` to `cel::`.
- **No changes to Python API** – all existing code continues to work.

## [0.4.1] - 2025-08-02
### ✨ 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

### Added
- **Automatic Type Coercion**: Intelligent preprocessing of expressions to handle mixed int/float arithmetic
- Expressions with float literals automatically convert integer literals to floats
- Context variables containing floats trigger integer-to-float promotion for compatibility
- Preserves array indexing with integers (e.g., `list[2]` remains as integer)
- **Enhanced Error Handling**: Added panic handling with `std::panic::catch_unwind` for parser errors
- Invalid expressions now return proper ValueError instead of crashing the Python process
- Graceful handling of upstream parser panics from cel-interpreter
## [0.4.1] - 2025-08-02

### Changed
- Updated `cel-interpreter` from 0.9.0 to 0.10.0
### ✨ Added
- **Automatic type coercion** for mixed int/float arithmetic:
- 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 `ValueError` instead of crashing Python.

### Fixed
- **Mixed-type arithmetic compatibility**: Expressions like `3.14 * 2`, `2 + 3.14`, `value * 2` (where value is float) now work as expected
- **Parser panic handling**: Implemented `std::panic::catch_unwind` to gracefully handle upstream parser panics
- Users get proper error messages instead of application crashes
- Fixed deprecation warnings by updating to compatible PyO3 APIs
### πŸ› Fixed
- Mixed-type arithmetic now works in expressions like:
- `3.14 * 2`
- `2 + 3.14`
- `value * 2` (where `value` is float)
- Parser panics from `cel-interpreter` handled gracefully with proper error messages.
- Updated to latest PyO3 APIs to remove deprecation warnings.

### Known Issues
- **Bytes Concatenation**: cel-interpreter 0.10.0 does not implement bytes concatenation with `+` operator
- **CEL specification requires**: `b'hello' + b'world'` should work
- **Current behavior**: Returns "Unsupported binary operator 'add'" error
- **Workaround**: Use `bytes(string(part1) + string(part2))` for concatenation
- **Status**: This is a missing feature in the cel-interpreter crate, not a design limitation
### ⚠ Known Issues
- **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.

### Dependencies Updated
- cel-interpreter: 0.9.0 β†’ 0.10.0 (major version update with breaking changes)
### πŸ“¦ Dependencies
- 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 with IntoPyObject migration)
- pyo3-log: 0.11.0 β†’ 0.12.1 (compatible with pyo3 0.25.0)
- 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)

### Notes
- **PyO3 0.25.0 Migration**: Migrated from deprecated `IntoPy` trait to new `IntoPyObject` API
- **API Improvements**: New conversion system provides better error handling and type safety
- **Build Status**: All 120 tests pass with current dependency versions
### πŸ—’ Maintainer Notes
- **PyO3 migration**: moved from deprecated `IntoPy` to new `IntoPyObject` API.
- New conversion system improves error handling and type safety.
- All 120 tests pass on current dependency set.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cel"
version = "0.4.2"
version = "0.5.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
63 changes: 62 additions & 1 deletion docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,20 @@ cd python-common-expression-language

# Install development dependencies
uv sync --dev
# β†’ Installing project dependencies and development tools

# Build the Rust extension
uv run maturin develop
# β†’ πŸ”— Found pyo3 bindings
# β†’ πŸ“¦ Built wheel for CPython 3.11 to target/wheels/common_expression_language-0.11.0-cp311-cp311-linux_x86_64.whl
# β†’ πŸ“¦ Installed common-expression-language-0.11.0

# Run tests to verify setup
uv run pytest
# β†’ ========================= test session starts =========================
# β†’ collected 300+ items
# β†’ tests/test_basics.py ........ [ 95%]
# β†’ ========================= 300 passed in 2.34s =========================
```

### Code Organization
Expand All @@ -87,15 +95,34 @@ We maintain comprehensive test coverage across multiple categories:
```bash
# Run all tests
uv run pytest
# β†’ ========================= test session starts =========================
# β†’ collected 300+ items
# β†’ tests/test_basics.py ........ [ 95%]
# β†’ ========================= 300 passed in 2.34s =========================

# Run specific test categories
uv run pytest tests/test_basics.py # Core functionality
# β†’ ========================= 25 passed in 0.12s =========================

uv run pytest tests/test_arithmetic.py # Math operations
# β†’ ========================= 42 passed in 0.18s =========================

uv run pytest tests/test_context.py # Variable handling
# β†’ ========================= 18 passed in 0.09s =========================

uv run pytest tests/test_upstream_improvements.py # Future compatibility
# β†’ ========================= 15 passed, 8 xfailed in 0.15s =========================

# Run with coverage
uv run pytest --cov=cel
# β†’ ========================= test session starts =========================
# β†’ ----------- coverage: platform linux, python 3.11.0-final-0 -----------
# β†’ Name Stmts Miss Cover
# β†’ ------------------------------------------
# β†’ cel/__init__.py 12 0 100%
# β†’ ------------------------------------------
# β†’ TOTAL 12 0 100%
# β†’ ========================= 300 passed in 3.45s =========================
```


Expand Down Expand Up @@ -123,11 +150,14 @@ def test_lower_ascii_not_implemented(self):
"""When this test starts failing, lowerAscii() has been implemented."""
with pytest.raises(RuntimeError, match="Undefined variable or function.*lowerAscii"):
cel.evaluate('"HELLO".lowerAscii()')
# β†’ RuntimeError: Undefined variable or function 'lowerAscii'

@pytest.mark.xfail(reason="String utilities not implemented in cel v0.11.0", strict=False)
def test_lower_ascii_expected_behavior(self):
"""This test will pass when upstream implements lowerAscii()."""
assert cel.evaluate('"HELLO".lowerAscii()') == "hello"
result = cel.evaluate('"HELLO".lowerAscii()')
# β†’ "hello" (when implemented)
assert result == "hello"
```

#### Monitored Categories
Expand All @@ -146,9 +176,15 @@ def test_lower_ascii_expected_behavior(self):
```bash
# Check current upstream compatibility status
uv run pytest tests/test_upstream_improvements.py -v
# β†’ test_lower_ascii_not_implemented PASSED
# β†’ test_lower_ascii_expected_behavior XFAIL
# β†’ test_type_function_not_implemented PASSED
# β†’ test_type_function_expected_behavior XFAIL
# β†’ ========================= 15 passed, 8 xfailed in 0.15s =========================

# Look for XPASS results indicating new capabilities
uv run pytest tests/test_upstream_improvements.py -v --tb=no | grep -E "(XPASS|FAILED)"
# β†’ (no output means no unexpected passes - all limitations still exist)
```

**Interpreting Results:**
Expand Down Expand Up @@ -218,35 +254,60 @@ def add_function(self, name: str, func: Callable) -> None:
```bash
# Clean rebuild
uv run maturin develop --release
# β†’ πŸ”— Found pyo3 bindings
# β†’ πŸ“¦ Built wheel for CPython 3.11 to target/wheels/common_expression_language-0.11.0-cp311-cp311-linux_x86_64.whl
# β†’ πŸ“¦ Installed common-expression-language-0.11.0

# Check Rust toolchain
rustc --version
# β†’ rustc 1.75.0 (82e1608df 2023-12-21)

cargo --version
# β†’ cargo 1.75.0 (1d8b05cdd 2023-11-20)
```

**Test Failures:**
```bash
# Run with verbose output
uv run pytest tests/test_failing.py -v -s
# β†’ ========================= test session starts =========================
# β†’ tests/test_failing.py::test_function FAILED
# β†’ ===================== short test summary info =====================
# β†’ FAILED tests/test_failing.py::test_function - AssertionError: ...

# Debug specific test
uv run pytest tests/test_file.py::test_name --pdb
# β†’ ========================= test session starts =========================
# β†’ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PDB set_trace >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
# β†’ (Pdb)
```

**Type Conversion Issues:**
```bash
# Check Python-Rust boundary
uv run pytest tests/test_types.py -v --tb=long
# β†’ ========================= test session starts =========================
# β†’ tests/test_types.py::test_string_conversion PASSED
# β†’ tests/test_types.py::test_int_conversion PASSED
# β†’ tests/test_types.py::test_list_conversion PASSED
# β†’ ========================= 25 passed in 0.12s =========================
```

### Performance Profiling

```bash
# Basic performance verification
uv run pytest tests/test_performance_verification.py
# β†’ ========================= test session starts =========================
# β†’ tests/test_performance_verification.py::test_basic_performance PASSED
# β†’ tests/test_performance_verification.py::test_bulk_evaluations PASSED
# β†’ ========================= 5 passed in 0.45s =========================

# Memory profiling (if needed)
uv run pytest --profile tests/test_performance.py
# β†’ ========================= test session starts =========================
# β†’ Profiling enabled, results saved to .pytest_cache/profiling/
# β†’ ========================= 12 passed in 1.23s =========================
```

## Release Process
Expand Down
Loading
Loading