Skip to content

Commit 1ef7b37

Browse files
committed
🧹 fmt
1 parent e4e6469 commit 1ef7b37

9 files changed

Lines changed: 306 additions & 303 deletions

File tree

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ jobs:
4343

4444
- name: Install dependencies
4545
run: |
46-
uv sync --dev
47-
uv run maturin develop
46+
uv sync --dev --group docs
47+
#uv run maturin develop
4848
4949
- name: Run Rust tests
5050
run: cargo test --verbose

docs/how-to-guides/access-control-policies.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@ Hard-coding these rules makes them difficult to update and test.
1717

1818
Instead of complex if/else chains in your application code, define access policies as portable, safe expressions that can be updated without code changes.
1919

20-
!!! tip "Start Simple"
21-
If you're new to CEL access control, check out the [basic policy evaluation example](../index.md#python-integration) on the main page first.
22-
2320
CEL enables sophisticated, multi-factor access control policies that handle complex business rules:
2421

2522
```python

examples/basic.py

Lines changed: 0 additions & 24 deletions
This file was deleted.

python/cel/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@
1010
__all__ = [
1111
"evaluate",
1212
"Context",
13-
]
13+
]

tests/test_boolean_coercion.py

Lines changed: 73 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ def test_not_operator_basic(self):
1818
# Test with boolean literals - correctly returns booleans
1919
assert evaluate("!true") is False
2020
assert evaluate("!false") is True
21-
21+
2222
def test_not_operator_with_numbers(self):
2323
"""Test NOT operator with numeric values."""
2424
# Zero is falsy
2525
assert evaluate("!0") is True
2626
assert evaluate("!0.0") is True
27-
27+
2828
# Non-zero numbers are truthy
2929
assert evaluate("!1") is False
3030
assert evaluate("!42") is False
@@ -36,7 +36,7 @@ def test_not_operator_with_strings(self):
3636
# Empty string is falsy
3737
assert evaluate("!''") is True
3838
assert evaluate('!""') is True
39-
39+
4040
# Non-empty strings are truthy
4141
assert evaluate("!'hello'") is False
4242
assert evaluate("!'0'") is False # String "0" is truthy
@@ -51,7 +51,7 @@ def test_not_operator_with_collections(self):
5151
# Empty collections are falsy
5252
assert evaluate("![]") is True
5353
assert evaluate("!{}") is True
54-
54+
5555
# Non-empty collections are truthy
5656
assert evaluate("![1, 2]") is False
5757
assert evaluate("!{'key': 'value'}") is False
@@ -60,29 +60,29 @@ def test_double_not_operator_parser_bug(self):
6060
"""Test double NOT (!!) operator - documents upstream parser bug."""
6161
# UPSTREAM BUG: The !! syntax is parsed incorrectly and behaves like single !
6262
# This is a known issue in the cel-interpreter crate
63-
assert evaluate("!!true") is False # BUG: Should be True, behaves like !true
64-
assert evaluate("!!false") is True # BUG: Should be False, behaves like !false
65-
assert evaluate("!!0") is True # BUG: Should be False, behaves like !0
66-
assert evaluate("!!1") is False # BUG: Should be True, behaves like !1
67-
assert evaluate("!!''") is True # BUG: Should be False, behaves like !''
68-
assert evaluate("!!'hello'") is False # BUG: Should be True, behaves like !'hello'
69-
63+
assert evaluate("!!true") is False # BUG: Should be True, behaves like !true
64+
assert evaluate("!!false") is True # BUG: Should be False, behaves like !false
65+
assert evaluate("!!0") is True # BUG: Should be False, behaves like !0
66+
assert evaluate("!!1") is False # BUG: Should be True, behaves like !1
67+
assert evaluate("!!''") is True # BUG: Should be False, behaves like !''
68+
assert evaluate("!!'hello'") is False # BUG: Should be True, behaves like !'hello'
69+
7070
# WORKAROUND: Use parentheses for correct double NOT behavior
71-
assert evaluate("!(!true)") is True # Correct: NOT(NOT(true)) = True
71+
assert evaluate("!(!true)") is True # Correct: NOT(NOT(true)) = True
7272
assert evaluate("!(!false)") is False # Correct: NOT(NOT(false)) = False
73-
assert evaluate("!(!0)") is False # Correct: NOT(NOT(0)) = False
74-
assert evaluate("!(!1)") is True # Correct: NOT(NOT(1)) = True
75-
assert evaluate("!(!(''))")is False # Correct: NOT(NOT('')) = False
76-
assert evaluate("!(!('hello'))") is True # Correct: NOT(NOT('hello')) = True
73+
assert evaluate("!(!0)") is False # Correct: NOT(NOT(0)) = False
74+
assert evaluate("!(!1)") is True # Correct: NOT(NOT(1)) = True
75+
assert evaluate("!(!(''))") is False # Correct: NOT(NOT('')) = False
76+
assert evaluate("!(!('hello'))") is True # Correct: NOT(NOT('hello')) = True
7777

7878
def test_bool_function_unavailable(self):
7979
"""Test that bool() function is not available."""
8080
with pytest.raises(RuntimeError, match="Undefined variable or function: 'bool'"):
8181
evaluate("bool(true)")
82-
82+
8383
with pytest.raises(RuntimeError, match="Undefined variable or function: 'bool'"):
8484
evaluate("bool(0)")
85-
85+
8686
with pytest.raises(RuntimeError, match="Undefined variable or function: 'bool'"):
8787
evaluate("bool('')")
8888

@@ -96,29 +96,29 @@ def test_logical_and_truthiness(self):
9696
assert evaluate("null && true") is False
9797
assert evaluate("[] && true") is False
9898
assert evaluate("{} && true") is False
99-
99+
100100
# Truthy values in AND return True when both operands are truthy
101101
assert evaluate("1 && true") is True
102102
assert evaluate("true && 1") is True
103-
assert evaluate("'hello' && true") is True
103+
assert evaluate("'hello' && true") is True
104104
assert evaluate("true && 'hello'") is True
105105

106106
def test_logical_or_truthiness(self):
107107
"""Test truthiness evaluation in logical OR operations."""
108108
# OR operator shows behavioral difference from CEL spec - returns original values
109109
# Falsy values in OR
110-
assert evaluate("0 || false") is False # Both falsy -> False
111-
assert evaluate("false || 0") == 0 # Returns second operand when first is falsy
112-
assert evaluate("'' || false") is False # Both falsy -> False
113-
assert evaluate("null || false") is False # Both falsy -> False
114-
110+
assert evaluate("0 || false") is False # Both falsy -> False
111+
assert evaluate("false || 0") == 0 # Returns second operand when first is falsy
112+
assert evaluate("'' || false") is False # Both falsy -> False
113+
assert evaluate("null || false") is False # Both falsy -> False
114+
115115
# Truthy values in OR - demonstrates the documented behavioral difference
116116
# CEL spec: should return boolean true/false
117117
# This implementation: returns original truthy value (JavaScript-like)
118-
assert evaluate("1 || false") == 1 # Returns original int, not boolean
119-
assert evaluate("42 || false") == 42 # Returns original int, not boolean
118+
assert evaluate("1 || false") == 1 # Returns original int, not boolean
119+
assert evaluate("42 || false") == 42 # Returns original int, not boolean
120120
assert evaluate("'hello' || false") == "hello" # Returns string, not boolean
121-
assert evaluate("[1, 2] || false") == [1, 2] # Returns list, not boolean
121+
assert evaluate("[1, 2] || false") == [1, 2] # Returns list, not boolean
122122

123123
def test_ternary_operator_truthiness(self):
124124
"""Test truthiness evaluation in ternary conditional expressions."""
@@ -129,7 +129,7 @@ def test_ternary_operator_truthiness(self):
129129
assert evaluate("null ? 'truthy' : 'falsy'") == "falsy"
130130
assert evaluate("[] ? 'truthy' : 'falsy'") == "falsy"
131131
assert evaluate("{} ? 'truthy' : 'falsy'") == "falsy"
132-
132+
133133
# Truthy values
134134
assert evaluate("1 ? 'truthy' : 'falsy'") == "truthy"
135135
assert evaluate("true ? 'truthy' : 'falsy'") == "truthy"
@@ -141,26 +141,30 @@ def test_boolean_coercion_consistency(self):
141141
"""Test consistency of boolean coercion across different contexts."""
142142
# Test that the same value has consistent truthiness
143143
test_values = [
144-
(0, False), # Zero is falsy
145-
(1, True), # One is truthy
146-
('', False), # Empty string is falsy
147-
('hello', True), # Non-empty string is truthy
148-
([], False), # Empty list is falsy
149-
([1], True), # Non-empty list is truthy
150-
({}, False), # Empty map is falsy
151-
({'a': 1}, True) # Non-empty map is truthy
144+
(0, False), # Zero is falsy
145+
(1, True), # One is truthy
146+
("", False), # Empty string is falsy
147+
("hello", True), # Non-empty string is truthy
148+
([], False), # Empty list is falsy
149+
([1], True), # Non-empty list is truthy
150+
({}, False), # Empty map is falsy
151+
({"a": 1}, True), # Non-empty map is truthy
152152
]
153-
153+
154154
for value, is_truthy in test_values:
155155
# NOT operator returns proper booleans
156156
not_result = evaluate("!x", {"x": value})
157157
expected_not = False if is_truthy else True
158-
assert not_result == expected_not, f"!{value} should be {expected_not}, got {not_result}"
159-
158+
assert not_result == expected_not, (
159+
f"!{value} should be {expected_not}, got {not_result}"
160+
)
161+
160162
# Ternary operator
161163
ternary_result = evaluate("x ? 'T' : 'F'", {"x": value})
162-
expected_ternary = 'T' if is_truthy else 'F'
163-
assert ternary_result == expected_ternary, f"{value} ? 'T' : 'F' should be {expected_ternary}"
164+
expected_ternary = "T" if is_truthy else "F"
165+
assert ternary_result == expected_ternary, (
166+
f"{value} ? 'T' : 'F' should be {expected_ternary}"
167+
)
164168

165169
def test_comparison_operators_return_booleans(self):
166170
"""Test that comparison operators properly return boolean values."""
@@ -171,7 +175,7 @@ def test_comparison_operators_return_booleans(self):
171175
assert evaluate("2 > 1") is True
172176
assert evaluate("1 <= 1") is True
173177
assert evaluate("1 >= 1") is True
174-
178+
175179
assert evaluate("1 == 2") is False
176180
assert evaluate("1 != 1") is False
177181
assert evaluate("2 < 1") is False
@@ -189,20 +193,24 @@ def test_mixed_boolean_expressions(self):
189193
"empty_list": [],
190194
"non_empty_list": [1, 2, 3],
191195
"is_valid": True,
192-
"is_invalid": False
196+
"is_invalid": False,
193197
}
194-
198+
195199
# Complex AND/OR with mixed types
196200
assert evaluate("positive && non_empty_string", context) is True # AND returns boolean
197-
assert evaluate("zero || positive", context) == 42 # OR returns original truthy value
198-
assert evaluate("empty_string || 'default'", context) == "default" # OR returns original value
199-
201+
assert evaluate("zero || positive", context) == 42 # OR returns original truthy value
202+
assert (
203+
evaluate("empty_string || 'default'", context) == "default"
204+
) # OR returns original value
205+
200206
# Mixed with comparisons
201207
assert evaluate("positive > 0 && non_empty_string", context) is True # AND returns boolean
202-
assert evaluate("zero == 0 || is_invalid", context) is True # OR with boolean
203-
208+
assert evaluate("zero == 0 || is_invalid", context) is True # OR with boolean
209+
204210
# Complex ternary expressions
205-
assert evaluate("positive ? (empty_string || 'fallback') : 'negative'", context) == "fallback"
211+
assert (
212+
evaluate("positive ? (empty_string || 'fallback') : 'negative'", context) == "fallback"
213+
)
206214

207215
def test_boolean_context_with_variables(self):
208216
"""Test boolean coercion with context variables."""
@@ -211,38 +219,38 @@ def test_boolean_context_with_variables(self):
211219
"settings": {},
212220
"items": [1, 2, 3],
213221
"empty_items": [],
214-
"config": {"debug": True}
222+
"config": {"debug": True},
215223
}
216-
224+
217225
# Object truthiness
218226
assert evaluate("user ? 'has_user' : 'no_user'", context) == "has_user"
219227
assert evaluate("settings ? 'has_settings' : 'no_settings'", context) == "no_settings"
220-
228+
221229
# List truthiness
222230
assert evaluate("items ? 'has_items' : 'no_items'", context) == "has_items"
223231
assert evaluate("empty_items ? 'has_items' : 'no_items'", context) == "no_items"
224-
232+
225233
# Nested access with boolean logic
226-
assert evaluate("user && user.age > 18", context) == True
227-
assert evaluate("!settings || config.debug", context) == True
234+
assert evaluate("user && user.age > 18", context)
235+
assert evaluate("!settings || config.debug", context)
228236

229237
def test_documented_behavioral_differences(self):
230238
"""Test and document the known behavioral differences from CEL spec."""
231239
# This test documents the behavioral differences mentioned in cel-compliance.md
232-
240+
233241
# OR operator returns original values instead of booleans
234242
# CEL spec: 42 || false should return true (boolean)
235243
# This implementation: returns 42 (original value)
236244
result = evaluate("42 || false")
237245
assert result == 42 # JavaScript-like behavior, not CEL spec
238-
246+
239247
result = evaluate("0 || 'default'")
240248
assert result == "default" # Returns original string, not boolean
241-
249+
242250
# AND operator behaves differently - returns boolean values
243251
result = evaluate("'hello' && 42")
244252
assert result is True # Returns boolean True when both operands are truthy
245-
253+
246254
result = evaluate("0 && 'unreachable'")
247255
assert result is False # Returns boolean False when first operand is falsy
248256

@@ -251,15 +259,15 @@ def test_edge_cases_and_special_values(self):
251259
# Unicode strings
252260
assert evaluate("'🌍' ? 'truthy' : 'falsy'") == "truthy"
253261
assert evaluate("!''") == 1 # Empty string is falsy
254-
262+
255263
# Large numbers
256264
assert evaluate("!9999999999") == 0
257265
assert evaluate("!0.0000001") == 0
258-
266+
259267
# Negative numbers
260268
assert evaluate("!-1") == 0
261269
assert evaluate("!-42") == 0
262-
270+
263271
# Floating point edge cases
264272
assert evaluate("!0.0") == 1
265-
assert evaluate("!-0.0") == 1
273+
assert evaluate("!-0.0") == 1

tests/test_docs.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
"""Test documentation code blocks using mktestdocs."""
22

33
import pathlib
4+
45
import pytest
56
from mktestdocs import check_md_file
67

78

8-
@pytest.mark.parametrize(
9-
"fpath",
10-
pathlib.Path("docs").glob("**/*.md"),
11-
ids=str
12-
)
9+
@pytest.mark.parametrize("fpath", pathlib.Path("docs").glob("**/*.md"), ids=str)
1310
def test_documentation_code_blocks(fpath):
1411
"""Test that all Python code blocks in documentation execute without errors."""
15-
check_md_file(fpath=fpath, memory=True)
12+
check_md_file(fpath=fpath, memory=True)

0 commit comments

Comments
 (0)