]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-104683: Argument clinic: cleanup `state_modulename_name()` (#107340)
authorAlex Waygood <Alex.Waygood@Gmail.com>
Thu, 27 Jul 2023 21:51:18 +0000 (22:51 +0100)
committerGitHub <noreply@github.com>
Thu, 27 Jul 2023 21:51:18 +0000 (22:51 +0100)
Lib/test/test_clinic.py
Tools/clinic/clinic.py

index d1c61b1d401b98d382156cb224f1d4a26bd00c3e..d21c7d84c88d2dad18102589b07648aad716d834 100644 (file)
@@ -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
index 5d3ed4167b06c476ddba16a05dd81071d52fd2e5..a343dc5c7fc080884c0cdafe742cb4545adc34f0 100755 (executable)
@@ -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()