From c2b1689abcfa80ad959862168b5260fbbd478484 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Thu, 27 Jul 2023 22:51:18 +0100 Subject: gh-104683: Argument clinic: cleanup `state_modulename_name()` (#107340) --- Lib/test/test_clinic.py | 26 ++++++++++++++++++++++++++ Tools/clinic/clinic.py | 19 +++++++++---------- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index d1c61b1..d21c7d8 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -679,6 +679,32 @@ class ClinicParserTest(_ParserBase): """) self.assertIsInstance(function.return_converter, clinic.int_return_converter) + def test_return_converter_invalid_syntax(self): + stdout = self.parse_function_should_fail(""" + module os + os.stat -> invalid syntax + """) + expected_error = "Badly formed annotation for os.stat: 'invalid syntax'" + self.assertIn(expected_error, stdout) + + def test_legacy_converter_disallowed_in_return_annotation(self): + stdout = self.parse_function_should_fail(""" + module os + os.stat -> "s" + """) + expected_error = "Legacy converter 's' not allowed as a return converter" + self.assertIn(expected_error, stdout) + + def test_unknown_return_converter(self): + stdout = self.parse_function_should_fail(""" + module os + os.stat -> foooooooooooooooooooooooo + """) + expected_error = ( + "No available return converter called 'foooooooooooooooooooooooo'" + ) + self.assertIn(expected_error, stdout) + def test_star(self): function = self.parse_function(""" module os diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 5d3ed41..a343dc5 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -4730,6 +4730,7 @@ class DSLParser: return line, _, returns = line.partition('->') + returns = returns.strip() full_name, _, c_basename = line.partition(' as ') full_name = full_name.strip() @@ -4743,23 +4744,21 @@ class DSLParser: return_converter = None if returns: ast_input = f"def x() -> {returns}: pass" - module = None try: - module = ast.parse(ast_input) + module_node = ast.parse(ast_input) except SyntaxError: - pass - if not module: - fail("Badly-formed annotation for " + full_name + ": " + returns) + fail(f"Badly formed annotation for {full_name}: {returns!r}") + function_node = module_node.body[0] + assert isinstance(function_node, ast.FunctionDef) try: - name, legacy, kwargs = self.parse_converter(module.body[0].returns) + name, legacy, kwargs = self.parse_converter(function_node.returns) if legacy: - fail("Legacy converter {!r} not allowed as a return converter" - .format(name)) + fail(f"Legacy converter {name!r} not allowed as a return converter") if name not in return_converters: - fail("No available return converter called " + repr(name)) + fail(f"No available return converter called {name!r}") return_converter = return_converters[name](**kwargs) except ValueError: - fail("Badly-formed annotation for " + full_name + ": " + returns) + fail(f"Badly formed annotation for {full_name}: {returns!r}") fields = [x.strip() for x in full_name.split('.')] function_name = fields.pop() -- cgit v0.12