File: | numpy/core/src/multiarray/descriptor.c |
Warning: | line 2800, column 30 PyObject ownership leak with reference count of 1 |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* Array Descr Object */ | ||||||||
2 | |||||||||
3 | #define PY_SSIZE_T_CLEAN | ||||||||
4 | #include <Python.h> | ||||||||
5 | #include "structmember.h" | ||||||||
6 | |||||||||
7 | #define NPY_NO_DEPRECATED_API0x0000000E NPY_API_VERSION0x0000000E | ||||||||
8 | #define _MULTIARRAYMODULE | ||||||||
9 | #include "numpy/arrayobject.h" | ||||||||
10 | #include "numpy/arrayscalars.h" | ||||||||
11 | |||||||||
12 | #include "npy_config.h" | ||||||||
13 | #include "npy_ctypes.h" | ||||||||
14 | #include "npy_pycompat.h" | ||||||||
15 | |||||||||
16 | #include "_datetime.h" | ||||||||
17 | #include "common.h" | ||||||||
18 | #include "templ_common.h" /* for npy_mul_with_overflow_intp */ | ||||||||
19 | #include "descriptor.h" | ||||||||
20 | #include "alloc.h" | ||||||||
21 | #include "assert.h" | ||||||||
22 | #include "npy_buffer.h" | ||||||||
23 | |||||||||
24 | /* | ||||||||
25 | * offset: A starting offset. | ||||||||
26 | * alignment: A power-of-two alignment. | ||||||||
27 | * | ||||||||
28 | * This macro returns the smallest value >= 'offset' | ||||||||
29 | * that is divisible by 'alignment'. Because 'alignment' | ||||||||
30 | * is a power of two and integers are twos-complement, | ||||||||
31 | * it is possible to use some simple bit-fiddling to do this. | ||||||||
32 | */ | ||||||||
33 | #define NPY_NEXT_ALIGNED_OFFSET(offset, alignment)(((offset) + (alignment) - 1) & (-(alignment))) \ | ||||||||
34 | (((offset) + (alignment) - 1) & (-(alignment))) | ||||||||
35 | |||||||||
36 | #ifndef PyDictProxy_Check | ||||||||
37 | #define PyDictProxy_Check(obj)((((PyObject*)(obj))->ob_type) == &PyDictProxy_Type) (Py_TYPE(obj)(((PyObject*)(obj))->ob_type) == &PyDictProxy_Type) | ||||||||
38 | #endif | ||||||||
39 | |||||||||
40 | static PyObject *typeDict = NULL((void*)0); /* Must be explicitly loaded */ | ||||||||
41 | |||||||||
42 | static PyArray_Descr * | ||||||||
43 | _try_convert_from_inherit_tuple(PyArray_Descr *type, PyObject *newobj); | ||||||||
44 | |||||||||
45 | static PyArray_Descr * | ||||||||
46 | _convert_from_any(PyObject *obj, int align); | ||||||||
47 | |||||||||
48 | /* | ||||||||
49 | * This function creates a dtype object when the object is a ctypes subclass. | ||||||||
50 | * | ||||||||
51 | * Returns `Py_NotImplemented` if the type is not a ctypes subclass. | ||||||||
52 | */ | ||||||||
53 | static PyArray_Descr * | ||||||||
54 | _try_convert_from_ctypes_type(PyTypeObject *type) | ||||||||
55 | { | ||||||||
56 | PyObject *_numpy_dtype_ctypes; | ||||||||
57 | PyObject *res; | ||||||||
58 | |||||||||
59 | if (!npy_ctypes_check(type)) { | ||||||||
60 | Py_INCREF(Py_NotImplemented)_Py_INCREF(((PyObject*)((&_Py_NotImplementedStruct)))); | ||||||||
61 | return (PyArray_Descr *)Py_NotImplemented(&_Py_NotImplementedStruct); | ||||||||
62 | } | ||||||||
63 | |||||||||
64 | /* Call the python function of the same name. */ | ||||||||
65 | _numpy_dtype_ctypes = PyImport_ImportModule("numpy.core._dtype_ctypes"); | ||||||||
66 | if (_numpy_dtype_ctypes == NULL((void*)0)) { | ||||||||
67 | return NULL((void*)0); | ||||||||
68 | } | ||||||||
69 | res = PyObject_CallMethod_PyObject_CallMethod_SizeT(_numpy_dtype_ctypes, "dtype_from_ctypes_type", "O", (PyObject *)type); | ||||||||
70 | Py_DECREF(_numpy_dtype_ctypes)_Py_DECREF(((PyObject*)(_numpy_dtype_ctypes))); | ||||||||
71 | if (res == NULL((void*)0)) { | ||||||||
72 | return NULL((void*)0); | ||||||||
73 | } | ||||||||
74 | |||||||||
75 | /* | ||||||||
76 | * sanity check that dtype_from_ctypes_type returned the right type, | ||||||||
77 | * since getting it wrong would give segfaults. | ||||||||
78 | */ | ||||||||
79 | if (!PyObject_TypeCheck(res, &PyArrayDescr_Type)((((PyObject*)(res))->ob_type) == (&(*(PyTypeObject *) (&PyArrayDescr_TypeFull))) || PyType_IsSubtype((((PyObject *)(res))->ob_type), (&(*(PyTypeObject *)(&PyArrayDescr_TypeFull )))))) { | ||||||||
80 | Py_DECREF(res)_Py_DECREF(((PyObject*)(res))); | ||||||||
81 | PyErr_BadInternalCall()_PyErr_BadInternalCall("numpy/core/src/multiarray/descriptor.c" , 81); | ||||||||
82 | return NULL((void*)0); | ||||||||
83 | } | ||||||||
84 | |||||||||
85 | return (PyArray_Descr *)res; | ||||||||
86 | } | ||||||||
87 | |||||||||
88 | static PyArray_Descr * | ||||||||
89 | _convert_from_any(PyObject *obj, int align); | ||||||||
90 | |||||||||
91 | /* | ||||||||
92 | * This function creates a dtype object when the object has a "dtype" attribute, | ||||||||
93 | * and it can be converted to a dtype object. | ||||||||
94 | * | ||||||||
95 | * Returns `Py_NotImplemented` if this is not possible. | ||||||||
96 | * Currently the only failure mode for a NULL return is a RecursionError. | ||||||||
97 | */ | ||||||||
98 | static PyArray_Descr * | ||||||||
99 | _try_convert_from_dtype_attr(PyObject *obj) | ||||||||
100 | { | ||||||||
101 | /* For arbitrary objects that have a "dtype" attribute */ | ||||||||
102 | PyObject *dtypedescr = PyObject_GetAttrString(obj, "dtype"); | ||||||||
103 | if (dtypedescr == NULL((void*)0)) { | ||||||||
104 | /* | ||||||||
105 | * This can be reached due to recursion limit being hit while fetching | ||||||||
106 | * the attribute (tested for py3.7). This removes the custom message. | ||||||||
107 | */ | ||||||||
108 | goto fail; | ||||||||
109 | } | ||||||||
110 | |||||||||
111 | if (PyArray_DescrCheck(dtypedescr)((((PyObject*)(dtypedescr))->ob_type) == (&(*(PyTypeObject *)(&PyArrayDescr_TypeFull))) || PyType_IsSubtype((((PyObject *)(dtypedescr))->ob_type), (&(*(PyTypeObject *)(&PyArrayDescr_TypeFull )))))) { | ||||||||
112 | /* The dtype attribute is already a valid descriptor */ | ||||||||
113 | return (PyArray_Descr *)dtypedescr; | ||||||||
114 | } | ||||||||
115 | |||||||||
116 | if (Py_EnterRecursiveCall(((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit ) && _Py_CheckRecursiveCall(" while trying to convert the given data type from its " "`.dtype` attribute.")) | ||||||||
117 | " while trying to convert the given data type from its "((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit ) && _Py_CheckRecursiveCall(" while trying to convert the given data type from its " "`.dtype` attribute.")) | ||||||||
118 | "`.dtype` attribute.")((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit ) && _Py_CheckRecursiveCall(" while trying to convert the given data type from its " "`.dtype` attribute.")) != 0) { | ||||||||
119 | Py_DECREF(dtypedescr)_Py_DECREF(((PyObject*)(dtypedescr))); | ||||||||
120 | return NULL((void*)0); | ||||||||
121 | } | ||||||||
122 | |||||||||
123 | PyArray_Descr *newdescr = _convert_from_any(dtypedescr, 0); | ||||||||
124 | Py_DECREF(dtypedescr)_Py_DECREF(((PyObject*)(dtypedescr))); | ||||||||
125 | Py_LeaveRecursiveCall()do{ if((--(PyThreadState_Get()->recursion_depth) < (((_Py_CheckRecursionLimit ) > 200) ? ((_Py_CheckRecursionLimit) - 50) : (3 * ((_Py_CheckRecursionLimit ) >> 2))))) PyThreadState_Get()->overflowed = 0; } while (0); | ||||||||
126 | if (newdescr == NULL((void*)0)) { | ||||||||
127 | goto fail; | ||||||||
128 | } | ||||||||
129 | |||||||||
130 | /* Deprecated 2021-01-05, NumPy 1.21 */ | ||||||||
131 | if (DEPRECATE("in the future the `.dtype` attribute of a given data"PyErr_WarnEx(PyExc_DeprecationWarning,"in the future the `.dtype` attribute of a given data" "type object must be a valid dtype instance. " "`data_type.dtype` may need to be coerced using " "`np.dtype(data_type.dtype)`. (Deprecated NumPy 1.20)",1) | ||||||||
132 | "type object must be a valid dtype instance. "PyErr_WarnEx(PyExc_DeprecationWarning,"in the future the `.dtype` attribute of a given data" "type object must be a valid dtype instance. " "`data_type.dtype` may need to be coerced using " "`np.dtype(data_type.dtype)`. (Deprecated NumPy 1.20)",1) | ||||||||
133 | "`data_type.dtype` may need to be coerced using "PyErr_WarnEx(PyExc_DeprecationWarning,"in the future the `.dtype` attribute of a given data" "type object must be a valid dtype instance. " "`data_type.dtype` may need to be coerced using " "`np.dtype(data_type.dtype)`. (Deprecated NumPy 1.20)",1) | ||||||||
134 | "`np.dtype(data_type.dtype)`. (Deprecated NumPy 1.20)")PyErr_WarnEx(PyExc_DeprecationWarning,"in the future the `.dtype` attribute of a given data" "type object must be a valid dtype instance. " "`data_type.dtype` may need to be coerced using " "`np.dtype(data_type.dtype)`. (Deprecated NumPy 1.20)",1) < 0) { | ||||||||
135 | Py_DECREF(newdescr)_Py_DECREF(((PyObject*)(newdescr))); | ||||||||
136 | return NULL((void*)0); | ||||||||
137 | } | ||||||||
138 | |||||||||
139 | return newdescr; | ||||||||
140 | |||||||||
141 | fail: | ||||||||
142 | /* Ignore all but recursion errors, to give ctypes a full try. */ | ||||||||
143 | if (!PyErr_ExceptionMatches(PyExc_RecursionError)) { | ||||||||
144 | PyErr_Clear(); | ||||||||
145 | Py_INCREF(Py_NotImplemented)_Py_INCREF(((PyObject*)((&_Py_NotImplementedStruct)))); | ||||||||
146 | return (PyArray_Descr *)Py_NotImplemented(&_Py_NotImplementedStruct); | ||||||||
147 | } | ||||||||
148 | return NULL((void*)0); | ||||||||
149 | } | ||||||||
150 | |||||||||
151 | /* Expose to another file with a prefixed name */ | ||||||||
152 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyArray_Descr * | ||||||||
153 | _arraydescr_try_convert_from_dtype_attr(PyObject *obj) | ||||||||
154 | { | ||||||||
155 | return _try_convert_from_dtype_attr(obj); | ||||||||
156 | } | ||||||||
157 | |||||||||
158 | /* | ||||||||
159 | * Sets the global typeDict object, which is a dictionary mapping | ||||||||
160 | * dtype names to numpy scalar types. | ||||||||
161 | */ | ||||||||
162 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
163 | array_set_typeDict(PyObject *NPY_UNUSED(ignored)(__NPY_UNUSED_TAGGEDignored) __attribute__ ((__unused__)), PyObject *args) | ||||||||
164 | { | ||||||||
165 | PyObject *dict; | ||||||||
166 | |||||||||
167 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O:set_typeDict", &dict)) { | ||||||||
168 | return NULL((void*)0); | ||||||||
169 | } | ||||||||
170 | /* Decrement old reference (if any)*/ | ||||||||
171 | Py_XDECREF(typeDict)_Py_XDECREF(((PyObject*)(typeDict))); | ||||||||
172 | typeDict = dict; | ||||||||
173 | /* Create an internal reference to it */ | ||||||||
174 | Py_INCREF(dict)_Py_INCREF(((PyObject*)(dict))); | ||||||||
175 | Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (& _Py_NoneStruct); | ||||||||
176 | } | ||||||||
177 | |||||||||
178 | #define _chk_byteorder(arg) (arg == '>' || arg == '<' || \ | ||||||||
179 | arg == '|' || arg == '=') | ||||||||
180 | |||||||||
181 | static int | ||||||||
182 | _check_for_commastring(const char *type, Py_ssize_t len) | ||||||||
183 | { | ||||||||
184 | Py_ssize_t i; | ||||||||
185 | int sqbracket; | ||||||||
186 | |||||||||
187 | /* Check for ints at start of string */ | ||||||||
188 | if ((type[0] >= '0' | ||||||||
189 | && type[0] <= '9') | ||||||||
190 | || ((len > 1) | ||||||||
191 | && _chk_byteorder(type[0]) | ||||||||
192 | && (type[1] >= '0' | ||||||||
193 | && type[1] <= '9'))) { | ||||||||
194 | return 1; | ||||||||
195 | } | ||||||||
196 | /* Check for empty tuple */ | ||||||||
197 | if (((len > 1) | ||||||||
198 | && (type[0] == '(' | ||||||||
199 | && type[1] == ')')) | ||||||||
200 | || ((len > 3) | ||||||||
201 | && _chk_byteorder(type[0]) | ||||||||
202 | && (type[1] == '(' | ||||||||
203 | && type[2] == ')'))) { | ||||||||
204 | return 1; | ||||||||
205 | } | ||||||||
206 | /* | ||||||||
207 | * Check for presence of commas outside square [] brackets. This | ||||||||
208 | * allows commas inside of [], for parameterized dtypes to use. | ||||||||
209 | */ | ||||||||
210 | sqbracket = 0; | ||||||||
211 | for (i = 0; i < len; i++) { | ||||||||
212 | switch (type[i]) { | ||||||||
213 | case ',': | ||||||||
214 | if (sqbracket == 0) { | ||||||||
215 | return 1; | ||||||||
216 | } | ||||||||
217 | break; | ||||||||
218 | case '[': | ||||||||
219 | ++sqbracket; | ||||||||
220 | break; | ||||||||
221 | case ']': | ||||||||
222 | --sqbracket; | ||||||||
223 | break; | ||||||||
224 | } | ||||||||
225 | } | ||||||||
226 | return 0; | ||||||||
227 | } | ||||||||
228 | |||||||||
229 | #undef _chk_byteorder | ||||||||
230 | |||||||||
231 | static int | ||||||||
232 | is_datetime_typestr(char const *type, Py_ssize_t len) | ||||||||
233 | { | ||||||||
234 | if (len < 2) { | ||||||||
235 | return 0; | ||||||||
236 | } | ||||||||
237 | if (type[1] == '8' && (type[0] == 'M' || type[0] == 'm')) { | ||||||||
238 | return 1; | ||||||||
239 | } | ||||||||
240 | if (len < 10) { | ||||||||
241 | return 0; | ||||||||
242 | } | ||||||||
243 | if (strncmp(type, "datetime64", 10) == 0) { | ||||||||
244 | return 1; | ||||||||
245 | } | ||||||||
246 | if (len < 11) { | ||||||||
247 | return 0; | ||||||||
248 | } | ||||||||
249 | if (strncmp(type, "timedelta64", 11) == 0) { | ||||||||
250 | return 1; | ||||||||
251 | } | ||||||||
252 | return 0; | ||||||||
253 | } | ||||||||
254 | |||||||||
255 | static PyArray_Descr * | ||||||||
256 | _convert_from_tuple(PyObject *obj, int align) | ||||||||
257 | { | ||||||||
258 | if (PyTuple_GET_SIZE(obj)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(obj))))-> ob_size) != 2) { | ||||||||
259 | PyErr_Format(PyExc_TypeError, | ||||||||
260 | "Tuple must have size 2, but has size %zd", | ||||||||
261 | PyTuple_GET_SIZE(obj)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(obj))))-> ob_size)); | ||||||||
262 | return NULL((void*)0); | ||||||||
263 | } | ||||||||
264 | PyArray_Descr *type = _convert_from_any(PyTuple_GET_ITEM(obj, 0)((((void) (0)), (PyTupleObject *)(obj))->ob_item[0]), align); | ||||||||
265 | if (type == NULL((void*)0)) { | ||||||||
266 | return NULL((void*)0); | ||||||||
267 | } | ||||||||
268 | PyObject *val = PyTuple_GET_ITEM(obj,1)((((void) (0)), (PyTupleObject *)(obj))->ob_item[1]); | ||||||||
269 | /* try to interpret next item as a type */ | ||||||||
270 | PyArray_Descr *res = _try_convert_from_inherit_tuple(type, val); | ||||||||
271 | if ((PyObject *)res != Py_NotImplemented(&_Py_NotImplementedStruct)) { | ||||||||
272 | Py_DECREF(type)_Py_DECREF(((PyObject*)(type))); | ||||||||
273 | return res; | ||||||||
274 | } | ||||||||
275 | Py_DECREF(res)_Py_DECREF(((PyObject*)(res))); | ||||||||
276 | /* | ||||||||
277 | * We get here if _try_convert_from_inherit_tuple failed without crashing | ||||||||
278 | */ | ||||||||
279 | if (PyDataType_ISUNSIZED(type)((type)->elsize == 0 && !(((PyArray_Descr *)(type) )->names != ((void*)0)))) { | ||||||||
280 | /* interpret next item as a typesize */ | ||||||||
281 | int itemsize = PyArray_PyIntAsInt(PyTuple_GET_ITEM(obj,1)((((void) (0)), (PyTupleObject *)(obj))->ob_item[1])); | ||||||||
282 | |||||||||
283 | if (error_converting(itemsize)(((itemsize) == -1) && PyErr_Occurred())) { | ||||||||
284 | PyErr_SetString(PyExc_ValueError, | ||||||||
285 | "invalid itemsize in generic type tuple"); | ||||||||
286 | Py_DECREF(type)_Py_DECREF(((PyObject*)(type))); | ||||||||
287 | return NULL((void*)0); | ||||||||
288 | } | ||||||||
289 | PyArray_DESCR_REPLACE(type)do { PyArray_Descr *_new_; _new_ = PyArray_DescrNew(type); _Py_XDECREF (((PyObject*)(type))); type = _new_; } while(0); | ||||||||
290 | if (type == NULL((void*)0)) { | ||||||||
291 | return NULL((void*)0); | ||||||||
292 | } | ||||||||
293 | if (type->type_num == NPY_UNICODE) { | ||||||||
294 | type->elsize = itemsize << 2; | ||||||||
295 | } | ||||||||
296 | else { | ||||||||
297 | type->elsize = itemsize; | ||||||||
298 | } | ||||||||
299 | return type; | ||||||||
300 | } | ||||||||
301 | else if (type->metadata && (PyDict_Check(val)((((((PyObject*)(val))->ob_type))->tp_flags & ((1UL << 29))) != 0) || PyDictProxy_Check(val)((((PyObject*)(val))->ob_type) == &PyDictProxy_Type))) { | ||||||||
302 | /* Assume it's a metadata dictionary */ | ||||||||
303 | if (PyDict_Merge(type->metadata, val, 0) == -1) { | ||||||||
304 | Py_DECREF(type)_Py_DECREF(((PyObject*)(type))); | ||||||||
305 | return NULL((void*)0); | ||||||||
306 | } | ||||||||
307 | return type; | ||||||||
308 | } | ||||||||
309 | else { | ||||||||
310 | /* | ||||||||
311 | * interpret next item as shape (if it's a tuple) | ||||||||
312 | * and reset the type to NPY_VOID with | ||||||||
313 | * a new fields attribute. | ||||||||
314 | */ | ||||||||
315 | PyArray_Dims shape = {NULL((void*)0), -1}; | ||||||||
316 | if (!(PyArray_IntpConverter(val, &shape)) || (shape.len > NPY_MAXDIMS32)) { | ||||||||
317 | PyErr_SetString(PyExc_ValueError, | ||||||||
318 | "invalid shape in fixed-type tuple."); | ||||||||
319 | goto fail; | ||||||||
320 | } | ||||||||
321 | /* if (type, ()) was given it is equivalent to type... */ | ||||||||
322 | if (shape.len == 0 && PyTuple_Check(val)((((((PyObject*)(val))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { | ||||||||
323 | npy_free_cache_dim_obj(shape); | ||||||||
324 | return type; | ||||||||
325 | } | ||||||||
326 | /* (type, 1) use to be equivalent to type, but is deprecated */ | ||||||||
327 | if (shape.len == 1 | ||||||||
328 | && shape.ptr[0] == 1 | ||||||||
329 | && PyNumber_Check(val)) { | ||||||||
330 | /* 2019-05-20, 1.17 */ | ||||||||
331 | if (DEPRECATE_FUTUREWARNING(PyErr_WarnEx(PyExc_FutureWarning,"Passing (type, 1) or '1type' as a synonym of type is " "deprecated; in a future version of numpy, it will be " "understood as (type, (1,)) / '(1,)type'." ,1) | ||||||||
332 | "Passing (type, 1) or '1type' as a synonym of type is "PyErr_WarnEx(PyExc_FutureWarning,"Passing (type, 1) or '1type' as a synonym of type is " "deprecated; in a future version of numpy, it will be " "understood as (type, (1,)) / '(1,)type'." ,1) | ||||||||
333 | "deprecated; in a future version of numpy, it will be "PyErr_WarnEx(PyExc_FutureWarning,"Passing (type, 1) or '1type' as a synonym of type is " "deprecated; in a future version of numpy, it will be " "understood as (type, (1,)) / '(1,)type'." ,1) | ||||||||
334 | "understood as (type, (1,)) / '(1,)type'.")PyErr_WarnEx(PyExc_FutureWarning,"Passing (type, 1) or '1type' as a synonym of type is " "deprecated; in a future version of numpy, it will be " "understood as (type, (1,)) / '(1,)type'." ,1) < 0) { | ||||||||
335 | goto fail; | ||||||||
336 | } | ||||||||
337 | npy_free_cache_dim_obj(shape); | ||||||||
338 | return type; | ||||||||
339 | } | ||||||||
340 | |||||||||
341 | /* validate and set shape */ | ||||||||
342 | for (int i=0; i < shape.len; i++) { | ||||||||
343 | if (shape.ptr[i] < 0) { | ||||||||
344 | PyErr_SetString(PyExc_ValueError, | ||||||||
345 | "invalid shape in fixed-type tuple: " | ||||||||
346 | "dimension smaller then zero."); | ||||||||
347 | goto fail; | ||||||||
348 | } | ||||||||
349 | if (shape.ptr[i] > NPY_MAX_INT2147483647) { | ||||||||
350 | PyErr_SetString(PyExc_ValueError, | ||||||||
351 | "invalid shape in fixed-type tuple: " | ||||||||
352 | "dimension does not fit into a C int."); | ||||||||
353 | goto fail; | ||||||||
354 | } | ||||||||
355 | } | ||||||||
356 | npy_intp items = PyArray_OverflowMultiplyList(shape.ptr, shape.len); | ||||||||
357 | int overflowed; | ||||||||
358 | int nbytes; | ||||||||
359 | if (items < 0 || items > NPY_MAX_INT2147483647) { | ||||||||
360 | overflowed = 1; | ||||||||
361 | } | ||||||||
362 | else { | ||||||||
363 | overflowed = npy_mul_with_overflow_int( | ||||||||
364 | &nbytes, type->elsize, (int) items); | ||||||||
365 | } | ||||||||
366 | if (overflowed) { | ||||||||
367 | PyErr_SetString(PyExc_ValueError, | ||||||||
368 | "invalid shape in fixed-type tuple: dtype size in " | ||||||||
369 | "bytes must fit into a C int."); | ||||||||
370 | goto fail; | ||||||||
371 | } | ||||||||
372 | PyArray_Descr *newdescr = PyArray_DescrNewFromType(NPY_VOID); | ||||||||
373 | if (newdescr == NULL((void*)0)) { | ||||||||
374 | goto fail; | ||||||||
375 | } | ||||||||
376 | newdescr->elsize = nbytes; | ||||||||
377 | newdescr->subarray = PyArray_mallocPyMem_RawMalloc(sizeof(PyArray_ArrayDescr)); | ||||||||
378 | if (newdescr->subarray == NULL((void*)0)) { | ||||||||
379 | Py_DECREF(newdescr)_Py_DECREF(((PyObject*)(newdescr))); | ||||||||
380 | PyErr_NoMemory(); | ||||||||
381 | goto fail; | ||||||||
382 | } | ||||||||
383 | newdescr->flags = type->flags; | ||||||||
384 | newdescr->alignment = type->alignment; | ||||||||
385 | newdescr->subarray->base = type; | ||||||||
386 | type = NULL((void*)0); | ||||||||
387 | Py_XDECREF(newdescr->fields)_Py_XDECREF(((PyObject*)(newdescr->fields))); | ||||||||
388 | Py_XDECREF(newdescr->names)_Py_XDECREF(((PyObject*)(newdescr->names))); | ||||||||
389 | newdescr->fields = NULL((void*)0); | ||||||||
390 | newdescr->names = NULL((void*)0); | ||||||||
391 | |||||||||
392 | /* | ||||||||
393 | * Create a new subarray->shape tuple (it can be an arbitrary | ||||||||
394 | * sequence of integer like objects, neither of which is safe. | ||||||||
395 | */ | ||||||||
396 | newdescr->subarray->shape = PyTuple_New(shape.len); | ||||||||
397 | if (newdescr->subarray->shape == NULL((void*)0)) { | ||||||||
398 | Py_DECREF(newdescr)_Py_DECREF(((PyObject*)(newdescr))); | ||||||||
399 | goto fail; | ||||||||
400 | } | ||||||||
401 | for (int i=0; i < shape.len; i++) { | ||||||||
402 | PyTuple_SET_ITEM(newdescr->subarray->shape, i,PyTuple_SetItem(newdescr->subarray->shape, i, PyLong_FromLong ((long)shape.ptr[i])) | ||||||||
403 | PyLong_FromLong((long)shape.ptr[i]))PyTuple_SetItem(newdescr->subarray->shape, i, PyLong_FromLong ((long)shape.ptr[i])); | ||||||||
404 | |||||||||
405 | if (PyTuple_GET_ITEM(newdescr->subarray->shape, i)((((void) (0)), (PyTupleObject *)(newdescr->subarray->shape ))->ob_item[i]) == NULL((void*)0)) { | ||||||||
406 | Py_DECREF(newdescr)_Py_DECREF(((PyObject*)(newdescr))); | ||||||||
407 | goto fail; | ||||||||
408 | } | ||||||||
409 | } | ||||||||
410 | |||||||||
411 | npy_free_cache_dim_obj(shape); | ||||||||
412 | return newdescr; | ||||||||
413 | |||||||||
414 | fail: | ||||||||
415 | Py_XDECREF(type)_Py_XDECREF(((PyObject*)(type))); | ||||||||
416 | npy_free_cache_dim_obj(shape); | ||||||||
417 | return NULL((void*)0); | ||||||||
418 | } | ||||||||
419 | } | ||||||||
420 | |||||||||
421 | /* | ||||||||
422 | * obj is a list. Each item is a tuple with | ||||||||
423 | * | ||||||||
424 | * (field-name, data-type (either a list or a string), and an optional | ||||||||
425 | * shape parameter). | ||||||||
426 | * | ||||||||
427 | * field-name can be a string or a 2-tuple | ||||||||
428 | * data-type can now be a list, string, or 2-tuple | ||||||||
429 | * (string, metadata dictionary) | ||||||||
430 | */ | ||||||||
431 | static PyArray_Descr * | ||||||||
432 | _convert_from_array_descr(PyObject *obj, int align) | ||||||||
433 | { | ||||||||
434 | int n = PyList_GET_SIZE(obj)(((void) (0)), (((PyVarObject*)(obj))->ob_size)); | ||||||||
435 | PyObject *nameslist = PyTuple_New(n); | ||||||||
436 | if (!nameslist) { | ||||||||
437 | return NULL((void*)0); | ||||||||
438 | } | ||||||||
439 | |||||||||
440 | /* Types with fields need the Python C API for field access */ | ||||||||
441 | char dtypeflags = NPY_NEEDS_PYAPI0x10; | ||||||||
442 | int maxalign = 0; | ||||||||
443 | int totalsize = 0; | ||||||||
444 | PyObject *fields = PyDict_New(); | ||||||||
445 | if (!fields) { | ||||||||
446 | return NULL((void*)0); | ||||||||
447 | } | ||||||||
448 | for (int i = 0; i < n; i++) { | ||||||||
449 | PyObject *item = PyList_GET_ITEM(obj, i)(((PyListObject *)(obj))->ob_item[i]); | ||||||||
450 | if (!PyTuple_Check(item)((((((PyObject*)(item))->ob_type))->tp_flags & ((1UL << 26))) != 0) || (PyTuple_GET_SIZE(item)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(item))))-> ob_size) < 2)) { | ||||||||
451 | PyErr_Format(PyExc_TypeError, | ||||||||
452 | "Field elements must be 2- or 3-tuples, got '%R'", | ||||||||
453 | item); | ||||||||
454 | goto fail; | ||||||||
455 | } | ||||||||
456 | PyObject *name = PyTuple_GET_ITEM(item, 0)((((void) (0)), (PyTupleObject *)(item))->ob_item[0]); | ||||||||
457 | PyObject *title; | ||||||||
458 | if (PyUnicode_Check(name)((((((PyObject*)(name))->ob_type))->tp_flags & ((1UL << 28))) != 0)) { | ||||||||
459 | title = NULL((void*)0); | ||||||||
460 | } | ||||||||
461 | else if (PyTuple_Check(name)((((((PyObject*)(name))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { | ||||||||
462 | if (PyTuple_GET_SIZE(name)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(name))))-> ob_size) != 2) { | ||||||||
463 | PyErr_Format(PyExc_TypeError, | ||||||||
464 | "If a tuple, the first element of a field tuple must have " | ||||||||
465 | "two elements, not %zd", | ||||||||
466 | PyTuple_GET_SIZE(name)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(name))))-> ob_size)); | ||||||||
467 | goto fail; | ||||||||
468 | } | ||||||||
469 | title = PyTuple_GET_ITEM(name, 0)((((void) (0)), (PyTupleObject *)(name))->ob_item[0]); | ||||||||
470 | name = PyTuple_GET_ITEM(name, 1)((((void) (0)), (PyTupleObject *)(name))->ob_item[1]); | ||||||||
471 | if (!PyUnicode_Check(name)((((((PyObject*)(name))->ob_type))->tp_flags & ((1UL << 28))) != 0)) { | ||||||||
472 | PyErr_SetString(PyExc_TypeError, "Field name must be a str"); | ||||||||
473 | goto fail; | ||||||||
474 | } | ||||||||
475 | } | ||||||||
476 | else { | ||||||||
477 | PyErr_SetString(PyExc_TypeError, | ||||||||
478 | "First element of field tuple is " | ||||||||
479 | "neither a tuple nor str"); | ||||||||
480 | goto fail; | ||||||||
481 | } | ||||||||
482 | |||||||||
483 | /* Insert name into nameslist */ | ||||||||
484 | Py_INCREF(name)_Py_INCREF(((PyObject*)(name))); | ||||||||
485 | |||||||||
486 | if (PyUnicode_GetLength(name) == 0) { | ||||||||
487 | Py_DECREF(name)_Py_DECREF(((PyObject*)(name))); | ||||||||
488 | if (title == NULL((void*)0)) { | ||||||||
489 | name = PyUnicode_FromFormat("f%d", i); | ||||||||
490 | if (name == NULL((void*)0)) { | ||||||||
491 | goto fail; | ||||||||
492 | } | ||||||||
493 | } | ||||||||
494 | /* On Py3, allow only non-empty Unicode strings as field names */ | ||||||||
495 | else if (PyUnicode_Check(title)((((((PyObject*)(title))->ob_type))->tp_flags & ((1UL << 28))) != 0) && PyUnicode_GetLength(title) > 0) { | ||||||||
496 | name = title; | ||||||||
497 | Py_INCREF(name)_Py_INCREF(((PyObject*)(name))); | ||||||||
498 | } | ||||||||
499 | else { | ||||||||
500 | PyErr_SetString(PyExc_TypeError, "Field titles must be non-empty strings"); | ||||||||
501 | goto fail; | ||||||||
502 | } | ||||||||
503 | } | ||||||||
504 | PyTuple_SET_ITEM(nameslist, i, name)PyTuple_SetItem(nameslist, i, name); | ||||||||
505 | |||||||||
506 | /* Process rest */ | ||||||||
507 | PyArray_Descr *conv; | ||||||||
508 | if (PyTuple_GET_SIZE(item)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(item))))-> ob_size) == 2) { | ||||||||
509 | conv = _convert_from_any(PyTuple_GET_ITEM(item, 1)((((void) (0)), (PyTupleObject *)(item))->ob_item[1]), align); | ||||||||
510 | if (conv == NULL((void*)0)) { | ||||||||
511 | goto fail; | ||||||||
512 | } | ||||||||
513 | } | ||||||||
514 | else if (PyTuple_GET_SIZE(item)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(item))))-> ob_size) == 3) { | ||||||||
515 | PyObject *newobj = PyTuple_GetSlice(item, 1, 3); | ||||||||
516 | conv = _convert_from_any(newobj, align); | ||||||||
517 | Py_DECREF(newobj)_Py_DECREF(((PyObject*)(newobj))); | ||||||||
518 | if (conv == NULL((void*)0)) { | ||||||||
519 | goto fail; | ||||||||
520 | } | ||||||||
521 | } | ||||||||
522 | else { | ||||||||
523 | PyErr_Format(PyExc_TypeError, | ||||||||
524 | "Field elements must be tuples with at most 3 elements, got '%R'", item); | ||||||||
525 | goto fail; | ||||||||
526 | } | ||||||||
527 | if ((PyDict_GetItemWithError(fields, name) != NULL((void*)0)) | ||||||||
528 | || (title | ||||||||
529 | && PyUnicode_Check(title)((((((PyObject*)(title))->ob_type))->tp_flags & ((1UL << 28))) != 0) | ||||||||
530 | && (PyDict_GetItemWithError(fields, title) != NULL((void*)0)))) { | ||||||||
531 | PyErr_Format(PyExc_ValueError, | ||||||||
532 | "field %R occurs more than once", name); | ||||||||
533 | Py_DECREF(conv)_Py_DECREF(((PyObject*)(conv))); | ||||||||
534 | goto fail; | ||||||||
535 | } | ||||||||
536 | else if (PyErr_Occurred()) { | ||||||||
537 | /* Dict lookup crashed */ | ||||||||
538 | Py_DECREF(conv)_Py_DECREF(((PyObject*)(conv))); | ||||||||
539 | goto fail; | ||||||||
540 | } | ||||||||
541 | dtypeflags |= (conv->flags & NPY_FROM_FIELDS(0x08 | 0x02 | 0x01 | 0x10)); | ||||||||
542 | if (align) { | ||||||||
543 | int _align = conv->alignment; | ||||||||
544 | if (_align > 1) { | ||||||||
545 | totalsize = NPY_NEXT_ALIGNED_OFFSET(totalsize, _align)(((totalsize) + (_align) - 1) & (-(_align))); | ||||||||
546 | } | ||||||||
547 | maxalign = PyArray_MAX(maxalign, _align)(((maxalign)>(_align))?(maxalign):(_align)); | ||||||||
548 | } | ||||||||
549 | PyObject *tup = PyTuple_New((title == NULL((void*)0) ? 2 : 3)); | ||||||||
550 | if (tup == NULL((void*)0)) { | ||||||||
551 | goto fail; | ||||||||
552 | } | ||||||||
553 | PyTuple_SET_ITEM(tup, 0, (PyObject *)conv)PyTuple_SetItem(tup, 0, (PyObject *)conv); | ||||||||
554 | PyTuple_SET_ITEM(tup, 1, PyLong_FromLong((long) totalsize))PyTuple_SetItem(tup, 1, PyLong_FromLong((long) totalsize)); | ||||||||
555 | |||||||||
556 | /* | ||||||||
557 | * Title can be "meta-data". Only insert it | ||||||||
558 | * into the fields dictionary if it is a string | ||||||||
559 | * and if it is not the same as the name. | ||||||||
560 | */ | ||||||||
561 | if (title != NULL((void*)0)) { | ||||||||
562 | Py_INCREF(title)_Py_INCREF(((PyObject*)(title))); | ||||||||
563 | PyTuple_SET_ITEM(tup, 2, title)PyTuple_SetItem(tup, 2, title); | ||||||||
564 | if (PyDict_SetItem(fields, name, tup) < 0) { | ||||||||
565 | goto fail; | ||||||||
566 | } | ||||||||
567 | if (PyUnicode_Check(title)((((((PyObject*)(title))->ob_type))->tp_flags & ((1UL << 28))) != 0)) { | ||||||||
568 | PyObject *existing = PyDict_GetItemWithError(fields, title); | ||||||||
569 | if (existing == NULL((void*)0) && PyErr_Occurred()) { | ||||||||
570 | goto fail; | ||||||||
571 | } | ||||||||
572 | if (existing != NULL((void*)0)) { | ||||||||
573 | PyErr_SetString(PyExc_ValueError, | ||||||||
574 | "title already used as a name or title."); | ||||||||
575 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||||
576 | goto fail; | ||||||||
577 | } | ||||||||
578 | if (PyDict_SetItem(fields, title, tup) < 0) { | ||||||||
579 | goto fail; | ||||||||
580 | } | ||||||||
581 | } | ||||||||
582 | } | ||||||||
583 | else { | ||||||||
584 | if (PyDict_SetItem(fields, name, tup) < 0) { | ||||||||
585 | goto fail; | ||||||||
586 | } | ||||||||
587 | } | ||||||||
588 | |||||||||
589 | totalsize += conv->elsize; | ||||||||
590 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||||
591 | } | ||||||||
592 | |||||||||
593 | if (maxalign > 1) { | ||||||||
594 | totalsize = NPY_NEXT_ALIGNED_OFFSET(totalsize, maxalign)(((totalsize) + (maxalign) - 1) & (-(maxalign))); | ||||||||
595 | } | ||||||||
596 | |||||||||
597 | PyArray_Descr *new = PyArray_DescrNewFromType(NPY_VOID); | ||||||||
598 | if (new == NULL((void*)0)) { | ||||||||
599 | Py_XDECREF(fields)_Py_XDECREF(((PyObject*)(fields))); | ||||||||
600 | Py_XDECREF(nameslist)_Py_XDECREF(((PyObject*)(nameslist))); | ||||||||
601 | return NULL((void*)0); | ||||||||
602 | } | ||||||||
603 | new->fields = fields; | ||||||||
604 | new->names = nameslist; | ||||||||
605 | new->elsize = totalsize; | ||||||||
606 | new->flags = dtypeflags; | ||||||||
607 | |||||||||
608 | /* Structured arrays get a sticky aligned bit */ | ||||||||
609 | if (align) { | ||||||||
610 | new->flags |= NPY_ALIGNED_STRUCT0x80; | ||||||||
611 | new->alignment = maxalign; | ||||||||
612 | } | ||||||||
613 | return new; | ||||||||
614 | |||||||||
615 | fail: | ||||||||
616 | Py_DECREF(fields)_Py_DECREF(((PyObject*)(fields))); | ||||||||
617 | Py_DECREF(nameslist)_Py_DECREF(((PyObject*)(nameslist))); | ||||||||
618 | return NULL((void*)0); | ||||||||
619 | |||||||||
620 | } | ||||||||
621 | |||||||||
622 | /* | ||||||||
623 | * a list specifying a data-type can just be | ||||||||
624 | * a list of formats. The names for the fields | ||||||||
625 | * will default to f0, f1, f2, and so forth. | ||||||||
626 | */ | ||||||||
627 | static PyArray_Descr * | ||||||||
628 | _convert_from_list(PyObject *obj, int align) | ||||||||
629 | { | ||||||||
630 | int n = PyList_GET_SIZE(obj)(((void) (0)), (((PyVarObject*)(obj))->ob_size)); | ||||||||
631 | /* | ||||||||
632 | * Ignore any empty string at end which _internal._commastring | ||||||||
633 | * can produce | ||||||||
634 | */ | ||||||||
635 | PyObject *last_item = PyList_GET_ITEM(obj, n-1)(((PyListObject *)(obj))->ob_item[n-1]); | ||||||||
636 | if (PyUnicode_Check(last_item)((((((PyObject*)(last_item))->ob_type))->tp_flags & ((1UL << 28))) != 0)) { | ||||||||
637 | Py_ssize_t s = PySequence_Size(last_item); | ||||||||
638 | if (s < 0) { | ||||||||
639 | return NULL((void*)0); | ||||||||
640 | } | ||||||||
641 | if (s == 0) { | ||||||||
642 | n = n - 1; | ||||||||
643 | } | ||||||||
644 | } | ||||||||
645 | if (n == 0) { | ||||||||
646 | PyErr_SetString(PyExc_ValueError, "Expected at least one field name"); | ||||||||
647 | return NULL((void*)0); | ||||||||
648 | } | ||||||||
649 | PyObject *nameslist = PyTuple_New(n); | ||||||||
650 | if (!nameslist) { | ||||||||
651 | return NULL((void*)0); | ||||||||
652 | } | ||||||||
653 | PyObject *fields = PyDict_New(); | ||||||||
654 | if (!fields) { | ||||||||
655 | Py_DECREF(nameslist)_Py_DECREF(((PyObject*)(nameslist))); | ||||||||
656 | return NULL((void*)0); | ||||||||
657 | } | ||||||||
658 | |||||||||
659 | /* Types with fields need the Python C API for field access */ | ||||||||
660 | char dtypeflags = NPY_NEEDS_PYAPI0x10; | ||||||||
661 | int maxalign = 0; | ||||||||
662 | int totalsize = 0; | ||||||||
663 | for (int i = 0; i < n; i++) { | ||||||||
664 | PyArray_Descr *conv = _convert_from_any( | ||||||||
665 | PyList_GET_ITEM(obj, i)(((PyListObject *)(obj))->ob_item[i]), align); | ||||||||
666 | if (conv == NULL((void*)0)) { | ||||||||
667 | goto fail; | ||||||||
668 | } | ||||||||
669 | dtypeflags |= (conv->flags & NPY_FROM_FIELDS(0x08 | 0x02 | 0x01 | 0x10)); | ||||||||
670 | if (align) { | ||||||||
671 | int _align = conv->alignment; | ||||||||
672 | if (_align > 1) { | ||||||||
673 | totalsize = NPY_NEXT_ALIGNED_OFFSET(totalsize, _align)(((totalsize) + (_align) - 1) & (-(_align))); | ||||||||
674 | } | ||||||||
675 | maxalign = PyArray_MAX(maxalign, _align)(((maxalign)>(_align))?(maxalign):(_align)); | ||||||||
676 | } | ||||||||
677 | PyObject *size_obj = PyLong_FromLong((long) totalsize); | ||||||||
678 | if (!size_obj) { | ||||||||
679 | Py_DECREF(conv)_Py_DECREF(((PyObject*)(conv))); | ||||||||
680 | goto fail; | ||||||||
681 | } | ||||||||
682 | PyObject *tup = PyTuple_New(2); | ||||||||
683 | if (!tup) { | ||||||||
684 | Py_DECREF(size_obj)_Py_DECREF(((PyObject*)(size_obj))); | ||||||||
685 | Py_DECREF(conv)_Py_DECREF(((PyObject*)(conv))); | ||||||||
686 | goto fail; | ||||||||
687 | } | ||||||||
688 | PyTuple_SET_ITEM(tup, 0, (PyObject *)conv)PyTuple_SetItem(tup, 0, (PyObject *)conv); | ||||||||
689 | PyTuple_SET_ITEM(tup, 1, size_obj)PyTuple_SetItem(tup, 1, size_obj); | ||||||||
690 | PyObject *key = PyUnicode_FromFormat("f%d", i); | ||||||||
691 | if (!key) { | ||||||||
692 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||||
693 | goto fail; | ||||||||
694 | } | ||||||||
695 | /* steals a reference to key */ | ||||||||
696 | PyTuple_SET_ITEM(nameslist, i, key)PyTuple_SetItem(nameslist, i, key); | ||||||||
697 | int ret = PyDict_SetItem(fields, key, tup); | ||||||||
698 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||||
699 | if (ret < 0) { | ||||||||
700 | goto fail; | ||||||||
701 | } | ||||||||
702 | totalsize += conv->elsize; | ||||||||
703 | } | ||||||||
704 | PyArray_Descr *new = PyArray_DescrNewFromType(NPY_VOID); | ||||||||
705 | new->fields = fields; | ||||||||
706 | new->names = nameslist; | ||||||||
707 | new->flags = dtypeflags; | ||||||||
708 | if (maxalign > 1) { | ||||||||
709 | totalsize = NPY_NEXT_ALIGNED_OFFSET(totalsize, maxalign)(((totalsize) + (maxalign) - 1) & (-(maxalign))); | ||||||||
710 | } | ||||||||
711 | /* Structured arrays get a sticky aligned bit */ | ||||||||
712 | if (align) { | ||||||||
713 | new->flags |= NPY_ALIGNED_STRUCT0x80; | ||||||||
714 | new->alignment = maxalign; | ||||||||
715 | } | ||||||||
716 | new->elsize = totalsize; | ||||||||
717 | return new; | ||||||||
718 | |||||||||
719 | fail: | ||||||||
720 | Py_DECREF(nameslist)_Py_DECREF(((PyObject*)(nameslist))); | ||||||||
721 | Py_DECREF(fields)_Py_DECREF(((PyObject*)(fields))); | ||||||||
722 | return NULL((void*)0); | ||||||||
723 | } | ||||||||
724 | |||||||||
725 | |||||||||
726 | /* | ||||||||
727 | * comma-separated string | ||||||||
728 | * this is the format developed by the numarray records module and implemented | ||||||||
729 | * by the format parser in that module this is an alternative implementation | ||||||||
730 | * found in the _internal.py file patterned after that one -- the approach is | ||||||||
731 | * to try to convert to a list (with tuples if any repeat information is | ||||||||
732 | * present) and then call the _convert_from_list) | ||||||||
733 | * | ||||||||
734 | * TODO: Calling Python from C like this in critical-path code is not | ||||||||
735 | * a good idea. This should all be converted to C code. | ||||||||
736 | */ | ||||||||
737 | static PyArray_Descr * | ||||||||
738 | _convert_from_commastring(PyObject *obj, int align) | ||||||||
739 | { | ||||||||
740 | PyObject *listobj; | ||||||||
741 | PyArray_Descr *res; | ||||||||
742 | PyObject *_numpy_internal; | ||||||||
743 | assert(PyUnicode_Check(obj))((void) (0)); | ||||||||
744 | _numpy_internal = PyImport_ImportModule("numpy.core._internal"); | ||||||||
745 | if (_numpy_internal == NULL((void*)0)) { | ||||||||
746 | return NULL((void*)0); | ||||||||
747 | } | ||||||||
748 | listobj = PyObject_CallMethod_PyObject_CallMethod_SizeT(_numpy_internal, "_commastring", "O", obj); | ||||||||
749 | Py_DECREF(_numpy_internal)_Py_DECREF(((PyObject*)(_numpy_internal))); | ||||||||
750 | if (listobj == NULL((void*)0)) { | ||||||||
751 | return NULL((void*)0); | ||||||||
752 | } | ||||||||
753 | if (!PyList_Check(listobj)((((((PyObject*)(listobj))->ob_type))->tp_flags & ( (1UL << 25))) != 0) || PyList_GET_SIZE(listobj)(((void) (0)), (((PyVarObject*)(listobj))->ob_size)) < 1) { | ||||||||
754 | PyErr_SetString(PyExc_RuntimeError, | ||||||||
755 | "_commastring is not returning a list with len >= 1"); | ||||||||
756 | Py_DECREF(listobj)_Py_DECREF(((PyObject*)(listobj))); | ||||||||
757 | return NULL((void*)0); | ||||||||
758 | } | ||||||||
759 | if (PyList_GET_SIZE(listobj)(((void) (0)), (((PyVarObject*)(listobj))->ob_size)) == 1) { | ||||||||
760 | res = _convert_from_any(PyList_GET_ITEM(listobj, 0)(((PyListObject *)(listobj))->ob_item[0]), align); | ||||||||
761 | } | ||||||||
762 | else { | ||||||||
763 | res = _convert_from_list(listobj, align); | ||||||||
764 | } | ||||||||
765 | Py_DECREF(listobj)_Py_DECREF(((PyObject*)(listobj))); | ||||||||
766 | return res; | ||||||||
767 | } | ||||||||
768 | |||||||||
769 | static int | ||||||||
770 | _is_tuple_of_integers(PyObject *obj) | ||||||||
771 | { | ||||||||
772 | int i; | ||||||||
773 | |||||||||
774 | if (!PyTuple_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { | ||||||||
775 | return 0; | ||||||||
776 | } | ||||||||
777 | for (i = 0; i < PyTuple_GET_SIZE(obj)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(obj))))-> ob_size); i++) { | ||||||||
778 | if (!PyArray_IsIntegerScalar(PyTuple_GET_ITEM(obj, i))(((((((PyObject*)(((((void) (0)), (PyTupleObject *)(obj))-> ob_item[i])))->ob_type))->tp_flags & ((1UL << 24))) != 0) || (((((PyObject*)((((((void) (0)), (PyTupleObject *)(obj))->ob_item[i]))))->ob_type) == (&PyIntegerArrType_Type ) || PyType_IsSubtype((((PyObject*)((((((void) (0)), (PyTupleObject *)(obj))->ob_item[i]))))->ob_type), (&PyIntegerArrType_Type )))))) { | ||||||||
779 | return 0; | ||||||||
780 | } | ||||||||
781 | } | ||||||||
782 | return 1; | ||||||||
783 | } | ||||||||
784 | |||||||||
785 | /* | ||||||||
786 | * helper function for _try_convert_from_inherit_tuple to disallow dtypes of the form | ||||||||
787 | * (old_dtype, new_dtype) where either of the dtypes contains python | ||||||||
788 | * objects - these dtypes are not useful and can be a source of segfaults, | ||||||||
789 | * when an attempt is made to interpret a python object as a different dtype | ||||||||
790 | * or vice versa | ||||||||
791 | * an exception is made for dtypes of the form ('O', [('name', 'O')]), which | ||||||||
792 | * people have been using to add a field to an object array without fields | ||||||||
793 | */ | ||||||||
794 | static int | ||||||||
795 | _validate_union_object_dtype(PyArray_Descr *new, PyArray_Descr *conv) | ||||||||
796 | { | ||||||||
797 | PyObject *name, *tup; | ||||||||
798 | PyArray_Descr *dtype; | ||||||||
799 | |||||||||
800 | if (!PyDataType_REFCHK(new)(((new)->flags & (0x01)) == (0x01)) && !PyDataType_REFCHK(conv)(((conv)->flags & (0x01)) == (0x01))) { | ||||||||
801 | return 0; | ||||||||
802 | } | ||||||||
803 | if (PyDataType_HASFIELDS(new)(((PyArray_Descr *)(new))->names != ((void*)0)) || new->kind != 'O') { | ||||||||
804 | goto fail; | ||||||||
805 | } | ||||||||
806 | if (!PyDataType_HASFIELDS(conv)(((PyArray_Descr *)(conv))->names != ((void*)0)) || PyTuple_GET_SIZE(conv->names)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(conv->names ))))->ob_size) != 1) { | ||||||||
807 | goto fail; | ||||||||
808 | } | ||||||||
809 | name = PyTuple_GET_ITEM(conv->names, 0)((((void) (0)), (PyTupleObject *)(conv->names))->ob_item [0]); | ||||||||
810 | if (name == NULL((void*)0)) { | ||||||||
811 | return -1; | ||||||||
812 | } | ||||||||
813 | tup = PyDict_GetItemWithError(conv->fields, name); | ||||||||
814 | if (tup == NULL((void*)0)) { | ||||||||
815 | if (!PyErr_Occurred()) { | ||||||||
816 | /* fields was missing the name it claimed to contain */ | ||||||||
817 | PyErr_BadInternalCall()_PyErr_BadInternalCall("numpy/core/src/multiarray/descriptor.c" , 817); | ||||||||
818 | } | ||||||||
819 | return -1; | ||||||||
820 | } | ||||||||
821 | dtype = (PyArray_Descr *)PyTuple_GET_ITEM(tup, 0)((((void) (0)), (PyTupleObject *)(tup))->ob_item[0]); | ||||||||
822 | if (dtype == NULL((void*)0)) { | ||||||||
823 | return -1; | ||||||||
824 | } | ||||||||
825 | if (dtype->kind != 'O') { | ||||||||
826 | goto fail; | ||||||||
827 | } | ||||||||
828 | return 0; | ||||||||
829 | |||||||||
830 | fail: | ||||||||
831 | PyErr_SetString(PyExc_ValueError, | ||||||||
832 | "dtypes of the form (old_dtype, new_dtype) containing the object " | ||||||||
833 | "dtype are not supported"); | ||||||||
834 | return -1; | ||||||||
835 | } | ||||||||
836 | |||||||||
837 | /* | ||||||||
838 | * A tuple type would be either (generic typeobject, typesize) | ||||||||
839 | * or (fixed-length data-type, shape) | ||||||||
840 | * | ||||||||
841 | * or (inheriting data-type, new-data-type) | ||||||||
842 | * The new data-type must have the same itemsize as the inheriting data-type | ||||||||
843 | * unless the latter is 0 | ||||||||
844 | * | ||||||||
845 | * Thus (int32, {'real':(int16,0),'imag',(int16,2)}) | ||||||||
846 | * | ||||||||
847 | * is one way to specify a descriptor that will give | ||||||||
848 | * a['real'] and a['imag'] to an int32 array. | ||||||||
849 | * | ||||||||
850 | * leave type reference alone | ||||||||
851 | * | ||||||||
852 | * Returns `Py_NotImplemented` if the second tuple item is not | ||||||||
853 | * appropriate. | ||||||||
854 | */ | ||||||||
855 | static PyArray_Descr * | ||||||||
856 | _try_convert_from_inherit_tuple(PyArray_Descr *type, PyObject *newobj) | ||||||||
857 | { | ||||||||
858 | if (PyArray_IsScalar(newobj, Integer)(((((PyObject*)(newobj))->ob_type) == (&PyIntegerArrType_Type ) || PyType_IsSubtype((((PyObject*)(newobj))->ob_type), (& PyIntegerArrType_Type)))) || _is_tuple_of_integers(newobj)) { | ||||||||
859 | /* It's a subarray or flexible type instead */ | ||||||||
860 | Py_INCREF(Py_NotImplemented)_Py_INCREF(((PyObject*)((&_Py_NotImplementedStruct)))); | ||||||||
861 | return (PyArray_Descr *)Py_NotImplemented(&_Py_NotImplementedStruct); | ||||||||
862 | } | ||||||||
863 | PyArray_Descr *conv = _convert_from_any(newobj, 0); | ||||||||
864 | if (conv == NULL((void*)0)) { | ||||||||
865 | /* Let someone else try to convert this */ | ||||||||
866 | PyErr_Clear(); | ||||||||
867 | Py_INCREF(Py_NotImplemented)_Py_INCREF(((PyObject*)((&_Py_NotImplementedStruct)))); | ||||||||
868 | return (PyArray_Descr *)Py_NotImplemented(&_Py_NotImplementedStruct); | ||||||||
869 | } | ||||||||
870 | PyArray_Descr *new = PyArray_DescrNew(type); | ||||||||
871 | if (new == NULL((void*)0)) { | ||||||||
872 | goto fail; | ||||||||
873 | } | ||||||||
874 | if (PyDataType_ISUNSIZED(new)((new)->elsize == 0 && !(((PyArray_Descr *)(new))-> names != ((void*)0)))) { | ||||||||
875 | new->elsize = conv->elsize; | ||||||||
876 | } | ||||||||
877 | else if (new->elsize != conv->elsize) { | ||||||||
878 | PyErr_SetString(PyExc_ValueError, | ||||||||
879 | "mismatch in size of old and new data-descriptor"); | ||||||||
880 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); | ||||||||
881 | goto fail; | ||||||||
882 | } | ||||||||
883 | else if (_validate_union_object_dtype(new, conv) < 0) { | ||||||||
884 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); | ||||||||
885 | goto fail; | ||||||||
886 | } | ||||||||
887 | |||||||||
888 | if (PyDataType_HASFIELDS(conv)(((PyArray_Descr *)(conv))->names != ((void*)0))) { | ||||||||
889 | Py_XDECREF(new->fields)_Py_XDECREF(((PyObject*)(new->fields))); | ||||||||
890 | new->fields = conv->fields; | ||||||||
891 | Py_XINCREF(new->fields)_Py_XINCREF(((PyObject*)(new->fields))); | ||||||||
892 | |||||||||
893 | Py_XDECREF(new->names)_Py_XDECREF(((PyObject*)(new->names))); | ||||||||
894 | new->names = conv->names; | ||||||||
895 | Py_XINCREF(new->names)_Py_XINCREF(((PyObject*)(new->names))); | ||||||||
896 | } | ||||||||
897 | if (conv->metadata != NULL((void*)0)) { | ||||||||
898 | Py_XDECREF(new->metadata)_Py_XDECREF(((PyObject*)(new->metadata))); | ||||||||
899 | new->metadata = conv->metadata; | ||||||||
900 | Py_XINCREF(new->metadata)_Py_XINCREF(((PyObject*)(new->metadata))); | ||||||||
901 | } | ||||||||
902 | /* | ||||||||
903 | * Certain flags must be inherited from the fields. This is needed | ||||||||
904 | * only for void dtypes (or subclasses of it such as a record dtype). | ||||||||
905 | * For other dtypes, the field part will only be used for direct field | ||||||||
906 | * access and thus flag inheritance should not be necessary. | ||||||||
907 | * (We only allow object fields if the dtype is object as well.) | ||||||||
908 | * This ensures copying over of the NPY_FROM_FIELDS "inherited" flags. | ||||||||
909 | */ | ||||||||
910 | if (new->type_num == NPY_VOID) { | ||||||||
911 | new->flags = conv->flags; | ||||||||
912 | } | ||||||||
913 | Py_DECREF(conv)_Py_DECREF(((PyObject*)(conv))); | ||||||||
914 | return new; | ||||||||
915 | |||||||||
916 | fail: | ||||||||
917 | Py_DECREF(conv)_Py_DECREF(((PyObject*)(conv))); | ||||||||
918 | return NULL((void*)0); | ||||||||
919 | } | ||||||||
920 | |||||||||
921 | /* | ||||||||
922 | * Validates that any field of the structured array 'dtype' which has | ||||||||
923 | * the NPY_ITEM_HASOBJECT flag set does not overlap with another field. | ||||||||
924 | * | ||||||||
925 | * This algorithm is worst case O(n^2). It could be done with a sort | ||||||||
926 | * and sweep algorithm, but the structured dtype representation is | ||||||||
927 | * rather ugly right now, so writing something better can wait until | ||||||||
928 | * that representation is made sane. | ||||||||
929 | * | ||||||||
930 | * Returns 0 on success, -1 if an exception is raised. | ||||||||
931 | */ | ||||||||
932 | static int | ||||||||
933 | _validate_object_field_overlap(PyArray_Descr *dtype) | ||||||||
934 | { | ||||||||
935 | PyObject *names, *fields, *key, *tup, *title; | ||||||||
936 | Py_ssize_t i, j, names_size; | ||||||||
937 | PyArray_Descr *fld_dtype, *fld2_dtype; | ||||||||
938 | int fld_offset, fld2_offset; | ||||||||
939 | |||||||||
940 | /* Get some properties from the dtype */ | ||||||||
941 | names = dtype->names; | ||||||||
942 | names_size = PyTuple_GET_SIZE(names)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(names))))-> ob_size); | ||||||||
943 | fields = dtype->fields; | ||||||||
944 | |||||||||
945 | for (i = 0; i < names_size; ++i) { | ||||||||
946 | key = PyTuple_GET_ITEM(names, i)((((void) (0)), (PyTupleObject *)(names))->ob_item[i]); | ||||||||
947 | if (key == NULL((void*)0)) { | ||||||||
948 | return -1; | ||||||||
949 | } | ||||||||
950 | tup = PyDict_GetItemWithError(fields, key); | ||||||||
951 | if (tup == NULL((void*)0)) { | ||||||||
952 | if (!PyErr_Occurred()) { | ||||||||
953 | /* fields was missing the name it claimed to contain */ | ||||||||
954 | PyErr_BadInternalCall()_PyErr_BadInternalCall("numpy/core/src/multiarray/descriptor.c" , 954); | ||||||||
955 | } | ||||||||
956 | return -1; | ||||||||
957 | } | ||||||||
958 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(tup, "Oi|O", &fld_dtype, &fld_offset, &title)) { | ||||||||
959 | return -1; | ||||||||
960 | } | ||||||||
961 | |||||||||
962 | /* If this field has objects, check for overlaps */ | ||||||||
963 | if (PyDataType_REFCHK(fld_dtype)(((fld_dtype)->flags & (0x01)) == (0x01))) { | ||||||||
964 | for (j = 0; j < names_size; ++j) { | ||||||||
965 | if (i != j) { | ||||||||
966 | key = PyTuple_GET_ITEM(names, j)((((void) (0)), (PyTupleObject *)(names))->ob_item[j]); | ||||||||
967 | if (key == NULL((void*)0)) { | ||||||||
968 | return -1; | ||||||||
969 | } | ||||||||
970 | tup = PyDict_GetItemWithError(fields, key); | ||||||||
971 | if (tup == NULL((void*)0)) { | ||||||||
972 | if (!PyErr_Occurred()) { | ||||||||
973 | /* fields was missing the name it claimed to contain */ | ||||||||
974 | PyErr_BadInternalCall()_PyErr_BadInternalCall("numpy/core/src/multiarray/descriptor.c" , 974); | ||||||||
975 | } | ||||||||
976 | return -1; | ||||||||
977 | } | ||||||||
978 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(tup, "Oi|O", &fld2_dtype, | ||||||||
979 | &fld2_offset, &title)) { | ||||||||
980 | return -1; | ||||||||
981 | } | ||||||||
982 | /* Raise an exception if it overlaps */ | ||||||||
983 | if (fld_offset < fld2_offset + fld2_dtype->elsize && | ||||||||
984 | fld2_offset < fld_offset + fld_dtype->elsize) { | ||||||||
985 | PyErr_SetString(PyExc_TypeError, | ||||||||
986 | "Cannot create a NumPy dtype with overlapping " | ||||||||
987 | "object fields"); | ||||||||
988 | return -1; | ||||||||
989 | } | ||||||||
990 | } | ||||||||
991 | } | ||||||||
992 | } | ||||||||
993 | } | ||||||||
994 | |||||||||
995 | /* It passed all the overlap tests */ | ||||||||
996 | return 0; | ||||||||
997 | } | ||||||||
998 | |||||||||
999 | /* | ||||||||
1000 | * a dictionary specifying a data-type | ||||||||
1001 | * must have at least two and up to four | ||||||||
1002 | * keys These must all be sequences of the same length. | ||||||||
1003 | * | ||||||||
1004 | * can also have an additional key called "metadata" which can be any dictionary | ||||||||
1005 | * | ||||||||
1006 | * "names" --- field names | ||||||||
1007 | * "formats" --- the data-type descriptors for the field. | ||||||||
1008 | * | ||||||||
1009 | * Optional: | ||||||||
1010 | * | ||||||||
1011 | * "offsets" --- integers indicating the offset into the | ||||||||
1012 | * record of the start of the field. | ||||||||
1013 | * if not given, then "consecutive offsets" | ||||||||
1014 | * will be assumed and placed in the dictionary. | ||||||||
1015 | * | ||||||||
1016 | * "titles" --- Allows the use of an additional key | ||||||||
1017 | * for the fields dictionary.(if these are strings | ||||||||
1018 | * or unicode objects) or | ||||||||
1019 | * this can also be meta-data to | ||||||||
1020 | * be passed around with the field description. | ||||||||
1021 | * | ||||||||
1022 | * Attribute-lookup-based field names merely has to query the fields | ||||||||
1023 | * dictionary of the data-descriptor. Any result present can be used | ||||||||
1024 | * to return the correct field. | ||||||||
1025 | * | ||||||||
1026 | * So, the notion of what is a name and what is a title is really quite | ||||||||
1027 | * arbitrary. | ||||||||
1028 | * | ||||||||
1029 | * What does distinguish a title, however, is that if it is not None, | ||||||||
1030 | * it will be placed at the end of the tuple inserted into the | ||||||||
1031 | * fields dictionary.and can therefore be used to carry meta-data around. | ||||||||
1032 | * | ||||||||
1033 | * If the dictionary does not have "names" and "formats" entries, | ||||||||
1034 | * then it will be checked for conformity and used directly. | ||||||||
1035 | */ | ||||||||
1036 | static PyArray_Descr * | ||||||||
1037 | _convert_from_field_dict(PyObject *obj, int align) | ||||||||
1038 | { | ||||||||
1039 | PyObject *_numpy_internal; | ||||||||
1040 | PyArray_Descr *res; | ||||||||
1041 | |||||||||
1042 | _numpy_internal = PyImport_ImportModule("numpy.core._internal"); | ||||||||
1043 | if (_numpy_internal == NULL((void*)0)) { | ||||||||
1044 | return NULL((void*)0); | ||||||||
1045 | } | ||||||||
1046 | res = (PyArray_Descr *)PyObject_CallMethod_PyObject_CallMethod_SizeT(_numpy_internal, | ||||||||
1047 | "_usefields", "Oi", obj, align); | ||||||||
1048 | Py_DECREF(_numpy_internal)_Py_DECREF(((PyObject*)(_numpy_internal))); | ||||||||
1049 | return res; | ||||||||
1050 | } | ||||||||
1051 | |||||||||
1052 | /* | ||||||||
1053 | * Creates a struct dtype object from a Python dictionary. | ||||||||
1054 | */ | ||||||||
1055 | static PyArray_Descr * | ||||||||
1056 | _convert_from_dict(PyObject *obj, int align) | ||||||||
1057 | { | ||||||||
1058 | PyObject *fields = PyDict_New(); | ||||||||
1059 | if (fields == NULL((void*)0)) { | ||||||||
1060 | return (PyArray_Descr *)PyErr_NoMemory(); | ||||||||
1061 | } | ||||||||
1062 | /* | ||||||||
1063 | * Use PyMapping_GetItemString to support dictproxy objects as well. | ||||||||
1064 | */ | ||||||||
1065 | PyObject *names = PyMapping_GetItemString(obj, "names"); | ||||||||
1066 | if (names == NULL((void*)0)) { | ||||||||
1067 | Py_DECREF(fields)_Py_DECREF(((PyObject*)(fields))); | ||||||||
1068 | /* XXX should check this is a KeyError */ | ||||||||
1069 | PyErr_Clear(); | ||||||||
1070 | return _convert_from_field_dict(obj, align); | ||||||||
1071 | } | ||||||||
1072 | PyObject *descrs = PyMapping_GetItemString(obj, "formats"); | ||||||||
1073 | if (descrs == NULL((void*)0)) { | ||||||||
1074 | Py_DECREF(fields)_Py_DECREF(((PyObject*)(fields))); | ||||||||
1075 | /* XXX should check this is a KeyError */ | ||||||||
1076 | PyErr_Clear(); | ||||||||
1077 | Py_DECREF(names)_Py_DECREF(((PyObject*)(names))); | ||||||||
1078 | return _convert_from_field_dict(obj, align); | ||||||||
1079 | } | ||||||||
1080 | int n = PyObject_LengthPyObject_Size(names); | ||||||||
1081 | PyObject *offsets = PyMapping_GetItemString(obj, "offsets"); | ||||||||
1082 | if (!offsets) { | ||||||||
1083 | PyErr_Clear(); | ||||||||
1084 | } | ||||||||
1085 | PyObject *titles = PyMapping_GetItemString(obj, "titles"); | ||||||||
1086 | if (!titles) { | ||||||||
1087 | PyErr_Clear(); | ||||||||
1088 | } | ||||||||
1089 | |||||||||
1090 | if ((n > PyObject_LengthPyObject_Size(descrs)) | ||||||||
1091 | || (offsets && (n > PyObject_LengthPyObject_Size(offsets))) | ||||||||
1092 | || (titles && (n > PyObject_LengthPyObject_Size(titles)))) { | ||||||||
1093 | PyErr_SetString(PyExc_ValueError, | ||||||||
1094 | "'names', 'formats', 'offsets', and 'titles' dict " | ||||||||
1095 | "entries must have the same length"); | ||||||||
1096 | goto fail; | ||||||||
1097 | } | ||||||||
1098 | |||||||||
1099 | /* | ||||||||
1100 | * If a property 'aligned' is in the dict, it overrides the align flag | ||||||||
1101 | * to be True if it not already true. | ||||||||
1102 | */ | ||||||||
1103 | PyObject *tmp = PyMapping_GetItemString(obj, "aligned"); | ||||||||
1104 | if (tmp == NULL((void*)0)) { | ||||||||
1105 | PyErr_Clear(); | ||||||||
1106 | } else { | ||||||||
1107 | if (tmp == Py_True((PyObject *) &_Py_TrueStruct)) { | ||||||||
1108 | align = 1; | ||||||||
1109 | } | ||||||||
1110 | else if (tmp != Py_False((PyObject *) &_Py_FalseStruct)) { | ||||||||
1111 | Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp))); | ||||||||
1112 | PyErr_SetString(PyExc_ValueError, | ||||||||
1113 | "NumPy dtype descriptor includes 'aligned' entry, " | ||||||||
1114 | "but its value is neither True nor False"); | ||||||||
1115 | goto fail; | ||||||||
1116 | } | ||||||||
1117 | Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp))); | ||||||||
1118 | } | ||||||||
1119 | |||||||||
1120 | /* Types with fields need the Python C API for field access */ | ||||||||
1121 | char dtypeflags = NPY_NEEDS_PYAPI0x10; | ||||||||
1122 | int totalsize = 0; | ||||||||
1123 | int maxalign = 0; | ||||||||
1124 | int has_out_of_order_fields = 0; | ||||||||
1125 | for (int i = 0; i < n; i++) { | ||||||||
1126 | /* Build item to insert (descr, offset, [title])*/ | ||||||||
1127 | int len = 2; | ||||||||
1128 | PyObject *title = NULL((void*)0); | ||||||||
1129 | PyObject *ind = PyLong_FromLong(i); | ||||||||
1130 | if (titles) { | ||||||||
1131 | title=PyObject_GetItem(titles, ind); | ||||||||
1132 | if (title && title != Py_None(&_Py_NoneStruct)) { | ||||||||
1133 | len = 3; | ||||||||
1134 | } | ||||||||
1135 | else { | ||||||||
1136 | Py_XDECREF(title)_Py_XDECREF(((PyObject*)(title))); | ||||||||
1137 | } | ||||||||
1138 | PyErr_Clear(); | ||||||||
1139 | } | ||||||||
1140 | PyObject *tup = PyTuple_New(len); | ||||||||
1141 | PyObject *descr = PyObject_GetItem(descrs, ind); | ||||||||
1142 | if (!descr) { | ||||||||
1143 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||||
1144 | Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind))); | ||||||||
1145 | goto fail; | ||||||||
1146 | } | ||||||||
1147 | PyArray_Descr *newdescr = _convert_from_any(descr, align); | ||||||||
1148 | Py_DECREF(descr)_Py_DECREF(((PyObject*)(descr))); | ||||||||
1149 | if (newdescr == NULL((void*)0)) { | ||||||||
1150 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||||
1151 | Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind))); | ||||||||
1152 | goto fail; | ||||||||
1153 | } | ||||||||
1154 | PyTuple_SET_ITEM(tup, 0, (PyObject *)newdescr)PyTuple_SetItem(tup, 0, (PyObject *)newdescr); | ||||||||
1155 | int _align = 1; | ||||||||
1156 | if (align) { | ||||||||
1157 | _align = newdescr->alignment; | ||||||||
1158 | maxalign = PyArray_MAX(maxalign,_align)(((maxalign)>(_align))?(maxalign):(_align)); | ||||||||
1159 | } | ||||||||
1160 | if (offsets) { | ||||||||
1161 | PyObject *off = PyObject_GetItem(offsets, ind); | ||||||||
1162 | if (!off) { | ||||||||
1163 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||||
1164 | Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind))); | ||||||||
1165 | goto fail; | ||||||||
1166 | } | ||||||||
1167 | long offset = PyArray_PyIntAsInt(off); | ||||||||
1168 | if (error_converting(offset)(((offset) == -1) && PyErr_Occurred())) { | ||||||||
1169 | Py_DECREF(off)_Py_DECREF(((PyObject*)(off))); | ||||||||
1170 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||||
1171 | Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind))); | ||||||||
1172 | goto fail; | ||||||||
1173 | } | ||||||||
1174 | Py_DECREF(off)_Py_DECREF(((PyObject*)(off))); | ||||||||
1175 | if (offset < 0) { | ||||||||
1176 | PyErr_Format(PyExc_ValueError, "offset %ld cannot be negative", | ||||||||
1177 | offset); | ||||||||
1178 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||||
1179 | Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind))); | ||||||||
1180 | goto fail; | ||||||||
1181 | } | ||||||||
1182 | |||||||||
1183 | PyTuple_SET_ITEM(tup, 1, PyLong_FromLong(offset))PyTuple_SetItem(tup, 1, PyLong_FromLong(offset)); | ||||||||
1184 | /* Flag whether the fields are specified out of order */ | ||||||||
1185 | if (offset < totalsize) { | ||||||||
1186 | has_out_of_order_fields = 1; | ||||||||
1187 | } | ||||||||
1188 | /* If align=True, enforce field alignment */ | ||||||||
1189 | if (align && offset % newdescr->alignment != 0) { | ||||||||
1190 | PyErr_Format(PyExc_ValueError, | ||||||||
1191 | "offset %ld for NumPy dtype with fields is " | ||||||||
1192 | "not divisible by the field alignment %d " | ||||||||
1193 | "with align=True", | ||||||||
1194 | offset, newdescr->alignment); | ||||||||
1195 | Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind))); | ||||||||
1196 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||||
1197 | goto fail; | ||||||||
1198 | } | ||||||||
1199 | else if (offset + newdescr->elsize > totalsize) { | ||||||||
1200 | totalsize = offset + newdescr->elsize; | ||||||||
1201 | } | ||||||||
1202 | } | ||||||||
1203 | else { | ||||||||
1204 | if (align && _align > 1) { | ||||||||
1205 | totalsize = NPY_NEXT_ALIGNED_OFFSET(totalsize, _align)(((totalsize) + (_align) - 1) & (-(_align))); | ||||||||
1206 | } | ||||||||
1207 | PyTuple_SET_ITEM(tup, 1, PyLong_FromLong(totalsize))PyTuple_SetItem(tup, 1, PyLong_FromLong(totalsize)); | ||||||||
1208 | totalsize += newdescr->elsize; | ||||||||
1209 | } | ||||||||
1210 | if (len == 3) { | ||||||||
1211 | PyTuple_SET_ITEM(tup, 2, title)PyTuple_SetItem(tup, 2, title); | ||||||||
1212 | } | ||||||||
1213 | PyObject *name = PyObject_GetItem(names, ind); | ||||||||
1214 | Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind))); | ||||||||
1215 | if (!name) { | ||||||||
1216 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||||
1217 | goto fail; | ||||||||
1218 | } | ||||||||
1219 | if (!PyUnicode_Check(name)((((((PyObject*)(name))->ob_type))->tp_flags & ((1UL << 28))) != 0)) { | ||||||||
1220 | PyErr_SetString(PyExc_ValueError, | ||||||||
1221 | "field names must be strings"); | ||||||||
1222 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||||
1223 | goto fail; | ||||||||
1224 | } | ||||||||
1225 | |||||||||
1226 | /* Insert into dictionary */ | ||||||||
1227 | if (PyDict_GetItemWithError(fields, name) != NULL((void*)0)) { | ||||||||
1228 | PyErr_SetString(PyExc_ValueError, | ||||||||
1229 | "name already used as a name or title"); | ||||||||
1230 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||||
1231 | goto fail; | ||||||||
1232 | } | ||||||||
1233 | else if (PyErr_Occurred()) { | ||||||||
1234 | /* MemoryError during dict lookup */ | ||||||||
1235 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||||
1236 | goto fail; | ||||||||
1237 | } | ||||||||
1238 | int ret = PyDict_SetItem(fields, name, tup); | ||||||||
1239 | Py_DECREF(name)_Py_DECREF(((PyObject*)(name))); | ||||||||
1240 | if (ret < 0) { | ||||||||
1241 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||||
1242 | goto fail; | ||||||||
1243 | } | ||||||||
1244 | if (len == 3) { | ||||||||
1245 | if (PyUnicode_Check(title)((((((PyObject*)(title))->ob_type))->tp_flags & ((1UL << 28))) != 0)) { | ||||||||
1246 | if (PyDict_GetItemWithError(fields, title) != NULL((void*)0)) { | ||||||||
1247 | PyErr_SetString(PyExc_ValueError, | ||||||||
1248 | "title already used as a name or title."); | ||||||||
1249 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||||
1250 | goto fail; | ||||||||
1251 | } | ||||||||
1252 | else if (PyErr_Occurred()) { | ||||||||
1253 | /* MemoryError during dict lookup */ | ||||||||
1254 | goto fail; | ||||||||
1255 | } | ||||||||
1256 | if (PyDict_SetItem(fields, title, tup) < 0) { | ||||||||
1257 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||||
1258 | goto fail; | ||||||||
1259 | } | ||||||||
1260 | } | ||||||||
1261 | } | ||||||||
1262 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||||
1263 | dtypeflags |= (newdescr->flags & NPY_FROM_FIELDS(0x08 | 0x02 | 0x01 | 0x10)); | ||||||||
1264 | } | ||||||||
1265 | |||||||||
1266 | PyArray_Descr *new = PyArray_DescrNewFromType(NPY_VOID); | ||||||||
1267 | if (new == NULL((void*)0)) { | ||||||||
1268 | goto fail; | ||||||||
1269 | } | ||||||||
1270 | if (maxalign > 1) { | ||||||||
1271 | totalsize = NPY_NEXT_ALIGNED_OFFSET(totalsize, maxalign)(((totalsize) + (maxalign) - 1) & (-(maxalign))); | ||||||||
1272 | } | ||||||||
1273 | if (align) { | ||||||||
1274 | new->alignment = maxalign; | ||||||||
1275 | } | ||||||||
1276 | new->elsize = totalsize; | ||||||||
1277 | if (!PyTuple_Check(names)((((((PyObject*)(names))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { | ||||||||
1278 | Py_SETREF(names, PySequence_Tuple(names))do { PyObject *_py_tmp = ((PyObject*)(names)); (names) = (PySequence_Tuple (names)); _Py_DECREF(((PyObject*)(_py_tmp))); } while (0); | ||||||||
1279 | if (names == NULL((void*)0)) { | ||||||||
1280 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); | ||||||||
1281 | goto fail; | ||||||||
1282 | } | ||||||||
1283 | } | ||||||||
1284 | new->names = names; | ||||||||
1285 | new->fields = fields; | ||||||||
1286 | new->flags = dtypeflags; | ||||||||
1287 | /* new takes responsibility for DECREFing names, fields */ | ||||||||
1288 | names = NULL((void*)0); | ||||||||
1289 | fields = NULL((void*)0); | ||||||||
1290 | |||||||||
1291 | /* | ||||||||
1292 | * If the fields weren't in order, and there was an OBJECT type, | ||||||||
1293 | * need to verify that no OBJECT types overlap with something else. | ||||||||
1294 | */ | ||||||||
1295 | if (has_out_of_order_fields && PyDataType_REFCHK(new)(((new)->flags & (0x01)) == (0x01))) { | ||||||||
1296 | if (_validate_object_field_overlap(new) < 0) { | ||||||||
1297 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); | ||||||||
1298 | goto fail; | ||||||||
1299 | } | ||||||||
1300 | } | ||||||||
1301 | |||||||||
1302 | /* Structured arrays get a sticky aligned bit */ | ||||||||
1303 | if (align) { | ||||||||
1304 | new->flags |= NPY_ALIGNED_STRUCT0x80; | ||||||||
1305 | } | ||||||||
1306 | |||||||||
1307 | /* Override the itemsize if provided */ | ||||||||
1308 | tmp = PyMapping_GetItemString(obj, "itemsize"); | ||||||||
1309 | if (tmp == NULL((void*)0)) { | ||||||||
1310 | PyErr_Clear(); | ||||||||
1311 | } else { | ||||||||
1312 | int itemsize = (int)PyArray_PyIntAsInt(tmp); | ||||||||
1313 | Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp))); | ||||||||
1314 | if (error_converting(itemsize)(((itemsize) == -1) && PyErr_Occurred())) { | ||||||||
1315 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); | ||||||||
1316 | goto fail; | ||||||||
1317 | } | ||||||||
1318 | /* Make sure the itemsize isn't made too small */ | ||||||||
1319 | if (itemsize < new->elsize) { | ||||||||
1320 | PyErr_Format(PyExc_ValueError, | ||||||||
1321 | "NumPy dtype descriptor requires %d bytes, " | ||||||||
1322 | "cannot override to smaller itemsize of %d", | ||||||||
1323 | new->elsize, itemsize); | ||||||||
1324 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); | ||||||||
1325 | goto fail; | ||||||||
1326 | } | ||||||||
1327 | /* If align is set, make sure the alignment divides into the size */ | ||||||||
1328 | if (align && itemsize % new->alignment != 0) { | ||||||||
1329 | PyErr_Format(PyExc_ValueError, | ||||||||
1330 | "NumPy dtype descriptor requires alignment of %d bytes, " | ||||||||
1331 | "which is not divisible into the specified itemsize %d", | ||||||||
1332 | new->alignment, itemsize); | ||||||||
1333 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); | ||||||||
1334 | goto fail; | ||||||||
1335 | } | ||||||||
1336 | /* Set the itemsize */ | ||||||||
1337 | new->elsize = itemsize; | ||||||||
1338 | } | ||||||||
1339 | |||||||||
1340 | /* Add the metadata if provided */ | ||||||||
1341 | PyObject *metadata = PyMapping_GetItemString(obj, "metadata"); | ||||||||
1342 | |||||||||
1343 | if (metadata == NULL((void*)0)) { | ||||||||
1344 | PyErr_Clear(); | ||||||||
1345 | } | ||||||||
1346 | else if (new->metadata == NULL((void*)0)) { | ||||||||
1347 | new->metadata = metadata; | ||||||||
1348 | } | ||||||||
1349 | else { | ||||||||
1350 | int ret = PyDict_Merge(new->metadata, metadata, 0); | ||||||||
1351 | Py_DECREF(metadata)_Py_DECREF(((PyObject*)(metadata))); | ||||||||
1352 | if (ret < 0) { | ||||||||
1353 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); | ||||||||
1354 | goto fail; | ||||||||
1355 | } | ||||||||
1356 | } | ||||||||
1357 | |||||||||
1358 | Py_XDECREF(fields)_Py_XDECREF(((PyObject*)(fields))); | ||||||||
1359 | Py_XDECREF(names)_Py_XDECREF(((PyObject*)(names))); | ||||||||
1360 | Py_XDECREF(descrs)_Py_XDECREF(((PyObject*)(descrs))); | ||||||||
1361 | Py_XDECREF(offsets)_Py_XDECREF(((PyObject*)(offsets))); | ||||||||
1362 | Py_XDECREF(titles)_Py_XDECREF(((PyObject*)(titles))); | ||||||||
1363 | return new; | ||||||||
1364 | |||||||||
1365 | fail: | ||||||||
1366 | Py_XDECREF(fields)_Py_XDECREF(((PyObject*)(fields))); | ||||||||
1367 | Py_XDECREF(names)_Py_XDECREF(((PyObject*)(names))); | ||||||||
1368 | Py_XDECREF(descrs)_Py_XDECREF(((PyObject*)(descrs))); | ||||||||
1369 | Py_XDECREF(offsets)_Py_XDECREF(((PyObject*)(offsets))); | ||||||||
1370 | Py_XDECREF(titles)_Py_XDECREF(((PyObject*)(titles))); | ||||||||
1371 | return NULL((void*)0); | ||||||||
1372 | } | ||||||||
1373 | |||||||||
1374 | |||||||||
1375 | /*NUMPY_API*/ | ||||||||
1376 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyArray_Descr * | ||||||||
1377 | PyArray_DescrNewFromType(int type_num) | ||||||||
1378 | { | ||||||||
1379 | PyArray_Descr *old; | ||||||||
1380 | PyArray_Descr *new; | ||||||||
1381 | |||||||||
1382 | old = PyArray_DescrFromType(type_num); | ||||||||
1383 | new = PyArray_DescrNew(old); | ||||||||
1384 | Py_DECREF(old)_Py_DECREF(((PyObject*)(old))); | ||||||||
1385 | return new; | ||||||||
1386 | } | ||||||||
1387 | |||||||||
1388 | /*NUMPY_API | ||||||||
1389 | * Get typenum from an object -- None goes to NULL | ||||||||
1390 | */ | ||||||||
1391 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) int | ||||||||
1392 | PyArray_DescrConverter2(PyObject *obj, PyArray_Descr **at) | ||||||||
1393 | { | ||||||||
1394 | if (obj == Py_None(&_Py_NoneStruct)) { | ||||||||
1395 | *at = NULL((void*)0); | ||||||||
1396 | return NPY_SUCCEED1; | ||||||||
1397 | } | ||||||||
1398 | else { | ||||||||
1399 | return PyArray_DescrConverter(obj, at); | ||||||||
1400 | } | ||||||||
1401 | } | ||||||||
1402 | |||||||||
1403 | /** | ||||||||
1404 | * Get a dtype instance from a python type | ||||||||
1405 | */ | ||||||||
1406 | static PyArray_Descr * | ||||||||
1407 | _convert_from_type(PyObject *obj) { | ||||||||
1408 | PyTypeObject *typ = (PyTypeObject*)obj; | ||||||||
1409 | |||||||||
1410 | if (PyType_IsSubtype(typ, &PyGenericArrType_Type)) { | ||||||||
1411 | return PyArray_DescrFromTypeObject(obj); | ||||||||
1412 | } | ||||||||
1413 | else if (typ == &PyLong_Type) { | ||||||||
1414 | return PyArray_DescrFromType(NPY_LONG); | ||||||||
1415 | } | ||||||||
1416 | else if (typ == &PyFloat_Type) { | ||||||||
1417 | return PyArray_DescrFromType(NPY_DOUBLE); | ||||||||
1418 | } | ||||||||
1419 | else if (typ == &PyComplex_Type) { | ||||||||
1420 | return PyArray_DescrFromType(NPY_CDOUBLE); | ||||||||
1421 | } | ||||||||
1422 | else if (typ == &PyBool_Type) { | ||||||||
1423 | return PyArray_DescrFromType(NPY_BOOL); | ||||||||
1424 | } | ||||||||
1425 | else if (typ == &PyBytes_Type) { | ||||||||
1426 | /* | ||||||||
1427 | * TODO: This should be deprecated, and have special handling for | ||||||||
1428 | * dtype=bytes/"S" in coercion: It should not rely on "S0". | ||||||||
1429 | */ | ||||||||
1430 | return PyArray_DescrFromType(NPY_STRING); | ||||||||
1431 | } | ||||||||
1432 | else if (typ == &PyUnicode_Type) { | ||||||||
1433 | /* | ||||||||
1434 | * TODO: This should be deprecated, and have special handling for | ||||||||
1435 | * dtype=str/"U" in coercion: It should not rely on "U0". | ||||||||
1436 | */ | ||||||||
1437 | return PyArray_DescrFromType(NPY_UNICODE); | ||||||||
1438 | } | ||||||||
1439 | else if (typ == &PyMemoryView_Type) { | ||||||||
1440 | return PyArray_DescrFromType(NPY_VOID); | ||||||||
1441 | } | ||||||||
1442 | else if (typ == &PyBaseObject_Type) { | ||||||||
1443 | return PyArray_DescrFromType(NPY_OBJECT); | ||||||||
1444 | } | ||||||||
1445 | else { | ||||||||
1446 | PyArray_Descr *ret = _try_convert_from_dtype_attr(obj); | ||||||||
1447 | if ((PyObject *)ret != Py_NotImplemented(&_Py_NotImplementedStruct)) { | ||||||||
1448 | return ret; | ||||||||
1449 | } | ||||||||
1450 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | ||||||||
1451 | |||||||||
1452 | /* | ||||||||
1453 | * Note: this comes after _try_convert_from_dtype_attr because the ctypes | ||||||||
1454 | * type might override the dtype if numpy does not otherwise | ||||||||
1455 | * support it. | ||||||||
1456 | */ | ||||||||
1457 | ret = _try_convert_from_ctypes_type(typ); | ||||||||
1458 | if ((PyObject *)ret != Py_NotImplemented(&_Py_NotImplementedStruct)) { | ||||||||
1459 | return ret; | ||||||||
1460 | } | ||||||||
1461 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | ||||||||
1462 | |||||||||
1463 | /* | ||||||||
1464 | * All other classes are treated as object. This can be convenient | ||||||||
1465 | * to convey an intention of using it for a specific python type | ||||||||
1466 | * and possibly allow converting to a new type-specific dtype in the future. It may make sense to | ||||||||
1467 | * only allow this only within `dtype=...` keyword argument context | ||||||||
1468 | * in the future. | ||||||||
1469 | */ | ||||||||
1470 | return PyArray_DescrFromType(NPY_OBJECT); | ||||||||
1471 | } | ||||||||
1472 | } | ||||||||
1473 | |||||||||
1474 | |||||||||
1475 | static PyArray_Descr * | ||||||||
1476 | _convert_from_str(PyObject *obj, int align); | ||||||||
1477 | |||||||||
1478 | static PyArray_Descr * | ||||||||
1479 | _convert_from_any(PyObject *obj, int align) | ||||||||
1480 | { | ||||||||
1481 | /* default */ | ||||||||
1482 | if (obj == Py_None(&_Py_NoneStruct)) { | ||||||||
1483 | return PyArray_DescrFromType(NPY_DEFAULT_TYPENPY_DOUBLE); | ||||||||
1484 | } | ||||||||
1485 | else if (PyArray_DescrCheck(obj)((((PyObject*)(obj))->ob_type) == (&(*(PyTypeObject *) (&PyArrayDescr_TypeFull))) || PyType_IsSubtype((((PyObject *)(obj))->ob_type), (&(*(PyTypeObject *)(&PyArrayDescr_TypeFull )))))) { | ||||||||
1486 | PyArray_Descr *ret = (PyArray_Descr *)obj; | ||||||||
1487 | Py_INCREF(ret)_Py_INCREF(((PyObject*)(ret))); | ||||||||
1488 | return ret; | ||||||||
1489 | } | ||||||||
1490 | else if (PyType_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL << 31))) != 0)) { | ||||||||
1491 | return _convert_from_type(obj); | ||||||||
1492 | } | ||||||||
1493 | /* or a typecode string */ | ||||||||
1494 | else if (PyBytes_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL << 27))) != 0)) { | ||||||||
1495 | /* Allow bytes format strings: convert to unicode */ | ||||||||
1496 | PyObject *obj2 = PyUnicode_FromEncodedObject(obj, NULL((void*)0), NULL((void*)0)); | ||||||||
1497 | if (obj2 == NULL((void*)0)) { | ||||||||
1498 | /* Convert the exception into a TypeError */ | ||||||||
1499 | if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { | ||||||||
1500 | PyErr_SetString(PyExc_TypeError, | ||||||||
1501 | "data type not understood"); | ||||||||
1502 | } | ||||||||
1503 | return NULL((void*)0); | ||||||||
1504 | } | ||||||||
1505 | PyArray_Descr *ret = _convert_from_str(obj2, align); | ||||||||
1506 | Py_DECREF(obj2)_Py_DECREF(((PyObject*)(obj2))); | ||||||||
1507 | return ret; | ||||||||
1508 | } | ||||||||
1509 | else if (PyUnicode_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL << 28))) != 0)) { | ||||||||
1510 | return _convert_from_str(obj, align); | ||||||||
1511 | } | ||||||||
1512 | else if (PyTuple_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { | ||||||||
1513 | /* or a tuple */ | ||||||||
1514 | if (Py_EnterRecursiveCall(((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit ) && _Py_CheckRecursiveCall(" while trying to convert the given data type from" " a tuple object")) | ||||||||
1515 | " while trying to convert the given data type from"((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit ) && _Py_CheckRecursiveCall(" while trying to convert the given data type from" " a tuple object")) | ||||||||
1516 | " a tuple object" )((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit ) && _Py_CheckRecursiveCall(" while trying to convert the given data type from" " a tuple object")) != 0) { | ||||||||
1517 | return NULL((void*)0); | ||||||||
1518 | } | ||||||||
1519 | PyArray_Descr *ret = _convert_from_tuple(obj, align); | ||||||||
1520 | Py_LeaveRecursiveCall()do{ if((--(PyThreadState_Get()->recursion_depth) < (((_Py_CheckRecursionLimit ) > 200) ? ((_Py_CheckRecursionLimit) - 50) : (3 * ((_Py_CheckRecursionLimit ) >> 2))))) PyThreadState_Get()->overflowed = 0; } while (0); | ||||||||
1521 | return ret; | ||||||||
1522 | } | ||||||||
1523 | else if (PyList_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL << 25))) != 0)) { | ||||||||
1524 | /* or a list */ | ||||||||
1525 | if (Py_EnterRecursiveCall(((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit ) && _Py_CheckRecursiveCall(" while trying to convert the given data type from" " a list object")) | ||||||||
1526 | " while trying to convert the given data type from"((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit ) && _Py_CheckRecursiveCall(" while trying to convert the given data type from" " a list object")) | ||||||||
1527 | " a list object" )((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit ) && _Py_CheckRecursiveCall(" while trying to convert the given data type from" " a list object")) != 0) { | ||||||||
1528 | return NULL((void*)0); | ||||||||
1529 | } | ||||||||
1530 | PyArray_Descr *ret = _convert_from_array_descr(obj, align); | ||||||||
1531 | Py_LeaveRecursiveCall()do{ if((--(PyThreadState_Get()->recursion_depth) < (((_Py_CheckRecursionLimit ) > 200) ? ((_Py_CheckRecursionLimit) - 50) : (3 * ((_Py_CheckRecursionLimit ) >> 2))))) PyThreadState_Get()->overflowed = 0; } while (0); | ||||||||
1532 | return ret; | ||||||||
1533 | } | ||||||||
1534 | else if (PyDict_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL << 29))) != 0) || PyDictProxy_Check(obj)((((PyObject*)(obj))->ob_type) == &PyDictProxy_Type)) { | ||||||||
1535 | /* or a dictionary */ | ||||||||
1536 | if (Py_EnterRecursiveCall(((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit ) && _Py_CheckRecursiveCall(" while trying to convert the given data type from" " a dict object")) | ||||||||
1537 | " while trying to convert the given data type from"((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit ) && _Py_CheckRecursiveCall(" while trying to convert the given data type from" " a dict object")) | ||||||||
1538 | " a dict object" )((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit ) && _Py_CheckRecursiveCall(" while trying to convert the given data type from" " a dict object")) != 0) { | ||||||||
1539 | return NULL((void*)0); | ||||||||
1540 | } | ||||||||
1541 | PyArray_Descr *ret = _convert_from_dict(obj, align); | ||||||||
1542 | Py_LeaveRecursiveCall()do{ if((--(PyThreadState_Get()->recursion_depth) < (((_Py_CheckRecursionLimit ) > 200) ? ((_Py_CheckRecursionLimit) - 50) : (3 * ((_Py_CheckRecursionLimit ) >> 2))))) PyThreadState_Get()->overflowed = 0; } while (0); | ||||||||
1543 | return ret; | ||||||||
1544 | } | ||||||||
1545 | else if (PyArray_Check(obj)((((PyObject*)(obj))->ob_type) == (&PyArray_Type) || PyType_IsSubtype ((((PyObject*)(obj))->ob_type), (&PyArray_Type)))) { | ||||||||
1546 | PyErr_SetString(PyExc_TypeError, "Cannot construct a dtype from an array"); | ||||||||
1547 | return NULL((void*)0); | ||||||||
1548 | } | ||||||||
1549 | else { | ||||||||
1550 | PyArray_Descr *ret = _try_convert_from_dtype_attr(obj); | ||||||||
1551 | if ((PyObject *)ret != Py_NotImplemented(&_Py_NotImplementedStruct)) { | ||||||||
1552 | return ret; | ||||||||
1553 | } | ||||||||
1554 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | ||||||||
1555 | /* | ||||||||
1556 | * Note: this comes after _try_convert_from_dtype_attr because the ctypes | ||||||||
1557 | * type might override the dtype if numpy does not otherwise | ||||||||
1558 | * support it. | ||||||||
1559 | */ | ||||||||
1560 | ret = _try_convert_from_ctypes_type(Py_TYPE(obj)(((PyObject*)(obj))->ob_type)); | ||||||||
1561 | if ((PyObject *)ret != Py_NotImplemented(&_Py_NotImplementedStruct)) { | ||||||||
1562 | return ret; | ||||||||
1563 | } | ||||||||
1564 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | ||||||||
1565 | PyErr_Format(PyExc_TypeError, "Cannot interpret '%R' as a data type", obj); | ||||||||
1566 | return NULL((void*)0); | ||||||||
1567 | } | ||||||||
1568 | } | ||||||||
1569 | |||||||||
1570 | |||||||||
1571 | /*NUMPY_API | ||||||||
1572 | * Get typenum from an object -- None goes to NPY_DEFAULT_TYPE | ||||||||
1573 | * This function takes a Python object representing a type and converts it | ||||||||
1574 | * to a the correct PyArray_Descr * structure to describe the type. | ||||||||
1575 | * | ||||||||
1576 | * Many objects can be used to represent a data-type which in NumPy is | ||||||||
1577 | * quite a flexible concept. | ||||||||
1578 | * | ||||||||
1579 | * This is the central code that converts Python objects to | ||||||||
1580 | * Type-descriptor objects that are used throughout numpy. | ||||||||
1581 | * | ||||||||
1582 | * Returns a new reference in *at, but the returned should not be | ||||||||
1583 | * modified as it may be one of the canonical immutable objects or | ||||||||
1584 | * a reference to the input obj. | ||||||||
1585 | */ | ||||||||
1586 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) int | ||||||||
1587 | PyArray_DescrConverter(PyObject *obj, PyArray_Descr **at) | ||||||||
1588 | { | ||||||||
1589 | *at = _convert_from_any(obj, 0); | ||||||||
1590 | return (*at) ? NPY_SUCCEED1 : NPY_FAIL0; | ||||||||
1591 | } | ||||||||
1592 | |||||||||
1593 | /** Convert a bytestring specification into a dtype */ | ||||||||
1594 | static PyArray_Descr * | ||||||||
1595 | _convert_from_str(PyObject *obj, int align) | ||||||||
1596 | { | ||||||||
1597 | /* Check for a string typecode. */ | ||||||||
1598 | Py_ssize_t len = 0; | ||||||||
1599 | char const *type = PyUnicode_AsUTF8AndSize(obj, &len); | ||||||||
1600 | if (type == NULL((void*)0)) { | ||||||||
1601 | return NULL((void*)0); | ||||||||
1602 | } | ||||||||
1603 | |||||||||
1604 | /* Empty string is invalid */ | ||||||||
1605 | if (len == 0) { | ||||||||
1606 | goto fail; | ||||||||
1607 | } | ||||||||
1608 | |||||||||
1609 | /* check for commas present or first (or second) element a digit */ | ||||||||
1610 | if (_check_for_commastring(type, len)) { | ||||||||
1611 | return _convert_from_commastring(obj, align); | ||||||||
1612 | } | ||||||||
1613 | |||||||||
1614 | /* Process the endian character. '|' is replaced by '='*/ | ||||||||
1615 | char endian = '='; | ||||||||
1616 | switch (type[0]) { | ||||||||
1617 | case '>': | ||||||||
1618 | case '<': | ||||||||
1619 | case '=': | ||||||||
1620 | endian = type[0]; | ||||||||
1621 | ++type; | ||||||||
1622 | --len; | ||||||||
1623 | break; | ||||||||
1624 | |||||||||
1625 | case '|': | ||||||||
1626 | endian = '='; | ||||||||
1627 | ++type; | ||||||||
1628 | --len; | ||||||||
1629 | break; | ||||||||
1630 | } | ||||||||
1631 | |||||||||
1632 | /* Just an endian character is invalid */ | ||||||||
1633 | if (len == 0) { | ||||||||
1634 | goto fail; | ||||||||
1635 | } | ||||||||
1636 | |||||||||
1637 | /* Check for datetime format */ | ||||||||
1638 | if (is_datetime_typestr(type, len)) { | ||||||||
1639 | PyArray_Descr *ret = parse_dtype_from_datetime_typestr(type, len); | ||||||||
1640 | if (ret == NULL((void*)0)) { | ||||||||
1641 | return NULL((void*)0); | ||||||||
1642 | } | ||||||||
1643 | /* ret has byte order '=' at this point */ | ||||||||
1644 | if (!PyArray_ISNBO(endian)((endian) != '>')) { | ||||||||
1645 | ret->byteorder = endian; | ||||||||
1646 | } | ||||||||
1647 | return ret; | ||||||||
1648 | } | ||||||||
1649 | |||||||||
1650 | int check_num = NPY_NOTYPE + 10; | ||||||||
1651 | int elsize = 0; | ||||||||
1652 | /* A typecode like 'd' */ | ||||||||
1653 | if (len == 1) { | ||||||||
1654 | /* Python byte string characters are unsigned */ | ||||||||
1655 | check_num = (unsigned char) type[0]; | ||||||||
1656 | } | ||||||||
1657 | /* A kind + size like 'f8' */ | ||||||||
1658 | else { | ||||||||
1659 | char *typeend = NULL((void*)0); | ||||||||
1660 | int kind; | ||||||||
1661 | |||||||||
1662 | /* Parse the integer, make sure it's the rest of the string */ | ||||||||
1663 | elsize = (int)strtol(type + 1, &typeend, 10); | ||||||||
1664 | if (typeend - type == len) { | ||||||||
1665 | |||||||||
1666 | kind = type[0]; | ||||||||
1667 | switch (kind) { | ||||||||
1668 | case NPY_STRINGLTR: | ||||||||
1669 | case NPY_STRINGLTR2: | ||||||||
1670 | check_num = NPY_STRING; | ||||||||
1671 | break; | ||||||||
1672 | |||||||||
1673 | /* | ||||||||
1674 | * When specifying length of UNICODE | ||||||||
1675 | * the number of characters is given to match | ||||||||
1676 | * the STRING interface. Each character can be | ||||||||
1677 | * more than one byte and itemsize must be | ||||||||
1678 | * the number of bytes. | ||||||||
1679 | */ | ||||||||
1680 | case NPY_UNICODELTR: | ||||||||
1681 | check_num = NPY_UNICODE; | ||||||||
1682 | elsize <<= 2; | ||||||||
1683 | break; | ||||||||
1684 | |||||||||
1685 | case NPY_VOIDLTR: | ||||||||
1686 | check_num = NPY_VOID; | ||||||||
1687 | break; | ||||||||
1688 | |||||||||
1689 | default: | ||||||||
1690 | if (elsize == 0) { | ||||||||
1691 | check_num = NPY_NOTYPE+10; | ||||||||
1692 | } | ||||||||
1693 | /* Support for generic processing c8, i4, f8, etc...*/ | ||||||||
1694 | else { | ||||||||
1695 | check_num = PyArray_TypestrConvert(elsize, kind); | ||||||||
1696 | if (check_num == NPY_NOTYPE) { | ||||||||
1697 | check_num += 10; | ||||||||
1698 | } | ||||||||
1699 | elsize = 0; | ||||||||
1700 | } | ||||||||
1701 | } | ||||||||
1702 | } | ||||||||
1703 | } | ||||||||
1704 | |||||||||
1705 | if (PyErr_Occurred()) { | ||||||||
1706 | goto fail; | ||||||||
1707 | } | ||||||||
1708 | |||||||||
1709 | PyArray_Descr *ret; | ||||||||
1710 | if ((check_num == NPY_NOTYPE + 10) || | ||||||||
1711 | (ret = PyArray_DescrFromType(check_num)) == NULL((void*)0)) { | ||||||||
1712 | PyErr_Clear(); | ||||||||
1713 | /* Now check to see if the object is registered in typeDict */ | ||||||||
1714 | if (typeDict == NULL((void*)0)) { | ||||||||
1715 | goto fail; | ||||||||
1716 | } | ||||||||
1717 | PyObject *item = PyDict_GetItemWithError(typeDict, obj); | ||||||||
1718 | if (item == NULL((void*)0)) { | ||||||||
1719 | if (PyErr_Occurred()) { | ||||||||
1720 | return NULL((void*)0); | ||||||||
1721 | } | ||||||||
1722 | goto fail; | ||||||||
1723 | } | ||||||||
1724 | |||||||||
1725 | /* Check for a deprecated Numeric-style typecode */ | ||||||||
1726 | /* `Uint` has deliberately weird uppercasing */ | ||||||||
1727 | char *dep_tps[] = {"Bytes", "Datetime64", "Str", "Uint"}; | ||||||||
1728 | int ndep_tps = sizeof(dep_tps) / sizeof(dep_tps[0]); | ||||||||
1729 | for (int i = 0; i < ndep_tps; ++i) { | ||||||||
1730 | char *dep_tp = dep_tps[i]; | ||||||||
1731 | |||||||||
1732 | if (strncmp(type, dep_tp, strlen(dep_tp)) == 0) { | ||||||||
1733 | /* Deprecated 2020-06-09, NumPy 1.20 */ | ||||||||
1734 | if (DEPRECATE("Numeric-style type codes are "PyErr_WarnEx(PyExc_DeprecationWarning,"Numeric-style type codes are " "deprecated and will result in " "an error in the future.",1 ) | ||||||||
1735 | "deprecated and will result in "PyErr_WarnEx(PyExc_DeprecationWarning,"Numeric-style type codes are " "deprecated and will result in " "an error in the future.",1 ) | ||||||||
1736 | "an error in the future.")PyErr_WarnEx(PyExc_DeprecationWarning,"Numeric-style type codes are " "deprecated and will result in " "an error in the future.",1 ) < 0) { | ||||||||
1737 | goto fail; | ||||||||
1738 | } | ||||||||
1739 | } | ||||||||
1740 | } | ||||||||
1741 | /* | ||||||||
1742 | * Probably only ever dispatches to `_convert_from_type`, but who | ||||||||
1743 | * knows what users are injecting into `np.typeDict`. | ||||||||
1744 | */ | ||||||||
1745 | return _convert_from_any(item, align); | ||||||||
1746 | } | ||||||||
1747 | |||||||||
1748 | if (PyDataType_ISUNSIZED(ret)((ret)->elsize == 0 && !(((PyArray_Descr *)(ret))-> names != ((void*)0))) && ret->elsize != elsize) { | ||||||||
1749 | PyArray_DESCR_REPLACE(ret)do { PyArray_Descr *_new_; _new_ = PyArray_DescrNew(ret); _Py_XDECREF (((PyObject*)(ret))); ret = _new_; } while(0); | ||||||||
1750 | if (ret == NULL((void*)0)) { | ||||||||
1751 | return NULL((void*)0); | ||||||||
1752 | } | ||||||||
1753 | ret->elsize = elsize; | ||||||||
1754 | } | ||||||||
1755 | if (endian != '=' && PyArray_ISNBO(endian)((endian) != '>')) { | ||||||||
1756 | endian = '='; | ||||||||
1757 | } | ||||||||
1758 | if (endian != '=' && ret->byteorder != '|' && ret->byteorder != endian) { | ||||||||
1759 | PyArray_DESCR_REPLACE(ret)do { PyArray_Descr *_new_; _new_ = PyArray_DescrNew(ret); _Py_XDECREF (((PyObject*)(ret))); ret = _new_; } while(0); | ||||||||
1760 | if (ret == NULL((void*)0)) { | ||||||||
1761 | return NULL((void*)0); | ||||||||
1762 | } | ||||||||
1763 | ret->byteorder = endian; | ||||||||
1764 | } | ||||||||
1765 | return ret; | ||||||||
1766 | |||||||||
1767 | fail: | ||||||||
1768 | PyErr_Format(PyExc_TypeError, "data type %R not understood", obj); | ||||||||
1769 | return NULL((void*)0); | ||||||||
1770 | } | ||||||||
1771 | |||||||||
1772 | /** Array Descr Objects for dynamic types **/ | ||||||||
1773 | |||||||||
1774 | /* | ||||||||
1775 | * There are some statically-defined PyArray_Descr objects corresponding | ||||||||
1776 | * to the basic built-in types. | ||||||||
1777 | * These can and should be DECREF'd and INCREF'd as appropriate, anyway. | ||||||||
1778 | * If a mistake is made in reference counting, deallocation on these | ||||||||
1779 | * builtins will be attempted leading to problems. | ||||||||
1780 | * | ||||||||
1781 | * This lets us deal with all PyArray_Descr objects using reference | ||||||||
1782 | * counting (regardless of whether they are statically or dynamically | ||||||||
1783 | * allocated). | ||||||||
1784 | */ | ||||||||
1785 | |||||||||
1786 | /*NUMPY_API | ||||||||
1787 | * base cannot be NULL | ||||||||
1788 | */ | ||||||||
1789 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyArray_Descr * | ||||||||
1790 | PyArray_DescrNew(PyArray_Descr *base) | ||||||||
1791 | { | ||||||||
1792 | PyArray_Descr *newdescr = PyObject_New(PyArray_Descr, Py_TYPE(base))( (PyArray_Descr *) _PyObject_New((((PyObject*)(base))->ob_type )) ); | ||||||||
1793 | |||||||||
1794 | if (newdescr == NULL((void*)0)) { | ||||||||
1795 | return NULL((void*)0); | ||||||||
1796 | } | ||||||||
1797 | /* Don't copy PyObject_HEAD part */ | ||||||||
1798 | memcpy((char *)newdescr + sizeof(PyObject), | ||||||||
1799 | (char *)base + sizeof(PyObject), | ||||||||
1800 | sizeof(PyArray_Descr) - sizeof(PyObject)); | ||||||||
1801 | |||||||||
1802 | /* | ||||||||
1803 | * The c_metadata has a by-value ownership model, need to clone it | ||||||||
1804 | * (basically a deep copy, but the auxdata clone function has some | ||||||||
1805 | * flexibility still) so the new PyArray_Descr object owns | ||||||||
1806 | * a copy of the data. Having both 'base' and 'newdescr' point to | ||||||||
1807 | * the same auxdata pointer would cause a double-free of memory. | ||||||||
1808 | */ | ||||||||
1809 | if (base->c_metadata != NULL((void*)0)) { | ||||||||
1810 | newdescr->c_metadata = NPY_AUXDATA_CLONE(base->c_metadata)((base->c_metadata)->clone(base->c_metadata)); | ||||||||
1811 | if (newdescr->c_metadata == NULL((void*)0)) { | ||||||||
1812 | PyErr_NoMemory(); | ||||||||
1813 | /* TODO: This seems wrong, as the old fields get decref'd? */ | ||||||||
1814 | Py_DECREF(newdescr)_Py_DECREF(((PyObject*)(newdescr))); | ||||||||
1815 | return NULL((void*)0); | ||||||||
1816 | } | ||||||||
1817 | } | ||||||||
1818 | |||||||||
1819 | if (newdescr->fields == Py_None(&_Py_NoneStruct)) { | ||||||||
1820 | newdescr->fields = NULL((void*)0); | ||||||||
1821 | } | ||||||||
1822 | Py_XINCREF(newdescr->fields)_Py_XINCREF(((PyObject*)(newdescr->fields))); | ||||||||
1823 | Py_XINCREF(newdescr->names)_Py_XINCREF(((PyObject*)(newdescr->names))); | ||||||||
1824 | if (newdescr->subarray) { | ||||||||
1825 | newdescr->subarray = PyArray_mallocPyMem_RawMalloc(sizeof(PyArray_ArrayDescr)); | ||||||||
1826 | if (newdescr->subarray == NULL((void*)0)) { | ||||||||
1827 | Py_DECREF(newdescr)_Py_DECREF(((PyObject*)(newdescr))); | ||||||||
1828 | return (PyArray_Descr *)PyErr_NoMemory(); | ||||||||
1829 | } | ||||||||
1830 | memcpy(newdescr->subarray, base->subarray, sizeof(PyArray_ArrayDescr)); | ||||||||
1831 | Py_INCREF(newdescr->subarray->shape)_Py_INCREF(((PyObject*)(newdescr->subarray->shape))); | ||||||||
1832 | Py_INCREF(newdescr->subarray->base)_Py_INCREF(((PyObject*)(newdescr->subarray->base))); | ||||||||
1833 | } | ||||||||
1834 | Py_XINCREF(newdescr->typeobj)_Py_XINCREF(((PyObject*)(newdescr->typeobj))); | ||||||||
1835 | Py_XINCREF(newdescr->metadata)_Py_XINCREF(((PyObject*)(newdescr->metadata))); | ||||||||
1836 | newdescr->hash = -1; | ||||||||
1837 | |||||||||
1838 | return newdescr; | ||||||||
1839 | } | ||||||||
1840 | |||||||||
1841 | /* | ||||||||
1842 | * should never be called for builtin-types unless | ||||||||
1843 | * there is a reference-count problem | ||||||||
1844 | */ | ||||||||
1845 | static void | ||||||||
1846 | arraydescr_dealloc(PyArray_Descr *self) | ||||||||
1847 | { | ||||||||
1848 | if (self->fields == Py_None(&_Py_NoneStruct)) { | ||||||||
1849 | fprintf(stderr, "*** Reference count error detected: "__fprintf_chk (stderr, 2 - 1, "*** Reference count error detected: " "an attempt was made to deallocate the dtype %d (%c) ***\n", self->type_num, self->type) | ||||||||
1850 | "an attempt was made to deallocate the dtype %d (%c) ***\n",__fprintf_chk (stderr, 2 - 1, "*** Reference count error detected: " "an attempt was made to deallocate the dtype %d (%c) ***\n", self->type_num, self->type) | ||||||||
1851 | self->type_num, self->type)__fprintf_chk (stderr, 2 - 1, "*** Reference count error detected: " "an attempt was made to deallocate the dtype %d (%c) ***\n", self->type_num, self->type); | ||||||||
1852 | assert(0)((void) (0)); | ||||||||
1853 | Py_INCREF(self)_Py_INCREF(((PyObject*)(self))); | ||||||||
1854 | Py_INCREF(self)_Py_INCREF(((PyObject*)(self))); | ||||||||
1855 | return; | ||||||||
1856 | } | ||||||||
1857 | Py_XDECREF(self->typeobj)_Py_XDECREF(((PyObject*)(self->typeobj))); | ||||||||
1858 | Py_XDECREF(self->names)_Py_XDECREF(((PyObject*)(self->names))); | ||||||||
1859 | Py_XDECREF(self->fields)_Py_XDECREF(((PyObject*)(self->fields))); | ||||||||
1860 | if (self->subarray) { | ||||||||
1861 | Py_XDECREF(self->subarray->shape)_Py_XDECREF(((PyObject*)(self->subarray->shape))); | ||||||||
1862 | Py_DECREF(self->subarray->base)_Py_DECREF(((PyObject*)(self->subarray->base))); | ||||||||
1863 | PyArray_freePyMem_RawFree(self->subarray); | ||||||||
1864 | } | ||||||||
1865 | Py_XDECREF(self->metadata)_Py_XDECREF(((PyObject*)(self->metadata))); | ||||||||
1866 | NPY_AUXDATA_FREE(self->c_metadata)do { if ((self->c_metadata) != ((void*)0)) { (self->c_metadata )->free(self->c_metadata); } } while(0); | ||||||||
1867 | self->c_metadata = NULL((void*)0); | ||||||||
1868 | Py_TYPE(self)(((PyObject*)(self))->ob_type)->tp_free((PyObject *)self); | ||||||||
1869 | } | ||||||||
1870 | |||||||||
1871 | /* | ||||||||
1872 | * we need to be careful about setting attributes because these | ||||||||
1873 | * objects are pointed to by arrays that depend on them for interpreting | ||||||||
1874 | * data. Currently no attributes of data-type objects can be set | ||||||||
1875 | * directly except names. | ||||||||
1876 | */ | ||||||||
1877 | static PyMemberDef arraydescr_members[] = { | ||||||||
1878 | {"type", | ||||||||
1879 | T_OBJECT6, offsetof(PyArray_Descr, typeobj)__builtin_offsetof(PyArray_Descr, typeobj), READONLY1, NULL((void*)0)}, | ||||||||
1880 | {"kind", | ||||||||
1881 | T_CHAR7, offsetof(PyArray_Descr, kind)__builtin_offsetof(PyArray_Descr, kind), READONLY1, NULL((void*)0)}, | ||||||||
1882 | {"char", | ||||||||
1883 | T_CHAR7, offsetof(PyArray_Descr, type)__builtin_offsetof(PyArray_Descr, type), READONLY1, NULL((void*)0)}, | ||||||||
1884 | {"num", | ||||||||
1885 | T_INT1, offsetof(PyArray_Descr, type_num)__builtin_offsetof(PyArray_Descr, type_num), READONLY1, NULL((void*)0)}, | ||||||||
1886 | {"byteorder", | ||||||||
1887 | T_CHAR7, offsetof(PyArray_Descr, byteorder)__builtin_offsetof(PyArray_Descr, byteorder), READONLY1, NULL((void*)0)}, | ||||||||
1888 | {"itemsize", | ||||||||
1889 | T_INT1, offsetof(PyArray_Descr, elsize)__builtin_offsetof(PyArray_Descr, elsize), READONLY1, NULL((void*)0)}, | ||||||||
1890 | {"alignment", | ||||||||
1891 | T_INT1, offsetof(PyArray_Descr, alignment)__builtin_offsetof(PyArray_Descr, alignment), READONLY1, NULL((void*)0)}, | ||||||||
1892 | {"flags", | ||||||||
1893 | T_BYTE8, offsetof(PyArray_Descr, flags)__builtin_offsetof(PyArray_Descr, flags), READONLY1, NULL((void*)0)}, | ||||||||
1894 | {NULL((void*)0), 0, 0, 0, NULL((void*)0)}, | ||||||||
1895 | }; | ||||||||
1896 | |||||||||
1897 | static PyObject * | ||||||||
1898 | arraydescr_subdescr_get(PyArray_Descr *self) | ||||||||
1899 | { | ||||||||
1900 | if (!PyDataType_HASSUBARRAY(self)((self)->subarray != ((void*)0))) { | ||||||||
1901 | Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (& _Py_NoneStruct); | ||||||||
1902 | } | ||||||||
1903 | return Py_BuildValue_Py_BuildValue_SizeT("OO", | ||||||||
1904 | (PyObject *)self->subarray->base, self->subarray->shape); | ||||||||
1905 | } | ||||||||
1906 | |||||||||
1907 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
1908 | arraydescr_protocol_typestr_get(PyArray_Descr *self) | ||||||||
1909 | { | ||||||||
1910 | char basic_ = self->kind; | ||||||||
1911 | char endian = self->byteorder; | ||||||||
1912 | int size = self->elsize; | ||||||||
1913 | PyObject *ret; | ||||||||
1914 | |||||||||
1915 | if (endian == '=') { | ||||||||
1916 | endian = '<'; | ||||||||
1917 | if (!PyArray_IsNativeByteOrder(endian)((endian) != '>')) { | ||||||||
1918 | endian = '>'; | ||||||||
1919 | } | ||||||||
1920 | } | ||||||||
1921 | if (self->type_num == NPY_UNICODE) { | ||||||||
1922 | size >>= 2; | ||||||||
1923 | } | ||||||||
1924 | if (self->type_num == NPY_OBJECT) { | ||||||||
1925 | ret = PyUnicode_FromFormat("%c%c", endian, basic_); | ||||||||
1926 | } | ||||||||
1927 | else { | ||||||||
1928 | ret = PyUnicode_FromFormat("%c%c%d", endian, basic_, size); | ||||||||
1929 | } | ||||||||
1930 | if (ret == NULL((void*)0)) { | ||||||||
1931 | return NULL((void*)0); | ||||||||
1932 | } | ||||||||
1933 | |||||||||
1934 | if (PyDataType_ISDATETIME(self)(((((PyArray_Descr*)(self))->type_num) >=NPY_DATETIME) && ((((PyArray_Descr*)(self))->type_num) <=NPY_TIMEDELTA) )) { | ||||||||
1935 | PyArray_DatetimeMetaData *meta; | ||||||||
1936 | meta = get_datetime_metadata_from_dtype(self); | ||||||||
1937 | if (meta == NULL((void*)0)) { | ||||||||
1938 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | ||||||||
1939 | return NULL((void*)0); | ||||||||
1940 | } | ||||||||
1941 | PyObject *umeta = metastr_to_unicode(meta, 0); | ||||||||
1942 | if (umeta == NULL((void*)0)) { | ||||||||
1943 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | ||||||||
1944 | return NULL((void*)0); | ||||||||
1945 | } | ||||||||
1946 | |||||||||
1947 | Py_SETREF(ret, PyUnicode_Concat(ret, umeta))do { PyObject *_py_tmp = ((PyObject*)(ret)); (ret) = (PyUnicode_Concat (ret, umeta)); _Py_DECREF(((PyObject*)(_py_tmp))); } while (0 ); | ||||||||
1948 | Py_DECREF(umeta)_Py_DECREF(((PyObject*)(umeta))); | ||||||||
1949 | } | ||||||||
1950 | return ret; | ||||||||
1951 | } | ||||||||
1952 | |||||||||
1953 | static PyObject * | ||||||||
1954 | arraydescr_name_get(PyArray_Descr *self) | ||||||||
1955 | { | ||||||||
1956 | /* let python handle this */ | ||||||||
1957 | PyObject *_numpy_dtype; | ||||||||
1958 | PyObject *res; | ||||||||
1959 | _numpy_dtype = PyImport_ImportModule("numpy.core._dtype"); | ||||||||
1960 | if (_numpy_dtype == NULL((void*)0)) { | ||||||||
1961 | return NULL((void*)0); | ||||||||
1962 | } | ||||||||
1963 | res = PyObject_CallMethod_PyObject_CallMethod_SizeT(_numpy_dtype, "_name_get", "O", self); | ||||||||
1964 | Py_DECREF(_numpy_dtype)_Py_DECREF(((PyObject*)(_numpy_dtype))); | ||||||||
1965 | return res; | ||||||||
1966 | } | ||||||||
1967 | |||||||||
1968 | static PyObject * | ||||||||
1969 | arraydescr_base_get(PyArray_Descr *self) | ||||||||
1970 | { | ||||||||
1971 | if (!PyDataType_HASSUBARRAY(self)((self)->subarray != ((void*)0))) { | ||||||||
1972 | Py_INCREF(self)_Py_INCREF(((PyObject*)(self))); | ||||||||
1973 | return (PyObject *)self; | ||||||||
1974 | } | ||||||||
1975 | Py_INCREF(self->subarray->base)_Py_INCREF(((PyObject*)(self->subarray->base))); | ||||||||
1976 | return (PyObject *)(self->subarray->base); | ||||||||
1977 | } | ||||||||
1978 | |||||||||
1979 | static PyObject * | ||||||||
1980 | arraydescr_shape_get(PyArray_Descr *self) | ||||||||
1981 | { | ||||||||
1982 | if (!PyDataType_HASSUBARRAY(self)((self)->subarray != ((void*)0))) { | ||||||||
1983 | return PyTuple_New(0); | ||||||||
1984 | } | ||||||||
1985 | assert(PyTuple_Check(self->subarray->shape))((void) (0)); | ||||||||
1986 | Py_INCREF(self->subarray->shape)_Py_INCREF(((PyObject*)(self->subarray->shape))); | ||||||||
1987 | return self->subarray->shape; | ||||||||
1988 | } | ||||||||
1989 | |||||||||
1990 | static PyObject * | ||||||||
1991 | arraydescr_ndim_get(PyArray_Descr *self) | ||||||||
1992 | { | ||||||||
1993 | Py_ssize_t ndim; | ||||||||
1994 | |||||||||
1995 | if (!PyDataType_HASSUBARRAY(self)((self)->subarray != ((void*)0))) { | ||||||||
1996 | return PyLong_FromLong(0); | ||||||||
1997 | } | ||||||||
1998 | |||||||||
1999 | /* | ||||||||
2000 | * PyTuple_Size has built in check | ||||||||
2001 | * for tuple argument | ||||||||
2002 | */ | ||||||||
2003 | ndim = PyTuple_Size(self->subarray->shape); | ||||||||
2004 | return PyLong_FromLong(ndim); | ||||||||
2005 | } | ||||||||
2006 | |||||||||
2007 | |||||||||
2008 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
2009 | arraydescr_protocol_descr_get(PyArray_Descr *self) | ||||||||
2010 | { | ||||||||
2011 | PyObject *dobj, *res; | ||||||||
2012 | PyObject *_numpy_internal; | ||||||||
2013 | |||||||||
2014 | if (!PyDataType_HASFIELDS(self)(((PyArray_Descr *)(self))->names != ((void*)0))) { | ||||||||
2015 | /* get default */ | ||||||||
2016 | dobj = PyTuple_New(2); | ||||||||
2017 | if (dobj == NULL((void*)0)) { | ||||||||
2018 | return NULL((void*)0); | ||||||||
2019 | } | ||||||||
2020 | PyTuple_SET_ITEM(dobj, 0, PyUnicode_FromString(""))PyTuple_SetItem(dobj, 0, PyUnicode_FromString("")); | ||||||||
2021 | PyTuple_SET_ITEM(dobj, 1, arraydescr_protocol_typestr_get(self))PyTuple_SetItem(dobj, 1, arraydescr_protocol_typestr_get(self )); | ||||||||
2022 | res = PyList_New(1); | ||||||||
2023 | if (res == NULL((void*)0)) { | ||||||||
2024 | Py_DECREF(dobj)_Py_DECREF(((PyObject*)(dobj))); | ||||||||
2025 | return NULL((void*)0); | ||||||||
2026 | } | ||||||||
2027 | PyList_SET_ITEM(res, 0, dobj)PyList_SetItem(res, 0, dobj); | ||||||||
2028 | return res; | ||||||||
2029 | } | ||||||||
2030 | |||||||||
2031 | _numpy_internal = PyImport_ImportModule("numpy.core._internal"); | ||||||||
2032 | if (_numpy_internal == NULL((void*)0)) { | ||||||||
2033 | return NULL((void*)0); | ||||||||
2034 | } | ||||||||
2035 | res = PyObject_CallMethod_PyObject_CallMethod_SizeT(_numpy_internal, "_array_descr", "O", self); | ||||||||
2036 | Py_DECREF(_numpy_internal)_Py_DECREF(((PyObject*)(_numpy_internal))); | ||||||||
2037 | return res; | ||||||||
2038 | } | ||||||||
2039 | |||||||||
2040 | /* | ||||||||
2041 | * returns 1 for a builtin type | ||||||||
2042 | * and 2 for a user-defined data-type descriptor | ||||||||
2043 | * return 0 if neither (i.e. it's a copy of one) | ||||||||
2044 | */ | ||||||||
2045 | static PyObject * | ||||||||
2046 | arraydescr_isbuiltin_get(PyArray_Descr *self) | ||||||||
2047 | { | ||||||||
2048 | long val; | ||||||||
2049 | val = 0; | ||||||||
2050 | if (self->fields == Py_None(&_Py_NoneStruct)) { | ||||||||
2051 | val = 1; | ||||||||
2052 | } | ||||||||
2053 | if (PyTypeNum_ISUSERDEF(self->type_num)(((self->type_num) >= NPY_USERDEF) && ((self-> type_num) < NPY_USERDEF+ NPY_NUMUSERTYPES))) { | ||||||||
2054 | val = 2; | ||||||||
2055 | } | ||||||||
2056 | return PyLong_FromLong(val); | ||||||||
2057 | } | ||||||||
2058 | |||||||||
2059 | static int | ||||||||
2060 | _arraydescr_isnative(PyArray_Descr *self) | ||||||||
2061 | { | ||||||||
2062 | if (!PyDataType_HASFIELDS(self)(((PyArray_Descr *)(self))->names != ((void*)0))) { | ||||||||
2063 | return PyArray_ISNBO(self->byteorder)((self->byteorder) != '>'); | ||||||||
2064 | } | ||||||||
2065 | else { | ||||||||
2066 | PyObject *key, *value, *title = NULL((void*)0); | ||||||||
2067 | PyArray_Descr *new; | ||||||||
2068 | int offset; | ||||||||
2069 | Py_ssize_t pos = 0; | ||||||||
2070 | while (PyDict_Next(self->fields, &pos, &key, &value)) { | ||||||||
2071 | if (NPY_TITLE_KEY(key, value)(NPY_TITLE_KEY_check((key), (value)))) { | ||||||||
2072 | continue; | ||||||||
2073 | } | ||||||||
2074 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(value, "Oi|O", &new, &offset, &title)) { | ||||||||
2075 | return -1; | ||||||||
2076 | } | ||||||||
2077 | if (!_arraydescr_isnative(new)) { | ||||||||
2078 | return 0; | ||||||||
2079 | } | ||||||||
2080 | } | ||||||||
2081 | } | ||||||||
2082 | return 1; | ||||||||
2083 | } | ||||||||
2084 | |||||||||
2085 | /* | ||||||||
2086 | * return Py_True if this data-type descriptor | ||||||||
2087 | * has native byteorder if no fields are defined | ||||||||
2088 | * | ||||||||
2089 | * or if all sub-fields have native-byteorder if | ||||||||
2090 | * fields are defined | ||||||||
2091 | */ | ||||||||
2092 | static PyObject * | ||||||||
2093 | arraydescr_isnative_get(PyArray_Descr *self) | ||||||||
2094 | { | ||||||||
2095 | PyObject *ret; | ||||||||
2096 | int retval; | ||||||||
2097 | retval = _arraydescr_isnative(self); | ||||||||
2098 | if (retval == -1) { | ||||||||
2099 | return NULL((void*)0); | ||||||||
2100 | } | ||||||||
2101 | ret = retval ? Py_True((PyObject *) &_Py_TrueStruct) : Py_False((PyObject *) &_Py_FalseStruct); | ||||||||
2102 | Py_INCREF(ret)_Py_INCREF(((PyObject*)(ret))); | ||||||||
2103 | return ret; | ||||||||
2104 | } | ||||||||
2105 | |||||||||
2106 | static PyObject * | ||||||||
2107 | arraydescr_isalignedstruct_get(PyArray_Descr *self) | ||||||||
2108 | { | ||||||||
2109 | PyObject *ret; | ||||||||
2110 | ret = (self->flags&NPY_ALIGNED_STRUCT0x80) ? Py_True((PyObject *) &_Py_TrueStruct) : Py_False((PyObject *) &_Py_FalseStruct); | ||||||||
2111 | Py_INCREF(ret)_Py_INCREF(((PyObject*)(ret))); | ||||||||
2112 | return ret; | ||||||||
2113 | } | ||||||||
2114 | |||||||||
2115 | static PyObject * | ||||||||
2116 | arraydescr_fields_get(PyArray_Descr *self) | ||||||||
2117 | { | ||||||||
2118 | if (!PyDataType_HASFIELDS(self)(((PyArray_Descr *)(self))->names != ((void*)0))) { | ||||||||
2119 | Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (& _Py_NoneStruct); | ||||||||
2120 | } | ||||||||
2121 | return PyDictProxy_New(self->fields); | ||||||||
2122 | } | ||||||||
2123 | |||||||||
2124 | static PyObject * | ||||||||
2125 | arraydescr_metadata_get(PyArray_Descr *self) | ||||||||
2126 | { | ||||||||
2127 | if (self->metadata == NULL((void*)0)) { | ||||||||
2128 | Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (& _Py_NoneStruct); | ||||||||
2129 | } | ||||||||
2130 | return PyDictProxy_New(self->metadata); | ||||||||
2131 | } | ||||||||
2132 | |||||||||
2133 | static PyObject * | ||||||||
2134 | arraydescr_hasobject_get(PyArray_Descr *self) | ||||||||
2135 | { | ||||||||
2136 | if (PyDataType_FLAGCHK(self, NPY_ITEM_HASOBJECT)(((self)->flags & (0x01)) == (0x01))) { | ||||||||
2137 | Py_RETURN_TRUEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_TrueStruct )))), ((PyObject *) &_Py_TrueStruct); | ||||||||
2138 | } | ||||||||
2139 | else { | ||||||||
2140 | Py_RETURN_FALSEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_FalseStruct )))), ((PyObject *) &_Py_FalseStruct); | ||||||||
2141 | } | ||||||||
2142 | } | ||||||||
2143 | |||||||||
2144 | static PyObject * | ||||||||
2145 | arraydescr_names_get(PyArray_Descr *self) | ||||||||
2146 | { | ||||||||
2147 | if (!PyDataType_HASFIELDS(self)(((PyArray_Descr *)(self))->names != ((void*)0))) { | ||||||||
2148 | Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (& _Py_NoneStruct); | ||||||||
2149 | } | ||||||||
2150 | Py_INCREF(self->names)_Py_INCREF(((PyObject*)(self->names))); | ||||||||
2151 | return self->names; | ||||||||
2152 | } | ||||||||
2153 | |||||||||
2154 | static int | ||||||||
2155 | arraydescr_names_set(PyArray_Descr *self, PyObject *val) | ||||||||
2156 | { | ||||||||
2157 | int N = 0; | ||||||||
2158 | int i; | ||||||||
2159 | PyObject *new_names; | ||||||||
2160 | PyObject *new_fields; | ||||||||
2161 | |||||||||
2162 | if (val == NULL((void*)0)) { | ||||||||
2163 | PyErr_SetString(PyExc_AttributeError, | ||||||||
2164 | "Cannot delete dtype names attribute"); | ||||||||
2165 | return -1; | ||||||||
2166 | } | ||||||||
2167 | if (!PyDataType_HASFIELDS(self)(((PyArray_Descr *)(self))->names != ((void*)0))) { | ||||||||
2168 | PyErr_SetString(PyExc_ValueError, | ||||||||
2169 | "there are no fields defined"); | ||||||||
2170 | return -1; | ||||||||
2171 | } | ||||||||
2172 | |||||||||
2173 | /* | ||||||||
2174 | * FIXME | ||||||||
2175 | * | ||||||||
2176 | * This deprecation has been temporarily removed for the NumPy 1.7 | ||||||||
2177 | * release. It should be re-added after the 1.7 branch is done, | ||||||||
2178 | * and a convenience API to replace the typical use-cases for | ||||||||
2179 | * mutable names should be implemented. | ||||||||
2180 | * | ||||||||
2181 | * if (DEPRECATE("Setting NumPy dtype names is deprecated, the dtype " | ||||||||
2182 | * "will become immutable in a future version") < 0) { | ||||||||
2183 | * return -1; | ||||||||
2184 | * } | ||||||||
2185 | */ | ||||||||
2186 | |||||||||
2187 | N = PyTuple_GET_SIZE(self->names)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(self->names ))))->ob_size); | ||||||||
2188 | if (!PySequence_Check(val) || PyObject_Size((PyObject *)val) != N) { | ||||||||
2189 | PyErr_Format(PyExc_ValueError, | ||||||||
2190 | "must replace all names at once with a sequence of length %d", | ||||||||
2191 | N); | ||||||||
2192 | return -1; | ||||||||
2193 | } | ||||||||
2194 | /* Make sure all entries are strings */ | ||||||||
2195 | for (i = 0; i < N; i++) { | ||||||||
2196 | PyObject *item; | ||||||||
2197 | int valid = 1; | ||||||||
2198 | item = PySequence_GetItem(val, i); | ||||||||
2199 | valid = PyUnicode_Check(item)((((((PyObject*)(item))->ob_type))->tp_flags & ((1UL << 28))) != 0); | ||||||||
2200 | Py_DECREF(item)_Py_DECREF(((PyObject*)(item))); | ||||||||
2201 | if (!valid) { | ||||||||
2202 | PyErr_Format(PyExc_ValueError, | ||||||||
2203 | "item #%d of names is of type %s and not string", | ||||||||
2204 | i, Py_TYPE(item)(((PyObject*)(item))->ob_type)->tp_name); | ||||||||
2205 | return -1; | ||||||||
2206 | } | ||||||||
2207 | } | ||||||||
2208 | /* Invalidate cached hash value */ | ||||||||
2209 | self->hash = -1; | ||||||||
2210 | /* Update dictionary keys in fields */ | ||||||||
2211 | new_names = PySequence_Tuple(val); | ||||||||
2212 | if (new_names == NULL((void*)0)) { | ||||||||
2213 | return -1; | ||||||||
2214 | } | ||||||||
2215 | new_fields = PyDict_New(); | ||||||||
2216 | if (new_fields == NULL((void*)0)) { | ||||||||
2217 | Py_DECREF(new_names)_Py_DECREF(((PyObject*)(new_names))); | ||||||||
2218 | return -1; | ||||||||
2219 | } | ||||||||
2220 | for (i = 0; i < N; i++) { | ||||||||
2221 | PyObject *key; | ||||||||
2222 | PyObject *item; | ||||||||
2223 | PyObject *new_key; | ||||||||
2224 | int ret; | ||||||||
2225 | key = PyTuple_GET_ITEM(self->names, i)((((void) (0)), (PyTupleObject *)(self->names))->ob_item [i]); | ||||||||
2226 | /* Borrowed references to item and new_key */ | ||||||||
2227 | item = PyDict_GetItemWithError(self->fields, key); | ||||||||
2228 | if (item == NULL((void*)0)) { | ||||||||
2229 | if (!PyErr_Occurred()) { | ||||||||
2230 | /* fields was missing the name it claimed to contain */ | ||||||||
2231 | PyErr_BadInternalCall()_PyErr_BadInternalCall("numpy/core/src/multiarray/descriptor.c" , 2231); | ||||||||
2232 | } | ||||||||
2233 | Py_DECREF(new_names)_Py_DECREF(((PyObject*)(new_names))); | ||||||||
2234 | Py_DECREF(new_fields)_Py_DECREF(((PyObject*)(new_fields))); | ||||||||
2235 | return -1; | ||||||||
2236 | } | ||||||||
2237 | new_key = PyTuple_GET_ITEM(new_names, i)((((void) (0)), (PyTupleObject *)(new_names))->ob_item[i]); | ||||||||
2238 | /* Check for duplicates */ | ||||||||
2239 | ret = PyDict_Contains(new_fields, new_key); | ||||||||
2240 | if (ret < 0) { | ||||||||
2241 | Py_DECREF(new_names)_Py_DECREF(((PyObject*)(new_names))); | ||||||||
2242 | Py_DECREF(new_fields)_Py_DECREF(((PyObject*)(new_fields))); | ||||||||
2243 | return -1; | ||||||||
2244 | } | ||||||||
2245 | else if (ret != 0) { | ||||||||
2246 | PyErr_SetString(PyExc_ValueError, "Duplicate field names given."); | ||||||||
2247 | Py_DECREF(new_names)_Py_DECREF(((PyObject*)(new_names))); | ||||||||
2248 | Py_DECREF(new_fields)_Py_DECREF(((PyObject*)(new_fields))); | ||||||||
2249 | return -1; | ||||||||
2250 | } | ||||||||
2251 | if (PyDict_SetItem(new_fields, new_key, item) < 0) { | ||||||||
2252 | Py_DECREF(new_names)_Py_DECREF(((PyObject*)(new_names))); | ||||||||
2253 | Py_DECREF(new_fields)_Py_DECREF(((PyObject*)(new_fields))); | ||||||||
2254 | return -1; | ||||||||
2255 | } | ||||||||
2256 | } | ||||||||
2257 | |||||||||
2258 | /* Replace names */ | ||||||||
2259 | Py_DECREF(self->names)_Py_DECREF(((PyObject*)(self->names))); | ||||||||
2260 | self->names = new_names; | ||||||||
2261 | |||||||||
2262 | /* Replace fields */ | ||||||||
2263 | Py_DECREF(self->fields)_Py_DECREF(((PyObject*)(self->fields))); | ||||||||
2264 | self->fields = new_fields; | ||||||||
2265 | |||||||||
2266 | return 0; | ||||||||
2267 | } | ||||||||
2268 | |||||||||
2269 | static PyGetSetDef arraydescr_getsets[] = { | ||||||||
2270 | {"subdtype", | ||||||||
2271 | (getter)arraydescr_subdescr_get, | ||||||||
2272 | NULL((void*)0), NULL((void*)0), NULL((void*)0)}, | ||||||||
2273 | {"descr", | ||||||||
2274 | (getter)arraydescr_protocol_descr_get, | ||||||||
2275 | NULL((void*)0), NULL((void*)0), NULL((void*)0)}, | ||||||||
2276 | {"str", | ||||||||
2277 | (getter)arraydescr_protocol_typestr_get, | ||||||||
2278 | NULL((void*)0), NULL((void*)0), NULL((void*)0)}, | ||||||||
2279 | {"name", | ||||||||
2280 | (getter)arraydescr_name_get, | ||||||||
2281 | NULL((void*)0), NULL((void*)0), NULL((void*)0)}, | ||||||||
2282 | {"base", | ||||||||
2283 | (getter)arraydescr_base_get, | ||||||||
2284 | NULL((void*)0), NULL((void*)0), NULL((void*)0)}, | ||||||||
2285 | {"shape", | ||||||||
2286 | (getter)arraydescr_shape_get, | ||||||||
2287 | NULL((void*)0), NULL((void*)0), NULL((void*)0)}, | ||||||||
2288 | {"ndim", | ||||||||
2289 | (getter)arraydescr_ndim_get, | ||||||||
2290 | NULL((void*)0), NULL((void*)0), NULL((void*)0)}, | ||||||||
2291 | {"isbuiltin", | ||||||||
2292 | (getter)arraydescr_isbuiltin_get, | ||||||||
2293 | NULL((void*)0), NULL((void*)0), NULL((void*)0)}, | ||||||||
2294 | {"isnative", | ||||||||
2295 | (getter)arraydescr_isnative_get, | ||||||||
2296 | NULL((void*)0), NULL((void*)0), NULL((void*)0)}, | ||||||||
2297 | {"isalignedstruct", | ||||||||
2298 | (getter)arraydescr_isalignedstruct_get, | ||||||||
2299 | NULL((void*)0), NULL((void*)0), NULL((void*)0)}, | ||||||||
2300 | {"fields", | ||||||||
2301 | (getter)arraydescr_fields_get, | ||||||||
2302 | NULL((void*)0), NULL((void*)0), NULL((void*)0)}, | ||||||||
2303 | {"metadata", | ||||||||
2304 | (getter)arraydescr_metadata_get, | ||||||||
2305 | NULL((void*)0), NULL((void*)0), NULL((void*)0)}, | ||||||||
2306 | {"names", | ||||||||
2307 | (getter)arraydescr_names_get, | ||||||||
2308 | (setter)arraydescr_names_set, | ||||||||
2309 | NULL((void*)0), NULL((void*)0)}, | ||||||||
2310 | {"hasobject", | ||||||||
2311 | (getter)arraydescr_hasobject_get, | ||||||||
2312 | NULL((void*)0), NULL((void*)0), NULL((void*)0)}, | ||||||||
2313 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)}, | ||||||||
2314 | }; | ||||||||
2315 | |||||||||
2316 | static PyObject * | ||||||||
2317 | arraydescr_new(PyTypeObject *subtype, | ||||||||
2318 | PyObject *args, PyObject *kwds) | ||||||||
2319 | { | ||||||||
2320 | if (subtype != &PyArrayDescr_Type(*(PyTypeObject *)(&PyArrayDescr_TypeFull))) { | ||||||||
2321 | /* The DTypeMeta class should prevent this from happening. */ | ||||||||
2322 | PyErr_Format(PyExc_SystemError, | ||||||||
2323 | "'%S' must not inherit np.dtype.__new__().", subtype); | ||||||||
2324 | return NULL((void*)0); | ||||||||
2325 | } | ||||||||
2326 | |||||||||
2327 | PyObject *odescr, *metadata=NULL((void*)0); | ||||||||
2328 | PyArray_Descr *descr, *conv; | ||||||||
2329 | npy_bool align = NPY_FALSE0; | ||||||||
2330 | npy_bool copy = NPY_FALSE0; | ||||||||
2331 | npy_bool copied = NPY_FALSE0; | ||||||||
2332 | |||||||||
2333 | static char *kwlist[] = {"dtype", "align", "copy", "metadata", NULL((void*)0)}; | ||||||||
2334 | |||||||||
2335 | if (!PyArg_ParseTupleAndKeywords_PyArg_ParseTupleAndKeywords_SizeT(args, kwds, "O|O&O&O!:dtype", kwlist, | ||||||||
2336 | &odescr, | ||||||||
2337 | PyArray_BoolConverter, &align, | ||||||||
2338 | PyArray_BoolConverter, ©, | ||||||||
2339 | &PyDict_Type, &metadata)) { | ||||||||
2340 | return NULL((void*)0); | ||||||||
2341 | } | ||||||||
2342 | |||||||||
2343 | conv = _convert_from_any(odescr, align); | ||||||||
2344 | if (conv == NULL((void*)0)) { | ||||||||
2345 | return NULL((void*)0); | ||||||||
2346 | } | ||||||||
2347 | |||||||||
2348 | /* Get a new copy of it unless it's already a copy */ | ||||||||
2349 | if (copy && conv->fields == Py_None(&_Py_NoneStruct)) { | ||||||||
2350 | descr = PyArray_DescrNew(conv); | ||||||||
2351 | Py_DECREF(conv)_Py_DECREF(((PyObject*)(conv))); | ||||||||
2352 | conv = descr; | ||||||||
2353 | copied = NPY_TRUE1; | ||||||||
2354 | } | ||||||||
2355 | |||||||||
2356 | if ((metadata != NULL((void*)0))) { | ||||||||
2357 | /* | ||||||||
2358 | * We need to be sure to make a new copy of the data-type and any | ||||||||
2359 | * underlying dictionary | ||||||||
2360 | */ | ||||||||
2361 | if (!copied) { | ||||||||
2362 | copied = NPY_TRUE1; | ||||||||
2363 | descr = PyArray_DescrNew(conv); | ||||||||
2364 | Py_DECREF(conv)_Py_DECREF(((PyObject*)(conv))); | ||||||||
2365 | conv = descr; | ||||||||
2366 | } | ||||||||
2367 | if ((conv->metadata != NULL((void*)0))) { | ||||||||
2368 | /* | ||||||||
2369 | * Make a copy of the metadata before merging with the | ||||||||
2370 | * input metadata so that this data-type descriptor has | ||||||||
2371 | * it's own copy | ||||||||
2372 | */ | ||||||||
2373 | /* Save a reference */ | ||||||||
2374 | odescr = conv->metadata; | ||||||||
2375 | conv->metadata = PyDict_Copy(odescr); | ||||||||
2376 | /* Decrement the old reference */ | ||||||||
2377 | Py_DECREF(odescr)_Py_DECREF(((PyObject*)(odescr))); | ||||||||
2378 | |||||||||
2379 | /* | ||||||||
2380 | * Update conv->metadata with anything new in metadata | ||||||||
2381 | * keyword, but do not over-write anything already there | ||||||||
2382 | */ | ||||||||
2383 | if (PyDict_Merge(conv->metadata, metadata, 0) != 0) { | ||||||||
2384 | Py_DECREF(conv)_Py_DECREF(((PyObject*)(conv))); | ||||||||
2385 | return NULL((void*)0); | ||||||||
2386 | } | ||||||||
2387 | } | ||||||||
2388 | else { | ||||||||
2389 | /* Make a copy of the input dictionary */ | ||||||||
2390 | conv->metadata = PyDict_Copy(metadata); | ||||||||
2391 | } | ||||||||
2392 | } | ||||||||
2393 | |||||||||
2394 | return (PyObject *)conv; | ||||||||
2395 | } | ||||||||
2396 | |||||||||
2397 | |||||||||
2398 | /* | ||||||||
2399 | * Return a tuple of | ||||||||
2400 | * (cleaned metadata dictionary, tuple with (str, num)) | ||||||||
2401 | */ | ||||||||
2402 | static PyObject * | ||||||||
2403 | _get_pickleabletype_from_datetime_metadata(PyArray_Descr *dtype) | ||||||||
2404 | { | ||||||||
2405 | PyObject *ret, *dt_tuple; | ||||||||
2406 | PyArray_DatetimeMetaData *meta; | ||||||||
2407 | |||||||||
2408 | /* Create the 2-item tuple to return */ | ||||||||
2409 | ret = PyTuple_New(2); | ||||||||
2410 | if (ret == NULL((void*)0)) { | ||||||||
2411 | return NULL((void*)0); | ||||||||
2412 | } | ||||||||
2413 | |||||||||
2414 | /* Store the metadata dictionary */ | ||||||||
2415 | if (dtype->metadata != NULL((void*)0)) { | ||||||||
2416 | Py_INCREF(dtype->metadata)_Py_INCREF(((PyObject*)(dtype->metadata))); | ||||||||
2417 | PyTuple_SET_ITEM(ret, 0, dtype->metadata)PyTuple_SetItem(ret, 0, dtype->metadata); | ||||||||
2418 | } else { | ||||||||
2419 | PyTuple_SET_ITEM(ret, 0, PyDict_New())PyTuple_SetItem(ret, 0, PyDict_New()); | ||||||||
2420 | } | ||||||||
2421 | |||||||||
2422 | /* Convert the datetime metadata into a tuple */ | ||||||||
2423 | meta = get_datetime_metadata_from_dtype(dtype); | ||||||||
2424 | if (meta == NULL((void*)0)) { | ||||||||
2425 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | ||||||||
2426 | return NULL((void*)0); | ||||||||
2427 | } | ||||||||
2428 | /* Use a 4-tuple that numpy 1.6 knows how to unpickle */ | ||||||||
2429 | dt_tuple = PyTuple_New(4); | ||||||||
2430 | if (dt_tuple == NULL((void*)0)) { | ||||||||
2431 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | ||||||||
2432 | return NULL((void*)0); | ||||||||
2433 | } | ||||||||
2434 | PyTuple_SET_ITEM(dt_tuple, 0,PyTuple_SetItem(dt_tuple, 0, PyBytes_FromString(_datetime_strings [meta->base])) | ||||||||
2435 | PyBytes_FromString(_datetime_strings[meta->base]))PyTuple_SetItem(dt_tuple, 0, PyBytes_FromString(_datetime_strings [meta->base])); | ||||||||
2436 | PyTuple_SET_ITEM(dt_tuple, 1,PyTuple_SetItem(dt_tuple, 1, PyLong_FromLong(meta->num)) | ||||||||
2437 | PyLong_FromLong(meta->num))PyTuple_SetItem(dt_tuple, 1, PyLong_FromLong(meta->num)); | ||||||||
2438 | PyTuple_SET_ITEM(dt_tuple, 2,PyTuple_SetItem(dt_tuple, 2, PyLong_FromLong(1)) | ||||||||
2439 | PyLong_FromLong(1))PyTuple_SetItem(dt_tuple, 2, PyLong_FromLong(1)); | ||||||||
2440 | PyTuple_SET_ITEM(dt_tuple, 3,PyTuple_SetItem(dt_tuple, 3, PyLong_FromLong(1)) | ||||||||
2441 | PyLong_FromLong(1))PyTuple_SetItem(dt_tuple, 3, PyLong_FromLong(1)); | ||||||||
2442 | |||||||||
2443 | PyTuple_SET_ITEM(ret, 1, dt_tuple)PyTuple_SetItem(ret, 1, dt_tuple); | ||||||||
2444 | |||||||||
2445 | return ret; | ||||||||
2446 | } | ||||||||
2447 | |||||||||
2448 | /* | ||||||||
2449 | * return a tuple of (callable object, args, state). | ||||||||
2450 | * | ||||||||
2451 | * TODO: This method needs to change so that unpickling doesn't | ||||||||
2452 | * use __setstate__. This is required for the dtype | ||||||||
2453 | * to be an immutable object. | ||||||||
2454 | */ | ||||||||
2455 | static PyObject * | ||||||||
2456 | arraydescr_reduce(PyArray_Descr *self, PyObject *NPY_UNUSED(args)(__NPY_UNUSED_TAGGEDargs) __attribute__ ((__unused__))) | ||||||||
2457 | { | ||||||||
2458 | /* | ||||||||
2459 | * version number of this pickle type. Increment if we need to | ||||||||
2460 | * change the format. Be sure to handle the old versions in | ||||||||
2461 | * arraydescr_setstate. | ||||||||
2462 | */ | ||||||||
2463 | const int version = 4; | ||||||||
2464 | PyObject *ret, *mod, *obj; | ||||||||
2465 | PyObject *state; | ||||||||
2466 | char endian; | ||||||||
2467 | int elsize, alignment; | ||||||||
2468 | |||||||||
2469 | ret = PyTuple_New(3); | ||||||||
2470 | if (ret == NULL((void*)0)) { | ||||||||
2471 | return NULL((void*)0); | ||||||||
2472 | } | ||||||||
2473 | mod = PyImport_ImportModule("numpy.core._multiarray_umath"); | ||||||||
2474 | if (mod == NULL((void*)0)) { | ||||||||
2475 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | ||||||||
2476 | return NULL((void*)0); | ||||||||
2477 | } | ||||||||
2478 | obj = PyObject_GetAttrString(mod, "dtype"); | ||||||||
2479 | Py_DECREF(mod)_Py_DECREF(((PyObject*)(mod))); | ||||||||
2480 | if (obj == NULL((void*)0)) { | ||||||||
2481 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | ||||||||
2482 | return NULL((void*)0); | ||||||||
2483 | } | ||||||||
2484 | PyTuple_SET_ITEM(ret, 0, obj)PyTuple_SetItem(ret, 0, obj); | ||||||||
2485 | if (PyTypeNum_ISUSERDEF(self->type_num)(((self->type_num) >= NPY_USERDEF) && ((self-> type_num) < NPY_USERDEF+ NPY_NUMUSERTYPES)) | ||||||||
2486 | || ((self->type_num == NPY_VOID | ||||||||
2487 | && self->typeobj != &PyVoidArrType_Type))) { | ||||||||
2488 | obj = (PyObject *)self->typeobj; | ||||||||
2489 | Py_INCREF(obj)_Py_INCREF(((PyObject*)(obj))); | ||||||||
2490 | } | ||||||||
2491 | else { | ||||||||
2492 | elsize = self->elsize; | ||||||||
2493 | if (self->type_num == NPY_UNICODE) { | ||||||||
2494 | elsize >>= 2; | ||||||||
2495 | } | ||||||||
2496 | obj = PyUnicode_FromFormat("%c%d",self->kind, elsize); | ||||||||
2497 | } | ||||||||
2498 | PyTuple_SET_ITEM(ret, 1, Py_BuildValue("(NOO)", obj, Py_False, Py_True))PyTuple_SetItem(ret, 1, _Py_BuildValue_SizeT("(NOO)", obj, (( PyObject *) &_Py_FalseStruct), ((PyObject *) &_Py_TrueStruct ))); | ||||||||
2499 | |||||||||
2500 | /* | ||||||||
2501 | * Now return the state which is at least byteorder, | ||||||||
2502 | * subarray, and fields | ||||||||
2503 | */ | ||||||||
2504 | endian = self->byteorder; | ||||||||
2505 | if (endian == '=') { | ||||||||
2506 | endian = '<'; | ||||||||
2507 | if (!PyArray_IsNativeByteOrder(endian)((endian) != '>')) { | ||||||||
2508 | endian = '>'; | ||||||||
2509 | } | ||||||||
2510 | } | ||||||||
2511 | if (PyDataType_ISDATETIME(self)(((((PyArray_Descr*)(self))->type_num) >=NPY_DATETIME) && ((((PyArray_Descr*)(self))->type_num) <=NPY_TIMEDELTA) )) { | ||||||||
2512 | PyObject *newobj; | ||||||||
2513 | state = PyTuple_New(9); | ||||||||
2514 | PyTuple_SET_ITEM(state, 0, PyLong_FromLong(version))PyTuple_SetItem(state, 0, PyLong_FromLong(version)); | ||||||||
2515 | /* | ||||||||
2516 | * newobj is a tuple of the Python metadata dictionary | ||||||||
2517 | * and tuple of date_time info (str, num) | ||||||||
2518 | */ | ||||||||
2519 | newobj = _get_pickleabletype_from_datetime_metadata(self); | ||||||||
2520 | if (newobj == NULL((void*)0)) { | ||||||||
2521 | Py_DECREF(state)_Py_DECREF(((PyObject*)(state))); | ||||||||
2522 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | ||||||||
2523 | return NULL((void*)0); | ||||||||
2524 | } | ||||||||
2525 | PyTuple_SET_ITEM(state, 8, newobj)PyTuple_SetItem(state, 8, newobj); | ||||||||
2526 | } | ||||||||
2527 | else if (self->metadata) { | ||||||||
2528 | state = PyTuple_New(9); | ||||||||
2529 | PyTuple_SET_ITEM(state, 0, PyLong_FromLong(version))PyTuple_SetItem(state, 0, PyLong_FromLong(version)); | ||||||||
2530 | Py_INCREF(self->metadata)_Py_INCREF(((PyObject*)(self->metadata))); | ||||||||
2531 | PyTuple_SET_ITEM(state, 8, self->metadata)PyTuple_SetItem(state, 8, self->metadata); | ||||||||
2532 | } | ||||||||
2533 | else { /* Use version 3 pickle format */ | ||||||||
2534 | state = PyTuple_New(8); | ||||||||
2535 | PyTuple_SET_ITEM(state, 0, PyLong_FromLong(3))PyTuple_SetItem(state, 0, PyLong_FromLong(3)); | ||||||||
2536 | } | ||||||||
2537 | |||||||||
2538 | PyTuple_SET_ITEM(state, 1, PyUnicode_FromFormat("%c", endian))PyTuple_SetItem(state, 1, PyUnicode_FromFormat("%c", endian)); | ||||||||
2539 | PyTuple_SET_ITEM(state, 2, arraydescr_subdescr_get(self))PyTuple_SetItem(state, 2, arraydescr_subdescr_get(self)); | ||||||||
2540 | if (PyDataType_HASFIELDS(self)(((PyArray_Descr *)(self))->names != ((void*)0))) { | ||||||||
2541 | Py_INCREF(self->names)_Py_INCREF(((PyObject*)(self->names))); | ||||||||
2542 | Py_INCREF(self->fields)_Py_INCREF(((PyObject*)(self->fields))); | ||||||||
2543 | PyTuple_SET_ITEM(state, 3, self->names)PyTuple_SetItem(state, 3, self->names); | ||||||||
2544 | PyTuple_SET_ITEM(state, 4, self->fields)PyTuple_SetItem(state, 4, self->fields); | ||||||||
2545 | } | ||||||||
2546 | else { | ||||||||
2547 | PyTuple_SET_ITEM(state, 3, Py_None)PyTuple_SetItem(state, 3, (&_Py_NoneStruct)); | ||||||||
2548 | PyTuple_SET_ITEM(state, 4, Py_None)PyTuple_SetItem(state, 4, (&_Py_NoneStruct)); | ||||||||
2549 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | ||||||||
2550 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | ||||||||
2551 | } | ||||||||
2552 | |||||||||
2553 | /* for extended types it also includes elsize and alignment */ | ||||||||
2554 | if (PyTypeNum_ISEXTENDED(self->type_num)((((self->type_num) >=NPY_STRING) && ((self-> type_num) <=NPY_VOID)) || (((self->type_num) >= NPY_USERDEF ) && ((self->type_num) < NPY_USERDEF+ NPY_NUMUSERTYPES )))) { | ||||||||
2555 | elsize = self->elsize; | ||||||||
2556 | alignment = self->alignment; | ||||||||
2557 | } | ||||||||
2558 | else { | ||||||||
2559 | elsize = -1; | ||||||||
2560 | alignment = -1; | ||||||||
2561 | } | ||||||||
2562 | PyTuple_SET_ITEM(state, 5, PyLong_FromLong(elsize))PyTuple_SetItem(state, 5, PyLong_FromLong(elsize)); | ||||||||
2563 | PyTuple_SET_ITEM(state, 6, PyLong_FromLong(alignment))PyTuple_SetItem(state, 6, PyLong_FromLong(alignment)); | ||||||||
2564 | PyTuple_SET_ITEM(state, 7, PyLong_FromLong(self->flags))PyTuple_SetItem(state, 7, PyLong_FromLong(self->flags)); | ||||||||
2565 | |||||||||
2566 | PyTuple_SET_ITEM(ret, 2, state)PyTuple_SetItem(ret, 2, state); | ||||||||
2567 | return ret; | ||||||||
2568 | } | ||||||||
2569 | |||||||||
2570 | /* | ||||||||
2571 | * returns NPY_OBJECT_DTYPE_FLAGS if this data-type has an object portion used | ||||||||
2572 | * when setting the state because hasobject is not stored. | ||||||||
2573 | */ | ||||||||
2574 | static char | ||||||||
2575 | _descr_find_object(PyArray_Descr *self) | ||||||||
2576 | { | ||||||||
2577 | if (self->flags | ||||||||
2578 | || self->type_num == NPY_OBJECT | ||||||||
2579 | || self->kind == 'O') { | ||||||||
2580 | return NPY_OBJECT_DTYPE_FLAGS(0x02 | 0x20 | 0x04 | 0x01 | 0x08 | 0x10); | ||||||||
2581 | } | ||||||||
2582 | if (PyDataType_HASFIELDS(self)(((PyArray_Descr *)(self))->names != ((void*)0))) { | ||||||||
2583 | PyObject *key, *value, *title = NULL((void*)0); | ||||||||
2584 | PyArray_Descr *new; | ||||||||
2585 | int offset; | ||||||||
2586 | Py_ssize_t pos = 0; | ||||||||
2587 | |||||||||
2588 | while (PyDict_Next(self->fields, &pos, &key, &value)) { | ||||||||
2589 | if (NPY_TITLE_KEY(key, value)(NPY_TITLE_KEY_check((key), (value)))) { | ||||||||
2590 | continue; | ||||||||
2591 | } | ||||||||
2592 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(value, "Oi|O", &new, &offset, &title)) { | ||||||||
2593 | PyErr_Clear(); | ||||||||
2594 | return 0; | ||||||||
2595 | } | ||||||||
2596 | if (_descr_find_object(new)) { | ||||||||
2597 | new->flags = NPY_OBJECT_DTYPE_FLAGS(0x02 | 0x20 | 0x04 | 0x01 | 0x08 | 0x10); | ||||||||
2598 | return NPY_OBJECT_DTYPE_FLAGS(0x02 | 0x20 | 0x04 | 0x01 | 0x08 | 0x10); | ||||||||
2599 | } | ||||||||
2600 | } | ||||||||
2601 | } | ||||||||
2602 | return 0; | ||||||||
2603 | } | ||||||||
2604 | |||||||||
2605 | /* | ||||||||
2606 | * state is at least byteorder, subarray, and fields but could include elsize | ||||||||
2607 | * and alignment for EXTENDED arrays | ||||||||
2608 | */ | ||||||||
2609 | static PyObject * | ||||||||
2610 | arraydescr_setstate(PyArray_Descr *self, PyObject *args) | ||||||||
2611 | { | ||||||||
2612 | int elsize = -1, alignment = -1; | ||||||||
2613 | int version = 4; | ||||||||
2614 | char endian; | ||||||||
2615 | PyObject *endian_obj; | ||||||||
2616 | PyObject *subarray, *fields, *names = NULL((void*)0), *metadata=NULL((void*)0); | ||||||||
2617 | int incref_names = 1; | ||||||||
2618 | int int_dtypeflags = 0; | ||||||||
2619 | char dtypeflags; | ||||||||
2620 | |||||||||
2621 | if (self->fields == Py_None(&_Py_NoneStruct)) { | ||||||||
| |||||||||
2622 | Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (& _Py_NoneStruct); | ||||||||
2623 | } | ||||||||
2624 | if (PyTuple_GET_SIZE(args)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(args))))-> ob_size) != 1 | ||||||||
2625 | || !(PyTuple_Check(PyTuple_GET_ITEM(args, 0))((((((PyObject*)(((((void) (0)), (PyTupleObject *)(args))-> ob_item[0])))->ob_type))->tp_flags & ((1UL << 26))) != 0))) { | ||||||||
2626 | PyErr_BadInternalCall()_PyErr_BadInternalCall("numpy/core/src/multiarray/descriptor.c" , 2626); | ||||||||
2627 | return NULL((void*)0); | ||||||||
2628 | } | ||||||||
2629 | switch (PyTuple_GET_SIZE(PyTuple_GET_ITEM(args,0))(((PyVarObject*)((((void) (0)), (PyTupleObject *)(((((void) ( 0)), (PyTupleObject *)(args))->ob_item[0])))))->ob_size )) { | ||||||||
2630 | case 9: | ||||||||
2631 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "(iOOOOiiiO):__setstate__", | ||||||||
2632 | &version, &endian_obj, | ||||||||
2633 | &subarray, &names, &fields, &elsize, | ||||||||
2634 | &alignment, &int_dtypeflags, &metadata)) { | ||||||||
2635 | PyErr_Clear(); | ||||||||
2636 | return NULL((void*)0); | ||||||||
2637 | } | ||||||||
2638 | break; | ||||||||
2639 | case 8: | ||||||||
2640 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "(iOOOOiii):__setstate__", | ||||||||
2641 | &version, &endian_obj, | ||||||||
2642 | &subarray, &names, &fields, &elsize, | ||||||||
2643 | &alignment, &int_dtypeflags)) { | ||||||||
2644 | return NULL((void*)0); | ||||||||
2645 | } | ||||||||
2646 | break; | ||||||||
2647 | case 7: | ||||||||
2648 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "(iOOOOii):__setstate__", | ||||||||
2649 | &version, &endian_obj, | ||||||||
2650 | &subarray, &names, &fields, &elsize, | ||||||||
2651 | &alignment)) { | ||||||||
2652 | return NULL((void*)0); | ||||||||
2653 | } | ||||||||
2654 | break; | ||||||||
2655 | case 6: | ||||||||
2656 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "(iOOOii):__setstate__", | ||||||||
2657 | &version, | ||||||||
2658 | &endian_obj, &subarray, &fields, | ||||||||
2659 | &elsize, &alignment)) { | ||||||||
2660 | return NULL((void*)0); | ||||||||
2661 | } | ||||||||
2662 | break; | ||||||||
2663 | case 5: | ||||||||
2664 | version = 0; | ||||||||
2665 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "(OOOii):__setstate__", | ||||||||
2666 | &endian_obj, &subarray, &fields, &elsize, | ||||||||
2667 | &alignment)) { | ||||||||
2668 | return NULL((void*)0); | ||||||||
2669 | } | ||||||||
2670 | break; | ||||||||
2671 | default: | ||||||||
2672 | /* raise an error */ | ||||||||
2673 | if (PyTuple_GET_SIZE(PyTuple_GET_ITEM(args,0))(((PyVarObject*)((((void) (0)), (PyTupleObject *)(((((void) ( 0)), (PyTupleObject *)(args))->ob_item[0])))))->ob_size ) > 5) { | ||||||||
2674 | version = PyLong_AsLong(PyTuple_GET_ITEM(args, 0)((((void) (0)), (PyTupleObject *)(args))->ob_item[0])); | ||||||||
2675 | } | ||||||||
2676 | else { | ||||||||
2677 | version = -1; | ||||||||
2678 | } | ||||||||
2679 | } | ||||||||
2680 | |||||||||
2681 | /* | ||||||||
2682 | * If we ever need another pickle format, increment the version | ||||||||
2683 | * number. But we should still be able to handle the old versions. | ||||||||
2684 | */ | ||||||||
2685 | if (version
| ||||||||
2686 | PyErr_Format(PyExc_ValueError, | ||||||||
2687 | "can't handle version %d of numpy.dtype pickle", | ||||||||
2688 | version); | ||||||||
2689 | return NULL((void*)0); | ||||||||
2690 | } | ||||||||
2691 | /* Invalidate cached hash value */ | ||||||||
2692 | self->hash = -1; | ||||||||
2693 | |||||||||
2694 | if (version
| ||||||||
2695 | if (fields != Py_None(&_Py_NoneStruct)) { | ||||||||
2696 | PyObject *key, *list; | ||||||||
2697 | key = PyLong_FromLong(-1); | ||||||||
2698 | list = PyDict_GetItemWithError(fields, key); | ||||||||
2699 | if (!list) { | ||||||||
2700 | if (!PyErr_Occurred()) { | ||||||||
2701 | /* fields was missing the name it claimed to contain */ | ||||||||
2702 | PyErr_BadInternalCall()_PyErr_BadInternalCall("numpy/core/src/multiarray/descriptor.c" , 2702); | ||||||||
2703 | } | ||||||||
2704 | return NULL((void*)0); | ||||||||
2705 | } | ||||||||
2706 | Py_INCREF(list)_Py_INCREF(((PyObject*)(list))); | ||||||||
2707 | names = list; | ||||||||
2708 | PyDict_DelItem(fields, key); | ||||||||
2709 | incref_names = 0; | ||||||||
2710 | } | ||||||||
2711 | else { | ||||||||
2712 | names = Py_None(&_Py_NoneStruct); | ||||||||
2713 | } | ||||||||
2714 | } | ||||||||
2715 | |||||||||
2716 | /* Parse endian */ | ||||||||
2717 | if (PyUnicode_Check(endian_obj)((((((PyObject*)(endian_obj))->ob_type))->tp_flags & ((1UL << 28))) != 0) || PyBytes_Check(endian_obj)((((((PyObject*)(endian_obj))->ob_type))->tp_flags & ((1UL << 27))) != 0)) { | ||||||||
2718 | PyObject *tmp = NULL((void*)0); | ||||||||
2719 | char *str; | ||||||||
2720 | Py_ssize_t len; | ||||||||
2721 | |||||||||
2722 | if (PyUnicode_Check(endian_obj)((((((PyObject*)(endian_obj))->ob_type))->tp_flags & ((1UL << 28))) != 0)) { | ||||||||
2723 | tmp = PyUnicode_AsASCIIString(endian_obj); | ||||||||
2724 | if (tmp == NULL((void*)0)) { | ||||||||
2725 | return NULL((void*)0); | ||||||||
2726 | } | ||||||||
2727 | endian_obj = tmp; | ||||||||
2728 | } | ||||||||
2729 | |||||||||
2730 | if (PyBytes_AsStringAndSize(endian_obj, &str, &len) < 0) { | ||||||||
2731 | Py_XDECREF(tmp)_Py_XDECREF(((PyObject*)(tmp))); | ||||||||
2732 | return NULL((void*)0); | ||||||||
2733 | } | ||||||||
2734 | if (len != 1) { | ||||||||
2735 | PyErr_SetString(PyExc_ValueError, | ||||||||
2736 | "endian is not 1-char string in Numpy dtype unpickling"); | ||||||||
2737 | Py_XDECREF(tmp)_Py_XDECREF(((PyObject*)(tmp))); | ||||||||
2738 | return NULL((void*)0); | ||||||||
2739 | } | ||||||||
2740 | endian = str[0]; | ||||||||
2741 | Py_XDECREF(tmp)_Py_XDECREF(((PyObject*)(tmp))); | ||||||||
2742 | } | ||||||||
2743 | else { | ||||||||
2744 | PyErr_SetString(PyExc_ValueError, | ||||||||
2745 | "endian is not a string in Numpy dtype unpickling"); | ||||||||
2746 | return NULL((void*)0); | ||||||||
2747 | } | ||||||||
2748 | |||||||||
2749 | if ((fields == Py_None(&_Py_NoneStruct) && names != Py_None(&_Py_NoneStruct)) || | ||||||||
2750 | (names == Py_None(&_Py_NoneStruct) && fields != Py_None(&_Py_NoneStruct))) { | ||||||||
2751 | PyErr_Format(PyExc_ValueError, | ||||||||
2752 | "inconsistent fields and names in Numpy dtype unpickling"); | ||||||||
2753 | return NULL((void*)0); | ||||||||
2754 | } | ||||||||
2755 | |||||||||
2756 | if (names != Py_None(&_Py_NoneStruct) && !PyTuple_Check(names)((((((PyObject*)(names))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { | ||||||||
2757 | PyErr_Format(PyExc_ValueError, | ||||||||
2758 | "non-tuple names in Numpy dtype unpickling"); | ||||||||
2759 | return NULL((void*)0); | ||||||||
2760 | } | ||||||||
2761 | |||||||||
2762 | if (fields != Py_None(&_Py_NoneStruct) && !PyDict_Check(fields)((((((PyObject*)(fields))->ob_type))->tp_flags & (( 1UL << 29))) != 0)) { | ||||||||
2763 | PyErr_Format(PyExc_ValueError, | ||||||||
2764 | "non-dict fields in Numpy dtype unpickling"); | ||||||||
2765 | return NULL((void*)0); | ||||||||
2766 | } | ||||||||
2767 | |||||||||
2768 | if (endian != '|' && PyArray_IsNativeByteOrder(endian)((endian) != '>')) { | ||||||||
2769 | endian = '='; | ||||||||
2770 | } | ||||||||
2771 | self->byteorder = endian; | ||||||||
2772 | if (self->subarray) { | ||||||||
2773 | Py_XDECREF(self->subarray->base)_Py_XDECREF(((PyObject*)(self->subarray->base))); | ||||||||
2774 | Py_XDECREF(self->subarray->shape)_Py_XDECREF(((PyObject*)(self->subarray->shape))); | ||||||||
2775 | PyArray_freePyMem_RawFree(self->subarray); | ||||||||
2776 | } | ||||||||
2777 | self->subarray = NULL((void*)0); | ||||||||
2778 | |||||||||
2779 | if (subarray != Py_None(&_Py_NoneStruct)) { | ||||||||
2780 | PyObject *subarray_shape; | ||||||||
2781 | |||||||||
2782 | /* | ||||||||
2783 | * Ensure that subarray[0] is an ArrayDescr and | ||||||||
2784 | * that subarray_shape obtained from subarray[1] is a tuple of integers. | ||||||||
2785 | */ | ||||||||
2786 | if (!(PyTuple_Check(subarray)((((((PyObject*)(subarray))->ob_type))->tp_flags & ( (1UL << 26))) != 0) && | ||||||||
2787 | PyTuple_Size(subarray) == 2 && | ||||||||
2788 | PyArray_DescrCheck(PyTuple_GET_ITEM(subarray, 0))((((PyObject*)(((((void) (0)), (PyTupleObject *)(subarray))-> ob_item[0])))->ob_type) == (&(*(PyTypeObject *)(&PyArrayDescr_TypeFull ))) || PyType_IsSubtype((((PyObject*)(((((void) (0)), (PyTupleObject *)(subarray))->ob_item[0])))->ob_type), (&(*(PyTypeObject *)(&PyArrayDescr_TypeFull))))))) { | ||||||||
2789 | PyErr_Format(PyExc_ValueError, | ||||||||
2790 | "incorrect subarray in __setstate__"); | ||||||||
2791 | return NULL((void*)0); | ||||||||
2792 | } | ||||||||
2793 | subarray_shape = PyTuple_GET_ITEM(subarray, 1)((((void) (0)), (PyTupleObject *)(subarray))->ob_item[1]); | ||||||||
2794 | if (PyNumber_Check(subarray_shape)) { | ||||||||
2795 | PyObject *tmp; | ||||||||
2796 | tmp = PyNumber_Long(subarray_shape); | ||||||||
2797 | if (tmp == NULL((void*)0)) { | ||||||||
2798 | return NULL((void*)0); | ||||||||
2799 | } | ||||||||
2800 | subarray_shape = Py_BuildValue_Py_BuildValue_SizeT("(O)", tmp); | ||||||||
| |||||||||
2801 | Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp))); | ||||||||
2802 | if (subarray_shape == NULL((void*)0)) { | ||||||||
2803 | return NULL((void*)0); | ||||||||
2804 | } | ||||||||
2805 | } | ||||||||
2806 | else if (_is_tuple_of_integers(subarray_shape)) { | ||||||||
2807 | Py_INCREF(subarray_shape)_Py_INCREF(((PyObject*)(subarray_shape))); | ||||||||
2808 | } | ||||||||
2809 | else { | ||||||||
2810 | PyErr_Format(PyExc_ValueError, | ||||||||
2811 | "incorrect subarray shape in __setstate__"); | ||||||||
2812 | return NULL((void*)0); | ||||||||
2813 | } | ||||||||
2814 | |||||||||
2815 | self->subarray = PyArray_mallocPyMem_RawMalloc(sizeof(PyArray_ArrayDescr)); | ||||||||
2816 | if (!PyDataType_HASSUBARRAY(self)((self)->subarray != ((void*)0))) { | ||||||||
2817 | return PyErr_NoMemory(); | ||||||||
2818 | } | ||||||||
2819 | self->subarray->base = (PyArray_Descr *)PyTuple_GET_ITEM(subarray, 0)((((void) (0)), (PyTupleObject *)(subarray))->ob_item[0]); | ||||||||
2820 | Py_INCREF(self->subarray->base)_Py_INCREF(((PyObject*)(self->subarray->base))); | ||||||||
2821 | self->subarray->shape = subarray_shape; | ||||||||
2822 | } | ||||||||
2823 | |||||||||
2824 | if (fields != Py_None(&_Py_NoneStruct)) { | ||||||||
2825 | /* | ||||||||
2826 | * Ensure names are of appropriate string type | ||||||||
2827 | */ | ||||||||
2828 | Py_ssize_t i; | ||||||||
2829 | int names_ok = 1; | ||||||||
2830 | PyObject *name; | ||||||||
2831 | |||||||||
2832 | for (i = 0; i < PyTuple_GET_SIZE(names)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(names))))-> ob_size); ++i) { | ||||||||
2833 | name = PyTuple_GET_ITEM(names, i)((((void) (0)), (PyTupleObject *)(names))->ob_item[i]); | ||||||||
2834 | if (!PyUnicode_Check(name)((((((PyObject*)(name))->ob_type))->tp_flags & ((1UL << 28))) != 0)) { | ||||||||
2835 | names_ok = 0; | ||||||||
2836 | break; | ||||||||
2837 | } | ||||||||
2838 | } | ||||||||
2839 | |||||||||
2840 | if (names_ok) { | ||||||||
2841 | Py_XDECREF(self->fields)_Py_XDECREF(((PyObject*)(self->fields))); | ||||||||
2842 | self->fields = fields; | ||||||||
2843 | Py_INCREF(fields)_Py_INCREF(((PyObject*)(fields))); | ||||||||
2844 | Py_XDECREF(self->names)_Py_XDECREF(((PyObject*)(self->names))); | ||||||||
2845 | self->names = names; | ||||||||
2846 | if (incref_names) { | ||||||||
2847 | Py_INCREF(names)_Py_INCREF(((PyObject*)(names))); | ||||||||
2848 | } | ||||||||
2849 | } | ||||||||
2850 | else { | ||||||||
2851 | /* | ||||||||
2852 | * To support pickle.load(f, encoding='bytes') for loading Py2 | ||||||||
2853 | * generated pickles on Py3, we need to be more lenient and convert | ||||||||
2854 | * field names from byte strings to unicode. | ||||||||
2855 | */ | ||||||||
2856 | PyObject *tmp, *new_name, *field; | ||||||||
2857 | |||||||||
2858 | tmp = PyDict_New(); | ||||||||
2859 | if (tmp == NULL((void*)0)) { | ||||||||
2860 | return NULL((void*)0); | ||||||||
2861 | } | ||||||||
2862 | Py_XDECREF(self->fields)_Py_XDECREF(((PyObject*)(self->fields))); | ||||||||
2863 | self->fields = tmp; | ||||||||
2864 | |||||||||
2865 | tmp = PyTuple_New(PyTuple_GET_SIZE(names)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(names))))-> ob_size)); | ||||||||
2866 | if (tmp == NULL((void*)0)) { | ||||||||
2867 | return NULL((void*)0); | ||||||||
2868 | } | ||||||||
2869 | Py_XDECREF(self->names)_Py_XDECREF(((PyObject*)(self->names))); | ||||||||
2870 | self->names = tmp; | ||||||||
2871 | |||||||||
2872 | for (i = 0; i < PyTuple_GET_SIZE(names)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(names))))-> ob_size); ++i) { | ||||||||
2873 | name = PyTuple_GET_ITEM(names, i)((((void) (0)), (PyTupleObject *)(names))->ob_item[i]); | ||||||||
2874 | field = PyDict_GetItemWithError(fields, name); | ||||||||
2875 | if (!field) { | ||||||||
2876 | if (!PyErr_Occurred()) { | ||||||||
2877 | /* fields was missing the name it claimed to contain */ | ||||||||
2878 | PyErr_BadInternalCall()_PyErr_BadInternalCall("numpy/core/src/multiarray/descriptor.c" , 2878); | ||||||||
2879 | } | ||||||||
2880 | return NULL((void*)0); | ||||||||
2881 | } | ||||||||
2882 | |||||||||
2883 | if (PyUnicode_Check(name)((((((PyObject*)(name))->ob_type))->tp_flags & ((1UL << 28))) != 0)) { | ||||||||
2884 | new_name = name; | ||||||||
2885 | Py_INCREF(new_name)_Py_INCREF(((PyObject*)(new_name))); | ||||||||
2886 | } | ||||||||
2887 | else { | ||||||||
2888 | new_name = PyUnicode_FromEncodedObject(name, "ASCII", "strict"); | ||||||||
2889 | if (new_name == NULL((void*)0)) { | ||||||||
2890 | return NULL((void*)0); | ||||||||
2891 | } | ||||||||
2892 | } | ||||||||
2893 | |||||||||
2894 | PyTuple_SET_ITEM(self->names, i, new_name)PyTuple_SetItem(self->names, i, new_name); | ||||||||
2895 | if (PyDict_SetItem(self->fields, new_name, field) != 0) { | ||||||||
2896 | return NULL((void*)0); | ||||||||
2897 | } | ||||||||
2898 | } | ||||||||
2899 | } | ||||||||
2900 | } | ||||||||
2901 | |||||||||
2902 | if (PyTypeNum_ISEXTENDED(self->type_num)((((self->type_num) >=NPY_STRING) && ((self-> type_num) <=NPY_VOID)) || (((self->type_num) >= NPY_USERDEF ) && ((self->type_num) < NPY_USERDEF+ NPY_NUMUSERTYPES )))) { | ||||||||
2903 | self->elsize = elsize; | ||||||||
2904 | self->alignment = alignment; | ||||||||
2905 | } | ||||||||
2906 | |||||||||
2907 | /* | ||||||||
2908 | * We use an integer converted to char for backward compatibility with | ||||||||
2909 | * pickled arrays. Pickled arrays created with previous versions encoded | ||||||||
2910 | * flags as an int even though it actually was a char in the PyArray_Descr | ||||||||
2911 | * structure | ||||||||
2912 | */ | ||||||||
2913 | dtypeflags = int_dtypeflags; | ||||||||
2914 | if (dtypeflags != int_dtypeflags) { | ||||||||
2915 | PyErr_Format(PyExc_ValueError, | ||||||||
2916 | "incorrect value for flags variable (overflow)"); | ||||||||
2917 | return NULL((void*)0); | ||||||||
2918 | } | ||||||||
2919 | else { | ||||||||
2920 | self->flags = dtypeflags; | ||||||||
2921 | } | ||||||||
2922 | |||||||||
2923 | if (version < 3) { | ||||||||
2924 | self->flags = _descr_find_object(self); | ||||||||
2925 | } | ||||||||
2926 | |||||||||
2927 | /* | ||||||||
2928 | * We have a borrowed reference to metadata so no need | ||||||||
2929 | * to alter reference count when throwing away Py_None. | ||||||||
2930 | */ | ||||||||
2931 | if (metadata == Py_None(&_Py_NoneStruct)) { | ||||||||
2932 | metadata = NULL((void*)0); | ||||||||
2933 | } | ||||||||
2934 | |||||||||
2935 | if (PyDataType_ISDATETIME(self)(((((PyArray_Descr*)(self))->type_num) >=NPY_DATETIME) && ((((PyArray_Descr*)(self))->type_num) <=NPY_TIMEDELTA) ) && (metadata != NULL((void*)0))) { | ||||||||
2936 | PyObject *old_metadata; | ||||||||
2937 | PyArray_DatetimeMetaData temp_dt_data; | ||||||||
2938 | |||||||||
2939 | if ((! PyTuple_Check(metadata)((((((PyObject*)(metadata))->ob_type))->tp_flags & ( (1UL << 26))) != 0)) || (PyTuple_Size(metadata) != 2)) { | ||||||||
2940 | PyErr_Format(PyExc_ValueError, | ||||||||
2941 | "Invalid datetime dtype (metadata, c_metadata): %R", | ||||||||
2942 | metadata); | ||||||||
2943 | return NULL((void*)0); | ||||||||
2944 | } | ||||||||
2945 | |||||||||
2946 | if (convert_datetime_metadata_tuple_to_datetime_metadata( | ||||||||
2947 | PyTuple_GET_ITEM(metadata, 1)((((void) (0)), (PyTupleObject *)(metadata))->ob_item[1]), | ||||||||
2948 | &temp_dt_data, | ||||||||
2949 | NPY_TRUE1) < 0) { | ||||||||
2950 | return NULL((void*)0); | ||||||||
2951 | } | ||||||||
2952 | |||||||||
2953 | old_metadata = self->metadata; | ||||||||
2954 | self->metadata = PyTuple_GET_ITEM(metadata, 0)((((void) (0)), (PyTupleObject *)(metadata))->ob_item[0]); | ||||||||
2955 | memcpy((char *) &((PyArray_DatetimeDTypeMetaData *)self->c_metadata)->meta, | ||||||||
2956 | (char *) &temp_dt_data, | ||||||||
2957 | sizeof(PyArray_DatetimeMetaData)); | ||||||||
2958 | Py_XINCREF(self->metadata)_Py_XINCREF(((PyObject*)(self->metadata))); | ||||||||
2959 | Py_XDECREF(old_metadata)_Py_XDECREF(((PyObject*)(old_metadata))); | ||||||||
2960 | } | ||||||||
2961 | else { | ||||||||
2962 | PyObject *old_metadata = self->metadata; | ||||||||
2963 | self->metadata = metadata; | ||||||||
2964 | Py_XINCREF(self->metadata)_Py_XINCREF(((PyObject*)(self->metadata))); | ||||||||
2965 | Py_XDECREF(old_metadata)_Py_XDECREF(((PyObject*)(old_metadata))); | ||||||||
2966 | } | ||||||||
2967 | |||||||||
2968 | Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (& _Py_NoneStruct); | ||||||||
2969 | } | ||||||||
2970 | |||||||||
2971 | /*NUMPY_API | ||||||||
2972 | * | ||||||||
2973 | * Get type-descriptor from an object forcing alignment if possible | ||||||||
2974 | * None goes to DEFAULT type. | ||||||||
2975 | * | ||||||||
2976 | * any object with the .fields attribute and/or .itemsize attribute (if the | ||||||||
2977 | *.fields attribute does not give the total size -- i.e. a partial record | ||||||||
2978 | * naming). If itemsize is given it must be >= size computed from fields | ||||||||
2979 | * | ||||||||
2980 | * The .fields attribute must return a convertible dictionary if present. | ||||||||
2981 | * Result inherits from NPY_VOID. | ||||||||
2982 | */ | ||||||||
2983 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) int | ||||||||
2984 | PyArray_DescrAlignConverter(PyObject *obj, PyArray_Descr **at) | ||||||||
2985 | { | ||||||||
2986 | *at = _convert_from_any(obj, 1); | ||||||||
2987 | return (*at) ? NPY_SUCCEED1 : NPY_FAIL0; | ||||||||
2988 | } | ||||||||
2989 | |||||||||
2990 | /*NUMPY_API | ||||||||
2991 | * | ||||||||
2992 | * Get type-descriptor from an object forcing alignment if possible | ||||||||
2993 | * None goes to NULL. | ||||||||
2994 | */ | ||||||||
2995 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) int | ||||||||
2996 | PyArray_DescrAlignConverter2(PyObject *obj, PyArray_Descr **at) | ||||||||
2997 | { | ||||||||
2998 | if (obj == Py_None(&_Py_NoneStruct)) { | ||||||||
2999 | *at = NULL((void*)0); | ||||||||
3000 | return NPY_SUCCEED1; | ||||||||
3001 | } | ||||||||
3002 | else { | ||||||||
3003 | return PyArray_DescrAlignConverter(obj, at); | ||||||||
3004 | } | ||||||||
3005 | } | ||||||||
3006 | |||||||||
3007 | |||||||||
3008 | |||||||||
3009 | /*NUMPY_API | ||||||||
3010 | * | ||||||||
3011 | * returns a copy of the PyArray_Descr structure with the byteorder | ||||||||
3012 | * altered: | ||||||||
3013 | * no arguments: The byteorder is swapped (in all subfields as well) | ||||||||
3014 | * single argument: The byteorder is forced to the given state | ||||||||
3015 | * (in all subfields as well) | ||||||||
3016 | * | ||||||||
3017 | * Valid states: ('big', '>') or ('little' or '<') | ||||||||
3018 | * ('native', or '=') | ||||||||
3019 | * | ||||||||
3020 | * If a descr structure with | is encountered it's own | ||||||||
3021 | * byte-order is not changed but any fields are: | ||||||||
3022 | * | ||||||||
3023 | * | ||||||||
3024 | * Deep bytorder change of a data-type descriptor | ||||||||
3025 | * *** Leaves reference count of self unchanged --- does not DECREF self *** | ||||||||
3026 | */ | ||||||||
3027 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyArray_Descr * | ||||||||
3028 | PyArray_DescrNewByteorder(PyArray_Descr *self, char newendian) | ||||||||
3029 | { | ||||||||
3030 | PyArray_Descr *new; | ||||||||
3031 | char endian; | ||||||||
3032 | |||||||||
3033 | new = PyArray_DescrNew(self); | ||||||||
3034 | endian = new->byteorder; | ||||||||
3035 | if (endian != NPY_IGNORE'|') { | ||||||||
3036 | if (newendian == NPY_SWAP's') { | ||||||||
3037 | /* swap byteorder */ | ||||||||
3038 | if (PyArray_ISNBO(endian)((endian) != '>')) { | ||||||||
3039 | endian = NPY_OPPBYTE'>'; | ||||||||
3040 | } | ||||||||
3041 | else { | ||||||||
3042 | endian = NPY_NATBYTE'<'; | ||||||||
3043 | } | ||||||||
3044 | new->byteorder = endian; | ||||||||
3045 | } | ||||||||
3046 | else if (newendian != NPY_IGNORE'|') { | ||||||||
3047 | new->byteorder = newendian; | ||||||||
3048 | } | ||||||||
3049 | } | ||||||||
3050 | if (PyDataType_HASFIELDS(new)(((PyArray_Descr *)(new))->names != ((void*)0))) { | ||||||||
3051 | PyObject *newfields; | ||||||||
3052 | PyObject *key, *value; | ||||||||
3053 | PyObject *newvalue; | ||||||||
3054 | PyObject *old; | ||||||||
3055 | PyArray_Descr *newdescr; | ||||||||
3056 | Py_ssize_t pos = 0; | ||||||||
3057 | int len, i; | ||||||||
3058 | |||||||||
3059 | newfields = PyDict_New(); | ||||||||
3060 | /* make new dictionary with replaced PyArray_Descr Objects */ | ||||||||
3061 | while (PyDict_Next(self->fields, &pos, &key, &value)) { | ||||||||
3062 | if (NPY_TITLE_KEY(key, value)(NPY_TITLE_KEY_check((key), (value)))) { | ||||||||
3063 | continue; | ||||||||
3064 | } | ||||||||
3065 | if (!PyUnicode_Check(key)((((((PyObject*)(key))->ob_type))->tp_flags & ((1UL << 28))) != 0) || !PyTuple_Check(value)((((((PyObject*)(value))->ob_type))->tp_flags & ((1UL << 26))) != 0) || | ||||||||
3066 | ((len=PyTuple_GET_SIZE(value)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(value))))-> ob_size)) < 2)) { | ||||||||
3067 | continue; | ||||||||
3068 | } | ||||||||
3069 | old = PyTuple_GET_ITEM(value, 0)((((void) (0)), (PyTupleObject *)(value))->ob_item[0]); | ||||||||
3070 | if (!PyArray_DescrCheck(old)((((PyObject*)(old))->ob_type) == (&(*(PyTypeObject *) (&PyArrayDescr_TypeFull))) || PyType_IsSubtype((((PyObject *)(old))->ob_type), (&(*(PyTypeObject *)(&PyArrayDescr_TypeFull )))))) { | ||||||||
3071 | continue; | ||||||||
3072 | } | ||||||||
3073 | newdescr = PyArray_DescrNewByteorder( | ||||||||
3074 | (PyArray_Descr *)old, newendian); | ||||||||
3075 | if (newdescr == NULL((void*)0)) { | ||||||||
3076 | Py_DECREF(newfields)_Py_DECREF(((PyObject*)(newfields))); Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); | ||||||||
3077 | return NULL((void*)0); | ||||||||
3078 | } | ||||||||
3079 | newvalue = PyTuple_New(len); | ||||||||
3080 | PyTuple_SET_ITEM(newvalue, 0, (PyObject *)newdescr)PyTuple_SetItem(newvalue, 0, (PyObject *)newdescr); | ||||||||
3081 | for (i = 1; i < len; i++) { | ||||||||
3082 | old = PyTuple_GET_ITEM(value, i)((((void) (0)), (PyTupleObject *)(value))->ob_item[i]); | ||||||||
3083 | Py_INCREF(old)_Py_INCREF(((PyObject*)(old))); | ||||||||
3084 | PyTuple_SET_ITEM(newvalue, i, old)PyTuple_SetItem(newvalue, i, old); | ||||||||
3085 | } | ||||||||
3086 | int ret = PyDict_SetItem(newfields, key, newvalue); | ||||||||
3087 | Py_DECREF(newvalue)_Py_DECREF(((PyObject*)(newvalue))); | ||||||||
3088 | if (ret < 0) { | ||||||||
3089 | Py_DECREF(newfields)_Py_DECREF(((PyObject*)(newfields))); | ||||||||
3090 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); | ||||||||
3091 | return NULL((void*)0); | ||||||||
3092 | } | ||||||||
3093 | } | ||||||||
3094 | Py_DECREF(new->fields)_Py_DECREF(((PyObject*)(new->fields))); | ||||||||
3095 | new->fields = newfields; | ||||||||
3096 | } | ||||||||
3097 | if (PyDataType_HASSUBARRAY(new)((new)->subarray != ((void*)0))) { | ||||||||
3098 | Py_DECREF(new->subarray->base)_Py_DECREF(((PyObject*)(new->subarray->base))); | ||||||||
3099 | new->subarray->base = PyArray_DescrNewByteorder( | ||||||||
3100 | self->subarray->base, newendian); | ||||||||
3101 | } | ||||||||
3102 | return new; | ||||||||
3103 | } | ||||||||
3104 | |||||||||
3105 | |||||||||
3106 | static PyObject * | ||||||||
3107 | arraydescr_newbyteorder(PyArray_Descr *self, PyObject *args) | ||||||||
3108 | { | ||||||||
3109 | char endian=NPY_SWAP's'; | ||||||||
3110 | |||||||||
3111 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "|O&:newbyteorder", PyArray_ByteorderConverter, | ||||||||
3112 | &endian)) { | ||||||||
3113 | return NULL((void*)0); | ||||||||
3114 | } | ||||||||
3115 | return (PyObject *)PyArray_DescrNewByteorder(self, endian); | ||||||||
3116 | } | ||||||||
3117 | |||||||||
3118 | static PyMethodDef arraydescr_methods[] = { | ||||||||
3119 | /* for pickling */ | ||||||||
3120 | {"__reduce__", | ||||||||
3121 | (PyCFunction)arraydescr_reduce, | ||||||||
3122 | METH_VARARGS0x0001, NULL((void*)0)}, | ||||||||
3123 | {"__setstate__", | ||||||||
3124 | (PyCFunction)arraydescr_setstate, | ||||||||
3125 | METH_VARARGS0x0001, NULL((void*)0)}, | ||||||||
3126 | {"newbyteorder", | ||||||||
3127 | (PyCFunction)arraydescr_newbyteorder, | ||||||||
3128 | METH_VARARGS0x0001, NULL((void*)0)}, | ||||||||
3129 | {NULL((void*)0), NULL((void*)0), 0, NULL((void*)0)} /* sentinel */ | ||||||||
3130 | }; | ||||||||
3131 | |||||||||
3132 | /* | ||||||||
3133 | * Checks whether the structured data type in 'dtype' | ||||||||
3134 | * has a simple layout, where all the fields are in order, | ||||||||
3135 | * and follow each other with no alignment padding. | ||||||||
3136 | * | ||||||||
3137 | * When this returns true, the dtype can be reconstructed | ||||||||
3138 | * from a list of the field names and dtypes with no additional | ||||||||
3139 | * dtype parameters. | ||||||||
3140 | * | ||||||||
3141 | * Returns 1 if it has a simple layout, 0 otherwise. | ||||||||
3142 | */ | ||||||||
3143 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) int | ||||||||
3144 | is_dtype_struct_simple_unaligned_layout(PyArray_Descr *dtype) | ||||||||
3145 | { | ||||||||
3146 | PyObject *names, *fields, *key, *tup, *title; | ||||||||
3147 | Py_ssize_t i, names_size; | ||||||||
3148 | PyArray_Descr *fld_dtype; | ||||||||
3149 | int fld_offset; | ||||||||
3150 | npy_intp total_offset; | ||||||||
3151 | |||||||||
3152 | /* Get some properties from the dtype */ | ||||||||
3153 | names = dtype->names; | ||||||||
3154 | names_size = PyTuple_GET_SIZE(names)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(names))))-> ob_size); | ||||||||
3155 | fields = dtype->fields; | ||||||||
3156 | |||||||||
3157 | /* Start at offset zero */ | ||||||||
3158 | total_offset = 0; | ||||||||
3159 | |||||||||
3160 | for (i = 0; i < names_size; ++i) { | ||||||||
3161 | key = PyTuple_GET_ITEM(names, i)((((void) (0)), (PyTupleObject *)(names))->ob_item[i]); | ||||||||
3162 | if (key == NULL((void*)0)) { | ||||||||
3163 | return 0; | ||||||||
3164 | } | ||||||||
3165 | tup = PyDict_GetItem(fields, key); | ||||||||
3166 | if (tup == NULL((void*)0)) { | ||||||||
3167 | return 0; | ||||||||
3168 | } | ||||||||
3169 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(tup, "Oi|O", &fld_dtype, &fld_offset, &title)) { | ||||||||
3170 | PyErr_Clear(); | ||||||||
3171 | return 0; | ||||||||
3172 | } | ||||||||
3173 | /* If this field doesn't follow the pattern, not a simple layout */ | ||||||||
3174 | if (total_offset != fld_offset) { | ||||||||
3175 | return 0; | ||||||||
3176 | } | ||||||||
3177 | /* Get the next offset */ | ||||||||
3178 | total_offset += fld_dtype->elsize; | ||||||||
3179 | } | ||||||||
3180 | |||||||||
3181 | /* | ||||||||
3182 | * If the itemsize doesn't match the final offset, it's | ||||||||
3183 | * not a simple layout. | ||||||||
3184 | */ | ||||||||
3185 | if (total_offset != dtype->elsize) { | ||||||||
3186 | return 0; | ||||||||
3187 | } | ||||||||
3188 | |||||||||
3189 | /* It's a simple layout, since all the above tests passed */ | ||||||||
3190 | return 1; | ||||||||
3191 | } | ||||||||
3192 | |||||||||
3193 | /* | ||||||||
3194 | * The general dtype repr function. | ||||||||
3195 | */ | ||||||||
3196 | static PyObject * | ||||||||
3197 | arraydescr_repr(PyArray_Descr *dtype) | ||||||||
3198 | { | ||||||||
3199 | PyObject *_numpy_dtype; | ||||||||
3200 | PyObject *res; | ||||||||
3201 | _numpy_dtype = PyImport_ImportModule("numpy.core._dtype"); | ||||||||
3202 | if (_numpy_dtype == NULL((void*)0)) { | ||||||||
3203 | return NULL((void*)0); | ||||||||
3204 | } | ||||||||
3205 | res = PyObject_CallMethod_PyObject_CallMethod_SizeT(_numpy_dtype, "__repr__", "O", dtype); | ||||||||
3206 | Py_DECREF(_numpy_dtype)_Py_DECREF(((PyObject*)(_numpy_dtype))); | ||||||||
3207 | return res; | ||||||||
3208 | } | ||||||||
3209 | /* | ||||||||
3210 | * The general dtype str function. | ||||||||
3211 | */ | ||||||||
3212 | static PyObject * | ||||||||
3213 | arraydescr_str(PyArray_Descr *dtype) | ||||||||
3214 | { | ||||||||
3215 | PyObject *_numpy_dtype; | ||||||||
3216 | PyObject *res; | ||||||||
3217 | _numpy_dtype = PyImport_ImportModule("numpy.core._dtype"); | ||||||||
3218 | if (_numpy_dtype == NULL((void*)0)) { | ||||||||
3219 | return NULL((void*)0); | ||||||||
3220 | } | ||||||||
3221 | res = PyObject_CallMethod_PyObject_CallMethod_SizeT(_numpy_dtype, "__str__", "O", dtype); | ||||||||
3222 | Py_DECREF(_numpy_dtype)_Py_DECREF(((PyObject*)(_numpy_dtype))); | ||||||||
3223 | return res; | ||||||||
3224 | } | ||||||||
3225 | |||||||||
3226 | static PyObject * | ||||||||
3227 | arraydescr_richcompare(PyArray_Descr *self, PyObject *other, int cmp_op) | ||||||||
3228 | { | ||||||||
3229 | PyArray_Descr *new = _convert_from_any(other, 0); | ||||||||
3230 | if (new == NULL((void*)0)) { | ||||||||
3231 | return NULL((void*)0); | ||||||||
3232 | } | ||||||||
3233 | |||||||||
3234 | npy_bool ret; | ||||||||
3235 | switch (cmp_op) { | ||||||||
3236 | case Py_LT0: | ||||||||
3237 | ret = !PyArray_EquivTypes(self, new) && PyArray_CanCastTo(self, new); | ||||||||
3238 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); | ||||||||
3239 | return PyBool_FromLong(ret); | ||||||||
3240 | case Py_LE1: | ||||||||
3241 | ret = PyArray_CanCastTo(self, new); | ||||||||
3242 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); | ||||||||
3243 | return PyBool_FromLong(ret); | ||||||||
3244 | case Py_EQ2: | ||||||||
3245 | ret = PyArray_EquivTypes(self, new); | ||||||||
3246 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); | ||||||||
3247 | return PyBool_FromLong(ret); | ||||||||
3248 | case Py_NE3: | ||||||||
3249 | ret = !PyArray_EquivTypes(self, new); | ||||||||
3250 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); | ||||||||
3251 | return PyBool_FromLong(ret); | ||||||||
3252 | case Py_GT4: | ||||||||
3253 | ret = !PyArray_EquivTypes(self, new) && PyArray_CanCastTo(new, self); | ||||||||
3254 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); | ||||||||
3255 | return PyBool_FromLong(ret); | ||||||||
3256 | case Py_GE5: | ||||||||
3257 | ret = PyArray_CanCastTo(new, self); | ||||||||
3258 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); | ||||||||
3259 | return PyBool_FromLong(ret); | ||||||||
3260 | default: | ||||||||
3261 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); | ||||||||
3262 | Py_RETURN_NOTIMPLEMENTEDreturn _Py_INCREF(((PyObject*)((&_Py_NotImplementedStruct )))), (&_Py_NotImplementedStruct); | ||||||||
3263 | } | ||||||||
3264 | } | ||||||||
3265 | |||||||||
3266 | static int | ||||||||
3267 | descr_nonzero(PyObject *NPY_UNUSED(self)(__NPY_UNUSED_TAGGEDself) __attribute__ ((__unused__))) | ||||||||
3268 | { | ||||||||
3269 | /* `bool(np.dtype(...)) == True` for all dtypes. Needed to override default | ||||||||
3270 | * nonzero implementation, which checks if `len(object) > 0`. */ | ||||||||
3271 | return 1; | ||||||||
3272 | } | ||||||||
3273 | |||||||||
3274 | static PyNumberMethods descr_as_number = { | ||||||||
3275 | .nb_bool = (inquiry)descr_nonzero, | ||||||||
3276 | }; | ||||||||
3277 | |||||||||
3278 | /************************************************************************* | ||||||||
3279 | **************** Implement Mapping Protocol *************************** | ||||||||
3280 | *************************************************************************/ | ||||||||
3281 | |||||||||
3282 | static Py_ssize_t | ||||||||
3283 | descr_length(PyObject *self0) | ||||||||
3284 | { | ||||||||
3285 | PyArray_Descr *self = (PyArray_Descr *)self0; | ||||||||
3286 | |||||||||
3287 | if (PyDataType_HASFIELDS(self)(((PyArray_Descr *)(self))->names != ((void*)0))) { | ||||||||
3288 | return PyTuple_GET_SIZE(self->names)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(self->names ))))->ob_size); | ||||||||
3289 | } | ||||||||
3290 | else { | ||||||||
3291 | return 0; | ||||||||
3292 | } | ||||||||
3293 | } | ||||||||
3294 | |||||||||
3295 | static PyObject * | ||||||||
3296 | descr_repeat(PyObject *self, Py_ssize_t length) | ||||||||
3297 | { | ||||||||
3298 | PyObject *tup; | ||||||||
3299 | PyArray_Descr *new; | ||||||||
3300 | if (length < 0) { | ||||||||
3301 | return PyErr_Format(PyExc_ValueError, | ||||||||
3302 | "Array length must be >= 0, not %"NPY_INTP_FMT"ld", (npy_intp)length); | ||||||||
3303 | } | ||||||||
3304 | tup = Py_BuildValue_Py_BuildValue_SizeT("O" NPY_SSIZE_T_PYFMT"n", self, length); | ||||||||
3305 | if (tup == NULL((void*)0)) { | ||||||||
3306 | return NULL((void*)0); | ||||||||
3307 | } | ||||||||
3308 | new = _convert_from_any(tup, 0); | ||||||||
3309 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||||
3310 | return (PyObject *)new; | ||||||||
3311 | } | ||||||||
3312 | |||||||||
3313 | static int | ||||||||
3314 | _check_has_fields(PyArray_Descr *self) | ||||||||
3315 | { | ||||||||
3316 | if (!PyDataType_HASFIELDS(self)(((PyArray_Descr *)(self))->names != ((void*)0))) { | ||||||||
3317 | PyErr_Format(PyExc_KeyError, "There are no fields in dtype %S.", self); | ||||||||
3318 | return -1; | ||||||||
3319 | } | ||||||||
3320 | else { | ||||||||
3321 | return 0; | ||||||||
3322 | } | ||||||||
3323 | } | ||||||||
3324 | |||||||||
3325 | static PyObject * | ||||||||
3326 | _subscript_by_name(PyArray_Descr *self, PyObject *op) | ||||||||
3327 | { | ||||||||
3328 | PyObject *obj = PyDict_GetItemWithError(self->fields, op); | ||||||||
3329 | if (obj == NULL((void*)0)) { | ||||||||
3330 | if (!PyErr_Occurred()) { | ||||||||
3331 | PyErr_Format(PyExc_KeyError, | ||||||||
3332 | "Field named %R not found.", op); | ||||||||
3333 | } | ||||||||
3334 | return NULL((void*)0); | ||||||||
3335 | } | ||||||||
3336 | PyObject *descr = PyTuple_GET_ITEM(obj, 0)((((void) (0)), (PyTupleObject *)(obj))->ob_item[0]); | ||||||||
3337 | Py_INCREF(descr)_Py_INCREF(((PyObject*)(descr))); | ||||||||
3338 | return descr; | ||||||||
3339 | } | ||||||||
3340 | |||||||||
3341 | static PyObject * | ||||||||
3342 | _subscript_by_index(PyArray_Descr *self, Py_ssize_t i) | ||||||||
3343 | { | ||||||||
3344 | PyObject *name = PySequence_GetItem(self->names, i); | ||||||||
3345 | PyObject *ret; | ||||||||
3346 | if (name == NULL((void*)0)) { | ||||||||
3347 | PyErr_Format(PyExc_IndexError, | ||||||||
3348 | "Field index %zd out of range.", i); | ||||||||
3349 | return NULL((void*)0); | ||||||||
3350 | } | ||||||||
3351 | ret = _subscript_by_name(self, name); | ||||||||
3352 | Py_DECREF(name)_Py_DECREF(((PyObject*)(name))); | ||||||||
3353 | return ret; | ||||||||
3354 | } | ||||||||
3355 | |||||||||
3356 | static npy_bool | ||||||||
3357 | _is_list_of_strings(PyObject *obj) | ||||||||
3358 | { | ||||||||
3359 | int seqlen, i; | ||||||||
3360 | if (!PyList_CheckExact(obj)((((PyObject*)(obj))->ob_type) == &PyList_Type)) { | ||||||||
3361 | return NPY_FALSE0; | ||||||||
3362 | } | ||||||||
3363 | seqlen = PyList_GET_SIZE(obj)(((void) (0)), (((PyVarObject*)(obj))->ob_size)); | ||||||||
3364 | for (i = 0; i < seqlen; i++) { | ||||||||
3365 | PyObject *item = PyList_GET_ITEM(obj, i)(((PyListObject *)(obj))->ob_item[i]); | ||||||||
3366 | if (!PyUnicode_Check(item)((((((PyObject*)(item))->ob_type))->tp_flags & ((1UL << 28))) != 0)) { | ||||||||
3367 | return NPY_FALSE0; | ||||||||
3368 | } | ||||||||
3369 | } | ||||||||
3370 | |||||||||
3371 | return NPY_TRUE1; | ||||||||
3372 | } | ||||||||
3373 | |||||||||
3374 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyArray_Descr * | ||||||||
3375 | arraydescr_field_subset_view(PyArray_Descr *self, PyObject *ind) | ||||||||
3376 | { | ||||||||
3377 | int seqlen, i; | ||||||||
3378 | PyObject *fields = NULL((void*)0); | ||||||||
3379 | PyObject *names = NULL((void*)0); | ||||||||
3380 | PyArray_Descr *view_dtype; | ||||||||
3381 | |||||||||
3382 | seqlen = PySequence_Size(ind); | ||||||||
3383 | if (seqlen == -1) { | ||||||||
3384 | return NULL((void*)0); | ||||||||
3385 | } | ||||||||
3386 | |||||||||
3387 | fields = PyDict_New(); | ||||||||
3388 | if (fields == NULL((void*)0)) { | ||||||||
3389 | goto fail; | ||||||||
3390 | } | ||||||||
3391 | names = PyTuple_New(seqlen); | ||||||||
3392 | if (names == NULL((void*)0)) { | ||||||||
3393 | goto fail; | ||||||||
3394 | } | ||||||||
3395 | |||||||||
3396 | for (i = 0; i < seqlen; i++) { | ||||||||
3397 | PyObject *name; | ||||||||
3398 | PyObject *tup; | ||||||||
3399 | |||||||||
3400 | name = PySequence_GetItem(ind, i); | ||||||||
3401 | if (name == NULL((void*)0)) { | ||||||||
3402 | goto fail; | ||||||||
3403 | } | ||||||||
3404 | |||||||||
3405 | /* Let the names tuple steal a reference now, so we don't need to | ||||||||
3406 | * decref name if an error occurs further on. | ||||||||
3407 | */ | ||||||||
3408 | PyTuple_SET_ITEM(names, i, name)PyTuple_SetItem(names, i, name); | ||||||||
3409 | |||||||||
3410 | tup = PyDict_GetItemWithError(self->fields, name); | ||||||||
3411 | if (tup == NULL((void*)0)) { | ||||||||
3412 | if (!PyErr_Occurred()) { | ||||||||
3413 | PyErr_SetObject(PyExc_KeyError, name); | ||||||||
3414 | } | ||||||||
3415 | goto fail; | ||||||||
3416 | } | ||||||||
3417 | |||||||||
3418 | /* disallow use of titles as index */ | ||||||||
3419 | if (PyTuple_Size(tup) == 3) { | ||||||||
3420 | PyObject *title = PyTuple_GET_ITEM(tup, 2)((((void) (0)), (PyTupleObject *)(tup))->ob_item[2]); | ||||||||
3421 | int titlecmp = PyObject_RichCompareBool(title, name, Py_EQ2); | ||||||||
3422 | if (titlecmp < 0) { | ||||||||
3423 | goto fail; | ||||||||
3424 | } | ||||||||
3425 | if (titlecmp == 1) { | ||||||||
3426 | /* if title == name, we were given a title, not a field name */ | ||||||||
3427 | PyErr_SetString(PyExc_KeyError, | ||||||||
3428 | "cannot use field titles in multi-field index"); | ||||||||
3429 | goto fail; | ||||||||
3430 | } | ||||||||
3431 | if (PyDict_SetItem(fields, title, tup) < 0) { | ||||||||
3432 | goto fail; | ||||||||
3433 | } | ||||||||
3434 | } | ||||||||
3435 | /* disallow duplicate field indices */ | ||||||||
3436 | if (PyDict_Contains(fields, name)) { | ||||||||
3437 | PyObject *msg = NULL((void*)0); | ||||||||
3438 | PyObject *fmt = PyUnicode_FromString( | ||||||||
3439 | "duplicate field of name {!r}"); | ||||||||
3440 | if (fmt != NULL((void*)0)) { | ||||||||
3441 | msg = PyObject_CallMethod_PyObject_CallMethod_SizeT(fmt, "format", "O", name); | ||||||||
3442 | Py_DECREF(fmt)_Py_DECREF(((PyObject*)(fmt))); | ||||||||
3443 | } | ||||||||
3444 | PyErr_SetObject(PyExc_ValueError, msg); | ||||||||
3445 | Py_XDECREF(msg)_Py_XDECREF(((PyObject*)(msg))); | ||||||||
3446 | goto fail; | ||||||||
3447 | } | ||||||||
3448 | if (PyDict_SetItem(fields, name, tup) < 0) { | ||||||||
3449 | goto fail; | ||||||||
3450 | } | ||||||||
3451 | } | ||||||||
3452 | |||||||||
3453 | view_dtype = PyArray_DescrNewFromType(NPY_VOID); | ||||||||
3454 | if (view_dtype == NULL((void*)0)) { | ||||||||
3455 | goto fail; | ||||||||
3456 | } | ||||||||
3457 | view_dtype->elsize = self->elsize; | ||||||||
3458 | view_dtype->names = names; | ||||||||
3459 | view_dtype->fields = fields; | ||||||||
3460 | view_dtype->flags = self->flags; | ||||||||
3461 | return view_dtype; | ||||||||
3462 | |||||||||
3463 | fail: | ||||||||
3464 | Py_XDECREF(fields)_Py_XDECREF(((PyObject*)(fields))); | ||||||||
3465 | Py_XDECREF(names)_Py_XDECREF(((PyObject*)(names))); | ||||||||
3466 | return NULL((void*)0); | ||||||||
3467 | } | ||||||||
3468 | |||||||||
3469 | static PyObject * | ||||||||
3470 | descr_subscript(PyArray_Descr *self, PyObject *op) | ||||||||
3471 | { | ||||||||
3472 | if (_check_has_fields(self) < 0) { | ||||||||
3473 | return NULL((void*)0); | ||||||||
3474 | } | ||||||||
3475 | |||||||||
3476 | if (PyUnicode_Check(op)((((((PyObject*)(op))->ob_type))->tp_flags & ((1UL << 28))) != 0)) { | ||||||||
3477 | return _subscript_by_name(self, op); | ||||||||
3478 | } | ||||||||
3479 | else if (_is_list_of_strings(op)) { | ||||||||
3480 | return (PyObject *)arraydescr_field_subset_view(self, op); | ||||||||
3481 | } | ||||||||
3482 | else { | ||||||||
3483 | Py_ssize_t i = PyArray_PyIntAsIntp(op); | ||||||||
3484 | if (error_converting(i)(((i) == -1) && PyErr_Occurred())) { | ||||||||
3485 | /* if converting to an int gives a type error, adjust the message */ | ||||||||
3486 | PyObject *err = PyErr_Occurred(); | ||||||||
3487 | if (PyErr_GivenExceptionMatches(err, PyExc_TypeError)) { | ||||||||
3488 | PyErr_SetString(PyExc_TypeError, | ||||||||
3489 | "Field key must be an integer field offset, " | ||||||||
3490 | "single field name, or list of field names."); | ||||||||
3491 | } | ||||||||
3492 | return NULL((void*)0); | ||||||||
3493 | } | ||||||||
3494 | return _subscript_by_index(self, i); | ||||||||
3495 | } | ||||||||
3496 | } | ||||||||
3497 | |||||||||
3498 | static PySequenceMethods descr_as_sequence = { | ||||||||
3499 | (lenfunc) descr_length, /* sq_length */ | ||||||||
3500 | (binaryfunc) NULL((void*)0), /* sq_concat */ | ||||||||
3501 | (ssizeargfunc) descr_repeat, /* sq_repeat */ | ||||||||
3502 | (ssizeargfunc) NULL((void*)0), /* sq_item */ | ||||||||
3503 | (ssizessizeargfunc) NULL((void*)0), /* sq_slice */ | ||||||||
3504 | (ssizeobjargproc) NULL((void*)0), /* sq_ass_item */ | ||||||||
3505 | (ssizessizeobjargproc) NULL((void*)0), /* sq_ass_slice */ | ||||||||
3506 | (objobjproc) NULL((void*)0), /* sq_contains */ | ||||||||
3507 | (binaryfunc) NULL((void*)0), /* sq_inplace_concat */ | ||||||||
3508 | (ssizeargfunc) NULL((void*)0), /* sq_inplace_repeat */ | ||||||||
3509 | }; | ||||||||
3510 | |||||||||
3511 | static PyMappingMethods descr_as_mapping = { | ||||||||
3512 | descr_length, /* mp_length*/ | ||||||||
3513 | (binaryfunc)descr_subscript, /* mp_subscript*/ | ||||||||
3514 | (objobjargproc)NULL((void*)0), /* mp_ass_subscript*/ | ||||||||
3515 | }; | ||||||||
3516 | |||||||||
3517 | /****************** End of Mapping Protocol ******************************/ | ||||||||
3518 | |||||||||
3519 | |||||||||
3520 | /* | ||||||||
3521 | * NOTE: Since this is a MetaClass, the name has Full appended here, the | ||||||||
3522 | * correct name of the type is PyArrayDescr_Type. | ||||||||
3523 | */ | ||||||||
3524 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyArray_DTypeMeta PyArrayDescr_TypeFull = { | ||||||||
3525 | {{ | ||||||||
3526 | /* NULL represents `type`, this is set to DTypeMeta at import time */ | ||||||||
3527 | PyVarObject_HEAD_INIT(NULL, 0){ { 1, ((void*)0) }, 0 }, | ||||||||
3528 | .tp_name = "numpy.dtype", | ||||||||
3529 | .tp_basicsize = sizeof(PyArray_Descr), | ||||||||
3530 | .tp_dealloc = (destructor)arraydescr_dealloc, | ||||||||
3531 | .tp_repr = (reprfunc)arraydescr_repr, | ||||||||
3532 | .tp_as_number = &descr_as_number, | ||||||||
3533 | .tp_as_sequence = &descr_as_sequence, | ||||||||
3534 | .tp_as_mapping = &descr_as_mapping, | ||||||||
3535 | .tp_str = (reprfunc)arraydescr_str, | ||||||||
3536 | .tp_flags = Py_TPFLAGS_DEFAULT( 0 | (1UL << 18) | 0) | Py_TPFLAGS_BASETYPE(1UL << 10), | ||||||||
3537 | .tp_richcompare = (richcmpfunc)arraydescr_richcompare, | ||||||||
3538 | .tp_methods = arraydescr_methods, | ||||||||
3539 | .tp_members = arraydescr_members, | ||||||||
3540 | .tp_getset = arraydescr_getsets, | ||||||||
3541 | .tp_new = arraydescr_new, | ||||||||
3542 | },}, | ||||||||
3543 | .type_num = -1, | ||||||||
3544 | .kind = '\0', | ||||||||
3545 | .abstract = 1, | ||||||||
3546 | .parametric = 0, | ||||||||
3547 | .singleton = 0, | ||||||||
3548 | .scalar_type = NULL((void*)0), | ||||||||
3549 | }; |
1 | #ifndef _Py_BuildValue_SizeT |
2 | struct _object; |
3 | typedef struct _object PyObject; |
4 | PyObject* clang_analyzer_PyObject_New_Reference(); |
5 | PyObject* _Py_BuildValue_SizeT(const char *format, ...) { |
6 | return clang_analyzer_PyObject_New_Reference(); |
7 | } |
8 | #else |
9 | #warning "API _Py_BuildValue_SizeT is defined as a macro." |
10 | #endif |