Skip to content

Commit 3419a99

Browse files
dmitriplotnikovcopybara-github
authored andcommitted
Rename "py_cel.Cel" class to "py_cel.Env" for consistency
Documentation of CEL ubiquitously refers to this object as "enviroment". The API should reflect this convention. PiperOrigin-RevId: 858266397
1 parent a95b351 commit 3419a99

9 files changed

Lines changed: 109 additions & 110 deletions

File tree

BUILD

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ exports_files(["LICENSE"])
1212
pybind_extension(
1313
name = "py_cel",
1414
srcs = [
15-
"py_cel.cc",
16-
"py_cel.h",
1715
"py_cel_activation.cc",
1816
"py_cel_activation.h",
1917
"py_cel_arena.cc",
2018
"py_cel_arena.h",
19+
"py_cel_env.cc",
20+
"py_cel_env.h",
2121
"py_cel_env_internal.cc",
2222
"py_cel_env_internal.h",
2323
"py_cel_expression.cc",

README.md

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ To create a CEL environment, you need to define
1616
variable types that can be used in expressions.
1717

1818
```python
19-
cel = py_cel.Cel(variables={"x": py_cel.Type.INT, "y": py_cel.Type.INT})
19+
cel_env = py_cel.NewEnv(variables={"x": py_cel.Type.INT, "y": py_cel.Type.INT})
2020
```
2121

2222
#### Optional configuration parameters
2323

24-
The `py_cel.Cel` constructor also accepts the following optional parameters:
24+
The `py_cel.NewEnv` constructor also accepts the following optional parameters:
2525

2626
* `pool` (`descriptor_pool.DescriptorPool`): The descriptor pool used for
2727
resolving protobuf message types within CEL expressions. If not provided,
@@ -39,7 +39,7 @@ Use the `compile()` method to compile a CEL expression string into a reusable
3939
expression object.
4040

4141
```python
42-
expr = cel.compile("x + y > 10")
42+
expr = cel_env.compile("x + y > 10")
4343
```
4444

4545
The `expr` object can be serialized into a binary format for persistence and
@@ -48,7 +48,7 @@ later deserialized.
4848
```python
4949
serialized_expr = expr.serialize()
5050
# ... can be stored or sent over network ...
51-
deserialized_expr = cel.deserialize(serialized_expr)
51+
deserialized_expr = cel_env.deserialize(serialized_expr)
5252
```
5353

5454
The `compile` method can take an optional `disable_check=True` argument, which
@@ -62,7 +62,7 @@ provides bindings for variables, and then call `eval()`.
6262

6363
```python
6464
# Provide variable values in a dictionary.
65-
activation = cel.Activation({"x": 7, "y": 4})
65+
activation = cel_env.Activation({"x": 7, "y": 4})
6666

6767
# Evaluate the expression.
6868
result = expr.eval(activation)
@@ -94,9 +94,9 @@ garbage-collected in Python.
9494
```python
9595
arena = py_cel.Arena()
9696

97-
activation1 = cel.Activation({"x": 7, "y": 4}, arena)
97+
activation1 = cel_env.Activation({"x": 7, "y": 4}, arena)
9898
# evaluate some expressions
99-
activation2 = cel.Activation({"x": 8, "y": 9}, arena)
99+
activation2 = cel_env.Activation({"x": 8, "y": 9}, arena)
100100
# evaluate some more expressions
101101

102102
# Process all results. Note: Don't put CelValues in long-lived data structures
@@ -112,7 +112,7 @@ You can pass protobuf messages as variables to an activation; CEL
112112
expressions can return protobuf messages.
113113

114114
First, ensure your proto messages are available in the descriptor pool used by
115-
`py_cel.Cel`, by importing your proto library in Python:
115+
`py_cel.NewEnv`, by importing your proto library in Python:
116116

117117
from cel.expr.conformance.proto2 import test_all_types_pb2 as test_pb
118118

@@ -121,7 +121,7 @@ qualified name.
121121

122122
```python
123123
# Declare 'msg_var' as a message type.
124-
cel = py_cel.Cel(
124+
cel = py_cel.NewEnv(
125125
pool,
126126
variables={
127127
"msg_var": py_cel.Type("cel.expr.conformance.proto2.TestAllTypes"),
@@ -141,15 +141,15 @@ an instance of the Python proto message class.
141141
```python
142142
my_msg = test_pb.TestAllTypes(single_int32=42)
143143

144-
activation = cel.Activation({"msg_var": my_msg})
144+
activation = cel_env.Activation({"msg_var": my_msg})
145145
result = expr.eval(activation)
146146
print(f"Result: {result.value()}")
147147
```
148148

149149
An expression can also return a proto message:
150150

151151
```python
152-
msg_expr = cel.compile(
152+
msg_expr = cel_env.compile(
153153
"cel.expr.conformance.proto2.TestAllTypes{single_int32: 123}"
154154
)
155155
msg_result = msg_expr.eval(activation)
@@ -174,8 +174,8 @@ Standard extensions are available under `py_cel.ext`.
174174
```python
175175
from py_cel.ext import ext_math
176176

177-
cel = py_cel.Cel(pool, extensions=[ext_math.ExtMath()])
178-
expr = cel.compile("math.sqrt(4)")
177+
cel = py_cel.NewEnv(pool, extensions=[ext_math.ExtMath()])
178+
expr = cel_env.compile("math.sqrt(4)")
179179
```
180180

181181
#### Defining a custom extension in Python
@@ -203,8 +203,8 @@ my_ext = py_cel.CelExtension(
203203
],
204204
)
205205

206-
cel = py_cel.Cel(pool, extensions=[my_ext])
207-
expr = cel.compile("my_func(1)")
206+
cel_env = py_cel.NewEnv(pool, extensions=[my_ext])
207+
expr = cel_env.compile("my_func(1)")
208208
```
209209

210210
#### Defining a custom extension in C++
@@ -304,10 +304,10 @@ Now you can use the extension in PyCel:
304304
```python
305305
import translation_cel_ext
306306

307-
cel = py_cel.Cel(variables={},
307+
cel_env = py_cel.NewEnv(variables={},
308308
extensions=[translation_cel_ext.TranslationCelExtension()])
309309

310-
expr = cel.compile("'Hello, world!'.translate('en', 'es')")
310+
expr = cel_env.compile("'Hello, world!'.translate('en', 'es')")
311311
```
312312

313313
#### Late-bound extension functions
@@ -357,11 +357,11 @@ If the extension is written in C++, use the `RegisterLazyFunction` function:
357357
Now you can bind the function at runtime:
358358
359359
```python
360-
cel = py_cel.Cel(variables={}, extensions=[my_ext])
361-
expr = cel.compile("my_func(42)")
360+
cel_env = py_cel.NewEnv(variables={}, extensions=[my_ext])
361+
expr = cel_env.compile("my_func(42)")
362362
363363
multiplier = 2
364-
act = cel.Activation({}, functions={"my_func": lambda x: x * multiplier})
364+
act = cel_env.Activation({}, functions={"my_func": lambda x: x * multiplier})
365365
res = expr.eval(act)
366366
# res.value() == 84
367367
```

conformance/conformance_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,14 +158,14 @@ def _run_conformance_test(self, simple_test: simple_pb.SimpleTest):
158158
break
159159

160160
self.descriptor_pool = descriptor_pool.Default()
161-
self.cel = cel.Cel(
161+
self.env = cel.NewEnv(
162162
self.descriptor_pool,
163163
variables=decls,
164164
extensions=extensions,
165165
container=simple_test.container,
166166
)
167167
try:
168-
compiled_expr = self.cel.compile(
168+
compiled_expr = self.env.compile(
169169
simple_test.expr, disable_check=simple_test.disable_check
170170
)
171171
except Exception as e: # pylint: disable=broad-except
@@ -188,7 +188,7 @@ def _run_conformance_test(self, simple_test: simple_pb.SimpleTest):
188188
for key, value in simple_test.bindings.items():
189189
values[key] = self._convert_value(value.value)
190190

191-
act = self.cel.Activation(values)
191+
act = self.env.Activation(values)
192192
try:
193193
res = compiled_expr.eval(act)
194194
except Exception as e: # pylint: disable=broad-except

custom_ext/custom_ext_test.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,16 @@ def _compile_expr(
4040
) -> cel.Expression:
4141
"""Creates a CEL expression for the given extension and compiles the expression."""
4242
self.descriptor_pool = descriptor_pool.Default()
43-
self.cel = cel.Cel(
43+
self.env = cel.NewEnv(
4444
self.descriptor_pool,
4545
variables={},
4646
extensions=[ext()],
4747
)
48-
return self.cel.compile(expression)
48+
return self.env.compile(expression)
4949

5050
def _create_activation(self, impl) -> cel.Activation:
5151
"""Creates a CEL Activation with a late-bound translate function."""
52-
return self.cel.Activation(
52+
return self.env.Activation(
5353
{},
5454
functions=[
5555
cel.Function(
@@ -66,7 +66,7 @@ def test_basic_function(self, ext):
6666
compiled_expr = self._compile_expr(
6767
ext, "'Hello, world!'.translate('en', 'es')"
6868
)
69-
act = self.cel.Activation({})
69+
act = self.env.Activation({})
7070
res = compiled_expr.eval(act)
7171

7272
self.assertEqual(res.value(), "¡Hola Mundo!")
@@ -85,7 +85,7 @@ def test_late_bound_function(self, ext):
8585
@parameterized.named_parameters(EXT_IMPLEMENTATIONS)
8686
def test_error_no_matching_overload(self, ext):
8787
compiled_expr = self._compile_expr(ext, "translate_late('Hello, world!')")
88-
act = self.cel.Activation(
88+
act = self.env.Activation(
8989
{},
9090
functions=[
9191
cel.Function(

py_cel.cc renamed to py_cel_env.cc

Lines changed: 46 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
#include "py_cel.h"
15+
#include "py_cel_env.h"
1616

1717
#include <Python.h> // IWYU pragma: keep - Needed for PyObject
1818

@@ -38,48 +38,47 @@ namespace cel_python {
3838

3939
namespace py = ::pybind11;
4040

41-
void PyCel::DefinePythonBindings(pybind11::module& m) {
42-
py::class_<PyCel, std::shared_ptr<PyCel>> cel_class(m, "Cel");
43-
cel_class
44-
.def(py::init([](py::object descriptor_pool,
45-
std::optional<std::unordered_map<std::string, PyCelType>>
46-
variables,
47-
std::optional<std::vector<py::object>> extensions,
48-
const std::optional<std::string>& container) {
49-
PyObject* pool_ptr = nullptr;
50-
if (descriptor_pool.is_none()) {
51-
// Replicates python's `descriptor_pool.Default()`
52-
pool_ptr = py::module::import("google.protobuf.descriptor_pool")
53-
.attr("Default")()
54-
.ptr();
55-
} else {
56-
pool_ptr = descriptor_pool.ptr();
57-
}
41+
void PyCelEnv::DefinePythonBindings(pybind11::module& m) {
42+
py::class_<PyCelEnv, std::shared_ptr<PyCelEnv>> cel_class(m, "Env");
43+
m.def(
44+
"NewEnv",
45+
[](py::object descriptor_pool,
46+
std::optional<std::unordered_map<std::string, PyCelType>> variables,
47+
std::optional<std::vector<py::object>> extensions,
48+
const std::optional<std::string>& container) {
49+
PyObject* pool_ptr = nullptr;
50+
if (descriptor_pool.is_none()) {
51+
// Replicates python's `descriptor_pool.Default()`
52+
pool_ptr = py::module::import("google.protobuf.descriptor_pool")
53+
.attr("Default")()
54+
.ptr();
55+
} else {
56+
pool_ptr = descriptor_pool.ptr();
57+
}
5858

59-
std::vector<PyObject*> ext_ptrs;
60-
if (extensions) {
61-
ext_ptrs.reserve(extensions->size());
62-
for (const auto& ext : *extensions) {
63-
ext_ptrs.push_back(ext.ptr());
64-
}
65-
}
59+
std::vector<PyObject*> ext_ptrs;
60+
if (extensions) {
61+
ext_ptrs.reserve(extensions->size());
62+
for (const auto& ext : *extensions) {
63+
ext_ptrs.push_back(ext.ptr());
64+
}
65+
}
6666

67-
return std::make_shared<PyCel>(
68-
pool_ptr,
69-
std::move(variables).value_or(
70-
std::unordered_map<std::string, PyCelType>{}),
71-
ext_ptrs, container.value_or(""));
72-
}),
73-
py::arg("descriptor_pool") = py::none(),
74-
py::arg("variables") = py::none(),
75-
py::arg("extensions") = py::none(),
76-
py::arg("container") = py::none())
77-
.def("compile", &PyCel::Compile, py::arg("expression"),
67+
return PyCelEnv(pool_ptr,
68+
std::move(variables).value_or(
69+
std::unordered_map<std::string, PyCelType>{}),
70+
ext_ptrs, container.value_or(""));
71+
},
72+
py::arg("descriptor_pool") = py::none(),
73+
py::arg("variables") = py::none(), py::arg("extensions") = py::none(),
74+
py::arg("container") = py::none());
75+
cel_class
76+
.def("compile", &PyCelEnv::Compile, py::arg("expression"),
7877
py::arg("disable_check") = false)
79-
.def("deserialize", &PyCel::Deserialize, py::arg("serialized"))
78+
.def("deserialize", &PyCelEnv::Deserialize, py::arg("serialized"))
8079
.def(
8180
"Activation",
82-
[](PyCel& self,
81+
[](PyCelEnv& self,
8382
std::optional<std::unordered_map<std::string, py::object>> data,
8483
const std::optional<std::vector<std::shared_ptr<PyCelFunction>>>&
8584
functions,
@@ -103,30 +102,31 @@ void PyCel::DefinePythonBindings(pybind11::module& m) {
103102
py::arg("arena") = nullptr);
104103
}
105104

106-
PyCel::PyCel(PyObject* descriptor_pool,
107-
std::unordered_map<std::string, PyCelType> variable_types,
108-
const std::vector<PyObject*>& extensions, std::string container)
105+
PyCelEnv::PyCelEnv(PyObject* descriptor_pool,
106+
std::unordered_map<std::string, PyCelType> variable_types,
107+
const std::vector<PyObject*>& extensions,
108+
std::string container)
109109
: env_(std::make_unique<PyCelEnvInternal>(
110110
descriptor_pool, std::move(variable_types), extensions,
111111
std::move(container))) {
112112
ABSL_CHECK(PyGILState_Check());
113113
}
114114

115-
PyCel::~PyCel() = default;
115+
PyCelEnv::~PyCelEnv() = default;
116116

117-
std::shared_ptr<PyCelActivation> PyCel::NewActivation(
117+
std::shared_ptr<PyCelActivation> PyCelEnv::NewActivation(
118118
const std::unordered_map<std::string, PyObject*>& data,
119119
const std::vector<std::shared_ptr<PyCelFunction>>& functions,
120120
const std::shared_ptr<PyCelArena>& arena) {
121121
return std::make_shared<PyCelActivation>(env_, data, functions, arena);
122122
}
123123

124-
absl::StatusOr<PyCelExpression> PyCel::Compile(const std::string& cel_expr,
125-
bool disable_check) {
124+
absl::StatusOr<PyCelExpression> PyCelEnv::Compile(const std::string& cel_expr,
125+
bool disable_check) {
126126
return PyCelExpression::Compile(env_, cel_expr, disable_check);
127127
}
128128

129-
absl::StatusOr<PyCelExpression> PyCel::Deserialize(
129+
absl::StatusOr<PyCelExpression> PyCelEnv::Deserialize(
130130
const std::string& serialized_expr) {
131131
return PyCelExpression::Deserialize(env_, serialized_expr);
132132
}

0 commit comments

Comments
 (0)