Skip to content

Commit 14897ed

Browse files
erlend-aaslanddiegorusso
authored andcommitted
pythongh-113317: Argument Clinic: move C/Py identifier helpers into libclinic (python#115520)
1 parent cbb3cbf commit 14897ed

File tree

3 files changed

+45
-29
lines changed

3 files changed

+45
-29
lines changed

Tools/clinic/clinic.py

+4-29
Original file line numberDiff line numberDiff line change
@@ -138,31 +138,6 @@ def fail(
138138
warn_or_fail(*args, filename=filename, line_number=line_number, fail=True)
139139

140140

141-
is_legal_c_identifier = re.compile('^[A-Za-z_][A-Za-z0-9_]*$').match
142-
143-
def is_legal_py_identifier(s: str) -> bool:
144-
return all(is_legal_c_identifier(field) for field in s.split('.'))
145-
146-
# identifiers that are okay in Python but aren't a good idea in C.
147-
# so if they're used Argument Clinic will add "_value" to the end
148-
# of the name in C.
149-
c_keywords = set("""
150-
asm auto break case char const continue default do double
151-
else enum extern float for goto if inline int long
152-
register return short signed sizeof static struct switch
153-
typedef typeof union unsigned void volatile while
154-
""".strip().split())
155-
156-
def ensure_legal_c_identifier(s: str) -> str:
157-
# for now, just complain if what we're given isn't legal
158-
if not is_legal_c_identifier(s):
159-
fail("Illegal C identifier:", s)
160-
# but if we picked a C keyword, pick something else
161-
if s in c_keywords:
162-
return s + "_value"
163-
return s
164-
165-
166141
class CRenderData:
167142
def __init__(self) -> None:
168143

@@ -2954,7 +2929,7 @@ def __init__(self,
29542929
unused: bool = False,
29552930
**kwargs: Any
29562931
) -> None:
2957-
self.name = ensure_legal_c_identifier(name)
2932+
self.name = libclinic.ensure_legal_c_identifier(name)
29582933
self.py_name = py_name
29592934
self.unused = unused
29602935
self.includes: list[Include] = []
@@ -5083,9 +5058,9 @@ def parse_function_names(self, line: str) -> FunctionNames:
50835058
if fields[-1] == '__new__':
50845059
fields.pop()
50855060
c_basename = "_".join(fields)
5086-
if not is_legal_py_identifier(full_name):
5061+
if not libclinic.is_legal_py_identifier(full_name):
50875062
fail(f"Illegal function name: {full_name!r}")
5088-
if not is_legal_c_identifier(c_basename):
5063+
if not libclinic.is_legal_c_identifier(c_basename):
50895064
fail(f"Illegal C basename: {c_basename!r}")
50905065
names = FunctionNames(full_name=full_name, c_basename=c_basename)
50915066
self.normalize_function_kind(names.full_name)
@@ -5207,7 +5182,7 @@ def state_modulename_name(self, line: str) -> None:
52075182
before, equals, existing = line.rpartition('=')
52085183
if equals:
52095184
existing = existing.strip()
5210-
if is_legal_py_identifier(existing):
5185+
if libclinic.is_legal_py_identifier(existing):
52115186
# we're cloning!
52125187
names = self.parse_function_names(before)
52135188
return self.parse_cloned_function(names, existing)

Tools/clinic/libclinic/__init__.py

+10
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616
wrap_declarations,
1717
wrapped_c_string_literal,
1818
)
19+
from .identifiers import (
20+
ensure_legal_c_identifier,
21+
is_legal_c_identifier,
22+
is_legal_py_identifier,
23+
)
1924
from .utils import (
2025
FormatCounterFormatter,
2126
compute_checksum,
@@ -41,6 +46,11 @@
4146
"wrap_declarations",
4247
"wrapped_c_string_literal",
4348

49+
# Identifier helpers
50+
"ensure_legal_c_identifier",
51+
"is_legal_c_identifier",
52+
"is_legal_py_identifier",
53+
4454
# Utility functions
4555
"FormatCounterFormatter",
4656
"compute_checksum",

Tools/clinic/libclinic/identifiers.py

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import re
2+
from .errors import ClinicError
3+
4+
5+
is_legal_c_identifier = re.compile("^[A-Za-z_][A-Za-z0-9_]*$").match
6+
7+
8+
def is_legal_py_identifier(identifier: str) -> bool:
9+
return all(is_legal_c_identifier(field) for field in identifier.split("."))
10+
11+
12+
# Identifiers that are okay in Python but aren't a good idea in C.
13+
# So if they're used Argument Clinic will add "_value" to the end
14+
# of the name in C.
15+
_c_keywords = frozenset("""
16+
asm auto break case char const continue default do double
17+
else enum extern float for goto if inline int long
18+
register return short signed sizeof static struct switch
19+
typedef typeof union unsigned void volatile while
20+
""".strip().split()
21+
)
22+
23+
24+
def ensure_legal_c_identifier(identifier: str) -> str:
25+
# For now, just complain if what we're given isn't legal.
26+
if not is_legal_c_identifier(identifier):
27+
raise ClinicError(f"Illegal C identifier: {identifier}")
28+
# But if we picked a C keyword, pick something else.
29+
if identifier in _c_keywords:
30+
return identifier + "_value"
31+
return identifier

0 commit comments

Comments
 (0)