ยปCore Development>Code coverage>Lib/ctypes/__init__.py

Python code coverage for Lib/ctypes/__init__.py

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