diff options
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rwxr-xr-x | Tools/clinic/clinic.py | 18 | ||||
-rw-r--r-- | Tools/clinic/clinic_test.py | 19 |
3 files changed, 35 insertions, 5 deletions
@@ -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. diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 78600ee..5378a0b 100755 --- 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 @@ 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: diff --git a/Tools/clinic/clinic_test.py b/Tools/clinic/clinic_test.py index aeb60a2..e6c5c6c 100644 --- a/Tools/clinic/clinic_test.py +++ b/Tools/clinic/clinic_test.py @@ -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): |