Skip to content

Commit 96be97c

Browse files
authored
Issue 107 (#118)
Add Transpiler capability, and an additional benchmark. Update the documentation significantly. Update some sketchy design features, also. Most notably. `celtypes.TypeType` should **not** have created types from their string names. Eliminate a test case that doesn't apply to all versions.
1 parent 2b7eafa commit 96be97c

File tree

118 files changed

+18457
-3994
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

118 files changed

+18457
-3994
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,6 @@ type_check/lineprecision.txt
134134
demo/issue_41.py
135135
demo/issue_80.py
136136
setup.sh
137+
/docs/build/doctrees
138+
docs/build/html/.buildinfo
139+
docs/build/html/.buildinfo.bak

.travis.yml

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

Makefile

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,35 +21,30 @@ build:
2121
uv build
2222

2323
install-tools:
24-
cd tools && export PATH="/usr/local/go/bin:/usr/local/bin:$PATH" && go mod init mkgherkin && go mod tidy
24+
cd tools && docker pull golang && docker build -t mkgherkin .
2525

2626
test:
2727
cd features && $(MAKE) all
28-
tox -e py312
28+
tox run -e py312
2929

3030
test-all:
3131
cd features && $(MAKE) all
32-
tox
32+
tox run
3333

3434
test-wip:
3535
cd features && $(MAKE) all
36-
tox -e wip
36+
tox run -e wip
3737

3838
test-tools:
39-
tox -e tools
39+
tox run -e tools
4040
cd features && $(MAKE) scan
4141

42-
unit-test:
43-
PYTHONPATH=src python -m pytest -vv --cov=src --cov-report=term-missing ${test}
44-
PYTHONPATH=src python -m doctest tools/*.py
45-
PYTHONPATH=src python -m doctest features/steps/*.py
46-
4742
docs: $(wildcard docs/source/*.rst)
4843
PYTHONPATH=src python -m doctest docs/source/*.rst
4944
export PYTHONPATH=$(PWD)/src:$(PWD)/tools && cd docs && $(MAKE) html
5045

5146
lint:
52-
tox -e lint
47+
tox run -e lint
5348

5449
coverage:
5550
coverage report -m

README.rst

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,11 @@ can then be applied to argument values.
128128
>>> ast = env.compile(cel_source)
129129
>>> prgm = env.program(ast)
130130

131-
>>> activation = {
131+
>>> context = {
132132
... "account": celpy.json_to_cel({"balance": 500, "overdraftProtection": False}),
133133
... "transaction": celpy.json_to_cel({"withdrawal": 600})
134134
... }
135-
>>> result = prgm.evaluate(activation)
135+
>>> result = prgm.evaluate(context)
136136
>>> result
137137
BoolType(False)
138138

@@ -153,10 +153,15 @@ https://github.com/google/cel-cpp/blob/master/parser/Cel.g4
153153

154154
https://github.com/google/cel-go/blob/master/parser/gen/CEL.g4
155155

156+
The documentation includes PlantUML diagrams.
157+
The Sphinx ``conf.py`` provides the location for the PlantUML local JAR file if one is used.
158+
Currently, it expects ``docs/plantuml-asl-1.2025.3.jar``.
159+
The JAR is not provided in this repository, get one from https://plantuml.com.
160+
If you install a different version, update the ``conf.py`` to refer to the JAR file you've downloaded.
161+
156162
Notes
157163
=====
158164

159-
160165
CEL provides a number of runtime errors that are mapped to Python exceptions.
161166

162167
- ``no_matching_overload``: this function has no overload for the types of the arguments.
@@ -171,6 +176,79 @@ However, see https://github.com/google/cel-spec/blob/master/doc/langdef.md#gradu
171176
Rather than try to pre-check types, we'll rely on Python's implementation.
172177

173178

179+
Example 2
180+
=========
181+
182+
Here's an example with some details::
183+
184+
>>> import celpy
185+
186+
# A list of type names and class bindings used to create an environment.
187+
>>> types = []
188+
>>> env = celpy.Environment(types)
189+
190+
# Parse the code to create the CEL AST.
191+
>>> ast = env.compile("355. / 113.")
192+
193+
# Use the AST and any overriding functions to create an executable program.
194+
>>> functions = {}
195+
>>> prgm = env.program(ast, functions)
196+
197+
# Variable bindings.
198+
>>> activation = {}
199+
200+
# Final evaluation.
201+
>>> try:
202+
... result = prgm.evaluate(activation)
203+
... error = None
204+
... except CELEvalError as ex:
205+
... result = None
206+
... error = ex.args[0]
207+
208+
>>> result # doctest: +ELLIPSIS
209+
DoubleType(3.14159...)
210+
211+
Example 3
212+
=========
213+
214+
See https://github.com/google/cel-go/blob/master/examples/simple_test.go
215+
216+
The model Go we're sticking close to::
217+
218+
d := cel.Declarations(decls.NewVar("name", decls.String))
219+
env, err := cel.NewEnv(d)
220+
if err != nil {
221+
log.Fatalf("environment creation error: %v\\n", err)
222+
}
223+
ast, iss := env.Compile(`"Hello world! I'm " + name + "."`)
224+
// Check iss for compilation errors.
225+
if iss.Err() != nil {
226+
log.Fatalln(iss.Err())
227+
}
228+
prg, err := env.Program(ast)
229+
if err != nil {
230+
log.Fatalln(err)
231+
}
232+
out, _, err := prg.Eval(map[string]interface{}{
233+
"name": "CEL",
234+
})
235+
if err != nil {
236+
log.Fatalln(err)
237+
}
238+
fmt.Println(out)
239+
// Output:Hello world! I'm CEL.
240+
241+
Here's the Pythonic approach, using concept patterned after the Go implementation::
242+
243+
>>> from celpy import *
244+
>>> decls = {"name": celtypes.StringType}
245+
>>> env = Environment(annotations=decls)
246+
>>> ast = env.compile('"Hello world! I\'m " + name + "."')
247+
>>> out = env.program(ast).evaluate({"name": "CEL"})
248+
>>> print(out)
249+
Hello world! I'm CEL.
250+
251+
174252
Contributing
175253
============
176254

benches/complex_expression.py

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,8 @@
351351
"none": lambda optional, : None
352352
}
353353

354-
def simple_performance():
355-
env = celpy.Environment()
354+
def simple_performance(runner_class: type[celpy.Runner] | None = None) -> None:
355+
env = celpy.Environment(runner_class=runner_class)
356356

357357
number = 100
358358
compile = timeit.timeit(
@@ -364,8 +364,8 @@ def simple_performance():
364364
'CEL_EXPRESSION_ORIGINAL_NO_OPTIONAL': CEL_EXPRESSION_ORIGINAL_NO_OPTIONAL
365365
},
366366
number=number
367-
) / number
368-
print(f"Compile: {1_000 * compile:9.4f} ms")
367+
)
368+
print(f"Compile: {1_000 * compile / number:9.4f} ms")
369369

370370
ast = env.compile(CEL_EXPRESSION_ORIGINAL_NO_OPTIONAL)
371371

@@ -380,8 +380,8 @@ def simple_performance():
380380
'functions': functions
381381
},
382382
number=number
383-
) / number
384-
print(f"Prepare: {1_000 * prepare:9.4f} ms")
383+
)
384+
print(f"Prepare: {1_000 * prepare / number:9.4f} ms")
385385

386386
program = env.program(ast, functions=functions)
387387

@@ -398,8 +398,8 @@ def simple_performance():
398398
"""),
399399
globals={'celpy': celpy},
400400
number=number
401-
) / number
402-
print(f"Convert: {1_000 * convert:9.4f} ms")
401+
)
402+
print(f"Convert: {1_000 * convert / number:9.4f} ms")
403403

404404
cel_context = {
405405
"class_a": celpy.json_to_cel({"property_a": "something"}),
@@ -419,8 +419,8 @@ def simple_performance():
419419
'cel_context': cel_context
420420
},
421421
number=number
422-
) / number
423-
print(f"Evaluate: {1_000 * evaluation:9.4f} ms")
422+
)
423+
print(f"Evaluate: {1_000 * evaluation / number:9.4f} ms")
424424

425425
print()
426426

@@ -450,7 +450,18 @@ def detailed_profile():
450450
ps.print_stats()
451451

452452
def main():
453-
simple_performance()
453+
print("# Performance")
454+
print()
455+
print("## Interpreter")
456+
print()
457+
simple_performance(celpy.InterpretedRunner)
458+
print()
459+
print("## Transpiler")
460+
print()
461+
simple_performance(celpy.CompiledRunner)
462+
print()
463+
print("# Profile")
464+
print()
454465
detailed_profile()
455466

456467
if __name__ == "__main__":

docs/build/doctrees/api.doctree

1.85 MB
Binary file not shown.
3 Bytes
Binary file not shown.

docs/build/doctrees/cli.doctree

47.8 KB
Binary file not shown.
4.58 KB
Binary file not shown.
2.54 MB
Binary file not shown.

0 commit comments

Comments
 (0)