From 98dbfdb32ee38accabe50dbc2bc3d8894c7fde6a Mon Sep 17 00:00:00 2001 From: Dmitri Plotnikov Date: Thu, 5 Feb 2026 15:14:14 -0800 Subject: [PATCH] Add support for cibuildwheel distribution generator PiperOrigin-RevId: 866133804 --- README.md | 2 +- conformance/BUILD | 14 +-- conformance/conformance_test.py | 23 ++-- custom_ext/BUILD | 12 +- custom_ext/custom_ext_test.py | 2 +- custom_ext/sample_cel_ext.cc | 4 +- custom_ext/sample_cel_ext.py | 2 +- BUILD => py_cel/BUILD | 0 {ext => py_cel/ext}/BUILD | 26 ++--- {ext => py_cel/ext}/ext_bindings.cc | 2 +- {ext => py_cel/ext}/ext_encoders.cc | 2 +- {ext => py_cel/ext}/ext_math.cc | 4 +- {ext => py_cel/ext}/ext_optional.cc | 2 +- {ext => py_cel/ext}/ext_proto.cc | 2 +- {ext => py_cel/ext}/ext_string.cc | 2 +- .../py_cel_activation.cc | 10 +- .../py_cel_activation.h | 2 +- py_cel_arena.cc => py_cel/py_cel_arena.cc | 2 +- py_cel_arena.h => py_cel/py_cel_arena.h | 0 py_cel_env.cc => py_cel/py_cel_env.cc | 14 +-- py_cel_env.h => py_cel/py_cel_env.h | 10 +- .../py_cel_env_internal.cc | 14 +-- .../py_cel_env_internal.h | 8 +- .../py_cel_expression.cc | 18 +-- .../py_cel_expression.h | 6 +- .../py_cel_extension.h | 0 .../py_cel_function.cc | 14 +-- py_cel_function.h => py_cel/py_cel_function.h | 2 +- .../py_cel_function_decl.cc | 4 +- .../py_cel_function_decl.h | 2 +- py_cel_module.cc => py_cel/py_cel_module.cc | 20 ++-- .../py_cel_overload.cc | 4 +- py_cel_overload.h => py_cel/py_cel_overload.h | 2 +- .../py_cel_python_extension.cc | 14 +-- .../py_cel_python_extension.h | 4 +- py_cel_test.py => py_cel/py_cel_test.py | 2 +- py_cel_type.cc => py_cel/py_cel_type.cc | 4 +- py_cel_type.h => py_cel/py_cel_type.h | 0 py_cel_value.cc => py_cel/py_cel_value.cc | 14 +-- py_cel_value.h => py_cel/py_cel_value.h | 2 +- .../py_cel_value_provider.h | 2 +- .../py_descriptor_database.cc | 4 +- .../py_descriptor_database.h | 0 .../py_error_status.cc | 2 +- py_error_status.h => py_cel/py_error_status.h | 2 +- .../py_message_factory.cc | 2 +- .../py_message_factory.h | 0 status_macros.h => py_cel/status_macros.h | 0 release/README.md | 45 ++++++++ release/build_wheel.sh | 42 +++++++ release/py_cel_basic_test.py | 32 ++++++ release/pyproject.toml | 35 ++++++ release/setup.py | 103 ++++++++++++++++++ 53 files changed, 402 insertions(+), 138 deletions(-) rename BUILD => py_cel/BUILD (100%) rename {ext => py_cel/ext}/BUILD (90%) rename {ext => py_cel/ext}/ext_bindings.cc (97%) rename {ext => py_cel/ext}/ext_encoders.cc (97%) rename {ext => py_cel/ext}/ext_math.cc (95%) rename {ext => py_cel/ext}/ext_optional.cc (97%) rename {ext => py_cel/ext}/ext_proto.cc (96%) rename {ext => py_cel/ext}/ext_string.cc (97%) rename py_cel_activation.cc => py_cel/py_cel_activation.cc (94%) rename py_cel_activation.h => py_cel/py_cel_activation.h (98%) rename py_cel_arena.cc => py_cel/py_cel_arena.cc (98%) rename py_cel_arena.h => py_cel/py_cel_arena.h (100%) rename py_cel_env.cc => py_cel/py_cel_env.cc (95%) rename py_cel_env.h => py_cel/py_cel_env.h (92%) rename py_cel_env_internal.cc => py_cel/py_cel_env_internal.cc (96%) rename py_cel_env_internal.h => py_cel/py_cel_env_internal.h (96%) rename py_cel_expression.cc => py_cel/py_cel_expression.cc (96%) rename py_cel_expression.h => py_cel/py_cel_expression.h (95%) rename py_cel_extension.h => py_cel/py_cel_extension.h (100%) rename py_cel_function.cc => py_cel/py_cel_function.cc (93%) rename py_cel_function.h => py_cel/py_cel_function.h (98%) rename py_cel_function_decl.cc => py_cel/py_cel_function_decl.cc (93%) rename py_cel_function_decl.h => py_cel/py_cel_function_decl.h (97%) rename py_cel_module.cc => py_cel/py_cel_module.cc (76%) rename py_cel_overload.cc => py_cel/py_cel_overload.cc (96%) rename py_cel_overload.h => py_cel/py_cel_overload.h (98%) rename py_cel_python_extension.cc => py_cel/py_cel_python_extension.cc (94%) rename py_cel_python_extension.h => py_cel/py_cel_python_extension.h (95%) rename py_cel_test.py => py_cel/py_cel_test.py (99%) rename py_cel_type.cc => py_cel/py_cel_type.cc (99%) rename py_cel_type.h => py_cel/py_cel_type.h (100%) rename py_cel_value.cc => py_cel/py_cel_value.cc (99%) rename py_cel_value.h => py_cel/py_cel_value.h (99%) rename py_cel_value_provider.h => py_cel/py_cel_value_provider.h (97%) rename py_descriptor_database.cc => py_cel/py_descriptor_database.cc (98%) rename py_descriptor_database.h => py_cel/py_descriptor_database.h (100%) rename py_error_status.cc => py_cel/py_error_status.cc (99%) rename py_error_status.h => py_cel/py_error_status.h (97%) rename py_message_factory.cc => py_cel/py_message_factory.cc (99%) rename py_message_factory.h => py_cel/py_message_factory.h (100%) rename status_macros.h => py_cel/status_macros.h (100%) create mode 100644 release/README.md create mode 100755 release/build_wheel.sh create mode 100644 release/py_cel_basic_test.py create mode 100644 release/pyproject.toml create mode 100644 release/setup.py diff --git a/README.md b/README.md index 029861f..e9709b2 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ This is a Python wrapper for the CEL C++ implementation. ### Importing CEL module ```python -import py_cel +from py_cel import py_cel ``` ### Creating and configuring Cel diff --git a/conformance/BUILD b/conformance/BUILD index 77addc6..259fc40 100644 --- a/conformance/BUILD +++ b/conformance/BUILD @@ -39,13 +39,13 @@ py_test( deps = [ "@com_google_cel_spec//proto/cel/expr:checked_py_pb2", "@com_google_cel_spec//proto/cel/expr:value_py_pb2", - "//:py_cel", - "//ext:ext_bindings", - "//ext:ext_encoders", - "//ext:ext_math", - "//ext:ext_optional", - "//ext:ext_proto", - "//ext:ext_string", + "//py_cel", + "//py_cel/ext:ext_bindings", + "//py_cel/ext:ext_encoders", + "//py_cel/ext:ext_math", + "//py_cel/ext:ext_optional", + "//py_cel/ext:ext_proto", + "//py_cel/ext:ext_string", "@com_google_absl_py//absl/testing:absltest", "//testing:proto2_test_all_types_py_pb2", "//testing:proto3_test_all_types_py_pb2", diff --git a/conformance/conformance_test.py b/conformance/conformance_test.py index 084391f..27dde0a 100644 --- a/conformance/conformance_test.py +++ b/conformance/conformance_test.py @@ -27,13 +27,13 @@ from cel.expr import value_pb2 as value_pb from absl.testing import absltest from python.runfiles import runfiles -import py_cel as cel -from ext import ext_bindings -from ext import ext_encoders -from ext import ext_math -from ext import ext_optional -from ext import ext_proto -from ext import ext_string +from py_cel import py_cel as cel +from py_cel.ext import ext_bindings +from py_cel.ext import ext_encoders +from py_cel.ext import ext_math +from py_cel.ext import ext_optional +from py_cel.ext import ext_proto +from py_cel.ext import ext_string from cel.expr.conformance.proto2 import test_all_types_extensions_pb2 as test_all_types_extensions_proto2 # pylint: disable=unused-import from cel.expr.conformance.proto2 import test_all_types_pb2 as test_all_types_proto2 # pylint: disable=unused-import from cel.expr.conformance.proto3 import test_all_types_pb2 as test_all_types_proto3 # pylint: disable=unused-import @@ -65,6 +65,13 @@ class ConformanceTestSuite(unittest.TestSuite): "parse/bytes_literals/triple_single_quoted_unescaped_punctuation", "parse/string_literals/triple_double_quoted_unescaped_punctuation", "parse/string_literals/triple_single_quoted_unescaped_punctuation", + # TODO(b/481818110): fix support for optional types. + "optionals/optionals/empty_struct_optindex_hasValue", + "optionals/optionals/optional_empty_struct_optindex_hasValue", + "optionals/optionals/optional_struct_optindex_index_value", + "optionals/optionals/optional_struct_optindex_index_value", + "optionals/optionals/optional_struct_optindex_value", + "optionals/optionals/struct_optindex_value", ] def __init__(self): @@ -89,7 +96,7 @@ def _load_tests(self): them to the test suite. """ testfiles = self._all_test_files( - "google3/third_party/cel/spec/tests/simple/testdata" + "cel-spec+/tests/simple/testdata" ) for testfile in testfiles: diff --git a/custom_ext/BUILD b/custom_ext/BUILD index 16e2c54..874648a 100644 --- a/custom_ext/BUILD +++ b/custom_ext/BUILD @@ -8,12 +8,12 @@ pybind_extension( name = "sample_cel_ext_cc", srcs = ["sample_cel_ext.cc"], data = [ - "//:py_cel", + "//py_cel", ], deps = [ - "//:py_cel", - "//:py_cel_extension", - "//:status_macros", + "//py_cel", + "//py_cel:py_cel_extension", + "//py_cel:status_macros", "@com_google_absl//absl/base:nullability", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", @@ -33,7 +33,7 @@ py_library( name = "sample_cel_ext_py", srcs = ["sample_cel_ext.py"], deps = [ - "//:py_cel", + "//py_cel", ], ) @@ -43,7 +43,7 @@ py_test( deps = [ ":sample_cel_ext_cc", ":sample_cel_ext_py", - "//:py_cel", + "//py_cel", "@com_google_absl_py//absl/testing:absltest", "@com_google_absl_py//absl/testing:parameterized", "@com_google_protobuf//:protobuf_python", diff --git a/custom_ext/custom_ext_test.py b/custom_ext/custom_ext_test.py index 2e02a31..df4a2d8 100644 --- a/custom_ext/custom_ext_test.py +++ b/custom_ext/custom_ext_test.py @@ -18,7 +18,7 @@ from absl.testing import absltest from absl.testing import parameterized -import py_cel as cel +from py_cel import py_cel as cel from custom_ext import sample_cel_ext from custom_ext import sample_cel_ext_cc diff --git a/custom_ext/sample_cel_ext.cc b/custom_ext/sample_cel_ext.cc index 6330663..f1cf257 100644 --- a/custom_ext/sample_cel_ext.cc +++ b/custom_ext/sample_cel_ext.cc @@ -23,8 +23,8 @@ #include "runtime/function_adapter.h" #include "runtime/runtime_builder.h" #include "runtime/runtime_options.h" -#include "py_cel_extension.h" -#include "status_macros.h" +#include "py_cel/py_cel_extension.h" +#include "py_cel/status_macros.h" #include "google/protobuf/arena.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/message.h" diff --git a/custom_ext/sample_cel_ext.py b/custom_ext/sample_cel_ext.py index 012c086..313eb05 100644 --- a/custom_ext/sample_cel_ext.py +++ b/custom_ext/sample_cel_ext.py @@ -16,7 +16,7 @@ from typing import Any -import py_cel as cel +from py_cel import py_cel as cel class SampleCelExtension(cel.CelExtension): diff --git a/BUILD b/py_cel/BUILD similarity index 100% rename from BUILD rename to py_cel/BUILD diff --git a/ext/BUILD b/py_cel/ext/BUILD similarity index 90% rename from ext/BUILD rename to py_cel/ext/BUILD index 7352ab3..ea1b961 100644 --- a/ext/BUILD +++ b/py_cel/ext/BUILD @@ -8,11 +8,11 @@ pybind_extension( "ext_bindings.cc", ], data = [ - "//:py_cel", + "//py_cel", ], visibility = ["//visibility:public"], deps = [ - "//:py_cel_extension", + "//py_cel:py_cel_extension", "@com_google_absl//absl/status", "@com_google_cel_cpp//compiler", "@com_google_cel_cpp//extensions:bindings_ext", @@ -26,11 +26,11 @@ pybind_extension( "ext_encoders.cc", ], data = [ - "//:py_cel", + "//py_cel", ], visibility = ["//visibility:public"], deps = [ - "//:py_cel_extension", + "//py_cel:py_cel_extension", "@com_google_absl//absl/status", "@com_google_cel_cpp//checker:type_checker_builder", "@com_google_cel_cpp//compiler", @@ -47,12 +47,12 @@ pybind_extension( "ext_math.cc", ], data = [ - "//:py_cel", + "//py_cel", ], visibility = ["//visibility:public"], deps = [ - "//:py_cel_extension", - "//:status_macros", + "//py_cel:py_cel_extension", + "//py_cel:status_macros", "@com_google_absl//absl/base:nullability", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", @@ -80,11 +80,11 @@ pybind_extension( "ext_optional.cc", ], data = [ - "//:py_cel", + "//py_cel", ], visibility = ["//visibility:public"], deps = [ - "//:py_cel_extension", + "//py_cel:py_cel_extension", "@com_google_absl//absl/status", "@com_google_cel_cpp//compiler", "@com_google_cel_cpp//compiler:optional", @@ -101,11 +101,11 @@ pybind_extension( "ext_proto.cc", ], data = [ - "//:py_cel", + "//py_cel", ], visibility = ["//visibility:public"], deps = [ - "//:py_cel_extension", + "//py_cel:py_cel_extension", "@com_google_absl//absl/status", "@com_google_cel_cpp//compiler", "@com_google_cel_cpp//extensions:proto_ext", @@ -119,11 +119,11 @@ pybind_extension( "ext_string.cc", ], data = [ - "//:py_cel", + "//py_cel", ], visibility = ["//visibility:public"], deps = [ - "//:py_cel_extension", + "//py_cel:py_cel_extension", "@com_google_absl//absl/status", "@com_google_cel_cpp//compiler", "@com_google_cel_cpp//extensions:strings", diff --git a/ext/ext_bindings.cc b/py_cel/ext/ext_bindings.cc similarity index 97% rename from ext/ext_bindings.cc rename to py_cel/ext/ext_bindings.cc index f552e6c..be52106 100644 --- a/ext/ext_bindings.cc +++ b/py_cel/ext/ext_bindings.cc @@ -15,7 +15,7 @@ #include "absl/status/status.h" #include "compiler/compiler.h" #include "extensions/bindings_ext.h" -#include "py_cel_extension.h" +#include "py_cel/py_cel_extension.h" #include "google/protobuf/descriptor.h" namespace cel_python { diff --git a/ext/ext_encoders.cc b/py_cel/ext/ext_encoders.cc similarity index 97% rename from ext/ext_encoders.cc rename to py_cel/ext/ext_encoders.cc index 7c3c413..84f9916 100644 --- a/ext/ext_encoders.cc +++ b/py_cel/ext/ext_encoders.cc @@ -18,7 +18,7 @@ #include "extensions/encoders.h" #include "runtime/runtime_builder.h" #include "runtime/runtime_options.h" -#include "py_cel_extension.h" +#include "py_cel/py_cel_extension.h" #include "google/protobuf/descriptor.h" namespace cel_python { diff --git a/ext/ext_math.cc b/py_cel/ext/ext_math.cc similarity index 95% rename from ext/ext_math.cc rename to py_cel/ext/ext_math.cc index 3dea354..c1833aa 100644 --- a/ext/ext_math.cc +++ b/py_cel/ext/ext_math.cc @@ -18,8 +18,8 @@ #include "extensions/math_ext_decls.h" #include "runtime/runtime_builder.h" #include "runtime/runtime_options.h" -#include "py_cel_extension.h" -#include "status_macros.h" +#include "py_cel/py_cel_extension.h" +#include "py_cel/status_macros.h" #include "google/protobuf/descriptor.h" namespace cel_python { diff --git a/ext/ext_optional.cc b/py_cel/ext/ext_optional.cc similarity index 97% rename from ext/ext_optional.cc rename to py_cel/ext/ext_optional.cc index 50df4b5..c65e0e3 100644 --- a/ext/ext_optional.cc +++ b/py_cel/ext/ext_optional.cc @@ -18,7 +18,7 @@ #include "runtime/optional_types.h" #include "runtime/runtime_builder.h" #include "runtime/runtime_options.h" -#include "py_cel_extension.h" +#include "py_cel/py_cel_extension.h" #include "google/protobuf/descriptor.h" namespace cel_python { diff --git a/ext/ext_proto.cc b/py_cel/ext/ext_proto.cc similarity index 96% rename from ext/ext_proto.cc rename to py_cel/ext/ext_proto.cc index ca7ddb9..3cc6cc9 100644 --- a/ext/ext_proto.cc +++ b/py_cel/ext/ext_proto.cc @@ -15,7 +15,7 @@ #include "absl/status/status.h" #include "compiler/compiler.h" #include "extensions/proto_ext.h" -#include "py_cel_extension.h" +#include "py_cel/py_cel_extension.h" #include "google/protobuf/descriptor.h" namespace cel_python { diff --git a/ext/ext_string.cc b/py_cel/ext/ext_string.cc similarity index 97% rename from ext/ext_string.cc rename to py_cel/ext/ext_string.cc index 1c71b20..e1e4359 100644 --- a/ext/ext_string.cc +++ b/py_cel/ext/ext_string.cc @@ -17,7 +17,7 @@ #include "extensions/strings.h" #include "runtime/runtime_builder.h" #include "runtime/runtime_options.h" -#include "py_cel_extension.h" +#include "py_cel/py_cel_extension.h" #include "google/protobuf/descriptor.h" namespace cel_python { diff --git a/py_cel_activation.cc b/py_cel/py_cel_activation.cc similarity index 94% rename from py_cel_activation.cc rename to py_cel/py_cel_activation.cc index cf4f1c7..e9d365a 100644 --- a/py_cel_activation.cc +++ b/py_cel/py_cel_activation.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "py_cel_activation.h" +#include "py_cel/py_cel_activation.h" #include // IWYU pragma: keep - Needed for PyObject @@ -26,10 +26,10 @@ #include "absl/strings/string_view.h" #include "common/function_descriptor.h" #include "common/kind.h" -#include "py_cel_arena.h" -#include "py_cel_env_internal.h" -#include "py_cel_function.h" -#include "py_cel_value_provider.h" +#include "py_cel/py_cel_arena.h" +#include "py_cel/py_cel_env_internal.h" +#include "py_cel/py_cel_function.h" +#include "py_cel/py_cel_value_provider.h" #include "google/protobuf/arena.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/message.h" diff --git a/py_cel_activation.h b/py_cel/py_cel_activation.h similarity index 98% rename from py_cel_activation.h rename to py_cel/py_cel_activation.h index e2b6e66..6006fe8 100644 --- a/py_cel_activation.h +++ b/py_cel/py_cel_activation.h @@ -23,7 +23,7 @@ #include #include "runtime/activation.h" -#include "py_cel_arena.h" +#include "py_cel/py_cel_arena.h" #include namespace cel_python { diff --git a/py_cel_arena.cc b/py_cel/py_cel_arena.cc similarity index 98% rename from py_cel_arena.cc rename to py_cel/py_cel_arena.cc index c317bac..3a80098 100644 --- a/py_cel_arena.cc +++ b/py_cel/py_cel_arena.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "py_cel_arena.h" +#include "py_cel/py_cel_arena.h" #include // IWYU pragma: keep - Needed for PyObject diff --git a/py_cel_arena.h b/py_cel/py_cel_arena.h similarity index 100% rename from py_cel_arena.h rename to py_cel/py_cel_arena.h diff --git a/py_cel_env.cc b/py_cel/py_cel_env.cc similarity index 95% rename from py_cel_env.cc rename to py_cel/py_cel_env.cc index ebe0092..7df5cab 100644 --- a/py_cel_env.cc +++ b/py_cel/py_cel_env.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "py_cel_env.h" +#include "py_cel/py_cel_env.h" #include // IWYU pragma: keep - Needed for PyObject @@ -25,12 +25,12 @@ #include #include "absl/log/absl_check.h" -#include "py_cel_activation.h" -#include "py_cel_arena.h" -#include "py_cel_env_internal.h" -#include "py_cel_expression.h" -#include "py_cel_type.h" -#include "py_error_status.h" +#include "py_cel/py_cel_activation.h" +#include "py_cel/py_cel_arena.h" +#include "py_cel/py_cel_env_internal.h" +#include "py_cel/py_cel_expression.h" +#include "py_cel/py_cel_type.h" +#include "py_cel/py_error_status.h" #include #include diff --git a/py_cel_env.h b/py_cel/py_cel_env.h similarity index 92% rename from py_cel_env.h rename to py_cel/py_cel_env.h index 73133a4..e1f8764 100644 --- a/py_cel_env.h +++ b/py_cel/py_cel_env.h @@ -23,11 +23,11 @@ #include #include -#include "py_cel_activation.h" -#include "py_cel_arena.h" -#include "py_cel_expression.h" -#include "py_cel_function.h" -#include "py_cel_type.h" +#include "py_cel/py_cel_activation.h" +#include "py_cel/py_cel_arena.h" +#include "py_cel/py_cel_expression.h" +#include "py_cel/py_cel_function.h" +#include "py_cel/py_cel_type.h" #include namespace cel { diff --git a/py_cel_env_internal.cc b/py_cel/py_cel_env_internal.cc similarity index 96% rename from py_cel_env_internal.cc rename to py_cel/py_cel_env_internal.cc index d487033..0c320b6 100644 --- a/py_cel_env_internal.cc +++ b/py_cel/py_cel_env_internal.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "py_cel_env_internal.h" +#include "py_cel/py_cel_env_internal.h" #include #include @@ -35,12 +35,12 @@ #include "runtime/runtime_builder.h" #include "runtime/runtime_options.h" #include "runtime/standard_runtime_builder_factory.h" -#include "py_cel_extension.h" -#include "py_cel_python_extension.h" -#include "py_cel_type.h" -#include "py_descriptor_database.h" -#include "py_message_factory.h" -#include "status_macros.h" +#include "py_cel/py_cel_extension.h" +#include "py_cel/py_cel_python_extension.h" +#include "py_cel/py_cel_type.h" +#include "py_cel/py_descriptor_database.h" +#include "py_cel/py_message_factory.h" +#include "py_cel/status_macros.h" #include "google/protobuf/arena.h" #include "google/protobuf/descriptor.h" #include diff --git a/py_cel_env_internal.h b/py_cel/py_cel_env_internal.h similarity index 96% rename from py_cel_env_internal.h rename to py_cel/py_cel_env_internal.h index c12f404..ecba90c 100644 --- a/py_cel_env_internal.h +++ b/py_cel/py_cel_env_internal.h @@ -29,10 +29,10 @@ #include "runtime/runtime.h" #include "runtime/runtime_builder.h" #include "runtime/runtime_options.h" -#include "py_cel_extension.h" -#include "py_cel_type.h" -#include "py_descriptor_database.h" -#include "py_message_factory.h" +#include "py_cel/py_cel_extension.h" +#include "py_cel/py_cel_type.h" +#include "py_cel/py_descriptor_database.h" +#include "py_cel/py_message_factory.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/dynamic_message.h" #include "google/protobuf/message.h" diff --git a/py_cel_expression.cc b/py_cel/py_cel_expression.cc similarity index 96% rename from py_cel_expression.cc rename to py_cel/py_cel_expression.cc index 1bf7c9c..82ba99f 100644 --- a/py_cel_expression.cc +++ b/py_cel/py_cel_expression.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "py_cel_expression.h" +#include "py_cel/py_cel_expression.h" #include // IWYU pragma: keep - Needed for PyObject @@ -43,14 +43,14 @@ #include "parser/parser_interface.h" #include "runtime/embedder_context.h" #include "runtime/runtime.h" -#include "py_cel_activation.h" -#include "py_cel_arena.h" -#include "py_cel_env_internal.h" -#include "py_cel_function.h" -#include "py_cel_type.h" -#include "py_cel_value.h" -#include "py_error_status.h" -#include "status_macros.h" +#include "py_cel/py_cel_activation.h" +#include "py_cel/py_cel_arena.h" +#include "py_cel/py_cel_env_internal.h" +#include "py_cel/py_cel_function.h" +#include "py_cel/py_cel_type.h" +#include "py_cel/py_cel_value.h" +#include "py_cel/py_error_status.h" +#include "py_cel/status_macros.h" #include #include diff --git a/py_cel_expression.h b/py_cel/py_cel_expression.h similarity index 95% rename from py_cel_expression.h rename to py_cel/py_cel_expression.h index ba6debb..e5c3f6f 100644 --- a/py_cel_expression.h +++ b/py_cel/py_cel_expression.h @@ -24,9 +24,9 @@ #include "cel/expr/syntax.pb.h" #include "absl/status/statusor.h" #include "runtime/runtime.h" -#include "py_cel_activation.h" -#include "py_cel_type.h" -#include "py_cel_value.h" +#include "py_cel/py_cel_activation.h" +#include "py_cel/py_cel_type.h" +#include "py_cel/py_cel_value.h" #include namespace cel_python { diff --git a/py_cel_extension.h b/py_cel/py_cel_extension.h similarity index 100% rename from py_cel_extension.h rename to py_cel/py_cel_extension.h diff --git a/py_cel_function.cc b/py_cel/py_cel_function.cc similarity index 93% rename from py_cel_function.cc rename to py_cel/py_cel_function.cc index 8710686..f65ff40 100644 --- a/py_cel_function.cc +++ b/py_cel/py_cel_function.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "py_cel_function.h" +#include "py_cel/py_cel_function.h" #include @@ -29,12 +29,12 @@ #include "common/value.h" #include "runtime/embedder_context.h" #include "runtime/function.h" -#include "py_cel_arena.h" -#include "py_cel_env_internal.h" -#include "py_cel_type.h" -#include "py_cel_value.h" -#include "py_error_status.h" -#include "status_macros.h" +#include "py_cel/py_cel_arena.h" +#include "py_cel/py_cel_env_internal.h" +#include "py_cel/py_cel_type.h" +#include "py_cel/py_cel_value.h" +#include "py_cel/py_error_status.h" +#include "py_cel/status_macros.h" #include #include diff --git a/py_cel_function.h b/py_cel/py_cel_function.h similarity index 98% rename from py_cel_function.h rename to py_cel/py_cel_function.h index 2394d83..d630025 100644 --- a/py_cel_function.h +++ b/py_cel/py_cel_function.h @@ -24,7 +24,7 @@ #include "absl/types/span.h" #include "common/value.h" #include "runtime/function.h" -#include "py_cel_type.h" +#include "py_cel/py_cel_type.h" #include namespace cel_python { diff --git a/py_cel_function_decl.cc b/py_cel/py_cel_function_decl.cc similarity index 93% rename from py_cel_function_decl.cc rename to py_cel/py_cel_function_decl.cc index f775124..ae724ff 100644 --- a/py_cel_function_decl.cc +++ b/py_cel/py_cel_function_decl.cc @@ -12,13 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "py_cel_function_decl.h" +#include "py_cel/py_cel_function_decl.h" #include #include #include -#include "py_cel_overload.h" +#include "py_cel/py_cel_overload.h" #include #include diff --git a/py_cel_function_decl.h b/py_cel/py_cel_function_decl.h similarity index 97% rename from py_cel_function_decl.h rename to py_cel/py_cel_function_decl.h index d3bab64..4ad24d8 100644 --- a/py_cel_function_decl.h +++ b/py_cel/py_cel_function_decl.h @@ -19,7 +19,7 @@ #include #include -#include "py_cel_overload.h" +#include "py_cel/py_cel_overload.h" #include namespace cel_python { diff --git a/py_cel_module.cc b/py_cel/py_cel_module.cc similarity index 76% rename from py_cel_module.cc rename to py_cel/py_cel_module.cc index 11bbd26..dbf17d0 100644 --- a/py_cel_module.cc +++ b/py_cel/py_cel_module.cc @@ -12,16 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "py_cel_activation.h" -#include "py_cel_arena.h" -#include "py_cel_env.h" -#include "py_cel_expression.h" -#include "py_cel_function.h" -#include "py_cel_function_decl.h" -#include "py_cel_overload.h" -#include "py_cel_python_extension.h" -#include "py_cel_type.h" -#include "py_cel_value.h" +#include "py_cel/py_cel_activation.h" +#include "py_cel/py_cel_arena.h" +#include "py_cel/py_cel_env.h" +#include "py_cel/py_cel_expression.h" +#include "py_cel/py_cel_function.h" +#include "py_cel/py_cel_function_decl.h" +#include "py_cel/py_cel_overload.h" +#include "py_cel/py_cel_python_extension.h" +#include "py_cel/py_cel_type.h" +#include "py_cel/py_cel_value.h" #include namespace cel_python { diff --git a/py_cel_overload.cc b/py_cel/py_cel_overload.cc similarity index 96% rename from py_cel_overload.cc rename to py_cel/py_cel_overload.cc index aa305b2..a38c826 100644 --- a/py_cel_overload.cc +++ b/py_cel/py_cel_overload.cc @@ -12,14 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "py_cel_overload.h" +#include "py_cel/py_cel_overload.h" #include #include #include #include -#include "py_cel_type.h" +#include "py_cel/py_cel_type.h" #include #include diff --git a/py_cel_overload.h b/py_cel/py_cel_overload.h similarity index 98% rename from py_cel_overload.h rename to py_cel/py_cel_overload.h index 0163179..d5ddcfd 100644 --- a/py_cel_overload.h +++ b/py_cel/py_cel_overload.h @@ -20,7 +20,7 @@ #include #include -#include "py_cel_type.h" +#include "py_cel/py_cel_type.h" #include namespace cel_python { diff --git a/py_cel_python_extension.cc b/py_cel/py_cel_python_extension.cc similarity index 94% rename from py_cel_python_extension.cc rename to py_cel/py_cel_python_extension.cc index 189c3ef..9500815 100644 --- a/py_cel_python_extension.cc +++ b/py_cel/py_cel_python_extension.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "py_cel_python_extension.h" +#include "py_cel/py_cel_python_extension.h" #include // IWYU pragma: keep - Needed for PyObject @@ -30,12 +30,12 @@ #include "compiler/compiler.h" #include "runtime/runtime_builder.h" #include "runtime/runtime_options.h" -#include "py_cel_extension.h" -#include "py_cel_function.h" -#include "py_cel_function_decl.h" -#include "py_cel_overload.h" -#include "py_cel_type.h" -#include "status_macros.h" +#include "py_cel/py_cel_extension.h" +#include "py_cel/py_cel_function.h" +#include "py_cel/py_cel_function_decl.h" +#include "py_cel/py_cel_overload.h" +#include "py_cel/py_cel_type.h" +#include "py_cel/status_macros.h" #include "google/protobuf/arena.h" #include "google/protobuf/descriptor.h" #include diff --git a/py_cel_python_extension.h b/py_cel/py_cel_python_extension.h similarity index 95% rename from py_cel_python_extension.h rename to py_cel/py_cel_python_extension.h index a533c1a..689a30e 100644 --- a/py_cel_python_extension.h +++ b/py_cel/py_cel_python_extension.h @@ -22,8 +22,8 @@ #include "compiler/compiler.h" #include "runtime/runtime_builder.h" #include "runtime/runtime_options.h" -#include "py_cel_extension.h" -#include "py_cel_function_decl.h" +#include "py_cel/py_cel_extension.h" +#include "py_cel/py_cel_function_decl.h" #include "google/protobuf/descriptor.h" #include diff --git a/py_cel_test.py b/py_cel/py_cel_test.py similarity index 99% rename from py_cel_test.py rename to py_cel/py_cel_test.py index 5ca4515..ba423de 100644 --- a/py_cel_test.py +++ b/py_cel/py_cel_test.py @@ -23,7 +23,7 @@ from google.protobuf import duration_pb2 as duration_pb from google.protobuf import timestamp_pb2 as timestamp_pb from absl.testing import absltest -import py_cel as cel +from py_cel import py_cel as cel from cel.expr.conformance.proto2 import test_all_types_pb2 as test_all_types_pb diff --git a/py_cel_type.cc b/py_cel/py_cel_type.cc similarity index 99% rename from py_cel_type.cc rename to py_cel/py_cel_type.cc index 7fcb7e1..735021c 100644 --- a/py_cel_type.cc +++ b/py_cel/py_cel_type.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "py_cel_type.h" +#include "py_cel/py_cel_type.h" #include // IWYU pragma: keep - Needed for PyObject @@ -36,7 +36,7 @@ #include "common/types/map_type.h" #include "common/value.h" #include "common/value_kind.h" -#include "py_error_status.h" +#include "py_cel/py_error_status.h" #include "google/protobuf/arena.h" #include "google/protobuf/descriptor.h" #include diff --git a/py_cel_type.h b/py_cel/py_cel_type.h similarity index 100% rename from py_cel_type.h rename to py_cel/py_cel_type.h diff --git a/py_cel_value.cc b/py_cel/py_cel_value.cc similarity index 99% rename from py_cel_value.cc rename to py_cel/py_cel_value.cc index fac377f..2563280 100644 --- a/py_cel_value.cc +++ b/py_cel/py_cel_value.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "py_cel_value.h" +#include "py_cel/py_cel_value.h" #include // IWYU pragma: keep - Needed for PyObject #include // IWYU pragma: keep @@ -36,12 +36,12 @@ #include "common/type.h" #include "common/value.h" #include "common/value_kind.h" -#include "py_cel_arena.h" -#include "py_cel_env_internal.h" -#include "py_cel_type.h" -#include "py_cel_value_provider.h" -#include "py_error_status.h" -#include "status_macros.h" +#include "py_cel/py_cel_arena.h" +#include "py_cel/py_cel_env_internal.h" +#include "py_cel/py_cel_type.h" +#include "py_cel/py_cel_value_provider.h" +#include "py_cel/py_error_status.h" +#include "py_cel/status_macros.h" #include "google/protobuf/arena.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/message.h" diff --git a/py_cel_value.h b/py_cel/py_cel_value.h similarity index 99% rename from py_cel_value.h rename to py_cel/py_cel_value.h index aeeef8b..c436c89 100644 --- a/py_cel_value.h +++ b/py_cel/py_cel_value.h @@ -24,7 +24,7 @@ #include "absl/functional/function_ref.h" #include "absl/status/statusor.h" #include "common/value.h" -#include "py_cel_type.h" +#include "py_cel/py_cel_type.h" #include "google/protobuf/arena.h" #include diff --git a/py_cel_value_provider.h b/py_cel/py_cel_value_provider.h similarity index 97% rename from py_cel_value_provider.h rename to py_cel/py_cel_value_provider.h index fa564e3..fa21878 100644 --- a/py_cel_value_provider.h +++ b/py_cel/py_cel_value_provider.h @@ -22,7 +22,7 @@ #include #include "common/value.h" -#include "py_cel_env_internal.h" +#include "py_cel/py_cel_env_internal.h" #include "google/protobuf/arena.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/message.h" diff --git a/py_descriptor_database.cc b/py_cel/py_descriptor_database.cc similarity index 98% rename from py_descriptor_database.cc rename to py_cel/py_descriptor_database.cc index 8f7df2b..9eb8924 100644 --- a/py_descriptor_database.cc +++ b/py_cel/py_descriptor_database.cc @@ -15,7 +15,7 @@ */ #define PY_SSIZE_T_CLEAN -#include "py_descriptor_database.h" +#include "py_cel/py_descriptor_database.h" #include // IWYU pragma: keep - Needed for PyObject @@ -23,7 +23,7 @@ #include "absl/log/absl_check.h" #include "common/minimal_descriptor_pool.h" -#include "py_error_status.h" +#include "py_cel/py_error_status.h" #include "google/protobuf/descriptor.h" namespace cel_python { diff --git a/py_descriptor_database.h b/py_cel/py_descriptor_database.h similarity index 100% rename from py_descriptor_database.h rename to py_cel/py_descriptor_database.h diff --git a/py_error_status.cc b/py_cel/py_error_status.cc similarity index 99% rename from py_error_status.cc rename to py_cel/py_error_status.cc index 78ec7b3..0c463b2 100644 --- a/py_error_status.cc +++ b/py_cel/py_error_status.cc @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "py_error_status.h" +#include "py_cel/py_error_status.h" #include // IWYU pragma: keep - Needed for PyObject diff --git a/py_error_status.h b/py_cel/py_error_status.h similarity index 97% rename from py_error_status.h rename to py_cel/py_error_status.h index d4f7bdd..2ac8d83 100644 --- a/py_error_status.h +++ b/py_cel/py_error_status.h @@ -22,7 +22,7 @@ #include "absl/status/status.h" #include "absl/status/statusor.h" -#include "status_macros.h" +#include "py_cel/status_macros.h" #include #define CEL_PYTHON_ASSIGN_OR_RETURN(...) \ diff --git a/py_message_factory.cc b/py_cel/py_message_factory.cc similarity index 99% rename from py_message_factory.cc rename to py_cel/py_message_factory.cc index ef0f641..96a2fd8 100644 --- a/py_message_factory.cc +++ b/py_cel/py_message_factory.cc @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "py_message_factory.h" +#include "py_cel/py_message_factory.h" #include // IWYU pragma: keep - Needed for PyObject diff --git a/py_message_factory.h b/py_cel/py_message_factory.h similarity index 100% rename from py_message_factory.h rename to py_cel/py_message_factory.h diff --git a/status_macros.h b/py_cel/status_macros.h similarity index 100% rename from status_macros.h rename to py_cel/status_macros.h diff --git a/release/README.md b/release/README.md new file mode 100644 index 0000000..326bbb1 --- /dev/null +++ b/release/README.md @@ -0,0 +1,45 @@ +To build the py_cel wheel locally for testing: + +- Install `cibuildwheel` + + ``` + pip install cibuildwheel + ``` + +- [Optional] Use `podman` + + If you are using podman instead of docker, run + + ``` + export CIBW_CONTAINER_ENGINE="podman" + ``` + +- Navigate to the source directory + + Go to the parent directory of the one containing this file, e.g. + + ``` + cd py-cel-git-repo + ``` + +- Update release version + Edit `release/build_wheel.sh`: update `VERSION` + +- Run `cibuildwheel` + + ``` + cibuildwheel + ``` + +- Install the resulting wheel: + + ``` + pip uninstall py-cel + pip install wheelhouse/py_cel-*.whl + ``` + +- Verify that the wheel is working correctly + + ``` + python release/py_cel_basic_test.py + ``` \ No newline at end of file diff --git a/release/build_wheel.sh b/release/build_wheel.sh new file mode 100755 index 0000000..c8af639 --- /dev/null +++ b/release/build_wheel.sh @@ -0,0 +1,42 @@ +#!/bin/bash +set -e + +# Version of pycel to build. +# IMPORTANT: Update this to the latest version before building. +VERSION="0.0.1" + + +# Find the installation directory of cibuildwheel +CIBWHEEL_DIR=$(pip show cibuildwheel | grep Location: | awk '{print $2}') +# Derive the cibuildwheel binary path from the site-packages directory. +# Example: "/.../lib/python3.11/site-packages" -> "/.../bin/cibuildwheel" +CIBWHEEL_BIN=$(echo "${CIBWHEEL_DIR}" | sed 's/\/lib\/python[0-9.]*\/site-packages/\/bin/')/cibuildwheel + +SRC_DIR=$(pwd) +echo "PyCEL source directory: ${SRC_DIR}" + +TMP_DIR=$(mktemp -d) +echo "Build directory: ${TMP_DIR}" + +pushd "${TMP_DIR}" + +cp -r "${SRC_DIR}"/{*,.*} . +cp "${SRC_DIR}"/release/* . + +# Substitute $VERSION in pyproject.toml with the value of VRS. +sed -i "s/\$VERSION/${VERSION}/g" pyproject.toml + +echo "Running cibuildwheel: ${CIBWHEEL_BIN}" +"${CIBWHEEL_BIN}" + +echo "Copying generated wheels to ${SRC_DIR}/wheelhouse" +mkdir -p "${SRC_DIR}"/wheelhouse +cp wheelhouse/py_cel-*.whl "${SRC_DIR}"/wheelhouse/ + +echo "Cleaning up build directory: ${TMP_DIR}" +rm -rf "${TMP_DIR}" + +popd + +echo "Successfully built py_cel wheels" +ls -l "${SRC_DIR}"/wheelhouse diff --git a/release/py_cel_basic_test.py b/release/py_cel_basic_test.py new file mode 100644 index 0000000..065cbe5 --- /dev/null +++ b/release/py_cel_basic_test.py @@ -0,0 +1,32 @@ +# 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. + +"""Basic tests for cel-python.""" + +import unittest +from py_cel import py_cel +from py_cel.ext import ext_math + + +class BasicTest(unittest.TestCase): + + def test_basic_test(self): + env = py_cel.NewEnv(extensions=[ext_math.ExtMath()]) + expr = env.compile("math.sqrt(2)") + res = expr.eval() + self.assertAlmostEqual(res.value(), 1.4142135623730951) + + +if __name__ == "__main__": + unittest.main() diff --git a/release/pyproject.toml b/release/pyproject.toml new file mode 100644 index 0000000..1740bd9 --- /dev/null +++ b/release/pyproject.toml @@ -0,0 +1,35 @@ +# 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. + +[project] +name = "py-cel" +# $VERSION is replaced with the desired version in build_wheel.sh. +version = "$VERSION" +description = "The CEL Python runtime" +requires-python = ">=3.11" +classifiers = [ + "Topic :: Software Development :: Interpreters", + "Topic :: Software Development :: Libraries :: Python Modules", +] +license = "Apache-2.0" + +[tool.setuptools.packages.find] +where = ["."] +exclude = ["wheelhouse*", "conformance*", "custom_ext*"] + +[tool.cibuildwheel] +build = "cp311-*" +skip = "*musllinux*" +before-all = "echo 'Installing bazelisk'; curl -LO https://github.com/bazelbuild/bazelisk/releases/download/v1.19.0/bazelisk-linux-amd64 && chmod +x bazelisk-linux-amd64 && mv bazelisk-linux-amd64 /usr/local/bin/bazel" +test-command = "python {project}/py_cel_basic_test.py" diff --git a/release/setup.py b/release/setup.py new file mode 100644 index 0000000..2f84830 --- /dev/null +++ b/release/setup.py @@ -0,0 +1,103 @@ +# 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. + +"""Helper for building py_cel with bazel for PyPI releases.""" + +import os +import shutil +import subprocess +import setuptools +import setuptools.command.build_ext + + +class BazelExtension(setuptools.Extension): + + def __init__(self, name, target): + super().__init__(name, sources=[]) + self.target = target + + +class BazelBuild(setuptools.command.build_ext.build_ext): + """Custom build_ext command to build extensions with bazel.""" + + def run(self): + # Ensure bazel is available + if shutil.which('bazel') is None: + raise RuntimeError('bazel must be installed to build the extensions.') + + for ext in self.extensions: + self.build_extension(ext) + + def build_extension(self, ext): + dest_path = self.get_ext_fullpath(ext.name) + dest_dir = os.path.dirname(dest_path) + os.makedirs(dest_dir, exist_ok=True) + + # Build with bazel + # Use --compilation_mode=opt for release builds + cmd = ['bazel', 'build', ext.target, '--compilation_mode=opt'] + print(f"Building {ext.name} with bazel: {' '.join(cmd)}") + subprocess.check_call(cmd) + + # Determine the output path of the bazel build + # We handle targets like //:py_cel and //ext:ext_math + rel_path = ext.target.lstrip('/').replace(':', '/') + if rel_path.startswith('/'): + rel_path = rel_path[1:] + + # Bazel output directory + bazel_bin = 'bazel-bin' + + # Attempt to find the generated shared library + # Suffixes can vary by platform + suffixes = ['.so', '.pyd', '.dylib'] + found = None + + candidate_base = os.path.join(bazel_bin, rel_path) + + for suffix in suffixes: + candidate = candidate_base + suffix + if os.path.exists(candidate): + found = candidate + break + + if not found: + # Fallback check for exact name match + # (less likely for extensions but possible) + if os.path.exists(candidate_base): + found = candidate_base + + if not found: + raise RuntimeError( + f'Could not find bazel output for {ext.target} at {candidate_base}.*' + ) + + print(f'Copying {found} to {dest_path}') + shutil.copyfile(found, dest_path) + + +setuptools.setup( + name='py-cel', + ext_modules=[ + BazelExtension('py_cel.py_cel', '//py_cel:py_cel'), + BazelExtension('py_cel.ext.ext_bindings', '//py_cel/ext:ext_bindings'), + BazelExtension('py_cel.ext.ext_encoders', '//py_cel/ext:ext_encoders'), + BazelExtension('py_cel.ext.ext_math', '//py_cel/ext:ext_math'), + BazelExtension('py_cel.ext.ext_optional', '//py_cel/ext:ext_optional'), + BazelExtension('py_cel.ext.ext_proto', '//py_cel/ext:ext_proto'), + BazelExtension('py_cel.ext.ext_string', '//py_cel/ext:ext_string'), + ], + cmdclass={'build_ext': BazelBuild}, + zip_safe=False, +)