Skip to content

Commit 94e082e

Browse files
Improve str_converter unsupported combination of args error message
1 parent 53b2e04 commit 94e082e

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

Lib/test/test_clinic.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2028,6 +2028,15 @@ def test_legacy_converters_non_string_constant_annotation(self):
20282028
with self.subTest(block=block):
20292029
self.expect_failure(block, err, lineno=2)
20302030

2031+
def test_str_converter_invalid_format_unit(self):
2032+
block = """
2033+
module foo
2034+
foo.bar
2035+
a: str(encoding='foo', zeroes=True, accept={})
2036+
"""
2037+
err = "unsupported combination of str converter arguments"
2038+
self.expect_failure(block, err, lineno=2)
2039+
20312040
def test_other_bizarre_things_in_annotations_fail(self):
20322041
err = "Annotations must be either a name, a function call, or a string"
20332042
dataset = (

Tools/clinic/clinic.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4043,14 +4043,27 @@ class buffer: pass
40434043
class rwbuffer: pass
40444044
class robuffer: pass
40454045

4046-
StrConverterKeyType = tuple[frozenset[type[object]], bool, bool]
4046+
@dc.dataclass
4047+
class StrConverterKey:
4048+
accept: frozenset[type[object]]
4049+
encoding: bool
4050+
zeroes: bool
4051+
4052+
def __hash__(self) -> int:
4053+
return hash((self.accept, self.encoding, self.zeroes))
4054+
4055+
def __str__(self) -> str:
4056+
accept = "{" + ", ".join([tp.__name__ for tp in self.accept]) + "}"
4057+
encoding = 'encodingname' if self.encoding else None
4058+
zeroes = self.zeroes
4059+
return f"{accept=!r}, {encoding=!r}, {zeroes=!r}"
40474060

40484061
def str_converter_key(
40494062
types: TypeSet, encoding: bool | str | None, zeroes: bool
4050-
) -> StrConverterKeyType:
4051-
return (frozenset(types), bool(encoding), bool(zeroes))
4063+
) -> StrConverterKey:
4064+
return StrConverterKey(frozenset(types), bool(encoding), bool(zeroes))
40524065

4053-
str_converter_argument_map: dict[StrConverterKeyType, str] = {}
4066+
str_converter_argument_map: dict[StrConverterKey, str] = {}
40544067

40554068
class str_converter(CConverter):
40564069
type = 'const char *'
@@ -4068,7 +4081,10 @@ def converter_init(
40684081
key = str_converter_key(accept, encoding, zeroes)
40694082
format_unit = str_converter_argument_map.get(key)
40704083
if not format_unit:
4071-
fail("str_converter: illegal combination of arguments", key)
4084+
fail("unsupported combination of str converter arguments: "
4085+
f"{accept=!r}, {encoding=!r}, {zeroes=!r}; "
4086+
"allowed combinations are:\n\n"
4087+
f"{'\n'.join([str(k) for k in str_converter_argument_map.keys()])}")
40724088

40734089
self.format_unit = format_unit
40744090
self.length = bool(zeroes)

0 commit comments

Comments
 (0)