From 74bb85b000764847461f3da6683a65cd6e1c1729 Mon Sep 17 00:00:00 2001 From: Steve Ayers Date: Wed, 14 May 2025 16:15:24 -0400 Subject: [PATCH 1/7] Download file --- Makefile | 6 + string_ext.textproto | 1974 ++++++++++++++++++++++++++++++++++++++++++ tests/format_test.py | 0 3 files changed, 1980 insertions(+) create mode 100644 string_ext.textproto create mode 100644 tests/format_test.py diff --git a/Makefile b/Makefile index f5bc54e5..8870cfa1 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,8 @@ ADD_LICENSE_HEADER := $(BIN)/license-header \ # This version should be kept in sync with the version in buf.yaml PROTOVALIDATE_VERSION ?= v0.11.0 +CEL_SPEC_VERSION ?= v0.24.0 + .PHONY: help help: ## Describe useful make targets @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "%-15s %s\n", $$1, $$2}' @@ -69,6 +71,10 @@ checkgenerate: generate @# Used in CI to verify that `make generate` doesn't produce a diff. test -z "$$(git status --porcelain | tee /dev/stderr)" +.PHONY: gettextproto +gettextproto: + curl -fsSL -o .tmp/string_ext_$(CEL_SPEC_VERSION).textproto https://raw.githubusercontent.com/google/cel-spec/refs/tags/$(CEL_SPEC_VERSION)/tests/simple/testdata/string_ext.textproto + $(BIN): @mkdir -p $(BIN) diff --git a/string_ext.textproto b/string_ext.textproto new file mode 100644 index 00000000..2d61084f --- /dev/null +++ b/string_ext.textproto @@ -0,0 +1,1974 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + cel-spec/tests/simple/testdata/string_ext.textproto at v0.24.0 · google/cel-spec · GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ Skip to content + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + + + + +
+ + + + + + + + + +
+
+
+ + + + + + + + + + + + +
+ +
+ +
+ +
+ + + + / + + cel-spec + + + Public +
+ + +
+ +
+ + +
+
+ +
+
+ + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + +
+
+ + + + +
+ +
+ +
+
+ +
+ +
+

Footer

+ + + + +
+
+ + + + + © 2025 GitHub, Inc. + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + diff --git a/tests/format_test.py b/tests/format_test.py new file mode 100644 index 00000000..e69de29b From 49684a1b780e094bed558db1e244e518c1ee3bb9 Mon Sep 17 00:00:00 2001 From: Steve Ayers Date: Thu, 15 May 2025 18:15:33 -0400 Subject: [PATCH 2/7] Format tests --- Makefile | 10 +- Pipfile | 1 + Pipfile.lock | 105 +- buf.lock | 8 +- gen/cel/expr/checked_pb2.py | 86 + gen/cel/expr/checked_pb2.pyi | 186 +++ .../conformance/conformance_service_pb2.py | 77 + .../conformance/conformance_service_pb2.pyi | 125 ++ gen/cel/expr/conformance/env_config_pb2.py | 70 + gen/cel/expr/conformance/env_config_pb2.pyi | 111 ++ gen/cel/expr/conformance/test/simple_pb2.py | 68 + gen/cel/expr/conformance/test/simple_pb2.pyi | 107 ++ gen/cel/expr/conformance/test/suite_pb2.py | 70 + gen/cel/expr/conformance/test/suite_pb2.pyi | 103 ++ gen/cel/expr/eval_pb2.py | 63 + gen/cel/expr/eval_pb2.pyi | 70 + gen/cel/expr/explain_pb2.py | 56 + gen/cel/expr/explain_pb2.pyi | 37 + gen/cel/expr/syntax_pb2.py | 92 ++ gen/cel/expr/syntax_pb2.pyi | 200 +++ gen/cel/expr/value_pb2.py | 61 + gen/cel/expr/value_pb2.pyi | 78 + protovalidate/internal/string_format.py | 2 +- tests/format_test.py | 79 + tests/testdata/string_ext_v0.24.0.textproto | 1417 +++++++++++++++++ 25 files changed, 3272 insertions(+), 10 deletions(-) create mode 100644 gen/cel/expr/checked_pb2.py create mode 100644 gen/cel/expr/checked_pb2.pyi create mode 100644 gen/cel/expr/conformance/conformance_service_pb2.py create mode 100644 gen/cel/expr/conformance/conformance_service_pb2.pyi create mode 100644 gen/cel/expr/conformance/env_config_pb2.py create mode 100644 gen/cel/expr/conformance/env_config_pb2.pyi create mode 100644 gen/cel/expr/conformance/test/simple_pb2.py create mode 100644 gen/cel/expr/conformance/test/simple_pb2.pyi create mode 100644 gen/cel/expr/conformance/test/suite_pb2.py create mode 100644 gen/cel/expr/conformance/test/suite_pb2.pyi create mode 100644 gen/cel/expr/eval_pb2.py create mode 100644 gen/cel/expr/eval_pb2.pyi create mode 100644 gen/cel/expr/explain_pb2.py create mode 100644 gen/cel/expr/explain_pb2.pyi create mode 100644 gen/cel/expr/syntax_pb2.py create mode 100644 gen/cel/expr/syntax_pb2.pyi create mode 100644 gen/cel/expr/value_pb2.py create mode 100644 gen/cel/expr/value_pb2.pyi create mode 100644 tests/testdata/string_ext_v0.24.0.textproto diff --git a/Makefile b/Makefile index 8870cfa1..dde5149a 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,7 @@ generate: $(BIN)/buf $(BIN)/license-header ## Regenerate code and license header rm -rf gen $(BIN)/buf generate buf.build/bufbuild/protovalidate:$(PROTOVALIDATE_VERSION) $(BIN)/buf generate buf.build/bufbuild/protovalidate-testing:$(PROTOVALIDATE_VERSION) + $(BIN)/buf generate buf.build/google/cel-spec:$(CEL_SPEC_VERSION) --exclude-path cel/expr/conformance/proto2 --exclude-path cel/expr/conformance/proto3 $(BIN)/buf generate $(ADD_LICENSE_HEADER) @@ -48,7 +49,7 @@ format: install $(BIN)/license-header ## Format code pipenv run ruff check --fix protovalidate tests .PHONY: test -test: generate install ## Run unit tests +test: generate install gettestdata ## Run unit tests pipenv run pytest .PHONY: conformance @@ -71,9 +72,10 @@ checkgenerate: generate @# Used in CI to verify that `make generate` doesn't produce a diff. test -z "$$(git status --porcelain | tee /dev/stderr)" -.PHONY: gettextproto -gettextproto: - curl -fsSL -o .tmp/string_ext_$(CEL_SPEC_VERSION).textproto https://raw.githubusercontent.com/google/cel-spec/refs/tags/$(CEL_SPEC_VERSION)/tests/simple/testdata/string_ext.textproto +.PHONY: gettestdata +gettestdata: generate + mkdir -p tests/testdata + curl -fsSL -o tests/testdata/string_ext_$(CEL_SPEC_VERSION).textproto https://raw.githubusercontent.com/google/cel-spec/refs/tags/$(CEL_SPEC_VERSION)/tests/simple/testdata/string_ext.textproto $(BIN): @mkdir -p $(BIN) diff --git a/Pipfile b/Pipfile index e8d48843..9f94ee47 100644 --- a/Pipfile +++ b/Pipfile @@ -6,6 +6,7 @@ name = "pypi" [packages] cel-python = "==0.2.*" protobuf = "==6.*" +pytest-subtests = "*" [dev-packages] pytest = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 1f812aac..c28c2192 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "f546975999f17cdad6eecce592ae22a1710abe4959bc3757e67e3fdd581548ae" + "sha256": "11e1248d6af4c57423db004bec0594a4bd4b8a432d50cd36f4ed4f8edc0a9020" }, "pipfile-spec": 6, "requires": { @@ -16,6 +16,14 @@ ] }, "default": { + "attrs": { + "hashes": [ + "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", + "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b" + ], + "markers": "python_version >= '3.8'", + "version": "==25.3.0" + }, "cel-python": { "hashes": [ "sha256:478ff73def7b39d51e6982f95d937a57c2b088c491c578fe5cecdbd79f476f60", @@ -25,6 +33,22 @@ "markers": "python_version >= '3.8' and python_version < '4.0'", "version": "==0.2.0" }, + "exceptiongroup": { + "hashes": [ + "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", + "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88" + ], + "markers": "python_version >= '3.7'", + "version": "==1.3.0" + }, + "iniconfig": { + "hashes": [ + "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", + "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760" + ], + "markers": "python_version >= '3.8'", + "version": "==2.1.0" + }, "jmespath": { "hashes": [ "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", @@ -40,6 +64,22 @@ ], "version": "==0.12.0" }, + "packaging": { + "hashes": [ + "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", + "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f" + ], + "markers": "python_version >= '3.8'", + "version": "==25.0" + }, + "pluggy": { + "hashes": [ + "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", + "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" + ], + "markers": "python_version >= '3.9'", + "version": "==1.6.0" + }, "protobuf": { "hashes": [ "sha256:0eb523c550a66a09a0c20f86dd554afbf4d32b02af34ae53d93268c1f73bc65b", @@ -56,6 +96,23 @@ "markers": "python_version >= '3.9'", "version": "==6.30.2" }, + "pytest": { + "hashes": [ + "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", + "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845" + ], + "markers": "python_version >= '3.8'", + "version": "==8.3.5" + }, + "pytest-subtests": { + "hashes": [ + "sha256:350c00adc36c3aff676a66135c81aed9e2182e15f6c3ec8721366918bbbf7580", + "sha256:e92a780d98b43118c28a16044ad9b841727bd7cb6a417073b38fd2d7ccdf052d" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==0.14.1" + }, "python-dateutil": { "hashes": [ "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", @@ -131,6 +188,44 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.17.0" }, + "tomli": { + "hashes": [ + "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", + "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", + "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", + "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", + "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", + "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", + "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", + "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", + "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", + "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", + "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", + "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", + "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", + "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", + "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", + "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", + "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", + "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", + "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", + "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", + "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", + "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", + "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", + "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", + "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", + "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", + "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", + "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", + "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", + "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", + "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", + "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7" + ], + "markers": "python_version >= '3.8'", + "version": "==2.2.1" + }, "types-python-dateutil": { "hashes": [ "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb", @@ -146,6 +241,14 @@ ], "markers": "python_version >= '3.9'", "version": "==6.0.12.20250402" + }, + "typing-extensions": { + "hashes": [ + "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", + "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef" + ], + "markers": "python_version >= '3.8'", + "version": "==4.13.2" } }, "develop": { diff --git a/buf.lock b/buf.lock index 9df54bc2..668d3a62 100644 --- a/buf.lock +++ b/buf.lock @@ -2,8 +2,8 @@ version: v2 deps: - name: buf.build/bufbuild/protovalidate - commit: 0409229c37804d6187ee0806eb4eebce - digest: b5:795db9d3a6e066dc61d99ac651fa7f136171869abe2211ca272dd84aada7bc4583b9508249fa5b61300a5b1fe8b6dbf6edbc088aa0345d1ccb9fff705e3d48e9 + commit: 7712fb530c574b95bc1d57c0877543c3 + digest: b5:b3e9c9428384357e3b73e4d5a4614328b0a4b1595b10163bbe9483fa16204749274c41797bd49b0d716479c855aa35c1172a94f471fa120ba8369637fd138829 - name: buf.build/bufbuild/protovalidate-testing - commit: 5acbe1f3c8f24ced9466b9ccccad4cb0 - digest: b5:5e9d54d19ce3d9d368f4b1b5ee4f20094d1c33d0f2dca19536339335c2e70d5ffedbd4fa28e290b59ecae0671c9d2dc20b6b8ebba5a9ac76cbf5f9d2af655ef4 + commit: 485aa672244b4befa63053fdc75d4a03 + digest: b5:82930441f8c3ad186d825d226536baec007b94d23fa974b9905abea7b891a43bd276969d7e8a27453b632cb8b1557079decdd3044306a81de34316d2707089be diff --git a/gen/cel/expr/checked_pb2.py b/gen/cel/expr/checked_pb2.py new file mode 100644 index 00000000..ceeac79b --- /dev/null +++ b/gen/cel/expr/checked_pb2.py @@ -0,0 +1,86 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: cel/expr/checked.proto +# Protobuf Python Version: 6.30.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 30, + 1, + '', + 'cel/expr/checked.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from cel.expr import syntax_pb2 as cel_dot_expr_dot_syntax__pb2 +from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 +from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16\x63\x65l/expr/checked.proto\x12\x08\x63\x65l.expr\x1a\x15\x63\x65l/expr/syntax.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1cgoogle/protobuf/struct.proto\"\xba\x03\n\x0b\x43heckedExpr\x12L\n\rreference_map\x18\x02 \x03(\x0b\x32\'.cel.expr.CheckedExpr.ReferenceMapEntryR\x0creferenceMap\x12=\n\x08type_map\x18\x03 \x03(\x0b\x32\".cel.expr.CheckedExpr.TypeMapEntryR\x07typeMap\x12\x35\n\x0bsource_info\x18\x05 \x01(\x0b\x32\x14.cel.expr.SourceInfoR\nsourceInfo\x12!\n\x0c\x65xpr_version\x18\x06 \x01(\tR\x0b\x65xprVersion\x12\"\n\x04\x65xpr\x18\x04 \x01(\x0b\x32\x0e.cel.expr.ExprR\x04\x65xpr\x1aT\n\x11ReferenceMapEntry\x12\x10\n\x03key\x18\x01 \x01(\x03R\x03key\x12)\n\x05value\x18\x02 \x01(\x0b\x32\x13.cel.expr.ReferenceR\x05value:\x02\x38\x01\x1aJ\n\x0cTypeMapEntry\x12\x10\n\x03key\x18\x01 \x01(\x03R\x03key\x12$\n\x05value\x18\x02 \x01(\x0b\x32\x0e.cel.expr.TypeR\x05value:\x02\x38\x01\"\xe6\t\n\x04Type\x12*\n\x03\x64yn\x18\x01 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00R\x03\x64yn\x12\x30\n\x04null\x18\x02 \x01(\x0e\x32\x1a.google.protobuf.NullValueH\x00R\x04null\x12<\n\tprimitive\x18\x03 \x01(\x0e\x32\x1c.cel.expr.Type.PrimitiveTypeH\x00R\tprimitive\x12\x38\n\x07wrapper\x18\x04 \x01(\x0e\x32\x1c.cel.expr.Type.PrimitiveTypeH\x00R\x07wrapper\x12=\n\nwell_known\x18\x05 \x01(\x0e\x32\x1c.cel.expr.Type.WellKnownTypeH\x00R\twellKnown\x12\x36\n\tlist_type\x18\x06 \x01(\x0b\x32\x17.cel.expr.Type.ListTypeH\x00R\x08listType\x12\x33\n\x08map_type\x18\x07 \x01(\x0b\x32\x16.cel.expr.Type.MapTypeH\x00R\x07mapType\x12\x39\n\x08\x66unction\x18\x08 \x01(\x0b\x32\x1b.cel.expr.Type.FunctionTypeH\x00R\x08\x66unction\x12#\n\x0cmessage_type\x18\t \x01(\tH\x00R\x0bmessageType\x12\x1f\n\ntype_param\x18\n \x01(\tH\x00R\ttypeParam\x12$\n\x04type\x18\x0b \x01(\x0b\x32\x0e.cel.expr.TypeH\x00R\x04type\x12.\n\x05\x65rror\x18\x0c \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00R\x05\x65rror\x12\x42\n\rabstract_type\x18\x0e \x01(\x0b\x32\x1b.cel.expr.Type.AbstractTypeH\x00R\x0c\x61\x62stractType\x1a\x37\n\x08ListType\x12+\n\telem_type\x18\x01 \x01(\x0b\x32\x0e.cel.expr.TypeR\x08\x65lemType\x1a\x63\n\x07MapType\x12)\n\x08key_type\x18\x01 \x01(\x0b\x32\x0e.cel.expr.TypeR\x07keyType\x12-\n\nvalue_type\x18\x02 \x01(\x0b\x32\x0e.cel.expr.TypeR\tvalueType\x1al\n\x0c\x46unctionType\x12/\n\x0bresult_type\x18\x01 \x01(\x0b\x32\x0e.cel.expr.TypeR\nresultType\x12+\n\targ_types\x18\x02 \x03(\x0b\x32\x0e.cel.expr.TypeR\x08\x61rgTypes\x1a[\n\x0c\x41\x62stractType\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x37\n\x0fparameter_types\x18\x02 \x03(\x0b\x32\x0e.cel.expr.TypeR\x0eparameterTypes\"s\n\rPrimitiveType\x12\x1e\n\x1aPRIMITIVE_TYPE_UNSPECIFIED\x10\x00\x12\x08\n\x04\x42OOL\x10\x01\x12\t\n\x05INT64\x10\x02\x12\n\n\x06UINT64\x10\x03\x12\n\n\x06\x44OUBLE\x10\x04\x12\n\n\x06STRING\x10\x05\x12\t\n\x05\x42YTES\x10\x06\"V\n\rWellKnownType\x12\x1f\n\x1bWELL_KNOWN_TYPE_UNSPECIFIED\x10\x00\x12\x07\n\x03\x41NY\x10\x01\x12\r\n\tTIMESTAMP\x10\x02\x12\x0c\n\x08\x44URATION\x10\x03\x42\x0b\n\ttype_kind\"\xd4\x04\n\x04\x44\x65\x63l\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x30\n\x05ident\x18\x02 \x01(\x0b\x32\x18.cel.expr.Decl.IdentDeclH\x00R\x05ident\x12\x39\n\x08\x66unction\x18\x03 \x01(\x0b\x32\x1b.cel.expr.Decl.FunctionDeclH\x00R\x08\x66unction\x1ak\n\tIdentDecl\x12\"\n\x04type\x18\x01 \x01(\x0b\x32\x0e.cel.expr.TypeR\x04type\x12(\n\x05value\x18\x02 \x01(\x0b\x32\x12.cel.expr.ConstantR\x05value\x12\x10\n\x03\x64oc\x18\x03 \x01(\tR\x03\x64oc\x1a\xd0\x02\n\x0c\x46unctionDecl\x12\x42\n\toverloads\x18\x01 \x03(\x0b\x32$.cel.expr.Decl.FunctionDecl.OverloadR\toverloads\x12\x10\n\x03\x64oc\x18\x02 \x01(\tR\x03\x64oc\x1a\xe9\x01\n\x08Overload\x12\x1f\n\x0boverload_id\x18\x01 \x01(\tR\noverloadId\x12&\n\x06params\x18\x02 \x03(\x0b\x32\x0e.cel.expr.TypeR\x06params\x12\x1f\n\x0btype_params\x18\x03 \x03(\tR\ntypeParams\x12/\n\x0bresult_type\x18\x04 \x01(\x0b\x32\x0e.cel.expr.TypeR\nresultType\x12\x30\n\x14is_instance_function\x18\x05 \x01(\x08R\x12isInstanceFunction\x12\x10\n\x03\x64oc\x18\x06 \x01(\tR\x03\x64ocB\x0b\n\tdecl_kind\"j\n\tReference\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x1f\n\x0boverload_id\x18\x03 \x03(\tR\noverloadId\x12(\n\x05value\x18\x04 \x01(\x0b\x32\x12.cel.expr.ConstantR\x05valueBn\n\x0c\x63om.cel.exprB\x0c\x43heckedProtoP\x01Z\x0c\x63\x65l.dev/expr\xf8\x01\x01\xa2\x02\x03\x43\x45X\xaa\x02\x08\x43\x65l.Expr\xca\x02\x08\x43\x65l\\Expr\xe2\x02\x14\x43\x65l\\Expr\\GPBMetadata\xea\x02\tCel::Exprb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cel.expr.checked_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\014com.cel.exprB\014CheckedProtoP\001Z\014cel.dev/expr\370\001\001\242\002\003CEX\252\002\010Cel.Expr\312\002\010Cel\\Expr\342\002\024Cel\\Expr\\GPBMetadata\352\002\tCel::Expr' + _globals['_CHECKEDEXPR_REFERENCEMAPENTRY']._loaded_options = None + _globals['_CHECKEDEXPR_REFERENCEMAPENTRY']._serialized_options = b'8\001' + _globals['_CHECKEDEXPR_TYPEMAPENTRY']._loaded_options = None + _globals['_CHECKEDEXPR_TYPEMAPENTRY']._serialized_options = b'8\001' + _globals['_CHECKEDEXPR']._serialized_start=119 + _globals['_CHECKEDEXPR']._serialized_end=561 + _globals['_CHECKEDEXPR_REFERENCEMAPENTRY']._serialized_start=401 + _globals['_CHECKEDEXPR_REFERENCEMAPENTRY']._serialized_end=485 + _globals['_CHECKEDEXPR_TYPEMAPENTRY']._serialized_start=487 + _globals['_CHECKEDEXPR_TYPEMAPENTRY']._serialized_end=561 + _globals['_TYPE']._serialized_start=564 + _globals['_TYPE']._serialized_end=1818 + _globals['_TYPE_LISTTYPE']._serialized_start=1241 + _globals['_TYPE_LISTTYPE']._serialized_end=1296 + _globals['_TYPE_MAPTYPE']._serialized_start=1298 + _globals['_TYPE_MAPTYPE']._serialized_end=1397 + _globals['_TYPE_FUNCTIONTYPE']._serialized_start=1399 + _globals['_TYPE_FUNCTIONTYPE']._serialized_end=1507 + _globals['_TYPE_ABSTRACTTYPE']._serialized_start=1509 + _globals['_TYPE_ABSTRACTTYPE']._serialized_end=1600 + _globals['_TYPE_PRIMITIVETYPE']._serialized_start=1602 + _globals['_TYPE_PRIMITIVETYPE']._serialized_end=1717 + _globals['_TYPE_WELLKNOWNTYPE']._serialized_start=1719 + _globals['_TYPE_WELLKNOWNTYPE']._serialized_end=1805 + _globals['_DECL']._serialized_start=1821 + _globals['_DECL']._serialized_end=2417 + _globals['_DECL_IDENTDECL']._serialized_start=1958 + _globals['_DECL_IDENTDECL']._serialized_end=2065 + _globals['_DECL_FUNCTIONDECL']._serialized_start=2068 + _globals['_DECL_FUNCTIONDECL']._serialized_end=2404 + _globals['_DECL_FUNCTIONDECL_OVERLOAD']._serialized_start=2171 + _globals['_DECL_FUNCTIONDECL_OVERLOAD']._serialized_end=2404 + _globals['_REFERENCE']._serialized_start=2419 + _globals['_REFERENCE']._serialized_end=2525 +# @@protoc_insertion_point(module_scope) diff --git a/gen/cel/expr/checked_pb2.pyi b/gen/cel/expr/checked_pb2.pyi new file mode 100644 index 00000000..dd0108cd --- /dev/null +++ b/gen/cel/expr/checked_pb2.pyi @@ -0,0 +1,186 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +from cel.expr import syntax_pb2 as _syntax_pb2 +from google.protobuf import empty_pb2 as _empty_pb2 +from google.protobuf import struct_pb2 as _struct_pb2 +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from collections.abc import Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class CheckedExpr(_message.Message): + __slots__ = ("reference_map", "type_map", "source_info", "expr_version", "expr") + class ReferenceMapEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: int + value: Reference + def __init__(self, key: _Optional[int] = ..., value: _Optional[_Union[Reference, _Mapping]] = ...) -> None: ... + class TypeMapEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: int + value: Type + def __init__(self, key: _Optional[int] = ..., value: _Optional[_Union[Type, _Mapping]] = ...) -> None: ... + REFERENCE_MAP_FIELD_NUMBER: _ClassVar[int] + TYPE_MAP_FIELD_NUMBER: _ClassVar[int] + SOURCE_INFO_FIELD_NUMBER: _ClassVar[int] + EXPR_VERSION_FIELD_NUMBER: _ClassVar[int] + EXPR_FIELD_NUMBER: _ClassVar[int] + reference_map: _containers.MessageMap[int, Reference] + type_map: _containers.MessageMap[int, Type] + source_info: _syntax_pb2.SourceInfo + expr_version: str + expr: _syntax_pb2.Expr + def __init__(self, reference_map: _Optional[_Mapping[int, Reference]] = ..., type_map: _Optional[_Mapping[int, Type]] = ..., source_info: _Optional[_Union[_syntax_pb2.SourceInfo, _Mapping]] = ..., expr_version: _Optional[str] = ..., expr: _Optional[_Union[_syntax_pb2.Expr, _Mapping]] = ...) -> None: ... + +class Type(_message.Message): + __slots__ = ("dyn", "null", "primitive", "wrapper", "well_known", "list_type", "map_type", "function", "message_type", "type_param", "type", "error", "abstract_type") + class PrimitiveType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + PRIMITIVE_TYPE_UNSPECIFIED: _ClassVar[Type.PrimitiveType] + BOOL: _ClassVar[Type.PrimitiveType] + INT64: _ClassVar[Type.PrimitiveType] + UINT64: _ClassVar[Type.PrimitiveType] + DOUBLE: _ClassVar[Type.PrimitiveType] + STRING: _ClassVar[Type.PrimitiveType] + BYTES: _ClassVar[Type.PrimitiveType] + PRIMITIVE_TYPE_UNSPECIFIED: Type.PrimitiveType + BOOL: Type.PrimitiveType + INT64: Type.PrimitiveType + UINT64: Type.PrimitiveType + DOUBLE: Type.PrimitiveType + STRING: Type.PrimitiveType + BYTES: Type.PrimitiveType + class WellKnownType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + WELL_KNOWN_TYPE_UNSPECIFIED: _ClassVar[Type.WellKnownType] + ANY: _ClassVar[Type.WellKnownType] + TIMESTAMP: _ClassVar[Type.WellKnownType] + DURATION: _ClassVar[Type.WellKnownType] + WELL_KNOWN_TYPE_UNSPECIFIED: Type.WellKnownType + ANY: Type.WellKnownType + TIMESTAMP: Type.WellKnownType + DURATION: Type.WellKnownType + class ListType(_message.Message): + __slots__ = ("elem_type",) + ELEM_TYPE_FIELD_NUMBER: _ClassVar[int] + elem_type: Type + def __init__(self, elem_type: _Optional[_Union[Type, _Mapping]] = ...) -> None: ... + class MapType(_message.Message): + __slots__ = ("key_type", "value_type") + KEY_TYPE_FIELD_NUMBER: _ClassVar[int] + VALUE_TYPE_FIELD_NUMBER: _ClassVar[int] + key_type: Type + value_type: Type + def __init__(self, key_type: _Optional[_Union[Type, _Mapping]] = ..., value_type: _Optional[_Union[Type, _Mapping]] = ...) -> None: ... + class FunctionType(_message.Message): + __slots__ = ("result_type", "arg_types") + RESULT_TYPE_FIELD_NUMBER: _ClassVar[int] + ARG_TYPES_FIELD_NUMBER: _ClassVar[int] + result_type: Type + arg_types: _containers.RepeatedCompositeFieldContainer[Type] + def __init__(self, result_type: _Optional[_Union[Type, _Mapping]] = ..., arg_types: _Optional[_Iterable[_Union[Type, _Mapping]]] = ...) -> None: ... + class AbstractType(_message.Message): + __slots__ = ("name", "parameter_types") + NAME_FIELD_NUMBER: _ClassVar[int] + PARAMETER_TYPES_FIELD_NUMBER: _ClassVar[int] + name: str + parameter_types: _containers.RepeatedCompositeFieldContainer[Type] + def __init__(self, name: _Optional[str] = ..., parameter_types: _Optional[_Iterable[_Union[Type, _Mapping]]] = ...) -> None: ... + DYN_FIELD_NUMBER: _ClassVar[int] + NULL_FIELD_NUMBER: _ClassVar[int] + PRIMITIVE_FIELD_NUMBER: _ClassVar[int] + WRAPPER_FIELD_NUMBER: _ClassVar[int] + WELL_KNOWN_FIELD_NUMBER: _ClassVar[int] + LIST_TYPE_FIELD_NUMBER: _ClassVar[int] + MAP_TYPE_FIELD_NUMBER: _ClassVar[int] + FUNCTION_FIELD_NUMBER: _ClassVar[int] + MESSAGE_TYPE_FIELD_NUMBER: _ClassVar[int] + TYPE_PARAM_FIELD_NUMBER: _ClassVar[int] + TYPE_FIELD_NUMBER: _ClassVar[int] + ERROR_FIELD_NUMBER: _ClassVar[int] + ABSTRACT_TYPE_FIELD_NUMBER: _ClassVar[int] + dyn: _empty_pb2.Empty + null: _struct_pb2.NullValue + primitive: Type.PrimitiveType + wrapper: Type.PrimitiveType + well_known: Type.WellKnownType + list_type: Type.ListType + map_type: Type.MapType + function: Type.FunctionType + message_type: str + type_param: str + type: Type + error: _empty_pb2.Empty + abstract_type: Type.AbstractType + def __init__(self, dyn: _Optional[_Union[_empty_pb2.Empty, _Mapping]] = ..., null: _Optional[_Union[_struct_pb2.NullValue, str]] = ..., primitive: _Optional[_Union[Type.PrimitiveType, str]] = ..., wrapper: _Optional[_Union[Type.PrimitiveType, str]] = ..., well_known: _Optional[_Union[Type.WellKnownType, str]] = ..., list_type: _Optional[_Union[Type.ListType, _Mapping]] = ..., map_type: _Optional[_Union[Type.MapType, _Mapping]] = ..., function: _Optional[_Union[Type.FunctionType, _Mapping]] = ..., message_type: _Optional[str] = ..., type_param: _Optional[str] = ..., type: _Optional[_Union[Type, _Mapping]] = ..., error: _Optional[_Union[_empty_pb2.Empty, _Mapping]] = ..., abstract_type: _Optional[_Union[Type.AbstractType, _Mapping]] = ...) -> None: ... + +class Decl(_message.Message): + __slots__ = ("name", "ident", "function") + class IdentDecl(_message.Message): + __slots__ = ("type", "value", "doc") + TYPE_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + DOC_FIELD_NUMBER: _ClassVar[int] + type: Type + value: _syntax_pb2.Constant + doc: str + def __init__(self, type: _Optional[_Union[Type, _Mapping]] = ..., value: _Optional[_Union[_syntax_pb2.Constant, _Mapping]] = ..., doc: _Optional[str] = ...) -> None: ... + class FunctionDecl(_message.Message): + __slots__ = ("overloads", "doc") + class Overload(_message.Message): + __slots__ = ("overload_id", "params", "type_params", "result_type", "is_instance_function", "doc") + OVERLOAD_ID_FIELD_NUMBER: _ClassVar[int] + PARAMS_FIELD_NUMBER: _ClassVar[int] + TYPE_PARAMS_FIELD_NUMBER: _ClassVar[int] + RESULT_TYPE_FIELD_NUMBER: _ClassVar[int] + IS_INSTANCE_FUNCTION_FIELD_NUMBER: _ClassVar[int] + DOC_FIELD_NUMBER: _ClassVar[int] + overload_id: str + params: _containers.RepeatedCompositeFieldContainer[Type] + type_params: _containers.RepeatedScalarFieldContainer[str] + result_type: Type + is_instance_function: bool + doc: str + def __init__(self, overload_id: _Optional[str] = ..., params: _Optional[_Iterable[_Union[Type, _Mapping]]] = ..., type_params: _Optional[_Iterable[str]] = ..., result_type: _Optional[_Union[Type, _Mapping]] = ..., is_instance_function: bool = ..., doc: _Optional[str] = ...) -> None: ... + OVERLOADS_FIELD_NUMBER: _ClassVar[int] + DOC_FIELD_NUMBER: _ClassVar[int] + overloads: _containers.RepeatedCompositeFieldContainer[Decl.FunctionDecl.Overload] + doc: str + def __init__(self, overloads: _Optional[_Iterable[_Union[Decl.FunctionDecl.Overload, _Mapping]]] = ..., doc: _Optional[str] = ...) -> None: ... + NAME_FIELD_NUMBER: _ClassVar[int] + IDENT_FIELD_NUMBER: _ClassVar[int] + FUNCTION_FIELD_NUMBER: _ClassVar[int] + name: str + ident: Decl.IdentDecl + function: Decl.FunctionDecl + def __init__(self, name: _Optional[str] = ..., ident: _Optional[_Union[Decl.IdentDecl, _Mapping]] = ..., function: _Optional[_Union[Decl.FunctionDecl, _Mapping]] = ...) -> None: ... + +class Reference(_message.Message): + __slots__ = ("name", "overload_id", "value") + NAME_FIELD_NUMBER: _ClassVar[int] + OVERLOAD_ID_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + name: str + overload_id: _containers.RepeatedScalarFieldContainer[str] + value: _syntax_pb2.Constant + def __init__(self, name: _Optional[str] = ..., overload_id: _Optional[_Iterable[str]] = ..., value: _Optional[_Union[_syntax_pb2.Constant, _Mapping]] = ...) -> None: ... diff --git a/gen/cel/expr/conformance/conformance_service_pb2.py b/gen/cel/expr/conformance/conformance_service_pb2.py new file mode 100644 index 00000000..56f48f9b --- /dev/null +++ b/gen/cel/expr/conformance/conformance_service_pb2.py @@ -0,0 +1,77 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: cel/expr/conformance/conformance_service.proto +# Protobuf Python Version: 6.30.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 30, + 1, + '', + 'cel/expr/conformance/conformance_service.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from cel.expr import checked_pb2 as cel_dot_expr_dot_checked__pb2 +from cel.expr import eval_pb2 as cel_dot_expr_dot_eval__pb2 +from cel.expr import syntax_pb2 as cel_dot_expr_dot_syntax__pb2 +from google.rpc import status_pb2 as google_dot_rpc_dot_status__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n.cel/expr/conformance/conformance_service.proto\x12\x14\x63\x65l.expr.conformance\x1a\x16\x63\x65l/expr/checked.proto\x1a\x13\x63\x65l/expr/eval.proto\x1a\x15\x63\x65l/expr/syntax.proto\x1a\x17google/rpc/status.proto\"\xa4\x01\n\x0cParseRequest\x12\x1d\n\ncel_source\x18\x01 \x01(\tR\tcelSource\x12%\n\x0esyntax_version\x18\x02 \x01(\tR\rsyntaxVersion\x12\'\n\x0fsource_location\x18\x03 \x01(\tR\x0esourceLocation\x12%\n\x0e\x64isable_macros\x18\x04 \x01(\x08R\rdisableMacros\"r\n\rParseResponse\x12\x35\n\x0bparsed_expr\x18\x01 \x01(\x0b\x32\x14.cel.expr.ParsedExprR\nparsedExpr\x12*\n\x06issues\x18\x02 \x03(\x0b\x32\x12.google.rpc.StatusR\x06issues\"\xac\x01\n\x0c\x43heckRequest\x12\x35\n\x0bparsed_expr\x18\x01 \x01(\x0b\x32\x14.cel.expr.ParsedExprR\nparsedExpr\x12)\n\x08type_env\x18\x02 \x03(\x0b\x32\x0e.cel.expr.DeclR\x07typeEnv\x12\x1c\n\tcontainer\x18\x03 \x01(\tR\tcontainer\x12\x1c\n\nno_std_env\x18\x04 \x01(\x08R\x08noStdEnv\"u\n\rCheckResponse\x12\x38\n\x0c\x63hecked_expr\x18\x01 \x01(\x0b\x32\x15.cel.expr.CheckedExprR\x0b\x63heckedExpr\x12*\n\x06issues\x18\x02 \x03(\x0b\x32\x12.google.rpc.StatusR\x06issues\"\xcc\x02\n\x0b\x45valRequest\x12\x37\n\x0bparsed_expr\x18\x01 \x01(\x0b\x32\x14.cel.expr.ParsedExprH\x00R\nparsedExpr\x12:\n\x0c\x63hecked_expr\x18\x02 \x01(\x0b\x32\x15.cel.expr.CheckedExprH\x00R\x0b\x63heckedExpr\x12K\n\x08\x62indings\x18\x03 \x03(\x0b\x32/.cel.expr.conformance.EvalRequest.BindingsEntryR\x08\x62indings\x12\x1c\n\tcontainer\x18\x04 \x01(\tR\tcontainer\x1aP\n\rBindingsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12)\n\x05value\x18\x02 \x01(\x0b\x32\x13.cel.expr.ExprValueR\x05value:\x02\x38\x01\x42\x0b\n\texpr_kind\"g\n\x0c\x45valResponse\x12+\n\x06result\x18\x01 \x01(\x0b\x32\x13.cel.expr.ExprValueR\x06result\x12*\n\x06issues\x18\x02 \x03(\x0b\x32\x12.google.rpc.StatusR\x06issues\"p\n\x0eSourcePosition\x12\x1a\n\x08location\x18\x01 \x01(\tR\x08location\x12\x16\n\x06offset\x18\x02 \x01(\x05R\x06offset\x12\x12\n\x04line\x18\x03 \x01(\x05R\x04line\x12\x16\n\x06\x63olumn\x18\x04 \x01(\x05R\x06\x63olumn\"\xf8\x01\n\x0cIssueDetails\x12G\n\x08severity\x18\x01 \x01(\x0e\x32+.cel.expr.conformance.IssueDetails.SeverityR\x08severity\x12@\n\x08position\x18\x02 \x01(\x0b\x32$.cel.expr.conformance.SourcePositionR\x08position\x12\x0e\n\x02id\x18\x03 \x01(\x03R\x02id\"M\n\x08Severity\x12\x18\n\x14SEVERITY_UNSPECIFIED\x10\x00\x12\x0f\n\x0b\x44\x45PRECATION\x10\x01\x12\x0b\n\x07WARNING\x10\x02\x12\t\n\x05\x45RROR\x10\x03\x32\x8d\x02\n\x12\x43onformanceService\x12R\n\x05Parse\x12\".cel.expr.conformance.ParseRequest\x1a#.cel.expr.conformance.ParseResponse\"\x00\x12R\n\x05\x43heck\x12\".cel.expr.conformance.CheckRequest\x1a#.cel.expr.conformance.CheckResponse\"\x00\x12O\n\x04\x45val\x12!.cel.expr.conformance.EvalRequest\x1a\".cel.expr.conformance.EvalResponse\"\x00\x42\xc2\x01\n\x18\x63om.cel.expr.conformanceB\x17\x43onformanceServiceProtoP\x01Z\x18\x63\x65l.dev/expr/conformance\xf8\x01\x01\xa2\x02\x03\x43\x45\x43\xaa\x02\x14\x43\x65l.Expr.Conformance\xca\x02\x14\x43\x65l\\Expr\\Conformance\xe2\x02 Cel\\Expr\\Conformance\\GPBMetadata\xea\x02\x16\x43\x65l::Expr::Conformanceb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cel.expr.conformance.conformance_service_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\030com.cel.expr.conformanceB\027ConformanceServiceProtoP\001Z\030cel.dev/expr/conformance\370\001\001\242\002\003CEC\252\002\024Cel.Expr.Conformance\312\002\024Cel\\Expr\\Conformance\342\002 Cel\\Expr\\Conformance\\GPBMetadata\352\002\026Cel::Expr::Conformance' + _globals['_EVALREQUEST_BINDINGSENTRY']._loaded_options = None + _globals['_EVALREQUEST_BINDINGSENTRY']._serialized_options = b'8\001' + _globals['_PARSEREQUEST']._serialized_start=166 + _globals['_PARSEREQUEST']._serialized_end=330 + _globals['_PARSERESPONSE']._serialized_start=332 + _globals['_PARSERESPONSE']._serialized_end=446 + _globals['_CHECKREQUEST']._serialized_start=449 + _globals['_CHECKREQUEST']._serialized_end=621 + _globals['_CHECKRESPONSE']._serialized_start=623 + _globals['_CHECKRESPONSE']._serialized_end=740 + _globals['_EVALREQUEST']._serialized_start=743 + _globals['_EVALREQUEST']._serialized_end=1075 + _globals['_EVALREQUEST_BINDINGSENTRY']._serialized_start=982 + _globals['_EVALREQUEST_BINDINGSENTRY']._serialized_end=1062 + _globals['_EVALRESPONSE']._serialized_start=1077 + _globals['_EVALRESPONSE']._serialized_end=1180 + _globals['_SOURCEPOSITION']._serialized_start=1182 + _globals['_SOURCEPOSITION']._serialized_end=1294 + _globals['_ISSUEDETAILS']._serialized_start=1297 + _globals['_ISSUEDETAILS']._serialized_end=1545 + _globals['_ISSUEDETAILS_SEVERITY']._serialized_start=1468 + _globals['_ISSUEDETAILS_SEVERITY']._serialized_end=1545 + _globals['_CONFORMANCESERVICE']._serialized_start=1548 + _globals['_CONFORMANCESERVICE']._serialized_end=1817 +# @@protoc_insertion_point(module_scope) diff --git a/gen/cel/expr/conformance/conformance_service_pb2.pyi b/gen/cel/expr/conformance/conformance_service_pb2.pyi new file mode 100644 index 00000000..38a004da --- /dev/null +++ b/gen/cel/expr/conformance/conformance_service_pb2.pyi @@ -0,0 +1,125 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +from cel.expr import checked_pb2 as _checked_pb2 +from cel.expr import eval_pb2 as _eval_pb2 +from cel.expr import syntax_pb2 as _syntax_pb2 +from google.rpc import status_pb2 as _status_pb2 +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from collections.abc import Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class ParseRequest(_message.Message): + __slots__ = ("cel_source", "syntax_version", "source_location", "disable_macros") + CEL_SOURCE_FIELD_NUMBER: _ClassVar[int] + SYNTAX_VERSION_FIELD_NUMBER: _ClassVar[int] + SOURCE_LOCATION_FIELD_NUMBER: _ClassVar[int] + DISABLE_MACROS_FIELD_NUMBER: _ClassVar[int] + cel_source: str + syntax_version: str + source_location: str + disable_macros: bool + def __init__(self, cel_source: _Optional[str] = ..., syntax_version: _Optional[str] = ..., source_location: _Optional[str] = ..., disable_macros: bool = ...) -> None: ... + +class ParseResponse(_message.Message): + __slots__ = ("parsed_expr", "issues") + PARSED_EXPR_FIELD_NUMBER: _ClassVar[int] + ISSUES_FIELD_NUMBER: _ClassVar[int] + parsed_expr: _syntax_pb2.ParsedExpr + issues: _containers.RepeatedCompositeFieldContainer[_status_pb2.Status] + def __init__(self, parsed_expr: _Optional[_Union[_syntax_pb2.ParsedExpr, _Mapping]] = ..., issues: _Optional[_Iterable[_Union[_status_pb2.Status, _Mapping]]] = ...) -> None: ... + +class CheckRequest(_message.Message): + __slots__ = ("parsed_expr", "type_env", "container", "no_std_env") + PARSED_EXPR_FIELD_NUMBER: _ClassVar[int] + TYPE_ENV_FIELD_NUMBER: _ClassVar[int] + CONTAINER_FIELD_NUMBER: _ClassVar[int] + NO_STD_ENV_FIELD_NUMBER: _ClassVar[int] + parsed_expr: _syntax_pb2.ParsedExpr + type_env: _containers.RepeatedCompositeFieldContainer[_checked_pb2.Decl] + container: str + no_std_env: bool + def __init__(self, parsed_expr: _Optional[_Union[_syntax_pb2.ParsedExpr, _Mapping]] = ..., type_env: _Optional[_Iterable[_Union[_checked_pb2.Decl, _Mapping]]] = ..., container: _Optional[str] = ..., no_std_env: bool = ...) -> None: ... + +class CheckResponse(_message.Message): + __slots__ = ("checked_expr", "issues") + CHECKED_EXPR_FIELD_NUMBER: _ClassVar[int] + ISSUES_FIELD_NUMBER: _ClassVar[int] + checked_expr: _checked_pb2.CheckedExpr + issues: _containers.RepeatedCompositeFieldContainer[_status_pb2.Status] + def __init__(self, checked_expr: _Optional[_Union[_checked_pb2.CheckedExpr, _Mapping]] = ..., issues: _Optional[_Iterable[_Union[_status_pb2.Status, _Mapping]]] = ...) -> None: ... + +class EvalRequest(_message.Message): + __slots__ = ("parsed_expr", "checked_expr", "bindings", "container") + class BindingsEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: _eval_pb2.ExprValue + def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[_eval_pb2.ExprValue, _Mapping]] = ...) -> None: ... + PARSED_EXPR_FIELD_NUMBER: _ClassVar[int] + CHECKED_EXPR_FIELD_NUMBER: _ClassVar[int] + BINDINGS_FIELD_NUMBER: _ClassVar[int] + CONTAINER_FIELD_NUMBER: _ClassVar[int] + parsed_expr: _syntax_pb2.ParsedExpr + checked_expr: _checked_pb2.CheckedExpr + bindings: _containers.MessageMap[str, _eval_pb2.ExprValue] + container: str + def __init__(self, parsed_expr: _Optional[_Union[_syntax_pb2.ParsedExpr, _Mapping]] = ..., checked_expr: _Optional[_Union[_checked_pb2.CheckedExpr, _Mapping]] = ..., bindings: _Optional[_Mapping[str, _eval_pb2.ExprValue]] = ..., container: _Optional[str] = ...) -> None: ... + +class EvalResponse(_message.Message): + __slots__ = ("result", "issues") + RESULT_FIELD_NUMBER: _ClassVar[int] + ISSUES_FIELD_NUMBER: _ClassVar[int] + result: _eval_pb2.ExprValue + issues: _containers.RepeatedCompositeFieldContainer[_status_pb2.Status] + def __init__(self, result: _Optional[_Union[_eval_pb2.ExprValue, _Mapping]] = ..., issues: _Optional[_Iterable[_Union[_status_pb2.Status, _Mapping]]] = ...) -> None: ... + +class SourcePosition(_message.Message): + __slots__ = ("location", "offset", "line", "column") + LOCATION_FIELD_NUMBER: _ClassVar[int] + OFFSET_FIELD_NUMBER: _ClassVar[int] + LINE_FIELD_NUMBER: _ClassVar[int] + COLUMN_FIELD_NUMBER: _ClassVar[int] + location: str + offset: int + line: int + column: int + def __init__(self, location: _Optional[str] = ..., offset: _Optional[int] = ..., line: _Optional[int] = ..., column: _Optional[int] = ...) -> None: ... + +class IssueDetails(_message.Message): + __slots__ = ("severity", "position", "id") + class Severity(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + SEVERITY_UNSPECIFIED: _ClassVar[IssueDetails.Severity] + DEPRECATION: _ClassVar[IssueDetails.Severity] + WARNING: _ClassVar[IssueDetails.Severity] + ERROR: _ClassVar[IssueDetails.Severity] + SEVERITY_UNSPECIFIED: IssueDetails.Severity + DEPRECATION: IssueDetails.Severity + WARNING: IssueDetails.Severity + ERROR: IssueDetails.Severity + SEVERITY_FIELD_NUMBER: _ClassVar[int] + POSITION_FIELD_NUMBER: _ClassVar[int] + ID_FIELD_NUMBER: _ClassVar[int] + severity: IssueDetails.Severity + position: SourcePosition + id: int + def __init__(self, severity: _Optional[_Union[IssueDetails.Severity, str]] = ..., position: _Optional[_Union[SourcePosition, _Mapping]] = ..., id: _Optional[int] = ...) -> None: ... diff --git a/gen/cel/expr/conformance/env_config_pb2.py b/gen/cel/expr/conformance/env_config_pb2.py new file mode 100644 index 00000000..2bd86286 --- /dev/null +++ b/gen/cel/expr/conformance/env_config_pb2.py @@ -0,0 +1,70 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: cel/expr/conformance/env_config.proto +# Protobuf Python Version: 6.30.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 30, + 1, + '', + 'cel/expr/conformance/env_config.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from cel.expr import checked_pb2 as cel_dot_expr_dot_checked__pb2 +from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 +from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n%cel/expr/conformance/env_config.proto\x12\x14\x63\x65l.expr.conformance\x1a\x16\x63\x65l/expr/checked.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a google/protobuf/descriptor.proto\"\xe1\x06\n\x0b\x45nvironment\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12 \n\x0b\x64\x65scription\x18\x02 \x01(\tR\x0b\x64\x65scription\x12\x1c\n\tcontainer\x18\x03 \x01(\tR\tcontainer\x12\x42\n\x07imports\x18\x04 \x03(\x0b\x32(.cel.expr.conformance.Environment.ImportR\x07imports\x12;\n\x06stdlib\x18\x05 \x01(\x0b\x32#.cel.expr.conformance.LibrarySubsetR\x06stdlib\x12?\n\nextensions\x18\x06 \x03(\x0b\x32\x1f.cel.expr.conformance.ExtensionR\nextensions\x12\\\n\x10\x63ontext_variable\x18\x07 \x01(\x0b\x32\x31.cel.expr.conformance.Environment.ContextVariableR\x0f\x63ontextVariable\x12\x32\n\x0c\x64\x65\x63larations\x18\x08 \x03(\x0b\x32\x0e.cel.expr.DeclR\x0c\x64\x65\x63larations\x12?\n\nvalidators\x18\t \x03(\x0b\x32\x1f.cel.expr.conformance.ValidatorR\nvalidators\x12\x39\n\x08\x66\x65\x61tures\x18\n \x03(\x0b\x32\x1d.cel.expr.conformance.FeatureR\x08\x66\x65\x61tures\x12I\n!disable_standard_cel_declarations\x18\x0b \x01(\x08R\x1e\x64isableStandardCelDeclarations\x12X\n\x16message_type_extension\x18\x0c \x01(\x0b\x32\".google.protobuf.FileDescriptorSetR\x14messageTypeExtension\x12;\n\x1a\x65nable_macro_call_tracking\x18\r \x01(\x08R\x17\x65nableMacroCallTracking\x1a\x1c\n\x06Import\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x1a.\n\x0f\x43ontextVariable\x12\x1b\n\ttype_name\x18\x01 \x01(\tR\x08typeName\"\xb7\x01\n\tValidator\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x43\n\x06\x63onfig\x18\x02 \x03(\x0b\x32+.cel.expr.conformance.Validator.ConfigEntryR\x06\x63onfig\x1aQ\n\x0b\x43onfigEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12,\n\x05value\x18\x02 \x01(\x0b\x32\x16.google.protobuf.ValueR\x05value:\x02\x38\x01\"7\n\x07\x46\x65\x61ture\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x18\n\x07\x65nabled\x18\x02 \x01(\x08R\x07\x65nabled\"9\n\tExtension\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x18\n\x07version\x18\x02 \x01(\tR\x07version\"\x9a\x02\n\rLibrarySubset\x12\x1a\n\x08\x64isabled\x18\x01 \x01(\x08R\x08\x64isabled\x12%\n\x0e\x64isable_macros\x18\x02 \x01(\x08R\rdisableMacros\x12%\n\x0einclude_macros\x18\x03 \x03(\tR\rincludeMacros\x12%\n\x0e\x65xclude_macros\x18\x04 \x03(\tR\rexcludeMacros\x12;\n\x11include_functions\x18\x05 \x03(\x0b\x32\x0e.cel.expr.DeclR\x10includeFunctions\x12;\n\x11\x65xclude_functions\x18\x06 \x03(\x0b\x32\x0e.cel.expr.DeclR\x10\x65xcludeFunctionsB\xb9\x01\n\x18\x63om.cel.expr.conformanceB\x0e\x45nvConfigProtoP\x01Z\x18\x63\x65l.dev/expr/conformance\xf8\x01\x01\xa2\x02\x03\x43\x45\x43\xaa\x02\x14\x43\x65l.Expr.Conformance\xca\x02\x14\x43\x65l\\Expr\\Conformance\xe2\x02 Cel\\Expr\\Conformance\\GPBMetadata\xea\x02\x16\x43\x65l::Expr::Conformanceb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cel.expr.conformance.env_config_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\030com.cel.expr.conformanceB\016EnvConfigProtoP\001Z\030cel.dev/expr/conformance\370\001\001\242\002\003CEC\252\002\024Cel.Expr.Conformance\312\002\024Cel\\Expr\\Conformance\342\002 Cel\\Expr\\Conformance\\GPBMetadata\352\002\026Cel::Expr::Conformance' + _globals['_VALIDATOR_CONFIGENTRY']._loaded_options = None + _globals['_VALIDATOR_CONFIGENTRY']._serialized_options = b'8\001' + _globals['_ENVIRONMENT']._serialized_start=152 + _globals['_ENVIRONMENT']._serialized_end=1017 + _globals['_ENVIRONMENT_IMPORT']._serialized_start=941 + _globals['_ENVIRONMENT_IMPORT']._serialized_end=969 + _globals['_ENVIRONMENT_CONTEXTVARIABLE']._serialized_start=971 + _globals['_ENVIRONMENT_CONTEXTVARIABLE']._serialized_end=1017 + _globals['_VALIDATOR']._serialized_start=1020 + _globals['_VALIDATOR']._serialized_end=1203 + _globals['_VALIDATOR_CONFIGENTRY']._serialized_start=1122 + _globals['_VALIDATOR_CONFIGENTRY']._serialized_end=1203 + _globals['_FEATURE']._serialized_start=1205 + _globals['_FEATURE']._serialized_end=1260 + _globals['_EXTENSION']._serialized_start=1262 + _globals['_EXTENSION']._serialized_end=1319 + _globals['_LIBRARYSUBSET']._serialized_start=1322 + _globals['_LIBRARYSUBSET']._serialized_end=1604 +# @@protoc_insertion_point(module_scope) diff --git a/gen/cel/expr/conformance/env_config_pb2.pyi b/gen/cel/expr/conformance/env_config_pb2.pyi new file mode 100644 index 00000000..47039086 --- /dev/null +++ b/gen/cel/expr/conformance/env_config_pb2.pyi @@ -0,0 +1,111 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +from cel.expr import checked_pb2 as _checked_pb2 +from google.protobuf import struct_pb2 as _struct_pb2 +from google.protobuf import descriptor_pb2 as _descriptor_pb2 +from google.protobuf.internal import containers as _containers +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from collections.abc import Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class Environment(_message.Message): + __slots__ = ("name", "description", "container", "imports", "stdlib", "extensions", "context_variable", "declarations", "validators", "features", "disable_standard_cel_declarations", "message_type_extension", "enable_macro_call_tracking") + class Import(_message.Message): + __slots__ = ("name",) + NAME_FIELD_NUMBER: _ClassVar[int] + name: str + def __init__(self, name: _Optional[str] = ...) -> None: ... + class ContextVariable(_message.Message): + __slots__ = ("type_name",) + TYPE_NAME_FIELD_NUMBER: _ClassVar[int] + type_name: str + def __init__(self, type_name: _Optional[str] = ...) -> None: ... + NAME_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + CONTAINER_FIELD_NUMBER: _ClassVar[int] + IMPORTS_FIELD_NUMBER: _ClassVar[int] + STDLIB_FIELD_NUMBER: _ClassVar[int] + EXTENSIONS_FIELD_NUMBER: _ClassVar[int] + CONTEXT_VARIABLE_FIELD_NUMBER: _ClassVar[int] + DECLARATIONS_FIELD_NUMBER: _ClassVar[int] + VALIDATORS_FIELD_NUMBER: _ClassVar[int] + FEATURES_FIELD_NUMBER: _ClassVar[int] + DISABLE_STANDARD_CEL_DECLARATIONS_FIELD_NUMBER: _ClassVar[int] + MESSAGE_TYPE_EXTENSION_FIELD_NUMBER: _ClassVar[int] + ENABLE_MACRO_CALL_TRACKING_FIELD_NUMBER: _ClassVar[int] + name: str + description: str + container: str + imports: _containers.RepeatedCompositeFieldContainer[Environment.Import] + stdlib: LibrarySubset + extensions: _containers.RepeatedCompositeFieldContainer[Extension] + context_variable: Environment.ContextVariable + declarations: _containers.RepeatedCompositeFieldContainer[_checked_pb2.Decl] + validators: _containers.RepeatedCompositeFieldContainer[Validator] + features: _containers.RepeatedCompositeFieldContainer[Feature] + disable_standard_cel_declarations: bool + message_type_extension: _descriptor_pb2.FileDescriptorSet + enable_macro_call_tracking: bool + def __init__(self, name: _Optional[str] = ..., description: _Optional[str] = ..., container: _Optional[str] = ..., imports: _Optional[_Iterable[_Union[Environment.Import, _Mapping]]] = ..., stdlib: _Optional[_Union[LibrarySubset, _Mapping]] = ..., extensions: _Optional[_Iterable[_Union[Extension, _Mapping]]] = ..., context_variable: _Optional[_Union[Environment.ContextVariable, _Mapping]] = ..., declarations: _Optional[_Iterable[_Union[_checked_pb2.Decl, _Mapping]]] = ..., validators: _Optional[_Iterable[_Union[Validator, _Mapping]]] = ..., features: _Optional[_Iterable[_Union[Feature, _Mapping]]] = ..., disable_standard_cel_declarations: bool = ..., message_type_extension: _Optional[_Union[_descriptor_pb2.FileDescriptorSet, _Mapping]] = ..., enable_macro_call_tracking: bool = ...) -> None: ... + +class Validator(_message.Message): + __slots__ = ("name", "config") + class ConfigEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: _struct_pb2.Value + def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[_struct_pb2.Value, _Mapping]] = ...) -> None: ... + NAME_FIELD_NUMBER: _ClassVar[int] + CONFIG_FIELD_NUMBER: _ClassVar[int] + name: str + config: _containers.MessageMap[str, _struct_pb2.Value] + def __init__(self, name: _Optional[str] = ..., config: _Optional[_Mapping[str, _struct_pb2.Value]] = ...) -> None: ... + +class Feature(_message.Message): + __slots__ = ("name", "enabled") + NAME_FIELD_NUMBER: _ClassVar[int] + ENABLED_FIELD_NUMBER: _ClassVar[int] + name: str + enabled: bool + def __init__(self, name: _Optional[str] = ..., enabled: bool = ...) -> None: ... + +class Extension(_message.Message): + __slots__ = ("name", "version") + NAME_FIELD_NUMBER: _ClassVar[int] + VERSION_FIELD_NUMBER: _ClassVar[int] + name: str + version: str + def __init__(self, name: _Optional[str] = ..., version: _Optional[str] = ...) -> None: ... + +class LibrarySubset(_message.Message): + __slots__ = ("disabled", "disable_macros", "include_macros", "exclude_macros", "include_functions", "exclude_functions") + DISABLED_FIELD_NUMBER: _ClassVar[int] + DISABLE_MACROS_FIELD_NUMBER: _ClassVar[int] + INCLUDE_MACROS_FIELD_NUMBER: _ClassVar[int] + EXCLUDE_MACROS_FIELD_NUMBER: _ClassVar[int] + INCLUDE_FUNCTIONS_FIELD_NUMBER: _ClassVar[int] + EXCLUDE_FUNCTIONS_FIELD_NUMBER: _ClassVar[int] + disabled: bool + disable_macros: bool + include_macros: _containers.RepeatedScalarFieldContainer[str] + exclude_macros: _containers.RepeatedScalarFieldContainer[str] + include_functions: _containers.RepeatedCompositeFieldContainer[_checked_pb2.Decl] + exclude_functions: _containers.RepeatedCompositeFieldContainer[_checked_pb2.Decl] + def __init__(self, disabled: bool = ..., disable_macros: bool = ..., include_macros: _Optional[_Iterable[str]] = ..., exclude_macros: _Optional[_Iterable[str]] = ..., include_functions: _Optional[_Iterable[_Union[_checked_pb2.Decl, _Mapping]]] = ..., exclude_functions: _Optional[_Iterable[_Union[_checked_pb2.Decl, _Mapping]]] = ...) -> None: ... diff --git a/gen/cel/expr/conformance/test/simple_pb2.py b/gen/cel/expr/conformance/test/simple_pb2.py new file mode 100644 index 00000000..eec7a56d --- /dev/null +++ b/gen/cel/expr/conformance/test/simple_pb2.py @@ -0,0 +1,68 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: cel/expr/conformance/test/simple.proto +# Protobuf Python Version: 6.30.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 30, + 1, + '', + 'cel/expr/conformance/test/simple.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from cel.expr import checked_pb2 as cel_dot_expr_dot_checked__pb2 +from cel.expr import eval_pb2 as cel_dot_expr_dot_eval__pb2 +from cel.expr import value_pb2 as cel_dot_expr_dot_value__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n&cel/expr/conformance/test/simple.proto\x12\x19\x63\x65l.expr.conformance.test\x1a\x16\x63\x65l/expr/checked.proto\x1a\x13\x63\x65l/expr/eval.proto\x1a\x14\x63\x65l/expr/value.proto\"\x8e\x01\n\x0eSimpleTestFile\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12 \n\x0b\x64\x65scription\x18\x02 \x01(\tR\x0b\x64\x65scription\x12\x46\n\x07section\x18\x03 \x03(\x0b\x32,.cel.expr.conformance.test.SimpleTestSectionR\x07section\"\x84\x01\n\x11SimpleTestSection\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12 \n\x0b\x64\x65scription\x18\x02 \x01(\tR\x0b\x64\x65scription\x12\x39\n\x04test\x18\x03 \x03(\x0b\x32%.cel.expr.conformance.test.SimpleTestR\x04test\"\xdd\x06\n\nSimpleTest\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12 \n\x0b\x64\x65scription\x18\x02 \x01(\tR\x0b\x64\x65scription\x12\x12\n\x04\x65xpr\x18\x03 \x01(\tR\x04\x65xpr\x12%\n\x0e\x64isable_macros\x18\x04 \x01(\x08R\rdisableMacros\x12#\n\rdisable_check\x18\x05 \x01(\x08R\x0c\x64isableCheck\x12\x1d\n\ncheck_only\x18\x0f \x01(\x08R\tcheckOnly\x12)\n\x08type_env\x18\x06 \x03(\x0b\x32\x0e.cel.expr.DeclR\x07typeEnv\x12\x1c\n\tcontainer\x18\r \x01(\tR\tcontainer\x12\x16\n\x06locale\x18\x0e \x01(\tR\x06locale\x12O\n\x08\x62indings\x18\x07 \x03(\x0b\x32\x33.cel.expr.conformance.test.SimpleTest.BindingsEntryR\x08\x62indings\x12\'\n\x05value\x18\x08 \x01(\x0b\x32\x0f.cel.expr.ValueH\x00R\x05value\x12K\n\x0ctyped_result\x18\x10 \x01(\x0b\x32&.cel.expr.conformance.test.TypedResultH\x00R\x0btypedResult\x12\x33\n\neval_error\x18\t \x01(\x0b\x32\x12.cel.expr.ErrorSetH\x00R\tevalError\x12T\n\x0f\x61ny_eval_errors\x18\n \x01(\x0b\x32*.cel.expr.conformance.test.ErrorSetMatcherH\x00R\ranyEvalErrors\x12\x30\n\x07unknown\x18\x0b \x01(\x0b\x32\x14.cel.expr.UnknownSetH\x00R\x07unknown\x12Q\n\x0c\x61ny_unknowns\x18\x0c \x01(\x0b\x32,.cel.expr.conformance.test.UnknownSetMatcherH\x00R\x0b\x61nyUnknowns\x1aP\n\rBindingsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12)\n\x05value\x18\x02 \x01(\x0b\x32\x13.cel.expr.ExprValueR\x05value:\x02\x38\x01\x42\x10\n\x0eresult_matcher\"i\n\x0bTypedResult\x12\'\n\x06result\x18\x01 \x01(\x0b\x32\x0f.cel.expr.ValueR\x06result\x12\x31\n\x0c\x64\x65\x64uced_type\x18\x02 \x01(\x0b\x32\x0e.cel.expr.TypeR\x0b\x64\x65\x64ucedType\"=\n\x0f\x45rrorSetMatcher\x12*\n\x06\x65rrors\x18\x01 \x03(\x0b\x32\x12.cel.expr.ErrorSetR\x06\x65rrors\"E\n\x11UnknownSetMatcher\x12\x30\n\x08unknowns\x18\x01 \x03(\x0b\x32\x14.cel.expr.UnknownSetR\x08unknownsB\xd6\x01\n\x1d\x63om.cel.expr.conformance.testB\x0bSimpleProtoP\x01Z\x1d\x63\x65l.dev/expr/conformance/test\xf8\x01\x01\xa2\x02\x04\x43\x45\x43T\xaa\x02\x19\x43\x65l.Expr.Conformance.Test\xca\x02\x19\x43\x65l\\Expr\\Conformance\\Test\xe2\x02%Cel\\Expr\\Conformance\\Test\\GPBMetadata\xea\x02\x1c\x43\x65l::Expr::Conformance::Testb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cel.expr.conformance.test.simple_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\035com.cel.expr.conformance.testB\013SimpleProtoP\001Z\035cel.dev/expr/conformance/test\370\001\001\242\002\004CECT\252\002\031Cel.Expr.Conformance.Test\312\002\031Cel\\Expr\\Conformance\\Test\342\002%Cel\\Expr\\Conformance\\Test\\GPBMetadata\352\002\034Cel::Expr::Conformance::Test' + _globals['_SIMPLETEST_BINDINGSENTRY']._loaded_options = None + _globals['_SIMPLETEST_BINDINGSENTRY']._serialized_options = b'8\001' + _globals['_SIMPLETESTFILE']._serialized_start=137 + _globals['_SIMPLETESTFILE']._serialized_end=279 + _globals['_SIMPLETESTSECTION']._serialized_start=282 + _globals['_SIMPLETESTSECTION']._serialized_end=414 + _globals['_SIMPLETEST']._serialized_start=417 + _globals['_SIMPLETEST']._serialized_end=1278 + _globals['_SIMPLETEST_BINDINGSENTRY']._serialized_start=1180 + _globals['_SIMPLETEST_BINDINGSENTRY']._serialized_end=1260 + _globals['_TYPEDRESULT']._serialized_start=1280 + _globals['_TYPEDRESULT']._serialized_end=1385 + _globals['_ERRORSETMATCHER']._serialized_start=1387 + _globals['_ERRORSETMATCHER']._serialized_end=1448 + _globals['_UNKNOWNSETMATCHER']._serialized_start=1450 + _globals['_UNKNOWNSETMATCHER']._serialized_end=1519 +# @@protoc_insertion_point(module_scope) diff --git a/gen/cel/expr/conformance/test/simple_pb2.pyi b/gen/cel/expr/conformance/test/simple_pb2.pyi new file mode 100644 index 00000000..8032507f --- /dev/null +++ b/gen/cel/expr/conformance/test/simple_pb2.pyi @@ -0,0 +1,107 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +from cel.expr import checked_pb2 as _checked_pb2 +from cel.expr import eval_pb2 as _eval_pb2 +from cel.expr import value_pb2 as _value_pb2 +from google.protobuf.internal import containers as _containers +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from collections.abc import Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class SimpleTestFile(_message.Message): + __slots__ = ("name", "description", "section") + NAME_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + SECTION_FIELD_NUMBER: _ClassVar[int] + name: str + description: str + section: _containers.RepeatedCompositeFieldContainer[SimpleTestSection] + def __init__(self, name: _Optional[str] = ..., description: _Optional[str] = ..., section: _Optional[_Iterable[_Union[SimpleTestSection, _Mapping]]] = ...) -> None: ... + +class SimpleTestSection(_message.Message): + __slots__ = ("name", "description", "test") + NAME_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + TEST_FIELD_NUMBER: _ClassVar[int] + name: str + description: str + test: _containers.RepeatedCompositeFieldContainer[SimpleTest] + def __init__(self, name: _Optional[str] = ..., description: _Optional[str] = ..., test: _Optional[_Iterable[_Union[SimpleTest, _Mapping]]] = ...) -> None: ... + +class SimpleTest(_message.Message): + __slots__ = ("name", "description", "expr", "disable_macros", "disable_check", "check_only", "type_env", "container", "locale", "bindings", "value", "typed_result", "eval_error", "any_eval_errors", "unknown", "any_unknowns") + class BindingsEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: _eval_pb2.ExprValue + def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[_eval_pb2.ExprValue, _Mapping]] = ...) -> None: ... + NAME_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + EXPR_FIELD_NUMBER: _ClassVar[int] + DISABLE_MACROS_FIELD_NUMBER: _ClassVar[int] + DISABLE_CHECK_FIELD_NUMBER: _ClassVar[int] + CHECK_ONLY_FIELD_NUMBER: _ClassVar[int] + TYPE_ENV_FIELD_NUMBER: _ClassVar[int] + CONTAINER_FIELD_NUMBER: _ClassVar[int] + LOCALE_FIELD_NUMBER: _ClassVar[int] + BINDINGS_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + TYPED_RESULT_FIELD_NUMBER: _ClassVar[int] + EVAL_ERROR_FIELD_NUMBER: _ClassVar[int] + ANY_EVAL_ERRORS_FIELD_NUMBER: _ClassVar[int] + UNKNOWN_FIELD_NUMBER: _ClassVar[int] + ANY_UNKNOWNS_FIELD_NUMBER: _ClassVar[int] + name: str + description: str + expr: str + disable_macros: bool + disable_check: bool + check_only: bool + type_env: _containers.RepeatedCompositeFieldContainer[_checked_pb2.Decl] + container: str + locale: str + bindings: _containers.MessageMap[str, _eval_pb2.ExprValue] + value: _value_pb2.Value + typed_result: TypedResult + eval_error: _eval_pb2.ErrorSet + any_eval_errors: ErrorSetMatcher + unknown: _eval_pb2.UnknownSet + any_unknowns: UnknownSetMatcher + def __init__(self, name: _Optional[str] = ..., description: _Optional[str] = ..., expr: _Optional[str] = ..., disable_macros: bool = ..., disable_check: bool = ..., check_only: bool = ..., type_env: _Optional[_Iterable[_Union[_checked_pb2.Decl, _Mapping]]] = ..., container: _Optional[str] = ..., locale: _Optional[str] = ..., bindings: _Optional[_Mapping[str, _eval_pb2.ExprValue]] = ..., value: _Optional[_Union[_value_pb2.Value, _Mapping]] = ..., typed_result: _Optional[_Union[TypedResult, _Mapping]] = ..., eval_error: _Optional[_Union[_eval_pb2.ErrorSet, _Mapping]] = ..., any_eval_errors: _Optional[_Union[ErrorSetMatcher, _Mapping]] = ..., unknown: _Optional[_Union[_eval_pb2.UnknownSet, _Mapping]] = ..., any_unknowns: _Optional[_Union[UnknownSetMatcher, _Mapping]] = ...) -> None: ... + +class TypedResult(_message.Message): + __slots__ = ("result", "deduced_type") + RESULT_FIELD_NUMBER: _ClassVar[int] + DEDUCED_TYPE_FIELD_NUMBER: _ClassVar[int] + result: _value_pb2.Value + deduced_type: _checked_pb2.Type + def __init__(self, result: _Optional[_Union[_value_pb2.Value, _Mapping]] = ..., deduced_type: _Optional[_Union[_checked_pb2.Type, _Mapping]] = ...) -> None: ... + +class ErrorSetMatcher(_message.Message): + __slots__ = ("errors",) + ERRORS_FIELD_NUMBER: _ClassVar[int] + errors: _containers.RepeatedCompositeFieldContainer[_eval_pb2.ErrorSet] + def __init__(self, errors: _Optional[_Iterable[_Union[_eval_pb2.ErrorSet, _Mapping]]] = ...) -> None: ... + +class UnknownSetMatcher(_message.Message): + __slots__ = ("unknowns",) + UNKNOWNS_FIELD_NUMBER: _ClassVar[int] + unknowns: _containers.RepeatedCompositeFieldContainer[_eval_pb2.UnknownSet] + def __init__(self, unknowns: _Optional[_Iterable[_Union[_eval_pb2.UnknownSet, _Mapping]]] = ...) -> None: ... diff --git a/gen/cel/expr/conformance/test/suite_pb2.py b/gen/cel/expr/conformance/test/suite_pb2.py new file mode 100644 index 00000000..d9706d19 --- /dev/null +++ b/gen/cel/expr/conformance/test/suite_pb2.py @@ -0,0 +1,70 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: cel/expr/conformance/test/suite.proto +# Protobuf Python Version: 6.30.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 30, + 1, + '', + 'cel/expr/conformance/test/suite.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from cel.expr import checked_pb2 as cel_dot_expr_dot_checked__pb2 +from cel.expr import eval_pb2 as cel_dot_expr_dot_eval__pb2 +from cel.expr import value_pb2 as cel_dot_expr_dot_value__pb2 +from cel.expr.conformance import env_config_pb2 as cel_dot_expr_dot_conformance_dot_env__config__pb2 +from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n%cel/expr/conformance/test/suite.proto\x12\x19\x63\x65l.expr.conformance.test\x1a\x16\x63\x65l/expr/checked.proto\x1a\x13\x63\x65l/expr/eval.proto\x1a\x14\x63\x65l/expr/value.proto\x1a%cel/expr/conformance/env_config.proto\x1a\x19google/protobuf/any.proto\"\x85\x01\n\tTestSuite\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12 \n\x0b\x64\x65scription\x18\x02 \x01(\tR\x0b\x64\x65scription\x12\x42\n\x08sections\x18\x03 \x03(\x0b\x32&.cel.expr.conformance.test.TestSectionR\x08sections\"~\n\x0bTestSection\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12 \n\x0b\x64\x65scription\x18\x02 \x01(\tR\x0b\x64\x65scription\x12\x39\n\x05tests\x18\x03 \x03(\x0b\x32#.cel.expr.conformance.test.TestCaseR\x05tests\"\x95\x04\n\x08TestCase\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12 \n\x0b\x64\x65scription\x18\x02 \x01(\tR\x0b\x64\x65scription\x12\x12\n\x04\x65xpr\x18\x03 \x01(\tR\x04\x65xpr\x12\x33\n\x03\x65nv\x18\x04 \x01(\x0b\x32!.cel.expr.conformance.EnvironmentR\x03\x65nv\x12\x44\n\x05input\x18\x05 \x03(\x0b\x32..cel.expr.conformance.test.TestCase.InputEntryR\x05input\x12L\n\rinput_context\x18\x06 \x01(\x0b\x32\'.cel.expr.conformance.test.InputContextR\x0cinputContext\x12=\n\x06output\x18\x07 \x01(\x0b\x32%.cel.expr.conformance.test.TestOutputR\x06output\x12\x31\n\x0c\x64\x65\x64uced_type\x18\x08 \x01(\x0b\x32\x0e.cel.expr.TypeR\x0b\x64\x65\x64ucedType\x12#\n\rdisable_check\x18\t \x01(\x08R\x0c\x64isableCheck\x1a_\n\nInputEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12;\n\x05value\x18\x02 \x01(\x0b\x32%.cel.expr.conformance.test.InputValueR\x05value:\x02\x38\x01\"\x8a\x01\n\x0cInputContext\x12?\n\x0f\x63ontext_message\x18\x01 \x01(\x0b\x32\x14.google.protobuf.AnyH\x00R\x0e\x63ontextMessage\x12#\n\x0c\x63ontext_expr\x18\x02 \x01(\tH\x00R\x0b\x63ontextExprB\x14\n\x12input_context_kind\"S\n\nInputValue\x12\'\n\x05value\x18\x01 \x01(\x0b\x32\x0f.cel.expr.ValueH\x00R\x05value\x12\x14\n\x04\x65xpr\x18\x02 \x01(\tH\x00R\x04\x65xprB\x06\n\x04kind\"\xdb\x01\n\nTestOutput\x12\x34\n\x0cresult_value\x18\x08 \x01(\x0b\x32\x0f.cel.expr.ValueH\x00R\x0bresultValue\x12!\n\x0bresult_expr\x18\t \x01(\tH\x00R\nresultExpr\x12\x33\n\neval_error\x18\n \x01(\x0b\x32\x12.cel.expr.ErrorSetH\x00R\tevalError\x12\x30\n\x07unknown\x18\x0b \x01(\x0b\x32\x14.cel.expr.UnknownSetH\x00R\x07unknownB\r\n\x0bresult_kindB\xd5\x01\n\x1d\x63om.cel.expr.conformance.testB\nSuiteProtoP\x01Z\x1d\x63\x65l.dev/expr/conformance/test\xf8\x01\x01\xa2\x02\x04\x43\x45\x43T\xaa\x02\x19\x43\x65l.Expr.Conformance.Test\xca\x02\x19\x43\x65l\\Expr\\Conformance\\Test\xe2\x02%Cel\\Expr\\Conformance\\Test\\GPBMetadata\xea\x02\x1c\x43\x65l::Expr::Conformance::Testb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cel.expr.conformance.test.suite_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\035com.cel.expr.conformance.testB\nSuiteProtoP\001Z\035cel.dev/expr/conformance/test\370\001\001\242\002\004CECT\252\002\031Cel.Expr.Conformance.Test\312\002\031Cel\\Expr\\Conformance\\Test\342\002%Cel\\Expr\\Conformance\\Test\\GPBMetadata\352\002\034Cel::Expr::Conformance::Test' + _globals['_TESTCASE_INPUTENTRY']._loaded_options = None + _globals['_TESTCASE_INPUTENTRY']._serialized_options = b'8\001' + _globals['_TESTSUITE']._serialized_start=202 + _globals['_TESTSUITE']._serialized_end=335 + _globals['_TESTSECTION']._serialized_start=337 + _globals['_TESTSECTION']._serialized_end=463 + _globals['_TESTCASE']._serialized_start=466 + _globals['_TESTCASE']._serialized_end=999 + _globals['_TESTCASE_INPUTENTRY']._serialized_start=904 + _globals['_TESTCASE_INPUTENTRY']._serialized_end=999 + _globals['_INPUTCONTEXT']._serialized_start=1002 + _globals['_INPUTCONTEXT']._serialized_end=1140 + _globals['_INPUTVALUE']._serialized_start=1142 + _globals['_INPUTVALUE']._serialized_end=1225 + _globals['_TESTOUTPUT']._serialized_start=1228 + _globals['_TESTOUTPUT']._serialized_end=1447 +# @@protoc_insertion_point(module_scope) diff --git a/gen/cel/expr/conformance/test/suite_pb2.pyi b/gen/cel/expr/conformance/test/suite_pb2.pyi new file mode 100644 index 00000000..fba21133 --- /dev/null +++ b/gen/cel/expr/conformance/test/suite_pb2.pyi @@ -0,0 +1,103 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +from cel.expr import checked_pb2 as _checked_pb2 +from cel.expr import eval_pb2 as _eval_pb2 +from cel.expr import value_pb2 as _value_pb2 +from cel.expr.conformance import env_config_pb2 as _env_config_pb2 +from google.protobuf import any_pb2 as _any_pb2 +from google.protobuf.internal import containers as _containers +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from collections.abc import Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class TestSuite(_message.Message): + __slots__ = ("name", "description", "sections") + NAME_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + SECTIONS_FIELD_NUMBER: _ClassVar[int] + name: str + description: str + sections: _containers.RepeatedCompositeFieldContainer[TestSection] + def __init__(self, name: _Optional[str] = ..., description: _Optional[str] = ..., sections: _Optional[_Iterable[_Union[TestSection, _Mapping]]] = ...) -> None: ... + +class TestSection(_message.Message): + __slots__ = ("name", "description", "tests") + NAME_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + TESTS_FIELD_NUMBER: _ClassVar[int] + name: str + description: str + tests: _containers.RepeatedCompositeFieldContainer[TestCase] + def __init__(self, name: _Optional[str] = ..., description: _Optional[str] = ..., tests: _Optional[_Iterable[_Union[TestCase, _Mapping]]] = ...) -> None: ... + +class TestCase(_message.Message): + __slots__ = ("name", "description", "expr", "env", "input", "input_context", "output", "deduced_type", "disable_check") + class InputEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: InputValue + def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[InputValue, _Mapping]] = ...) -> None: ... + NAME_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + EXPR_FIELD_NUMBER: _ClassVar[int] + ENV_FIELD_NUMBER: _ClassVar[int] + INPUT_FIELD_NUMBER: _ClassVar[int] + INPUT_CONTEXT_FIELD_NUMBER: _ClassVar[int] + OUTPUT_FIELD_NUMBER: _ClassVar[int] + DEDUCED_TYPE_FIELD_NUMBER: _ClassVar[int] + DISABLE_CHECK_FIELD_NUMBER: _ClassVar[int] + name: str + description: str + expr: str + env: _env_config_pb2.Environment + input: _containers.MessageMap[str, InputValue] + input_context: InputContext + output: TestOutput + deduced_type: _checked_pb2.Type + disable_check: bool + def __init__(self, name: _Optional[str] = ..., description: _Optional[str] = ..., expr: _Optional[str] = ..., env: _Optional[_Union[_env_config_pb2.Environment, _Mapping]] = ..., input: _Optional[_Mapping[str, InputValue]] = ..., input_context: _Optional[_Union[InputContext, _Mapping]] = ..., output: _Optional[_Union[TestOutput, _Mapping]] = ..., deduced_type: _Optional[_Union[_checked_pb2.Type, _Mapping]] = ..., disable_check: bool = ...) -> None: ... + +class InputContext(_message.Message): + __slots__ = ("context_message", "context_expr") + CONTEXT_MESSAGE_FIELD_NUMBER: _ClassVar[int] + CONTEXT_EXPR_FIELD_NUMBER: _ClassVar[int] + context_message: _any_pb2.Any + context_expr: str + def __init__(self, context_message: _Optional[_Union[_any_pb2.Any, _Mapping]] = ..., context_expr: _Optional[str] = ...) -> None: ... + +class InputValue(_message.Message): + __slots__ = ("value", "expr") + VALUE_FIELD_NUMBER: _ClassVar[int] + EXPR_FIELD_NUMBER: _ClassVar[int] + value: _value_pb2.Value + expr: str + def __init__(self, value: _Optional[_Union[_value_pb2.Value, _Mapping]] = ..., expr: _Optional[str] = ...) -> None: ... + +class TestOutput(_message.Message): + __slots__ = ("result_value", "result_expr", "eval_error", "unknown") + RESULT_VALUE_FIELD_NUMBER: _ClassVar[int] + RESULT_EXPR_FIELD_NUMBER: _ClassVar[int] + EVAL_ERROR_FIELD_NUMBER: _ClassVar[int] + UNKNOWN_FIELD_NUMBER: _ClassVar[int] + result_value: _value_pb2.Value + result_expr: str + eval_error: _eval_pb2.ErrorSet + unknown: _eval_pb2.UnknownSet + def __init__(self, result_value: _Optional[_Union[_value_pb2.Value, _Mapping]] = ..., result_expr: _Optional[str] = ..., eval_error: _Optional[_Union[_eval_pb2.ErrorSet, _Mapping]] = ..., unknown: _Optional[_Union[_eval_pb2.UnknownSet, _Mapping]] = ...) -> None: ... diff --git a/gen/cel/expr/eval_pb2.py b/gen/cel/expr/eval_pb2.py new file mode 100644 index 00000000..7d2280bf --- /dev/null +++ b/gen/cel/expr/eval_pb2.py @@ -0,0 +1,63 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: cel/expr/eval.proto +# Protobuf Python Version: 6.30.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 30, + 1, + '', + 'cel/expr/eval.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 +from cel.expr import value_pb2 as cel_dot_expr_dot_value__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x13\x63\x65l/expr/eval.proto\x12\x08\x63\x65l.expr\x1a\x19google/protobuf/any.proto\x1a\x14\x63\x65l/expr/value.proto\"\xa2\x01\n\tEvalState\x12+\n\x06values\x18\x01 \x03(\x0b\x32\x13.cel.expr.ExprValueR\x06values\x12\x34\n\x07results\x18\x03 \x03(\x0b\x32\x1a.cel.expr.EvalState.ResultR\x07results\x1a\x32\n\x06Result\x12\x12\n\x04\x65xpr\x18\x01 \x01(\x03R\x04\x65xpr\x12\x14\n\x05value\x18\x02 \x01(\x03R\x05value\"\x9a\x01\n\tExprValue\x12\'\n\x05value\x18\x01 \x01(\x0b\x32\x0f.cel.expr.ValueH\x00R\x05value\x12*\n\x05\x65rror\x18\x02 \x01(\x0b\x32\x12.cel.expr.ErrorSetH\x00R\x05\x65rror\x12\x30\n\x07unknown\x18\x03 \x01(\x0b\x32\x14.cel.expr.UnknownSetH\x00R\x07unknownB\x06\n\x04kind\"4\n\x08\x45rrorSet\x12(\n\x06\x65rrors\x18\x01 \x03(\x0b\x32\x10.cel.expr.StatusR\x06\x65rrors\"f\n\x06Status\x12\x12\n\x04\x63ode\x18\x01 \x01(\x05R\x04\x63ode\x12\x18\n\x07message\x18\x02 \x01(\tR\x07message\x12.\n\x07\x64\x65tails\x18\x03 \x03(\x0b\x32\x14.google.protobuf.AnyR\x07\x64\x65tails\"\"\n\nUnknownSet\x12\x14\n\x05\x65xprs\x18\x01 \x03(\x03R\x05\x65xprsBk\n\x0c\x63om.cel.exprB\tEvalProtoP\x01Z\x0c\x63\x65l.dev/expr\xf8\x01\x01\xa2\x02\x03\x43\x45X\xaa\x02\x08\x43\x65l.Expr\xca\x02\x08\x43\x65l\\Expr\xe2\x02\x14\x43\x65l\\Expr\\GPBMetadata\xea\x02\tCel::Exprb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cel.expr.eval_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\014com.cel.exprB\tEvalProtoP\001Z\014cel.dev/expr\370\001\001\242\002\003CEX\252\002\010Cel.Expr\312\002\010Cel\\Expr\342\002\024Cel\\Expr\\GPBMetadata\352\002\tCel::Expr' + _globals['_EVALSTATE']._serialized_start=83 + _globals['_EVALSTATE']._serialized_end=245 + _globals['_EVALSTATE_RESULT']._serialized_start=195 + _globals['_EVALSTATE_RESULT']._serialized_end=245 + _globals['_EXPRVALUE']._serialized_start=248 + _globals['_EXPRVALUE']._serialized_end=402 + _globals['_ERRORSET']._serialized_start=404 + _globals['_ERRORSET']._serialized_end=456 + _globals['_STATUS']._serialized_start=458 + _globals['_STATUS']._serialized_end=560 + _globals['_UNKNOWNSET']._serialized_start=562 + _globals['_UNKNOWNSET']._serialized_end=596 +# @@protoc_insertion_point(module_scope) diff --git a/gen/cel/expr/eval_pb2.pyi b/gen/cel/expr/eval_pb2.pyi new file mode 100644 index 00000000..6a980df1 --- /dev/null +++ b/gen/cel/expr/eval_pb2.pyi @@ -0,0 +1,70 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +from google.protobuf import any_pb2 as _any_pb2 +from cel.expr import value_pb2 as _value_pb2 +from google.protobuf.internal import containers as _containers +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from collections.abc import Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class EvalState(_message.Message): + __slots__ = ("values", "results") + class Result(_message.Message): + __slots__ = ("expr", "value") + EXPR_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + expr: int + value: int + def __init__(self, expr: _Optional[int] = ..., value: _Optional[int] = ...) -> None: ... + VALUES_FIELD_NUMBER: _ClassVar[int] + RESULTS_FIELD_NUMBER: _ClassVar[int] + values: _containers.RepeatedCompositeFieldContainer[ExprValue] + results: _containers.RepeatedCompositeFieldContainer[EvalState.Result] + def __init__(self, values: _Optional[_Iterable[_Union[ExprValue, _Mapping]]] = ..., results: _Optional[_Iterable[_Union[EvalState.Result, _Mapping]]] = ...) -> None: ... + +class ExprValue(_message.Message): + __slots__ = ("value", "error", "unknown") + VALUE_FIELD_NUMBER: _ClassVar[int] + ERROR_FIELD_NUMBER: _ClassVar[int] + UNKNOWN_FIELD_NUMBER: _ClassVar[int] + value: _value_pb2.Value + error: ErrorSet + unknown: UnknownSet + def __init__(self, value: _Optional[_Union[_value_pb2.Value, _Mapping]] = ..., error: _Optional[_Union[ErrorSet, _Mapping]] = ..., unknown: _Optional[_Union[UnknownSet, _Mapping]] = ...) -> None: ... + +class ErrorSet(_message.Message): + __slots__ = ("errors",) + ERRORS_FIELD_NUMBER: _ClassVar[int] + errors: _containers.RepeatedCompositeFieldContainer[Status] + def __init__(self, errors: _Optional[_Iterable[_Union[Status, _Mapping]]] = ...) -> None: ... + +class Status(_message.Message): + __slots__ = ("code", "message", "details") + CODE_FIELD_NUMBER: _ClassVar[int] + MESSAGE_FIELD_NUMBER: _ClassVar[int] + DETAILS_FIELD_NUMBER: _ClassVar[int] + code: int + message: str + details: _containers.RepeatedCompositeFieldContainer[_any_pb2.Any] + def __init__(self, code: _Optional[int] = ..., message: _Optional[str] = ..., details: _Optional[_Iterable[_Union[_any_pb2.Any, _Mapping]]] = ...) -> None: ... + +class UnknownSet(_message.Message): + __slots__ = ("exprs",) + EXPRS_FIELD_NUMBER: _ClassVar[int] + exprs: _containers.RepeatedScalarFieldContainer[int] + def __init__(self, exprs: _Optional[_Iterable[int]] = ...) -> None: ... diff --git a/gen/cel/expr/explain_pb2.py b/gen/cel/expr/explain_pb2.py new file mode 100644 index 00000000..de56b60c --- /dev/null +++ b/gen/cel/expr/explain_pb2.py @@ -0,0 +1,56 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: cel/expr/explain.proto +# Protobuf Python Version: 6.30.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 30, + 1, + '', + 'cel/expr/explain.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from cel.expr import value_pb2 as cel_dot_expr_dot_value__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16\x63\x65l/expr/explain.proto\x12\x08\x63\x65l.expr\x1a\x14\x63\x65l/expr/value.proto\"\xae\x01\n\x07\x45xplain\x12\'\n\x06values\x18\x01 \x03(\x0b\x32\x0f.cel.expr.ValueR\x06values\x12\x39\n\nexpr_steps\x18\x02 \x03(\x0b\x32\x1a.cel.expr.Explain.ExprStepR\texprSteps\x1a;\n\x08\x45xprStep\x12\x0e\n\x02id\x18\x01 \x01(\x03R\x02id\x12\x1f\n\x0bvalue_index\x18\x02 \x01(\x05R\nvalueIndex:\x02\x18\x01\x42n\n\x0c\x63om.cel.exprB\x0c\x45xplainProtoP\x01Z\x0c\x63\x65l.dev/expr\xf8\x01\x01\xa2\x02\x03\x43\x45X\xaa\x02\x08\x43\x65l.Expr\xca\x02\x08\x43\x65l\\Expr\xe2\x02\x14\x43\x65l\\Expr\\GPBMetadata\xea\x02\tCel::Exprb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cel.expr.explain_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\014com.cel.exprB\014ExplainProtoP\001Z\014cel.dev/expr\370\001\001\242\002\003CEX\252\002\010Cel.Expr\312\002\010Cel\\Expr\342\002\024Cel\\Expr\\GPBMetadata\352\002\tCel::Expr' + _globals['_EXPLAIN']._loaded_options = None + _globals['_EXPLAIN']._serialized_options = b'\030\001' + _globals['_EXPLAIN']._serialized_start=59 + _globals['_EXPLAIN']._serialized_end=233 + _globals['_EXPLAIN_EXPRSTEP']._serialized_start=170 + _globals['_EXPLAIN_EXPRSTEP']._serialized_end=229 +# @@protoc_insertion_point(module_scope) diff --git a/gen/cel/expr/explain_pb2.pyi b/gen/cel/expr/explain_pb2.pyi new file mode 100644 index 00000000..761b1bef --- /dev/null +++ b/gen/cel/expr/explain_pb2.pyi @@ -0,0 +1,37 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +from cel.expr import value_pb2 as _value_pb2 +from google.protobuf.internal import containers as _containers +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from collections.abc import Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class Explain(_message.Message): + __slots__ = ("values", "expr_steps") + class ExprStep(_message.Message): + __slots__ = ("id", "value_index") + ID_FIELD_NUMBER: _ClassVar[int] + VALUE_INDEX_FIELD_NUMBER: _ClassVar[int] + id: int + value_index: int + def __init__(self, id: _Optional[int] = ..., value_index: _Optional[int] = ...) -> None: ... + VALUES_FIELD_NUMBER: _ClassVar[int] + EXPR_STEPS_FIELD_NUMBER: _ClassVar[int] + values: _containers.RepeatedCompositeFieldContainer[_value_pb2.Value] + expr_steps: _containers.RepeatedCompositeFieldContainer[Explain.ExprStep] + def __init__(self, values: _Optional[_Iterable[_Union[_value_pb2.Value, _Mapping]]] = ..., expr_steps: _Optional[_Iterable[_Union[Explain.ExprStep, _Mapping]]] = ...) -> None: ... diff --git a/gen/cel/expr/syntax_pb2.py b/gen/cel/expr/syntax_pb2.py new file mode 100644 index 00000000..15e8560f --- /dev/null +++ b/gen/cel/expr/syntax_pb2.py @@ -0,0 +1,92 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: cel/expr/syntax.proto +# Protobuf Python Version: 6.30.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 30, + 1, + '', + 'cel/expr/syntax.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 +from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x63\x65l/expr/syntax.proto\x12\x08\x63\x65l.expr\x1a\x1egoogle/protobuf/duration.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"g\n\nParsedExpr\x12\"\n\x04\x65xpr\x18\x02 \x01(\x0b\x32\x0e.cel.expr.ExprR\x04\x65xpr\x12\x35\n\x0bsource_info\x18\x03 \x01(\x0b\x32\x14.cel.expr.SourceInfoR\nsourceInfo\"\x9a\x0b\n\x04\x45xpr\x12\x0e\n\x02id\x18\x02 \x01(\x03R\x02id\x12\x33\n\nconst_expr\x18\x03 \x01(\x0b\x32\x12.cel.expr.ConstantH\x00R\tconstExpr\x12\x35\n\nident_expr\x18\x04 \x01(\x0b\x32\x14.cel.expr.Expr.IdentH\x00R\tidentExpr\x12\x38\n\x0bselect_expr\x18\x05 \x01(\x0b\x32\x15.cel.expr.Expr.SelectH\x00R\nselectExpr\x12\x32\n\tcall_expr\x18\x06 \x01(\x0b\x32\x13.cel.expr.Expr.CallH\x00R\x08\x63\x61llExpr\x12\x38\n\tlist_expr\x18\x07 \x01(\x0b\x32\x19.cel.expr.Expr.CreateListH\x00R\x08listExpr\x12>\n\x0bstruct_expr\x18\x08 \x01(\x0b\x32\x1b.cel.expr.Expr.CreateStructH\x00R\nstructExpr\x12M\n\x12\x63omprehension_expr\x18\t \x01(\x0b\x32\x1c.cel.expr.Expr.ComprehensionH\x00R\x11\x63omprehensionExpr\x1a\x1b\n\x05Ident\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x1a\x65\n\x06Select\x12(\n\x07operand\x18\x01 \x01(\x0b\x32\x0e.cel.expr.ExprR\x07operand\x12\x14\n\x05\x66ield\x18\x02 \x01(\tR\x05\x66ield\x12\x1b\n\ttest_only\x18\x03 \x01(\x08R\x08testOnly\x1an\n\x04\x43\x61ll\x12&\n\x06target\x18\x01 \x01(\x0b\x32\x0e.cel.expr.ExprR\x06target\x12\x1a\n\x08\x66unction\x18\x02 \x01(\tR\x08\x66unction\x12\"\n\x04\x61rgs\x18\x03 \x03(\x0b\x32\x0e.cel.expr.ExprR\x04\x61rgs\x1a\x63\n\nCreateList\x12*\n\x08\x65lements\x18\x01 \x03(\x0b\x32\x0e.cel.expr.ExprR\x08\x65lements\x12)\n\x10optional_indices\x18\x02 \x03(\x05R\x0foptionalIndices\x1a\xab\x02\n\x0c\x43reateStruct\x12!\n\x0cmessage_name\x18\x01 \x01(\tR\x0bmessageName\x12;\n\x07\x65ntries\x18\x02 \x03(\x0b\x32!.cel.expr.Expr.CreateStruct.EntryR\x07\x65ntries\x1a\xba\x01\n\x05\x45ntry\x12\x0e\n\x02id\x18\x01 \x01(\x03R\x02id\x12\x1d\n\tfield_key\x18\x02 \x01(\tH\x00R\x08\x66ieldKey\x12)\n\x07map_key\x18\x03 \x01(\x0b\x32\x0e.cel.expr.ExprH\x00R\x06mapKey\x12$\n\x05value\x18\x04 \x01(\x0b\x32\x0e.cel.expr.ExprR\x05value\x12%\n\x0eoptional_entry\x18\x05 \x01(\x08R\roptionalEntryB\n\n\x08key_kind\x1a\xca\x02\n\rComprehension\x12\x19\n\x08iter_var\x18\x01 \x01(\tR\x07iterVar\x12\x1b\n\titer_var2\x18\x08 \x01(\tR\x08iterVar2\x12-\n\niter_range\x18\x02 \x01(\x0b\x32\x0e.cel.expr.ExprR\titerRange\x12\x19\n\x08\x61\x63\x63u_var\x18\x03 \x01(\tR\x07\x61\x63\x63uVar\x12+\n\taccu_init\x18\x04 \x01(\x0b\x32\x0e.cel.expr.ExprR\x08\x61\x63\x63uInit\x12\x35\n\x0eloop_condition\x18\x05 \x01(\x0b\x32\x0e.cel.expr.ExprR\rloopCondition\x12+\n\tloop_step\x18\x06 \x01(\x0b\x32\x0e.cel.expr.ExprR\x08loopStep\x12&\n\x06result\x18\x07 \x01(\x0b\x32\x0e.cel.expr.ExprR\x06resultB\x0b\n\texpr_kind\"\xc1\x03\n\x08\x43onstant\x12;\n\nnull_value\x18\x01 \x01(\x0e\x32\x1a.google.protobuf.NullValueH\x00R\tnullValue\x12\x1f\n\nbool_value\x18\x02 \x01(\x08H\x00R\tboolValue\x12!\n\x0bint64_value\x18\x03 \x01(\x03H\x00R\nint64Value\x12#\n\x0cuint64_value\x18\x04 \x01(\x04H\x00R\x0buint64Value\x12#\n\x0c\x64ouble_value\x18\x05 \x01(\x01H\x00R\x0b\x64oubleValue\x12#\n\x0cstring_value\x18\x06 \x01(\tH\x00R\x0bstringValue\x12!\n\x0b\x62ytes_value\x18\x07 \x01(\x0cH\x00R\nbytesValue\x12\x46\n\x0e\x64uration_value\x18\x08 \x01(\x0b\x32\x19.google.protobuf.DurationB\x02\x18\x01H\x00R\rdurationValue\x12I\n\x0ftimestamp_value\x18\t \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x02\x18\x01H\x00R\x0etimestampValueB\x0f\n\rconstant_kind\"\xac\x06\n\nSourceInfo\x12%\n\x0esyntax_version\x18\x01 \x01(\tR\rsyntaxVersion\x12\x1a\n\x08location\x18\x02 \x01(\tR\x08location\x12!\n\x0cline_offsets\x18\x03 \x03(\x05R\x0blineOffsets\x12\x41\n\tpositions\x18\x04 \x03(\x0b\x32#.cel.expr.SourceInfo.PositionsEntryR\tpositions\x12\x45\n\x0bmacro_calls\x18\x05 \x03(\x0b\x32$.cel.expr.SourceInfo.MacroCallsEntryR\nmacroCalls\x12>\n\nextensions\x18\x06 \x03(\x0b\x32\x1e.cel.expr.SourceInfo.ExtensionR\nextensions\x1a<\n\x0ePositionsEntry\x12\x10\n\x03key\x18\x01 \x01(\x03R\x03key\x12\x14\n\x05value\x18\x02 \x01(\x05R\x05value:\x02\x38\x01\x1aM\n\x0fMacroCallsEntry\x12\x10\n\x03key\x18\x01 \x01(\x03R\x03key\x12$\n\x05value\x18\x02 \x01(\x0b\x32\x0e.cel.expr.ExprR\x05value:\x02\x38\x01\x1a\xe0\x02\n\tExtension\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12Y\n\x13\x61\x66\x66\x65\x63ted_components\x18\x02 \x03(\x0e\x32(.cel.expr.SourceInfo.Extension.ComponentR\x12\x61\x66\x66\x65\x63tedComponents\x12@\n\x07version\x18\x03 \x01(\x0b\x32&.cel.expr.SourceInfo.Extension.VersionR\x07version\x1a\x35\n\x07Version\x12\x14\n\x05major\x18\x01 \x01(\x03R\x05major\x12\x14\n\x05minor\x18\x02 \x01(\x03R\x05minor\"o\n\tComponent\x12\x19\n\x15\x43OMPONENT_UNSPECIFIED\x10\x00\x12\x14\n\x10\x43OMPONENT_PARSER\x10\x01\x12\x1a\n\x16\x43OMPONENT_TYPE_CHECKER\x10\x02\x12\x15\n\x11\x43OMPONENT_RUNTIME\x10\x03\x42m\n\x0c\x63om.cel.exprB\x0bSyntaxProtoP\x01Z\x0c\x63\x65l.dev/expr\xf8\x01\x01\xa2\x02\x03\x43\x45X\xaa\x02\x08\x43\x65l.Expr\xca\x02\x08\x43\x65l\\Expr\xe2\x02\x14\x43\x65l\\Expr\\GPBMetadata\xea\x02\tCel::Exprb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cel.expr.syntax_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\014com.cel.exprB\013SyntaxProtoP\001Z\014cel.dev/expr\370\001\001\242\002\003CEX\252\002\010Cel.Expr\312\002\010Cel\\Expr\342\002\024Cel\\Expr\\GPBMetadata\352\002\tCel::Expr' + _globals['_CONSTANT'].fields_by_name['duration_value']._loaded_options = None + _globals['_CONSTANT'].fields_by_name['duration_value']._serialized_options = b'\030\001' + _globals['_CONSTANT'].fields_by_name['timestamp_value']._loaded_options = None + _globals['_CONSTANT'].fields_by_name['timestamp_value']._serialized_options = b'\030\001' + _globals['_SOURCEINFO_POSITIONSENTRY']._loaded_options = None + _globals['_SOURCEINFO_POSITIONSENTRY']._serialized_options = b'8\001' + _globals['_SOURCEINFO_MACROCALLSENTRY']._loaded_options = None + _globals['_SOURCEINFO_MACROCALLSENTRY']._serialized_options = b'8\001' + _globals['_PARSEDEXPR']._serialized_start=130 + _globals['_PARSEDEXPR']._serialized_end=233 + _globals['_EXPR']._serialized_start=236 + _globals['_EXPR']._serialized_end=1670 + _globals['_EXPR_IDENT']._serialized_start=679 + _globals['_EXPR_IDENT']._serialized_end=706 + _globals['_EXPR_SELECT']._serialized_start=708 + _globals['_EXPR_SELECT']._serialized_end=809 + _globals['_EXPR_CALL']._serialized_start=811 + _globals['_EXPR_CALL']._serialized_end=921 + _globals['_EXPR_CREATELIST']._serialized_start=923 + _globals['_EXPR_CREATELIST']._serialized_end=1022 + _globals['_EXPR_CREATESTRUCT']._serialized_start=1025 + _globals['_EXPR_CREATESTRUCT']._serialized_end=1324 + _globals['_EXPR_CREATESTRUCT_ENTRY']._serialized_start=1138 + _globals['_EXPR_CREATESTRUCT_ENTRY']._serialized_end=1324 + _globals['_EXPR_COMPREHENSION']._serialized_start=1327 + _globals['_EXPR_COMPREHENSION']._serialized_end=1657 + _globals['_CONSTANT']._serialized_start=1673 + _globals['_CONSTANT']._serialized_end=2122 + _globals['_SOURCEINFO']._serialized_start=2125 + _globals['_SOURCEINFO']._serialized_end=2937 + _globals['_SOURCEINFO_POSITIONSENTRY']._serialized_start=2443 + _globals['_SOURCEINFO_POSITIONSENTRY']._serialized_end=2503 + _globals['_SOURCEINFO_MACROCALLSENTRY']._serialized_start=2505 + _globals['_SOURCEINFO_MACROCALLSENTRY']._serialized_end=2582 + _globals['_SOURCEINFO_EXTENSION']._serialized_start=2585 + _globals['_SOURCEINFO_EXTENSION']._serialized_end=2937 + _globals['_SOURCEINFO_EXTENSION_VERSION']._serialized_start=2771 + _globals['_SOURCEINFO_EXTENSION_VERSION']._serialized_end=2824 + _globals['_SOURCEINFO_EXTENSION_COMPONENT']._serialized_start=2826 + _globals['_SOURCEINFO_EXTENSION_COMPONENT']._serialized_end=2937 +# @@protoc_insertion_point(module_scope) diff --git a/gen/cel/expr/syntax_pb2.pyi b/gen/cel/expr/syntax_pb2.pyi new file mode 100644 index 00000000..24959e1f --- /dev/null +++ b/gen/cel/expr/syntax_pb2.pyi @@ -0,0 +1,200 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +from google.protobuf import duration_pb2 as _duration_pb2 +from google.protobuf import struct_pb2 as _struct_pb2 +from google.protobuf import timestamp_pb2 as _timestamp_pb2 +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from collections.abc import Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class ParsedExpr(_message.Message): + __slots__ = ("expr", "source_info") + EXPR_FIELD_NUMBER: _ClassVar[int] + SOURCE_INFO_FIELD_NUMBER: _ClassVar[int] + expr: Expr + source_info: SourceInfo + def __init__(self, expr: _Optional[_Union[Expr, _Mapping]] = ..., source_info: _Optional[_Union[SourceInfo, _Mapping]] = ...) -> None: ... + +class Expr(_message.Message): + __slots__ = ("id", "const_expr", "ident_expr", "select_expr", "call_expr", "list_expr", "struct_expr", "comprehension_expr") + class Ident(_message.Message): + __slots__ = ("name",) + NAME_FIELD_NUMBER: _ClassVar[int] + name: str + def __init__(self, name: _Optional[str] = ...) -> None: ... + class Select(_message.Message): + __slots__ = ("operand", "field", "test_only") + OPERAND_FIELD_NUMBER: _ClassVar[int] + FIELD_FIELD_NUMBER: _ClassVar[int] + TEST_ONLY_FIELD_NUMBER: _ClassVar[int] + operand: Expr + field: str + test_only: bool + def __init__(self, operand: _Optional[_Union[Expr, _Mapping]] = ..., field: _Optional[str] = ..., test_only: bool = ...) -> None: ... + class Call(_message.Message): + __slots__ = ("target", "function", "args") + TARGET_FIELD_NUMBER: _ClassVar[int] + FUNCTION_FIELD_NUMBER: _ClassVar[int] + ARGS_FIELD_NUMBER: _ClassVar[int] + target: Expr + function: str + args: _containers.RepeatedCompositeFieldContainer[Expr] + def __init__(self, target: _Optional[_Union[Expr, _Mapping]] = ..., function: _Optional[str] = ..., args: _Optional[_Iterable[_Union[Expr, _Mapping]]] = ...) -> None: ... + class CreateList(_message.Message): + __slots__ = ("elements", "optional_indices") + ELEMENTS_FIELD_NUMBER: _ClassVar[int] + OPTIONAL_INDICES_FIELD_NUMBER: _ClassVar[int] + elements: _containers.RepeatedCompositeFieldContainer[Expr] + optional_indices: _containers.RepeatedScalarFieldContainer[int] + def __init__(self, elements: _Optional[_Iterable[_Union[Expr, _Mapping]]] = ..., optional_indices: _Optional[_Iterable[int]] = ...) -> None: ... + class CreateStruct(_message.Message): + __slots__ = ("message_name", "entries") + class Entry(_message.Message): + __slots__ = ("id", "field_key", "map_key", "value", "optional_entry") + ID_FIELD_NUMBER: _ClassVar[int] + FIELD_KEY_FIELD_NUMBER: _ClassVar[int] + MAP_KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + OPTIONAL_ENTRY_FIELD_NUMBER: _ClassVar[int] + id: int + field_key: str + map_key: Expr + value: Expr + optional_entry: bool + def __init__(self, id: _Optional[int] = ..., field_key: _Optional[str] = ..., map_key: _Optional[_Union[Expr, _Mapping]] = ..., value: _Optional[_Union[Expr, _Mapping]] = ..., optional_entry: bool = ...) -> None: ... + MESSAGE_NAME_FIELD_NUMBER: _ClassVar[int] + ENTRIES_FIELD_NUMBER: _ClassVar[int] + message_name: str + entries: _containers.RepeatedCompositeFieldContainer[Expr.CreateStruct.Entry] + def __init__(self, message_name: _Optional[str] = ..., entries: _Optional[_Iterable[_Union[Expr.CreateStruct.Entry, _Mapping]]] = ...) -> None: ... + class Comprehension(_message.Message): + __slots__ = ("iter_var", "iter_var2", "iter_range", "accu_var", "accu_init", "loop_condition", "loop_step", "result") + ITER_VAR_FIELD_NUMBER: _ClassVar[int] + ITER_VAR2_FIELD_NUMBER: _ClassVar[int] + ITER_RANGE_FIELD_NUMBER: _ClassVar[int] + ACCU_VAR_FIELD_NUMBER: _ClassVar[int] + ACCU_INIT_FIELD_NUMBER: _ClassVar[int] + LOOP_CONDITION_FIELD_NUMBER: _ClassVar[int] + LOOP_STEP_FIELD_NUMBER: _ClassVar[int] + RESULT_FIELD_NUMBER: _ClassVar[int] + iter_var: str + iter_var2: str + iter_range: Expr + accu_var: str + accu_init: Expr + loop_condition: Expr + loop_step: Expr + result: Expr + def __init__(self, iter_var: _Optional[str] = ..., iter_var2: _Optional[str] = ..., iter_range: _Optional[_Union[Expr, _Mapping]] = ..., accu_var: _Optional[str] = ..., accu_init: _Optional[_Union[Expr, _Mapping]] = ..., loop_condition: _Optional[_Union[Expr, _Mapping]] = ..., loop_step: _Optional[_Union[Expr, _Mapping]] = ..., result: _Optional[_Union[Expr, _Mapping]] = ...) -> None: ... + ID_FIELD_NUMBER: _ClassVar[int] + CONST_EXPR_FIELD_NUMBER: _ClassVar[int] + IDENT_EXPR_FIELD_NUMBER: _ClassVar[int] + SELECT_EXPR_FIELD_NUMBER: _ClassVar[int] + CALL_EXPR_FIELD_NUMBER: _ClassVar[int] + LIST_EXPR_FIELD_NUMBER: _ClassVar[int] + STRUCT_EXPR_FIELD_NUMBER: _ClassVar[int] + COMPREHENSION_EXPR_FIELD_NUMBER: _ClassVar[int] + id: int + const_expr: Constant + ident_expr: Expr.Ident + select_expr: Expr.Select + call_expr: Expr.Call + list_expr: Expr.CreateList + struct_expr: Expr.CreateStruct + comprehension_expr: Expr.Comprehension + def __init__(self, id: _Optional[int] = ..., const_expr: _Optional[_Union[Constant, _Mapping]] = ..., ident_expr: _Optional[_Union[Expr.Ident, _Mapping]] = ..., select_expr: _Optional[_Union[Expr.Select, _Mapping]] = ..., call_expr: _Optional[_Union[Expr.Call, _Mapping]] = ..., list_expr: _Optional[_Union[Expr.CreateList, _Mapping]] = ..., struct_expr: _Optional[_Union[Expr.CreateStruct, _Mapping]] = ..., comprehension_expr: _Optional[_Union[Expr.Comprehension, _Mapping]] = ...) -> None: ... + +class Constant(_message.Message): + __slots__ = ("null_value", "bool_value", "int64_value", "uint64_value", "double_value", "string_value", "bytes_value", "duration_value", "timestamp_value") + NULL_VALUE_FIELD_NUMBER: _ClassVar[int] + BOOL_VALUE_FIELD_NUMBER: _ClassVar[int] + INT64_VALUE_FIELD_NUMBER: _ClassVar[int] + UINT64_VALUE_FIELD_NUMBER: _ClassVar[int] + DOUBLE_VALUE_FIELD_NUMBER: _ClassVar[int] + STRING_VALUE_FIELD_NUMBER: _ClassVar[int] + BYTES_VALUE_FIELD_NUMBER: _ClassVar[int] + DURATION_VALUE_FIELD_NUMBER: _ClassVar[int] + TIMESTAMP_VALUE_FIELD_NUMBER: _ClassVar[int] + null_value: _struct_pb2.NullValue + bool_value: bool + int64_value: int + uint64_value: int + double_value: float + string_value: str + bytes_value: bytes + duration_value: _duration_pb2.Duration + timestamp_value: _timestamp_pb2.Timestamp + def __init__(self, null_value: _Optional[_Union[_struct_pb2.NullValue, str]] = ..., bool_value: bool = ..., int64_value: _Optional[int] = ..., uint64_value: _Optional[int] = ..., double_value: _Optional[float] = ..., string_value: _Optional[str] = ..., bytes_value: _Optional[bytes] = ..., duration_value: _Optional[_Union[_duration_pb2.Duration, _Mapping]] = ..., timestamp_value: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ...) -> None: ... + +class SourceInfo(_message.Message): + __slots__ = ("syntax_version", "location", "line_offsets", "positions", "macro_calls", "extensions") + class PositionsEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: int + value: int + def __init__(self, key: _Optional[int] = ..., value: _Optional[int] = ...) -> None: ... + class MacroCallsEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: int + value: Expr + def __init__(self, key: _Optional[int] = ..., value: _Optional[_Union[Expr, _Mapping]] = ...) -> None: ... + class Extension(_message.Message): + __slots__ = ("id", "affected_components", "version") + class Component(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + COMPONENT_UNSPECIFIED: _ClassVar[SourceInfo.Extension.Component] + COMPONENT_PARSER: _ClassVar[SourceInfo.Extension.Component] + COMPONENT_TYPE_CHECKER: _ClassVar[SourceInfo.Extension.Component] + COMPONENT_RUNTIME: _ClassVar[SourceInfo.Extension.Component] + COMPONENT_UNSPECIFIED: SourceInfo.Extension.Component + COMPONENT_PARSER: SourceInfo.Extension.Component + COMPONENT_TYPE_CHECKER: SourceInfo.Extension.Component + COMPONENT_RUNTIME: SourceInfo.Extension.Component + class Version(_message.Message): + __slots__ = ("major", "minor") + MAJOR_FIELD_NUMBER: _ClassVar[int] + MINOR_FIELD_NUMBER: _ClassVar[int] + major: int + minor: int + def __init__(self, major: _Optional[int] = ..., minor: _Optional[int] = ...) -> None: ... + ID_FIELD_NUMBER: _ClassVar[int] + AFFECTED_COMPONENTS_FIELD_NUMBER: _ClassVar[int] + VERSION_FIELD_NUMBER: _ClassVar[int] + id: str + affected_components: _containers.RepeatedScalarFieldContainer[SourceInfo.Extension.Component] + version: SourceInfo.Extension.Version + def __init__(self, id: _Optional[str] = ..., affected_components: _Optional[_Iterable[_Union[SourceInfo.Extension.Component, str]]] = ..., version: _Optional[_Union[SourceInfo.Extension.Version, _Mapping]] = ...) -> None: ... + SYNTAX_VERSION_FIELD_NUMBER: _ClassVar[int] + LOCATION_FIELD_NUMBER: _ClassVar[int] + LINE_OFFSETS_FIELD_NUMBER: _ClassVar[int] + POSITIONS_FIELD_NUMBER: _ClassVar[int] + MACRO_CALLS_FIELD_NUMBER: _ClassVar[int] + EXTENSIONS_FIELD_NUMBER: _ClassVar[int] + syntax_version: str + location: str + line_offsets: _containers.RepeatedScalarFieldContainer[int] + positions: _containers.ScalarMap[int, int] + macro_calls: _containers.MessageMap[int, Expr] + extensions: _containers.RepeatedCompositeFieldContainer[SourceInfo.Extension] + def __init__(self, syntax_version: _Optional[str] = ..., location: _Optional[str] = ..., line_offsets: _Optional[_Iterable[int]] = ..., positions: _Optional[_Mapping[int, int]] = ..., macro_calls: _Optional[_Mapping[int, Expr]] = ..., extensions: _Optional[_Iterable[_Union[SourceInfo.Extension, _Mapping]]] = ...) -> None: ... diff --git a/gen/cel/expr/value_pb2.py b/gen/cel/expr/value_pb2.py new file mode 100644 index 00000000..9a7673d4 --- /dev/null +++ b/gen/cel/expr/value_pb2.py @@ -0,0 +1,61 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: cel/expr/value.proto +# Protobuf Python Version: 6.30.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 30, + 1, + '', + 'cel/expr/value.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 +from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x63\x65l/expr/value.proto\x12\x08\x63\x65l.expr\x1a\x19google/protobuf/any.proto\x1a\x1cgoogle/protobuf/struct.proto\"\x9d\x04\n\x05Value\x12;\n\nnull_value\x18\x01 \x01(\x0e\x32\x1a.google.protobuf.NullValueH\x00R\tnullValue\x12\x1f\n\nbool_value\x18\x02 \x01(\x08H\x00R\tboolValue\x12!\n\x0bint64_value\x18\x03 \x01(\x03H\x00R\nint64Value\x12#\n\x0cuint64_value\x18\x04 \x01(\x04H\x00R\x0buint64Value\x12#\n\x0c\x64ouble_value\x18\x05 \x01(\x01H\x00R\x0b\x64oubleValue\x12#\n\x0cstring_value\x18\x06 \x01(\tH\x00R\x0bstringValue\x12!\n\x0b\x62ytes_value\x18\x07 \x01(\x0cH\x00R\nbytesValue\x12\x34\n\nenum_value\x18\t \x01(\x0b\x32\x13.cel.expr.EnumValueH\x00R\tenumValue\x12\x39\n\x0cobject_value\x18\n \x01(\x0b\x32\x14.google.protobuf.AnyH\x00R\x0bobjectValue\x12\x31\n\tmap_value\x18\x0b \x01(\x0b\x32\x12.cel.expr.MapValueH\x00R\x08mapValue\x12\x34\n\nlist_value\x18\x0c \x01(\x0b\x32\x13.cel.expr.ListValueH\x00R\tlistValue\x12\x1f\n\ntype_value\x18\x0f \x01(\tH\x00R\ttypeValueB\x06\n\x04kind\"5\n\tEnumValue\x12\x12\n\x04type\x18\x01 \x01(\tR\x04type\x12\x14\n\x05value\x18\x02 \x01(\x05R\x05value\"4\n\tListValue\x12\'\n\x06values\x18\x01 \x03(\x0b\x32\x0f.cel.expr.ValueR\x06values\"\x91\x01\n\x08MapValue\x12\x32\n\x07\x65ntries\x18\x01 \x03(\x0b\x32\x18.cel.expr.MapValue.EntryR\x07\x65ntries\x1aQ\n\x05\x45ntry\x12!\n\x03key\x18\x01 \x01(\x0b\x32\x0f.cel.expr.ValueR\x03key\x12%\n\x05value\x18\x02 \x01(\x0b\x32\x0f.cel.expr.ValueR\x05valueBl\n\x0c\x63om.cel.exprB\nValueProtoP\x01Z\x0c\x63\x65l.dev/expr\xf8\x01\x01\xa2\x02\x03\x43\x45X\xaa\x02\x08\x43\x65l.Expr\xca\x02\x08\x43\x65l\\Expr\xe2\x02\x14\x43\x65l\\Expr\\GPBMetadata\xea\x02\tCel::Exprb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cel.expr.value_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\014com.cel.exprB\nValueProtoP\001Z\014cel.dev/expr\370\001\001\242\002\003CEX\252\002\010Cel.Expr\312\002\010Cel\\Expr\342\002\024Cel\\Expr\\GPBMetadata\352\002\tCel::Expr' + _globals['_VALUE']._serialized_start=92 + _globals['_VALUE']._serialized_end=633 + _globals['_ENUMVALUE']._serialized_start=635 + _globals['_ENUMVALUE']._serialized_end=688 + _globals['_LISTVALUE']._serialized_start=690 + _globals['_LISTVALUE']._serialized_end=742 + _globals['_MAPVALUE']._serialized_start=745 + _globals['_MAPVALUE']._serialized_end=890 + _globals['_MAPVALUE_ENTRY']._serialized_start=809 + _globals['_MAPVALUE_ENTRY']._serialized_end=890 +# @@protoc_insertion_point(module_scope) diff --git a/gen/cel/expr/value_pb2.pyi b/gen/cel/expr/value_pb2.pyi new file mode 100644 index 00000000..009cdbba --- /dev/null +++ b/gen/cel/expr/value_pb2.pyi @@ -0,0 +1,78 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +from google.protobuf import any_pb2 as _any_pb2 +from google.protobuf import struct_pb2 as _struct_pb2 +from google.protobuf.internal import containers as _containers +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from collections.abc import Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class Value(_message.Message): + __slots__ = ("null_value", "bool_value", "int64_value", "uint64_value", "double_value", "string_value", "bytes_value", "enum_value", "object_value", "map_value", "list_value", "type_value") + NULL_VALUE_FIELD_NUMBER: _ClassVar[int] + BOOL_VALUE_FIELD_NUMBER: _ClassVar[int] + INT64_VALUE_FIELD_NUMBER: _ClassVar[int] + UINT64_VALUE_FIELD_NUMBER: _ClassVar[int] + DOUBLE_VALUE_FIELD_NUMBER: _ClassVar[int] + STRING_VALUE_FIELD_NUMBER: _ClassVar[int] + BYTES_VALUE_FIELD_NUMBER: _ClassVar[int] + ENUM_VALUE_FIELD_NUMBER: _ClassVar[int] + OBJECT_VALUE_FIELD_NUMBER: _ClassVar[int] + MAP_VALUE_FIELD_NUMBER: _ClassVar[int] + LIST_VALUE_FIELD_NUMBER: _ClassVar[int] + TYPE_VALUE_FIELD_NUMBER: _ClassVar[int] + null_value: _struct_pb2.NullValue + bool_value: bool + int64_value: int + uint64_value: int + double_value: float + string_value: str + bytes_value: bytes + enum_value: EnumValue + object_value: _any_pb2.Any + map_value: MapValue + list_value: ListValue + type_value: str + def __init__(self, null_value: _Optional[_Union[_struct_pb2.NullValue, str]] = ..., bool_value: bool = ..., int64_value: _Optional[int] = ..., uint64_value: _Optional[int] = ..., double_value: _Optional[float] = ..., string_value: _Optional[str] = ..., bytes_value: _Optional[bytes] = ..., enum_value: _Optional[_Union[EnumValue, _Mapping]] = ..., object_value: _Optional[_Union[_any_pb2.Any, _Mapping]] = ..., map_value: _Optional[_Union[MapValue, _Mapping]] = ..., list_value: _Optional[_Union[ListValue, _Mapping]] = ..., type_value: _Optional[str] = ...) -> None: ... + +class EnumValue(_message.Message): + __slots__ = ("type", "value") + TYPE_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + type: str + value: int + def __init__(self, type: _Optional[str] = ..., value: _Optional[int] = ...) -> None: ... + +class ListValue(_message.Message): + __slots__ = ("values",) + VALUES_FIELD_NUMBER: _ClassVar[int] + values: _containers.RepeatedCompositeFieldContainer[Value] + def __init__(self, values: _Optional[_Iterable[_Union[Value, _Mapping]]] = ...) -> None: ... + +class MapValue(_message.Message): + __slots__ = ("entries",) + class Entry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: Value + value: Value + def __init__(self, key: _Optional[_Union[Value, _Mapping]] = ..., value: _Optional[_Union[Value, _Mapping]] = ...) -> None: ... + ENTRIES_FIELD_NUMBER: _ClassVar[int] + entries: _containers.RepeatedCompositeFieldContainer[MapValue.Entry] + def __init__(self, entries: _Optional[_Iterable[_Union[MapValue.Entry, _Mapping]]] = ...) -> None: ... diff --git a/protovalidate/internal/string_format.py b/protovalidate/internal/string_format.py index 9353ccf9..b6009266 100644 --- a/protovalidate/internal/string_format.py +++ b/protovalidate/internal/string_format.py @@ -82,7 +82,7 @@ def format(self, fmt: celtypes.Value, args: celtypes.Value) -> celpy.Result: return celpy.CELEvalError("format() incomplete format specifier") if fmt[i] == "f": result += self.format_float(arg, precision) - if fmt[i] == "e": + elif fmt[i] == "e": result += self.format_exponential(arg, precision) elif fmt[i] == "d": result += self.format_int(arg) diff --git a/tests/format_test.py b/tests/format_test.py index e69de29b..77a8b967 100644 --- a/tests/format_test.py +++ b/tests/format_test.py @@ -0,0 +1,79 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +import unittest +from typing import Any + +import celpy +from celpy import celtypes +from google.protobuf import text_format + +# from gen.cel.expr import checked_pb2 +from gen.cel.expr.conformance.test import simple_pb2 +from protovalidate.internal import extra_func +from protovalidate.internal.cel_field_presence import InterpretedRunner + +CEL_SPEC_VERSION = "v0.24.0" + +def read_textproto(): + msg = simple_pb2.SimpleTestFile() + with open(f"tests/testdata/string_ext_{CEL_SPEC_VERSION}.textproto") as f: + text_data = f.read() + text_format.Parse(text_data, msg) + return msg + + +class TestFormat(unittest.TestCase): + @classmethod + def setUpClass(cls): + test_data = read_textproto() + cls._format_tests = [x for x in test_data.section if x.name == "format"] + cls._format_error_tests = [x for x in test_data.section if x.name == "format_errors"] + cls._env = celpy.Environment(runner_class=InterpretedRunner) + + def _binding(self, bindings) -> dict[Any, Any]: + binder = {} + for key, value in bindings.items(): + if value.HasField("value"): + val = value.value + if val.HasField("string_value"): + binder[key] = celtypes.StringType(val.string_value) + + # for type_env in test.type_env: + # print(type_env) + # if type_env.HasField("ident"): + # ident = type_env.ident + # if ident.type.HasField("primitive"): + # prim = ident.type.primitive + # if prim == checked_pb2.Type.PrimitiveType.STRING: + # print("das string") + # elif type_env.HasField("function"): + # print('funker') + # print(type_env.function) + return binder + + def test_format_success(self): + format_tests = self._format_tests[0] + for test in format_tests.test: + ast = self._env.compile(test.expr) + prog = self._env.program(ast, functions=extra_func.EXTRA_FUNCS) + + binders = self._binding(test.bindings) + with self.subTest(test.name): + try: + result = prog.evaluate(binders) + if test.value.HasField("string_value"): + self.assertEqual(result, test.value.string_value) + except celpy.CELEvalError as e: + self.fail(e) diff --git a/tests/testdata/string_ext_v0.24.0.textproto b/tests/testdata/string_ext_v0.24.0.textproto new file mode 100644 index 00000000..d2455583 --- /dev/null +++ b/tests/testdata/string_ext_v0.24.0.textproto @@ -0,0 +1,1417 @@ +# proto-file: ../../../proto/cel/expr/conformance/test/simple.proto +# proto-message: cel.expr.conformance.test.SimpleTestFile + +name: "string_ext" +description: "Tests for the strings extension library." +section: { + name: "char_at" + test: { + name: "middle_index" + expr: "'tacocat'.charAt(3)" + value: { + string_value: "o" + } + } + test: { + name: "end_index" + expr: "'tacocat'.charAt(7)" + value: { + string_value: "" + } + } + test: { + name: "multiple" + expr: "'©αT'.charAt(0) == '©' && '©αT'.charAt(1) == 'α' && '©αT'.charAt(2) == 'T'" + } +} +section: { + name: "index_of" + test: { + name: "empty_index" + expr: "'tacocat'.indexOf('')" + value: { + int64_value: 0 + } + } + test: { + name: "string_index" + expr: "'tacocat'.indexOf('ac')" + value: { + int64_value: 1 + } + } + test: { + name: "nomatch" + expr: "'tacocat'.indexOf('none') == -1" + } + test: { + name: "empty_index" + expr: "'tacocat'.indexOf('', 3) == 3" + } + test: { + name: "char_index" + expr: "'tacocat'.indexOf('a', 3) == 5" + } + test: { + name: "string_index" + expr: "'tacocat'.indexOf('at', 3) == 5" + } + test: { + name: "unicode_char" + expr: "'ta©o©αT'.indexOf('©') == 2" + } + test: { + name: "unicode_char_index" + expr: "'ta©o©αT'.indexOf('©', 3) == 4" + } + test: { + name: "unicode_string_index" + expr: "'ta©o©αT'.indexOf('©αT', 3) == 4" + } + test: { + name: "unicode_string_nomatch_index" + expr: "'ta©o©αT'.indexOf('©α', 5) == -1" + } + test: { + name: "char_index" + expr: "'ijk'.indexOf('k') == 2" + } + test: { + name: "string_with_space_fullmatch" + expr: "'hello wello'.indexOf('hello wello') == 0" + } + test: { + name: "string_with_space_index" + expr: "'hello wello'.indexOf('ello', 6) == 7" + } + test: { + name: "string_nomatch_index" + expr: "'hello wello'.indexOf('elbo room!!') == -1" + } +} +section: { + name: "last_index_of" + test: { + name: "empty" + expr: "'tacocat'.lastIndexOf('') == 7" + } + test: { + name: "string" + expr: "'tacocat'.lastIndexOf('at') == 5" + } + test: { + name: "string_nomatch" + expr: "'tacocat'.lastIndexOf('none') == -1" + } + test: { + name: "empty_index" + expr: "'tacocat'.lastIndexOf('', 3) == 3" + } + test: { + name: "char_index" + expr: "'tacocat'.lastIndexOf('a', 3) == 1" + } + test: { + name: "unicode_char" + expr: "'ta©o©αT'.lastIndexOf('©') == 4" + } + test: { + name: "unicode_char_index" + expr: "'ta©o©αT'.lastIndexOf('©', 3) == 2" + } + test: { + name: "unicode_string_index" + expr: "'ta©o©αT'.lastIndexOf('©α', 4) == 4" + } + test: { + name: "string_with_space_string_index" + expr: "'hello wello'.lastIndexOf('ello', 6) == 1" + } + test: { + name: "string_with_space_string_nomatch" + expr: "'hello wello'.lastIndexOf('low') == -1" + } + test: { + name: "string_with_space_string_with_space_nomatch" + expr: "'hello wello'.lastIndexOf('elbo room!!') == -1" + } + test: { + name: "string_with_space_fullmatch" + expr: "'hello wello'.lastIndexOf('hello wello') == 0" + } + test: { + name: "repeated_string" + expr: "'bananananana'.lastIndexOf('nana', 7) == 6" + } +} +section: { + name: "ascii_casing" + test: { + name: "lowerascii" + expr: "'TacoCat'.lowerAscii() == 'tacocat'" + } + test: { + name: "lowerascii_unicode" + expr: "'TacoCÆt'.lowerAscii() == 'tacocÆt'" + } + test: { + name: "lowerascii_unicode_with_space" + expr: "'TacoCÆt Xii'.lowerAscii() == 'tacocÆt xii'" + } + test: { + name: "upperascii" + expr: "'tacoCat'.upperAscii() == 'TACOCAT'" + } + test: { + name: "upperascii_unicode" + expr: "'tacoCαt'.upperAscii() == 'TACOCαT'" + } + test: { + name: "upperascii_unicode_with_space" + expr: "'TacoCÆt Xii'.upperAscii() == 'TACOCÆT XII'" + } +} +section: { + name: "replace" + test: { + name: "no_placeholder" + expr: "'12 days 12 hours'.replace('{0}', '2') == '12 days 12 hours'" + } + test: { + name: "basic" + expr: "'{0} days {0} hours'.replace('{0}', '2') == '2 days 2 hours'" + } + test: { + name: "chained" + expr: "'{0} days {0} hours'.replace('{0}', '2', 1).replace('{0}', '23') == '2 days 23 hours'" + } + test: { + name: "unicode" + expr: "'1 ©αT taco'.replace('αT', 'o©α') == '1 ©o©α taco'" + } +} +section: { + name: "split" + test: { + name: "empty" + expr: "'hello world'.split(' ') == ['hello', 'world']" + } + test: { + name: "zero_limit" + expr: "'hello world events!'.split(' ', 0) == []" + } + test: { + name: "one_limit" + expr: "'hello world events!'.split(' ', 1) == ['hello world events!']" + } + test: { + name: "unicode_negative_limit" + expr: "'o©o©o©o'.split('©', -1) == ['o', 'o', 'o', 'o']" + } +} +section: { + name: "substring" + test: { + name: "start" + expr: "'tacocat'.substring(4) == 'cat'" + } + test: { + name: "start_with_max_length" + expr: "'tacocat'.substring(7) == ''" + } + test: { + name: "start_and_end" + expr: "'tacocat'.substring(0, 4) == 'taco'" + } + test: { + name: "start_and_end_equal_value" + expr: "'tacocat'.substring(4, 4) == ''" + } + test: { + name: "unicode_start_and_end" + expr: "'ta©o©αT'.substring(2, 6) == '©o©α'" + } + test: { + name: "unicode_start_and_end_equal_value" + expr: "'ta©o©αT'.substring(7, 7) == ''" + } +} +section: { + name: "trim" + test: { + name: "blank_spaces_escaped_chars" + expr: "' \\f\\n\\r\\t\\vtext '.trim() == 'text'" + } + test: { + name: "unicode_space_chars_1" + expr: "'\\u0085\\u00a0\\u1680text'.trim() == 'text'" + } + test: { + name: "unicode_space_chars_2" + expr: "'text\\u2000\\u2001\\u2002\\u2003\\u2004\\u2004\\u2006\\u2007\\u2008\\u2009'.trim() == 'text'" + } + test: { + name: "unicode_space_chars_3" + expr: "'\\u200atext\\u2028\\u2029\\u202F\\u205F\\u3000'.trim() == 'text'" + } + test: { + name: "unicode_no_trim" + expr: "'\\u180etext\\u200b\\u200c\\u200d\\u2060\\ufeff'.trim() == '\\u180etext\\u200b\\u200c\\u200d\\u2060\\ufeff'" + } +} +section: { + name: "join" + test: { + name: "empty_separator" + expr: "['x', 'y'].join() == 'xy'" + } + test: { + name: "dash_separator" + expr: "['x', 'y'].join('-') == 'x-y'" + } + test: { + name: "empty_string_empty_separator" + expr: "[].join() == ''" + } + test: { + name: "empty_string_dash_separator" + expr: "[].join('-') == ''" + } +} +section: { + name: "quote" + test: { + name: "multiline" + expr: "strings.quote(\"first\\nsecond\") == \"\\\"first\\\\nsecond\\\"\"" + } + test: { + name: "escaped" + expr: "strings.quote(\"bell\\a\") == \"\\\"bell\\\\a\\\"\"" + } + test: { + name: "backspace" + expr: "strings.quote(\"\\bbackspace\") == \"\\\"\\\\bbackspace\\\"\"" + } + test: { + name: "form_feed" + expr: "strings.quote(\"\\fform feed\") == \"\\\"\\\\fform feed\\\"\"" + } + test: { + name: "carriage_return" + expr: "strings.quote(\"carriage \\r return\") == \"\\\"carriage \\\\r return\\\"\"" + } + test: { + name: "horizontal_tab" + expr: "strings.quote(\"horizontal tab\\t\") == \"\\\"horizontal tab\\\\t\\\"\"" + } + test: { + name: "vertical_tab" + expr: "strings.quote(\"vertical \\v tab\") == \"\\\"vertical \\\\v tab\\\"\"" + } + test: { + name: "double_slash" + expr: "strings.quote(\"double \\\\\\\\ slash\") == \"\\\"double \\\\\\\\\\\\\\\\ slash\\\"\"" + } + test: { + name: "two_escape_sequences" + expr: "strings.quote(\"two escape sequences \\\\a\\\\n\") == \"\\\"two escape sequences \\\\\\\\a\\\\\\\\n\\\"\"" + } + test: { + name: "verbatim" + expr: "strings.quote(\"verbatim\") == \"\\\"verbatim\\\"\"" + } + test: { + name: "ends_with" + expr: "strings.quote(\"ends with \\\\\") == \"\\\"ends with \\\\\\\\\\\"\"" + } + test: { + name: "starts_with" + expr: "strings.quote(\"\\\\ starts with\") == \"\\\"\\\\\\\\ starts with\\\"\"" + } + test: { + name: "printable_unicode" + expr: "strings.quote(\"printable unicode😀\") == \"\\\"printable unicode😀\\\"\"" + } + test: { + name: "mid_string_quote" + expr: "strings.quote(\"mid string \\\" quote\") == \"\\\"mid string \\\\\\\" quote\\\"\"" + } + test: { + name: "single_quote_with_double_quote" + expr: "strings.quote('single-quote with \"double quote\"') == \"\\\"single-quote with \\\\\\\"double quote\\\\\\\"\\\"\"" + } + test: { + name: "size_unicode_char" + expr: "strings.quote(\"size('ÿ')\") == \"\\\"size('ÿ')\\\"\"" + } + test: { + name: "size_unicode_string" + expr: "strings.quote(\"size('πέντε')\") == \"\\\"size('πέντε')\\\"\"" + } + test: { + name: "unicode" + expr: "strings.quote(\"завтра\") == \"\\\"завтра\\\"\"" + } + test: { + name: "unicode_code_points" + expr: "strings.quote(\"\\U0001F431\\U0001F600\\U0001F61B\")" + value: { + string_value: "\"🐱😀😛\"" + } + } + test: { + name: "unicode_2" + expr: "strings.quote(\"ta©o©αT\") == \"\\\"ta©o©αT\\\"\"" + } + test: { + name: "empty_quote" + expr: "strings.quote(\"\")" + value: { + string_value: "\"\"" + } + } +} +section: { + name: "format" + test: { + name: "no-op" + expr: '"no substitution".format([])' + value: { + string_value: 'no substitution', + } + } + test: { + name: "mid-string substitution" + expr: '"str is %s and some more".format(["filler"])' + value: { + string_value: 'str is filler and some more', + } + } + test: { + name: "percent escaping" + expr: '"%% and also %%".format([])' + value: { + string_value: '% and also %', + } + } + test: { + name: "substitution inside escaped percent signs" + expr: '"%%%s%%".format(["text"])' + value: { + string_value: '%text%', + } + } + test: { + name: "substitution with one escaped percent sign on the right" + expr: '"%s%%".format(["percent on the right"])' + value: { + string_value: 'percent on the right%', + } + } + test: { + name: "substitution with one escaped percent sign on the left" + expr: '"%%%s".format(["percent on the left"])' + value: { + string_value: '%percent on the left', + } + } + test: { + name: "multiple substitutions" + expr: '"%d %d %d, %s %s %s, %d %d %d, %s %s %s".format([1, 2, 3, "A", "B", "C", 4, 5, 6, "D", "E", "F"])' + value: { + string_value: '1 2 3, A B C, 4 5 6, D E F', + } + } + test: { + name: "percent sign escape sequence support" + expr: '"%%escaped %s%%".format(["percent"])' + value: { + string_value: '%escaped percent%', + } + } + test: { + name: "fixed point formatting clause" + expr: '"%.3f".format([1.2345])' + value: { + string_value: '1.234', + } + } + test: { + name: "binary formatting clause" + expr: '"this is 5 in binary: %b".format([5])' + value: { + string_value: 'this is 5 in binary: 101', + } + } + test: { + name: "uint support for binary formatting" + expr: '"unsigned 64 in binary: %b".format([uint(64)])' + value: { + string_value: 'unsigned 64 in binary: 1000000', + } + } + test: { + name: "bool support for binary formatting" + expr: '"bit set from bool: %b".format([true])' + value: { + string_value: 'bit set from bool: 1', + } + } + test: { + name: "octal formatting clause" + expr: '"%o".format([11])' + value: { + string_value: '13', + } + } + test: { + name: "uint support for octal formatting clause" + expr: '"this is an unsigned octal: %o".format([uint(65535)])' + value: { + string_value: 'this is an unsigned octal: 177777', + } + } + test: { + name: "lowercase hexadecimal formatting clause" + expr: '"%x is 20 in hexadecimal".format([30])' + value: { + string_value: '1e is 20 in hexadecimal', + } + } + test: { + name: "uppercase hexadecimal formatting clause" + expr: '"%X is 20 in hexadecimal".format([30])' + value: { + string_value: '1E is 20 in hexadecimal', + } + } + test: { + name: "unsigned support for hexadecimal formatting clause" + expr: '"%X is 6000 in hexadecimal".format([uint(6000)])' + value: { + string_value: '1770 is 6000 in hexadecimal', + } + } + test: { + name: "string support with hexadecimal formatting clause" + expr: '"%x".format(["Hello world!"])' + value: { + string_value: '48656c6c6f20776f726c6421', + } + } + test: { + name: "string support with uppercase hexadecimal formatting clause" + expr: '"%X".format(["Hello world!"])' + value: { + string_value: '48656C6C6F20776F726C6421', + } + } + test: { + name: "byte support with hexadecimal formatting clause" + expr: '"%x".format([b"byte string"])' + value: { + string_value: '6279746520737472696e67', + } + } + test: { + name: "byte support with uppercase hexadecimal formatting clause" + expr: '"%X".format([b"byte string"])' + value: { + string_value: '6279746520737472696E67', + } + } + test: { + name: "scientific notation formatting clause" + expr: '"%.6e".format([1052.032911275])' + value: { + string_value: '1.052033e+03', + } + } + test: { + name: "default precision for fixed-point clause" + expr: '"%f".format([2.71828])' + value: { + string_value: '2.718280', + } + } + test: { + name: "default precision for scientific notation" + expr: '"%e".format([2.71828])' + value: { + string_value: '2.718280e+00', + } + } + test: { + name: "NaN support for scientific notation" + expr: '"%e".format([double("NaN")])' + value: { + string_value: 'NaN', + } + } + test: { + name: "positive infinity support for scientific notation" + expr: '"%e".format([double("Infinity")])' + value: { + string_value: 'Infinity', + } + } + test: { + name: "negative infinity support for scientific notation" + expr: '"%e".format([double("-Infinity")])' + value: { + string_value: '-Infinity', + } + } + test: { + name: "NaN support for decimal" + expr: '"%d".format([double("NaN")])' + value: { + string_value: 'NaN', + } + } + test: { + name: "positive infinity support for decimal" + expr: '"%d".format([double("Infinity")])' + value: { + string_value: 'Infinity', + } + } + test: { + name: "negative infinity support for decimal" + expr: '"%d".format([double("-Infinity")])' + value: { + string_value: '-Infinity', + } + } + test: { + name: "NaN support for fixed-point" + expr: '"%f".format([double("NaN")])' + value: { + string_value: 'NaN', + } + } + test: { + name: "positive infinity support for fixed-point" + expr: '"%f".format([double("Infinity")])' + value: { + string_value: 'Infinity', + } + } + test: { + name: "negative infinity support for fixed-point" + expr: '"%f".format([double("-Infinity")])' + value: { + string_value: '-Infinity', + } + } + test: { + name: "uint support for decimal clause" + expr: '"%d".format([uint(64)])' + value: { + string_value: '64', + } + } + test: { + name: "null support for string" + expr: '"%s".format([null])' + value: { + string_value: 'null', + } + } + test: { + name: "int support for string" + expr: '"%s".format([999999999999])' + value: { + string_value: '999999999999', + } + } + test: { + name: "bytes support for string" + expr: '"%s".format([b"xyz"])' + value: { + string_value: 'xyz', + } + } + test: { + name: "type() support for string" + expr: '"%s".format([type("test string")])' + value: { + string_value: 'string', + } + } + test: { + name: "timestamp support for string" + expr: '"%s".format([timestamp("2023-02-03T23:31:20+00:00")])' + value: { + string_value: '2023-02-03T23:31:20Z', + } + } + test: { + name: "duration support for string" + expr: '"%s".format([duration("1h45m47s")])' + value: { + string_value: '6347s', + } + } + test: { + name: "list support for string" + expr: '"%s".format([["abc", 3.14, null, [9, 8, 7, 6], timestamp("2023-02-03T23:31:20Z")]])' + value: { + string_value: '[abc, 3.14, null, [9, 8, 7, 6], 2023-02-03T23:31:20Z]', + } + } + test: { + name: "map support for string" + expr: '"%s".format([{"key1": b"xyz", "key5": null, "key2": duration("2h"), "key4": true, "key3": 2.71828}])' + value: { + string_value: '{key1: xyz, key2: 7200s, key3: 2.71828, key4: true, key5: null}', + } + } + test: { + name: "map support (all key types)" + expr: '"%s".format([{1: "value1", uint(2): "value2", true: double("NaN")}])' + value: { + string_value: '{1: value1, 2: value2, true: NaN}', + } + } + test: { + name: "boolean support for %s" + expr: '"%s, %s".format([true, false])' + value: { + string_value: 'true, false', + } + } + test: { + name: "dyntype support for string formatting clause" + expr: '"%s".format([dyn("a string")])' + value: { + string_value: 'a string', + } + } + test: { + name: "dyntype support for numbers with string formatting clause" + expr: '"%s, %s".format([dyn(32), dyn(56.8)])' + value: { + string_value: '32, 56.8', + } + } + test: { + name: "dyntype support for integer formatting clause" + expr: '"%d".format([dyn(128)])' + value: { + string_value: '128', + } + } + test: { + name: "dyntype support for integer formatting clause (unsigned)" + expr: '"%d".format([dyn(256u)])' + value: { + string_value: '256', + } + } + test: { + name: "dyntype support for hex formatting clause" + expr: '"%x".format([dyn(22)])' + value: { + string_value: '16', + } + } + test: { + name: "dyntype support for hex formatting clause (uppercase)" + expr: '"%X".format([dyn(26)])' + value: { + string_value: '1A', + } + } + test: { + name: "dyntype support for unsigned hex formatting clause" + expr: '"%x".format([dyn(500u)])' + value: { + string_value: '1f4', + } + } + test: { + name: "dyntype support for fixed-point formatting clause" + expr: '"%.3f".format([dyn(4.5)])' + value: { + string_value: '4.500', + } + } + test: { + name: "dyntype support for scientific notation" + expr: '"%e".format([dyn(2.71828)])' + value: { + string_value: '2.718280e+00', + } + } + test: { + name: "dyntype NaN/infinity support" + expr: '"%s".format([[double("NaN"), double("Infinity"), double("-Infinity")]])' + value: { + string_value: '[NaN, Infinity, -Infinity]', + } + } + test: { + name: "dyntype support for timestamp" + expr: '"%s".format([dyn(timestamp("2009-11-10T23:00:00Z"))])' + value: { + string_value: '2009-11-10T23:00:00Z', + } + } + test: { + name: "dyntype support for duration" + expr: '"%s".format([dyn(duration("8747s"))])' + value: { + string_value: '8747s', + } + } + test: { + name: "dyntype support for lists" + expr: '"%s".format([dyn([6, 4.2, "a string"])])' + value: { + string_value: '[6, 4.2, a string]', + } + } + test: { + name: "dyntype support for maps" + expr: '"%s".format([{"strKey":"x", 6:duration("422s"), true:42}])' + value: { + string_value: '{6: 422s, strKey: x, true: 42}', + } + } + test: { + name: "string substitution in a string variable" + expr: 'str_var.format(["filler"])' + type_env: { + name: "str_var", + ident: { type: { primitive: STRING } } + } + bindings: { + key: "str_var" + value: { value: { string_value: "%s" } } + } + value: { + string_value: 'filler', + } + } + test: { + name: "multiple substitutions in a string variable" + expr: 'str_var.format([1, 2, 3, "A", "B", "C", 4, 5, 6, "D", "E", "F"])' + type_env: { + name: "str_var", + ident: { type: { primitive: STRING } } + } + bindings: { + key: "str_var" + value: { value: { string_value: "%d %d %d, %s %s %s, %d %d %d, %s %s %s" } } + } + value: { + string_value: '1 2 3, A B C, 4 5 6, D E F', + } + } + test: { + name: "substitution inside escaped percent signs in a string variable" + expr: 'str_var.format(["text"])' + type_env: { + name: "str_var", + ident: { type: { primitive: STRING } } + } + bindings: { + key: "str_var" + value: { value: { string_value: "%%%s%%" } } + } + value: { + string_value: '%text%', + } + } + test: { + name: "fixed point formatting clause in a string variable" + expr: 'str_var.format([1.2345])' + type_env: { + name: "str_var", + ident: { type: { primitive: STRING } } + } + bindings: { + key: "str_var" + value: { value: { string_value: "%.3f" } } + } + value: { + string_value: '1.234', + } + } + test: { + name: "binary formatting clause in a string variable" + expr: 'str_var.format([5])' + type_env: { + name: "str_var", + ident: { type: { primitive: STRING } } + } + bindings: { + key: "str_var" + value: { value: { string_value: "%b" } } + } + value: { + string_value: '101', + } + } + test: { + name: "scientific notation formatting clause in a string variable" + expr: 'str_var.format([1052.032911275])' + type_env: { + name: "str_var", + ident: { type: { primitive: STRING } } + } + bindings: { + key: "str_var" + value: { value: { string_value: "%.6e" } } + } + value: { + string_value: '1.052033e+03', + } + } + test: { + name: "default precision for fixed-point clause in a string variable" + expr: 'str_var.format([2.71828])' + type_env: { + name: "str_var", + ident: { type: { primitive: STRING } } + } + bindings: { + key: "str_var" + value: { value: { string_value: "%f" } } + } + value: { + string_value: '2.718280', + } + } +} +section: { + name: "format_errors" + test: { + name: "unrecognized formatting clause" + expr: '"%a".format([1])' + disable_check: true + eval_error: { + errors: { + message: 'could not parse formatting clause: unrecognized formatting clause "a"' + } + } + } + test: { + name: "out of bounds arg index" + expr: '"%d %d %d".format([0, 1])' + disable_check: true + eval_error: { + errors: { + message: 'index 2 out of range' + } + } + } + test: { + name: "string substitution is not allowed with binary clause" + expr: '"string is %b".format(["abc"])' + disable_check: true + eval_error: { + errors: { + message: 'error during formatting: only integers and bools can be formatted as binary, was given string' + } + } + } + test: { + name: "duration substitution not allowed with decimal clause" + expr: '"%d".format([duration("30m2s")])' + disable_check: true + eval_error: { + errors: { + message: 'error during formatting: decimal clause can only be used on integers, was given google.protobuf.Duration' + } + } + } + test: { + name: "string substitution not allowed with octal clause" + expr: '"octal: %o".format(["a string"])' + disable_check: true + eval_error: { + errors: { + message: 'error during formatting: octal clause can only be used on integers, was given string' + } + } + } + test: { + name: "double substitution not allowed with hex clause" + expr: '"double is %x".format([0.5])' + disable_check: true + eval_error: { + errors: { + message: 'error during formatting: only integers, byte buffers, and strings can be formatted as hex, was given double' + } + } + } + test: { + name: "uppercase not allowed for scientific clause" + expr: '"double is %E".format([0.5])' + disable_check: true + eval_error: { + errors: { + message: 'could not parse formatting clause: unrecognized formatting clause "E"' + } + } + } + test: { + name: "object not allowed" + expr: '"object is %s".format([cel.expr.conformance.proto3.TestAllTypes{}])' + disable_check: true + eval_error: { + errors: { + message: 'error during formatting: string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps, was given cel.expr.conformance.proto3.TestAllTypes' + } + } + } + test: { + name: "object inside list" + expr: '"%s".format([[1, 2, cel.expr.conformance.proto3.TestAllTypes{}]])' + disable_check: true + eval_error: { + errors: { + message: 'error during formatting: string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps, was given cel.expr.conformance.proto3.TestAllTypes' + } + } + } + test: { + name: "object inside map" + expr: '"%s".format([{1: "a", 2: cel.expr.conformance.proto3.TestAllTypes{}}])' + disable_check: true + eval_error: { + errors: { + message: 'error during formatting: string clause can only be used on strings, bools, bytes, ints, doubles, maps, lists, types, durations, and timestamps, was given cel.expr.conformance.proto3.TestAllTypes' + } + } + } + test: { + name: "null not allowed for %d" + expr: '"null: %d".format([null])' + disable_check: true + eval_error: { + errors: { + message: 'error during formatting: decimal clause can only be used on integers, was given null_type' + } + } + } + test: { + name: "null not allowed for %e" + expr: '"null: %e".format([null])' + disable_check: true + eval_error: { + errors: { + message: 'error during formatting: scientific clause can only be used on doubles, was given null_type' + } + } + } + test: { + name: "null not allowed for %f" + expr: '"null: %f".format([null])' + disable_check: true + eval_error: { + errors: { + message: 'error during formatting: fixed-point clause can only be used on doubles, was given null_type' + } + } + } + test: { + name: "null not allowed for %x" + expr: '"null: %x".format([null])' + disable_check: true + eval_error: { + errors: { + message: 'error during formatting: only integers, byte buffers, and strings can be formatted as hex, was given null_type' + } + } + } + test: { + name: "null not allowed for %X" + expr: '"null: %X".format([null])' + disable_check: true + eval_error: { + errors: { + message: 'error during formatting: only integers, byte buffers, and strings can be formatted as hex, was given null_type' + } + } + } + test: { + name: "null not allowed for %b" + expr: '"null: %b".format([null])' + disable_check: true + eval_error: { + errors: { + message: 'error during formatting: only integers and bools can be formatted as binary, was given null_type' + } + } + } + test: { + name: "null not allowed for %o" + expr: '"null: %o".format([null])' + disable_check: true + eval_error: { + errors: { + message: 'error during formatting: octal clause can only be used on integers, was given null_type' + } + } + } +} +section: { + name: "value_errors" + test: { + name: "charat_out_of_range" + expr: "'tacocat'.charAt(30) == ''" + eval_error: { + errors: { + message: "index out of range: 30" + } + } + } + test: { + name: "indexof_out_of_range" + expr: "'tacocat'.indexOf('a', 30) == -1" + eval_error: { + errors: { + message: "index out of range: 30" + } + } + } + test: { + name: "lastindexof_negative_index" + expr: "'tacocat'.lastIndexOf('a', -1) == -1" + eval_error: { + errors: { + message: "index out of range: -1" + } + } + } + test: { + name: "lastindexof_out_of_range" + expr: "'tacocat'.lastIndexOf('a', 30) == -1" + eval_error: { + errors: { + message: "index out of range: 30" + } + } + } + test: { + name: "substring_out_of_range" + expr: "'tacocat'.substring(40) == 'cat'" + eval_error: { + errors: { + message: "index out of range: 40" + } + } + } + test: { + name: "substring_negative_index" + expr: "'tacocat'.substring(-1) == 'cat'" + eval_error: { + errors: { + message: "index out of range: -1" + } + } + } + test: { + name: "substring_end_index_out_of_range" + expr: "'tacocat'.substring(1, 50) == 'cat'" + eval_error: { + errors: { + message: "index out of range: 50" + } + } + } + test: { + name: "substring_begin_index_out_of_range" + expr: "'tacocat'.substring(49, 50) == 'cat'" + eval_error: { + errors: { + message: "index out of range: 49" + } + } + } + test: { + name: "substring_end_index_greater_than_begin_index" + expr: "'tacocat'.substring(4, 3) == ''" + eval_error: { + errors: { + message: "invalid substring range. start: 4, end: 3" + } + } + } +} +section: { + name: "type_errors" + test: { + name: "charat_invalid_type" + expr: "42.charAt(2) == ''" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "charat_invalid_argument" + expr: "'hello'.charAt(true) == ''" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "indexof_unary_invalid_type" + expr: "24.indexOf('2') == 0" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "indexof_unary_invalid_argument" + expr: "'hello'.indexOf(true) == 1" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "indexof_binary_invalid_argument" + expr: "42.indexOf('4', 0) == 0" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "indexof_binary_invalid_argument_2" + expr: "'42'.indexOf(4, 0) == 0" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "indexof_binary_both_invalid_arguments" + expr: "'42'.indexOf('4', '0') == 0" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "indexof_ternary_invalid_arguments" + expr: "'42'.indexOf('4', 0, 1) == 0" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "split_invalid_type" + expr: "42.split('2') == ['4']" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "replace_invalid_type" + expr: "42.replace(2, 1) == '41'" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "replace_binary_invalid_argument" + expr: "'42'.replace(2, 1) == '41'" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "replace_binary_invalid_argument_2" + expr: "'42'.replace('2', 1) == '41'" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "replace_ternary_invalid_argument" + expr: "42.replace('2', '1', 1) == '41'" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "replace_ternary_invalid_argument_2" + expr: "'42'.replace(2, '1', 1) == '41'" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "replace_ternary_invalid_argument_3" + expr: "'42'.replace('2', 1, 1) == '41'" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "replace_ternary_invalid_argument_4" + expr: "'42'.replace('2', '1', '1') == '41'" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "replace_quaternary_invalid_argument" + expr: "'42'.replace('2', '1', 1, false) == '41'" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "split_invalid_type_empty_arg" + expr: "42.split('') == ['4', '2']" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "split_invalid_argument" + expr: "'42'.split(2) == ['4']" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "split_binary_invalid_type" + expr: "42.split('2', '1') == ['4']" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "split_binary_invalid_argument" + expr: "'42'.split(2, 1) == ['4']" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "split_binary_invalid_argument_2" + expr: "'42'.split('2', '1') == ['4']" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "split_ternary_invalid_argument" + expr: "'42'.split('2', 1, 1) == ['4']" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "substring_ternary_invalid_argument" + expr: "'hello'.substring(1, 2, 3) == ''" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "substring_binary_invalid_type" + expr: "30.substring(true, 3) == ''" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "substring_binary_invalid_argument" + expr: "'tacocat'.substring(true, 3) == ''" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } + test: { + name: "substring_binary_invalid_argument_2" + expr: "'tacocat'.substring(0, false) == ''" + disable_check: true + eval_error: { + errors: { + message: "no such overload" + } + } + } +} From f001e593b442b8d5e5aed995de99f722c948e239 Mon Sep 17 00:00:00 2001 From: Steve Ayers Date: Tue, 20 May 2025 11:30:12 -0400 Subject: [PATCH 3/7] Format tests --- Makefile | 12 +- gen/tests/example/v1/predefined_pb2.py | 68 + gen/tests/example/v1/predefined_pb2.pyi | 37 + proto/__init__.py | 18 + proto/tests/example/v1/predefined.proto | 61 + proto/tests/example/v1/validations.proto | 11 + protovalidate/internal/string_format.py | 235 ++- string_ext.textproto | 1974 ---------------------- tests/format_test.py | 76 +- tests/validate_test.py | 16 + 10 files changed, 443 insertions(+), 2065 deletions(-) create mode 100644 gen/tests/example/v1/predefined_pb2.py create mode 100644 gen/tests/example/v1/predefined_pb2.pyi create mode 100644 proto/__init__.py create mode 100644 proto/tests/example/v1/predefined.proto delete mode 100644 string_ext.textproto diff --git a/Makefile b/Makefile index dde5149a..f880fd7c 100644 --- a/Makefile +++ b/Makefile @@ -18,8 +18,10 @@ ADD_LICENSE_HEADER := $(BIN)/license-header \ --year-range "2023-2025" # This version should be kept in sync with the version in buf.yaml PROTOVALIDATE_VERSION ?= v0.11.0 - +# Version of the cel-spec that this implementation is conformant with +# This should be kept in sync with the version in format_test.py CEL_SPEC_VERSION ?= v0.24.0 +TESTDATA_FILE := tests/testdata/string_ext_$(CEL_SPEC_VERSION).textproto .PHONY: help help: ## Describe useful make targets @@ -73,9 +75,11 @@ checkgenerate: generate test -z "$$(git status --porcelain | tee /dev/stderr)" .PHONY: gettestdata -gettestdata: generate - mkdir -p tests/testdata - curl -fsSL -o tests/testdata/string_ext_$(CEL_SPEC_VERSION).textproto https://raw.githubusercontent.com/google/cel-spec/refs/tags/$(CEL_SPEC_VERSION)/tests/simple/testdata/string_ext.textproto +gettestdata: $(TESTDATA_FILE) + +$(TESTDATA_FILE): + mkdir -p $(dir @) + curl -fsSL -o $@ https://raw.githubusercontent.com/google/cel-spec/refs/tags/$(CEL_SPEC_VERSION)/tests/simple/testdata/string_ext.textproto $(BIN): @mkdir -p $(BIN) diff --git a/gen/tests/example/v1/predefined_pb2.py b/gen/tests/example/v1/predefined_pb2.py new file mode 100644 index 00000000..2656fb13 --- /dev/null +++ b/gen/tests/example/v1/predefined_pb2.py @@ -0,0 +1,68 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: tests/example/v1/predefined.proto +# Protobuf Python Version: 6.30.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 30, + 1, + '', + 'tests/example/v1/predefined.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from buf.validate import validate_pb2 as buf_dot_validate_dot_validate__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!tests/example/v1/predefined.proto\x12\x10tests.example.v1\x1a\x1b\x62uf/validate/validate.proto:\xc3\x01\n\x05maxim\x12\x16.buf.validate.MapRules\x18\x88\x0e \x01(\x04\x42\x93\x01\xc2H\x8f\x01\n\x8c\x01\n\tmap.maxim\x1a\x7fuint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{1: \'value1\', uint(2): \'keytruda\', true: double(\'NaN\')}]) : \'\'R\x05maxim:\xad\x01\n\x06maxim2\x12\x16.buf.validate.MapRules\x18\x89\x0e \x01(\x04\x42|\xc2Hy\nw\n\tmap.maxim\x1ajuint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{1: \'value1\', uint(2): \'keytruda\'}]) : \'\'R\x06maxim2:\xb7\x01\n\x06maxim3\x12\x16.buf.validate.MapRules\x18\x8a\x0e \x01(\x04\x42\x85\x01\xc2H\x81\x01\n\x7f\n\tmap.maxim\x1aruint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{uint(2): \'keytruda\', true: double(\'NaN\')}]) : \'\'R\x06maxim3:\xad\x01\n\x06maxim4\x12\x16.buf.validate.MapRules\x18\x8b\x0e \x01(\x04\x42|\xc2Hy\nw\n\tmap.maxim\x1ajuint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{1: \'value1\', true: double(\'NaN\')}]) : \'\'R\x06maxim4:\xb4\x01\n\x06maxim5\x12\x16.buf.validate.MapRules\x18\x8c\x0e \x01(\x04\x42\x82\x01\xc2H\x7f\n}\n\tmap.maxim\x1apuint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{uint(1): \'value1\', true: double(\'NaN\')}]) : \'\'R\x06maxim5:\xb4\x01\n\x06maxim6\x12\x16.buf.validate.MapRules\x18\x8d\x0e \x01(\x04\x42\x82\x01\xc2H\x7f\n}\n\tmap.maxim\x1apuint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{uint(6): \'value1\', true: double(\'NaN\')}]) : \'\'R\x06maxim6:\xad\x01\n\x06maxim7\x12\x16.buf.validate.MapRules\x18\x8e\x0e \x01(\x04\x42|\xc2Hy\nw\n\tmap.maxim\x1ajuint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{6: \'value1\', true: double(\'NaN\')}]) : \'\'R\x06maxim7:\xad\x01\n\x06maxim8\x12\x16.buf.validate.MapRules\x18\x8f\x0e \x01(\x04\x42|\xc2Hy\nw\n\tmap.maxim\x1ajuint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{2: \'value1\', true: double(\'NaN\')}]) : \'\'R\x06maxim8:\xae\x01\n\x06maxim9\x12\x16.buf.validate.MapRules\x18\x90\x0e \x01(\x04\x42}\xc2Hz\nx\n\tmap.maxim\x1akuint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{0: \'value1\', false: double(\'NaN\')}]) : \'\'R\x06maxim9B\x89\x01\n\x14\x63om.tests.example.v1B\x0fPredefinedProtoP\x01\xa2\x02\x03TEX\xaa\x02\x10Tests.Example.V1\xca\x02\x10Tests\\Example\\V1\xe2\x02\x1cTests\\Example\\V1\\GPBMetadata\xea\x02\x12Tests::Example::V1') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tests.example.v1.predefined_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\024com.tests.example.v1B\017PredefinedProtoP\001\242\002\003TEX\252\002\020Tests.Example.V1\312\002\020Tests\\Example\\V1\342\002\034Tests\\Example\\V1\\GPBMetadata\352\002\022Tests::Example::V1' + _globals['maxim']._loaded_options = None + _globals['maxim']._serialized_options = b'\302H\217\001\n\214\001\n\tmap.maxim\032\177uint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{1: \'value1\', uint(2): \'keytruda\', true: double(\'NaN\')}]) : \'\'' + _globals['maxim2']._loaded_options = None + _globals['maxim2']._serialized_options = b'\302Hy\nw\n\tmap.maxim\032juint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{1: \'value1\', uint(2): \'keytruda\'}]) : \'\'' + _globals['maxim3']._loaded_options = None + _globals['maxim3']._serialized_options = b'\302H\201\001\n\177\n\tmap.maxim\032ruint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{uint(2): \'keytruda\', true: double(\'NaN\')}]) : \'\'' + _globals['maxim4']._loaded_options = None + _globals['maxim4']._serialized_options = b'\302Hy\nw\n\tmap.maxim\032juint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{1: \'value1\', true: double(\'NaN\')}]) : \'\'' + _globals['maxim5']._loaded_options = None + _globals['maxim5']._serialized_options = b'\302H\177\n}\n\tmap.maxim\032puint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{uint(1): \'value1\', true: double(\'NaN\')}]) : \'\'' + _globals['maxim6']._loaded_options = None + _globals['maxim6']._serialized_options = b'\302H\177\n}\n\tmap.maxim\032puint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{uint(6): \'value1\', true: double(\'NaN\')}]) : \'\'' + _globals['maxim7']._loaded_options = None + _globals['maxim7']._serialized_options = b'\302Hy\nw\n\tmap.maxim\032juint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{6: \'value1\', true: double(\'NaN\')}]) : \'\'' + _globals['maxim8']._loaded_options = None + _globals['maxim8']._serialized_options = b'\302Hy\nw\n\tmap.maxim\032juint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{2: \'value1\', true: double(\'NaN\')}]) : \'\'' + _globals['maxim9']._loaded_options = None + _globals['maxim9']._serialized_options = b'\302Hz\nx\n\tmap.maxim\032kuint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{0: \'value1\', false: double(\'NaN\')}]) : \'\'' +# @@protoc_insertion_point(module_scope) diff --git a/gen/tests/example/v1/predefined_pb2.pyi b/gen/tests/example/v1/predefined_pb2.pyi new file mode 100644 index 00000000..21167323 --- /dev/null +++ b/gen/tests/example/v1/predefined_pb2.pyi @@ -0,0 +1,37 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +from buf.validate import validate_pb2 as _validate_pb2 +from google.protobuf import descriptor as _descriptor +from typing import ClassVar as _ClassVar + +DESCRIPTOR: _descriptor.FileDescriptor +MAXIM_FIELD_NUMBER: _ClassVar[int] +maxim: _descriptor.FieldDescriptor +MAXIM2_FIELD_NUMBER: _ClassVar[int] +maxim2: _descriptor.FieldDescriptor +MAXIM3_FIELD_NUMBER: _ClassVar[int] +maxim3: _descriptor.FieldDescriptor +MAXIM4_FIELD_NUMBER: _ClassVar[int] +maxim4: _descriptor.FieldDescriptor +MAXIM5_FIELD_NUMBER: _ClassVar[int] +maxim5: _descriptor.FieldDescriptor +MAXIM6_FIELD_NUMBER: _ClassVar[int] +maxim6: _descriptor.FieldDescriptor +MAXIM7_FIELD_NUMBER: _ClassVar[int] +maxim7: _descriptor.FieldDescriptor +MAXIM8_FIELD_NUMBER: _ClassVar[int] +maxim8: _descriptor.FieldDescriptor +MAXIM9_FIELD_NUMBER: _ClassVar[int] +maxim9: _descriptor.FieldDescriptor diff --git a/proto/__init__.py b/proto/__init__.py new file mode 100644 index 00000000..062464d7 --- /dev/null +++ b/proto/__init__.py @@ -0,0 +1,18 @@ +# Copyright 2023-2025 Buf Technologies, Inc. +# +# 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 +# +# http://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. + +import os +import sys + +sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) diff --git a/proto/tests/example/v1/predefined.proto b/proto/tests/example/v1/predefined.proto new file mode 100644 index 00000000..d17024bd --- /dev/null +++ b/proto/tests/example/v1/predefined.proto @@ -0,0 +1,61 @@ +// Copyright 2023-2025 Buf Technologies, Inc. +// +// 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 +// +// http://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. + +syntax = "proto2"; + +package tests.example.v1; + +import "buf/validate/validate.proto"; + +extend buf.validate.MapRules { + optional uint64 maxim = 1800 [(buf.validate.predefined).cel = { + id: "map.maxim" + expression: "uint(this.size()) > 2 ? 'map must be at most %s entries'.format([{1: 'value1', uint(2): 'keytruda', true: double('NaN')}]) : ''" + }]; + optional uint64 maxim2 = 1801 [(buf.validate.predefined).cel = { + id: "map.maxim" + expression: "uint(this.size()) > 2 ? 'map must be at most %s entries'.format([{1: 'value1', uint(2): 'keytruda'}]) : ''" + }]; + optional uint64 maxim3 = 1802 [(buf.validate.predefined).cel = { + id: "map.maxim" + expression: "uint(this.size()) > 2 ? 'map must be at most %s entries'.format([{uint(2): 'keytruda', true: double('NaN')}]) : ''" + }]; + optional uint64 maxim4 = 1803 [(buf.validate.predefined).cel = { + id: "map.maxim" + expression: "uint(this.size()) > 2 ? 'map must be at most %s entries'.format([{1: 'value1', true: double('NaN')}]) : ''" + }]; + optional uint64 maxim5 = 1804 [(buf.validate.predefined).cel = { + id: "map.maxim" + expression: "uint(this.size()) > 2 ? 'map must be at most %s entries'.format([{uint(1): 'value1', true: double('NaN')}]) : ''" + }]; + optional uint64 maxim6 = 1805 [(buf.validate.predefined).cel = { + id: "map.maxim" + expression: "uint(this.size()) > 2 ? 'map must be at most %s entries'.format([{uint(6): 'value1', true: double('NaN')}]) : ''" + }]; + optional uint64 maxim7 = 1806 [(buf.validate.predefined).cel = { + id: "map.maxim" + expression: "uint(this.size()) > 2 ? 'map must be at most %s entries'.format([{6: 'value1', true: double('NaN')}]) : ''" + }]; + optional uint64 maxim8 = 1807 [(buf.validate.predefined).cel = { + id: "map.maxim" + expression: "uint(this.size()) > 2 ? 'map must be at most %s entries'.format([{2: 'value1', true: double('NaN')}]) : ''" + }]; + optional uint64 maxim9 = 1808 [(buf.validate.predefined).cel = { + id: "map.maxim" + expression: "uint(this.size()) > 2 ? 'map must be at most %s entries'.format([{0: 'value1', false: double('NaN')}]) : ''" + }]; +} + +// 4, 5, 1 don't work + diff --git a/proto/tests/example/v1/validations.proto b/proto/tests/example/v1/validations.proto index 4fff574d..d0930ffb 100644 --- a/proto/tests/example/v1/validations.proto +++ b/proto/tests/example/v1/validations.proto @@ -63,3 +63,14 @@ message Embed { message RepeatedEmbedSkip { repeated Embed val = 1 [(buf.validate.field).repeated.items.ignore = IGNORE_ALWAYS]; } +/* message MapInts { */ +/* map stuff = 1 [(buf.validate.field).map.(maxim) = 4]; */ +/* map stuff2 = 2 [(buf.validate.field).map.(maxim2) = 4]; */ +/* map stuff3 = 3 [(buf.validate.field).map.(maxim3) = 4]; */ +/* map stuff4 = 4 [(buf.validate.field).map.(maxim4) = 4]; */ +/* map stuff5 = 5 [(buf.validate.field).map.(maxim5) = 4]; */ +/* map stuff6 = 6 [(buf.validate.field).map.(maxim6) = 4]; */ +/* map stuff7 = 7 [(buf.validate.field).map.(maxim7) = 4]; */ +/* map stuff8 = 8 [(buf.validate.field).map.(maxim8) = 4]; */ +/* map stuff9 = 9 [(buf.validate.field).map.(maxim9) = 4]; */ +/* } */ diff --git a/protovalidate/internal/string_format.py b/protovalidate/internal/string_format.py index b6009266..84ef70b8 100644 --- a/protovalidate/internal/string_format.py +++ b/protovalidate/internal/string_format.py @@ -12,38 +12,20 @@ # See the License for the specific language governing permissions and # limitations under the License. -# type: ignore -# TODO(#257): Fully test and fix types in this file. - +import math from decimal import Decimal +from typing import Optional, Union import celpy from celpy import celtypes -QUOTE_TRANS = str.maketrans( - { - "\a": r"\a", - "\b": r"\b", - "\f": r"\f", - "\n": r"\n", - "\r": r"\r", - "\t": r"\t", - "\v": r"\v", - "\\": r"\\", - '"': r"\"", - } -) - - -def quote(s: str) -> str: - return '"' + s.translate(QUOTE_TRANS) + '"' - class StringFormat: """An implementation of string.format() in CEL.""" def __init__(self, locale: str): self.locale = locale + self.fmt = None def format(self, fmt: celtypes.Value, args: celtypes.Value) -> celpy.Result: if not isinstance(fmt, celtypes.StringType): @@ -65,7 +47,7 @@ def format(self, fmt: celtypes.Value, args: celtypes.Value) -> celpy.Result: i += 2 continue if j >= len(args): - return celpy.CELEvalError("format() not enough arguments for format string") + return celpy.CELEvalError(f"index {j} out of range") arg = args[j] j += 1 i += 1 @@ -81,101 +63,206 @@ def format(self, fmt: celtypes.Value, args: celtypes.Value) -> celpy.Result: if i >= len(fmt): return celpy.CELEvalError("format() incomplete format specifier") if fmt[i] == "f": - result += self.format_float(arg, precision) + result += self.__format_float(arg, precision) elif fmt[i] == "e": - result += self.format_exponential(arg, precision) + result += self.__format_exponential(arg, precision) elif fmt[i] == "d": - result += self.format_int(arg) + result += self.__format_int(arg) elif fmt[i] == "s": - result += self.format_string(arg) + result += self.__format_string(arg) elif fmt[i] == "x": - result += self.format_hex(arg) + result += self.__format_hex(arg) elif fmt[i] == "X": - result += self.format_hex(arg).upper() + result += self.__format_hex(arg).upper() elif fmt[i] == "o": - result += self.format_oct(arg) + result += self.__format_oct(arg) elif fmt[i] == "b": - result += self.format_bin(arg) + result += self.__format_bin(arg) else: - return celpy.CELEvalError("format() unknown format specifier: " + fmt[i]) + return celpy.CELEvalError( + f'could not parse formatting clause: unrecognized formatting clause "{fmt[i]}"' + ) i += 1 if j < len(args): return celpy.CELEvalError("format() too many arguments for format string") + return celtypes.StringType(result) - def format_float(self, arg: celtypes.Value, precision: int) -> celpy.Result: + def __validate_number(self, arg: Union[celtypes.DoubleType, celtypes.IntType, celtypes.UintType]) -> Optional[str]: + if math.isnan(arg): + return "NaN" + if math.isinf(arg): + if arg < 0: + return "-Infinity" + return "Infinity" + return None + + def __format_float(self, arg: celtypes.Value, precision: int) -> str: if isinstance(arg, celtypes.DoubleType): - return celtypes.StringType(f"{arg:.{precision}f}") - return self.format_int(arg) + result = self.__validate_number(arg) + if result is not None: + return result + return f"{arg:.{precision}f}" + msg = ( + "error during formatting: fixed-point clause can only be used on doubles, was given " + f"{self.__type_str(type(arg))}" + ) + raise celpy.CELEvalError(msg) - def format_exponential(self, arg: celtypes.Value, precision: int) -> celpy.Result: + def __format_exponential(self, arg: celtypes.Value, precision: int) -> str: if isinstance(arg, celtypes.DoubleType): - return celtypes.StringType(f"{arg:.{precision}e}") - return self.format_int(arg) + result = self.__validate_number(arg) + if result is not None: + return result + return f"{arg:.{precision}e}" + msg = ( + "error during formatting: scientific clause can only be used on doubles, was given " + f"{self.__type_str(type(arg))}" + ) + raise celpy.CELEvalError(msg) - def format_int(self, arg: celtypes.Value) -> celpy.Result: - if isinstance(arg, celtypes.IntType): - return celtypes.StringType(arg) - if isinstance(arg, celtypes.UintType): - return celtypes.StringType(arg) - return celpy.CELEvalError("format_int() requires an integer argument") + def __format_int(self, arg: celtypes.Value) -> str: + if ( + isinstance(arg, celtypes.IntType) + or isinstance(arg, celtypes.UintType) + or isinstance(arg, celtypes.DoubleType) + ): + result = self.__validate_number(arg) + if result is not None: + return result + return f"{arg}" + msg = ( + "error during formatting: decimal clause can only be used on integers, was given " + f"{self.__type_str(type(arg))}" + ) + raise celpy.CELEvalError(msg) - def format_hex(self, arg: celtypes.Value) -> celpy.Result: + def __format_hex(self, arg: celtypes.Value) -> str: if isinstance(arg, celtypes.IntType): - return celtypes.StringType(f"{arg:x}") + return f"{arg:x}" if isinstance(arg, celtypes.UintType): - return celtypes.StringType(f"{arg:x}") + return f"{arg:x}" if isinstance(arg, celtypes.BytesType): - return celtypes.StringType(arg.hex()) + return arg.hex() if isinstance(arg, celtypes.StringType): - return celtypes.StringType(arg.encode("utf-8").hex()) - return celpy.CELEvalError("format_hex() requires an integer, string, or binary argument") + return arg.encode("utf-8").hex() + msg = ( + "error during formatting: only integers, byte buffers, and strings can be formatted as hex, was given " + f"{self.__type_str(type(arg))}" + ) + raise celpy.CELEvalError(msg) - def format_oct(self, arg: celtypes.Value) -> celpy.Result: + def __format_oct(self, arg: celtypes.Value) -> str: if isinstance(arg, celtypes.IntType): - return celtypes.StringType(f"{arg:o}") + return f"{arg:o}" if isinstance(arg, celtypes.UintType): - return celtypes.StringType(f"{arg:o}") - return celpy.CELEvalError("format_oct() requires an integer argument") + return f"{arg:o}" + msg = ( + "error during formatting: octal clause can only be used on integers, was given " + f"{self.__type_str(type(arg))}" + ) + raise celpy.CELEvalError(msg) - def format_bin(self, arg: celtypes.Value) -> celpy.Result: + def __format_bin(self, arg: celtypes.Value) -> str: if isinstance(arg, celtypes.IntType): - return celtypes.StringType(f"{arg:b}") + return f"{arg:b}" if isinstance(arg, celtypes.UintType): - return celtypes.StringType(f"{arg:b}") + return f"{arg:b}" if isinstance(arg, celtypes.BoolType): - return celtypes.StringType(f"{arg:b}") - return celpy.CELEvalError("format_bin() requires an integer argument") + return f"{arg:b}" + msg = ( + "error during formatting: only integers and bools can be formatted as binary, was given " + f"{self.__type_str(type(arg))}" + ) - def format_string(self, arg: celtypes.Value) -> celpy.Result: - if isinstance(arg, celtypes.StringType): - return arg - if isinstance(arg, celtypes.BytesType): - return celtypes.StringType(arg) - if isinstance(arg, celtypes.ListType): - return self.format_list(arg) + raise celpy.CELEvalError(msg) + + def __format_string(self, arg: celtypes.Value) -> str: + if arg is None: + return "null" + if isinstance(arg, type): + return self.__type_str(arg) if isinstance(arg, celtypes.BoolType): # True -> true - return celtypes.StringType(str(arg).lower()) + return str(arg).lower() + if isinstance(arg, celtypes.BytesType): + return str(arg, "utf-8") if isinstance(arg, celtypes.DoubleType): - return celtypes.StringType(f"{arg:g}") + result = self.__validate_number(arg) + if result is not None: + return result + return f"{arg:g}" if isinstance(arg, celtypes.DurationType): - return celtypes.StringType(self._format_duration(arg)) + return self.__format_duration(arg) + if isinstance(arg, celtypes.IntType) or isinstance(arg, celtypes.UintType): + result = self.__validate_number(arg) + if result is not None: + return result + return f"{arg}" + if isinstance(arg, celtypes.ListType): + return self.__format_list(arg) + if isinstance(arg, celtypes.MapType): + return self.__format_map(arg) + if isinstance(arg, celtypes.StringType): + return f"{arg}" if isinstance(arg, celtypes.TimestampType): base = arg.isoformat() if arg.getMilliseconds() != 0: base = arg.isoformat(timespec="milliseconds") - return celtypes.StringType(base.removesuffix("+00:00") + "Z") - return celtypes.StringType(arg) + return base.removesuffix("+00:00") + "Z" + return "unknown" - def format_list(self, arg: celtypes.ListType) -> celpy.Result: + def __format_list(self, arg: celtypes.ListType) -> str: result = "[" for i in range(len(arg)): if i > 0: result += ", " - result += self.format_string(arg[i]) + result += self.__format_string(arg[i]) result += "]" - return celtypes.StringType(result) + return result + + def __format_map(self, arg: celtypes.MapType) -> str: + m = {} + for cel_key, cel_val in arg.items(): + key = self.__format_string(cel_key) + val = self.__format_string(cel_val) + m[key] = val + + m = dict(sorted(m.items())) - def _format_duration(self, arg: celtypes.DurationType) -> celpy.Result: + result = "{" + for i, (key, val) in enumerate(m.items()): + if i > 0: + result += ", " + result += key + ": " + val + + result += "}" + return result + + def __format_duration(self, arg: celtypes.DurationType) -> str: return f"{arg.seconds + Decimal(arg.microseconds) / Decimal(1_000_000):f}s" + + def __type_str(self, arg: celtypes.Type) -> str: + if arg is type(None): + return "null_type" + if arg is celtypes.BoolType: + return "bool" + if arg is celtypes.BytesType: + return "bytes" + if arg is celtypes.DoubleType: + return "double" + if arg is celtypes.DurationType: + return "google.protobuf.Duration" + if arg is celtypes.IntType: + return "int" + if arg is celtypes.ListType: + return "list" + if arg is celtypes.MapType: + return "map" + if arg is celtypes.StringType: + return "string" + if arg is celtypes.TimestampType: + return "google.protobuf.Timestamp" + if arg is celtypes.UintType: + return "uint" + return "unknown" diff --git a/string_ext.textproto b/string_ext.textproto deleted file mode 100644 index 2d61084f..00000000 --- a/string_ext.textproto +++ /dev/null @@ -1,1974 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - cel-spec/tests/simple/testdata/string_ext.textproto at v0.24.0 · google/cel-spec · GitHub - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - -
- Skip to content - - - - - - - - - - - - - -
-
- - - - - - - - - - - - - - -
- -
- - - - - - - - -
- - - - - -
- - - - - - - - - -
-
-
- - - - - - - - - - - - -
- -
- -
- -
- - - - / - - cel-spec - - - Public -
- - -
- -
- - -
-
- -
-
- - - - -
- - - - - - -
- - - - - - - - - - - - - - - - - - -
-
- - - - -
- -
- -
-
- -
- -
-

Footer

- - - - -
-
- - - - - © 2025 GitHub, Inc. - -
- - -
-
- - - - - - - - - - - - - - - - - - - -
- -
-
- - - diff --git a/tests/format_test.py b/tests/format_test.py index 77a8b967..d048ed3d 100644 --- a/tests/format_test.py +++ b/tests/format_test.py @@ -19,17 +19,36 @@ from celpy import celtypes from google.protobuf import text_format -# from gen.cel.expr import checked_pb2 +from gen.cel.expr import eval_pb2 from gen.cel.expr.conformance.test import simple_pb2 from protovalidate.internal import extra_func from protovalidate.internal.cel_field_presence import InterpretedRunner +# Version of the cel-spec that this implementation is conformant with +# This should be kept in sync with the version in the Makefile CEL_SPEC_VERSION = "v0.24.0" -def read_textproto(): +skipped_tests = [ + # cel-python seems to have a bug with ints and booleans in the same map which evaluate to the same value + # which the test data for this test has. For example: {1: 'value1', true: 'value2'}]). + # This throws an error like: + # "no such overload: IntType(0) != + # BoolType(False) ",)) + "map support (all key types)", +] +skipped_error_tests = [ + # cel-python does not support Protobuf messages at the moment and these tests use a MessageType + # See https://github.com/cloud-custodian/cel-python/issues/43 + "object not allowed", + "object inside list", + "object inside map", +] + + +def read_textproto() -> simple_pb2.SimpleTestFile: msg = simple_pb2.SimpleTestFile() - with open(f"tests/testdata/string_ext_{CEL_SPEC_VERSION}.textproto") as f: - text_data = f.read() + with open(f"tests/testdata/string_ext_{CEL_SPEC_VERSION}.textproto") as file: + text_data = file.read() text_format.Parse(text_data, msg) return msg @@ -38,17 +57,24 @@ class TestFormat(unittest.TestCase): @classmethod def setUpClass(cls): test_data = read_textproto() - cls._format_tests = [x for x in test_data.section if x.name == "format"] - cls._format_error_tests = [x for x in test_data.section if x.name == "format_errors"] + cls._format_test_section = next((x for x in test_data.section if x.name == "format"), None) + cls._format_error_test_section = next((x for x in test_data.section if x.name == "format_errors"), None) cls._env = celpy.Environment(runner_class=InterpretedRunner) - def _binding(self, bindings) -> dict[Any, Any]: + def _binding(self, bindings: dict[str, eval_pb2.ExprValue]) -> dict[Any, Any]: binder = {} for key, value in bindings.items(): if value.HasField("value"): val = value.value if val.HasField("string_value"): binder[key] = celtypes.StringType(val.string_value) + return binder + + def get_eval_error_message(self, test) -> celtypes.Value: + if test.HasField("eval_error"): + err_set = test.eval_error + if len(err_set.errors) == 1: + return celtypes.StringType(err_set.errors[0].message) # for type_env in test.type_env: # print(type_env) @@ -61,19 +87,43 @@ def _binding(self, bindings) -> dict[Any, Any]: # elif type_env.HasField("function"): # print('funker') # print(type_env.function) - return binder - def test_format_success(self): - format_tests = self._format_tests[0] - for test in format_tests.test: + def test_format_successes(self): + section = self._format_test_section + if section is None: + return + print(f"Running {len(section.test)} subtests for formatting") + for test in section.test: + if test.name in skipped_tests: + continue ast = self._env.compile(test.expr) prog = self._env.program(ast, functions=extra_func.EXTRA_FUNCS) - binders = self._binding(test.bindings) + bindings = self._binding(test.bindings) with self.subTest(test.name): try: - result = prog.evaluate(binders) + result = prog.evaluate(bindings) if test.value.HasField("string_value"): self.assertEqual(result, test.value.string_value) except celpy.CELEvalError as e: self.fail(e) + + def test_format_errors(self): + section = self._format_error_test_section + if section is None: + return + print(f"Running {len(section.test)} subtests for formatting errors") + for test in section.test: + if test.name in skipped_error_tests: + continue + ast = self._env.compile(test.expr) + prog = self._env.program(ast, functions=extra_func.EXTRA_FUNCS) + + bindings = self._binding(test.bindings) + with self.subTest(test.name): + try: + prog.evaluate(bindings) + self.fail("expected error") + except celpy.CELEvalError as e: + msg = self.convert_result_matcher(test) + self.assertEqual(str(e), msg) diff --git a/tests/validate_test.py b/tests/validate_test.py index 263ffd99..2b4b3fec 100644 --- a/tests/validate_test.py +++ b/tests/validate_test.py @@ -77,6 +77,22 @@ def test_maps(self): violations = protovalidate.collect_violations(msg) assert len(violations) == 1 + # def test_map_max(self): + # msg = validations_pb2.MapInts() + # msg.stuff9[1] = 2 + # msg.stuff9[2] = 2 + # msg.stuff9[3] = 2 + # try: + # protovalidate.validate(msg) + # except protovalidate.ValidationError as e: + # print(e.violations[0]) + # # assert len(e.violations) == 1 + # print(e.to_proto().violations[0]) + # # assert str(e) == "invalid MapInts" + + # # violations = protovalidate.collect_violations(msg) + # # assert len(violations) == 1 + def test_timestamp(self): msg = validations_pb2.TimestampGTNow() protovalidate.validate(msg) From 99f629ab6e7c780ce325a1074cf1095498e54f85 Mon Sep 17 00:00:00 2001 From: Steve Ayers Date: Tue, 20 May 2025 11:50:54 -0400 Subject: [PATCH 4/7] Lint --- tests/format_test.py | 87 +++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 37 deletions(-) diff --git a/tests/format_test.py b/tests/format_test.py index d048ed3d..55e2cd81 100644 --- a/tests/format_test.py +++ b/tests/format_test.py @@ -13,7 +13,7 @@ # limitations under the License. import unittest -from typing import Any +from typing import Any, Optional import celpy from celpy import celtypes @@ -53,6 +53,32 @@ def read_textproto() -> simple_pb2.SimpleTestFile: return msg +def build_binding(bindings: dict[str, eval_pb2.ExprValue]) -> dict[Any, Any]: + binder = {} + for key, value in bindings.items(): + if value.HasField("value"): + val = value.value + if val.HasField("string_value"): + binder[key] = celtypes.StringType(val.string_value) + return binder + + +def get_expected_result(test: simple_pb2.SimpleTest) -> Optional[str]: + if test.HasField("value"): + val = test.value + if val.HasField("string_value"): + return val.string_value + return None + + +def get_eval_error_message(test: simple_pb2.SimpleTest) -> Optional[str]: + if test.HasField("eval_error"): + err_set = test.eval_error + if len(err_set.errors) == 1: + return celtypes.StringType(err_set.errors[0].message) + return None + + class TestFormat(unittest.TestCase): @classmethod def setUpClass(cls): @@ -61,69 +87,56 @@ def setUpClass(cls): cls._format_error_test_section = next((x for x in test_data.section if x.name == "format_errors"), None) cls._env = celpy.Environment(runner_class=InterpretedRunner) - def _binding(self, bindings: dict[str, eval_pb2.ExprValue]) -> dict[Any, Any]: - binder = {} - for key, value in bindings.items(): - if value.HasField("value"): - val = value.value - if val.HasField("string_value"): - binder[key] = celtypes.StringType(val.string_value) - return binder - - def get_eval_error_message(self, test) -> celtypes.Value: - if test.HasField("eval_error"): - err_set = test.eval_error - if len(err_set.errors) == 1: - return celtypes.StringType(err_set.errors[0].message) - - # for type_env in test.type_env: - # print(type_env) - # if type_env.HasField("ident"): - # ident = type_env.ident - # if ident.type.HasField("primitive"): - # prim = ident.type.primitive - # if prim == checked_pb2.Type.PrimitiveType.STRING: - # print("das string") - # elif type_env.HasField("function"): - # print('funker') - # print(type_env.function) - def test_format_successes(self): + """ + Tests success scenarios for string.format + """ section = self._format_test_section if section is None: return - print(f"Running {len(section.test)} subtests for formatting") for test in section.test: if test.name in skipped_tests: continue ast = self._env.compile(test.expr) prog = self._env.program(ast, functions=extra_func.EXTRA_FUNCS) - bindings = self._binding(test.bindings) + bindings = build_binding(test.bindings) + # Ideally we should use pytest parametrize instead of subtests, but + # that would require refactoring other tests also. with self.subTest(test.name): try: result = prog.evaluate(bindings) - if test.value.HasField("string_value"): - self.assertEqual(result, test.value.string_value) + expected = get_expected_result(test) + if expected is not None: + self.assertEqual(result, expected) + else: + self.fail(f"[{test.name}]: expected a success result to be defined") except celpy.CELEvalError as e: self.fail(e) def test_format_errors(self): + """ + Tests error scenarios for string.format + """ section = self._format_error_test_section if section is None: return - print(f"Running {len(section.test)} subtests for formatting errors") for test in section.test: if test.name in skipped_error_tests: continue ast = self._env.compile(test.expr) prog = self._env.program(ast, functions=extra_func.EXTRA_FUNCS) - bindings = self._binding(test.bindings) + bindings = build_binding(test.bindings) + # Ideally we should use pytest parametrize instead of subtests, but + # that would require refactoring other tests also. with self.subTest(test.name): try: prog.evaluate(bindings) - self.fail("expected error") + self.fail(f"[{test.name}]: expected an error to be raised during evaluation") except celpy.CELEvalError as e: - msg = self.convert_result_matcher(test) - self.assertEqual(str(e), msg) + msg = get_eval_error_message(test) + if msg is not None: + self.assertEqual(str(e), msg) + else: + self.fail(f"[{test.name}]: expected an eval error to be defined") From 3b6ad49ed58a751b4e4407edf5f4d1928a6e2bb2 Mon Sep 17 00:00:00 2001 From: Steve Ayers Date: Tue, 20 May 2025 11:52:45 -0400 Subject: [PATCH 5/7] Revert --- proto/__init__.py | 18 ------- proto/tests/example/v1/predefined.proto | 61 ------------------------ proto/tests/example/v1/validations.proto | 11 ----- tests/validate_test.py | 16 ------- 4 files changed, 106 deletions(-) delete mode 100644 proto/__init__.py delete mode 100644 proto/tests/example/v1/predefined.proto diff --git a/proto/__init__.py b/proto/__init__.py deleted file mode 100644 index 062464d7..00000000 --- a/proto/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2023-2025 Buf Technologies, Inc. -# -# 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 -# -# http://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. - -import os -import sys - -sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) diff --git a/proto/tests/example/v1/predefined.proto b/proto/tests/example/v1/predefined.proto deleted file mode 100644 index d17024bd..00000000 --- a/proto/tests/example/v1/predefined.proto +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2023-2025 Buf Technologies, Inc. -// -// 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 -// -// http://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. - -syntax = "proto2"; - -package tests.example.v1; - -import "buf/validate/validate.proto"; - -extend buf.validate.MapRules { - optional uint64 maxim = 1800 [(buf.validate.predefined).cel = { - id: "map.maxim" - expression: "uint(this.size()) > 2 ? 'map must be at most %s entries'.format([{1: 'value1', uint(2): 'keytruda', true: double('NaN')}]) : ''" - }]; - optional uint64 maxim2 = 1801 [(buf.validate.predefined).cel = { - id: "map.maxim" - expression: "uint(this.size()) > 2 ? 'map must be at most %s entries'.format([{1: 'value1', uint(2): 'keytruda'}]) : ''" - }]; - optional uint64 maxim3 = 1802 [(buf.validate.predefined).cel = { - id: "map.maxim" - expression: "uint(this.size()) > 2 ? 'map must be at most %s entries'.format([{uint(2): 'keytruda', true: double('NaN')}]) : ''" - }]; - optional uint64 maxim4 = 1803 [(buf.validate.predefined).cel = { - id: "map.maxim" - expression: "uint(this.size()) > 2 ? 'map must be at most %s entries'.format([{1: 'value1', true: double('NaN')}]) : ''" - }]; - optional uint64 maxim5 = 1804 [(buf.validate.predefined).cel = { - id: "map.maxim" - expression: "uint(this.size()) > 2 ? 'map must be at most %s entries'.format([{uint(1): 'value1', true: double('NaN')}]) : ''" - }]; - optional uint64 maxim6 = 1805 [(buf.validate.predefined).cel = { - id: "map.maxim" - expression: "uint(this.size()) > 2 ? 'map must be at most %s entries'.format([{uint(6): 'value1', true: double('NaN')}]) : ''" - }]; - optional uint64 maxim7 = 1806 [(buf.validate.predefined).cel = { - id: "map.maxim" - expression: "uint(this.size()) > 2 ? 'map must be at most %s entries'.format([{6: 'value1', true: double('NaN')}]) : ''" - }]; - optional uint64 maxim8 = 1807 [(buf.validate.predefined).cel = { - id: "map.maxim" - expression: "uint(this.size()) > 2 ? 'map must be at most %s entries'.format([{2: 'value1', true: double('NaN')}]) : ''" - }]; - optional uint64 maxim9 = 1808 [(buf.validate.predefined).cel = { - id: "map.maxim" - expression: "uint(this.size()) > 2 ? 'map must be at most %s entries'.format([{0: 'value1', false: double('NaN')}]) : ''" - }]; -} - -// 4, 5, 1 don't work - diff --git a/proto/tests/example/v1/validations.proto b/proto/tests/example/v1/validations.proto index d0930ffb..4fff574d 100644 --- a/proto/tests/example/v1/validations.proto +++ b/proto/tests/example/v1/validations.proto @@ -63,14 +63,3 @@ message Embed { message RepeatedEmbedSkip { repeated Embed val = 1 [(buf.validate.field).repeated.items.ignore = IGNORE_ALWAYS]; } -/* message MapInts { */ -/* map stuff = 1 [(buf.validate.field).map.(maxim) = 4]; */ -/* map stuff2 = 2 [(buf.validate.field).map.(maxim2) = 4]; */ -/* map stuff3 = 3 [(buf.validate.field).map.(maxim3) = 4]; */ -/* map stuff4 = 4 [(buf.validate.field).map.(maxim4) = 4]; */ -/* map stuff5 = 5 [(buf.validate.field).map.(maxim5) = 4]; */ -/* map stuff6 = 6 [(buf.validate.field).map.(maxim6) = 4]; */ -/* map stuff7 = 7 [(buf.validate.field).map.(maxim7) = 4]; */ -/* map stuff8 = 8 [(buf.validate.field).map.(maxim8) = 4]; */ -/* map stuff9 = 9 [(buf.validate.field).map.(maxim9) = 4]; */ -/* } */ diff --git a/tests/validate_test.py b/tests/validate_test.py index 2b4b3fec..263ffd99 100644 --- a/tests/validate_test.py +++ b/tests/validate_test.py @@ -77,22 +77,6 @@ def test_maps(self): violations = protovalidate.collect_violations(msg) assert len(violations) == 1 - # def test_map_max(self): - # msg = validations_pb2.MapInts() - # msg.stuff9[1] = 2 - # msg.stuff9[2] = 2 - # msg.stuff9[3] = 2 - # try: - # protovalidate.validate(msg) - # except protovalidate.ValidationError as e: - # print(e.violations[0]) - # # assert len(e.violations) == 1 - # print(e.to_proto().violations[0]) - # # assert str(e) == "invalid MapInts" - - # # violations = protovalidate.collect_violations(msg) - # # assert len(violations) == 1 - def test_timestamp(self): msg = validations_pb2.TimestampGTNow() protovalidate.validate(msg) From 4722849ce91bdb7e891f68c0eceb0bb0dd2087bf Mon Sep 17 00:00:00 2001 From: Steve Ayers Date: Tue, 20 May 2025 11:53:23 -0400 Subject: [PATCH 6/7] Revert --- gen/tests/example/v1/predefined_pb2.py | 68 ------------------------- gen/tests/example/v1/predefined_pb2.pyi | 37 -------------- 2 files changed, 105 deletions(-) delete mode 100644 gen/tests/example/v1/predefined_pb2.py delete mode 100644 gen/tests/example/v1/predefined_pb2.pyi diff --git a/gen/tests/example/v1/predefined_pb2.py b/gen/tests/example/v1/predefined_pb2.py deleted file mode 100644 index 2656fb13..00000000 --- a/gen/tests/example/v1/predefined_pb2.py +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright 2023-2025 Buf Technologies, Inc. -# -# 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 -# -# http://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. - -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: tests/example/v1/predefined.proto -# Protobuf Python Version: 6.30.1 -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import runtime_version as _runtime_version -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 6, - 30, - 1, - '', - 'tests/example/v1/predefined.proto' -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from buf.validate import validate_pb2 as buf_dot_validate_dot_validate__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!tests/example/v1/predefined.proto\x12\x10tests.example.v1\x1a\x1b\x62uf/validate/validate.proto:\xc3\x01\n\x05maxim\x12\x16.buf.validate.MapRules\x18\x88\x0e \x01(\x04\x42\x93\x01\xc2H\x8f\x01\n\x8c\x01\n\tmap.maxim\x1a\x7fuint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{1: \'value1\', uint(2): \'keytruda\', true: double(\'NaN\')}]) : \'\'R\x05maxim:\xad\x01\n\x06maxim2\x12\x16.buf.validate.MapRules\x18\x89\x0e \x01(\x04\x42|\xc2Hy\nw\n\tmap.maxim\x1ajuint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{1: \'value1\', uint(2): \'keytruda\'}]) : \'\'R\x06maxim2:\xb7\x01\n\x06maxim3\x12\x16.buf.validate.MapRules\x18\x8a\x0e \x01(\x04\x42\x85\x01\xc2H\x81\x01\n\x7f\n\tmap.maxim\x1aruint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{uint(2): \'keytruda\', true: double(\'NaN\')}]) : \'\'R\x06maxim3:\xad\x01\n\x06maxim4\x12\x16.buf.validate.MapRules\x18\x8b\x0e \x01(\x04\x42|\xc2Hy\nw\n\tmap.maxim\x1ajuint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{1: \'value1\', true: double(\'NaN\')}]) : \'\'R\x06maxim4:\xb4\x01\n\x06maxim5\x12\x16.buf.validate.MapRules\x18\x8c\x0e \x01(\x04\x42\x82\x01\xc2H\x7f\n}\n\tmap.maxim\x1apuint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{uint(1): \'value1\', true: double(\'NaN\')}]) : \'\'R\x06maxim5:\xb4\x01\n\x06maxim6\x12\x16.buf.validate.MapRules\x18\x8d\x0e \x01(\x04\x42\x82\x01\xc2H\x7f\n}\n\tmap.maxim\x1apuint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{uint(6): \'value1\', true: double(\'NaN\')}]) : \'\'R\x06maxim6:\xad\x01\n\x06maxim7\x12\x16.buf.validate.MapRules\x18\x8e\x0e \x01(\x04\x42|\xc2Hy\nw\n\tmap.maxim\x1ajuint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{6: \'value1\', true: double(\'NaN\')}]) : \'\'R\x06maxim7:\xad\x01\n\x06maxim8\x12\x16.buf.validate.MapRules\x18\x8f\x0e \x01(\x04\x42|\xc2Hy\nw\n\tmap.maxim\x1ajuint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{2: \'value1\', true: double(\'NaN\')}]) : \'\'R\x06maxim8:\xae\x01\n\x06maxim9\x12\x16.buf.validate.MapRules\x18\x90\x0e \x01(\x04\x42}\xc2Hz\nx\n\tmap.maxim\x1akuint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{0: \'value1\', false: double(\'NaN\')}]) : \'\'R\x06maxim9B\x89\x01\n\x14\x63om.tests.example.v1B\x0fPredefinedProtoP\x01\xa2\x02\x03TEX\xaa\x02\x10Tests.Example.V1\xca\x02\x10Tests\\Example\\V1\xe2\x02\x1cTests\\Example\\V1\\GPBMetadata\xea\x02\x12Tests::Example::V1') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tests.example.v1.predefined_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\024com.tests.example.v1B\017PredefinedProtoP\001\242\002\003TEX\252\002\020Tests.Example.V1\312\002\020Tests\\Example\\V1\342\002\034Tests\\Example\\V1\\GPBMetadata\352\002\022Tests::Example::V1' - _globals['maxim']._loaded_options = None - _globals['maxim']._serialized_options = b'\302H\217\001\n\214\001\n\tmap.maxim\032\177uint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{1: \'value1\', uint(2): \'keytruda\', true: double(\'NaN\')}]) : \'\'' - _globals['maxim2']._loaded_options = None - _globals['maxim2']._serialized_options = b'\302Hy\nw\n\tmap.maxim\032juint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{1: \'value1\', uint(2): \'keytruda\'}]) : \'\'' - _globals['maxim3']._loaded_options = None - _globals['maxim3']._serialized_options = b'\302H\201\001\n\177\n\tmap.maxim\032ruint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{uint(2): \'keytruda\', true: double(\'NaN\')}]) : \'\'' - _globals['maxim4']._loaded_options = None - _globals['maxim4']._serialized_options = b'\302Hy\nw\n\tmap.maxim\032juint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{1: \'value1\', true: double(\'NaN\')}]) : \'\'' - _globals['maxim5']._loaded_options = None - _globals['maxim5']._serialized_options = b'\302H\177\n}\n\tmap.maxim\032puint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{uint(1): \'value1\', true: double(\'NaN\')}]) : \'\'' - _globals['maxim6']._loaded_options = None - _globals['maxim6']._serialized_options = b'\302H\177\n}\n\tmap.maxim\032puint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{uint(6): \'value1\', true: double(\'NaN\')}]) : \'\'' - _globals['maxim7']._loaded_options = None - _globals['maxim7']._serialized_options = b'\302Hy\nw\n\tmap.maxim\032juint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{6: \'value1\', true: double(\'NaN\')}]) : \'\'' - _globals['maxim8']._loaded_options = None - _globals['maxim8']._serialized_options = b'\302Hy\nw\n\tmap.maxim\032juint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{2: \'value1\', true: double(\'NaN\')}]) : \'\'' - _globals['maxim9']._loaded_options = None - _globals['maxim9']._serialized_options = b'\302Hz\nx\n\tmap.maxim\032kuint(this.size()) > 2 ? \'map must be at most %s entries\'.format([{0: \'value1\', false: double(\'NaN\')}]) : \'\'' -# @@protoc_insertion_point(module_scope) diff --git a/gen/tests/example/v1/predefined_pb2.pyi b/gen/tests/example/v1/predefined_pb2.pyi deleted file mode 100644 index 21167323..00000000 --- a/gen/tests/example/v1/predefined_pb2.pyi +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright 2023-2025 Buf Technologies, Inc. -# -# 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 -# -# http://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. - -from buf.validate import validate_pb2 as _validate_pb2 -from google.protobuf import descriptor as _descriptor -from typing import ClassVar as _ClassVar - -DESCRIPTOR: _descriptor.FileDescriptor -MAXIM_FIELD_NUMBER: _ClassVar[int] -maxim: _descriptor.FieldDescriptor -MAXIM2_FIELD_NUMBER: _ClassVar[int] -maxim2: _descriptor.FieldDescriptor -MAXIM3_FIELD_NUMBER: _ClassVar[int] -maxim3: _descriptor.FieldDescriptor -MAXIM4_FIELD_NUMBER: _ClassVar[int] -maxim4: _descriptor.FieldDescriptor -MAXIM5_FIELD_NUMBER: _ClassVar[int] -maxim5: _descriptor.FieldDescriptor -MAXIM6_FIELD_NUMBER: _ClassVar[int] -maxim6: _descriptor.FieldDescriptor -MAXIM7_FIELD_NUMBER: _ClassVar[int] -maxim7: _descriptor.FieldDescriptor -MAXIM8_FIELD_NUMBER: _ClassVar[int] -maxim8: _descriptor.FieldDescriptor -MAXIM9_FIELD_NUMBER: _ClassVar[int] -maxim9: _descriptor.FieldDescriptor From eca2a07109de09a4cfec27dd4ac1dd3165db5481 Mon Sep 17 00:00:00 2001 From: Steve Ayers Date: Tue, 20 May 2025 12:48:19 -0400 Subject: [PATCH 7/7] Move pytest-subtests to dev --- Pipfile | 2 +- Pipfile.lock | 208 +++++++++++++++------------------------------------ 2 files changed, 62 insertions(+), 148 deletions(-) diff --git a/Pipfile b/Pipfile index 9f94ee47..83a62435 100644 --- a/Pipfile +++ b/Pipfile @@ -6,10 +6,10 @@ name = "pypi" [packages] cel-python = "==0.2.*" protobuf = "==6.*" -pytest-subtests = "*" [dev-packages] pytest = "*" +pytest-subtests = "*" mypy = "*" ruff = "*" types-protobuf = "==6.30.2.20250503" diff --git a/Pipfile.lock b/Pipfile.lock index c28c2192..66b6263d 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "11e1248d6af4c57423db004bec0594a4bd4b8a432d50cd36f4ed4f8edc0a9020" + "sha256": "64807b9d6710f69cea833d41d5eff4e956835972cdf6c5e737d3def186921504" }, "pipfile-spec": 6, "requires": { @@ -16,14 +16,6 @@ ] }, "default": { - "attrs": { - "hashes": [ - "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", - "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b" - ], - "markers": "python_version >= '3.8'", - "version": "==25.3.0" - }, "cel-python": { "hashes": [ "sha256:478ff73def7b39d51e6982f95d937a57c2b088c491c578fe5cecdbd79f476f60", @@ -33,22 +25,6 @@ "markers": "python_version >= '3.8' and python_version < '4.0'", "version": "==0.2.0" }, - "exceptiongroup": { - "hashes": [ - "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", - "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88" - ], - "markers": "python_version >= '3.7'", - "version": "==1.3.0" - }, - "iniconfig": { - "hashes": [ - "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", - "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760" - ], - "markers": "python_version >= '3.8'", - "version": "==2.1.0" - }, "jmespath": { "hashes": [ "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", @@ -64,54 +40,21 @@ ], "version": "==0.12.0" }, - "packaging": { - "hashes": [ - "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", - "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f" - ], - "markers": "python_version >= '3.8'", - "version": "==25.0" - }, - "pluggy": { - "hashes": [ - "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", - "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" - ], - "markers": "python_version >= '3.9'", - "version": "==1.6.0" - }, "protobuf": { "hashes": [ - "sha256:0eb523c550a66a09a0c20f86dd554afbf4d32b02af34ae53d93268c1f73bc65b", - "sha256:35c859ae076d8c56054c25b59e5e59638d86545ed6e2b6efac6be0b6ea3ba048", - "sha256:4f6c687ae8efae6cf6093389a596548214467778146b7245e886f35e1485315d", - "sha256:50f32cc9fd9cb09c783ebc275611b4f19dfdfb68d1ee55d2f0c7fa040df96815", - "sha256:524afedc03b31b15586ca7f64d877a98b184f007180ce25183d1a5cb230ee72b", - "sha256:7653c99774f73fe6b9301b87da52af0e69783a2e371e8b599b3e9cb4da4b12b9", - "sha256:acec579c39c88bd8fbbacab1b8052c793efe83a0a5bd99db4a31423a25c0a0e2", - "sha256:ae86b030e69a98e08c77beab574cbcb9fff6d031d57209f574a5aea1445f4b51", - "sha256:b12ef7df7b9329886e66404bef5e9ce6a26b54069d7f7436a0853ccdeb91c103" - ], - "index": "pypi", - "markers": "python_version >= '3.9'", - "version": "==6.30.2" - }, - "pytest": { - "hashes": [ - "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", - "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845" - ], - "markers": "python_version >= '3.8'", - "version": "==8.3.5" - }, - "pytest-subtests": { - "hashes": [ - "sha256:350c00adc36c3aff676a66135c81aed9e2182e15f6c3ec8721366918bbbf7580", - "sha256:e92a780d98b43118c28a16044ad9b841727bd7cb6a417073b38fd2d7ccdf052d" + "sha256:00a873c06efdfb854145d9ded730b09cf57d206075c38132674093370e2edabb", + "sha256:10bd62802dfa0588649740a59354090eaf54b8322f772fbdcca19bc78d27f0d6", + "sha256:2c812f0f96ceb6b514448cefeb1df54ec06dde456783f5099c0e2f8a0f2caa89", + "sha256:314fab1a6a316469dc2dd46f993cbbe95c861ea6807da910becfe7475bc26ffe", + "sha256:3e987c99fd634be8347246a02123250f394ba20573c953de133dc8b2c107dd71", + "sha256:5353e38844168a327acd2b2aa440044411cd8d1b6774d5701008bd1dba067c79", + "sha256:67ce50195e4e584275623b8e6bc6d3d3dfd93924bf6116b86b3b8975ab9e4571", + "sha256:6ac2e82556e822c17a8d23aa1190bbc1d06efb9c261981da95c71c9da09e9e23", + "sha256:96d8da25c83b11db5fe9e0376351ce25e7205e13224d939e097b6f82a72af824" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==0.14.1" + "version": "==6.31.0" }, "python-dateutil": { "hashes": [ @@ -188,78 +131,40 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.17.0" }, - "tomli": { - "hashes": [ - "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", - "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", - "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", - "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", - "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", - "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", - "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", - "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", - "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", - "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", - "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", - "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", - "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", - "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", - "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", - "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", - "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", - "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", - "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", - "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", - "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", - "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", - "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", - "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", - "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", - "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", - "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", - "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", - "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", - "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", - "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", - "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7" - ], - "markers": "python_version >= '3.8'", - "version": "==2.2.1" - }, "types-python-dateutil": { "hashes": [ - "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb", - "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53" + "sha256:13e80d6c9c47df23ad773d54b2826bd52dbbb41be87c3f339381c1700ad21ee5", + "sha256:2b2b3f57f9c6a61fba26a9c0ffb9ea5681c9b83e69cd897c6b5f668d9c0cab93" ], - "markers": "python_version >= '3.8'", - "version": "==2.9.0.20241206" + "markers": "python_version >= '3.9'", + "version": "==2.9.0.20250516" }, "types-pyyaml": { "hashes": [ - "sha256:652348fa9e7a203d4b0d21066dfb00760d3cbd5a15ebb7cf8d33c88a49546681", - "sha256:d7c13c3e6d335b6af4b0122a01ff1d270aba84ab96d1a1a1063ecba3e13ec075" + "sha256:8478208feaeb53a34cb5d970c56a7cd76b72659442e733e268a94dc72b2d0530", + "sha256:9f21a70216fc0fa1b216a8176db5f9e0af6eb35d2f2932acb87689d03a5bf6ba" ], "markers": "python_version >= '3.9'", - "version": "==6.0.12.20250402" - }, - "typing-extensions": { - "hashes": [ - "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", - "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef" - ], - "markers": "python_version >= '3.8'", - "version": "==4.13.2" + "version": "==6.0.12.20250516" } }, "develop": { + "attrs": { + "hashes": [ + "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", + "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b" + ], + "markers": "python_version >= '3.8'", + "version": "==25.3.0" + }, "exceptiongroup": { "hashes": [ - "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", - "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc" + "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", + "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==1.2.2" + "version": "==1.3.0" }, "iniconfig": { "hashes": [ @@ -326,11 +231,11 @@ }, "pluggy": { "hashes": [ - "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", - "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" + "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", + "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" ], - "markers": "python_version >= '3.8'", - "version": "==1.5.0" + "markers": "python_version >= '3.9'", + "version": "==1.6.0" }, "pytest": { "hashes": [ @@ -341,30 +246,39 @@ "markers": "python_version >= '3.8'", "version": "==8.3.5" }, + "pytest-subtests": { + "hashes": [ + "sha256:350c00adc36c3aff676a66135c81aed9e2182e15f6c3ec8721366918bbbf7580", + "sha256:e92a780d98b43118c28a16044ad9b841727bd7cb6a417073b38fd2d7ccdf052d" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==0.14.1" + }, "ruff": { "hashes": [ - "sha256:0eba551324733efc76116d9f3a0d52946bc2751f0cd30661564117d6fd60897c", - "sha256:161eb4cff5cfefdb6c9b8b3671d09f7def2f960cee33481dd898caf2bcd02304", - "sha256:258f3585057508d317610e8a412788cf726efeefa2fec4dba4001d9e6f90d46c", - "sha256:304432e4c4a792e3da85b7699feb3426a0908ab98bf29df22a31b0cdd098fac2", - "sha256:3dca977cc4fc8f66e89900fa415ffe4dbc2e969da9d7a54bfca81a128c5ac219", - "sha256:4d9aaa91035bdf612c8ee7266153bcf16005c7c7e2f5878406911c92a31633cb", - "sha256:5b18caa297a786465cc511d7f8be19226acf9c0a1127e06e736cd4e1878c3ea2", - "sha256:6d742d10626f9004b781f4558154bb226620a7242080e11caeffab1a40e99df8", - "sha256:6e70d11043bef637c5617297bdedec9632af15d53ac1e1ba29c448da9341b0c4", - "sha256:727d01702f7c30baed3fc3a34901a640001a2828c793525043c29f7614994a8c", - "sha256:7f024d32e62faad0f76b2d6afd141b8c171515e4fb91ce9fd6464335c81244e5", - "sha256:896a37516c594805e34020c4a7546c8f8a234b679a7716a3f08197f38913e1a3", - "sha256:ab86d22d3d721a40dd3ecbb5e86ab03b2e053bc93c700dc68d1c3346b36ce835", - "sha256:c1dba3135ca503727aa4648152c0fa67c3b1385d3dc81c75cd8a229c4b2a1458", - "sha256:c657fa987d60b104d2be8b052d66da0a2a88f9bd1d66b2254333e84ea2720c7f", - "sha256:d365618d3ad747432e1ae50d61775b78c055fee5936d77fb4d92c6f559741948", - "sha256:f2e74b021d0de5eceb8bd32919f6ff8a9b40ee62ed97becd44993ae5b9949474", - "sha256:f9b5ef39820abc0f2c62111f7045009e46b275f5b99d5e59dda113c39b7f4f38" + "sha256:1067245bad978e7aa7b22f67113ecc6eb241dca0d9b696144256c3a879663bca", + "sha256:2f071b0deed7e9245d5820dac235cbdd4ef99d7b12ff04c330a241ad3534319f", + "sha256:3afead355f1d16d95630df28d4ba17fb2cb9c8dfac8d21ced14984121f639bad", + "sha256:4a60e3a0a617eafba1f2e4186d827759d65348fa53708ca547e384db28406a0b", + "sha256:5a94acf798a82db188f6f36575d80609072b032105d114b0f98661e1679c9125", + "sha256:5b6a9cc5b62c03cc1fea0044ed8576379dbaf751d5503d718c973d5418483641", + "sha256:5cc725fbb4d25b0f185cb42df07ab6b76c4489b4bfb740a175f3a59c70e8a224", + "sha256:607ecbb6f03e44c9e0a93aedacb17b4eb4f3563d00e8b474298a201622677947", + "sha256:7b3a522fa389402cd2137df9ddefe848f727250535c70dafa840badffb56b7a4", + "sha256:859a7bfa7bc8888abbea31ef8a2b411714e6a80f0d173c2a82f9041ed6b50f58", + "sha256:8b4564e9f99168c0f9195a0fd5fa5928004b33b377137f978055e40008a082c5", + "sha256:968220a57e09ea5e4fd48ed1c646419961a0570727c7e069842edd018ee8afed", + "sha256:d522fb204b4959909ecac47da02830daec102eeb100fb50ea9554818d47a5fa6", + "sha256:da8ec977eaa4b7bf75470fb575bea2cb41a0e07c7ea9d5a0a97d13dbca697bf2", + "sha256:dc061a98d32a97211af7e7f3fa1d4ca2fcf919fb96c28f39551f35fc55bdbc19", + "sha256:ddf8967e08227d1bd95cc0851ef80d2ad9c7c0c5aab1eba31db49cf0a7b99523", + "sha256:ef69637b35fb8b210743926778d0e45e1bffa850a7c61e428c6b971549b5f5d1", + "sha256:f4854fd09c7aed5b1590e996a81aeff0c9ff51378b084eb5a0b9cd9518e6cff2" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==0.11.8" + "version": "==0.11.10" }, "tomli": { "hashes": [