Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/numpy/core/_dtype_ctypes.py: 34%
54 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1"""
2Conversion from ctypes to dtype.
4In an ideal world, we could achieve this through the PEP3118 buffer protocol,
5something like::
7 def dtype_from_ctypes_type(t):
8 # needed to ensure that the shape of `t` is within memoryview.format
9 class DummyStruct(ctypes.Structure):
10 _fields_ = [('a', t)]
12 # empty to avoid memory allocation
13 ctype_0 = (DummyStruct * 0)()
14 mv = memoryview(ctype_0)
16 # convert the struct, and slice back out the field
17 return _dtype_from_pep3118(mv.format)['a']
19Unfortunately, this fails because:
21* ctypes cannot handle length-0 arrays with PEP3118 (bpo-32782)
22* PEP3118 cannot represent unions, but both numpy and ctypes can
23* ctypes cannot handle big-endian structs with PEP3118 (bpo-32780)
24"""
26# We delay-import ctypes for distributions that do not include it.
27# While this module is not used unless the user passes in ctypes
28# members, it is eagerly imported from numpy/core/__init__.py.
29import numpy as np
32def _from_ctypes_array(t):
33 return np.dtype((dtype_from_ctypes_type(t._type_), (t._length_,)))
36def _from_ctypes_structure(t):
37 for item in t._fields_:
38 if len(item) > 2:
39 raise TypeError(
40 "ctypes bitfields have no dtype equivalent")
42 if hasattr(t, "_pack_"):
43 import ctypes
44 formats = []
45 offsets = []
46 names = []
47 current_offset = 0
48 for fname, ftyp in t._fields_:
49 names.append(fname)
50 formats.append(dtype_from_ctypes_type(ftyp))
51 # Each type has a default offset, this is platform dependent for some types.
52 effective_pack = min(t._pack_, ctypes.alignment(ftyp))
53 current_offset = ((current_offset + effective_pack - 1) // effective_pack) * effective_pack
54 offsets.append(current_offset)
55 current_offset += ctypes.sizeof(ftyp)
57 return np.dtype(dict(
58 formats=formats,
59 offsets=offsets,
60 names=names,
61 itemsize=ctypes.sizeof(t)))
62 else:
63 fields = []
64 for fname, ftyp in t._fields_:
65 fields.append((fname, dtype_from_ctypes_type(ftyp)))
67 # by default, ctypes structs are aligned
68 return np.dtype(fields, align=True)
71def _from_ctypes_scalar(t):
72 """
73 Return the dtype type with endianness included if it's the case
74 """
75 if getattr(t, '__ctype_be__', None) is t:
76 return np.dtype('>' + t._type_)
77 elif getattr(t, '__ctype_le__', None) is t:
78 return np.dtype('<' + t._type_)
79 else:
80 return np.dtype(t._type_)
83def _from_ctypes_union(t):
84 import ctypes
85 formats = []
86 offsets = []
87 names = []
88 for fname, ftyp in t._fields_:
89 names.append(fname)
90 formats.append(dtype_from_ctypes_type(ftyp))
91 offsets.append(0) # Union fields are offset to 0
93 return np.dtype(dict(
94 formats=formats,
95 offsets=offsets,
96 names=names,
97 itemsize=ctypes.sizeof(t)))
100def dtype_from_ctypes_type(t):
101 """
102 Construct a dtype object from a ctypes type
103 """
104 import _ctypes
105 if issubclass(t, _ctypes.Array): 105 ↛ 106line 105 didn't jump to line 106, because the condition on line 105 was never true
106 return _from_ctypes_array(t)
107 elif issubclass(t, _ctypes._Pointer): 107 ↛ 108line 107 didn't jump to line 108, because the condition on line 107 was never true
108 raise TypeError("ctypes pointers have no dtype equivalent")
109 elif issubclass(t, _ctypes.Structure): 109 ↛ 110line 109 didn't jump to line 110, because the condition on line 109 was never true
110 return _from_ctypes_structure(t)
111 elif issubclass(t, _ctypes.Union): 111 ↛ 112line 111 didn't jump to line 112, because the condition on line 111 was never true
112 return _from_ctypes_union(t)
113 elif isinstance(getattr(t, '_type_', None), str): 113 ↛ 116line 113 didn't jump to line 116, because the condition on line 113 was never false
114 return _from_ctypes_scalar(t)
115 else:
116 raise NotImplementedError(
117 "Unknown ctypes type {}".format(t.__name__))