File: | numpy/core/src/multiarray/descriptor.c |
Warning: | line 549, column 25 PyObject ownership leak with reference count of 1 |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* Array Descr Object */ | |||
2 | ||||
3 | #define PY_SSIZE_T_CLEAN | |||
4 | #include <Python.h> | |||
5 | #include "structmember.h" | |||
6 | ||||
7 | #define NPY_NO_DEPRECATED_API0x0000000E NPY_API_VERSION0x0000000E | |||
8 | #define _MULTIARRAYMODULE | |||
9 | #include "numpy/arrayobject.h" | |||
10 | ||||
11 | #include "npy_config.h" | |||
12 | #include "npy_pycompat.h" | |||
13 | #include "npy_import.h" | |||
14 | ||||
15 | #include "common.h" | |||
16 | #include "conversion_utils.h" | |||
17 | #include "ctors.h" | |||
18 | #include "scalartypes.h" | |||
19 | #include "descriptor.h" | |||
20 | #include "getset.h" | |||
21 | #include "arrayobject.h" | |||
22 | #include "mem_overlap.h" | |||
23 | #include "alloc.h" | |||
24 | #include "npy_buffer.h" | |||
25 | ||||
26 | /******************* array attribute get and set routines ******************/ | |||
27 | ||||
28 | static PyObject * | |||
29 | array_ndim_get(PyArrayObject *self) | |||
30 | { | |||
31 | return PyLong_FromLong(PyArray_NDIM(self)); | |||
32 | } | |||
33 | ||||
34 | static PyObject * | |||
35 | array_flags_get(PyArrayObject *self) | |||
36 | { | |||
37 | return PyArray_NewFlagsObject((PyObject *)self); | |||
38 | } | |||
39 | ||||
40 | static PyObject * | |||
41 | array_shape_get(PyArrayObject *self) | |||
42 | { | |||
43 | return PyArray_IntTupleFromIntp(PyArray_NDIM(self), PyArray_DIMS(self)); | |||
44 | } | |||
45 | ||||
46 | ||||
47 | static int | |||
48 | array_shape_set(PyArrayObject *self, PyObject *val) | |||
49 | { | |||
50 | int nd; | |||
51 | PyArrayObject *ret; | |||
52 | ||||
53 | if (val == NULL((void*)0)) { | |||
54 | PyErr_SetString(PyExc_AttributeError, | |||
55 | "Cannot delete array shape"); | |||
56 | return -1; | |||
57 | } | |||
58 | /* Assumes C-order */ | |||
59 | ret = (PyArrayObject *)PyArray_Reshape(self, val); | |||
60 | if (ret == NULL((void*)0)) { | |||
61 | return -1; | |||
62 | } | |||
63 | if (PyArray_DATA(ret) != PyArray_DATA(self)) { | |||
64 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | |||
65 | PyErr_SetString(PyExc_AttributeError, | |||
66 | "Incompatible shape for in-place modification. Use " | |||
67 | "`.reshape()` to make a copy with the desired shape."); | |||
68 | return -1; | |||
69 | } | |||
70 | ||||
71 | nd = PyArray_NDIM(ret); | |||
72 | if (nd > 0) { | |||
73 | /* create new dimensions and strides */ | |||
74 | npy_intp *_dimensions = npy_alloc_cache_dim(2 * nd); | |||
75 | if (_dimensions == NULL((void*)0)) { | |||
76 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | |||
77 | PyErr_NoMemory(); | |||
78 | return -1; | |||
79 | } | |||
80 | /* Free old dimensions and strides */ | |||
81 | npy_free_cache_dim_array(self); | |||
82 | ((PyArrayObject_fields *)self)->nd = nd; | |||
83 | ((PyArrayObject_fields *)self)->dimensions = _dimensions; | |||
84 | ((PyArrayObject_fields *)self)->strides = _dimensions + nd; | |||
85 | ||||
86 | if (nd) { | |||
87 | memcpy(PyArray_DIMS(self), PyArray_DIMS(ret), nd*sizeof(npy_intp)); | |||
88 | memcpy(PyArray_STRIDES(self), PyArray_STRIDES(ret), nd*sizeof(npy_intp)); | |||
89 | } | |||
90 | } | |||
91 | else { | |||
92 | /* Free old dimensions and strides */ | |||
93 | npy_free_cache_dim_array(self); | |||
94 | ((PyArrayObject_fields *)self)->nd = 0; | |||
95 | ((PyArrayObject_fields *)self)->dimensions = NULL((void*)0); | |||
96 | ((PyArrayObject_fields *)self)->strides = NULL((void*)0); | |||
97 | } | |||
98 | ||||
99 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | |||
100 | PyArray_UpdateFlags(self, NPY_ARRAY_C_CONTIGUOUS0x0001 | NPY_ARRAY_F_CONTIGUOUS0x0002); | |||
101 | return 0; | |||
102 | } | |||
103 | ||||
104 | ||||
105 | static PyObject * | |||
106 | array_strides_get(PyArrayObject *self) | |||
107 | { | |||
108 | return PyArray_IntTupleFromIntp(PyArray_NDIM(self), PyArray_STRIDES(self)); | |||
109 | } | |||
110 | ||||
111 | static int | |||
112 | array_strides_set(PyArrayObject *self, PyObject *obj) | |||
113 | { | |||
114 | PyArray_Dims newstrides = {NULL((void*)0), -1}; | |||
115 | PyArrayObject *new; | |||
116 | npy_intp numbytes = 0; | |||
117 | npy_intp offset = 0; | |||
118 | npy_intp lower_offset = 0; | |||
119 | npy_intp upper_offset = 0; | |||
120 | Py_buffer view; | |||
121 | ||||
122 | if (obj == NULL((void*)0)) { | |||
123 | PyErr_SetString(PyExc_AttributeError, | |||
124 | "Cannot delete array strides"); | |||
125 | return -1; | |||
126 | } | |||
127 | if (!PyArray_OptionalIntpConverter(obj, &newstrides) || | |||
128 | newstrides.len == -1) { | |||
129 | PyErr_SetString(PyExc_TypeError, "invalid strides"); | |||
130 | return -1; | |||
131 | } | |||
132 | if (newstrides.len != PyArray_NDIM(self)) { | |||
133 | PyErr_Format(PyExc_ValueError, "strides must be " \ | |||
134 | " same length as shape (%d)", PyArray_NDIM(self)); | |||
135 | goto fail; | |||
136 | } | |||
137 | new = self; | |||
138 | while(PyArray_BASE(new) && PyArray_Check(PyArray_BASE(new))((((PyObject*)(PyArray_BASE(new)))->ob_type) == (&PyArray_Type ) || PyType_IsSubtype((((PyObject*)(PyArray_BASE(new)))->ob_type ), (&PyArray_Type)))) { | |||
139 | new = (PyArrayObject *)(PyArray_BASE(new)); | |||
140 | } | |||
141 | /* | |||
142 | * Get the available memory through the buffer interface on | |||
143 | * PyArray_BASE(new) or if that fails from the current new | |||
144 | */ | |||
145 | if (PyArray_BASE(new) && | |||
146 | PyObject_GetBuffer(PyArray_BASE(new), &view, PyBUF_SIMPLE0) >= 0) { | |||
147 | offset = PyArray_BYTES(self) - (char *)view.buf; | |||
148 | numbytes = view.len + offset; | |||
149 | PyBuffer_Release(&view); | |||
150 | } | |||
151 | else { | |||
152 | PyErr_Clear(); | |||
153 | offset_bounds_from_strides(PyArray_ITEMSIZE(new), PyArray_NDIM(new), | |||
154 | PyArray_DIMS(new), PyArray_STRIDES(new), | |||
155 | &lower_offset, &upper_offset); | |||
156 | ||||
157 | offset = PyArray_BYTES(self) - (PyArray_BYTES(new) + lower_offset); | |||
158 | numbytes = upper_offset - lower_offset; | |||
159 | } | |||
160 | ||||
161 | /* numbytes == 0 is special here, but the 0-size array case always works */ | |||
162 | if (!PyArray_CheckStrides(PyArray_ITEMSIZE(self), PyArray_NDIM(self), | |||
163 | numbytes, offset, | |||
164 | PyArray_DIMS(self), newstrides.ptr)) { | |||
165 | PyErr_SetString(PyExc_ValueError, "strides is not "\ | |||
166 | "compatible with available memory"); | |||
167 | goto fail; | |||
168 | } | |||
169 | if (newstrides.len) { | |||
170 | memcpy(PyArray_STRIDES(self), newstrides.ptr, sizeof(npy_intp)*newstrides.len); | |||
171 | } | |||
172 | PyArray_UpdateFlags(self, NPY_ARRAY_C_CONTIGUOUS0x0001 | NPY_ARRAY_F_CONTIGUOUS0x0002 | | |||
173 | NPY_ARRAY_ALIGNED0x0100); | |||
174 | npy_free_cache_dim_obj(newstrides); | |||
175 | return 0; | |||
176 | ||||
177 | fail: | |||
178 | npy_free_cache_dim_obj(newstrides); | |||
179 | return -1; | |||
180 | } | |||
181 | ||||
182 | ||||
183 | ||||
184 | static PyObject * | |||
185 | array_priority_get(PyArrayObject *NPY_UNUSED(self)(__NPY_UNUSED_TAGGEDself) __attribute__ ((__unused__))) | |||
186 | { | |||
187 | return PyFloat_FromDouble(NPY_PRIORITY0.0); | |||
188 | } | |||
189 | ||||
190 | static PyObject * | |||
191 | array_typestr_get(PyArrayObject *self) | |||
192 | { | |||
193 | return arraydescr_protocol_typestr_get(PyArray_DESCR(self)); | |||
194 | } | |||
195 | ||||
196 | static PyObject * | |||
197 | array_descr_get(PyArrayObject *self) | |||
198 | { | |||
199 | Py_INCREF(PyArray_DESCR(self))_Py_INCREF(((PyObject*)(PyArray_DESCR(self)))); | |||
200 | return (PyObject *)PyArray_DESCR(self); | |||
201 | } | |||
202 | ||||
203 | static PyObject * | |||
204 | array_protocol_descr_get(PyArrayObject *self) | |||
205 | { | |||
206 | PyObject *res; | |||
207 | PyObject *dobj; | |||
208 | ||||
209 | res = arraydescr_protocol_descr_get(PyArray_DESCR(self)); | |||
210 | if (res) { | |||
211 | return res; | |||
212 | } | |||
213 | PyErr_Clear(); | |||
214 | ||||
215 | /* get default */ | |||
216 | dobj = PyTuple_New(2); | |||
217 | if (dobj == NULL((void*)0)) { | |||
218 | return NULL((void*)0); | |||
219 | } | |||
220 | PyTuple_SET_ITEM(dobj, 0, PyUnicode_FromString(""))PyTuple_SetItem(dobj, 0, PyUnicode_FromString("")); | |||
221 | PyTuple_SET_ITEM(dobj, 1, array_typestr_get(self))PyTuple_SetItem(dobj, 1, array_typestr_get(self)); | |||
222 | res = PyList_New(1); | |||
223 | if (res == NULL((void*)0)) { | |||
224 | Py_DECREF(dobj)_Py_DECREF(((PyObject*)(dobj))); | |||
225 | return NULL((void*)0); | |||
226 | } | |||
227 | PyList_SET_ITEM(res, 0, dobj)PyList_SetItem(res, 0, dobj); | |||
228 | return res; | |||
229 | } | |||
230 | ||||
231 | static PyObject * | |||
232 | array_protocol_strides_get(PyArrayObject *self) | |||
233 | { | |||
234 | if (PyArray_ISCONTIGUOUS(self)PyArray_CHKFLAGS((self), 0x0001)) { | |||
235 | Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (& _Py_NoneStruct); | |||
236 | } | |||
237 | return PyArray_IntTupleFromIntp(PyArray_NDIM(self), PyArray_STRIDES(self)); | |||
238 | } | |||
239 | ||||
240 | ||||
241 | ||||
242 | static PyObject * | |||
243 | array_dataptr_get(PyArrayObject *self) | |||
244 | { | |||
245 | return Py_BuildValue_Py_BuildValue_SizeT("NO", | |||
246 | PyLong_FromVoidPtr(PyArray_DATA(self)), | |||
247 | ((PyArray_FLAGS(self) & NPY_ARRAY_WRITEABLE0x0400) && | |||
248 | !(PyArray_FLAGS(self) & NPY_ARRAY_WARN_ON_WRITE)) ? | |||
249 | Py_False((PyObject *) &_Py_FalseStruct) : Py_True((PyObject *) &_Py_TrueStruct)); | |||
250 | } | |||
251 | ||||
252 | static PyObject * | |||
253 | array_ctypes_get(PyArrayObject *self) | |||
254 | { | |||
255 | PyObject *_numpy_internal; | |||
256 | PyObject *ret; | |||
257 | _numpy_internal = PyImport_ImportModule("numpy.core._internal"); | |||
258 | if (_numpy_internal == NULL((void*)0)) { | |||
259 | return NULL((void*)0); | |||
260 | } | |||
261 | ret = PyObject_CallMethod_PyObject_CallMethod_SizeT(_numpy_internal, "_ctypes", "ON", self, | |||
262 | PyLong_FromVoidPtr(PyArray_DATA(self))); | |||
263 | Py_DECREF(_numpy_internal)_Py_DECREF(((PyObject*)(_numpy_internal))); | |||
264 | return ret; | |||
265 | } | |||
266 | ||||
267 | static PyObject * | |||
268 | array_interface_get(PyArrayObject *self) | |||
269 | { | |||
270 | PyObject *dict; | |||
271 | PyObject *obj; | |||
272 | ||||
273 | dict = PyDict_New(); | |||
274 | if (dict == NULL((void*)0)) { | |||
275 | return NULL((void*)0); | |||
276 | } | |||
277 | ||||
278 | int ret; | |||
279 | ||||
280 | /* dataptr */ | |||
281 | obj = array_dataptr_get(self); | |||
282 | ret = PyDict_SetItemString(dict, "data", obj); | |||
283 | Py_DECREF(obj)_Py_DECREF(((PyObject*)(obj))); | |||
284 | if (ret < 0) { | |||
285 | Py_DECREF(dict)_Py_DECREF(((PyObject*)(dict))); | |||
286 | return NULL((void*)0); | |||
287 | } | |||
288 | ||||
289 | obj = array_protocol_strides_get(self); | |||
290 | ret = PyDict_SetItemString(dict, "strides", obj); | |||
291 | Py_DECREF(obj)_Py_DECREF(((PyObject*)(obj))); | |||
292 | if (ret < 0) { | |||
293 | Py_DECREF(dict)_Py_DECREF(((PyObject*)(dict))); | |||
294 | return NULL((void*)0); | |||
295 | } | |||
296 | ||||
297 | obj = array_protocol_descr_get(self); | |||
298 | ret = PyDict_SetItemString(dict, "descr", obj); | |||
299 | Py_DECREF(obj)_Py_DECREF(((PyObject*)(obj))); | |||
300 | if (ret < 0) { | |||
301 | Py_DECREF(dict)_Py_DECREF(((PyObject*)(dict))); | |||
302 | return NULL((void*)0); | |||
303 | } | |||
304 | ||||
305 | obj = arraydescr_protocol_typestr_get(PyArray_DESCR(self)); | |||
306 | ret = PyDict_SetItemString(dict, "typestr", obj); | |||
307 | Py_DECREF(obj)_Py_DECREF(((PyObject*)(obj))); | |||
308 | if (ret < 0) { | |||
309 | Py_DECREF(dict)_Py_DECREF(((PyObject*)(dict))); | |||
310 | return NULL((void*)0); | |||
311 | } | |||
312 | ||||
313 | obj = array_shape_get(self); | |||
314 | ret = PyDict_SetItemString(dict, "shape", obj); | |||
315 | Py_DECREF(obj)_Py_DECREF(((PyObject*)(obj))); | |||
316 | if (ret < 0) { | |||
317 | Py_DECREF(dict)_Py_DECREF(((PyObject*)(dict))); | |||
318 | return NULL((void*)0); | |||
319 | } | |||
320 | ||||
321 | obj = PyLong_FromLong(3); | |||
322 | ret = PyDict_SetItemString(dict, "version", obj); | |||
323 | Py_DECREF(obj)_Py_DECREF(((PyObject*)(obj))); | |||
324 | if (ret < 0) { | |||
325 | Py_DECREF(dict)_Py_DECREF(((PyObject*)(dict))); | |||
326 | return NULL((void*)0); | |||
327 | } | |||
328 | ||||
329 | return dict; | |||
330 | } | |||
331 | ||||
332 | static PyObject * | |||
333 | array_data_get(PyArrayObject *self) | |||
334 | { | |||
335 | return PyMemoryView_FromObject((PyObject *)self); | |||
336 | } | |||
337 | ||||
338 | static int | |||
339 | array_data_set(PyArrayObject *self, PyObject *op) | |||
340 | { | |||
341 | void *buf; | |||
342 | Py_ssize_t buf_len; | |||
343 | int writeable=1; | |||
344 | Py_buffer view; | |||
345 | ||||
346 | /* 2016-19-02, 1.12 */ | |||
347 | int ret = DEPRECATE("Assigning the 'data' attribute is an "PyErr_WarnEx(PyExc_DeprecationWarning,"Assigning the 'data' attribute is an " "inherently unsafe operation and will " "be removed in the future." ,1) | |||
348 | "inherently unsafe operation and will "PyErr_WarnEx(PyExc_DeprecationWarning,"Assigning the 'data' attribute is an " "inherently unsafe operation and will " "be removed in the future." ,1) | |||
349 | "be removed in the future.")PyErr_WarnEx(PyExc_DeprecationWarning,"Assigning the 'data' attribute is an " "inherently unsafe operation and will " "be removed in the future." ,1); | |||
350 | if (ret < 0) { | |||
351 | return -1; | |||
352 | } | |||
353 | ||||
354 | if (op == NULL((void*)0)) { | |||
355 | PyErr_SetString(PyExc_AttributeError, | |||
356 | "Cannot delete array data"); | |||
357 | return -1; | |||
358 | } | |||
359 | if (PyObject_GetBuffer(op, &view, PyBUF_WRITABLE0x0001|PyBUF_SIMPLE0) < 0) { | |||
360 | writeable = 0; | |||
361 | PyErr_Clear(); | |||
362 | if (PyObject_GetBuffer(op, &view, PyBUF_SIMPLE0) < 0) { | |||
363 | return -1; | |||
364 | } | |||
365 | } | |||
366 | buf = view.buf; | |||
367 | buf_len = view.len; | |||
368 | /* | |||
369 | * In Python 3 both of the deprecated functions PyObject_AsWriteBuffer and | |||
370 | * PyObject_AsReadBuffer that this code replaces release the buffer. It is | |||
371 | * up to the object that supplies the buffer to guarantee that the buffer | |||
372 | * sticks around after the release. | |||
373 | */ | |||
374 | PyBuffer_Release(&view); | |||
375 | ||||
376 | if (!PyArray_ISONESEGMENT(self)(PyArray_CHKFLAGS(self, 0x0001) || PyArray_CHKFLAGS(self, 0x0002 ))) { | |||
377 | PyErr_SetString(PyExc_AttributeError, | |||
378 | "cannot set single-segment buffer for discontiguous array"); | |||
379 | return -1; | |||
380 | } | |||
381 | if (PyArray_NBYTES(self)(PyArray_ITEMSIZE(self) * PyArray_MultiplyList(PyArray_DIMS(self ), PyArray_NDIM(self))) > buf_len) { | |||
382 | PyErr_SetString(PyExc_AttributeError, "not enough data for array"); | |||
383 | return -1; | |||
384 | } | |||
385 | if (PyArray_FLAGS(self) & NPY_ARRAY_OWNDATA0x0004) { | |||
386 | PyArray_XDECREF(self); | |||
387 | PyDataMem_FREE(PyArray_DATA(self)); | |||
388 | } | |||
389 | if (PyArray_BASE(self)) { | |||
390 | if ((PyArray_FLAGS(self) & NPY_ARRAY_WRITEBACKIFCOPY0x2000) || | |||
391 | (PyArray_FLAGS(self) & NPY_ARRAY_UPDATEIFCOPY0x1000)) { | |||
392 | PyArray_ENABLEFLAGS((PyArrayObject *)PyArray_BASE(self), | |||
393 | NPY_ARRAY_WRITEABLE0x0400); | |||
394 | PyArray_CLEARFLAGS(self, NPY_ARRAY_WRITEBACKIFCOPY0x2000); | |||
395 | PyArray_CLEARFLAGS(self, NPY_ARRAY_UPDATEIFCOPY0x1000); | |||
396 | } | |||
397 | Py_DECREF(PyArray_BASE(self))_Py_DECREF(((PyObject*)(PyArray_BASE(self)))); | |||
398 | ((PyArrayObject_fields *)self)->base = NULL((void*)0); | |||
399 | } | |||
400 | Py_INCREF(op)_Py_INCREF(((PyObject*)(op))); | |||
401 | if (PyArray_SetBaseObject(self, op) < 0) { | |||
402 | return -1; | |||
403 | } | |||
404 | ((PyArrayObject_fields *)self)->data = buf; | |||
405 | ((PyArrayObject_fields *)self)->flags = NPY_ARRAY_CARRAY(0x0001 | (0x0100 | 0x0400)); | |||
406 | if (!writeable) { | |||
407 | PyArray_CLEARFLAGS(self, ~NPY_ARRAY_WRITEABLE0x0400); | |||
408 | } | |||
409 | return 0; | |||
410 | } | |||
411 | ||||
412 | ||||
413 | static PyObject * | |||
414 | array_itemsize_get(PyArrayObject *self) | |||
415 | { | |||
416 | return PyLong_FromLong((long) PyArray_DESCR(self)->elsize); | |||
417 | } | |||
418 | ||||
419 | static PyObject * | |||
420 | array_size_get(PyArrayObject *self) | |||
421 | { | |||
422 | npy_intp size=PyArray_SIZE(self)PyArray_MultiplyList(PyArray_DIMS(self), PyArray_NDIM(self)); | |||
423 | #if NPY_SIZEOF_INTP8 <= NPY_SIZEOF_LONG8 | |||
424 | return PyLong_FromLong((long) size); | |||
425 | #else | |||
426 | if (size > NPY_MAX_LONG9223372036854775807L || size < NPY_MIN_LONG(-9223372036854775807L -1L)) { | |||
427 | return PyLong_FromLongLong(size); | |||
428 | } | |||
429 | else { | |||
430 | return PyLong_FromLong((long) size); | |||
431 | } | |||
432 | #endif | |||
433 | } | |||
434 | ||||
435 | static PyObject * | |||
436 | array_nbytes_get(PyArrayObject *self) | |||
437 | { | |||
438 | npy_intp nbytes = PyArray_NBYTES(self)(PyArray_ITEMSIZE(self) * PyArray_MultiplyList(PyArray_DIMS(self ), PyArray_NDIM(self))); | |||
439 | #if NPY_SIZEOF_INTP8 <= NPY_SIZEOF_LONG8 | |||
440 | return PyLong_FromLong((long) nbytes); | |||
441 | #else | |||
442 | if (nbytes > NPY_MAX_LONG9223372036854775807L || nbytes < NPY_MIN_LONG(-9223372036854775807L -1L)) { | |||
443 | return PyLong_FromLongLong(nbytes); | |||
444 | } | |||
445 | else { | |||
446 | return PyLong_FromLong((long) nbytes); | |||
447 | } | |||
448 | #endif | |||
449 | } | |||
450 | ||||
451 | ||||
452 | /* | |||
453 | * If the type is changed. | |||
454 | * Also needing change: strides, itemsize | |||
455 | * | |||
456 | * Either itemsize is exactly the same or the array is single-segment | |||
457 | * (contiguous or fortran) with compatible dimensions The shape and strides | |||
458 | * will be adjusted in that case as well. | |||
459 | */ | |||
460 | static int | |||
461 | array_descr_set(PyArrayObject *self, PyObject *arg) | |||
462 | { | |||
463 | PyArray_Descr *newtype = NULL((void*)0); | |||
464 | ||||
465 | if (arg == NULL((void*)0)) { | |||
| ||||
466 | PyErr_SetString(PyExc_AttributeError, | |||
467 | "Cannot delete array dtype"); | |||
468 | return -1; | |||
469 | } | |||
470 | ||||
471 | if (!(PyArray_DescrConverter(arg, &newtype)) || | |||
472 | newtype == NULL((void*)0)) { | |||
473 | PyErr_SetString(PyExc_TypeError, | |||
474 | "invalid data-type for array"); | |||
475 | return -1; | |||
476 | } | |||
477 | ||||
478 | /* check that we are not reinterpreting memory containing Objects. */ | |||
479 | if (_may_have_objects(PyArray_DESCR(self)) || _may_have_objects(newtype)) { | |||
480 | static PyObject *checkfunc = NULL((void*)0); | |||
481 | PyObject *safe; | |||
482 | ||||
483 | npy_cache_import("numpy.core._internal", "_view_is_safe", &checkfunc); | |||
484 | if (checkfunc == NULL((void*)0)) { | |||
485 | goto fail; | |||
486 | } | |||
487 | ||||
488 | safe = PyObject_CallFunction_PyObject_CallFunction_SizeT(checkfunc, "OO", | |||
489 | PyArray_DESCR(self), newtype); | |||
490 | if (safe == NULL((void*)0)) { | |||
491 | goto fail; | |||
492 | } | |||
493 | Py_DECREF(safe)_Py_DECREF(((PyObject*)(safe))); | |||
494 | } | |||
495 | ||||
496 | /* | |||
497 | * Viewing as an unsized void implies a void dtype matching the size of the | |||
498 | * current dtype. | |||
499 | */ | |||
500 | if (newtype->type_num == NPY_VOID && | |||
501 | PyDataType_ISUNSIZED(newtype)((newtype)->elsize == 0 && !(((PyArray_Descr *)(newtype ))->names != ((void*)0))) && | |||
502 | newtype->elsize != PyArray_DESCR(self)->elsize) { | |||
503 | PyArray_DESCR_REPLACE(newtype)do { PyArray_Descr *_new_; _new_ = PyArray_DescrNew(newtype); _Py_XDECREF(((PyObject*)(newtype))); newtype = _new_; } while (0); | |||
504 | if (newtype == NULL((void*)0)) { | |||
505 | return -1; | |||
506 | } | |||
507 | newtype->elsize = PyArray_DESCR(self)->elsize; | |||
508 | } | |||
509 | ||||
510 | /* Changing the size of the dtype results in a shape change */ | |||
511 | if (newtype->elsize != PyArray_DESCR(self)->elsize) { | |||
512 | int axis; | |||
513 | npy_intp newdim; | |||
514 | ||||
515 | /* forbidden cases */ | |||
516 | if (PyArray_NDIM(self) == 0) { | |||
517 | PyErr_SetString(PyExc_ValueError, | |||
518 | "Changing the dtype of a 0d array is only supported " | |||
519 | "if the itemsize is unchanged"); | |||
520 | goto fail; | |||
521 | } | |||
522 | else if (PyDataType_HASSUBARRAY(newtype)((newtype)->subarray != ((void*)0))) { | |||
523 | PyErr_SetString(PyExc_ValueError, | |||
524 | "Changing the dtype to a subarray type is only supported " | |||
525 | "if the total itemsize is unchanged"); | |||
526 | goto fail; | |||
527 | } | |||
528 | ||||
529 | /* determine which axis to resize */ | |||
530 | if (PyArray_IS_C_CONTIGUOUS(self)PyArray_CHKFLAGS((self), 0x0001)) { | |||
531 | axis = PyArray_NDIM(self) - 1; | |||
532 | } | |||
533 | else if (PyArray_IS_F_CONTIGUOUS(self)PyArray_CHKFLAGS((self), 0x0002)) { | |||
534 | /* 2015-11-27 1.11.0, gh-6747 */ | |||
535 | if (DEPRECATE(PyErr_WarnEx(PyExc_DeprecationWarning,"Changing the shape of an F-contiguous array by " "descriptor assignment is deprecated. To maintain the " "Fortran contiguity of a multidimensional Fortran " "array, use 'a.T.view(...).T' instead",1) | |||
536 | "Changing the shape of an F-contiguous array by "PyErr_WarnEx(PyExc_DeprecationWarning,"Changing the shape of an F-contiguous array by " "descriptor assignment is deprecated. To maintain the " "Fortran contiguity of a multidimensional Fortran " "array, use 'a.T.view(...).T' instead",1) | |||
537 | "descriptor assignment is deprecated. To maintain the "PyErr_WarnEx(PyExc_DeprecationWarning,"Changing the shape of an F-contiguous array by " "descriptor assignment is deprecated. To maintain the " "Fortran contiguity of a multidimensional Fortran " "array, use 'a.T.view(...).T' instead",1) | |||
538 | "Fortran contiguity of a multidimensional Fortran "PyErr_WarnEx(PyExc_DeprecationWarning,"Changing the shape of an F-contiguous array by " "descriptor assignment is deprecated. To maintain the " "Fortran contiguity of a multidimensional Fortran " "array, use 'a.T.view(...).T' instead",1) | |||
539 | "array, use 'a.T.view(...).T' instead")PyErr_WarnEx(PyExc_DeprecationWarning,"Changing the shape of an F-contiguous array by " "descriptor assignment is deprecated. To maintain the " "Fortran contiguity of a multidimensional Fortran " "array, use 'a.T.view(...).T' instead",1) < 0) { | |||
540 | goto fail; | |||
541 | } | |||
542 | axis = 0; | |||
543 | } | |||
544 | else { | |||
545 | /* Don't mention the deprecated F-contiguous support */ | |||
546 | PyErr_SetString(PyExc_ValueError, | |||
547 | "To change to a dtype of a different size, the array must " | |||
548 | "be C-contiguous"); | |||
549 | goto fail; | |||
550 | } | |||
551 | ||||
552 | if (newtype->elsize < PyArray_DESCR(self)->elsize) { | |||
553 | /* if it is compatible, increase the size of the relevant axis */ | |||
554 | if (newtype->elsize == 0 || | |||
555 | PyArray_DESCR(self)->elsize % newtype->elsize != 0) { | |||
556 | PyErr_SetString(PyExc_ValueError, | |||
557 | "When changing to a smaller dtype, its size must be a " | |||
558 | "divisor of the size of original dtype"); | |||
559 | goto fail; | |||
560 | } | |||
561 | newdim = PyArray_DESCR(self)->elsize / newtype->elsize; | |||
562 | PyArray_DIMS(self)[axis] *= newdim; | |||
563 | PyArray_STRIDES(self)[axis] = newtype->elsize; | |||
564 | } | |||
565 | else if (newtype->elsize > PyArray_DESCR(self)->elsize) { | |||
566 | /* if it is compatible, decrease the size of the relevant axis */ | |||
567 | newdim = PyArray_DIMS(self)[axis] * PyArray_DESCR(self)->elsize; | |||
568 | if ((newdim % newtype->elsize) != 0) { | |||
569 | PyErr_SetString(PyExc_ValueError, | |||
570 | "When changing to a larger dtype, its size must be a " | |||
571 | "divisor of the total size in bytes of the last axis " | |||
572 | "of the array."); | |||
573 | goto fail; | |||
574 | } | |||
575 | PyArray_DIMS(self)[axis] = newdim / newtype->elsize; | |||
576 | PyArray_STRIDES(self)[axis] = newtype->elsize; | |||
577 | } | |||
578 | } | |||
579 | ||||
580 | /* Viewing as a subarray increases the number of dimensions */ | |||
581 | if (PyDataType_HASSUBARRAY(newtype)((newtype)->subarray != ((void*)0))) { | |||
582 | /* | |||
583 | * create new array object from data and update | |||
584 | * dimensions, strides and descr from it | |||
585 | */ | |||
586 | PyArrayObject *temp; | |||
587 | /* | |||
588 | * We would decref newtype here. | |||
589 | * temp will steal a reference to it | |||
590 | */ | |||
591 | temp = (PyArrayObject *) | |||
592 | PyArray_NewFromDescr(&PyArray_Type, newtype, PyArray_NDIM(self), | |||
593 | PyArray_DIMS(self), PyArray_STRIDES(self), | |||
594 | PyArray_DATA(self), PyArray_FLAGS(self), NULL((void*)0)); | |||
595 | if (temp == NULL((void*)0)) { | |||
596 | return -1; | |||
597 | } | |||
598 | npy_free_cache_dim_array(self); | |||
599 | ((PyArrayObject_fields *)self)->dimensions = PyArray_DIMS(temp); | |||
600 | ((PyArrayObject_fields *)self)->nd = PyArray_NDIM(temp); | |||
601 | ((PyArrayObject_fields *)self)->strides = PyArray_STRIDES(temp); | |||
602 | newtype = PyArray_DESCR(temp); | |||
603 | Py_INCREF(PyArray_DESCR(temp))_Py_INCREF(((PyObject*)(PyArray_DESCR(temp)))); | |||
604 | /* Fool deallocator not to delete these*/ | |||
605 | ((PyArrayObject_fields *)temp)->nd = 0; | |||
606 | ((PyArrayObject_fields *)temp)->dimensions = NULL((void*)0); | |||
607 | Py_DECREF(temp)_Py_DECREF(((PyObject*)(temp))); | |||
608 | } | |||
609 | ||||
610 | Py_DECREF(PyArray_DESCR(self))_Py_DECREF(((PyObject*)(PyArray_DESCR(self)))); | |||
611 | ((PyArrayObject_fields *)self)->descr = newtype; | |||
612 | PyArray_UpdateFlags(self, NPY_ARRAY_UPDATE_ALL(0x0001 | 0x0002 | 0x0100)); | |||
613 | return 0; | |||
614 | ||||
615 | fail: | |||
616 | Py_DECREF(newtype)_Py_DECREF(((PyObject*)(newtype))); | |||
617 | return -1; | |||
618 | } | |||
619 | ||||
620 | static PyObject * | |||
621 | array_struct_get(PyArrayObject *self) | |||
622 | { | |||
623 | PyArrayInterface *inter; | |||
624 | ||||
625 | inter = (PyArrayInterface *)PyArray_mallocPyMem_RawMalloc(sizeof(PyArrayInterface)); | |||
626 | if (inter==NULL((void*)0)) { | |||
627 | return PyErr_NoMemory(); | |||
628 | } | |||
629 | inter->two = 2; | |||
630 | inter->nd = PyArray_NDIM(self); | |||
631 | inter->typekind = PyArray_DESCR(self)->kind; | |||
632 | inter->itemsize = PyArray_DESCR(self)->elsize; | |||
633 | inter->flags = PyArray_FLAGS(self); | |||
634 | if (inter->flags & NPY_ARRAY_WARN_ON_WRITE) { | |||
635 | /* Export a warn-on-write array as read-only */ | |||
636 | inter->flags = inter->flags & ~NPY_ARRAY_WARN_ON_WRITE; | |||
637 | inter->flags = inter->flags & ~NPY_ARRAY_WRITEABLE0x0400; | |||
638 | } | |||
639 | /* reset unused flags */ | |||
640 | inter->flags &= ~(NPY_ARRAY_WRITEBACKIFCOPY0x2000 | NPY_ARRAY_UPDATEIFCOPY0x1000 |NPY_ARRAY_OWNDATA0x0004); | |||
641 | if (PyArray_ISNOTSWAPPED(self)((PyArray_DESCR(self)->byteorder) != '>')) inter->flags |= NPY_ARRAY_NOTSWAPPED0x0200; | |||
642 | /* | |||
643 | * Copy shape and strides over since these can be reset | |||
644 | *when the array is "reshaped". | |||
645 | */ | |||
646 | if (PyArray_NDIM(self) > 0) { | |||
647 | inter->shape = (npy_intp *)PyArray_mallocPyMem_RawMalloc(2*sizeof(npy_intp)*PyArray_NDIM(self)); | |||
648 | if (inter->shape == NULL((void*)0)) { | |||
649 | PyArray_freePyMem_RawFree(inter); | |||
650 | return PyErr_NoMemory(); | |||
651 | } | |||
652 | inter->strides = inter->shape + PyArray_NDIM(self); | |||
653 | if (PyArray_NDIM(self)) { | |||
654 | memcpy(inter->shape, PyArray_DIMS(self), sizeof(npy_intp)*PyArray_NDIM(self)); | |||
655 | memcpy(inter->strides, PyArray_STRIDES(self), sizeof(npy_intp)*PyArray_NDIM(self)); | |||
656 | } | |||
657 | } | |||
658 | else { | |||
659 | inter->shape = NULL((void*)0); | |||
660 | inter->strides = NULL((void*)0); | |||
661 | } | |||
662 | inter->data = PyArray_DATA(self); | |||
663 | if (PyDataType_HASFIELDS(PyArray_DESCR(self))(((PyArray_Descr *)(PyArray_DESCR(self)))->names != ((void *)0))) { | |||
664 | inter->descr = arraydescr_protocol_descr_get(PyArray_DESCR(self)); | |||
665 | if (inter->descr == NULL((void*)0)) { | |||
666 | PyErr_Clear(); | |||
667 | } | |||
668 | else { | |||
669 | inter->flags &= NPY_ARR_HAS_DESCR0x0800; | |||
670 | } | |||
671 | } | |||
672 | else { | |||
673 | inter->descr = NULL((void*)0); | |||
674 | } | |||
675 | PyObject *ret = PyCapsule_New(inter, NULL((void*)0), gentype_struct_free); | |||
676 | if (ret == NULL((void*)0)) { | |||
677 | return NULL((void*)0); | |||
678 | } | |||
679 | Py_INCREF(self)_Py_INCREF(((PyObject*)(self))); | |||
680 | if (PyCapsule_SetContext(ret, self) < 0) { | |||
681 | return NULL((void*)0); | |||
682 | } | |||
683 | return ret; | |||
684 | } | |||
685 | ||||
686 | static PyObject * | |||
687 | array_base_get(PyArrayObject *self) | |||
688 | { | |||
689 | if (PyArray_BASE(self) == NULL((void*)0)) { | |||
690 | Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (& _Py_NoneStruct); | |||
691 | } | |||
692 | else { | |||
693 | Py_INCREF(PyArray_BASE(self))_Py_INCREF(((PyObject*)(PyArray_BASE(self)))); | |||
694 | return PyArray_BASE(self); | |||
695 | } | |||
696 | } | |||
697 | ||||
698 | /* | |||
699 | * Create a view of a complex array with an equivalent data-type | |||
700 | * except it is real instead of complex. | |||
701 | */ | |||
702 | static PyArrayObject * | |||
703 | _get_part(PyArrayObject *self, int imag) | |||
704 | { | |||
705 | int float_type_num; | |||
706 | PyArray_Descr *type; | |||
707 | PyArrayObject *ret; | |||
708 | int offset; | |||
709 | ||||
710 | switch (PyArray_DESCR(self)->type_num) { | |||
711 | case NPY_CFLOAT: | |||
712 | float_type_num = NPY_FLOAT; | |||
713 | break; | |||
714 | case NPY_CDOUBLE: | |||
715 | float_type_num = NPY_DOUBLE; | |||
716 | break; | |||
717 | case NPY_CLONGDOUBLE: | |||
718 | float_type_num = NPY_LONGDOUBLE; | |||
719 | break; | |||
720 | default: | |||
721 | PyErr_Format(PyExc_ValueError, | |||
722 | "Cannot convert complex type number %d to float", | |||
723 | PyArray_DESCR(self)->type_num); | |||
724 | return NULL((void*)0); | |||
725 | ||||
726 | } | |||
727 | type = PyArray_DescrFromType(float_type_num); | |||
728 | ||||
729 | offset = (imag ? type->elsize : 0); | |||
730 | ||||
731 | if (!PyArray_ISNBO(PyArray_DESCR(self)->byteorder)((PyArray_DESCR(self)->byteorder) != '>')) { | |||
732 | PyArray_Descr *new; | |||
733 | new = PyArray_DescrNew(type); | |||
734 | new->byteorder = PyArray_DESCR(self)->byteorder; | |||
735 | Py_DECREF(type)_Py_DECREF(((PyObject*)(type))); | |||
736 | type = new; | |||
737 | } | |||
738 | ret = (PyArrayObject *)PyArray_NewFromDescrAndBase( | |||
739 | Py_TYPE(self)(((PyObject*)(self))->ob_type), | |||
740 | type, | |||
741 | PyArray_NDIM(self), | |||
742 | PyArray_DIMS(self), | |||
743 | PyArray_STRIDES(self), | |||
744 | PyArray_BYTES(self) + offset, | |||
745 | PyArray_FLAGS(self), (PyObject *)self, (PyObject *)self); | |||
746 | if (ret == NULL((void*)0)) { | |||
747 | return NULL((void*)0); | |||
748 | } | |||
749 | return ret; | |||
750 | } | |||
751 | ||||
752 | /* For Object arrays, we need to get and set the | |||
753 | real part of each element. | |||
754 | */ | |||
755 | ||||
756 | static PyObject * | |||
757 | array_real_get(PyArrayObject *self) | |||
758 | { | |||
759 | PyArrayObject *ret; | |||
760 | ||||
761 | if (PyArray_ISCOMPLEX(self)(((PyArray_TYPE(self)) >= NPY_CFLOAT) && ((PyArray_TYPE (self)) <= NPY_CLONGDOUBLE))) { | |||
762 | ret = _get_part(self, 0); | |||
763 | return (PyObject *)ret; | |||
764 | } | |||
765 | else { | |||
766 | Py_INCREF(self)_Py_INCREF(((PyObject*)(self))); | |||
767 | return (PyObject *)self; | |||
768 | } | |||
769 | } | |||
770 | ||||
771 | ||||
772 | static int | |||
773 | array_real_set(PyArrayObject *self, PyObject *val) | |||
774 | { | |||
775 | PyArrayObject *ret; | |||
776 | PyArrayObject *new; | |||
777 | int retcode; | |||
778 | ||||
779 | if (val == NULL((void*)0)) { | |||
780 | PyErr_SetString(PyExc_AttributeError, | |||
781 | "Cannot delete array real part"); | |||
782 | return -1; | |||
783 | } | |||
784 | if (PyArray_ISCOMPLEX(self)(((PyArray_TYPE(self)) >= NPY_CFLOAT) && ((PyArray_TYPE (self)) <= NPY_CLONGDOUBLE))) { | |||
785 | ret = _get_part(self, 0); | |||
786 | if (ret == NULL((void*)0)) { | |||
787 | return -1; | |||
788 | } | |||
789 | } | |||
790 | else { | |||
791 | Py_INCREF(self)_Py_INCREF(((PyObject*)(self))); | |||
792 | ret = self; | |||
793 | } | |||
794 | new = (PyArrayObject *)PyArray_FROM_O(val)PyArray_FromAny(val, ((void*)0), 0, 0, 0, ((void*)0)); | |||
795 | if (new == NULL((void*)0)) { | |||
796 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | |||
797 | return -1; | |||
798 | } | |||
799 | retcode = PyArray_MoveInto(ret, new); | |||
800 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | |||
801 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); | |||
802 | return retcode; | |||
803 | } | |||
804 | ||||
805 | /* For Object arrays we need to get | |||
806 | and set the imaginary part of | |||
807 | each element | |||
808 | */ | |||
809 | ||||
810 | static PyObject * | |||
811 | array_imag_get(PyArrayObject *self) | |||
812 | { | |||
813 | PyArrayObject *ret; | |||
814 | ||||
815 | if (PyArray_ISCOMPLEX(self)(((PyArray_TYPE(self)) >= NPY_CFLOAT) && ((PyArray_TYPE (self)) <= NPY_CLONGDOUBLE))) { | |||
816 | ret = _get_part(self, 1); | |||
817 | } | |||
818 | else { | |||
819 | Py_INCREF(PyArray_DESCR(self))_Py_INCREF(((PyObject*)(PyArray_DESCR(self)))); | |||
820 | ret = (PyArrayObject *)PyArray_NewFromDescr(Py_TYPE(self)(((PyObject*)(self))->ob_type), | |||
821 | PyArray_DESCR(self), | |||
822 | PyArray_NDIM(self), | |||
823 | PyArray_DIMS(self), | |||
824 | NULL((void*)0), NULL((void*)0), | |||
825 | PyArray_ISFORTRAN(self)(PyArray_CHKFLAGS(self, 0x0002) && (!PyArray_CHKFLAGS (self, 0x0001))), | |||
826 | (PyObject *)self); | |||
827 | if (ret == NULL((void*)0)) { | |||
828 | return NULL((void*)0); | |||
829 | } | |||
830 | if (_zerofill(ret) < 0) { | |||
831 | return NULL((void*)0); | |||
832 | } | |||
833 | PyArray_CLEARFLAGS(ret, NPY_ARRAY_WRITEABLE0x0400); | |||
834 | } | |||
835 | return (PyObject *) ret; | |||
836 | } | |||
837 | ||||
838 | static int | |||
839 | array_imag_set(PyArrayObject *self, PyObject *val) | |||
840 | { | |||
841 | if (val == NULL((void*)0)) { | |||
842 | PyErr_SetString(PyExc_AttributeError, | |||
843 | "Cannot delete array imaginary part"); | |||
844 | return -1; | |||
845 | } | |||
846 | if (PyArray_ISCOMPLEX(self)(((PyArray_TYPE(self)) >= NPY_CFLOAT) && ((PyArray_TYPE (self)) <= NPY_CLONGDOUBLE))) { | |||
847 | PyArrayObject *ret; | |||
848 | PyArrayObject *new; | |||
849 | int retcode; | |||
850 | ||||
851 | ret = _get_part(self, 1); | |||
852 | if (ret == NULL((void*)0)) { | |||
853 | return -1; | |||
854 | } | |||
855 | new = (PyArrayObject *)PyArray_FROM_O(val)PyArray_FromAny(val, ((void*)0), 0, 0, 0, ((void*)0)); | |||
856 | if (new == NULL((void*)0)) { | |||
857 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | |||
858 | return -1; | |||
859 | } | |||
860 | retcode = PyArray_MoveInto(ret, new); | |||
861 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | |||
862 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); | |||
863 | return retcode; | |||
864 | } | |||
865 | else { | |||
866 | PyErr_SetString(PyExc_TypeError, | |||
867 | "array does not have imaginary part to set"); | |||
868 | return -1; | |||
869 | } | |||
870 | } | |||
871 | ||||
872 | static PyObject * | |||
873 | array_flat_get(PyArrayObject *self) | |||
874 | { | |||
875 | return PyArray_IterNew((PyObject *)self); | |||
876 | } | |||
877 | ||||
878 | static int | |||
879 | array_flat_set(PyArrayObject *self, PyObject *val) | |||
880 | { | |||
881 | PyArrayObject *arr = NULL((void*)0); | |||
882 | int retval = -1; | |||
883 | PyArrayIterObject *selfit = NULL((void*)0), *arrit = NULL((void*)0); | |||
884 | PyArray_Descr *typecode; | |||
885 | int swap; | |||
886 | PyArray_CopySwapFunc *copyswap; | |||
887 | ||||
888 | if (val == NULL((void*)0)) { | |||
889 | PyErr_SetString(PyExc_AttributeError, | |||
890 | "Cannot delete array flat iterator"); | |||
891 | return -1; | |||
892 | } | |||
893 | if (PyArray_FailUnlessWriteable(self, "array") < 0) return -1; | |||
894 | typecode = PyArray_DESCR(self); | |||
895 | Py_INCREF(typecode)_Py_INCREF(((PyObject*)(typecode))); | |||
896 | arr = (PyArrayObject *)PyArray_FromAny(val, typecode, | |||
897 | 0, 0, NPY_ARRAY_FORCECAST0x0010 | PyArray_FORTRAN_IF(self)((PyArray_CHKFLAGS(self, 0x0002) ? 0x0002 : 0)), NULL((void*)0)); | |||
898 | if (arr == NULL((void*)0)) { | |||
899 | return -1; | |||
900 | } | |||
901 | arrit = (PyArrayIterObject *)PyArray_IterNew((PyObject *)arr); | |||
902 | if (arrit == NULL((void*)0)) { | |||
903 | goto exit; | |||
904 | } | |||
905 | selfit = (PyArrayIterObject *)PyArray_IterNew((PyObject *)self); | |||
906 | if (selfit == NULL((void*)0)) { | |||
907 | goto exit; | |||
908 | } | |||
909 | if (arrit->size == 0) { | |||
910 | retval = 0; | |||
911 | goto exit; | |||
912 | } | |||
913 | swap = PyArray_ISNOTSWAPPED(self)((PyArray_DESCR(self)->byteorder) != '>') != PyArray_ISNOTSWAPPED(arr)((PyArray_DESCR(arr)->byteorder) != '>'); | |||
914 | copyswap = PyArray_DESCR(self)->f->copyswap; | |||
915 | if (PyDataType_REFCHK(PyArray_DESCR(self))(((PyArray_DESCR(self))->flags & (0x01)) == (0x01))) { | |||
916 | while (selfit->index < selfit->size) { | |||
917 | PyArray_Item_XDECREF(selfit->dataptr, PyArray_DESCR(self)); | |||
918 | PyArray_Item_INCREF(arrit->dataptr, PyArray_DESCR(arr)); | |||
919 | memmove(selfit->dataptr, arrit->dataptr, sizeof(PyObject **)); | |||
920 | if (swap) { | |||
921 | copyswap(selfit->dataptr, NULL((void*)0), swap, self); | |||
922 | } | |||
923 | PyArray_ITER_NEXT(selfit)do { ((PyArrayIterObject *)(selfit))->index++; if (((PyArrayIterObject *)(selfit))->nd_m1 == 0) { do { (((PyArrayIterObject *)(selfit )))->dataptr += ((PyArrayIterObject *)(((PyArrayIterObject *)(selfit))))->strides[0]; (((PyArrayIterObject *)(selfit )))->coordinates[0]++; } while (0); } else if (((PyArrayIterObject *)(selfit))->contiguous) ((PyArrayIterObject *)(selfit))-> dataptr += PyArray_DESCR(((PyArrayIterObject *)(selfit))-> ao)->elsize; else if (((PyArrayIterObject *)(selfit))-> nd_m1 == 1) { do { if ((((PyArrayIterObject *)(selfit)))-> coordinates[1] < (((PyArrayIterObject *)(selfit)))->dims_m1 [1]) { (((PyArrayIterObject *)(selfit)))->coordinates[1]++ ; (((PyArrayIterObject *)(selfit)))->dataptr += (((PyArrayIterObject *)(selfit)))->strides[1]; } else { (((PyArrayIterObject * )(selfit)))->coordinates[1] = 0; (((PyArrayIterObject *)(selfit )))->coordinates[0]++; (((PyArrayIterObject *)(selfit)))-> dataptr += (((PyArrayIterObject *)(selfit)))->strides[0] - (((PyArrayIterObject *)(selfit)))->backstrides[1]; } } while (0); } else { int __npy_i; for (__npy_i=((PyArrayIterObject * )(selfit))->nd_m1; __npy_i >= 0; __npy_i--) { if (((PyArrayIterObject *)(selfit))->coordinates[__npy_i] < ((PyArrayIterObject *)(selfit))->dims_m1[__npy_i]) { ((PyArrayIterObject *)(selfit ))->coordinates[__npy_i]++; ((PyArrayIterObject *)(selfit) )->dataptr += ((PyArrayIterObject *)(selfit))->strides[ __npy_i]; break; } else { ((PyArrayIterObject *)(selfit))-> coordinates[__npy_i] = 0; ((PyArrayIterObject *)(selfit))-> dataptr -= ((PyArrayIterObject *)(selfit))->backstrides[__npy_i ]; } } } } while (0); | |||
924 | PyArray_ITER_NEXT(arrit)do { ((PyArrayIterObject *)(arrit))->index++; if (((PyArrayIterObject *)(arrit))->nd_m1 == 0) { do { (((PyArrayIterObject *)(arrit )))->dataptr += ((PyArrayIterObject *)(((PyArrayIterObject *)(arrit))))->strides[0]; (((PyArrayIterObject *)(arrit)) )->coordinates[0]++; } while (0); } else if (((PyArrayIterObject *)(arrit))->contiguous) ((PyArrayIterObject *)(arrit))-> dataptr += PyArray_DESCR(((PyArrayIterObject *)(arrit))->ao )->elsize; else if (((PyArrayIterObject *)(arrit))->nd_m1 == 1) { do { if ((((PyArrayIterObject *)(arrit)))->coordinates [1] < (((PyArrayIterObject *)(arrit)))->dims_m1[1]) { ( ((PyArrayIterObject *)(arrit)))->coordinates[1]++; (((PyArrayIterObject *)(arrit)))->dataptr += (((PyArrayIterObject *)(arrit)))-> strides[1]; } else { (((PyArrayIterObject *)(arrit)))->coordinates [1] = 0; (((PyArrayIterObject *)(arrit)))->coordinates[0]++ ; (((PyArrayIterObject *)(arrit)))->dataptr += (((PyArrayIterObject *)(arrit)))->strides[0] - (((PyArrayIterObject *)(arrit)) )->backstrides[1]; } } while (0); } else { int __npy_i; for (__npy_i=((PyArrayIterObject *)(arrit))->nd_m1; __npy_i >= 0; __npy_i--) { if (((PyArrayIterObject *)(arrit))->coordinates [__npy_i] < ((PyArrayIterObject *)(arrit))->dims_m1[__npy_i ]) { ((PyArrayIterObject *)(arrit))->coordinates[__npy_i]++ ; ((PyArrayIterObject *)(arrit))->dataptr += ((PyArrayIterObject *)(arrit))->strides[__npy_i]; break; } else { ((PyArrayIterObject *)(arrit))->coordinates[__npy_i] = 0; ((PyArrayIterObject *)(arrit))->dataptr -= ((PyArrayIterObject *)(arrit))-> backstrides[__npy_i]; } } } } while (0); | |||
925 | if (arrit->index == arrit->size) { | |||
926 | PyArray_ITER_RESET(arrit)do { ((PyArrayIterObject *)(arrit))->index = 0; ((PyArrayIterObject *)(arrit))->dataptr = PyArray_BYTES(((PyArrayIterObject * )(arrit))->ao); memset(((PyArrayIterObject *)(arrit))-> coordinates, 0, (((PyArrayIterObject *)(arrit))->nd_m1+1)* sizeof(npy_intp)); } while (0); | |||
927 | } | |||
928 | } | |||
929 | retval = 0; | |||
930 | goto exit; | |||
931 | } | |||
932 | ||||
933 | while(selfit->index < selfit->size) { | |||
934 | copyswap(selfit->dataptr, arrit->dataptr, swap, self); | |||
935 | PyArray_ITER_NEXT(selfit)do { ((PyArrayIterObject *)(selfit))->index++; if (((PyArrayIterObject *)(selfit))->nd_m1 == 0) { do { (((PyArrayIterObject *)(selfit )))->dataptr += ((PyArrayIterObject *)(((PyArrayIterObject *)(selfit))))->strides[0]; (((PyArrayIterObject *)(selfit )))->coordinates[0]++; } while (0); } else if (((PyArrayIterObject *)(selfit))->contiguous) ((PyArrayIterObject *)(selfit))-> dataptr += PyArray_DESCR(((PyArrayIterObject *)(selfit))-> ao)->elsize; else if (((PyArrayIterObject *)(selfit))-> nd_m1 == 1) { do { if ((((PyArrayIterObject *)(selfit)))-> coordinates[1] < (((PyArrayIterObject *)(selfit)))->dims_m1 [1]) { (((PyArrayIterObject *)(selfit)))->coordinates[1]++ ; (((PyArrayIterObject *)(selfit)))->dataptr += (((PyArrayIterObject *)(selfit)))->strides[1]; } else { (((PyArrayIterObject * )(selfit)))->coordinates[1] = 0; (((PyArrayIterObject *)(selfit )))->coordinates[0]++; (((PyArrayIterObject *)(selfit)))-> dataptr += (((PyArrayIterObject *)(selfit)))->strides[0] - (((PyArrayIterObject *)(selfit)))->backstrides[1]; } } while (0); } else { int __npy_i; for (__npy_i=((PyArrayIterObject * )(selfit))->nd_m1; __npy_i >= 0; __npy_i--) { if (((PyArrayIterObject *)(selfit))->coordinates[__npy_i] < ((PyArrayIterObject *)(selfit))->dims_m1[__npy_i]) { ((PyArrayIterObject *)(selfit ))->coordinates[__npy_i]++; ((PyArrayIterObject *)(selfit) )->dataptr += ((PyArrayIterObject *)(selfit))->strides[ __npy_i]; break; } else { ((PyArrayIterObject *)(selfit))-> coordinates[__npy_i] = 0; ((PyArrayIterObject *)(selfit))-> dataptr -= ((PyArrayIterObject *)(selfit))->backstrides[__npy_i ]; } } } } while (0); | |||
936 | PyArray_ITER_NEXT(arrit)do { ((PyArrayIterObject *)(arrit))->index++; if (((PyArrayIterObject *)(arrit))->nd_m1 == 0) { do { (((PyArrayIterObject *)(arrit )))->dataptr += ((PyArrayIterObject *)(((PyArrayIterObject *)(arrit))))->strides[0]; (((PyArrayIterObject *)(arrit)) )->coordinates[0]++; } while (0); } else if (((PyArrayIterObject *)(arrit))->contiguous) ((PyArrayIterObject *)(arrit))-> dataptr += PyArray_DESCR(((PyArrayIterObject *)(arrit))->ao )->elsize; else if (((PyArrayIterObject *)(arrit))->nd_m1 == 1) { do { if ((((PyArrayIterObject *)(arrit)))->coordinates [1] < (((PyArrayIterObject *)(arrit)))->dims_m1[1]) { ( ((PyArrayIterObject *)(arrit)))->coordinates[1]++; (((PyArrayIterObject *)(arrit)))->dataptr += (((PyArrayIterObject *)(arrit)))-> strides[1]; } else { (((PyArrayIterObject *)(arrit)))->coordinates [1] = 0; (((PyArrayIterObject *)(arrit)))->coordinates[0]++ ; (((PyArrayIterObject *)(arrit)))->dataptr += (((PyArrayIterObject *)(arrit)))->strides[0] - (((PyArrayIterObject *)(arrit)) )->backstrides[1]; } } while (0); } else { int __npy_i; for (__npy_i=((PyArrayIterObject *)(arrit))->nd_m1; __npy_i >= 0; __npy_i--) { if (((PyArrayIterObject *)(arrit))->coordinates [__npy_i] < ((PyArrayIterObject *)(arrit))->dims_m1[__npy_i ]) { ((PyArrayIterObject *)(arrit))->coordinates[__npy_i]++ ; ((PyArrayIterObject *)(arrit))->dataptr += ((PyArrayIterObject *)(arrit))->strides[__npy_i]; break; } else { ((PyArrayIterObject *)(arrit))->coordinates[__npy_i] = 0; ((PyArrayIterObject *)(arrit))->dataptr -= ((PyArrayIterObject *)(arrit))-> backstrides[__npy_i]; } } } } while (0); | |||
937 | if (arrit->index == arrit->size) { | |||
938 | PyArray_ITER_RESET(arrit)do { ((PyArrayIterObject *)(arrit))->index = 0; ((PyArrayIterObject *)(arrit))->dataptr = PyArray_BYTES(((PyArrayIterObject * )(arrit))->ao); memset(((PyArrayIterObject *)(arrit))-> coordinates, 0, (((PyArrayIterObject *)(arrit))->nd_m1+1)* sizeof(npy_intp)); } while (0); | |||
939 | } | |||
940 | } | |||
941 | retval = 0; | |||
942 | ||||
943 | exit: | |||
944 | Py_XDECREF(selfit)_Py_XDECREF(((PyObject*)(selfit))); | |||
945 | Py_XDECREF(arrit)_Py_XDECREF(((PyObject*)(arrit))); | |||
946 | Py_XDECREF(arr)_Py_XDECREF(((PyObject*)(arr))); | |||
947 | return retval; | |||
948 | } | |||
949 | ||||
950 | static PyObject * | |||
951 | array_transpose_get(PyArrayObject *self) | |||
952 | { | |||
953 | return PyArray_Transpose(self, NULL((void*)0)); | |||
954 | } | |||
955 | ||||
956 | /* If this is None, no function call is made | |||
957 | --- default sub-class behavior | |||
958 | */ | |||
959 | static PyObject * | |||
960 | array_finalize_get(PyArrayObject *NPY_UNUSED(self)(__NPY_UNUSED_TAGGEDself) __attribute__ ((__unused__))) | |||
961 | { | |||
962 | Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (& _Py_NoneStruct); | |||
963 | } | |||
964 | ||||
965 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyGetSetDef array_getsetlist[] = { | |||
966 | {"ndim", | |||
967 | (getter)array_ndim_get, | |||
968 | NULL((void*)0), | |||
969 | NULL((void*)0), NULL((void*)0)}, | |||
970 | {"flags", | |||
971 | (getter)array_flags_get, | |||
972 | NULL((void*)0), | |||
973 | NULL((void*)0), NULL((void*)0)}, | |||
974 | {"shape", | |||
975 | (getter)array_shape_get, | |||
976 | (setter)array_shape_set, | |||
977 | NULL((void*)0), NULL((void*)0)}, | |||
978 | {"strides", | |||
979 | (getter)array_strides_get, | |||
980 | (setter)array_strides_set, | |||
981 | NULL((void*)0), NULL((void*)0)}, | |||
982 | {"data", | |||
983 | (getter)array_data_get, | |||
984 | (setter)array_data_set, | |||
985 | NULL((void*)0), NULL((void*)0)}, | |||
986 | {"itemsize", | |||
987 | (getter)array_itemsize_get, | |||
988 | NULL((void*)0), | |||
989 | NULL((void*)0), NULL((void*)0)}, | |||
990 | {"size", | |||
991 | (getter)array_size_get, | |||
992 | NULL((void*)0), | |||
993 | NULL((void*)0), NULL((void*)0)}, | |||
994 | {"nbytes", | |||
995 | (getter)array_nbytes_get, | |||
996 | NULL((void*)0), | |||
997 | NULL((void*)0), NULL((void*)0)}, | |||
998 | {"base", | |||
999 | (getter)array_base_get, | |||
1000 | NULL((void*)0), | |||
1001 | NULL((void*)0), NULL((void*)0)}, | |||
1002 | {"dtype", | |||
1003 | (getter)array_descr_get, | |||
1004 | (setter)array_descr_set, | |||
1005 | NULL((void*)0), NULL((void*)0)}, | |||
1006 | {"real", | |||
1007 | (getter)array_real_get, | |||
1008 | (setter)array_real_set, | |||
1009 | NULL((void*)0), NULL((void*)0)}, | |||
1010 | {"imag", | |||
1011 | (getter)array_imag_get, | |||
1012 | (setter)array_imag_set, | |||
1013 | NULL((void*)0), NULL((void*)0)}, | |||
1014 | {"flat", | |||
1015 | (getter)array_flat_get, | |||
1016 | (setter)array_flat_set, | |||
1017 | NULL((void*)0), NULL((void*)0)}, | |||
1018 | {"ctypes", | |||
1019 | (getter)array_ctypes_get, | |||
1020 | NULL((void*)0), | |||
1021 | NULL((void*)0), NULL((void*)0)}, | |||
1022 | {"T", | |||
1023 | (getter)array_transpose_get, | |||
1024 | NULL((void*)0), | |||
1025 | NULL((void*)0), NULL((void*)0)}, | |||
1026 | {"__array_interface__", | |||
1027 | (getter)array_interface_get, | |||
1028 | NULL((void*)0), | |||
1029 | NULL((void*)0), NULL((void*)0)}, | |||
1030 | {"__array_struct__", | |||
1031 | (getter)array_struct_get, | |||
1032 | NULL((void*)0), | |||
1033 | NULL((void*)0), NULL((void*)0)}, | |||
1034 | {"__array_priority__", | |||
1035 | (getter)array_priority_get, | |||
1036 | NULL((void*)0), | |||
1037 | NULL((void*)0), NULL((void*)0)}, | |||
1038 | {"__array_finalize__", | |||
1039 | (getter)array_finalize_get, | |||
1040 | NULL((void*)0), | |||
1041 | NULL((void*)0), NULL((void*)0)}, | |||
1042 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)}, /* Sentinel */ | |||
1043 | }; | |||
1044 | ||||
1045 | /****************** end of attribute get and set routines *******************/ |
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) \ | ||||||
34 | (((offset) + (alignment) - 1) & (-(alignment))) | ||||||
35 | |||||||
36 | #ifndef PyDictProxy_Check | ||||||
37 | #define PyDictProxy_Check(obj) (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("/tmp/pyrefcon/numpy/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))) { | ||||||
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); | ||||||
546 | } | ||||||
547 | maxalign = PyArray_MAX(maxalign, _align)(((maxalign)>(_align))?(maxalign):(_align)); | ||||||
548 | } | ||||||
549 | PyObject *tup = PyTuple_New((title
| ||||||
| |||||||
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
| ||||||
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); | ||||||
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); | ||||||
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); | ||||||
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("/tmp/pyrefcon/numpy/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("/tmp/pyrefcon/numpy/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("/tmp/pyrefcon/numpy/numpy/core/src/multiarray/descriptor.c" , 974); | ||||||
975 | } | ||||||
976 | return -1; | ||||||
977 | } | ||||||
978 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(tup, "Oi|O", &fld2_dtype, | ||||||
979 | &fld2_offset, &title)) { | ||||||
980 | return -1; | ||||||
981 | } | ||||||
982 | /* Raise an exception if it overlaps */ | ||||||
983 | if (fld_offset < fld2_offset + fld2_dtype->elsize && | ||||||
984 | fld2_offset < fld_offset + fld_dtype->elsize) { | ||||||
985 | PyErr_SetString(PyExc_TypeError, | ||||||
986 | "Cannot create a NumPy dtype with overlapping " | ||||||
987 | "object fields"); | ||||||
988 | return -1; | ||||||
989 | } | ||||||
990 | } | ||||||
991 | } | ||||||
992 | } | ||||||
993 | } | ||||||
994 | |||||||
995 | /* It passed all the overlap tests */ | ||||||
996 | return 0; | ||||||
997 | } | ||||||
998 | |||||||
999 | /* | ||||||
1000 | * a dictionary specifying a data-type | ||||||
1001 | * must have at least two and up to four | ||||||
1002 | * keys These must all be sequences of the same length. | ||||||
1003 | * | ||||||
1004 | * can also have an additional key called "metadata" which can be any dictionary | ||||||
1005 | * | ||||||
1006 | * "names" --- field names | ||||||
1007 | * "formats" --- the data-type descriptors for the field. | ||||||
1008 | * | ||||||
1009 | * Optional: | ||||||
1010 | * | ||||||
1011 | * "offsets" --- integers indicating the offset into the | ||||||
1012 | * record of the start of the field. | ||||||
1013 | * if not given, then "consecutive offsets" | ||||||
1014 | * will be assumed and placed in the dictionary. | ||||||
1015 | * | ||||||
1016 | * "titles" --- Allows the use of an additional key | ||||||
1017 | * for the fields dictionary.(if these are strings | ||||||
1018 | * or unicode objects) or | ||||||
1019 | * this can also be meta-data to | ||||||
1020 | * be passed around with the field description. | ||||||
1021 | * | ||||||
1022 | * Attribute-lookup-based field names merely has to query the fields | ||||||
1023 | * dictionary of the data-descriptor. Any result present can be used | ||||||
1024 | * to return the correct field. | ||||||
1025 | * | ||||||
1026 | * So, the notion of what is a name and what is a title is really quite | ||||||
1027 | * arbitrary. | ||||||
1028 | * | ||||||
1029 | * What does distinguish a title, however, is that if it is not None, | ||||||
1030 | * it will be placed at the end of the tuple inserted into the | ||||||
1031 | * fields dictionary.and can therefore be used to carry meta-data around. | ||||||
1032 | * | ||||||
1033 | * If the dictionary does not have "names" and "formats" entries, | ||||||
1034 | * then it will be checked for conformity and used directly. | ||||||
1035 | */ | ||||||
1036 | static PyArray_Descr * | ||||||
1037 | _convert_from_field_dict(PyObject *obj, int align) | ||||||
1038 | { | ||||||
1039 | PyObject *_numpy_internal; | ||||||
1040 | PyArray_Descr *res; | ||||||
1041 | |||||||
1042 | _numpy_internal = PyImport_ImportModule("numpy.core._internal"); | ||||||
1043 | if (_numpy_internal == NULL((void*)0)) { | ||||||
1044 | return NULL((void*)0); | ||||||
1045 | } | ||||||
1046 | res = (PyArray_Descr *)PyObject_CallMethod_PyObject_CallMethod_SizeT(_numpy_internal, | ||||||
1047 | "_usefields", "Oi", obj, align); | ||||||
1048 | Py_DECREF(_numpy_internal)_Py_DECREF(((PyObject*)(_numpy_internal))); | ||||||
1049 | return res; | ||||||
1050 | } | ||||||
1051 | |||||||
1052 | /* | ||||||
1053 | * Creates a struct dtype object from a Python dictionary. | ||||||
1054 | */ | ||||||
1055 | static PyArray_Descr * | ||||||
1056 | _convert_from_dict(PyObject *obj, int align) | ||||||
1057 | { | ||||||
1058 | PyObject *fields = PyDict_New(); | ||||||
1059 | if (fields == NULL((void*)0)) { | ||||||
1060 | return (PyArray_Descr *)PyErr_NoMemory(); | ||||||
1061 | } | ||||||
1062 | /* | ||||||
1063 | * Use PyMapping_GetItemString to support dictproxy objects as well. | ||||||
1064 | */ | ||||||
1065 | PyObject *names = PyMapping_GetItemString(obj, "names"); | ||||||
1066 | if (names == NULL((void*)0)) { | ||||||
1067 | Py_DECREF(fields)_Py_DECREF(((PyObject*)(fields))); | ||||||
1068 | /* XXX should check this is a KeyError */ | ||||||
1069 | PyErr_Clear(); | ||||||
1070 | return _convert_from_field_dict(obj, align); | ||||||
1071 | } | ||||||
1072 | PyObject *descrs = PyMapping_GetItemString(obj, "formats"); | ||||||
1073 | if (descrs == NULL((void*)0)) { | ||||||
1074 | Py_DECREF(fields)_Py_DECREF(((PyObject*)(fields))); | ||||||
1075 | /* XXX should check this is a KeyError */ | ||||||
1076 | PyErr_Clear(); | ||||||
1077 | Py_DECREF(names)_Py_DECREF(((PyObject*)(names))); | ||||||
1078 | return _convert_from_field_dict(obj, align); | ||||||
1079 | } | ||||||
1080 | int n = PyObject_LengthPyObject_Size(names); | ||||||
1081 | PyObject *offsets = PyMapping_GetItemString(obj, "offsets"); | ||||||
1082 | if (!offsets) { | ||||||
1083 | PyErr_Clear(); | ||||||
1084 | } | ||||||
1085 | PyObject *titles = PyMapping_GetItemString(obj, "titles"); | ||||||
1086 | if (!titles) { | ||||||
1087 | PyErr_Clear(); | ||||||
1088 | } | ||||||
1089 | |||||||
1090 | if ((n > PyObject_LengthPyObject_Size(descrs)) | ||||||
1091 | || (offsets && (n > PyObject_LengthPyObject_Size(offsets))) | ||||||
1092 | || (titles && (n > PyObject_LengthPyObject_Size(titles)))) { | ||||||
1093 | PyErr_SetString(PyExc_ValueError, | ||||||
1094 | "'names', 'formats', 'offsets', and 'titles' dict " | ||||||
1095 | "entries must have the same length"); | ||||||
1096 | goto fail; | ||||||
1097 | } | ||||||
1098 | |||||||
1099 | /* | ||||||
1100 | * If a property 'aligned' is in the dict, it overrides the align flag | ||||||
1101 | * to be True if it not already true. | ||||||
1102 | */ | ||||||
1103 | PyObject *tmp = PyMapping_GetItemString(obj, "aligned"); | ||||||
1104 | if (tmp == NULL((void*)0)) { | ||||||
1105 | PyErr_Clear(); | ||||||
1106 | } else { | ||||||
1107 | if (tmp == Py_True((PyObject *) &_Py_TrueStruct)) { | ||||||
1108 | align = 1; | ||||||
1109 | } | ||||||
1110 | else if (tmp != Py_False((PyObject *) &_Py_FalseStruct)) { | ||||||
1111 | Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp))); | ||||||
1112 | PyErr_SetString(PyExc_ValueError, | ||||||
1113 | "NumPy dtype descriptor includes 'aligned' entry, " | ||||||
1114 | "but its value is neither True nor False"); | ||||||
1115 | goto fail; | ||||||
1116 | } | ||||||
1117 | Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp))); | ||||||
1118 | } | ||||||
1119 | |||||||
1120 | /* Types with fields need the Python C API for field access */ | ||||||
1121 | char dtypeflags = NPY_NEEDS_PYAPI0x10; | ||||||
1122 | int totalsize = 0; | ||||||
1123 | int maxalign = 0; | ||||||
1124 | int has_out_of_order_fields = 0; | ||||||
1125 | for (int i = 0; i < n; i++) { | ||||||
1126 | /* Build item to insert (descr, offset, [title])*/ | ||||||
1127 | int len = 2; | ||||||
1128 | PyObject *title = NULL((void*)0); | ||||||
1129 | PyObject *ind = PyLong_FromLong(i); | ||||||
1130 | if (titles) { | ||||||
1131 | title=PyObject_GetItem(titles, ind); | ||||||
1132 | if (title && title != Py_None(&_Py_NoneStruct)) { | ||||||
1133 | len = 3; | ||||||
1134 | } | ||||||
1135 | else { | ||||||
1136 | Py_XDECREF(title)_Py_XDECREF(((PyObject*)(title))); | ||||||
1137 | } | ||||||
1138 | PyErr_Clear(); | ||||||
1139 | } | ||||||
1140 | PyObject *tup = PyTuple_New(len); | ||||||
1141 | PyObject *descr = PyObject_GetItem(descrs, ind); | ||||||
1142 | if (!descr) { | ||||||
1143 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||
1144 | Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind))); | ||||||
1145 | goto fail; | ||||||
1146 | } | ||||||
1147 | PyArray_Descr *newdescr = _convert_from_any(descr, align); | ||||||
1148 | Py_DECREF(descr)_Py_DECREF(((PyObject*)(descr))); | ||||||
1149 | if (newdescr == NULL((void*)0)) { | ||||||
1150 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||
1151 | Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind))); | ||||||
1152 | goto fail; | ||||||
1153 | } | ||||||
1154 | PyTuple_SET_ITEM(tup, 0, (PyObject *)newdescr)PyTuple_SetItem(tup, 0, (PyObject *)newdescr); | ||||||
1155 | int _align = 1; | ||||||
1156 | if (align) { | ||||||
1157 | _align = newdescr->alignment; | ||||||
1158 | maxalign = PyArray_MAX(maxalign,_align)(((maxalign)>(_align))?(maxalign):(_align)); | ||||||
1159 | } | ||||||
1160 | if (offsets) { | ||||||
1161 | PyObject *off = PyObject_GetItem(offsets, ind); | ||||||
1162 | if (!off) { | ||||||
1163 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||
1164 | Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind))); | ||||||
1165 | goto fail; | ||||||
1166 | } | ||||||
1167 | long offset = PyArray_PyIntAsInt(off); | ||||||
1168 | if (error_converting(offset)(((offset) == -1) && PyErr_Occurred())) { | ||||||
1169 | Py_DECREF(off)_Py_DECREF(((PyObject*)(off))); | ||||||
1170 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||
1171 | Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind))); | ||||||
1172 | goto fail; | ||||||
1173 | } | ||||||
1174 | Py_DECREF(off)_Py_DECREF(((PyObject*)(off))); | ||||||
1175 | if (offset < 0) { | ||||||
1176 | PyErr_Format(PyExc_ValueError, "offset %ld cannot be negative", | ||||||
1177 | offset); | ||||||
1178 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||
1179 | Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind))); | ||||||
1180 | goto fail; | ||||||
1181 | } | ||||||
1182 | |||||||
1183 | PyTuple_SET_ITEM(tup, 1, PyLong_FromLong(offset))PyTuple_SetItem(tup, 1, PyLong_FromLong(offset)); | ||||||
1184 | /* Flag whether the fields are specified out of order */ | ||||||
1185 | if (offset < totalsize) { | ||||||
1186 | has_out_of_order_fields = 1; | ||||||
1187 | } | ||||||
1188 | /* If align=True, enforce field alignment */ | ||||||
1189 | if (align && offset % newdescr->alignment != 0) { | ||||||
1190 | PyErr_Format(PyExc_ValueError, | ||||||
1191 | "offset %ld for NumPy dtype with fields is " | ||||||
1192 | "not divisible by the field alignment %d " | ||||||
1193 | "with align=True", | ||||||
1194 | offset, newdescr->alignment); | ||||||
1195 | Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind))); | ||||||
1196 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | ||||||
1197 | goto fail; | ||||||
1198 | } | ||||||
1199 | else if (offset + newdescr->elsize > totalsize) { | ||||||
1200 | totalsize = offset + newdescr->elsize; | ||||||
1201 | } | ||||||
1202 | } | ||||||
1203 | else { | ||||||
1204 | if (align && _align > 1) { | ||||||
1205 | totalsize = NPY_NEXT_ALIGNED_OFFSET(totalsize, _align); | ||||||
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); | ||||||
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)) { | ||||||
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("/tmp/pyrefcon/numpy/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("/tmp/pyrefcon/numpy/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("/tmp/pyrefcon/numpy/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("/tmp/pyrefcon/numpy/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_New |
2 | struct _object; |
3 | typedef struct _object PyObject; |
4 | PyObject* clang_analyzer_PyObject_New_Reference(); |
5 | PyObject* PyTuple_New(Py_ssize_t len) { |
6 | return clang_analyzer_PyObject_New_Reference(); |
7 | } |
8 | #else |
9 | #warning "API PyTuple_New is defined as a macro." |
10 | #endif |