[Python-checkins] cpython: Issue #20157: When Argument Clinic renames a parameter because its name

larry.hastings python-checkins at python.org
Tue Jan 7 21:21:46 CET 2014


http://hg.python.org/cpython/rev/f61c63ec4e70
changeset:   88343:f61c63ec4e70
user:        Larry Hastings <larry at hastings.org>
date:        Tue Jan 07 12:21:08 2014 -0800
summary:
  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.

files:
  Misc/NEWS                   |   3 +++
  Tools/clinic/clinic.py      |  18 +++++++++++++-----
  Tools/clinic/clinic_test.py |  19 +++++++++++++++++++
  3 files changed, 35 insertions(+), 5 deletions(-)


diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -21,6 +21,9 @@
 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.
 
diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py
--- a/Tools/clinic/clinic.py
+++ b/Tools/clinic/clinic.py
@@ -8,7 +8,6 @@
 import abc
 import ast
 import atexit
-import clinic
 import collections
 import contextlib
 import functools
@@ -898,13 +897,21 @@
     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 @@
         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 @@
             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:
diff --git a/Tools/clinic/clinic_test.py b/Tools/clinic/clinic_test.py
--- a/Tools/clinic/clinic_test.py
+++ b/Tools/clinic/clinic_test.py
@@ -54,6 +54,25 @@
 
     _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):

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list