diff options
author | Erlend E. Aasland <erlend@python.org> | 2024-02-16 06:42:15 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-16 06:42:15 (GMT) |
commit | 351c103134e43c2ee43deb10cdc9afb37b916a4e (patch) | |
tree | 703799c1471a81bcb36bf400565350485ce794e5 /Tools | |
parent | 20eaf4d5dff7fa20f8a745450fef760f0923eb52 (diff) | |
download | cpython-351c103134e43c2ee43deb10cdc9afb37b916a4e.zip cpython-351c103134e43c2ee43deb10cdc9afb37b916a4e.tar.gz cpython-351c103134e43c2ee43deb10cdc9afb37b916a4e.tar.bz2 |
gh-113317: Argument Clinic: move C/Py identifier helpers into libclinic (#115520)
Diffstat (limited to 'Tools')
-rwxr-xr-x | Tools/clinic/clinic.py | 33 | ||||
-rw-r--r-- | Tools/clinic/libclinic/__init__.py | 10 | ||||
-rw-r--r-- | Tools/clinic/libclinic/identifiers.py | 31 |
3 files changed, 45 insertions, 29 deletions
diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 4925f27..5d2617b 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -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) diff --git a/Tools/clinic/libclinic/__init__.py b/Tools/clinic/libclinic/__init__.py index 6237809..738864a 100644 --- a/Tools/clinic/libclinic/__init__.py +++ b/Tools/clinic/libclinic/__init__.py @@ -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", diff --git a/Tools/clinic/libclinic/identifiers.py b/Tools/clinic/libclinic/identifiers.py new file mode 100644 index 0000000..d3b80bb --- /dev/null +++ b/Tools/clinic/libclinic/identifiers.py @@ -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 |