[3.12] gh-117613: Argument Clinic: ensure that defining class params are positional-only (#117939)

This commit is contained in:
neonene 2024-04-18 06:11:17 +09:00 committed by GitHub
parent a72c4a93ef
commit 9f4ae13d2a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 29 additions and 1 deletions

View file

@ -1347,6 +1347,28 @@ def test_unused_param(self):
parser_decl = p.simple_declaration(in_parser=True)
self.assertNotIn("Py_UNUSED", parser_decl)
def test_kind_defining_class(self):
function = self.parse_function("""
module m
class m.C "PyObject *" ""
m.C.meth
cls: defining_class
""", signatures_in_block=3, function_index=2)
p = function.parameters['cls']
self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
def test_disallow_defining_class_at_module_level(self):
expected_error_msg = (
"Error on line 0:\n"
"A 'defining_class' parameter cannot be defined at module level.\n"
)
out = self.parse_function_should_fail("""
module m
m.func
cls: defining_class
""")
self.assertEqual(out, expected_error_msg)
def parse(self, text):
c = FakeClinic()
parser = DSLParser(c)

View file

@ -4997,6 +4997,9 @@ def bad_node(self, node):
fail("A 'defining_class' parameter cannot have a default value.")
if self.group:
fail("A 'defining_class' parameter cannot be in an optional group.")
if self.function.cls is None:
fail("A 'defining_class' parameter cannot be defined at module level.")
kind = inspect.Parameter.POSITIONAL_ONLY
else:
fail("A 'defining_class' parameter, if specified, must either be the first thing in the parameter block, or come just after 'self'.")
@ -5074,7 +5077,10 @@ def parse_special_symbol(self, symbol):
for p in self.function.parameters.values():
if p.is_vararg():
continue
if (p.kind != inspect.Parameter.POSITIONAL_OR_KEYWORD and not isinstance(p.converter, self_converter)):
if (p.kind != inspect.Parameter.POSITIONAL_OR_KEYWORD and
not isinstance(p.converter, self_converter) and
not isinstance(p.converter, defining_class_converter)
):
fail("Function " + self.function.name + " mixes keyword-only and positional-only parameters, which is unsupported.")
p.kind = inspect.Parameter.POSITIONAL_ONLY