File: | numpy/core/src/multiarray/descriptor.c |
Warning: | line 527, column 14 Calling function 'PyDict_GetItemWithError' with a PyObject argument whose ownership has been released (with stolen reference) |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* Array Descr Object */ | |||
2 | ||||
3 | #define PY_SSIZE_T_CLEAN | |||
4 | #include <Python.h> | |||
5 | #include "structmember.h" | |||
6 | ||||
7 | #define NPY_NO_DEPRECATED_API0x0000000E NPY_API_VERSION0x0000000E | |||
8 | #define _MULTIARRAYMODULE | |||
9 | #include "numpy/arrayobject.h" | |||
10 | ||||
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 == NULL((void*)0) ? 2 : 3)); | |||
550 | if (tup == NULL((void*)0)) { | |||
551 | goto fail; | |||
552 | } | |||
553 | PyTuple_SET_ITEM(tup, 0, (PyObject *)conv)PyTuple_SetItem(tup, 0, (PyObject *)conv); | |||
554 | PyTuple_SET_ITEM(tup, 1, PyLong_FromLong((long) totalsize))PyTuple_SetItem(tup, 1, PyLong_FromLong((long) totalsize)); | |||
555 | ||||
556 | /* | |||
557 | * Title can be "meta-data". Only insert it | |||
558 | * into the fields dictionary if it is a string | |||
559 | * and if it is not the same as the name. | |||
560 | */ | |||
561 | if (title != NULL((void*)0)) { | |||
562 | Py_INCREF(title)_Py_INCREF(((PyObject*)(title))); | |||
563 | PyTuple_SET_ITEM(tup, 2, title)PyTuple_SetItem(tup, 2, title); | |||
564 | if (PyDict_SetItem(fields, name, tup) < 0) { | |||
565 | goto fail; | |||
566 | } | |||
567 | if (PyUnicode_Check(title)((((((PyObject*)(title))->ob_type))->tp_flags & ((1UL << 28))) != 0)) { | |||
568 | PyObject *existing = PyDict_GetItemWithError(fields, title); | |||
569 | if (existing == NULL((void*)0) && PyErr_Occurred()) { | |||
570 | goto fail; | |||
571 | } | |||
572 | if (existing != NULL((void*)0)) { | |||
573 | PyErr_SetString(PyExc_ValueError, | |||
574 | "title already used as a name or title."); | |||
575 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | |||
576 | goto fail; | |||
577 | } | |||
578 | if (PyDict_SetItem(fields, title, tup) < 0) { | |||
579 | goto fail; | |||
580 | } | |||
581 | } | |||
582 | } | |||
583 | else { | |||
584 | if (PyDict_SetItem(fields, name, tup) < 0) { | |||
585 | goto fail; | |||
586 | } | |||
587 | } | |||
588 | ||||
589 | totalsize += conv->elsize; | |||
590 | Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup))); | |||
591 | } | |||
592 | ||||
593 | if (maxalign > 1) { | |||
594 | totalsize = NPY_NEXT_ALIGNED_OFFSET(totalsize, maxalign); | |||
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 PyUnicode_FromFormat |
2 | struct _object; |
3 | typedef struct _object PyObject; |
4 | PyObject* clang_analyzer_PyObject_New_Reference(); |
5 | PyObject* PyUnicode_FromFormat(const char *format, ...) { |
6 | return clang_analyzer_PyObject_New_Reference(); |
7 | } |
8 | #else |
9 | #warning "API PyUnicode_FromFormat is defined as a macro." |
10 | #endif |
1 | #ifndef PyTuple_SetItem |
2 | struct _object; |
3 | typedef struct _object PyObject; |
4 | void clang_analyzer_PyObject_Steal_Reference(const void *); |
5 | int clang_analyzer_noimpl_conjure_int(); |
6 | int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o) { |
7 | clang_analyzer_PyObject_Steal_Reference(o); |
8 | return clang_analyzer_noimpl_conjure_int(); |
9 | } |
10 | #else |
11 | #warning "API PyTuple_SetItem is defined as a macro." |
12 | #endif |