Skip to content

Commit b45f69c

Browse files
Fix operator overloads: remove _==_/_!=_, fix _%_, add size(bytes)->int64
FunctionDecl for operators replaces the entire built-in, removing all standard overloads. The previous _==_ and _!=_ FunctionDecls broke bool/bool, int/int, bytes/bytes, etc. equality comparisons. Fix by: - Removing _==_ and _!=_ FunctionDecls entirely - Adding size(bytes)->int64 overload so "this.size() == 4" uses the built-in _==_(int64, int64) instead of needing cross-type equality - Fixing _%_ to include all standard overloads (int/int, uint/uint) plus the cross-type (int/uint)->uint overload
1 parent ceb1494 commit b45f69c

1 file changed

Lines changed: 29 additions & 35 deletions

File tree

protovalidate/internal/extra_func.py

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1778,59 +1778,53 @@ def make_extra_funcs() -> cel.CelExtension:
17781778
)
17791779
],
17801780
),
1781-
# Cross-type int/uint arithmetic overloads.
1782-
# CEL predefined rules for uint types use uint literals (e.g. "this % 2u == 0u"),
1783-
# but Python int values are mapped to CEL int64. These overloads bridge the gap.
1781+
# Override size(bytes) -> int64 so that comparisons like "this.size() == 4"
1782+
# use the built-in _==_(int64, int64) operator. The C++ CEL runtime's built-in
1783+
# size(bytes) returns uint64, but integer literals (e.g. 4) are int64, causing
1784+
# "this.size() == 4" to always be false due to strict type checking.
1785+
# Extension function FunctionDecls add overloads without replacing other
1786+
# parameter-type variants, so size(string)/size(list)/size(map) are unaffected.
17841787
cel.FunctionDecl(
1785-
"_%_",
1788+
"size",
17861789
[
17871790
cel.Overload(
1788-
"_mod__int_uint",
1791+
"size_bytes_int",
17891792
return_type=cel.Type.INT,
1790-
parameters=[cel.Type.INT, cel.Type.UINT],
1791-
is_member=False,
1792-
impl=lambda a, b: a % b,
1793+
parameters=[cel.Type.BYTES],
1794+
is_member=True,
1795+
impl=lambda b: len(b),
17931796
),
17941797
],
17951798
),
1796-
# Cross-type int/uint equality overloads.
1797-
# CEL built-in size() for bytes returns uint64, but integer literals are int64.
1798-
# These overloads allow comparisons like "this.size() == 4" to work correctly.
1799+
# Cross-type int/uint modulo overload.
1800+
# CEL predefined rules for uint types use uint literals (e.g. "this % 2u == 0u"),
1801+
# but Python int values are mapped to CEL int64. The result is uint64 so that
1802+
# the subsequent "== 0u" comparison uses the built-in _==_(uint64, uint64).
1803+
# Operator FunctionDecls replace the built-in, so all standard overloads must
1804+
# be included here alongside the cross-type overload.
17991805
cel.FunctionDecl(
1800-
"_==_",
1806+
"_%_",
18011807
[
18021808
cel.Overload(
1803-
"_eq__int_uint",
1804-
return_type=cel.Type.BOOL,
1805-
parameters=[cel.Type.INT, cel.Type.UINT],
1809+
"_mod__int_int",
1810+
return_type=cel.Type.INT,
1811+
parameters=[cel.Type.INT, cel.Type.INT],
18061812
is_member=False,
1807-
impl=lambda a, b: a == b,
1813+
impl=lambda a, b: a % b,
18081814
),
18091815
cel.Overload(
1810-
"_eq__uint_int",
1811-
return_type=cel.Type.BOOL,
1812-
parameters=[cel.Type.UINT, cel.Type.INT],
1816+
"_mod__uint_uint",
1817+
return_type=cel.Type.UINT,
1818+
parameters=[cel.Type.UINT, cel.Type.UINT],
18131819
is_member=False,
1814-
impl=lambda a, b: a == b,
1820+
impl=lambda a, b: a % b,
18151821
),
1816-
],
1817-
),
1818-
cel.FunctionDecl(
1819-
"_!=_",
1820-
[
18211822
cel.Overload(
1822-
"_ne__int_uint",
1823-
return_type=cel.Type.BOOL,
1823+
"_mod__int_uint",
1824+
return_type=cel.Type.UINT,
18241825
parameters=[cel.Type.INT, cel.Type.UINT],
18251826
is_member=False,
1826-
impl=lambda a, b: a != b,
1827-
),
1828-
cel.Overload(
1829-
"_ne__uint_int",
1830-
return_type=cel.Type.BOOL,
1831-
parameters=[cel.Type.UINT, cel.Type.INT],
1832-
is_member=False,
1833-
impl=lambda a, b: a != b,
1827+
impl=lambda a, b: a % b,
18341828
),
18351829
],
18361830
),

0 commit comments

Comments
 (0)