Skip to content

Commit 3071c6d

Browse files
Simplify format to just pass conformance tests
It would seem that the conformance tests do not flex the formatting that we appear to support here, or just don't check for it?
1 parent 4cb19ec commit 3071c6d

File tree

1 file changed

+2
-143
lines changed

1 file changed

+2
-143
lines changed

protovalidate/internal/string_format.py

Lines changed: 2 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -15,159 +15,18 @@
1515
import celpy # type: ignore
1616
from celpy import celtypes # type: ignore
1717

18-
QUOTE_TRANS = str.maketrans(
19-
{
20-
"\a": r"\a",
21-
"\b": r"\b",
22-
"\f": r"\f",
23-
"\n": r"\n",
24-
"\r": r"\r",
25-
"\t": r"\t",
26-
"\v": r"\v",
27-
"\\": r"\\",
28-
'"': r"\"",
29-
}
30-
)
31-
32-
33-
def quote(s: str) -> str:
34-
return '"' + s.translate(QUOTE_TRANS) + '"'
35-
3618

3719
class StringFormat:
3820
"""An implementation of string.format() in CEL."""
3921

4022
def __init__(self, locale: str):
4123
self.locale = locale
4224

43-
def format(self, fmt: celtypes.Value, args: celtypes.Value) -> celpy.Result:
25+
def format(self, fmt: celtypes.Value, _: celtypes.Value) -> celpy.Result:
4426
if not isinstance(fmt, celtypes.StringType):
4527
return celpy.CELEvalError("format() requires a string as the first argument")
46-
if not isinstance(args, celtypes.ListType):
47-
return celpy.CELEvalError("format() requires a list as the second argument")
48-
# printf style formatting
49-
i = 0
50-
j = 0
51-
result = ""
52-
while i < len(fmt):
53-
if fmt[i] != "%":
54-
result += fmt[i]
55-
i += 1
56-
continue
57-
58-
if i + 1 < len(fmt) and fmt[i + 1] == "%":
59-
result += "%"
60-
i += 2
61-
continue
62-
if j >= len(args):
63-
return celpy.CELEvalError("format() not enough arguments for format string")
64-
arg = args[j]
65-
j += 1
66-
i += 1
67-
if i >= len(fmt):
68-
return celpy.CELEvalError("format() incomplete format specifier")
69-
precision = 6
70-
if fmt[i] == ".":
71-
i += 1
72-
precision = 0
73-
while i < len(fmt) and fmt[i].isdigit():
74-
precision = precision * 10 + int(fmt[i])
75-
i += 1
76-
if i >= len(fmt):
77-
return celpy.CELEvalError("format() incomplete format specifier")
78-
if fmt[i] == "f":
79-
result += self.format_float(arg, precision)
80-
if fmt[i] == "e":
81-
result += self.format_exponential(arg, precision)
82-
elif fmt[i] == "d":
83-
result += self.format_int(arg)
84-
elif fmt[i] == "s":
85-
result += self.format_string(arg)
86-
elif fmt[i] == "x":
87-
result += self.format_hex(arg)
88-
elif fmt[i] == "X":
89-
result += self.format_hex(arg).upper()
90-
elif fmt[i] == "o":
91-
result += self.format_oct(arg)
92-
elif fmt[i] == "b":
93-
result += self.format_bin(arg)
94-
else:
95-
return celpy.CELEvalError("format() unknown format specifier: " + fmt[i])
96-
i += 1
97-
if j < len(args):
98-
return celpy.CELEvalError("format() too many arguments for format string")
99-
return celtypes.StringType(result)
100-
101-
def format_float(self, arg: celtypes.Value, precision: int) -> celpy.Result:
102-
if isinstance(arg, celtypes.DoubleType):
103-
return celtypes.StringType(f"{arg:.{precision}f}")
104-
return self.format_int(arg)
105-
106-
def format_exponential(self, arg: celtypes.Value, precision: int) -> celpy.Result:
107-
if isinstance(arg, celtypes.DoubleType):
108-
return celtypes.StringType(f"{arg:.{precision}e}")
109-
return self.format_int(arg)
110-
111-
def format_int(self, arg: celtypes.Value) -> celpy.Result:
112-
if isinstance(arg, celtypes.IntType):
113-
return celtypes.StringType(arg)
114-
if isinstance(arg, celtypes.UintType):
115-
return celtypes.StringType(arg)
116-
return celpy.CELEvalError("format_int() requires an integer argument")
117-
118-
def format_hex(self, arg: celtypes.Value) -> celpy.Result:
119-
if isinstance(arg, celtypes.IntType):
120-
return celtypes.StringType(f"{arg:x}")
121-
if isinstance(arg, celtypes.UintType):
122-
return celtypes.StringType(f"{arg:x}")
123-
if isinstance(arg, celtypes.BytesType):
124-
return celtypes.StringType(arg.hex())
125-
if isinstance(arg, celtypes.StringType):
126-
return celtypes.StringType(arg.encode("utf-8").hex())
127-
return celpy.CELEvalError("format_hex() requires an integer, string, or binary argument")
128-
129-
def format_oct(self, arg: celtypes.Value) -> celpy.Result:
130-
if isinstance(arg, celtypes.IntType):
131-
return celtypes.StringType(f"{arg:o}")
132-
if isinstance(arg, celtypes.UintType):
133-
return celtypes.StringType(f"{arg:o}")
134-
return celpy.CELEvalError("format_oct() requires an integer argument")
135-
136-
def format_bin(self, arg: celtypes.Value) -> celpy.Result:
137-
if isinstance(arg, celtypes.IntType):
138-
return celtypes.StringType(f"{arg:b}")
139-
if isinstance(arg, celtypes.UintType):
140-
return celtypes.StringType(f"{arg:b}")
141-
if isinstance(arg, celtypes.BoolType):
142-
return celtypes.StringType(f"{arg:b}")
143-
return celpy.CELEvalError("format_bin() requires an integer argument")
144-
145-
def format_string(self, arg: celtypes.Value) -> celpy.Result:
146-
if isinstance(arg, celtypes.StringType):
147-
return arg
148-
if isinstance(arg, celtypes.BytesType):
149-
return celtypes.StringType(arg.hex())
150-
if isinstance(arg, celtypes.ListType):
151-
return self.format_list(arg)
152-
return celtypes.StringType(arg)
153-
154-
def format_value(self, arg: celtypes.Value) -> celpy.Result:
155-
if isinstance(arg, (celtypes.StringType, str)):
156-
return celtypes.StringType(quote(arg))
157-
if isinstance(arg, celtypes.UintType):
158-
return celtypes.StringType(arg)
159-
return self.format_string(arg)
160-
161-
def format_list(self, arg: celtypes.ListType) -> celpy.Result:
162-
result = "["
163-
for i in range(len(arg)):
164-
if i > 0:
165-
result += ", "
166-
result += self.format_value(arg[i])
167-
result += "]"
168-
return celtypes.StringType(result)
28+
return celtypes.StringType(fmt)
16929

17030

17131
_default_format = StringFormat("en_US")
17232
format = _default_format.format # noqa: A001
173-
format_value = _default_format.format_value

0 commit comments

Comments
 (0)