mirror of https://github.com/python/cpython
gh-113317: Argument Clinic: move C/Py identifier helpers into libclinic (#115520)
This commit is contained in:
parent
20eaf4d5df
commit
351c103134
|
@ -138,31 +138,6 @@ def fail(
|
|||
warn_or_fail(*args, filename=filename, line_number=line_number, fail=True)
|
||||
|
||||
|
||||
is_legal_c_identifier = re.compile('^[A-Za-z_][A-Za-z0-9_]*$').match
|
||||
|
||||
def is_legal_py_identifier(s: str) -> bool:
|
||||
return all(is_legal_c_identifier(field) for field in s.split('.'))
|
||||
|
||||
# identifiers that are okay in Python but aren't a good idea in C.
|
||||
# so if they're used Argument Clinic will add "_value" to the end
|
||||
# of the name in C.
|
||||
c_keywords = set("""
|
||||
asm auto break case char const continue default do double
|
||||
else enum extern float for goto if inline int long
|
||||
register return short signed sizeof static struct switch
|
||||
typedef typeof union unsigned void volatile while
|
||||
""".strip().split())
|
||||
|
||||
def ensure_legal_c_identifier(s: str) -> str:
|
||||
# for now, just complain if what we're given isn't legal
|
||||
if not is_legal_c_identifier(s):
|
||||
fail("Illegal C identifier:", s)
|
||||
# but if we picked a C keyword, pick something else
|
||||
if s in c_keywords:
|
||||
return s + "_value"
|
||||
return s
|
||||
|
||||
|
||||
class CRenderData:
|
||||
def __init__(self) -> None:
|
||||
|
||||
|
@ -2954,7 +2929,7 @@ class CConverter(metaclass=CConverterAutoRegister):
|
|||
unused: bool = False,
|
||||
**kwargs: Any
|
||||
) -> None:
|
||||
self.name = ensure_legal_c_identifier(name)
|
||||
self.name = libclinic.ensure_legal_c_identifier(name)
|
||||
self.py_name = py_name
|
||||
self.unused = unused
|
||||
self.includes: list[Include] = []
|
||||
|
@ -5083,9 +5058,9 @@ class DSLParser:
|
|||
if fields[-1] == '__new__':
|
||||
fields.pop()
|
||||
c_basename = "_".join(fields)
|
||||
if not is_legal_py_identifier(full_name):
|
||||
if not libclinic.is_legal_py_identifier(full_name):
|
||||
fail(f"Illegal function name: {full_name!r}")
|
||||
if not is_legal_c_identifier(c_basename):
|
||||
if not libclinic.is_legal_c_identifier(c_basename):
|
||||
fail(f"Illegal C basename: {c_basename!r}")
|
||||
names = FunctionNames(full_name=full_name, c_basename=c_basename)
|
||||
self.normalize_function_kind(names.full_name)
|
||||
|
@ -5207,7 +5182,7 @@ class DSLParser:
|
|||
before, equals, existing = line.rpartition('=')
|
||||
if equals:
|
||||
existing = existing.strip()
|
||||
if is_legal_py_identifier(existing):
|
||||
if libclinic.is_legal_py_identifier(existing):
|
||||
# we're cloning!
|
||||
names = self.parse_function_names(before)
|
||||
return self.parse_cloned_function(names, existing)
|
||||
|
|
|
@ -16,6 +16,11 @@ from .formatting import (
|
|||
wrap_declarations,
|
||||
wrapped_c_string_literal,
|
||||
)
|
||||
from .identifiers import (
|
||||
ensure_legal_c_identifier,
|
||||
is_legal_c_identifier,
|
||||
is_legal_py_identifier,
|
||||
)
|
||||
from .utils import (
|
||||
FormatCounterFormatter,
|
||||
compute_checksum,
|
||||
|
@ -41,6 +46,11 @@ __all__ = [
|
|||
"wrap_declarations",
|
||||
"wrapped_c_string_literal",
|
||||
|
||||
# Identifier helpers
|
||||
"ensure_legal_c_identifier",
|
||||
"is_legal_c_identifier",
|
||||
"is_legal_py_identifier",
|
||||
|
||||
# Utility functions
|
||||
"FormatCounterFormatter",
|
||||
"compute_checksum",
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import re
|
||||
from .errors import ClinicError
|
||||
|
||||
|
||||
is_legal_c_identifier = re.compile("^[A-Za-z_][A-Za-z0-9_]*$").match
|
||||
|
||||
|
||||
def is_legal_py_identifier(identifier: str) -> bool:
|
||||
return all(is_legal_c_identifier(field) for field in identifier.split("."))
|
||||
|
||||
|
||||
# Identifiers that are okay in Python but aren't a good idea in C.
|
||||
# So if they're used Argument Clinic will add "_value" to the end
|
||||
# of the name in C.
|
||||
_c_keywords = frozenset("""
|
||||
asm auto break case char const continue default do double
|
||||
else enum extern float for goto if inline int long
|
||||
register return short signed sizeof static struct switch
|
||||
typedef typeof union unsigned void volatile while
|
||||
""".strip().split()
|
||||
)
|
||||
|
||||
|
||||
def ensure_legal_c_identifier(identifier: str) -> str:
|
||||
# For now, just complain if what we're given isn't legal.
|
||||
if not is_legal_c_identifier(identifier):
|
||||
raise ClinicError(f"Illegal C identifier: {identifier}")
|
||||
# But if we picked a C keyword, pick something else.
|
||||
if identifier in _c_keywords:
|
||||
return identifier + "_value"
|
||||
return identifier
|
Loading…
Reference in New Issue