diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index a6ce9c2570cb62..108dc15c83356d 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -797,21 +797,18 @@ def test_other_bizarre_things_in_annotations_fail(self): Error on line 0: Annotations must be either a name, a function call, or a string. """ - - s = self.parse_function_should_fail( - 'module os\nos.access\n path: {"some": "dictionary"}' - ) - self.assertEqual(s, expected_failure_message) - - s = self.parse_function_should_fail( - 'module os\nos.access\n path: ["list", "of", "strings"]' + dataset = ( + 'module os\nos.access\n path: {"some": "dictionary"}', + 'module os\nos.access\n path: ["list", "of", "strings"]', + 'module os\nos.access\n path: (x for x in range(42))', + 'module fo\nfo.barbaz\n o: bool(**{None: "bang!"})', + 'module fo\nfo.barbaz -> bool(**{None: "bang!"})', ) - self.assertEqual(s, expected_failure_message) - s = self.parse_function_should_fail( - 'module os\nos.access\n path: (x for x in range(42))' - ) - self.assertEqual(s, expected_failure_message) + for fn in dataset: + with self.subTest(fn=fn): + actual = self.parse_function_should_fail(fn) + self.assertEqual(actual, expected_failure_message) def test_unused_param(self): block = self.parse(""" diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 2e46131d4e336a..a7a4d3dc93d1a5 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -5033,10 +5033,11 @@ def bad_node(self, node): key = f"{parameter_name}_as_{c_name}" if c_name else parameter_name self.function.parameters[key] = p - KwargDict = dict[str | None, Any] + KwargDict = dict[str, Any] @staticmethod def parse_converter(annotation: ast.expr | None) -> tuple[str, bool, KwargDict]: + msg = "Annotations must be either a name, a function call, or a string." match annotation: case ast.Constant(value=str() as value): return value, True, {} @@ -5044,15 +5045,15 @@ def parse_converter(annotation: ast.expr | None) -> tuple[str, bool, KwargDict]: return name, False, {} case ast.Call(func=ast.Name(name)): symbols = globals() - kwargs = { - node.arg: eval_ast_expr(node.value, symbols) - for node in annotation.keywords - } + kwargs: dict[str, Any] = {} + for node in annotation.keywords: + if not isinstance(node.arg, str): + fail(msg) + kwargs[node.arg] = eval_ast_expr(node.value, symbols) + print(kwargs) return name, False, kwargs case _: - fail( - "Annotations must be either a name, a function call, or a string." - ) + fail(msg) def parse_special_symbol(self, symbol): if symbol == '*':