File: | numpy/core/src/multiarray/descriptor.c |
Warning: | line 1157, column 22 Accessing a PyObject whose ownership has been released (with stolen reference) |
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
| ||||
1092 | || (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 < 0 || version > 4) { | ||||
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 == 1 || version == 0) { | ||||
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 PyTuple_SetItem |
2 | struct _object; |
3 | typedef struct _object PyObject; |
4 | void clang_analyzer_PyObject_Steal_Reference(const void *); |
5 | int clang_analyzer_noimpl_conjure_int(); |
6 | int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o) { |
7 | clang_analyzer_PyObject_Steal_Reference(o); |
8 | return clang_analyzer_noimpl_conjure_int(); |
9 | } |
10 | #else |
11 | #warning "API PyTuple_SetItem is defined as a macro." |
12 | #endif |