From 074f1cb8ff382606bd3ac93bf5928edb03906e0a Mon Sep 17 00:00:00 2001 From: neonene <53406459+neonene@users.noreply.github.com> Date: Wed, 17 Apr 2024 06:28:55 +0900 Subject: [PATCH 1/5] disallow defining_class inside a module block --- Lib/test/test_clinic.py | 9 +++++++++ Tools/clinic/libclinic/dsl_parser.py | 2 ++ 2 files changed, 11 insertions(+) diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index 43b629f59f0346..c8dda858e46862 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -2518,6 +2518,15 @@ class m.C "PyObject *" "" p = function.parameters['cls'] self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY) + def test_disallow_defining_class_inside_module(self): + err = "A 'defining_class' parameter can be specified inside a class method." + block = """ + module m + m.func + cls: defining_class + """ + self.expect_failure(block, err, lineno=2) + class ClinicExternalTest(TestCase): maxDiff = None diff --git a/Tools/clinic/libclinic/dsl_parser.py b/Tools/clinic/libclinic/dsl_parser.py index 56c6dca3db3d1d..78525b00fb8d11 100644 --- a/Tools/clinic/libclinic/dsl_parser.py +++ b/Tools/clinic/libclinic/dsl_parser.py @@ -1102,6 +1102,8 @@ def bad_node(self, node: ast.AST) -> None: 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.block.signatures[-1].cls is None: + fail("A 'defining_class' parameter can be specified inside a class method.") kind = inspect.Parameter.POSITIONAL_ONLY else: fail("A 'defining_class' parameter, if specified, must either " From 0db25072f8948a202422bc12382fe36ce4c6d3d5 Mon Sep 17 00:00:00 2001 From: neonene <53406459+neonene@users.noreply.github.com> Date: Wed, 17 Apr 2024 06:59:38 +0900 Subject: [PATCH 2/5] correct error msg --- Lib/test/test_clinic.py | 2 +- Tools/clinic/libclinic/dsl_parser.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index c8dda858e46862..009c7faf631915 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -2519,7 +2519,7 @@ class m.C "PyObject *" "" self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY) def test_disallow_defining_class_inside_module(self): - err = "A 'defining_class' parameter can be specified inside a class method." + err = "A 'defining_class' parameter cannot be defined at module level." block = """ module m m.func diff --git a/Tools/clinic/libclinic/dsl_parser.py b/Tools/clinic/libclinic/dsl_parser.py index 78525b00fb8d11..142b0f66b7e365 100644 --- a/Tools/clinic/libclinic/dsl_parser.py +++ b/Tools/clinic/libclinic/dsl_parser.py @@ -1103,7 +1103,7 @@ def bad_node(self, node: ast.AST) -> None: if self.group: fail("A 'defining_class' parameter cannot be in an optional group.") if self.block.signatures[-1].cls is None: - fail("A 'defining_class' parameter can be specified inside a class method.") + 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 " From 022db2be835ad3e3f61fbec4e1271a5d673040d0 Mon Sep 17 00:00:00 2001 From: neonene <53406459+neonene@users.noreply.github.com> Date: Wed, 17 Apr 2024 07:14:27 +0900 Subject: [PATCH 3/5] correct test name --- Lib/test/test_clinic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index 009c7faf631915..d9e4ce280c68a1 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -2518,7 +2518,7 @@ class m.C "PyObject *" "" p = function.parameters['cls'] self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY) - def test_disallow_defining_class_inside_module(self): + def test_disallow_defining_class_at_module_level(self): err = "A 'defining_class' parameter cannot be defined at module level." block = """ module m From 952e436124241bdb41e0896e12a07cf201f1e597 Mon Sep 17 00:00:00 2001 From: neonene <53406459+neonene@users.noreply.github.com> Date: Wed, 17 Apr 2024 21:25:47 +0900 Subject: [PATCH 4/5] suppress a mypy error --- Tools/clinic/libclinic/dsl_parser.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Tools/clinic/libclinic/dsl_parser.py b/Tools/clinic/libclinic/dsl_parser.py index 142b0f66b7e365..e406e88278f51a 100644 --- a/Tools/clinic/libclinic/dsl_parser.py +++ b/Tools/clinic/libclinic/dsl_parser.py @@ -1102,6 +1102,7 @@ def bad_node(self, node: ast.AST) -> None: fail("A 'defining_class' parameter cannot have a default value.") if self.group: fail("A 'defining_class' parameter cannot be in an optional group.") + assert isinstance(self.block.signatures[-1], Function) if self.block.signatures[-1].cls is None: fail("A 'defining_class' parameter cannot be defined at module level.") kind = inspect.Parameter.POSITIONAL_ONLY From 73bbdfcaae1c4219d961b3e31cfec7c18adde88a Mon Sep 17 00:00:00 2001 From: neonene <53406459+neonene@users.noreply.github.com> Date: Wed, 17 Apr 2024 23:06:46 +0900 Subject: [PATCH 5/5] simplify the check --- Tools/clinic/libclinic/dsl_parser.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Tools/clinic/libclinic/dsl_parser.py b/Tools/clinic/libclinic/dsl_parser.py index e406e88278f51a..cb18374cf07e3c 100644 --- a/Tools/clinic/libclinic/dsl_parser.py +++ b/Tools/clinic/libclinic/dsl_parser.py @@ -1102,8 +1102,7 @@ def bad_node(self, node: ast.AST) -> None: fail("A 'defining_class' parameter cannot have a default value.") if self.group: fail("A 'defining_class' parameter cannot be in an optional group.") - assert isinstance(self.block.signatures[-1], Function) - if self.block.signatures[-1].cls is None: + if self.function.cls is None: fail("A 'defining_class' parameter cannot be defined at module level.") kind = inspect.Parameter.POSITIONAL_ONLY else: