]> granicus.if.org Git - python/commitdiff
Issue #20157: When Argument Clinic renames a parameter because its name
authorLarry Hastings <larry@hastings.org>
Tue, 7 Jan 2014 20:21:08 +0000 (12:21 -0800)
committerLarry Hastings <larry@hastings.org>
Tue, 7 Jan 2014 20:21:08 +0000 (12:21 -0800)
collides with a C keyword, it no longer exposes that rename to PyArg_Parse.

Misc/NEWS
Tools/clinic/clinic.py
Tools/clinic/clinic_test.py

index c46fb10aba4930a46010ea1a43e11879fc30c7b8..4be6cdea3a02074d5bc99fe19a1586d56be1ad8b 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -21,6 +21,9 @@ Library
 Tools/Demos
 -----------
 
+- Issue #20157: When Argument Clinic renames a parameter because its name
+  collides with a C keyword, it no longer exposes that rename to PyArg_Parse.
+
 - Issue #20141: Improved Argument Clinic's support for the PyArg_Parse "O!"
   format unit.
 
index 78600ee85c200dd7f427b0e8053556bb7bf2c604..5378a0b0a067bbe0bbeff8eb616a66202b2bf885 100755 (executable)
@@ -8,7 +8,6 @@
 import abc
 import ast
 import atexit
-import clinic
 import collections
 import contextlib
 import functools
@@ -898,13 +897,21 @@ class BlockParser:
     def parse_clinic_block(self, dsl_name):
         input_add, input_output = text_accumulator()
         self.block_start_line_number = self.line_number + 1
-        stop_line = self.language.stop_line.format(dsl_name=dsl_name) + '\n'
+        stop_line = self.language.stop_line.format(dsl_name=dsl_name)
         body_prefix = self.language.body_prefix.format(dsl_name=dsl_name)
 
+        def is_stop_line(line):
+            # make sure to recognize stop line even if it
+            # doesn't end with EOL (it could be the very end of the file)
+            if not line.startswith(stop_line):
+                return False
+            remainder = line[len(stop_line):]
+            return (not remainder) or remainder.isspace()
+
         # consume body of program
         while self.input:
             line = self._line()
-            if line == stop_line or self.is_start_line(line):
+            if is_stop_line(line) or self.is_start_line(line):
                 break
             if body_prefix:
                 line = line.lstrip()
@@ -1396,7 +1403,8 @@ class CConverter(metaclass=CConverterAutoRegister):
         data is a CRenderData instance.
         """
         self.parameter = parameter
-        name = ensure_legal_c_identifier(self.name)
+        original_name = self.name
+        name = ensure_legal_c_identifier(original_name)
 
         # declarations
         d = self.declaration()
@@ -1414,7 +1422,7 @@ class CConverter(metaclass=CConverterAutoRegister):
             data.impl_arguments.append(self.length_name())
 
         # keywords
-        data.keywords.append(name)
+        data.keywords.append(original_name)
 
         # format_units
         if self.is_optional() and '|' not in data.format_units:
index aeb60a2635d0a937cd6c8e810a3a62263fbb4a05..e6c5c6c6d276b95a4b406a473388db29aef2fc69 100644 (file)
@@ -54,6 +54,25 @@ class FakeClinic:
 
     _module_and_class = clinic.Clinic._module_and_class
 
+class ClinicWholeFileTest(TestCase):
+    def test_eol(self):
+        # regression test:
+        # clinic's block parser didn't recognize
+        # the "end line" for the block if it
+        # didn't end in "\n" (as in, the last)
+        # byte of the file was '/'.
+        # so it woudl 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())
+        raw = "/*[clinic]\nfoo\n[clinic]*/"
+        cooked = c.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]*/")
+
 
 
 class ClinicGroupPermuterTest(TestCase):