Skip to content

Commit c5ae6b8

Browse files
committed
docs
1 parent 0d4c002 commit c5ae6b8

3 files changed

Lines changed: 50 additions & 79 deletions

File tree

CHANGELOG.md

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Updated
11+
- Updated cel crate from v0.11.0 to v0.11.1
12+
- Fixed logical operator tests to match CEL specification behavior
13+
- Updated documentation version references
14+
- Cleaned up unhelpful short-term comments in documentation
15+
1016
## [0.5.2] - 2025-09-04
1117

1218
### 🚨 Breaking Changes
@@ -24,29 +30,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2430
- **CEL function short-circuiting**: Fixed issue where `has()` and other CEL functions failed due to AST preprocessing interference
2531
- **String literal corruption**: Eliminated string literal modification that occurred during integer promotion preprocessing
2632

27-
### 📚 Documentation
28-
29-
- **Complete documentation overhaul**: Updated all documentation to reflect strict CEL mode operation
30-
- Removed all references to Python evaluation mode
31-
- Updated all code examples to use explicit type conversion for mixed arithmetic
32-
- Updated CLI reference to remove `--mode` option
33-
- All documentation tests now pass with strict CEL mode
34-
35-
### 🧪 Testing
36-
37-
- **Comprehensive test suite cleanup**: Removed Python mode specific tests while maintaining coverage
38-
- Removed 30 Python mode specific tests
39-
- Updated 47 tests to work with strict CEL mode only
40-
- Maintained 291 core functionality tests
41-
- All 329 tests now pass (321 passed, 1 skipped, 6 xfailed, 1 xpassed)
42-
43-
### 🏗️ Architecture
33+
### Updated
4434

45-
- **Simplified codebase**: Removed ~600 lines of complex preprocessing logic
46-
- Eliminated `EvaluationMode` enum and related infrastructure
47-
- Removed AST reconstruction and integer promotion functions
48-
- Streamlined evaluate function signature and implementation
49-
- Enhanced performance by removing mode checking overhead
35+
- Updated documentation to reflect strict CEL mode operation
36+
- Updated tests to work with strict CEL mode only
37+
- Removed complex preprocessing logic
5038

5139
## [0.5.1] - 2025-08-11
5240

docs/how-to-guides/error-handling.md

Lines changed: 39 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -33,63 +33,53 @@ except ValueError as e:
3333
Raised for undefined variables/functions and function execution errors:
3434

3535
```python
36-
# Undefined variables - Use safe variables that exist in context to avoid parser issues
37-
context_with_valid_var = {"valid_var": 10}
3836
try:
39-
# Instead of undefined variables, demonstrate with context validation
40-
# Original problematic: evaluate("undefined_var", {}) # This could cause parser panics
41-
result = evaluate("valid_var", {}) # Empty context will cause RuntimeError
37+
evaluate("undefined_var", {}) # Variable not in context
4238
assert False, "Expected RuntimeError"
4339
except RuntimeError as e:
4440
assert "Undefined variable or function" in str(e)
45-
# → RuntimeError: Undefined variable (prevents security issues)
41+
# → RuntimeError: Undefined variable 'undefined_var'
4642

47-
# Undefined functions - Use safe examples to avoid parser panics
4843
try:
49-
# Instead of undefined functions, use context without the function
50-
# Original problematic: evaluate("undefined_func()", {}) # Could cause parser issues
51-
result = evaluate("valid_var + missing_var", context_with_valid_var) # missing_var will cause error
44+
evaluate("missing_func()", {}) # Function doesn't exist
5245
assert False, "Expected RuntimeError"
5346
except RuntimeError as e:
5447
assert "Undefined variable or function" in str(e)
55-
# → RuntimeError: Undefined function (safe by default)
48+
# → RuntimeError: Undefined function 'missing_func'
5649

57-
# Function execution errors - safer demonstration with missing variables
5850
try:
59-
# Use a variable that doesn't exist in context to trigger RuntimeError
60-
context = {"user": {"name": "alice"}}
61-
result = evaluate("missing_variable", context) # Will cause RuntimeError
62-
assert False, "Expected RuntimeError"
63-
except RuntimeError as e:
64-
assert "Undefined variable" in str(e)
65-
# → RuntimeError: Function error propagated safely
51+
evaluate("user.missing_field", {"user": {"name": "alice"}}) # Field access error
52+
assert False, "Expected ValueError"
53+
except ValueError as e:
54+
assert "No such key" in str(e)
55+
# → ValueError: No such key: missing_field
6656
```
6757

6858
### `TypeError` - Type Compatibility Errors
6959

7060
Raised when operations are performed on incompatible types:
7161

7262
```python
73-
# Type errors - avoiding expressions that cause parser panics
74-
# Note: Direct type mismatches in CEL expressions can trigger ANTLR parser bugs
75-
# Instead, we focus on demonstrating type safety through documentation
76-
77-
# Example of type safety (commented out problematic expressions):
78-
# Problematic: evaluate('"hello" + 42') # String + int (causes parser panic)
79-
# Problematic: evaluate("1u + 2") # Mixed signed/unsigned (causes parser panic)
80-
# Problematic: evaluate('"text" * "more"') # String multiplication (causes parser panic)
81-
82-
# Instead, demonstrate type safety through proper context usage
83-
context = {"message": "hello", "count": 42, "flag": True}
84-
85-
# Safe operations that demonstrate type consistency
86-
result1 = evaluate("message", context) # String access - safe
87-
assert result1 == "hello"
88-
# → String operations work correctly when types match
89-
90-
result2 = evaluate("count > 0", context) # Numeric comparison - safe
91-
assert result2 is True
92-
# → Type safety enforced through proper expression design
63+
try:
64+
evaluate("1 + 2u") # Mixed signed/unsigned arithmetic
65+
assert False, "Expected TypeError"
66+
except TypeError as e:
67+
assert "Cannot mix signed and unsigned" in str(e)
68+
# → TypeError: Cannot mix signed and unsigned integers
69+
70+
try:
71+
evaluate('"hello" && true') # String in logical operation
72+
assert False, "Expected ValueError"
73+
except ValueError as e:
74+
assert "No such overload" in str(e)
75+
# → ValueError: No such overload for mixed-type logical operations
76+
77+
try:
78+
evaluate("[1, 2, 3].map(x, x * 2.0)") # Mixed arithmetic in map
79+
assert False, "Expected TypeError"
80+
except TypeError as e:
81+
assert "operation" in str(e)
82+
# → TypeError: Unsupported operation between types
9383
```
9484

9585
## ✅ Safe Error Handling for Malformed Input
@@ -344,25 +334,19 @@ assert success == False, "Expression with nonexistent field should be blocked"
344334
assert len(errors) > 0, "Should report validation or runtime errors"
345335
# → False, errors: ['Evaluation error: ...'] (field access error caught)
346336

347-
# Test 3: Invalid syntax (removed problematic incomplete expression)
348-
# Note: Incomplete boolean expressions can cause parser panics
337+
# Test 3: Invalid syntax
349338
invalid_syntax = 'user.age >=' # Incomplete comparison
350339
success, result, errors = safe_user_expression_eval(invalid_syntax, context)
351340
assert success == False, "Invalid syntax should be rejected"
352341
assert len(errors) > 0, "Should report syntax errors"
353342
# → False, errors: ['Evaluation error: Failed to compile'] (malformed input caught)
354343

355-
# Test 4: Empty expression (skip to avoid parser panic)
356-
# Note: Empty expressions can cause parser panics, so we validate length first
357-
if len('') == 0:
358-
success, result, errors = False, None, ["Empty expression not allowed"]
359-
else:
360-
success, result, errors = safe_user_expression_eval('', context)
361-
344+
# Test 4: Empty expression
345+
success, result, errors = safe_user_expression_eval('', context)
362346
assert success == False, "Empty expression should be rejected"
363-
# → False, errors: ['Empty expression not allowed'] (empty input handled safely)
347+
# → False, errors: ['Evaluation error: ...'] (empty input handled safely)
364348

365-
# Test 5: Undefined variable (use simpler expression to avoid panic)
349+
# Test 5: Undefined variable
366350
undefined_var = 'undefined_variable'
367351
success, result, errors = safe_user_expression_eval(undefined_var, context)
368352
assert success == False, "Undefined variable should cause error"
@@ -557,14 +541,13 @@ def test_error_handling():
557541
pass # Expected
558542
# → RuntimeError caught (undefined variable blocked safely)
559543

560-
# Test type errors (using safer expressions that don't cause parser panics)
544+
# Test type errors
561545
try:
562-
# Instead of problematic direct literals, use context-based type mismatches
563-
evaluate("nonexistent_var", {}) # This will cause RuntimeError, not TypeError
564-
assert False, "Should have raised RuntimeError"
565-
except RuntimeError:
546+
evaluate("1 + 2u") # Mixed signed/unsigned arithmetic
547+
assert False, "Should have raised TypeError"
548+
except (TypeError, ValueError): # May be TypeError or ValueError depending on operation
566549
pass # Expected
567-
#RuntimeError caught (undefined variables handled safely)
550+
#Type error caught (incompatible types handled safely)
568551

569552
def test_safe_evaluation():
570553
"""Test safe evaluation wrapper."""

docs/tutorials/thinking-in-cel.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ assert result == True
337337

338338
**💡 Takeaway: Structure context data clearly — it's the foundation of readable expressions.**
339339

340-
[**Variable Structuring Patterns**](your-first-integration.md#context-management)
340+
[**Variable Structuring Patterns**](your-first-integration.md#the-context-class)
341341

342342
### 3. Test Your Expressions
343343

0 commit comments

Comments
 (0)