[clang] [clang-bindings] Add strict typing to clang Python bindings (#76664) (PR #78114)
Jannick Kremer via cfe-commits
cfe-commits at lists.llvm.org
Sun Jan 14 13:34:29 PST 2024
================
@@ -67,89 +67,690 @@
import clang.enumerations
import os
-import sys
-
-if sys.version_info[0] == 3:
- # Python 3 strings are unicode, translate them to/from utf8 for C-interop.
- class c_interop_string(c_char_p):
- def __init__(self, p=None):
- if p is None:
- p = ""
- if isinstance(p, str):
- p = p.encode("utf8")
- super(c_char_p, self).__init__(p)
-
- def __str__(self):
- return self.value
-
- @property
- def value(self):
- if super(c_char_p, self).value is None:
- return None
- return super(c_char_p, self).value.decode("utf8")
-
- @classmethod
- def from_param(cls, param):
- if isinstance(param, str):
- return cls(param)
- if isinstance(param, bytes):
- return cls(param)
- if param is None:
- # Support passing null to C functions expecting char arrays
- return None
- raise TypeError(
- "Cannot convert '{}' to '{}'".format(type(param).__name__, cls.__name__)
- )
+from enum import Enum
+
+from typing import (
+ Any,
+ Callable,
+ cast as Tcast,
+ Generic,
+ Iterable,
+ Iterator,
+ Optional,
+ Sequence,
+ Type as TType,
+ TypeVar,
+ TYPE_CHECKING,
+ Union as TUnion,
+)
+from typing_extensions import Protocol, TypeAlias
+
+if TYPE_CHECKING:
+ from ctypes import _Pointer, _FuncPointer, _CArgObject
+ from io import TextIOWrapper
+
+ StrPath: TypeAlias = TUnion[str, os.PathLike[str]]
+ InMemoryFile: TypeAlias = (
+ "tuple[TUnion[str, os.PathLike[Any]], TUnion[str, TextIOWrapper]]"
+ )
+ LibFunc: TypeAlias = TUnion[
+ "tuple[str, Optional[list[Any]]]",
+ "tuple[str, Optional[list[Any]], Any]",
+ "tuple[str, Optional[list[Any]], Any, Callable[..., Any]]",
+ ]
+ CObjP: TypeAlias = _Pointer[Any]
- @staticmethod
- def to_python_string(x, *args):
- return x.value
+ TSeq = TypeVar("TSeq", covariant=True)
- def b(x):
- if isinstance(x, bytes):
- return x
- return x.encode("utf8")
+ class NoSliceSequence(Protocol[TSeq]):
+ def __len__(self) -> int:
+ ...
-elif sys.version_info[0] == 2:
- # Python 2 strings are utf8 byte strings, no translation is needed for
- # C-interop.
- c_interop_string = c_char_p
+ def __getitem__(self, key: int) -> TSeq:
+ ...
- def _to_python_string(x, *args):
- return x
- c_interop_string.to_python_string = staticmethod(_to_python_string)
+class ClangLib(Protocol):
----------------
DeinAlptraum wrote:
This protocol was the only working way I found to pass the type check with the CDLL, due to the library functions being added dynamically, but it is rather ugly and adds a thousand lines of bloat. If anyone has a better idea, I'm happy to hear it.
https://github.com/llvm/llvm-project/pull/78114
More information about the cfe-commits
mailing list