Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9026113

Browse files
committed
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.
1 parent 77561cc commit 9026113

3 files changed

Lines changed: 35 additions & 5 deletions

File tree

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ Library
2121
Tools/Demos
2222
-----------
2323

24+
- Issue #20157: When Argument Clinic renames a parameter because its name
25+
collides with a C keyword, it no longer exposes that rename to PyArg_Parse.
26+
2427
- Issue #20141: Improved Argument Clinic's support for the PyArg_Parse "O!"
2528
format unit.
2629

Tools/clinic/clinic.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import abc
99
import ast
1010
import atexit
11-
import clinic
1211
import collections
1312
import contextlib
1413
import functools
@@ -898,13 +897,21 @@ def parse_verbatim_block(self):
898897
def parse_clinic_block(self, dsl_name):
899898
input_add, input_output = text_accumulator()
900899
self.block_start_line_number = self.line_number + 1
901-
stop_line = self.language.stop_line.format(dsl_name=dsl_name) + '\n'
900+
stop_line = self.language.stop_line.format(dsl_name=dsl_name)
902901
body_prefix = self.language.body_prefix.format(dsl_name=dsl_name)
903902

903+
def is_stop_line(line):
904+
# make sure to recognize stop line even if it
905+
# doesn't end with EOL (it could be the very end of the file)
906+
if not line.startswith(stop_line):
907+
return False
908+
remainder = line[len(stop_line):]
909+
return (not remainder) or remainder.isspace()
910+
904911
# consume body of program
905912
while self.input:
906913
line = self._line()
907-
if line == stop_line or self.is_start_line(line):
914+
if is_stop_line(line) or self.is_start_line(line):
908915
break
909916
if body_prefix:
910917
line = line.lstrip()
@@ -1396,7 +1403,8 @@ def render(self, parameter, data):
13961403
data is a CRenderData instance.
13971404
"""
13981405
self.parameter = parameter
1399-
name = ensure_legal_c_identifier(self.name)
1406+
original_name = self.name
1407+
name = ensure_legal_c_identifier(original_name)
14001408

14011409
# declarations
14021410
d = self.declaration()
@@ -1414,7 +1422,7 @@ def render(self, parameter, data):
14141422
data.impl_arguments.append(self.length_name())
14151423

14161424
# keywords
1417-
data.keywords.append(name)
1425+
data.keywords.append(original_name)
14181426

14191427
# format_units
14201428
if self.is_optional() and '|' not in data.format_units:

Tools/clinic/clinic_test.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,25 @@ def directive(self, name, args):
5454

5555
_module_and_class = clinic.Clinic._module_and_class
5656

57+
class ClinicWholeFileTest(TestCase):
58+
def test_eol(self):
59+
# regression test:
60+
# clinic's block parser didn't recognize
61+
# the "end line" for the block if it
62+
# didn't end in "\n" (as in, the last)
63+
# byte of the file was '/'.
64+
# so it woudl spit out an end line for you.
65+
# and since you really already had one,
66+
# the last line of the block got corrupted.
67+
c = clinic.Clinic(clinic.CLanguage())
68+
raw = "/*[clinic]\nfoo\n[clinic]*/"
69+
cooked = c.parse(raw).splitlines()
70+
end_line = cooked[2].rstrip()
71+
# this test is redundant, it's just here explicitly to catch
72+
# the regression test so we don't forget what it looked like
73+
self.assertNotEqual(end_line, "[clinic]*/[clinic]*/")
74+
self.assertEqual(end_line, "[clinic]*/")
75+
5776

5877

5978
class ClinicGroupPermuterTest(TestCase):

0 commit comments

Comments
 (0)