Skip to content

Commit 7ac00b5

Browse files
dmitriplotnikovcopybara-github
authored andcommitted
Add context_variable to CEL Env
Context_variable is a struct type that defines top-level variables that can be directly referenced by a CEL policy. PiperOrigin-RevId: 933417419
1 parent adc0bfd commit 7ac00b5

4 files changed

Lines changed: 51 additions & 0 deletions

File tree

cel_expr_python/cel.pyi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ class CelExtensionBase:
1313
def __init__(self, name: str) -> None: ...
1414

1515
class EnvConfig:
16+
@property
17+
def context_type(self) -> str: ...
1618
def to_yaml(self) -> str: ...
1719

1820
class ExpressionContainer:

cel_expr_python/cel_env_test.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,52 @@ def test_invalid_yaml(self):
9898
str(e.exception),
9999
)
100100

101+
def test_parse_context_variable_config(self):
102+
config = cel.NewEnvConfigFromYaml("""
103+
context_variable:
104+
type_name: "cel.expr.conformance.proto2.TestAllTypes"
105+
""")
106+
self.assertEqual(
107+
config.context_type, "cel.expr.conformance.proto2.TestAllTypes"
108+
)
109+
110+
def test_parse_context_variable_config_alternative_syntax(self):
111+
config = cel.NewEnvConfigFromYaml("""
112+
context_variable:
113+
type: "cel.expr.conformance.proto2.TestAllTypes"
114+
""")
115+
self.assertEqual(
116+
config.context_type, "cel.expr.conformance.proto2.TestAllTypes"
117+
)
118+
119+
def test_parse_context_variable_malformed(self):
120+
with self.assertRaisesRegex(
121+
Exception, "Node 'context_variable' is not a map"
122+
):
123+
cel.NewEnvConfigFromYaml("context_variable: 123")
124+
125+
def test_parse_context_variable_malformed2(self):
126+
with self.assertRaisesRegex(
127+
Exception, "Node 'context_variable' does not have a valid type"
128+
):
129+
cel.NewEnvConfigFromYaml("""
130+
context_variable:
131+
type:
132+
foo: bar
133+
""")
134+
135+
def test_context_variable_basic(self):
136+
config = cel.NewEnvConfigFromYaml("""
137+
context_variable:
138+
type_name: "cel.expr.conformance.proto2.TestAllTypes"
139+
""")
140+
env = cel.NewEnv(config=config)
141+
ast = env.compile("single_int32 > 10")
142+
self.assertIsNotNone(ast)
143+
144+
with self.assertRaises(Exception):
145+
env.compile("non_existent_field > 10")
146+
101147
def test_config_export_container(self):
102148
env: cel.Env = cel.NewEnv(container="test.container")
103149
yaml: str = env.config().to_yaml()

cel_expr_python/py_cel_env_config.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ void PyCelEnvConfig::DefinePythonBindings(pybind11::module& m) {
3333
m.def("NewEnvConfigFromYaml", &PyCelEnvConfig::FromYaml, py::arg("yaml"));
3434

3535
cel_class.def("to_yaml", &PyCelEnvConfig::ToYaml);
36+
cel_class.def_property_readonly("context_type",
37+
&PyCelEnvConfig::GetContextType);
3638
}
3739

3840
PyCelEnvConfig PyCelEnvConfig::FromYaml(std::string yaml) {

cel_expr_python/py_cel_env_config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class PyCelEnvConfig {
3434
std::string ToYaml() const;
3535

3636
const cel::Config& GetConfig() const { return config_; }
37+
std::string GetContextType() const { return config_.GetContextType(); }
3738

3839
private:
3940
cel::Config config_;

0 commit comments

Comments
 (0)