From 23aac2cb55a72e3b8981c41d17bd09255ca064fa Mon Sep 17 00:00:00 2001 From: Stefan VanBuren Date: Tue, 4 Nov 2025 09:51:44 -0500 Subject: [PATCH 1/2] Bump CEL_SPEC_VERSION to v0.25.0 --- Makefile | 2 +- .../conformance/conformance_service_pb2.py | 47 ++++++------ .../conformance/conformance_service_pb2.pyi | 13 ++-- gen/cel/policy/policy_pb2.py | 49 ++++++++++++ gen/cel/policy/policy_pb2.pyi | 76 +++++++++++++++++++ 5 files changed, 155 insertions(+), 32 deletions(-) create mode 100644 gen/cel/policy/policy_pb2.py create mode 100644 gen/cel/policy/policy_pb2.pyi diff --git a/Makefile b/Makefile index 3454acbf..9ee5b9bd 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ ADD_LICENSE_HEADER := $(BIN)/license-header \ # This version should be kept in sync with the version in buf.yaml PROTOVALIDATE_VERSION ?= v1.0.0 # Version of the cel-spec that this implementation is conformant with -CEL_SPEC_VERSION ?= v0.24.0 +CEL_SPEC_VERSION ?= v0.25.0 TESTDATA_FILE := test/testdata/string_ext.textproto .PHONY: help diff --git a/gen/cel/expr/conformance/conformance_service_pb2.py b/gen/cel/expr/conformance/conformance_service_pb2.py index 3641db5a..54d582f6 100644 --- a/gen/cel/expr/conformance/conformance_service_pb2.py +++ b/gen/cel/expr/conformance/conformance_service_pb2.py @@ -29,10 +29,9 @@ 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') +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\"\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 \x01(\x0b\x32\x12.cel.expr.ErrorSetR\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 \x01(\x0b\x32\x12.cel.expr.ErrorSetR\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 \x01(\x0b\x32\x12.cel.expr.ErrorSetR\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) @@ -42,26 +41,26 @@ _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 + _globals['_PARSEREQUEST']._serialized_start=141 + _globals['_PARSEREQUEST']._serialized_end=305 + _globals['_PARSERESPONSE']._serialized_start=307 + _globals['_PARSERESPONSE']._serialized_end=421 + _globals['_CHECKREQUEST']._serialized_start=424 + _globals['_CHECKREQUEST']._serialized_end=596 + _globals['_CHECKRESPONSE']._serialized_start=598 + _globals['_CHECKRESPONSE']._serialized_end=715 + _globals['_EVALREQUEST']._serialized_start=718 + _globals['_EVALREQUEST']._serialized_end=1050 + _globals['_EVALREQUEST_BINDINGSENTRY']._serialized_start=957 + _globals['_EVALREQUEST_BINDINGSENTRY']._serialized_end=1037 + _globals['_EVALRESPONSE']._serialized_start=1052 + _globals['_EVALRESPONSE']._serialized_end=1155 + _globals['_SOURCEPOSITION']._serialized_start=1157 + _globals['_SOURCEPOSITION']._serialized_end=1269 + _globals['_ISSUEDETAILS']._serialized_start=1272 + _globals['_ISSUEDETAILS']._serialized_end=1520 + _globals['_ISSUEDETAILS_SEVERITY']._serialized_start=1443 + _globals['_ISSUEDETAILS_SEVERITY']._serialized_end=1520 + _globals['_CONFORMANCESERVICE']._serialized_start=1523 + _globals['_CONFORMANCESERVICE']._serialized_end=1792 # @@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 index 6860dfa9..c05be4d1 100644 --- a/gen/cel/expr/conformance/conformance_service_pb2.pyi +++ b/gen/cel/expr/conformance/conformance_service_pb2.pyi @@ -15,7 +15,6 @@ 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 @@ -41,8 +40,8 @@ class ParseResponse(_message.Message): 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: ... + issues: _eval_pb2.ErrorSet + def __init__(self, parsed_expr: _Optional[_Union[_syntax_pb2.ParsedExpr, _Mapping]] = ..., issues: _Optional[_Union[_eval_pb2.ErrorSet, _Mapping]] = ...) -> None: ... class CheckRequest(_message.Message): __slots__ = ("parsed_expr", "type_env", "container", "no_std_env") @@ -61,8 +60,8 @@ class CheckResponse(_message.Message): 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: ... + issues: _eval_pb2.ErrorSet + def __init__(self, checked_expr: _Optional[_Union[_checked_pb2.CheckedExpr, _Mapping]] = ..., issues: _Optional[_Union[_eval_pb2.ErrorSet, _Mapping]] = ...) -> None: ... class EvalRequest(_message.Message): __slots__ = ("parsed_expr", "checked_expr", "bindings", "container") @@ -88,8 +87,8 @@ class EvalResponse(_message.Message): 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: ... + issues: _eval_pb2.ErrorSet + def __init__(self, result: _Optional[_Union[_eval_pb2.ExprValue, _Mapping]] = ..., issues: _Optional[_Union[_eval_pb2.ErrorSet, _Mapping]] = ...) -> None: ... class SourcePosition(_message.Message): __slots__ = ("location", "offset", "line", "column") diff --git a/gen/cel/policy/policy_pb2.py b/gen/cel/policy/policy_pb2.py new file mode 100644 index 00000000..35904ea3 --- /dev/null +++ b/gen/cel/policy/policy_pb2.py @@ -0,0 +1,49 @@ +# 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! +# source: cel/policy/policy.proto +# Protobuf Python Version: 5.26.0 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x17\x63\x65l/policy/policy.proto\x12\ncel.policy\"\xf5\x06\n\nPolicySpec\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x37\n\x07imports\x18\x02 \x03(\x0b\x32\x1d.cel.policy.PolicySpec.ImportR\x07imports\x12=\n\tvariables\x18\x03 \x03(\x0b\x32\x1f.cel.policy.PolicySpec.VariableR\tvariables\x12\x1b\n\x06output\x18\x04 \x01(\tH\x00R\x06output\x88\x01\x01\x12%\n\x0b\x64\x65scription\x18\x05 \x01(\tH\x01R\x0b\x64\x65scription\x88\x01\x01\x12%\n\x0b\x65xplanation\x18\x06 \x01(\tH\x02R\x0b\x65xplanation\x88\x01\x01\x12\x32\n\x05match\x18\x07 \x03(\x0b\x32\x1c.cel.policy.PolicySpec.MatchR\x05match\x12/\n\x04rule\x18\x08 \x01(\x0b\x32\x1b.cel.policy.PolicySpec.RuleR\x04rule\x1a\x1c\n\x06Import\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x1a`\n\x08Variable\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12 \n\x0b\x64\x65scription\x18\x02 \x01(\tR\x0b\x64\x65scription\x12\x1e\n\nexpression\x18\x03 \x01(\tR\nexpression\x1a\xab\x01\n\x04Rule\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12 \n\x0b\x64\x65scription\x18\x02 \x01(\tR\x0b\x64\x65scription\x12=\n\tvariables\x18\x03 \x03(\x0b\x32\x1f.cel.policy.PolicySpec.VariableR\tvariables\x12\x32\n\x05match\x18\x04 \x03(\x0b\x32\x1c.cel.policy.PolicySpec.MatchR\x05match\x1a\xb1\x01\n\x05Match\x12!\n\tcondition\x18\x01 \x01(\tH\x01R\tcondition\x88\x01\x01\x12\x18\n\x06output\x18\x02 \x01(\tH\x00R\x06output\x12\x31\n\x04rule\x18\x03 \x01(\x0b\x32\x1b.cel.policy.PolicySpec.RuleH\x00R\x04rule\x12 \n\x0b\x65xplanation\x18\x04 \x01(\tR\x0b\x65xplanationB\x08\n\x06\x61\x63tionB\x0c\n\n_conditionB\t\n\x07_outputB\x0e\n\x0c_descriptionB\x0e\n\x0c_explanationBy\n\x0e\x63om.cel.policyB\x0bPolicyProtoP\x01Z\x0e\x63\x65l.dev/policy\xf8\x01\x01\xa2\x02\x03\x43PX\xaa\x02\nCel.Policy\xca\x02\nCel\\Policy\xe2\x02\x16\x43\x65l\\Policy\\GPBMetadata\xea\x02\x0b\x43\x65l::Policyb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cel.policy.policy_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\016com.cel.policyB\013PolicyProtoP\001Z\016cel.dev/policy\370\001\001\242\002\003CPX\252\002\nCel.Policy\312\002\nCel\\Policy\342\002\026Cel\\Policy\\GPBMetadata\352\002\013Cel::Policy' + _globals['_POLICYSPEC']._serialized_start=40 + _globals['_POLICYSPEC']._serialized_end=925 + _globals['_POLICYSPEC_IMPORT']._serialized_start=402 + _globals['_POLICYSPEC_IMPORT']._serialized_end=430 + _globals['_POLICYSPEC_VARIABLE']._serialized_start=432 + _globals['_POLICYSPEC_VARIABLE']._serialized_end=528 + _globals['_POLICYSPEC_RULE']._serialized_start=531 + _globals['_POLICYSPEC_RULE']._serialized_end=702 + _globals['_POLICYSPEC_MATCH']._serialized_start=705 + _globals['_POLICYSPEC_MATCH']._serialized_end=882 +# @@protoc_insertion_point(module_scope) diff --git a/gen/cel/policy/policy_pb2.pyi b/gen/cel/policy/policy_pb2.pyi new file mode 100644 index 00000000..f1653363 --- /dev/null +++ b/gen/cel/policy/policy_pb2.pyi @@ -0,0 +1,76 @@ +# 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.internal import containers as _containers +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class PolicySpec(_message.Message): + __slots__ = ("name", "imports", "variables", "output", "description", "explanation", "match", "rule") + class Import(_message.Message): + __slots__ = ("name",) + NAME_FIELD_NUMBER: _ClassVar[int] + name: str + def __init__(self, name: _Optional[str] = ...) -> None: ... + class Variable(_message.Message): + __slots__ = ("name", "description", "expression") + NAME_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + EXPRESSION_FIELD_NUMBER: _ClassVar[int] + name: str + description: str + expression: str + def __init__(self, name: _Optional[str] = ..., description: _Optional[str] = ..., expression: _Optional[str] = ...) -> None: ... + class Rule(_message.Message): + __slots__ = ("id", "description", "variables", "match") + ID_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + VARIABLES_FIELD_NUMBER: _ClassVar[int] + MATCH_FIELD_NUMBER: _ClassVar[int] + id: str + description: str + variables: _containers.RepeatedCompositeFieldContainer[PolicySpec.Variable] + match: _containers.RepeatedCompositeFieldContainer[PolicySpec.Match] + def __init__(self, id: _Optional[str] = ..., description: _Optional[str] = ..., variables: _Optional[_Iterable[_Union[PolicySpec.Variable, _Mapping]]] = ..., match: _Optional[_Iterable[_Union[PolicySpec.Match, _Mapping]]] = ...) -> None: ... + class Match(_message.Message): + __slots__ = ("condition", "output", "rule", "explanation") + CONDITION_FIELD_NUMBER: _ClassVar[int] + OUTPUT_FIELD_NUMBER: _ClassVar[int] + RULE_FIELD_NUMBER: _ClassVar[int] + EXPLANATION_FIELD_NUMBER: _ClassVar[int] + condition: str + output: str + rule: PolicySpec.Rule + explanation: str + def __init__(self, condition: _Optional[str] = ..., output: _Optional[str] = ..., rule: _Optional[_Union[PolicySpec.Rule, _Mapping]] = ..., explanation: _Optional[str] = ...) -> None: ... + NAME_FIELD_NUMBER: _ClassVar[int] + IMPORTS_FIELD_NUMBER: _ClassVar[int] + VARIABLES_FIELD_NUMBER: _ClassVar[int] + OUTPUT_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + EXPLANATION_FIELD_NUMBER: _ClassVar[int] + MATCH_FIELD_NUMBER: _ClassVar[int] + RULE_FIELD_NUMBER: _ClassVar[int] + name: str + imports: _containers.RepeatedCompositeFieldContainer[PolicySpec.Import] + variables: _containers.RepeatedCompositeFieldContainer[PolicySpec.Variable] + output: str + description: str + explanation: str + match: _containers.RepeatedCompositeFieldContainer[PolicySpec.Match] + rule: PolicySpec.Rule + def __init__(self, name: _Optional[str] = ..., imports: _Optional[_Iterable[_Union[PolicySpec.Import, _Mapping]]] = ..., variables: _Optional[_Iterable[_Union[PolicySpec.Variable, _Mapping]]] = ..., output: _Optional[str] = ..., description: _Optional[str] = ..., explanation: _Optional[str] = ..., match: _Optional[_Iterable[_Union[PolicySpec.Match, _Mapping]]] = ..., rule: _Optional[_Union[PolicySpec.Rule, _Mapping]] = ...) -> None: ... From 6b53aa01ffbfae019b1c4e853ba8b3f7e57acd2e Mon Sep 17 00:00:00 2001 From: Stefan VanBuren Date: Wed, 12 Nov 2025 09:22:47 -0500 Subject: [PATCH 2/2] Reintroduce CEL spec version in filename Dropped in #374, but needed to pick up updates to the file trivially with `make`. Also, bump to 0.25.1 now that it's been released. --- Makefile | 5 +- test/test_format.py | 6 +- ...textproto => string_ext_v0.25.1.textproto} | 76 ++++++++++++++++++- 3 files changed, 83 insertions(+), 4 deletions(-) rename test/testdata/{string_ext.textproto => string_ext_v0.25.1.textproto} (95%) diff --git a/Makefile b/Makefile index 9ee5b9bd..d008d3ff 100644 --- a/Makefile +++ b/Makefile @@ -18,8 +18,9 @@ ADD_LICENSE_HEADER := $(BIN)/license-header \ # This version should be kept in sync with the version in buf.yaml PROTOVALIDATE_VERSION ?= v1.0.0 # Version of the cel-spec that this implementation is conformant with -CEL_SPEC_VERSION ?= v0.25.0 -TESTDATA_FILE := test/testdata/string_ext.textproto +# This should be kept in sync with the version in test/test_format.py +CEL_SPEC_VERSION ?= v0.25.1 +TESTDATA_FILE := test/testdata/string_ext_$(CEL_SPEC_VERSION).textproto .PHONY: help help: ## Describe useful make targets diff --git a/test/test_format.py b/test/test_format.py index aa1bfe6a..d206ef60 100644 --- a/test/test_format.py +++ b/test/test_format.py @@ -26,6 +26,10 @@ 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 ../Makefile. +CEL_SPEC_VERSION = "v0.25.1" + 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'}]). @@ -79,7 +83,7 @@ def get_eval_error_message(test: simple_pb2.SimpleTest) -> str | None: # The test data from the cel-spec conformance tests -cel_test_data = load_test_data("test/testdata/string_ext.textproto") +cel_test_data = load_test_data(f"test/testdata/string_ext_{CEL_SPEC_VERSION}.textproto") # Our supplemental tests of functionality not in the cel conformance file, but defined in the spec. supplemental_test_data = load_test_data("test/testdata/string_ext_supplemental.textproto") diff --git a/test/testdata/string_ext.textproto b/test/testdata/string_ext_v0.25.1.textproto similarity index 95% rename from test/testdata/string_ext.textproto rename to test/testdata/string_ext_v0.25.1.textproto index d2455583..fea2ad39 100644 --- a/test/testdata/string_ext.textproto +++ b/test/testdata/string_ext_v0.25.1.textproto @@ -92,7 +92,11 @@ section: { section: { name: "last_index_of" test: { - name: "empty" + name: "empty_string" + expr: "''.lastIndexOf('@@') == -1" + } + test: { + name: "empty_argument" expr: "'tacocat'.lastIndexOf('') == 7" } test: { @@ -884,6 +888,76 @@ section: { string_value: '2.718280', } } +test: { + name: "format_%f_insignificant_zeroes_removed" + expr: '"%.0f".format([123.000000])' + value: { + string_value: '123', + } + } + test: { + name: "format_%f_positive_round_to_whole_number" + expr: '"%.0f".format([3.5001])' + value: { + string_value: '4', + } + } + test: { + name: "format_%f_negative_truncate_to_whole_number" + expr: '"%.0f".format([3.4999])' + value: { + string_value: '3', + } + } + test: { + name: "format_%f_halfway_round_up_to_nearest_even" + expr: '"%.0f".format([1.5])' + value: { + string_value: '2', + } + } + test: { + name: "format_%f_halfway_truncate_to_nearest_even" + expr: '"%.0f".format([2.5])' + value: { + string_value: '2', + } + } + test: { + name: "format_%f_positive_round_up" + expr: '"%.3f".format([123.4999])' + value: { + string_value: '123.500', + } + } + test: { + name: "format_%f_positive_round_down" + expr: '"%.3f".format([123.4994])' + value: { + string_value: '123.499', + } + } + test: { + name: "format_%f_negative_round_up" + expr: '"%.3f".format([-123.4999])' + value: { + string_value: '-123.500', + } + } + test: { + name: "format_%f_negative_round_down" + expr: '"%.3f".format([-123.4994])' + value: { + string_value: '-123.499', + } + } + test: { + name: "format_%f_zero_padding" + expr: '"%.5f".format([-1.2])' + value: { + string_value: '-1.20000', + } + } } section: { name: "format_errors"