Mailing List Archive

[3.12] gh-117613: Argument Clinic: ensure that defining class params are positional-only (#117939)
https://github.com/python/cpython/commit/9f4ae13d2a432faa80e76e3948aec43f856fd320
commit: 9f4ae13d2a432faa80e76e3948aec43f856fd320
branch: 3.12
author: neonene <53406459+neonene@users.noreply.github.com>
committer: erlend-aasland <erlend.aasland@protonmail.com>
date: 2024-04-17T21:11:17Z
summary:

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

files:
M Lib/test/test_clinic.py
M Tools/clinic/clinic.py

diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py
index 3a0ff940d6a620..c114a62ce09d8d 100644
--- a/Lib/test/test_clinic.py
+++ b/Lib/test/test_clinic.py
@@ -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)
diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py
index d2ff422911ce15..efd519ff5ee629 100755
--- a/Tools/clinic/clinic.py
+++ b/Tools/clinic/clinic.py
@@ -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


_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-leave@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: list-python-checkins@lists.gossamer-threads.com