1# Stubs for ctypes 2 3from array import array 4from typing import ( 5 Any, Callable, ClassVar, Iterator, Iterable, List, Mapping, Optional, Sequence, Sized, Text, 6 Tuple, Type, Generic, TypeVar, overload, 7) 8from typing import Union as _UnionT 9import sys 10 11_T = TypeVar('_T') 12_DLLT = TypeVar('_DLLT', bound=CDLL) 13_CT = TypeVar('_CT', bound=_CData) 14 15 16RTLD_GLOBAL: int = ... 17RTLD_LOCAL: int = ... 18DEFAULT_MODE: int = ... 19 20 21class CDLL(object): 22 _func_flags_: ClassVar[int] = ... 23 _func_restype_: ClassVar[_CData] = ... 24 _name: str = ... 25 _handle: int = ... 26 _FuncPtr: Type[_FuncPointer] = ... 27 def __init__( 28 self, 29 name: Optional[str], 30 mode: int = ..., 31 handle: Optional[int] = ..., 32 use_errno: bool = ..., 33 use_last_error: bool = ..., 34 winmode: Optional[int] = ..., 35 ) -> None: ... 36 def __getattr__(self, name: str) -> _FuncPointer: ... 37 def __getitem__(self, name: str) -> _FuncPointer: ... 38if sys.platform == 'win32': 39 class OleDLL(CDLL): ... 40 class WinDLL(CDLL): ... 41class PyDLL(CDLL): ... 42 43class LibraryLoader(Generic[_DLLT]): 44 def __init__(self, dlltype: Type[_DLLT]) -> None: ... 45 def __getattr__(self, name: str) -> _DLLT: ... 46 def __getitem__(self, name: str) -> _DLLT: ... 47 def LoadLibrary(self, name: str) -> _DLLT: ... 48 49cdll: LibraryLoader[CDLL] = ... 50if sys.platform == 'win32': 51 windll: LibraryLoader[WinDLL] = ... 52 oledll: LibraryLoader[OleDLL] = ... 53pydll: LibraryLoader[PyDLL] = ... 54pythonapi: PyDLL = ... 55 56# Anything that implements the read-write buffer interface. 57# The buffer interface is defined purely on the C level, so we cannot define a normal Protocol 58# for it. Instead we have to list the most common stdlib buffer classes in a Union. 59_WritableBuffer = _UnionT[bytearray, memoryview, array, _CData] 60# Same as _WritableBuffer, but also includes read-only buffer types (like bytes). 61_ReadOnlyBuffer = _UnionT[_WritableBuffer, bytes] 62 63class _CDataMeta(type): 64 # By default mypy complains about the following two methods, because strictly speaking cls 65 # might not be a Type[_CT]. However this can never actually happen, because the only class that 66 # uses _CDataMeta as its metaclass is _CData. So it's safe to ignore the errors here. 67 def __mul__(cls: Type[_CT], other: int) -> Type[Array[_CT]]: ... # type: ignore 68 def __rmul__(cls: Type[_CT], other: int) -> Type[Array[_CT]]: ... # type: ignore 69class _CData(metaclass=_CDataMeta): 70 _b_base: int = ... 71 _b_needsfree_: bool = ... 72 _objects: Optional[Mapping[Any, int]] = ... 73 @classmethod 74 def from_buffer(cls: Type[_CT], source: _WritableBuffer, offset: int = ...) -> _CT: ... 75 @classmethod 76 def from_buffer_copy(cls: Type[_CT], source: _ReadOnlyBuffer, offset: int = ...) -> _CT: ... 77 @classmethod 78 def from_address(cls: Type[_CT], address: int) -> _CT: ... 79 @classmethod 80 def from_param(cls: Type[_CT], obj: Any) -> _UnionT[_CT, _CArgObject]: ... 81 @classmethod 82 def in_dll(cls: Type[_CT], library: CDLL, name: str) -> _CT: ... 83 84class _PointerLike(_CData): ... 85 86_ECT = Callable[[Optional[Type[_CData]], 87 _FuncPointer, 88 Tuple[_CData, ...]], 89 _CData] 90_PF = _UnionT[ 91 Tuple[int], 92 Tuple[int, str], 93 Tuple[int, str, Any] 94] 95class _FuncPointer(_PointerLike, _CData): 96 restype: _UnionT[Type[_CData], Callable[[int], None], None] = ... 97 argtypes: Sequence[Type[_CData]] = ... 98 errcheck: _ECT = ... 99 @overload 100 def __init__(self, address: int) -> None: ... 101 @overload 102 def __init__(self, callable: Callable[..., Any]) -> None: ... 103 @overload 104 def __init__(self, func_spec: Tuple[_UnionT[str, int], CDLL], 105 paramflags: Tuple[_PF, ...] = ...) -> None: ... 106 @overload 107 def __init__(self, vtlb_index: int, name: str, 108 paramflags: Tuple[_PF, ...] = ..., 109 iid: pointer[c_int] = ...) -> None: ... 110 def __call__(self, *args: Any, **kwargs: Any) -> Any: ... 111 112class ArgumentError(Exception): ... 113 114 115def CFUNCTYPE(restype: Optional[Type[_CData]], 116 *argtypes: Type[_CData], 117 use_errno: bool = ..., 118 use_last_error: bool = ...) -> Type[_FuncPointer]: ... 119if sys.platform == 'win32': 120 def WINFUNCTYPE(restype: Optional[Type[_CData]], 121 *argtypes: Type[_CData], 122 use_errno: bool = ..., 123 use_last_error: bool = ...) -> Type[_FuncPointer]: ... 124def PYFUNCTYPE(restype: Optional[Type[_CData]], 125 *argtypes: Type[_CData]) -> Type[_FuncPointer]: ... 126 127class _CArgObject: ... 128 129# Any type that can be implicitly converted to c_void_p when passed as a C function argument. 130# (bytes is not included here, see below.) 131_CVoidPLike = _UnionT[_PointerLike, Array[Any], _CArgObject, int] 132# Same as above, but including types known to be read-only (i. e. bytes). 133# This distinction is not strictly necessary (ctypes doesn't differentiate between const 134# and non-const pointers), but it catches errors like memmove(b'foo', buf, 4) 135# when memmove(buf, b'foo', 4) was intended. 136_CVoidConstPLike = _UnionT[_CVoidPLike, bytes] 137 138def addressof(obj: _CData) -> int: ... 139def alignment(obj_or_type: _UnionT[_CData, Type[_CData]]) -> int: ... 140def byref(obj: _CData, offset: int = ...) -> _CArgObject: ... 141_PT = TypeVar('_PT', bound=_PointerLike) 142def cast(obj: _UnionT[_CData, _CArgObject], type: Type[_PT]) -> _PT: ... 143def create_string_buffer(init_or_size: _UnionT[int, bytes], 144 size: Optional[int] = ...) -> Array[c_char]: ... 145c_buffer = create_string_buffer 146def create_unicode_buffer(init_or_size: _UnionT[int, Text], 147 size: Optional[int] = ...) -> Array[c_wchar]: ... 148if sys.platform == 'win32': 149 def DllCanUnloadNow() -> int: ... 150 def DllGetClassObject(rclsid: Any, riid: Any, ppv: Any) -> int: ... # TODO not documented 151 def FormatError(code: int) -> str: ... 152 def GetLastError() -> int: ... 153def get_errno() -> int: ... 154if sys.platform == 'win32': 155 def get_last_error() -> int: ... 156def memmove(dst: _CVoidPLike, src: _CVoidConstPLike, count: int) -> None: ... 157def memset(dst: _CVoidPLike, c: int, count: int) -> None: ... 158def POINTER(type: Type[_CT]) -> Type[pointer[_CT]]: ... 159 160# The real ctypes.pointer is a function, not a class. The stub version of pointer behaves like 161# ctypes._Pointer in that it is the base class for all pointer types. Unlike the real _Pointer, 162# it can be instantiated directly (to mimic the behavior of the real pointer function). 163class pointer(Generic[_CT], _PointerLike, _CData): 164 _type_: ClassVar[Type[_CT]] = ... 165 contents: _CT = ... 166 def __init__(self, arg: _CT = ...) -> None: ... 167 @overload 168 def __getitem__(self, i: int) -> _CT: ... 169 @overload 170 def __getitem__(self, s: slice) -> List[_CT]: ... 171 @overload 172 def __setitem__(self, i: int, o: _CT) -> None: ... 173 @overload 174 def __setitem__(self, s: slice, o: Iterable[_CT]) -> None: ... 175 176def resize(obj: _CData, size: int) -> None: ... 177if sys.version_info < (3,): 178 def set_conversion_mode(encoding: str, errors: str) -> Tuple[str, str]: ... 179def set_errno(value: int) -> int: ... 180if sys.platform == 'win32': 181 def set_last_error(value: int) -> int: ... 182def sizeof(obj_or_type: _UnionT[_CData, Type[_CData]]) -> int: ... 183def string_at(address: _CVoidConstPLike, size: int = ...) -> bytes: ... 184if sys.platform == 'win32': 185 def WinError(code: Optional[int] = ..., 186 descr: Optional[str] = ...) -> OSError: ... 187def wstring_at(address: _CVoidConstPLike, size: int = ...) -> str: ... 188 189class _SimpleCData(Generic[_T], _CData): 190 value: _T = ... 191 def __init__(self, value: _T = ...) -> None: ... 192 193class c_byte(_SimpleCData[int]): ... 194 195class c_char(_SimpleCData[bytes]): 196 def __init__(self, value: _UnionT[int, bytes] = ...) -> None: ... 197class c_char_p(_PointerLike, _SimpleCData[Optional[bytes]]): 198 def __init__(self, value: Optional[_UnionT[int, bytes]] = ...) -> None: ... 199 200class c_double(_SimpleCData[float]): ... 201class c_longdouble(_SimpleCData[float]): ... 202class c_float(_SimpleCData[float]): ... 203 204class c_int(_SimpleCData[int]): ... 205class c_int8(_SimpleCData[int]): ... 206class c_int16(_SimpleCData[int]): ... 207class c_int32(_SimpleCData[int]): ... 208class c_int64(_SimpleCData[int]): ... 209 210class c_long(_SimpleCData[int]): ... 211class c_longlong(_SimpleCData[int]): ... 212 213class c_short(_SimpleCData[int]): ... 214 215class c_size_t(_SimpleCData[int]): ... 216class c_ssize_t(_SimpleCData[int]): ... 217 218class c_ubyte(_SimpleCData[int]): ... 219 220class c_uint(_SimpleCData[int]): ... 221class c_uint8(_SimpleCData[int]): ... 222class c_uint16(_SimpleCData[int]): ... 223class c_uint32(_SimpleCData[int]): ... 224class c_uint64(_SimpleCData[int]): ... 225 226class c_ulong(_SimpleCData[int]): ... 227class c_ulonglong(_SimpleCData[int]): ... 228 229class c_ushort(_SimpleCData[int]): ... 230 231class c_void_p(_PointerLike, _SimpleCData[Optional[int]]): ... 232 233class c_wchar(_SimpleCData[Text]): ... 234class c_wchar_p(_PointerLike, _SimpleCData[Optional[Text]]): 235 def __init__(self, value: Optional[_UnionT[int, Text]] = ...) -> None: ... 236 237class c_bool(_SimpleCData[bool]): 238 def __init__(self, value: bool = ...) -> None: ... 239 240if sys.platform == 'win32': 241 class HRESULT(_SimpleCData[int]): ... # TODO undocumented 242 243class py_object(_SimpleCData[_T]): ... 244 245class _CField: 246 offset: int = ... 247 size: int = ... 248class _StructUnionMeta(_CDataMeta): 249 _fields_: Sequence[_UnionT[Tuple[str, Type[_CData]], Tuple[str, Type[_CData], int]]] = ... 250 _pack_: int = ... 251 _anonymous_: Sequence[str] = ... 252 def __getattr__(self, name: str) -> _CField: ... 253class _StructUnionBase(_CData, metaclass=_StructUnionMeta): 254 def __init__(self, *args: Any, **kw: Any) -> None: ... 255 def __getattr__(self, name: str) -> Any: ... 256 def __setattr__(self, name: str, value: Any) -> None: ... 257 258class Union(_StructUnionBase): ... 259class Structure(_StructUnionBase): ... 260class BigEndianStructure(Structure): ... 261class LittleEndianStructure(Structure): ... 262 263class Array(Generic[_CT], _CData): 264 _length_: ClassVar[int] = ... 265 _type_: ClassVar[Type[_CT]] = ... 266 raw: bytes = ... # Note: only available if _CT == c_char 267 value: Any = ... # Note: bytes if _CT == c_char, Text if _CT == c_wchar, unavailable otherwise 268 # TODO These methods cannot be annotated correctly at the moment. 269 # All of these "Any"s stand for the array's element type, but it's not possible to use _CT 270 # here, because of a special feature of ctypes. 271 # By default, when accessing an element of an Array[_CT], the returned object has type _CT. 272 # However, when _CT is a "simple type" like c_int, ctypes automatically "unboxes" the object 273 # and converts it to the corresponding Python primitive. For example, when accessing an element 274 # of an Array[c_int], a Python int object is returned, not a c_int. 275 # This behavior does *not* apply to subclasses of "simple types". 276 # If MyInt is a subclass of c_int, then accessing an element of an Array[MyInt] returns 277 # a MyInt, not an int. 278 # This special behavior is not easy to model in a stub, so for now all places where 279 # the array element type would belong are annotated with Any instead. 280 def __init__(self, *args: Any) -> None: ... 281 @overload 282 def __getitem__(self, i: int) -> Any: ... 283 @overload 284 def __getitem__(self, s: slice) -> List[Any]: ... 285 @overload 286 def __setitem__(self, i: int, o: Any) -> None: ... 287 @overload 288 def __setitem__(self, s: slice, o: Iterable[Any]) -> None: ... 289 def __iter__(self) -> Iterator[Any]: ... 290 # Can't inherit from Sized because the metaclass conflict between 291 # Sized and _CData prevents using _CDataMeta. 292 def __len__(self) -> int: ... 293