Skip to content

Commit

Permalink
pythongh-104683: Argument clinic: cleanup state_modulename_name() (p…
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexWaygood committed Jul 27, 2023
1 parent 2f9bb77 commit c2b1689
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 10 deletions.
26 changes: 26 additions & 0 deletions Lib/test/test_clinic.py
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,32 @@ def test_return_converter(self):
""")
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
Expand Down
19 changes: 9 additions & 10 deletions Tools/clinic/clinic.py
Original file line number Diff line number Diff line change
Expand Up @@ -4730,6 +4730,7 @@ def state_modulename_name(self, line: str | None) -> None:
return

line, _, returns = line.partition('->')
returns = returns.strip()

full_name, _, c_basename = line.partition(' as ')
full_name = full_name.strip()
Expand All @@ -4743,23 +4744,21 @@ def state_modulename_name(self, line: str | None) -> None:
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()
Expand Down

0 comments on commit c2b1689

Please sign in to comment.