https://github.com/python/cpython/commit/351c103134e43c2ee43deb10cdc9afb37b916a4e
commit: 351c103134e43c2ee43deb10cdc9afb37b916a4e
branch: main
author: Erlend E. Aasland <[email protected]>
committer: erlend-aasland <[email protected]>
date: 2024-02-16T07:42:15+01:00
summary:

gh-113317: Argument Clinic: move C/Py identifier helpers into libclinic 
(#115520)

files:
A Tools/clinic/libclinic/identifiers.py
M Tools/clinic/clinic.py
M Tools/clinic/libclinic/__init__.py

diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py
index 4925f27b2937b1..5d2617b3bd579f 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 @@ def __init__(self,
              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 @@ def parse_function_names(self, line: str) -> 
FunctionNames:
             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 @@ def state_modulename_name(self, line: str) -> None:
         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 6237809764d9e1..738864a48c08d3 100644
--- a/Tools/clinic/libclinic/__init__.py
+++ b/Tools/clinic/libclinic/__init__.py
@@ -16,6 +16,11 @@
     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 @@
     "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 00000000000000..d3b80bbcef3b2b
--- /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

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to