================
@@ -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):
+    def clang_annotateTokens(
+        self, tu: TranslationUnit, token: _CArgObject, num: int, cursor: 
_CArgObject
+    ) -> None:
+        ...
 
-    def b(x):
-        return x
+    def clang_CompilationDatabase_dispose(self, cdb: CompilationDatabase) -> 
None:
+        ...
+
+    def clang_CompilationDatabase_fromDirectory(
+        self, buildDir: str, errorCode: _CArgObject
+    ) -> CompilationDatabase:
+        ...
+
+    def clang_CompilationDatabase_getAllCompileCommands(
+        self, cdb: CompilationDatabase
+    ) -> CompileCommands:
+        ...
+
+    def clang_CompilationDatabase_getCompileCommands(
+        self, cdb: CompilationDatabase, filename: str
+    ) -> CompileCommands:
+        ...
+
+    def clang_CompileCommands_dispose(self, ccmds: CObjP) -> None:
+        ...
+
+    def clang_CompileCommands_getCommand(self, ccmds: CObjP, key: int) -> 
CObjP:
+        ...
+
+    def clang_CompileCommands_getSize(self, ccmds: CObjP) -> c_uint:
+        ...
+
+    def clang_CompileCommand_getArg(self, cmd: CObjP, key: int) -> str:
+        ...
+
+    def clang_CompileCommand_getDirectory(self, cmd: CObjP) -> str:
+        ...
+
+    def clang_CompileCommand_getFilename(self, cmd: CObjP) -> str:
+        ...
+
+    def clang_CompileCommand_getNumArgs(self, cmd: CObjP) -> int:
----------------
DeinAlptraum wrote:

According to the definitions in `functionList`, all library functions return C 
types for number (`c_int, c_uint, c_longlong, c_ulonglong`). However, checking 
the types of the return values tells me that in all cases where I looked, these 
actually returned Python `int`s. According to the `ctypes` docs, you need 
explicit conversion i.e. calling `c_uint(<int parameter)` or `some_c_int.value` 
for the other way. Neither of these is done anywhere in this file as far as I 
saw, so I'm not sure what types were appropriate where, and how they are 
converted in the first place.
I ended up calling the library functions with `int` and `c_int` parameters 
etc., and calling `type()` on their returns to check the types here, but I'm 
not sure I've covered everything.

https://github.com/llvm/llvm-project/pull/78114
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to