From b42974063326901fefea650dc4e32b832bf337ee Mon Sep 17 00:00:00 2001 From: Dmitri Plotnikov Date: Wed, 19 Aug 2026 17:16:07 -0700 Subject: [PATCH] Wrap the "lists" extension library PiperOrigin-RevId: 967488650 --- cel_expr_python/BUILD | 2 ++ cel_expr_python/ext/BUILD | 21 ++++++++++++ cel_expr_python/ext/ext_lists.cc | 54 +++++++++++++++++++++++++++++++ cel_expr_python/ext/ext_lists.pyi | 4 +++ conformance/BUILD | 2 ++ conformance/conformance_test.py | 4 +-- release/setup.py | 4 +++ 7 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 cel_expr_python/ext/ext_lists.cc create mode 100644 cel_expr_python/ext/ext_lists.pyi diff --git a/cel_expr_python/BUILD b/cel_expr_python/BUILD index acb75ab..3b60244 100644 --- a/cel_expr_python/BUILD +++ b/cel_expr_python/BUILD @@ -172,6 +172,7 @@ py_test( data = [ ":cel", "//cel_expr_python/ext:ext_bindings", + "//cel_expr_python/ext:ext_lists", "//cel_expr_python/ext:ext_math", "//cel_expr_python/ext:ext_optional", "//cel_expr_python/ext:ext_strings", @@ -184,6 +185,7 @@ py_test( "//conditions:default": [ ":cel", "//cel_expr_python/ext:ext_bindings", + "//cel_expr_python/ext:ext_lists", "//cel_expr_python/ext:ext_math", "//cel_expr_python/ext:ext_optional", "//cel_expr_python/ext:ext_strings", diff --git a/cel_expr_python/ext/BUILD b/cel_expr_python/ext/BUILD index 1e879c1..4161b32 100644 --- a/cel_expr_python/ext/BUILD +++ b/cel_expr_python/ext/BUILD @@ -39,6 +39,27 @@ pybind_extension( ], ) +pybind_extension( + name = "ext_lists", + srcs = [ + "ext_lists.cc", + ], + data = [ + "ext_lists.pyi", + "//cel_expr_python:cel", + ], + visibility = ["//visibility:public"], + deps = [ + "//cel_expr_python:cel_extension", + "@com_google_absl//absl/status", + "@com_google_absl//absl/strings", + "@com_google_cel_cpp//compiler", + "@com_google_cel_cpp//extensions:lists_functions", + "@com_google_cel_cpp//runtime:runtime_builder", + "@com_google_cel_cpp//runtime:runtime_options", + ], +) + pybind_extension( name = "ext_math", srcs = [ diff --git a/cel_expr_python/ext/ext_lists.cc b/cel_expr_python/ext/ext_lists.cc new file mode 100644 index 0000000..888c252 --- /dev/null +++ b/cel_expr_python/ext/ext_lists.cc @@ -0,0 +1,54 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/status/status.h" +#include "absl/strings/str_cat.h" +#include "compiler/compiler.h" +#include "extensions/lists_functions.h" +#include "runtime/runtime_builder.h" +#include "runtime/runtime_options.h" +#include "cel_expr_python/cel_extension.h" +#include "cel_expr_python/py_error_status.h" + +namespace cel_python { + +class ExtLists : public CelExtension { + public: + explicit ExtLists(int version) + : CelExtension("cel.lib.ext.lists", "lists", version) { + if (version < 0 || + version > cel::extensions::kListsExtensionLatestVersion) { + throw StatusToException(absl::InvalidArgumentError(absl::StrCat( + "'lists' extension version: ", version, " not in range [0, ", + cel::extensions::kListsExtensionLatestVersion, "]"))); + } + } + + ExtLists() : ExtLists(cel::extensions::kListsExtensionLatestVersion) {} + + cel::CompilerLibrary GetCompilerLibrary() override { + return cel::extensions::ListsCompilerLibrary(version()); + } + + absl::Status ConfigureRuntime(cel::RuntimeBuilder& runtime_builder, + const cel::RuntimeOptions& opts) override { + return cel::extensions::RegisterListsFunctions( + runtime_builder.function_registry(), opts, + cel::extensions::ListsExtensionOptions{.version = version()}); + } +}; + +CEL_VERSIONED_EXTENSION_MODULE(ext_lists, ExtLists); + +} // namespace cel_python diff --git a/cel_expr_python/ext/ext_lists.pyi b/cel_expr_python/ext/ext_lists.pyi new file mode 100644 index 0000000..68b199f --- /dev/null +++ b/cel_expr_python/ext/ext_lists.pyi @@ -0,0 +1,4 @@ +from cel_expr_python import cel + +class ExtLists(cel.CelExtensionBase): + def __init__(self, version: int = ...) -> None: ... diff --git a/conformance/BUILD b/conformance/BUILD index 00291fc..1897cc8 100644 --- a/conformance/BUILD +++ b/conformance/BUILD @@ -40,6 +40,7 @@ py_test( "//cel_expr_python:cel", "//cel_expr_python/ext:ext_bindings", "//cel_expr_python/ext:ext_encoders", + "//cel_expr_python/ext:ext_lists", "//cel_expr_python/ext:ext_math", "//cel_expr_python/ext:ext_optional", "//cel_expr_python/ext:ext_proto", @@ -63,6 +64,7 @@ py_test( "//cel_expr_python:cel", "//cel_expr_python/ext:ext_bindings", "//cel_expr_python/ext:ext_encoders", + "//cel_expr_python/ext:ext_lists", "//cel_expr_python/ext:ext_math", "//cel_expr_python/ext:ext_optional", "//cel_expr_python/ext:ext_proto", diff --git a/conformance/conformance_test.py b/conformance/conformance_test.py index 529bba2..de54d1b 100644 --- a/conformance/conformance_test.py +++ b/conformance/conformance_test.py @@ -32,6 +32,7 @@ from cel_expr_python import cel from cel_expr_python.ext import ext_bindings from cel_expr_python.ext import ext_encoders +from cel_expr_python.ext import ext_lists from cel_expr_python.ext import ext_math from cel_expr_python.ext import ext_optional from cel_expr_python.ext import ext_proto @@ -73,8 +74,6 @@ class ConformanceTestSuite(unittest.TestSuite): "proto3/set_null/map_timestamp_null_pruned", "proto3/set_null/map_duration_null_pruned", "proto3/set_null/map_wrapper_null_pruned", - # TODO(b/548571767): add lists_ext support - "lists_ext/.*", ] if sys.platform == "win32": @@ -147,6 +146,7 @@ class ConformanceTest(absltest.TestCase): EXTENSIONS_PER_TESTFILE = { "bindings_ext": [ext_bindings.ExtBindings()], "encoders_ext": [ext_encoders.ExtEncoders()], + "lists_ext": [ext_lists.ExtLists()], "math_ext": [ext_math.ExtMath()], "optionals": [ext_optional.ExtOptional()], "proto2_ext": [ext_proto.ExtProto()], diff --git a/release/setup.py b/release/setup.py index e2d0962..16babad 100644 --- a/release/setup.py +++ b/release/setup.py @@ -207,6 +207,10 @@ def platform_config_macos(self, cmd): 'cel_expr_python.ext.ext_encoders', '//cel_expr_python/ext:ext_encoders', ), + BazelExtension( + 'cel_expr_python.ext.ext_lists', + '//cel_expr_python/ext:ext_lists', + ), BazelExtension( 'cel_expr_python.ext.ext_math', '//cel_expr_python/ext:ext_math',