Skip to content

Commit 42429d3

Browse files
gh-104683: Argument Clinic: Extract parse function name helper (#107964)
Co-authored-by: Alex Waygood <[email protected]>
1 parent b61f599 commit 42429d3

File tree

2 files changed

+30
-33
lines changed

2 files changed

+30
-33
lines changed

Lib/test/test_clinic.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,7 @@ class C "void *" ""
682682
foo2 as .illegal. = foo1
683683
[clinic start generated code]*/
684684
"""
685-
err = "Illegal C basename: '.illegal. = foo1'"
685+
err = "Illegal C basename: '.illegal.'"
686686
self.expect_failure(block, err, lineno=7)
687687

688688

Tools/clinic/clinic.py

+29-32
Original file line numberDiff line numberDiff line change
@@ -1674,18 +1674,8 @@ def render_function(
16741674
full_name = f.full_name
16751675
template_dict = {'full_name': full_name}
16761676
template_dict['name'] = f.displayname
1677-
1678-
if f.c_basename:
1679-
c_basename = f.c_basename
1680-
else:
1681-
fields = full_name.split(".")
1682-
if fields[-1] == '__new__':
1683-
fields.pop()
1684-
c_basename = "_".join(fields)
1685-
1686-
template_dict['c_basename'] = c_basename
1687-
1688-
template_dict['methoddef_name'] = c_basename.upper() + "_METHODDEF"
1677+
template_dict['c_basename'] = f.c_basename
1678+
template_dict['methoddef_name'] = f.c_basename.upper() + "_METHODDEF"
16891679

16901680
template_dict['docstring'] = self.docstring_for_c_string(f)
16911681

@@ -2653,7 +2643,7 @@ class Function:
26532643
name: str
26542644
module: Module | Clinic
26552645
cls: Class | None
2656-
c_basename: str | None
2646+
c_basename: str
26572647
full_name: str
26582648
return_converter: CReturnConverter
26592649
kind: FunctionKind
@@ -4577,6 +4567,11 @@ class ParamState(enum.IntEnum):
45774567
RIGHT_SQUARE_AFTER = 6
45784568

45794569

4570+
class FunctionNames(NamedTuple):
4571+
full_name: str
4572+
c_basename: str
4573+
4574+
45804575
class DSLParser:
45814576
function: Function | None
45824577
state: StateKeeper
@@ -4840,6 +4835,24 @@ def state_dsl_start(self, line: str) -> None:
48404835

48414836
self.next(self.state_modulename_name, line)
48424837

4838+
@staticmethod
4839+
def parse_function_names(line: str) -> FunctionNames:
4840+
left, as_, right = line.partition(' as ')
4841+
full_name = left.strip()
4842+
c_basename = right.strip()
4843+
if as_ and not c_basename:
4844+
fail("No C basename provided after 'as' keyword")
4845+
if not c_basename:
4846+
fields = full_name.split(".")
4847+
if fields[-1] == '__new__':
4848+
fields.pop()
4849+
c_basename = "_".join(fields)
4850+
if not is_legal_py_identifier(full_name):
4851+
fail(f"Illegal function name: {full_name!r}")
4852+
if not is_legal_c_identifier(c_basename):
4853+
fail(f"Illegal C basename: {c_basename!r}")
4854+
return FunctionNames(full_name=full_name, c_basename=c_basename)
4855+
48434856
def update_function_kind(self, fullname: str) -> None:
48444857
fields = fullname.split('.')
48454858
name = fields.pop()
@@ -4877,17 +4890,10 @@ def state_modulename_name(self, line: str) -> None:
48774890

48784891
# are we cloning?
48794892
before, equals, existing = line.rpartition('=')
4880-
c_basename: str | None
48814893
if equals:
4882-
full_name, as_, c_basename = before.partition(' as ')
4883-
full_name = full_name.strip()
4884-
c_basename = c_basename.strip()
4885-
if as_ and not c_basename:
4886-
fail("No C basename provided after 'as' keyword")
4894+
full_name, c_basename = self.parse_function_names(before)
48874895
existing = existing.strip()
4888-
if (is_legal_py_identifier(full_name) and
4889-
(not c_basename or is_legal_c_identifier(c_basename)) and
4890-
is_legal_py_identifier(existing)):
4896+
if is_legal_py_identifier(existing):
48914897
# we're cloning!
48924898
fields = [x.strip() for x in existing.split('.')]
48934899
function_name = fields.pop()
@@ -4933,16 +4939,7 @@ def state_modulename_name(self, line: str) -> None:
49334939

49344940
line, _, returns = line.partition('->')
49354941
returns = returns.strip()
4936-
4937-
full_name, as_, c_basename = line.partition(' as ')
4938-
full_name = full_name.strip()
4939-
c_basename = c_basename.strip() or None
4940-
if as_ and not c_basename:
4941-
fail("No C basename provided after 'as' keyword")
4942-
if not is_legal_py_identifier(full_name):
4943-
fail(f"Illegal function name: {full_name!r}")
4944-
if c_basename and not is_legal_c_identifier(c_basename):
4945-
fail(f"Illegal C basename: {c_basename!r}")
4942+
full_name, c_basename = self.parse_function_names(line)
49464943

49474944
return_converter = None
49484945
if returns:

0 commit comments

Comments
 (0)