Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/ctypes/__init__.py: 5%
345 statements
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-25 06:11 +0000
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-25 06:11 +0000
1"""create and manipulate C data types in Python"""
3import os as _os, sys as _sys
5__version__ = "1.1.0"
7from _ctypes import Union, Structure, Array
8from _ctypes import _Pointer
9from _ctypes import CFuncPtr as _CFuncPtr
10from _ctypes import __version__ as _ctypes_version
11from _ctypes import RTLD_LOCAL, RTLD_GLOBAL
12from _ctypes import ArgumentError
14from struct import calcsize as _calcsize
16if __version__ != _ctypes_version:
17 raise Exception("Version number mismatch", __version__, _ctypes_version)
19if _os.name == "nt":
20 from _ctypes import FormatError
22DEFAULT_MODE = RTLD_LOCAL
23if _os.name == "posix" and _sys.platform == "darwin":
24 # On OS X 10.3, we use RTLD_GLOBAL as default mode
25 # because RTLD_LOCAL does not work at least on some
26 # libraries. OS X 10.3 is Darwin 7, so we check for
27 # that.
29 if int(_os.uname().release.split('.')[0]) < 8:
30 DEFAULT_MODE = RTLD_GLOBAL
32from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \
33 FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI, \
34 FUNCFLAG_USE_ERRNO as _FUNCFLAG_USE_ERRNO, \
35 FUNCFLAG_USE_LASTERROR as _FUNCFLAG_USE_LASTERROR
37# WINOLEAPI -> HRESULT
38# WINOLEAPI_(type)
39#
40# STDMETHODCALLTYPE
41#
42# STDMETHOD(name)
43# STDMETHOD_(type, name)
44#
45# STDAPICALLTYPE
47def create_string_buffer(init, size=None):
48 """create_string_buffer(aBytes) -> character array
49 create_string_buffer(anInteger) -> character array
50 create_string_buffer(aBytes, anInteger) -> character array
51 """
52 if isinstance(init, bytes):
53 if size is None:
54 size = len(init)+1
55 _sys.audit("ctypes.create_string_buffer", init, size)
56 buftype = c_char * size
57 buf = buftype()
58 buf.value = init
59 return buf
60 elif isinstance(init, int):
61 _sys.audit("ctypes.create_string_buffer", None, init)
62 buftype = c_char * init
63 buf = buftype()
64 return buf
65 raise TypeError(init)
67def c_buffer(init, size=None):
68## "deprecated, use create_string_buffer instead"
69## import warnings
70## warnings.warn("c_buffer is deprecated, use create_string_buffer instead",
71## DeprecationWarning, stacklevel=2)
72 return create_string_buffer(init, size)
74_c_functype_cache = {}
75def CFUNCTYPE(restype, *argtypes, **kw):
76 """CFUNCTYPE(restype, *argtypes,
77 use_errno=False, use_last_error=False) -> function prototype.
79 restype: the result type
80 argtypes: a sequence specifying the argument types
82 The function prototype can be called in different ways to create a
83 callable object:
85 prototype(integer address) -> foreign function
86 prototype(callable) -> create and return a C callable function from callable
87 prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method
88 prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal
89 prototype((function name, dll object)[, paramflags]) -> foreign function exported by name
90 """
91 flags = _FUNCFLAG_CDECL
92 if kw.pop("use_errno", False):
93 flags |= _FUNCFLAG_USE_ERRNO
94 if kw.pop("use_last_error", False):
95 flags |= _FUNCFLAG_USE_LASTERROR
96 if kw:
97 raise ValueError("unexpected keyword argument(s) %s" % kw.keys())
98 try:
99 return _c_functype_cache[(restype, argtypes, flags)]
100 except KeyError:
101 class CFunctionType(_CFuncPtr):
102 _argtypes_ = argtypes
103 _restype_ = restype
104 _flags_ = flags
105 _c_functype_cache[(restype, argtypes, flags)] = CFunctionType
106 return CFunctionType
108if _os.name == "nt":
109 from _ctypes import LoadLibrary as _dlopen
110 from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL
112 _win_functype_cache = {}
113 def WINFUNCTYPE(restype, *argtypes, **kw):
114 # docstring set later (very similar to CFUNCTYPE.__doc__)
115 flags = _FUNCFLAG_STDCALL
116 if kw.pop("use_errno", False):
117 flags |= _FUNCFLAG_USE_ERRNO
118 if kw.pop("use_last_error", False):
119 flags |= _FUNCFLAG_USE_LASTERROR
120 if kw:
121 raise ValueError("unexpected keyword argument(s) %s" % kw.keys())
122 try:
123 return _win_functype_cache[(restype, argtypes, flags)]
124 except KeyError:
125 class WinFunctionType(_CFuncPtr):
126 _argtypes_ = argtypes
127 _restype_ = restype
128 _flags_ = flags
129 _win_functype_cache[(restype, argtypes, flags)] = WinFunctionType
130 return WinFunctionType
131 if WINFUNCTYPE.__doc__:
132 WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE")
134elif _os.name == "posix":
135 from _ctypes import dlopen as _dlopen
137from _ctypes import sizeof, byref, addressof, alignment, resize
138from _ctypes import get_errno, set_errno
139from _ctypes import _SimpleCData
141def _check_size(typ, typecode=None):
142 # Check if sizeof(ctypes_type) against struct.calcsize. This
143 # should protect somewhat against a misconfigured libffi.
144 from struct import calcsize
145 if typecode is None:
146 # Most _type_ codes are the same as used in struct
147 typecode = typ._type_
148 actual, required = sizeof(typ), calcsize(typecode)
149 if actual != required:
150 raise SystemError("sizeof(%s) wrong: %d instead of %d" % \
151 (typ, actual, required))
153class py_object(_SimpleCData):
154 _type_ = "O"
155 def __repr__(self):
156 try:
157 return super().__repr__()
158 except ValueError:
159 return "%s(<NULL>)" % type(self).__name__
160_check_size(py_object, "P")
162class c_short(_SimpleCData):
163 _type_ = "h"
164_check_size(c_short)
166class c_ushort(_SimpleCData):
167 _type_ = "H"
168_check_size(c_ushort)
170class c_long(_SimpleCData):
171 _type_ = "l"
172_check_size(c_long)
174class c_ulong(_SimpleCData):
175 _type_ = "L"
176_check_size(c_ulong)
178if _calcsize("i") == _calcsize("l"):
179 # if int and long have the same size, make c_int an alias for c_long
180 c_int = c_long
181 c_uint = c_ulong
182else:
183 class c_int(_SimpleCData):
184 _type_ = "i"
185 _check_size(c_int)
187 class c_uint(_SimpleCData):
188 _type_ = "I"
189 _check_size(c_uint)
191class c_float(_SimpleCData):
192 _type_ = "f"
193_check_size(c_float)
195class c_double(_SimpleCData):
196 _type_ = "d"
197_check_size(c_double)
199class c_longdouble(_SimpleCData):
200 _type_ = "g"
201if sizeof(c_longdouble) == sizeof(c_double):
202 c_longdouble = c_double
204if _calcsize("l") == _calcsize("q"):
205 # if long and long long have the same size, make c_longlong an alias for c_long
206 c_longlong = c_long
207 c_ulonglong = c_ulong
208else:
209 class c_longlong(_SimpleCData):
210 _type_ = "q"
211 _check_size(c_longlong)
213 class c_ulonglong(_SimpleCData):
214 _type_ = "Q"
215 ## def from_param(cls, val):
216 ## return ('d', float(val), val)
217 ## from_param = classmethod(from_param)
218 _check_size(c_ulonglong)
220class c_ubyte(_SimpleCData):
221 _type_ = "B"
222c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte
223# backward compatibility:
224##c_uchar = c_ubyte
225_check_size(c_ubyte)
227class c_byte(_SimpleCData):
228 _type_ = "b"
229c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte
230_check_size(c_byte)
232class c_char(_SimpleCData):
233 _type_ = "c"
234c_char.__ctype_le__ = c_char.__ctype_be__ = c_char
235_check_size(c_char)
237class c_char_p(_SimpleCData):
238 _type_ = "z"
239 def __repr__(self):
240 return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value)
241_check_size(c_char_p, "P")
243class c_void_p(_SimpleCData):
244 _type_ = "P"
245c_voidp = c_void_p # backwards compatibility (to a bug)
246_check_size(c_void_p)
248class c_bool(_SimpleCData):
249 _type_ = "?"
251from _ctypes import POINTER, pointer, _pointer_type_cache
253class c_wchar_p(_SimpleCData):
254 _type_ = "Z"
255 def __repr__(self):
256 return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value)
258class c_wchar(_SimpleCData):
259 _type_ = "u"
261def _reset_cache():
262 _pointer_type_cache.clear()
263 _c_functype_cache.clear()
264 if _os.name == "nt":
265 _win_functype_cache.clear()
266 # _SimpleCData.c_wchar_p_from_param
267 POINTER(c_wchar).from_param = c_wchar_p.from_param
268 # _SimpleCData.c_char_p_from_param
269 POINTER(c_char).from_param = c_char_p.from_param
270 _pointer_type_cache[None] = c_void_p
272def create_unicode_buffer(init, size=None):
273 """create_unicode_buffer(aString) -> character array
274 create_unicode_buffer(anInteger) -> character array
275 create_unicode_buffer(aString, anInteger) -> character array
276 """
277 if isinstance(init, str):
278 if size is None:
279 if sizeof(c_wchar) == 2:
280 # UTF-16 requires a surrogate pair (2 wchar_t) for non-BMP
281 # characters (outside [U+0000; U+FFFF] range). +1 for trailing
282 # NUL character.
283 size = sum(2 if ord(c) > 0xFFFF else 1 for c in init) + 1
284 else:
285 # 32-bit wchar_t (1 wchar_t per Unicode character). +1 for
286 # trailing NUL character.
287 size = len(init) + 1
288 _sys.audit("ctypes.create_unicode_buffer", init, size)
289 buftype = c_wchar * size
290 buf = buftype()
291 buf.value = init
292 return buf
293 elif isinstance(init, int):
294 _sys.audit("ctypes.create_unicode_buffer", None, init)
295 buftype = c_wchar * init
296 buf = buftype()
297 return buf
298 raise TypeError(init)
301# XXX Deprecated
302def SetPointerType(pointer, cls):
303 if _pointer_type_cache.get(cls, None) is not None:
304 raise RuntimeError("This type already exists in the cache")
305 if id(pointer) not in _pointer_type_cache:
306 raise RuntimeError("What's this???")
307 pointer.set_type(cls)
308 _pointer_type_cache[cls] = pointer
309 del _pointer_type_cache[id(pointer)]
311# XXX Deprecated
312def ARRAY(typ, len):
313 return typ * len
315################################################################
318class CDLL(object):
319 """An instance of this class represents a loaded dll/shared
320 library, exporting functions using the standard C calling
321 convention (named 'cdecl' on Windows).
323 The exported functions can be accessed as attributes, or by
324 indexing with the function name. Examples:
326 <obj>.qsort -> callable object
327 <obj>['qsort'] -> callable object
329 Calling the functions releases the Python GIL during the call and
330 reacquires it afterwards.
331 """
332 _func_flags_ = _FUNCFLAG_CDECL
333 _func_restype_ = c_int
334 # default values for repr
335 _name = '<uninitialized>'
336 _handle = 0
337 _FuncPtr = None
339 def __init__(self, name, mode=DEFAULT_MODE, handle=None,
340 use_errno=False,
341 use_last_error=False,
342 winmode=None):
343 self._name = name
344 flags = self._func_flags_
345 if use_errno:
346 flags |= _FUNCFLAG_USE_ERRNO
347 if use_last_error:
348 flags |= _FUNCFLAG_USE_LASTERROR
349 if _sys.platform.startswith("aix"):
350 """When the name contains ".a(" and ends with ")",
351 e.g., "libFOO.a(libFOO.so)" - this is taken to be an
352 archive(member) syntax for dlopen(), and the mode is adjusted.
353 Otherwise, name is presented to dlopen() as a file argument.
354 """
355 if name and name.endswith(")") and ".a(" in name:
356 mode |= ( _os.RTLD_MEMBER | _os.RTLD_NOW )
357 if _os.name == "nt":
358 if winmode is not None:
359 mode = winmode
360 else:
361 import nt
362 mode = nt._LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
363 if '/' in name or '\\' in name:
364 self._name = nt._getfullpathname(self._name)
365 mode |= nt._LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
367 class _FuncPtr(_CFuncPtr):
368 _flags_ = flags
369 _restype_ = self._func_restype_
370 self._FuncPtr = _FuncPtr
372 if handle is None:
373 self._handle = _dlopen(self._name, mode)
374 else:
375 self._handle = handle
377 def __repr__(self):
378 return "<%s '%s', handle %x at %#x>" % \
379 (self.__class__.__name__, self._name,
380 (self._handle & (_sys.maxsize*2 + 1)),
381 id(self) & (_sys.maxsize*2 + 1))
383 def __getattr__(self, name):
384 if name.startswith('__') and name.endswith('__'):
385 raise AttributeError(name)
386 func = self.__getitem__(name)
387 setattr(self, name, func)
388 return func
390 def __getitem__(self, name_or_ordinal):
391 func = self._FuncPtr((name_or_ordinal, self))
392 if not isinstance(name_or_ordinal, int):
393 func.__name__ = name_or_ordinal
394 return func
396class PyDLL(CDLL):
397 """This class represents the Python library itself. It allows
398 accessing Python API functions. The GIL is not released, and
399 Python exceptions are handled correctly.
400 """
401 _func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
403if _os.name == "nt":
405 class WinDLL(CDLL):
406 """This class represents a dll exporting functions using the
407 Windows stdcall calling convention.
408 """
409 _func_flags_ = _FUNCFLAG_STDCALL
411 # XXX Hm, what about HRESULT as normal parameter?
412 # Mustn't it derive from c_long then?
413 from _ctypes import _check_HRESULT, _SimpleCData
414 class HRESULT(_SimpleCData):
415 _type_ = "l"
416 # _check_retval_ is called with the function's result when it
417 # is used as restype. It checks for the FAILED bit, and
418 # raises an OSError if it is set.
419 #
420 # The _check_retval_ method is implemented in C, so that the
421 # method definition itself is not included in the traceback
422 # when it raises an error - that is what we want (and Python
423 # doesn't have a way to raise an exception in the caller's
424 # frame).
425 _check_retval_ = _check_HRESULT
427 class OleDLL(CDLL):
428 """This class represents a dll exporting functions using the
429 Windows stdcall calling convention, and returning HRESULT.
430 HRESULT error values are automatically raised as OSError
431 exceptions.
432 """
433 _func_flags_ = _FUNCFLAG_STDCALL
434 _func_restype_ = HRESULT
436class LibraryLoader(object):
437 def __init__(self, dlltype):
438 self._dlltype = dlltype
440 def __getattr__(self, name):
441 if name[0] == '_':
442 raise AttributeError(name)
443 dll = self._dlltype(name)
444 setattr(self, name, dll)
445 return dll
447 def __getitem__(self, name):
448 return getattr(self, name)
450 def LoadLibrary(self, name):
451 return self._dlltype(name)
453cdll = LibraryLoader(CDLL)
454pydll = LibraryLoader(PyDLL)
456if _os.name == "nt":
457 pythonapi = PyDLL("python dll", None, _sys.dllhandle)
458elif _sys.platform == "cygwin":
459 pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
460else:
461 pythonapi = PyDLL(None)
464if _os.name == "nt":
465 windll = LibraryLoader(WinDLL)
466 oledll = LibraryLoader(OleDLL)
468 GetLastError = windll.kernel32.GetLastError
469 from _ctypes import get_last_error, set_last_error
471 def WinError(code=None, descr=None):
472 if code is None:
473 code = GetLastError()
474 if descr is None:
475 descr = FormatError(code).strip()
476 return OSError(None, descr, None, code)
478if sizeof(c_uint) == sizeof(c_void_p):
479 c_size_t = c_uint
480 c_ssize_t = c_int
481elif sizeof(c_ulong) == sizeof(c_void_p):
482 c_size_t = c_ulong
483 c_ssize_t = c_long
484elif sizeof(c_ulonglong) == sizeof(c_void_p):
485 c_size_t = c_ulonglong
486 c_ssize_t = c_longlong
488# functions
490from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr
492## void *memmove(void *, const void *, size_t);
493memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr)
495## void *memset(void *, int, size_t)
496memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr)
498def PYFUNCTYPE(restype, *argtypes):
499 class CFunctionType(_CFuncPtr):
500 _argtypes_ = argtypes
501 _restype_ = restype
502 _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
503 return CFunctionType
505_cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr)
506def cast(obj, typ):
507 return _cast(obj, obj, typ)
509_string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr)
510def string_at(ptr, size=-1):
511 """string_at(addr[, size]) -> string
513 Return the string at addr."""
514 return _string_at(ptr, size)
516try:
517 from _ctypes import _wstring_at_addr
518except ImportError:
519 pass
520else:
521 _wstring_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr)
522 def wstring_at(ptr, size=-1):
523 """wstring_at(addr[, size]) -> string
525 Return the string at addr."""
526 return _wstring_at(ptr, size)
529if _os.name == "nt": # COM stuff
530 def DllGetClassObject(rclsid, riid, ppv):
531 try:
532 ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
533 except ImportError:
534 return -2147221231 # CLASS_E_CLASSNOTAVAILABLE
535 else:
536 return ccom.DllGetClassObject(rclsid, riid, ppv)
538 def DllCanUnloadNow():
539 try:
540 ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
541 except ImportError:
542 return 0 # S_OK
543 return ccom.DllCanUnloadNow()
545from ctypes._endian import BigEndianStructure, LittleEndianStructure
547# Fill in specifically-sized types
548c_int8 = c_byte
549c_uint8 = c_ubyte
550for kind in [c_short, c_int, c_long, c_longlong]:
551 if sizeof(kind) == 2: c_int16 = kind
552 elif sizeof(kind) == 4: c_int32 = kind
553 elif sizeof(kind) == 8: c_int64 = kind
554for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]:
555 if sizeof(kind) == 2: c_uint16 = kind
556 elif sizeof(kind) == 4: c_uint32 = kind
557 elif sizeof(kind) == 8: c_uint64 = kind
558del(kind)
560_reset_cache()