From 2899599f40d678cec22e5f8811d83d23e3256ce4 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 3 Jul 2023 22:16:50 +0200 Subject: [PATCH 1/3] [3.11] gh-106368: Increase Argument Clinic test coverage (#106369) Add tests for 'self' and 'defining_class' converter requirements. (cherry picked from commit 7f4c8121db62a9f72f00f2d9f73381e82f289581) Co-authored-by: Erlend E. Aasland --- Lib/test/test_clinic.py | 111 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index 8d4f92fa310c3e..dbac535959d732 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -812,6 +812,117 @@ def test_other_bizarre_things_in_annotations_fail(self): ) self.assertEqual(s, expected_failure_message) + def test_kwarg_splats_disallowed_in_function_call_annotations(self): + expected_error_msg = ( + "Error on line 0:\n" + "Cannot use a kwarg splat in a function-call annotation\n" + ) + dataset = ( + 'module fo\nfo.barbaz\n o: bool(**{None: "bang!"})', + 'module fo\nfo.barbaz -> bool(**{None: "bang!"})', + 'module fo\nfo.barbaz -> bool(**{"bang": 42})', + 'module fo\nfo.barbaz\n o: bool(**{"bang": None})', + ) + for fn in dataset: + with self.subTest(fn=fn): + out = self.parse_function_should_fail(fn) + self.assertEqual(out, expected_error_msg) + + def test_self_param_placement(self): + expected_error_msg = ( + "Error on line 0:\n" + "A 'self' parameter, if specified, must be the very first thing " + "in the parameter block.\n" + ) + block = """ + module foo + foo.func + a: int + self: self(type="PyObject *") + """ + out = self.parse_function_should_fail(block) + self.assertEqual(out, expected_error_msg) + + def test_self_param_cannot_be_optional(self): + expected_error_msg = ( + "Error on line 0:\n" + "A 'self' parameter cannot be marked optional.\n" + ) + block = """ + module foo + foo.func + self: self(type="PyObject *") = None + """ + out = self.parse_function_should_fail(block) + self.assertEqual(out, expected_error_msg) + + def test_defining_class_param_placement(self): + expected_error_msg = ( + "Error on line 0:\n" + "A 'defining_class' parameter, if specified, must either be the " + "first thing in the parameter block, or come just after 'self'.\n" + ) + block = """ + module foo + foo.func + self: self(type="PyObject *") + a: int + cls: defining_class + """ + out = self.parse_function_should_fail(block) + self.assertEqual(out, expected_error_msg) + + def test_defining_class_param_cannot_be_optional(self): + expected_error_msg = ( + "Error on line 0:\n" + "A 'defining_class' parameter cannot be marked optional.\n" + ) + block = """ + module foo + foo.func + cls: defining_class(type="PyObject *") = None + """ + out = self.parse_function_should_fail(block) + self.assertEqual(out, expected_error_msg) + + def test_unused_param(self): + block = self.parse(""" + module foo + foo.func + fn: object + k: float + i: float(unused=True) + / + * + flag: bool(unused=True) = False + """) + sig = block.signatures[1] # Function index == 1 + params = sig.parameters + conv = lambda fn: params[fn].converter + dataset = ( + {"name": "fn", "unused": False}, + {"name": "k", "unused": False}, + {"name": "i", "unused": True}, + {"name": "flag", "unused": True}, + ) + for param in dataset: + name, unused = param.values() + with self.subTest(name=name, unused=unused): + p = conv(name) + # Verify that the unused flag is parsed correctly. + self.assertEqual(unused, p.unused) + + # Now, check that we'll produce correct code. + decl = p.simple_declaration(in_parser=False) + if unused: + self.assertIn("Py_UNUSED", decl) + else: + self.assertNotIn("Py_UNUSED", decl) + + # Make sure the Py_UNUSED macro is not used in the parser body. + parser_decl = p.simple_declaration(in_parser=True) + self.assertNotIn("Py_UNUSED", parser_decl) + def parse(self, text): c = FakeClinic() parser = DSLParser(c) From b0621092d725ca70db5b69a88234f1395e1c5633 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 3 Jul 2023 23:12:03 +0200 Subject: [PATCH 2/3] Unused param is not available in 3.11 --- Lib/test/test_clinic.py | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index dbac535959d732..be4553a27b245e 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -885,44 +885,6 @@ def test_defining_class_param_cannot_be_optional(self): out = self.parse_function_should_fail(block) self.assertEqual(out, expected_error_msg) - def test_unused_param(self): - block = self.parse(""" - module foo - foo.func - fn: object - k: float - i: float(unused=True) - / - * - flag: bool(unused=True) = False - """) - sig = block.signatures[1] # Function index == 1 - params = sig.parameters - conv = lambda fn: params[fn].converter - dataset = ( - {"name": "fn", "unused": False}, - {"name": "k", "unused": False}, - {"name": "i", "unused": True}, - {"name": "flag", "unused": True}, - ) - for param in dataset: - name, unused = param.values() - with self.subTest(name=name, unused=unused): - p = conv(name) - # Verify that the unused flag is parsed correctly. - self.assertEqual(unused, p.unused) - - # Now, check that we'll produce correct code. - decl = p.simple_declaration(in_parser=False) - if unused: - self.assertIn("Py_UNUSED", decl) - else: - self.assertNotIn("Py_UNUSED", decl) - - # Make sure the Py_UNUSED macro is not used in the parser body. - parser_decl = p.simple_declaration(in_parser=True) - self.assertNotIn("Py_UNUSED", parser_decl) - def parse(self, text): c = FakeClinic() parser = DSLParser(c) From 4ca8a9c53df836ff1a271cd8a8636885518c7681 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 3 Jul 2023 23:36:51 +0200 Subject: [PATCH 3/3] The kwargs bugfix is not in 3.11 --- Lib/test/test_clinic.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index be4553a27b245e..c2d2085ecd6de9 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -812,22 +812,6 @@ def test_other_bizarre_things_in_annotations_fail(self): ) self.assertEqual(s, expected_failure_message) - def test_kwarg_splats_disallowed_in_function_call_annotations(self): - expected_error_msg = ( - "Error on line 0:\n" - "Cannot use a kwarg splat in a function-call annotation\n" - ) - dataset = ( - 'module fo\nfo.barbaz\n o: bool(**{None: "bang!"})', - 'module fo\nfo.barbaz -> bool(**{None: "bang!"})', - 'module fo\nfo.barbaz -> bool(**{"bang": 42})', - 'module fo\nfo.barbaz\n o: bool(**{"bang": None})', - ) - for fn in dataset: - with self.subTest(fn=fn): - out = self.parse_function_should_fail(fn) - self.assertEqual(out, expected_error_msg) - def test_self_param_placement(self): expected_error_msg = ( "Error on line 0:\n" pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy