[Python-checkins] [3.12] gh-106368: Increase Argument Clinic BlockParser test coverage (GH-106759) (#106769)

erlend-aasland webhook-mailer at python.org
Sat Jul 15 05:55:28 EDT 2023


https://github.com/python/cpython/commit/1fe841254e453679ffeb16aa48ef633e67b7c08d
commit: 1fe841254e453679ffeb16aa48ef633e67b7c08d
branch: 3.12
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: erlend-aasland <erlend.aasland at protonmail.com>
date: 2023-07-15T09:55:25Z
summary:

[3.12] gh-106368: Increase Argument Clinic BlockParser test coverage (GH-106759) (#106769)

(cherry picked from commit 2d7d1aa4bcd5da0177458b22b1b856db76aa20d4)

Co-authored-by: Erlend E. Aasland <erlend at python.org>

files:
M Lib/test/test_clinic.py

diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py
index 975840333e590..b5744f7013d6a 100644
--- a/Lib/test/test_clinic.py
+++ b/Lib/test/test_clinic.py
@@ -18,6 +18,19 @@
     from clinic import DSLParser
 
 
+class _ParserBase(TestCase):
+    maxDiff = None
+
+    def expect_parser_failure(self, parser, _input):
+        with support.captured_stdout() as stdout:
+            with self.assertRaises(SystemExit):
+                parser(_input)
+        return stdout.getvalue()
+
+    def parse_function_should_fail(self, _input):
+        return self.expect_parser_failure(self.parse_function, _input)
+
+
 class FakeConverter:
     def __init__(self, name, args):
         self.name = name
@@ -88,7 +101,15 @@ def directive(self, name, args):
 
     _module_and_class = clinic.Clinic._module_and_class
 
-class ClinicWholeFileTest(TestCase):
+
+class ClinicWholeFileTest(_ParserBase):
+    def setUp(self):
+        self.clinic = clinic.Clinic(clinic.CLanguage(None), filename="test.c")
+
+    def expect_failure(self, raw):
+        _input = dedent(raw).strip()
+        return self.expect_parser_failure(self.clinic.parse, _input)
+
     def test_eol(self):
         # regression test:
         # clinic's block parser didn't recognize
@@ -98,15 +119,86 @@ def test_eol(self):
         # so it would spit out an end line for you.
         # and since you really already had one,
         # the last line of the block got corrupted.
-        c = clinic.Clinic(clinic.CLanguage(None), filename="file")
         raw = "/*[clinic]\nfoo\n[clinic]*/"
-        cooked = c.parse(raw).splitlines()
+        cooked = self.clinic.parse(raw).splitlines()
         end_line = cooked[2].rstrip()
         # this test is redundant, it's just here explicitly to catch
         # the regression test so we don't forget what it looked like
         self.assertNotEqual(end_line, "[clinic]*/[clinic]*/")
         self.assertEqual(end_line, "[clinic]*/")
 
+    def test_mangled_marker_line(self):
+        raw = """
+            /*[clinic input]
+            [clinic start generated code]*/
+            /*[clinic end generated code: foo]*/
+        """
+        msg = (
+            'Error in file "test.c" on line 3:\n'
+            "Mangled Argument Clinic marker line: '/*[clinic end generated code: foo]*/'\n"
+        )
+        out = self.expect_failure(raw)
+        self.assertEqual(out, msg)
+
+    def test_checksum_mismatch(self):
+        raw = """
+            /*[clinic input]
+            [clinic start generated code]*/
+            /*[clinic end generated code: output=0123456789abcdef input=fedcba9876543210]*/
+        """
+        msg = (
+            'Error in file "test.c" on line 3:\n'
+            'Checksum mismatch!\n'
+            'Expected: 0123456789abcdef\n'
+            'Computed: da39a3ee5e6b4b0d\n'
+        )
+        out = self.expect_failure(raw)
+        self.assertIn(msg, out)
+
+    def test_garbage_after_stop_line(self):
+        raw = """
+            /*[clinic input]
+            [clinic start generated code]*/foobarfoobar!
+        """
+        msg = (
+            'Error in file "test.c" on line 2:\n'
+            "Garbage after stop line: 'foobarfoobar!'\n"
+        )
+        out = self.expect_failure(raw)
+        self.assertEqual(out, msg)
+
+    def test_whitespace_before_stop_line(self):
+        raw = """
+            /*[clinic input]
+             [clinic start generated code]*/
+        """
+        msg = (
+            'Error in file "test.c" on line 2:\n'
+            "Whitespace is not allowed before the stop line: ' [clinic start generated code]*/'\n"
+        )
+        out = self.expect_failure(raw)
+        self.assertEqual(out, msg)
+
+    def test_parse_with_body_prefix(self):
+        clang = clinic.CLanguage(None)
+        clang.body_prefix = "//"
+        clang.start_line = "//[{dsl_name} start]"
+        clang.stop_line = "//[{dsl_name} stop]"
+        cl = clinic.Clinic(clang, filename="test.c")
+        raw = dedent("""
+            //[clinic start]
+            //module test
+            //[clinic stop]
+        """).strip()
+        out = cl.parse(raw)
+        expected = dedent("""
+            //[clinic start]
+            //module test
+            //
+            //[clinic stop]
+            /*[clinic end generated code: output=da39a3ee5e6b4b0d input=65fab8adff58cf08]*/
+        """).lstrip()  # Note, lstrip() because of the newline
+        self.assertEqual(out, expected)
 
 
 class ClinicGroupPermuterTest(TestCase):
@@ -285,7 +377,7 @@ def test_clinic_1(self):
 """)
 
 
-class ClinicParserTest(TestCase):
+class ClinicParserTest(_ParserBase):
     def checkDocstring(self, fn, expected):
         self.assertTrue(hasattr(fn, "docstring"))
         self.assertEqual(fn.docstring.strip(),



More information about the Python-checkins mailing list