Skip to content

Commit ee1a9d4

Browse files
Minor tweaks / cleanup (#370)
* Use re2 instead of re in more places * Simplify config * Simplify `isinstance` calls with tuples * Use comprehensions when reasonable
1 parent 773b131 commit ee1a9d4

File tree

5 files changed

+16
-58
lines changed

5 files changed

+16
-58
lines changed

protovalidate/internal/extra_func.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
# limitations under the License.
1414

1515
import math
16-
import re
1716
import typing
1817
from urllib import parse as urlparse
1918

@@ -25,7 +24,7 @@
2524
from protovalidate.internal.rules import MessageType, field_to_cel
2625

2726
# See https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address
28-
_email_regex = re.compile(
27+
_email_regex = re2.compile(
2928
r"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"
3029
)
3130

@@ -107,17 +106,17 @@ def cel_is_ip_prefix(val: celtypes.Value, *args) -> celpy.Result:
107106
msg = "invalid argument, expected string or bytes"
108107
raise celpy.CELEvalError(msg)
109108
version = 0
110-
strict = celtypes.BoolType(False)
109+
strict = False
111110
if len(args) == 1 and isinstance(args[0], celtypes.BoolType):
112-
strict = args[0]
111+
strict = bool(args[0])
113112
elif len(args) == 1 and isinstance(args[0], celtypes.IntType):
114113
version = args[0]
115114
elif len(args) == 1 and (not isinstance(args[0], celtypes.BoolType) or not isinstance(args[0], celtypes.IntType)):
116115
msg = "invalid argument, expected bool or int"
117116
raise celpy.CELEvalError(msg)
118117
elif len(args) == 2 and isinstance(args[0], celtypes.IntType) and isinstance(args[1], celtypes.BoolType):
119118
version = args[0]
120-
strict = args[1]
119+
strict = bool(args[1])
121120
elif len(args) == 2 and (not isinstance(args[0], celtypes.IntType) or not isinstance(args[1], celtypes.BoolType)):
122121
msg = "invalid argument, expected int and bool"
123122
raise celpy.CELEvalError(msg)

protovalidate/internal/rules.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,14 +413,14 @@ def validate(self, ctx: RuleContext, msg: message.Message):
413413
ctx.add(
414414
Violation(
415415
rule_id="message.oneof",
416-
message=f"only one of {', '.join([field.name for field in self._fields])} can be set",
416+
message=f"only one of {', '.join(field.name for field in self._fields)} can be set",
417417
)
418418
)
419419
if self._required and num_set_fields == 0:
420420
ctx.add(
421421
Violation(
422422
rule_id="message.oneof",
423-
message=f"one of {', '.join([field.name for field in self._fields])} must be set",
423+
message=f"one of {', '.join(field.name for field in self._fields)} must be set",
424424
)
425425
)
426426

protovalidate/internal/string_format.py

Lines changed: 9 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,7 @@ def __format_exponential(self, arg: celtypes.Value, precision: int) -> str:
122122
raise celpy.CELEvalError(msg)
123123

124124
def __format_int(self, arg: celtypes.Value) -> str:
125-
if (
126-
isinstance(arg, celtypes.IntType)
127-
or isinstance(arg, celtypes.UintType)
128-
or isinstance(arg, celtypes.DoubleType)
129-
):
125+
if isinstance(arg, (celtypes.IntType, celtypes.UintType, celtypes.DoubleType)):
130126
result = self.__validate_number(arg)
131127
if result is not None:
132128
return result
@@ -138,9 +134,7 @@ def __format_int(self, arg: celtypes.Value) -> str:
138134
raise celpy.CELEvalError(msg)
139135

140136
def __format_hex(self, arg: celtypes.Value) -> str:
141-
if isinstance(arg, celtypes.IntType):
142-
return f"{arg:x}"
143-
if isinstance(arg, celtypes.UintType):
137+
if isinstance(arg, (celtypes.IntType, celtypes.UintType)):
144138
return f"{arg:x}"
145139
if isinstance(arg, celtypes.BytesType):
146140
return arg.hex()
@@ -153,9 +147,7 @@ def __format_hex(self, arg: celtypes.Value) -> str:
153147
raise celpy.CELEvalError(msg)
154148

155149
def __format_oct(self, arg: celtypes.Value) -> str:
156-
if isinstance(arg, celtypes.IntType):
157-
return f"{arg:o}"
158-
if isinstance(arg, celtypes.UintType):
150+
if isinstance(arg, (celtypes.IntType, celtypes.UintType)):
159151
return f"{arg:o}"
160152
msg = (
161153
"error during formatting: octal clause can only be used on integers, was given "
@@ -164,17 +156,12 @@ def __format_oct(self, arg: celtypes.Value) -> str:
164156
raise celpy.CELEvalError(msg)
165157

166158
def __format_bin(self, arg: celtypes.Value) -> str:
167-
if isinstance(arg, celtypes.IntType):
168-
return f"{arg:b}"
169-
if isinstance(arg, celtypes.UintType):
170-
return f"{arg:b}"
171-
if isinstance(arg, celtypes.BoolType):
159+
if isinstance(arg, (celtypes.IntType, celtypes.UintType, celtypes.BoolType)):
172160
return f"{arg:b}"
173161
msg = (
174162
"error during formatting: only integers and bools can be formatted as binary, was given "
175163
f"{self.__type_str(type(arg))}"
176164
)
177-
178165
raise celpy.CELEvalError(msg)
179166

180167
def __format_string(self, arg: celtypes.Value) -> str:
@@ -189,6 +176,7 @@ def __format_string(self, arg: celtypes.Value) -> str:
189176
decoded = arg.decode("utf-8", errors="replace")
190177
# Collapse any contiguous placeholders into one
191178
return re.sub("\\ufffd+", "\ufffd", decoded)
179+
192180
if isinstance(arg, celtypes.DoubleType):
193181
result = self.__validate_number(arg)
194182
if result is not None:
@@ -206,7 +194,7 @@ def __format_string(self, arg: celtypes.Value) -> str:
206194
if isinstance(arg, celtypes.MapType):
207195
return self.__format_map(arg)
208196
if isinstance(arg, celtypes.StringType):
209-
return f"{arg}"
197+
return arg
210198
if isinstance(arg, celtypes.TimestampType):
211199
base = arg.isoformat()
212200
if arg.getMilliseconds() != 0:
@@ -215,31 +203,11 @@ def __format_string(self, arg: celtypes.Value) -> str:
215203
return "unknown"
216204

217205
def __format_list(self, arg: celtypes.ListType) -> str:
218-
result = "["
219-
for i in range(len(arg)):
220-
if i > 0:
221-
result += ", "
222-
result += self.__format_string(arg[i])
223-
result += "]"
224-
return result
206+
return "[" + ", ".join(self.__format_string(val) for val in arg) + "]"
225207

226208
def __format_map(self, arg: celtypes.MapType) -> str:
227-
m = {}
228-
for cel_key, cel_val in arg.items():
229-
key = self.__format_string(cel_key)
230-
val = self.__format_string(cel_val)
231-
m[key] = val
232-
233-
m = dict(sorted(m.items()))
234-
235-
result = "{"
236-
for i, (key, val) in enumerate(m.items()):
237-
if i > 0:
238-
result += ", "
239-
result += key + ": " + val
240-
241-
result += "}"
242-
return result
209+
m = {self.__format_string(cel_key): self.__format_string(cel_val) for cel_key, cel_val in arg.items()}
210+
return "{" + ", ".join(key + ": " + val for key, val in sorted(m.items())) + "}"
243211

244212
def __format_duration(self, arg: celtypes.DurationType) -> str:
245213
return f"{arg.seconds + Decimal(arg.microseconds) / Decimal(1_000_000):f}s"

protovalidate/validator.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,7 @@ def to_proto(self) -> validate_pb2.Violations:
105105
"""
106106
Provides the Protobuf form of the validation errors.
107107
"""
108-
result = validate_pb2.Violations()
109-
for violation in self._violations:
110-
result.violations.append(violation.proto)
111-
return result
108+
return validate_pb2.Violations(violations=[violation.proto for violation in self._violations])
112109

113110
@property
114111
def violations(self) -> list[Violation]:

pyproject.toml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,6 @@ lint.select = [
7979
"YTT",
8080
]
8181
lint.ignore = [
82-
# Allow boolean positional values in function calls, like `dict.get(..., True)`.
83-
"FBT003",
8482
# Ignore complexity
8583
"C901",
8684
"PLR0911",
@@ -90,10 +88,6 @@ lint.ignore = [
9088
# Ignore magic values - in this library, most are obvious in context.
9189
"PLR2004",
9290
]
93-
lint.unfixable = [
94-
# Don't autofix unused imports.
95-
"F401",
96-
]
9791

9892
[tool.ruff.lint.isort]
9993
known-first-party = ["protovalidate", "buf"]

0 commit comments

Comments
 (0)