Bug Summary

File:numpy/core/src/multiarray/descriptor.c
Warning:line 2698, column 20
PyObject ownership leak with reference count of 1

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name descriptor.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -analyzer-output=html -analyzer-checker=python -analyzer-disable-checker=deadcode -analyzer-config prune-paths=true,suppress-c++-stdlib=true,suppress-null-return-paths=false,crosscheck-with-z3=true,model-path=/opt/pyrefcon/lib/pyrefcon/models/models -analyzer-config experimental-enable-naive-ctu-analysis=true,ctu-dir=/tmp/pyrefcon/numpy/csa-scan,ctu-index-name=/tmp/pyrefcon/numpy/csa-scan/externalDefMap.txt,ctu-invocation-list=/tmp/pyrefcon/numpy/csa-scan/invocations.yaml,display-ctu-progress=false -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +sse -target-feature +sse2 -target-feature +sse3 -tune-cpu generic -debug-info-kind=limited -dwarf-version=4 -debugger-tuning=gdb -fcoverage-compilation-dir=/tmp/pyrefcon/numpy -resource-dir /opt/pyrefcon/lib/clang/13.0.0 -isystem /opt/pyrefcon/lib/pyrefcon/models/python3.8 -D NDEBUG -D _FORTIFY_SOURCE=2 -D NPY_INTERNAL_BUILD=1 -D HAVE_NPY_CONFIG_H=1 -D _FILE_OFFSET_BITS=64 -D _LARGEFILE_SOURCE=1 -D _LARGEFILE64_SOURCE=1 -I build/src.linux-x86_64-3.8/numpy/core/src/common -I build/src.linux-x86_64-3.8/numpy/core/src/umath -I numpy/core/include -I build/src.linux-x86_64-3.8/numpy/core/include/numpy -I build/src.linux-x86_64-3.8/numpy/distutils/include -I numpy/core/src/common -I numpy/core/src -I numpy/core -I numpy/core/src/npymath -I numpy/core/src/multiarray -I numpy/core/src/umath -I numpy/core/src/npysort -I numpy/core/src/_simd -I build/src.linux-x86_64-3.8/numpy/core/src/common -I build/src.linux-x86_64-3.8/numpy/core/src/npymath -internal-isystem /opt/pyrefcon/lib/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-result -Wsign-compare -Wall -Wformat -Werror=format-security -Wformat -Werror=format-security -Wdate-time -fdebug-compilation-dir=/tmp/pyrefcon/numpy -ferror-limit 19 -fwrapv -pthread -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/pyrefcon/numpy/csa-scan/reports -x c numpy/core/src/multiarray/descriptor.c

numpy/core/src/multiarray/descriptor.c

1/* Array Descr Object */
2
3#define PY_SSIZE_T_CLEAN
4#include <Python.h>
5#include "structmember.h"
6
7#define NPY_NO_DEPRECATED_API0x0000000E NPY_API_VERSION0x0000000E
8#define _MULTIARRAYMODULE
9#include "numpy/arrayobject.h"
10#include "numpy/arrayscalars.h"
11
12#include "npy_config.h"
13#include "npy_ctypes.h"
14#include "npy_pycompat.h"
15
16#include "_datetime.h"
17#include "common.h"
18#include "templ_common.h" /* for npy_mul_with_overflow_intp */
19#include "descriptor.h"
20#include "alloc.h"
21#include "assert.h"
22#include "npy_buffer.h"
23
24/*
25 * offset: A starting offset.
26 * alignment: A power-of-two alignment.
27 *
28 * This macro returns the smallest value >= 'offset'
29 * that is divisible by 'alignment'. Because 'alignment'
30 * is a power of two and integers are twos-complement,
31 * it is possible to use some simple bit-fiddling to do this.
32 */
33#define NPY_NEXT_ALIGNED_OFFSET(offset, alignment)(((offset) + (alignment) - 1) & (-(alignment))) \
34 (((offset) + (alignment) - 1) & (-(alignment)))
35
36#ifndef PyDictProxy_Check
37#define PyDictProxy_Check(obj)((((PyObject*)(obj))->ob_type) == &PyDictProxy_Type) (Py_TYPE(obj)(((PyObject*)(obj))->ob_type) == &PyDictProxy_Type)
38#endif
39
40static PyObject *typeDict = NULL((void*)0); /* Must be explicitly loaded */
41
42static PyArray_Descr *
43_try_convert_from_inherit_tuple(PyArray_Descr *type, PyObject *newobj);
44
45static 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 */
53static PyArray_Descr *
54_try_convert_from_ctypes_type(PyTypeObject *type)
55{
56 PyObject *_numpy_dtype_ctypes;
57 PyObject *res;
58
59 if (!npy_ctypes_check(type)) {
60 Py_INCREF(Py_NotImplemented)_Py_INCREF(((PyObject*)((&_Py_NotImplementedStruct))));
61 return (PyArray_Descr *)Py_NotImplemented(&_Py_NotImplementedStruct);
62 }
63
64 /* Call the python function of the same name. */
65 _numpy_dtype_ctypes = PyImport_ImportModule("numpy.core._dtype_ctypes");
66 if (_numpy_dtype_ctypes == NULL((void*)0)) {
67 return NULL((void*)0);
68 }
69 res = PyObject_CallMethod_PyObject_CallMethod_SizeT(_numpy_dtype_ctypes, "dtype_from_ctypes_type", "O", (PyObject *)type);
70 Py_DECREF(_numpy_dtype_ctypes)_Py_DECREF(((PyObject*)(_numpy_dtype_ctypes)));
71 if (res == NULL((void*)0)) {
72 return NULL((void*)0);
73 }
74
75 /*
76 * sanity check that dtype_from_ctypes_type returned the right type,
77 * since getting it wrong would give segfaults.
78 */
79 if (!PyObject_TypeCheck(res, &PyArrayDescr_Type)((((PyObject*)(res))->ob_type) == (&(*(PyTypeObject *)
(&PyArrayDescr_TypeFull))) || PyType_IsSubtype((((PyObject
*)(res))->ob_type), (&(*(PyTypeObject *)(&PyArrayDescr_TypeFull
)))))
) {
80 Py_DECREF(res)_Py_DECREF(((PyObject*)(res)));
81 PyErr_BadInternalCall()_PyErr_BadInternalCall("numpy/core/src/multiarray/descriptor.c"
, 81)
;
82 return NULL((void*)0);
83 }
84
85 return (PyArray_Descr *)res;
86}
87
88static 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 */
98static 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 */
152NPY_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 */
162NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject *
163array_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
181static 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
231static int
232is_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
255static PyArray_Descr *
256_convert_from_tuple(PyObject *obj, int align)
257{
258 if (PyTuple_GET_SIZE(obj)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(obj))))->
ob_size)
!= 2) {
259 PyErr_Format(PyExc_TypeError,
260 "Tuple must have size 2, but has size %zd",
261 PyTuple_GET_SIZE(obj)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(obj))))->
ob_size)
);
262 return NULL((void*)0);
263 }
264 PyArray_Descr *type = _convert_from_any(PyTuple_GET_ITEM(obj, 0)((((void) (0)), (PyTupleObject *)(obj))->ob_item[0]), align);
265 if (type == NULL((void*)0)) {
266 return NULL((void*)0);
267 }
268 PyObject *val = PyTuple_GET_ITEM(obj,1)((((void) (0)), (PyTupleObject *)(obj))->ob_item[1]);
269 /* try to interpret next item as a type */
270 PyArray_Descr *res = _try_convert_from_inherit_tuple(type, val);
271 if ((PyObject *)res != Py_NotImplemented(&_Py_NotImplementedStruct)) {
272 Py_DECREF(type)_Py_DECREF(((PyObject*)(type)));
273 return res;
274 }
275 Py_DECREF(res)_Py_DECREF(((PyObject*)(res)));
276 /*
277 * We get here if _try_convert_from_inherit_tuple failed without crashing
278 */
279 if (PyDataType_ISUNSIZED(type)((type)->elsize == 0 && !(((PyArray_Descr *)(type)
)->names != ((void*)0)))
) {
280 /* interpret next item as a typesize */
281 int itemsize = PyArray_PyIntAsInt(PyTuple_GET_ITEM(obj,1)((((void) (0)), (PyTupleObject *)(obj))->ob_item[1]));
282
283 if (error_converting(itemsize)(((itemsize) == -1) && PyErr_Occurred())) {
284 PyErr_SetString(PyExc_ValueError,
285 "invalid itemsize in generic type tuple");
286 Py_DECREF(type)_Py_DECREF(((PyObject*)(type)));
287 return NULL((void*)0);
288 }
289 PyArray_DESCR_REPLACE(type)do { PyArray_Descr *_new_; _new_ = PyArray_DescrNew(type); _Py_XDECREF
(((PyObject*)(type))); type = _new_; } while(0)
;
290 if (type == NULL((void*)0)) {
291 return NULL((void*)0);
292 }
293 if (type->type_num == NPY_UNICODE) {
294 type->elsize = itemsize << 2;
295 }
296 else {
297 type->elsize = itemsize;
298 }
299 return type;
300 }
301 else if (type->metadata && (PyDict_Check(val)((((((PyObject*)(val))->ob_type))->tp_flags & ((1UL
<< 29))) != 0)
|| PyDictProxy_Check(val)((((PyObject*)(val))->ob_type) == &PyDictProxy_Type))) {
302 /* Assume it's a metadata dictionary */
303 if (PyDict_Merge(type->metadata, val, 0) == -1) {
304 Py_DECREF(type)_Py_DECREF(((PyObject*)(type)));
305 return NULL((void*)0);
306 }
307 return type;
308 }
309 else {
310 /*
311 * interpret next item as shape (if it's a tuple)
312 * and reset the type to NPY_VOID with
313 * a new fields attribute.
314 */
315 PyArray_Dims shape = {NULL((void*)0), -1};
316 if (!(PyArray_IntpConverter(val, &shape)) || (shape.len > NPY_MAXDIMS32)) {
317 PyErr_SetString(PyExc_ValueError,
318 "invalid shape in fixed-type tuple.");
319 goto fail;
320 }
321 /* if (type, ()) was given it is equivalent to type... */
322 if (shape.len == 0 && PyTuple_Check(val)((((((PyObject*)(val))->ob_type))->tp_flags & ((1UL
<< 26))) != 0)
) {
323 npy_free_cache_dim_obj(shape);
324 return type;
325 }
326 /* (type, 1) use to be equivalent to type, but is deprecated */
327 if (shape.len == 1
328 && shape.ptr[0] == 1
329 && PyNumber_Check(val)) {
330 /* 2019-05-20, 1.17 */
331 if (DEPRECATE_FUTUREWARNING(PyErr_WarnEx(PyExc_FutureWarning,"Passing (type, 1) or '1type' as a synonym of type is "
"deprecated; in a future version of numpy, it will be " "understood as (type, (1,)) / '(1,)type'."
,1)
332 "Passing (type, 1) or '1type' as a synonym of type is "PyErr_WarnEx(PyExc_FutureWarning,"Passing (type, 1) or '1type' as a synonym of type is "
"deprecated; in a future version of numpy, it will be " "understood as (type, (1,)) / '(1,)type'."
,1)
333 "deprecated; in a future version of numpy, it will be "PyErr_WarnEx(PyExc_FutureWarning,"Passing (type, 1) or '1type' as a synonym of type is "
"deprecated; in a future version of numpy, it will be " "understood as (type, (1,)) / '(1,)type'."
,1)
334 "understood as (type, (1,)) / '(1,)type'.")PyErr_WarnEx(PyExc_FutureWarning,"Passing (type, 1) or '1type' as a synonym of type is "
"deprecated; in a future version of numpy, it will be " "understood as (type, (1,)) / '(1,)type'."
,1)
< 0) {
335 goto fail;
336 }
337 npy_free_cache_dim_obj(shape);
338 return type;
339 }
340
341 /* validate and set shape */
342 for (int i=0; i < shape.len; i++) {
343 if (shape.ptr[i] < 0) {
344 PyErr_SetString(PyExc_ValueError,
345 "invalid shape in fixed-type tuple: "
346 "dimension smaller then zero.");
347 goto fail;
348 }
349 if (shape.ptr[i] > NPY_MAX_INT2147483647) {
350 PyErr_SetString(PyExc_ValueError,
351 "invalid shape in fixed-type tuple: "
352 "dimension does not fit into a C int.");
353 goto fail;
354 }
355 }
356 npy_intp items = PyArray_OverflowMultiplyList(shape.ptr, shape.len);
357 int overflowed;
358 int nbytes;
359 if (items < 0 || items > NPY_MAX_INT2147483647) {
360 overflowed = 1;
361 }
362 else {
363 overflowed = npy_mul_with_overflow_int(
364 &nbytes, type->elsize, (int) items);
365 }
366 if (overflowed) {
367 PyErr_SetString(PyExc_ValueError,
368 "invalid shape in fixed-type tuple: dtype size in "
369 "bytes must fit into a C int.");
370 goto fail;
371 }
372 PyArray_Descr *newdescr = PyArray_DescrNewFromType(NPY_VOID);
373 if (newdescr == NULL((void*)0)) {
374 goto fail;
375 }
376 newdescr->elsize = nbytes;
377 newdescr->subarray = PyArray_mallocPyMem_RawMalloc(sizeof(PyArray_ArrayDescr));
378 if (newdescr->subarray == NULL((void*)0)) {
379 Py_DECREF(newdescr)_Py_DECREF(((PyObject*)(newdescr)));
380 PyErr_NoMemory();
381 goto fail;
382 }
383 newdescr->flags = type->flags;
384 newdescr->alignment = type->alignment;
385 newdescr->subarray->base = type;
386 type = NULL((void*)0);
387 Py_XDECREF(newdescr->fields)_Py_XDECREF(((PyObject*)(newdescr->fields)));
388 Py_XDECREF(newdescr->names)_Py_XDECREF(((PyObject*)(newdescr->names)));
389 newdescr->fields = NULL((void*)0);
390 newdescr->names = NULL((void*)0);
391
392 /*
393 * Create a new subarray->shape tuple (it can be an arbitrary
394 * sequence of integer like objects, neither of which is safe.
395 */
396 newdescr->subarray->shape = PyTuple_New(shape.len);
397 if (newdescr->subarray->shape == NULL((void*)0)) {
398 Py_DECREF(newdescr)_Py_DECREF(((PyObject*)(newdescr)));
399 goto fail;
400 }
401 for (int i=0; i < shape.len; i++) {
402 PyTuple_SET_ITEM(newdescr->subarray->shape, i,PyTuple_SetItem(newdescr->subarray->shape, i, PyLong_FromLong
((long)shape.ptr[i]))
403 PyLong_FromLong((long)shape.ptr[i]))PyTuple_SetItem(newdescr->subarray->shape, i, PyLong_FromLong
((long)shape.ptr[i]))
;
404
405 if (PyTuple_GET_ITEM(newdescr->subarray->shape, i)((((void) (0)), (PyTupleObject *)(newdescr->subarray->shape
))->ob_item[i])
== NULL((void*)0)) {
406 Py_DECREF(newdescr)_Py_DECREF(((PyObject*)(newdescr)));
407 goto fail;
408 }
409 }
410
411 npy_free_cache_dim_obj(shape);
412 return newdescr;
413
414 fail:
415 Py_XDECREF(type)_Py_XDECREF(((PyObject*)(type)));
416 npy_free_cache_dim_obj(shape);
417 return NULL((void*)0);
418 }
419}
420
421/*
422 * obj is a list. Each item is a tuple with
423 *
424 * (field-name, data-type (either a list or a string), and an optional
425 * shape parameter).
426 *
427 * field-name can be a string or a 2-tuple
428 * data-type can now be a list, string, or 2-tuple
429 * (string, metadata dictionary)
430 */
431static PyArray_Descr *
432_convert_from_array_descr(PyObject *obj, int align)
433{
434 int n = PyList_GET_SIZE(obj)(((void) (0)), (((PyVarObject*)(obj))->ob_size));
435 PyObject *nameslist = PyTuple_New(n);
436 if (!nameslist) {
437 return NULL((void*)0);
438 }
439
440 /* Types with fields need the Python C API for field access */
441 char dtypeflags = NPY_NEEDS_PYAPI0x10;
442 int maxalign = 0;
443 int totalsize = 0;
444 PyObject *fields = PyDict_New();
445 if (!fields) {
446 return NULL((void*)0);
447 }
448 for (int i = 0; i < n; i++) {
449 PyObject *item = PyList_GET_ITEM(obj, i)(((PyListObject *)(obj))->ob_item[i]);
450 if (!PyTuple_Check(item)((((((PyObject*)(item))->ob_type))->tp_flags & ((1UL
<< 26))) != 0)
|| (PyTuple_GET_SIZE(item)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(item))))->
ob_size)
< 2)) {
451 PyErr_Format(PyExc_TypeError,
452 "Field elements must be 2- or 3-tuples, got '%R'",
453 item);
454 goto fail;
455 }
456 PyObject *name = PyTuple_GET_ITEM(item, 0)((((void) (0)), (PyTupleObject *)(item))->ob_item[0]);
457 PyObject *title;
458 if (PyUnicode_Check(name)((((((PyObject*)(name))->ob_type))->tp_flags & ((1UL
<< 28))) != 0)
) {
459 title = NULL((void*)0);
460 }
461 else if (PyTuple_Check(name)((((((PyObject*)(name))->ob_type))->tp_flags & ((1UL
<< 26))) != 0)
) {
462 if (PyTuple_GET_SIZE(name)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(name))))->
ob_size)
!= 2) {
463 PyErr_Format(PyExc_TypeError,
464 "If a tuple, the first element of a field tuple must have "
465 "two elements, not %zd",
466 PyTuple_GET_SIZE(name)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(name))))->
ob_size)
);
467 goto fail;
468 }
469 title = PyTuple_GET_ITEM(name, 0)((((void) (0)), (PyTupleObject *)(name))->ob_item[0]);
470 name = PyTuple_GET_ITEM(name, 1)((((void) (0)), (PyTupleObject *)(name))->ob_item[1]);
471 if (!PyUnicode_Check(name)((((((PyObject*)(name))->ob_type))->tp_flags & ((1UL
<< 28))) != 0)
) {
472 PyErr_SetString(PyExc_TypeError, "Field name must be a str");
473 goto fail;
474 }
475 }
476 else {
477 PyErr_SetString(PyExc_TypeError,
478 "First element of field tuple is "
479 "neither a tuple nor str");
480 goto fail;
481 }
482
483 /* Insert name into nameslist */
484 Py_INCREF(name)_Py_INCREF(((PyObject*)(name)));
485
486 if (PyUnicode_GetLength(name) == 0) {
487 Py_DECREF(name)_Py_DECREF(((PyObject*)(name)));
488 if (title == NULL((void*)0)) {
489 name = PyUnicode_FromFormat("f%d", i);
490 if (name == NULL((void*)0)) {
491 goto fail;
492 }
493 }
494 /* On Py3, allow only non-empty Unicode strings as field names */
495 else if (PyUnicode_Check(title)((((((PyObject*)(title))->ob_type))->tp_flags & ((1UL
<< 28))) != 0)
&& PyUnicode_GetLength(title) > 0) {
496 name = title;
497 Py_INCREF(name)_Py_INCREF(((PyObject*)(name)));
498 }
499 else {
500 PyErr_SetString(PyExc_TypeError, "Field titles must be non-empty strings");
501 goto fail;
502 }
503 }
504 PyTuple_SET_ITEM(nameslist, i, name)PyTuple_SetItem(nameslist, i, name);
505
506 /* Process rest */
507 PyArray_Descr *conv;
508 if (PyTuple_GET_SIZE(item)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(item))))->
ob_size)
== 2) {
509 conv = _convert_from_any(PyTuple_GET_ITEM(item, 1)((((void) (0)), (PyTupleObject *)(item))->ob_item[1]), align);
510 if (conv == NULL((void*)0)) {
511 goto fail;
512 }
513 }
514 else if (PyTuple_GET_SIZE(item)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(item))))->
ob_size)
== 3) {
515 PyObject *newobj = PyTuple_GetSlice(item, 1, 3);
516 conv = _convert_from_any(newobj, align);
517 Py_DECREF(newobj)_Py_DECREF(((PyObject*)(newobj)));
518 if (conv == NULL((void*)0)) {
519 goto fail;
520 }
521 }
522 else {
523 PyErr_Format(PyExc_TypeError,
524 "Field elements must be tuples with at most 3 elements, got '%R'", item);
525 goto fail;
526 }
527 if ((PyDict_GetItemWithError(fields, name) != NULL((void*)0))
528 || (title
529 && PyUnicode_Check(title)((((((PyObject*)(title))->ob_type))->tp_flags & ((1UL
<< 28))) != 0)
530 && (PyDict_GetItemWithError(fields, title) != NULL((void*)0)))) {
531 PyErr_Format(PyExc_ValueError,
532 "field %R occurs more than once", name);
533 Py_DECREF(conv)_Py_DECREF(((PyObject*)(conv)));
534 goto fail;
535 }
536 else if (PyErr_Occurred()) {
537 /* Dict lookup crashed */
538 Py_DECREF(conv)_Py_DECREF(((PyObject*)(conv)));
539 goto fail;
540 }
541 dtypeflags |= (conv->flags & NPY_FROM_FIELDS(0x08 | 0x02 | 0x01 | 0x10));
542 if (align) {
543 int _align = conv->alignment;
544 if (_align > 1) {
545 totalsize = NPY_NEXT_ALIGNED_OFFSET(totalsize, _align)(((totalsize) + (_align) - 1) & (-(_align)));
546 }
547 maxalign = PyArray_MAX(maxalign, _align)(((maxalign)>(_align))?(maxalign):(_align));
548 }
549 PyObject *tup = PyTuple_New((title == NULL((void*)0) ? 2 : 3));
550 if (tup == NULL((void*)0)) {
551 goto fail;
552 }
553 PyTuple_SET_ITEM(tup, 0, (PyObject *)conv)PyTuple_SetItem(tup, 0, (PyObject *)conv);
554 PyTuple_SET_ITEM(tup, 1, PyLong_FromLong((long) totalsize))PyTuple_SetItem(tup, 1, PyLong_FromLong((long) totalsize));
555
556 /*
557 * Title can be "meta-data". Only insert it
558 * into the fields dictionary if it is a string
559 * and if it is not the same as the name.
560 */
561 if (title != NULL((void*)0)) {
562 Py_INCREF(title)_Py_INCREF(((PyObject*)(title)));
563 PyTuple_SET_ITEM(tup, 2, title)PyTuple_SetItem(tup, 2, title);
564 if (PyDict_SetItem(fields, name, tup) < 0) {
565 goto fail;
566 }
567 if (PyUnicode_Check(title)((((((PyObject*)(title))->ob_type))->tp_flags & ((1UL
<< 28))) != 0)
) {
568 PyObject *existing = PyDict_GetItemWithError(fields, title);
569 if (existing == NULL((void*)0) && PyErr_Occurred()) {
570 goto fail;
571 }
572 if (existing != NULL((void*)0)) {
573 PyErr_SetString(PyExc_ValueError,
574 "title already used as a name or title.");
575 Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup)));
576 goto fail;
577 }
578 if (PyDict_SetItem(fields, title, tup) < 0) {
579 goto fail;
580 }
581 }
582 }
583 else {
584 if (PyDict_SetItem(fields, name, tup) < 0) {
585 goto fail;
586 }
587 }
588
589 totalsize += conv->elsize;
590 Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup)));
591 }
592
593 if (maxalign > 1) {
594 totalsize = NPY_NEXT_ALIGNED_OFFSET(totalsize, maxalign)(((totalsize) + (maxalign) - 1) & (-(maxalign)));
595 }
596
597 PyArray_Descr *new = PyArray_DescrNewFromType(NPY_VOID);
598 if (new == NULL((void*)0)) {
599 Py_XDECREF(fields)_Py_XDECREF(((PyObject*)(fields)));
600 Py_XDECREF(nameslist)_Py_XDECREF(((PyObject*)(nameslist)));
601 return NULL((void*)0);
602 }
603 new->fields = fields;
604 new->names = nameslist;
605 new->elsize = totalsize;
606 new->flags = dtypeflags;
607
608 /* Structured arrays get a sticky aligned bit */
609 if (align) {
610 new->flags |= NPY_ALIGNED_STRUCT0x80;
611 new->alignment = maxalign;
612 }
613 return new;
614
615 fail:
616 Py_DECREF(fields)_Py_DECREF(((PyObject*)(fields)));
617 Py_DECREF(nameslist)_Py_DECREF(((PyObject*)(nameslist)));
618 return NULL((void*)0);
619
620}
621
622/*
623 * a list specifying a data-type can just be
624 * a list of formats. The names for the fields
625 * will default to f0, f1, f2, and so forth.
626 */
627static PyArray_Descr *
628_convert_from_list(PyObject *obj, int align)
629{
630 int n = PyList_GET_SIZE(obj)(((void) (0)), (((PyVarObject*)(obj))->ob_size));
631 /*
632 * Ignore any empty string at end which _internal._commastring
633 * can produce
634 */
635 PyObject *last_item = PyList_GET_ITEM(obj, n-1)(((PyListObject *)(obj))->ob_item[n-1]);
636 if (PyUnicode_Check(last_item)((((((PyObject*)(last_item))->ob_type))->tp_flags &
((1UL << 28))) != 0)
) {
637 Py_ssize_t s = PySequence_Size(last_item);
638 if (s < 0) {
639 return NULL((void*)0);
640 }
641 if (s == 0) {
642 n = n - 1;
643 }
644 }
645 if (n == 0) {
646 PyErr_SetString(PyExc_ValueError, "Expected at least one field name");
647 return NULL((void*)0);
648 }
649 PyObject *nameslist = PyTuple_New(n);
650 if (!nameslist) {
651 return NULL((void*)0);
652 }
653 PyObject *fields = PyDict_New();
654 if (!fields) {
655 Py_DECREF(nameslist)_Py_DECREF(((PyObject*)(nameslist)));
656 return NULL((void*)0);
657 }
658
659 /* Types with fields need the Python C API for field access */
660 char dtypeflags = NPY_NEEDS_PYAPI0x10;
661 int maxalign = 0;
662 int totalsize = 0;
663 for (int i = 0; i < n; i++) {
664 PyArray_Descr *conv = _convert_from_any(
665 PyList_GET_ITEM(obj, i)(((PyListObject *)(obj))->ob_item[i]), align);
666 if (conv == NULL((void*)0)) {
667 goto fail;
668 }
669 dtypeflags |= (conv->flags & NPY_FROM_FIELDS(0x08 | 0x02 | 0x01 | 0x10));
670 if (align) {
671 int _align = conv->alignment;
672 if (_align > 1) {
673 totalsize = NPY_NEXT_ALIGNED_OFFSET(totalsize, _align)(((totalsize) + (_align) - 1) & (-(_align)));
674 }
675 maxalign = PyArray_MAX(maxalign, _align)(((maxalign)>(_align))?(maxalign):(_align));
676 }
677 PyObject *size_obj = PyLong_FromLong((long) totalsize);
678 if (!size_obj) {
679 Py_DECREF(conv)_Py_DECREF(((PyObject*)(conv)));
680 goto fail;
681 }
682 PyObject *tup = PyTuple_New(2);
683 if (!tup) {
684 Py_DECREF(size_obj)_Py_DECREF(((PyObject*)(size_obj)));
685 Py_DECREF(conv)_Py_DECREF(((PyObject*)(conv)));
686 goto fail;
687 }
688 PyTuple_SET_ITEM(tup, 0, (PyObject *)conv)PyTuple_SetItem(tup, 0, (PyObject *)conv);
689 PyTuple_SET_ITEM(tup, 1, size_obj)PyTuple_SetItem(tup, 1, size_obj);
690 PyObject *key = PyUnicode_FromFormat("f%d", i);
691 if (!key) {
692 Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup)));
693 goto fail;
694 }
695 /* steals a reference to key */
696 PyTuple_SET_ITEM(nameslist, i, key)PyTuple_SetItem(nameslist, i, key);
697 int ret = PyDict_SetItem(fields, key, tup);
698 Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup)));
699 if (ret < 0) {
700 goto fail;
701 }
702 totalsize += conv->elsize;
703 }
704 PyArray_Descr *new = PyArray_DescrNewFromType(NPY_VOID);
705 new->fields = fields;
706 new->names = nameslist;
707 new->flags = dtypeflags;
708 if (maxalign > 1) {
709 totalsize = NPY_NEXT_ALIGNED_OFFSET(totalsize, maxalign)(((totalsize) + (maxalign) - 1) & (-(maxalign)));
710 }
711 /* Structured arrays get a sticky aligned bit */
712 if (align) {
713 new->flags |= NPY_ALIGNED_STRUCT0x80;
714 new->alignment = maxalign;
715 }
716 new->elsize = totalsize;
717 return new;
718
719 fail:
720 Py_DECREF(nameslist)_Py_DECREF(((PyObject*)(nameslist)));
721 Py_DECREF(fields)_Py_DECREF(((PyObject*)(fields)));
722 return NULL((void*)0);
723}
724
725
726/*
727 * comma-separated string
728 * this is the format developed by the numarray records module and implemented
729 * by the format parser in that module this is an alternative implementation
730 * found in the _internal.py file patterned after that one -- the approach is
731 * to try to convert to a list (with tuples if any repeat information is
732 * present) and then call the _convert_from_list)
733 *
734 * TODO: Calling Python from C like this in critical-path code is not
735 * a good idea. This should all be converted to C code.
736 */
737static 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
769static 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 */
794static int
795_validate_union_object_dtype(PyArray_Descr *new, PyArray_Descr *conv)
796{
797 PyObject *name, *tup;
798 PyArray_Descr *dtype;
799
800 if (!PyDataType_REFCHK(new)(((new)->flags & (0x01)) == (0x01)) && !PyDataType_REFCHK(conv)(((conv)->flags & (0x01)) == (0x01))) {
801 return 0;
802 }
803 if (PyDataType_HASFIELDS(new)(((PyArray_Descr *)(new))->names != ((void*)0)) || new->kind != 'O') {
804 goto fail;
805 }
806 if (!PyDataType_HASFIELDS(conv)(((PyArray_Descr *)(conv))->names != ((void*)0)) || PyTuple_GET_SIZE(conv->names)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(conv->names
))))->ob_size)
!= 1) {
807 goto fail;
808 }
809 name = PyTuple_GET_ITEM(conv->names, 0)((((void) (0)), (PyTupleObject *)(conv->names))->ob_item
[0])
;
810 if (name == NULL((void*)0)) {
811 return -1;
812 }
813 tup = PyDict_GetItemWithError(conv->fields, name);
814 if (tup == NULL((void*)0)) {
815 if (!PyErr_Occurred()) {
816 /* fields was missing the name it claimed to contain */
817 PyErr_BadInternalCall()_PyErr_BadInternalCall("numpy/core/src/multiarray/descriptor.c"
, 817)
;
818 }
819 return -1;
820 }
821 dtype = (PyArray_Descr *)PyTuple_GET_ITEM(tup, 0)((((void) (0)), (PyTupleObject *)(tup))->ob_item[0]);
822 if (dtype == NULL((void*)0)) {
823 return -1;
824 }
825 if (dtype->kind != 'O') {
826 goto fail;
827 }
828 return 0;
829
830fail:
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 */
855static 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 */
932static int
933_validate_object_field_overlap(PyArray_Descr *dtype)
934{
935 PyObject *names, *fields, *key, *tup, *title;
936 Py_ssize_t i, j, names_size;
937 PyArray_Descr *fld_dtype, *fld2_dtype;
938 int fld_offset, fld2_offset;
939
940 /* Get some properties from the dtype */
941 names = dtype->names;
942 names_size = PyTuple_GET_SIZE(names)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(names))))->
ob_size)
;
943 fields = dtype->fields;
944
945 for (i = 0; i < names_size; ++i) {
946 key = PyTuple_GET_ITEM(names, i)((((void) (0)), (PyTupleObject *)(names))->ob_item[i]);
947 if (key == NULL((void*)0)) {
948 return -1;
949 }
950 tup = PyDict_GetItemWithError(fields, key);
951 if (tup == NULL((void*)0)) {
952 if (!PyErr_Occurred()) {
953 /* fields was missing the name it claimed to contain */
954 PyErr_BadInternalCall()_PyErr_BadInternalCall("numpy/core/src/multiarray/descriptor.c"
, 954)
;
955 }
956 return -1;
957 }
958 if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(tup, "Oi|O", &fld_dtype, &fld_offset, &title)) {
959 return -1;
960 }
961
962 /* If this field has objects, check for overlaps */
963 if (PyDataType_REFCHK(fld_dtype)(((fld_dtype)->flags & (0x01)) == (0x01))) {
964 for (j = 0; j < names_size; ++j) {
965 if (i != j) {
966 key = PyTuple_GET_ITEM(names, j)((((void) (0)), (PyTupleObject *)(names))->ob_item[j]);
967 if (key == NULL((void*)0)) {
968 return -1;
969 }
970 tup = PyDict_GetItemWithError(fields, key);
971 if (tup == NULL((void*)0)) {
972 if (!PyErr_Occurred()) {
973 /* fields was missing the name it claimed to contain */
974 PyErr_BadInternalCall()_PyErr_BadInternalCall("numpy/core/src/multiarray/descriptor.c"
, 974)
;
975 }
976 return -1;
977 }
978 if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(tup, "Oi|O", &fld2_dtype,
979 &fld2_offset, &title)) {
980 return -1;
981 }
982 /* Raise an exception if it overlaps */
983 if (fld_offset < fld2_offset + fld2_dtype->elsize &&
984 fld2_offset < fld_offset + fld_dtype->elsize) {
985 PyErr_SetString(PyExc_TypeError,
986 "Cannot create a NumPy dtype with overlapping "
987 "object fields");
988 return -1;
989 }
990 }
991 }
992 }
993 }
994
995 /* It passed all the overlap tests */
996 return 0;
997}
998
999/*
1000 * a dictionary specifying a data-type
1001 * must have at least two and up to four
1002 * keys These must all be sequences of the same length.
1003 *
1004 * can also have an additional key called "metadata" which can be any dictionary
1005 *
1006 * "names" --- field names
1007 * "formats" --- the data-type descriptors for the field.
1008 *
1009 * Optional:
1010 *
1011 * "offsets" --- integers indicating the offset into the
1012 * record of the start of the field.
1013 * if not given, then "consecutive offsets"
1014 * will be assumed and placed in the dictionary.
1015 *
1016 * "titles" --- Allows the use of an additional key
1017 * for the fields dictionary.(if these are strings
1018 * or unicode objects) or
1019 * this can also be meta-data to
1020 * be passed around with the field description.
1021 *
1022 * Attribute-lookup-based field names merely has to query the fields
1023 * dictionary of the data-descriptor. Any result present can be used
1024 * to return the correct field.
1025 *
1026 * So, the notion of what is a name and what is a title is really quite
1027 * arbitrary.
1028 *
1029 * What does distinguish a title, however, is that if it is not None,
1030 * it will be placed at the end of the tuple inserted into the
1031 * fields dictionary.and can therefore be used to carry meta-data around.
1032 *
1033 * If the dictionary does not have "names" and "formats" entries,
1034 * then it will be checked for conformity and used directly.
1035 */
1036static 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 */
1055static PyArray_Descr *
1056_convert_from_dict(PyObject *obj, int align)
1057{
1058 PyObject *fields = PyDict_New();
1059 if (fields == NULL((void*)0)) {
1060 return (PyArray_Descr *)PyErr_NoMemory();
1061 }
1062 /*
1063 * Use PyMapping_GetItemString to support dictproxy objects as well.
1064 */
1065 PyObject *names = PyMapping_GetItemString(obj, "names");
1066 if (names == NULL((void*)0)) {
1067 Py_DECREF(fields)_Py_DECREF(((PyObject*)(fields)));
1068 /* XXX should check this is a KeyError */
1069 PyErr_Clear();
1070 return _convert_from_field_dict(obj, align);
1071 }
1072 PyObject *descrs = PyMapping_GetItemString(obj, "formats");
1073 if (descrs == NULL((void*)0)) {
1074 Py_DECREF(fields)_Py_DECREF(((PyObject*)(fields)));
1075 /* XXX should check this is a KeyError */
1076 PyErr_Clear();
1077 Py_DECREF(names)_Py_DECREF(((PyObject*)(names)));
1078 return _convert_from_field_dict(obj, align);
1079 }
1080 int n = PyObject_LengthPyObject_Size(names);
1081 PyObject *offsets = PyMapping_GetItemString(obj, "offsets");
1082 if (!offsets) {
1083 PyErr_Clear();
1084 }
1085 PyObject *titles = PyMapping_GetItemString(obj, "titles");
1086 if (!titles) {
1087 PyErr_Clear();
1088 }
1089
1090 if ((n > PyObject_LengthPyObject_Size(descrs))
1091 || (offsets && (n > PyObject_LengthPyObject_Size(offsets)))
1092 || (titles && (n > PyObject_LengthPyObject_Size(titles)))) {
1093 PyErr_SetString(PyExc_ValueError,
1094 "'names', 'formats', 'offsets', and 'titles' dict "
1095 "entries must have the same length");
1096 goto fail;
1097 }
1098
1099 /*
1100 * If a property 'aligned' is in the dict, it overrides the align flag
1101 * to be True if it not already true.
1102 */
1103 PyObject *tmp = PyMapping_GetItemString(obj, "aligned");
1104 if (tmp == NULL((void*)0)) {
1105 PyErr_Clear();
1106 } else {
1107 if (tmp == Py_True((PyObject *) &_Py_TrueStruct)) {
1108 align = 1;
1109 }
1110 else if (tmp != Py_False((PyObject *) &_Py_FalseStruct)) {
1111 Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp)));
1112 PyErr_SetString(PyExc_ValueError,
1113 "NumPy dtype descriptor includes 'aligned' entry, "
1114 "but its value is neither True nor False");
1115 goto fail;
1116 }
1117 Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp)));
1118 }
1119
1120 /* Types with fields need the Python C API for field access */
1121 char dtypeflags = NPY_NEEDS_PYAPI0x10;
1122 int totalsize = 0;
1123 int maxalign = 0;
1124 int has_out_of_order_fields = 0;
1125 for (int i = 0; i < n; i++) {
1126 /* Build item to insert (descr, offset, [title])*/
1127 int len = 2;
1128 PyObject *title = NULL((void*)0);
1129 PyObject *ind = PyLong_FromLong(i);
1130 if (titles) {
1131 title=PyObject_GetItem(titles, ind);
1132 if (title && title != Py_None(&_Py_NoneStruct)) {
1133 len = 3;
1134 }
1135 else {
1136 Py_XDECREF(title)_Py_XDECREF(((PyObject*)(title)));
1137 }
1138 PyErr_Clear();
1139 }
1140 PyObject *tup = PyTuple_New(len);
1141 PyObject *descr = PyObject_GetItem(descrs, ind);
1142 if (!descr) {
1143 Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup)));
1144 Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind)));
1145 goto fail;
1146 }
1147 PyArray_Descr *newdescr = _convert_from_any(descr, align);
1148 Py_DECREF(descr)_Py_DECREF(((PyObject*)(descr)));
1149 if (newdescr == NULL((void*)0)) {
1150 Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup)));
1151 Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind)));
1152 goto fail;
1153 }
1154 PyTuple_SET_ITEM(tup, 0, (PyObject *)newdescr)PyTuple_SetItem(tup, 0, (PyObject *)newdescr);
1155 int _align = 1;
1156 if (align) {
1157 _align = newdescr->alignment;
1158 maxalign = PyArray_MAX(maxalign,_align)(((maxalign)>(_align))?(maxalign):(_align));
1159 }
1160 if (offsets) {
1161 PyObject *off = PyObject_GetItem(offsets, ind);
1162 if (!off) {
1163 Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup)));
1164 Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind)));
1165 goto fail;
1166 }
1167 long offset = PyArray_PyIntAsInt(off);
1168 if (error_converting(offset)(((offset) == -1) && PyErr_Occurred())) {
1169 Py_DECREF(off)_Py_DECREF(((PyObject*)(off)));
1170 Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup)));
1171 Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind)));
1172 goto fail;
1173 }
1174 Py_DECREF(off)_Py_DECREF(((PyObject*)(off)));
1175 if (offset < 0) {
1176 PyErr_Format(PyExc_ValueError, "offset %ld cannot be negative",
1177 offset);
1178 Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup)));
1179 Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind)));
1180 goto fail;
1181 }
1182
1183 PyTuple_SET_ITEM(tup, 1, PyLong_FromLong(offset))PyTuple_SetItem(tup, 1, PyLong_FromLong(offset));
1184 /* Flag whether the fields are specified out of order */
1185 if (offset < totalsize) {
1186 has_out_of_order_fields = 1;
1187 }
1188 /* If align=True, enforce field alignment */
1189 if (align && offset % newdescr->alignment != 0) {
1190 PyErr_Format(PyExc_ValueError,
1191 "offset %ld for NumPy dtype with fields is "
1192 "not divisible by the field alignment %d "
1193 "with align=True",
1194 offset, newdescr->alignment);
1195 Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind)));
1196 Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup)));
1197 goto fail;
1198 }
1199 else if (offset + newdescr->elsize > totalsize) {
1200 totalsize = offset + newdescr->elsize;
1201 }
1202 }
1203 else {
1204 if (align && _align > 1) {
1205 totalsize = NPY_NEXT_ALIGNED_OFFSET(totalsize, _align)(((totalsize) + (_align) - 1) & (-(_align)));
1206 }
1207 PyTuple_SET_ITEM(tup, 1, PyLong_FromLong(totalsize))PyTuple_SetItem(tup, 1, PyLong_FromLong(totalsize));
1208 totalsize += newdescr->elsize;
1209 }
1210 if (len == 3) {
1211 PyTuple_SET_ITEM(tup, 2, title)PyTuple_SetItem(tup, 2, title);
1212 }
1213 PyObject *name = PyObject_GetItem(names, ind);
1214 Py_DECREF(ind)_Py_DECREF(((PyObject*)(ind)));
1215 if (!name) {
1216 Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup)));
1217 goto fail;
1218 }
1219 if (!PyUnicode_Check(name)((((((PyObject*)(name))->ob_type))->tp_flags & ((1UL
<< 28))) != 0)
) {
1220 PyErr_SetString(PyExc_ValueError,
1221 "field names must be strings");
1222 Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup)));
1223 goto fail;
1224 }
1225
1226 /* Insert into dictionary */
1227 if (PyDict_GetItemWithError(fields, name) != NULL((void*)0)) {
1228 PyErr_SetString(PyExc_ValueError,
1229 "name already used as a name or title");
1230 Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup)));
1231 goto fail;
1232 }
1233 else if (PyErr_Occurred()) {
1234 /* MemoryError during dict lookup */
1235 Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup)));
1236 goto fail;
1237 }
1238 int ret = PyDict_SetItem(fields, name, tup);
1239 Py_DECREF(name)_Py_DECREF(((PyObject*)(name)));
1240 if (ret < 0) {
1241 Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup)));
1242 goto fail;
1243 }
1244 if (len == 3) {
1245 if (PyUnicode_Check(title)((((((PyObject*)(title))->ob_type))->tp_flags & ((1UL
<< 28))) != 0)
) {
1246 if (PyDict_GetItemWithError(fields, title) != NULL((void*)0)) {
1247 PyErr_SetString(PyExc_ValueError,
1248 "title already used as a name or title.");
1249 Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup)));
1250 goto fail;
1251 }
1252 else if (PyErr_Occurred()) {
1253 /* MemoryError during dict lookup */
1254 goto fail;
1255 }
1256 if (PyDict_SetItem(fields, title, tup) < 0) {
1257 Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup)));
1258 goto fail;
1259 }
1260 }
1261 }
1262 Py_DECREF(tup)_Py_DECREF(((PyObject*)(tup)));
1263 dtypeflags |= (newdescr->flags & NPY_FROM_FIELDS(0x08 | 0x02 | 0x01 | 0x10));
1264 }
1265
1266 PyArray_Descr *new = PyArray_DescrNewFromType(NPY_VOID);
1267 if (new == NULL((void*)0)) {
1268 goto fail;
1269 }
1270 if (maxalign > 1) {
1271 totalsize = NPY_NEXT_ALIGNED_OFFSET(totalsize, maxalign)(((totalsize) + (maxalign) - 1) & (-(maxalign)));
1272 }
1273 if (align) {
1274 new->alignment = maxalign;
1275 }
1276 new->elsize = totalsize;
1277 if (!PyTuple_Check(names)((((((PyObject*)(names))->ob_type))->tp_flags & ((1UL
<< 26))) != 0)
) {
1278 Py_SETREF(names, PySequence_Tuple(names))do { PyObject *_py_tmp = ((PyObject*)(names)); (names) = (PySequence_Tuple
(names)); _Py_DECREF(((PyObject*)(_py_tmp))); } while (0)
;
1279 if (names == NULL((void*)0)) {
1280 Py_DECREF(new)_Py_DECREF(((PyObject*)(new)));
1281 goto fail;
1282 }
1283 }
1284 new->names = names;
1285 new->fields = fields;
1286 new->flags = dtypeflags;
1287 /* new takes responsibility for DECREFing names, fields */
1288 names = NULL((void*)0);
1289 fields = NULL((void*)0);
1290
1291 /*
1292 * If the fields weren't in order, and there was an OBJECT type,
1293 * need to verify that no OBJECT types overlap with something else.
1294 */
1295 if (has_out_of_order_fields && PyDataType_REFCHK(new)(((new)->flags & (0x01)) == (0x01))) {
1296 if (_validate_object_field_overlap(new) < 0) {
1297 Py_DECREF(new)_Py_DECREF(((PyObject*)(new)));
1298 goto fail;
1299 }
1300 }
1301
1302 /* Structured arrays get a sticky aligned bit */
1303 if (align) {
1304 new->flags |= NPY_ALIGNED_STRUCT0x80;
1305 }
1306
1307 /* Override the itemsize if provided */
1308 tmp = PyMapping_GetItemString(obj, "itemsize");
1309 if (tmp == NULL((void*)0)) {
1310 PyErr_Clear();
1311 } else {
1312 int itemsize = (int)PyArray_PyIntAsInt(tmp);
1313 Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp)));
1314 if (error_converting(itemsize)(((itemsize) == -1) && PyErr_Occurred())) {
1315 Py_DECREF(new)_Py_DECREF(((PyObject*)(new)));
1316 goto fail;
1317 }
1318 /* Make sure the itemsize isn't made too small */
1319 if (itemsize < new->elsize) {
1320 PyErr_Format(PyExc_ValueError,
1321 "NumPy dtype descriptor requires %d bytes, "
1322 "cannot override to smaller itemsize of %d",
1323 new->elsize, itemsize);
1324 Py_DECREF(new)_Py_DECREF(((PyObject*)(new)));
1325 goto fail;
1326 }
1327 /* If align is set, make sure the alignment divides into the size */
1328 if (align && itemsize % new->alignment != 0) {
1329 PyErr_Format(PyExc_ValueError,
1330 "NumPy dtype descriptor requires alignment of %d bytes, "
1331 "which is not divisible into the specified itemsize %d",
1332 new->alignment, itemsize);
1333 Py_DECREF(new)_Py_DECREF(((PyObject*)(new)));
1334 goto fail;
1335 }
1336 /* Set the itemsize */
1337 new->elsize = itemsize;
1338 }
1339
1340 /* Add the metadata if provided */
1341 PyObject *metadata = PyMapping_GetItemString(obj, "metadata");
1342
1343 if (metadata == NULL((void*)0)) {
1344 PyErr_Clear();
1345 }
1346 else if (new->metadata == NULL((void*)0)) {
1347 new->metadata = metadata;
1348 }
1349 else {
1350 int ret = PyDict_Merge(new->metadata, metadata, 0);
1351 Py_DECREF(metadata)_Py_DECREF(((PyObject*)(metadata)));
1352 if (ret < 0) {
1353 Py_DECREF(new)_Py_DECREF(((PyObject*)(new)));
1354 goto fail;
1355 }
1356 }
1357
1358 Py_XDECREF(fields)_Py_XDECREF(((PyObject*)(fields)));
1359 Py_XDECREF(names)_Py_XDECREF(((PyObject*)(names)));
1360 Py_XDECREF(descrs)_Py_XDECREF(((PyObject*)(descrs)));
1361 Py_XDECREF(offsets)_Py_XDECREF(((PyObject*)(offsets)));
1362 Py_XDECREF(titles)_Py_XDECREF(((PyObject*)(titles)));
1363 return new;
1364
1365 fail:
1366 Py_XDECREF(fields)_Py_XDECREF(((PyObject*)(fields)));
1367 Py_XDECREF(names)_Py_XDECREF(((PyObject*)(names)));
1368 Py_XDECREF(descrs)_Py_XDECREF(((PyObject*)(descrs)));
1369 Py_XDECREF(offsets)_Py_XDECREF(((PyObject*)(offsets)));
1370 Py_XDECREF(titles)_Py_XDECREF(((PyObject*)(titles)));
1371 return NULL((void*)0);
1372}
1373
1374
1375/*NUMPY_API*/
1376NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyArray_Descr *
1377PyArray_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 */
1391NPY_NO_EXPORT__attribute__((visibility("hidden"))) int
1392PyArray_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 */
1406static 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
1475static PyArray_Descr *
1476_convert_from_str(PyObject *obj, int align);
1477
1478static PyArray_Descr *
1479_convert_from_any(PyObject *obj, int align)
1480{
1481 /* default */
1482 if (obj == Py_None(&_Py_NoneStruct)) {
1483 return PyArray_DescrFromType(NPY_DEFAULT_TYPENPY_DOUBLE);
1484 }
1485 else if (PyArray_DescrCheck(obj)((((PyObject*)(obj))->ob_type) == (&(*(PyTypeObject *)
(&PyArrayDescr_TypeFull))) || PyType_IsSubtype((((PyObject
*)(obj))->ob_type), (&(*(PyTypeObject *)(&PyArrayDescr_TypeFull
)))))
) {
1486 PyArray_Descr *ret = (PyArray_Descr *)obj;
1487 Py_INCREF(ret)_Py_INCREF(((PyObject*)(ret)));
1488 return ret;
1489 }
1490 else if (PyType_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL
<< 31))) != 0)
) {
1491 return _convert_from_type(obj);
1492 }
1493 /* or a typecode string */
1494 else if (PyBytes_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL
<< 27))) != 0)
) {
1495 /* Allow bytes format strings: convert to unicode */
1496 PyObject *obj2 = PyUnicode_FromEncodedObject(obj, NULL((void*)0), NULL((void*)0));
1497 if (obj2 == NULL((void*)0)) {
1498 /* Convert the exception into a TypeError */
1499 if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) {
1500 PyErr_SetString(PyExc_TypeError,
1501 "data type not understood");
1502 }
1503 return NULL((void*)0);
1504 }
1505 PyArray_Descr *ret = _convert_from_str(obj2, align);
1506 Py_DECREF(obj2)_Py_DECREF(((PyObject*)(obj2)));
1507 return ret;
1508 }
1509 else if (PyUnicode_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL
<< 28))) != 0)
) {
1510 return _convert_from_str(obj, align);
1511 }
1512 else if (PyTuple_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL
<< 26))) != 0)
) {
1513 /* or a tuple */
1514 if (Py_EnterRecursiveCall(((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit
) && _Py_CheckRecursiveCall(" while trying to convert the given data type from"
" a tuple object"))
1515 " while trying to convert the given data type from"((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit
) && _Py_CheckRecursiveCall(" while trying to convert the given data type from"
" a tuple object"))
1516 " a tuple object" )((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit
) && _Py_CheckRecursiveCall(" while trying to convert the given data type from"
" a tuple object"))
!= 0) {
1517 return NULL((void*)0);
1518 }
1519 PyArray_Descr *ret = _convert_from_tuple(obj, align);
1520 Py_LeaveRecursiveCall()do{ if((--(PyThreadState_Get()->recursion_depth) < (((_Py_CheckRecursionLimit
) > 200) ? ((_Py_CheckRecursionLimit) - 50) : (3 * ((_Py_CheckRecursionLimit
) >> 2))))) PyThreadState_Get()->overflowed = 0; } while
(0)
;
1521 return ret;
1522 }
1523 else if (PyList_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL
<< 25))) != 0)
) {
1524 /* or a list */
1525 if (Py_EnterRecursiveCall(((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit
) && _Py_CheckRecursiveCall(" while trying to convert the given data type from"
" a list object"))
1526 " while trying to convert the given data type from"((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit
) && _Py_CheckRecursiveCall(" while trying to convert the given data type from"
" a list object"))
1527 " a list object" )((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit
) && _Py_CheckRecursiveCall(" while trying to convert the given data type from"
" a list object"))
!= 0) {
1528 return NULL((void*)0);
1529 }
1530 PyArray_Descr *ret = _convert_from_array_descr(obj, align);
1531 Py_LeaveRecursiveCall()do{ if((--(PyThreadState_Get()->recursion_depth) < (((_Py_CheckRecursionLimit
) > 200) ? ((_Py_CheckRecursionLimit) - 50) : (3 * ((_Py_CheckRecursionLimit
) >> 2))))) PyThreadState_Get()->overflowed = 0; } while
(0)
;
1532 return ret;
1533 }
1534 else if (PyDict_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL
<< 29))) != 0)
|| PyDictProxy_Check(obj)((((PyObject*)(obj))->ob_type) == &PyDictProxy_Type)) {
1535 /* or a dictionary */
1536 if (Py_EnterRecursiveCall(((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit
) && _Py_CheckRecursiveCall(" while trying to convert the given data type from"
" a dict object"))
1537 " while trying to convert the given data type from"((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit
) && _Py_CheckRecursiveCall(" while trying to convert the given data type from"
" a dict object"))
1538 " a dict object" )((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit
) && _Py_CheckRecursiveCall(" while trying to convert the given data type from"
" a dict object"))
!= 0) {
1539 return NULL((void*)0);
1540 }
1541 PyArray_Descr *ret = _convert_from_dict(obj, align);
1542 Py_LeaveRecursiveCall()do{ if((--(PyThreadState_Get()->recursion_depth) < (((_Py_CheckRecursionLimit
) > 200) ? ((_Py_CheckRecursionLimit) - 50) : (3 * ((_Py_CheckRecursionLimit
) >> 2))))) PyThreadState_Get()->overflowed = 0; } while
(0)
;
1543 return ret;
1544 }
1545 else if (PyArray_Check(obj)((((PyObject*)(obj))->ob_type) == (&PyArray_Type) || PyType_IsSubtype
((((PyObject*)(obj))->ob_type), (&PyArray_Type)))
) {
1546 PyErr_SetString(PyExc_TypeError, "Cannot construct a dtype from an array");
1547 return NULL((void*)0);
1548 }
1549 else {
1550 PyArray_Descr *ret = _try_convert_from_dtype_attr(obj);
1551 if ((PyObject *)ret != Py_NotImplemented(&_Py_NotImplementedStruct)) {
1552 return ret;
1553 }
1554 Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret)));
1555 /*
1556 * Note: this comes after _try_convert_from_dtype_attr because the ctypes
1557 * type might override the dtype if numpy does not otherwise
1558 * support it.
1559 */
1560 ret = _try_convert_from_ctypes_type(Py_TYPE(obj)(((PyObject*)(obj))->ob_type));
1561 if ((PyObject *)ret != Py_NotImplemented(&_Py_NotImplementedStruct)) {
1562 return ret;
1563 }
1564 Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret)));
1565 PyErr_Format(PyExc_TypeError, "Cannot interpret '%R' as a data type", obj);
1566 return NULL((void*)0);
1567 }
1568}
1569
1570
1571/*NUMPY_API
1572 * Get typenum from an object -- None goes to NPY_DEFAULT_TYPE
1573 * This function takes a Python object representing a type and converts it
1574 * to a the correct PyArray_Descr * structure to describe the type.
1575 *
1576 * Many objects can be used to represent a data-type which in NumPy is
1577 * quite a flexible concept.
1578 *
1579 * This is the central code that converts Python objects to
1580 * Type-descriptor objects that are used throughout numpy.
1581 *
1582 * Returns a new reference in *at, but the returned should not be
1583 * modified as it may be one of the canonical immutable objects or
1584 * a reference to the input obj.
1585 */
1586NPY_NO_EXPORT__attribute__((visibility("hidden"))) int
1587PyArray_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 */
1594static 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
1767fail:
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 */
1789NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyArray_Descr *
1790PyArray_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 */
1845static void
1846arraydescr_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 */
1877static 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
1897static PyObject *
1898arraydescr_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
1907NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject *
1908arraydescr_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
1953static PyObject *
1954arraydescr_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
1968static PyObject *
1969arraydescr_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
1979static PyObject *
1980arraydescr_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
1990static PyObject *
1991arraydescr_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
2008NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject *
2009arraydescr_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 */
2045static PyObject *
2046arraydescr_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
2059static 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 */
2092static PyObject *
2093arraydescr_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
2106static PyObject *
2107arraydescr_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
2115static PyObject *
2116arraydescr_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
2124static PyObject *
2125arraydescr_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
2133static PyObject *
2134arraydescr_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
2144static PyObject *
2145arraydescr_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
2154static int
2155arraydescr_names_set(PyArray_Descr *self, PyObject *val)
2156{
2157 int N = 0;
2158 int i;
2159 PyObject *new_names;
2160 PyObject *new_fields;
2161
2162 if (val == NULL((void*)0)) {
2163 PyErr_SetString(PyExc_AttributeError,
2164 "Cannot delete dtype names attribute");
2165 return -1;
2166 }
2167 if (!PyDataType_HASFIELDS(self)(((PyArray_Descr *)(self))->names != ((void*)0))) {
2168 PyErr_SetString(PyExc_ValueError,
2169 "there are no fields defined");
2170 return -1;
2171 }
2172
2173 /*
2174 * FIXME
2175 *
2176 * This deprecation has been temporarily removed for the NumPy 1.7
2177 * release. It should be re-added after the 1.7 branch is done,
2178 * and a convenience API to replace the typical use-cases for
2179 * mutable names should be implemented.
2180 *
2181 * if (DEPRECATE("Setting NumPy dtype names is deprecated, the dtype "
2182 * "will become immutable in a future version") < 0) {
2183 * return -1;
2184 * }
2185 */
2186
2187 N = PyTuple_GET_SIZE(self->names)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(self->names
))))->ob_size)
;
2188 if (!PySequence_Check(val) || PyObject_Size((PyObject *)val) != N) {
2189 PyErr_Format(PyExc_ValueError,
2190 "must replace all names at once with a sequence of length %d",
2191 N);
2192 return -1;
2193 }
2194 /* Make sure all entries are strings */
2195 for (i = 0; i < N; i++) {
2196 PyObject *item;
2197 int valid = 1;
2198 item = PySequence_GetItem(val, i);
2199 valid = PyUnicode_Check(item)((((((PyObject*)(item))->ob_type))->tp_flags & ((1UL
<< 28))) != 0)
;
2200 Py_DECREF(item)_Py_DECREF(((PyObject*)(item)));
2201 if (!valid) {
2202 PyErr_Format(PyExc_ValueError,
2203 "item #%d of names is of type %s and not string",
2204 i, Py_TYPE(item)(((PyObject*)(item))->ob_type)->tp_name);
2205 return -1;
2206 }
2207 }
2208 /* Invalidate cached hash value */
2209 self->hash = -1;
2210 /* Update dictionary keys in fields */
2211 new_names = PySequence_Tuple(val);
2212 if (new_names == NULL((void*)0)) {
2213 return -1;
2214 }
2215 new_fields = PyDict_New();
2216 if (new_fields == NULL((void*)0)) {
2217 Py_DECREF(new_names)_Py_DECREF(((PyObject*)(new_names)));
2218 return -1;
2219 }
2220 for (i = 0; i < N; i++) {
2221 PyObject *key;
2222 PyObject *item;
2223 PyObject *new_key;
2224 int ret;
2225 key = PyTuple_GET_ITEM(self->names, i)((((void) (0)), (PyTupleObject *)(self->names))->ob_item
[i])
;
2226 /* Borrowed references to item and new_key */
2227 item = PyDict_GetItemWithError(self->fields, key);
2228 if (item == NULL((void*)0)) {
2229 if (!PyErr_Occurred()) {
2230 /* fields was missing the name it claimed to contain */
2231 PyErr_BadInternalCall()_PyErr_BadInternalCall("numpy/core/src/multiarray/descriptor.c"
, 2231)
;
2232 }
2233 Py_DECREF(new_names)_Py_DECREF(((PyObject*)(new_names)));
2234 Py_DECREF(new_fields)_Py_DECREF(((PyObject*)(new_fields)));
2235 return -1;
2236 }
2237 new_key = PyTuple_GET_ITEM(new_names, i)((((void) (0)), (PyTupleObject *)(new_names))->ob_item[i]);
2238 /* Check for duplicates */
2239 ret = PyDict_Contains(new_fields, new_key);
2240 if (ret < 0) {
2241 Py_DECREF(new_names)_Py_DECREF(((PyObject*)(new_names)));
2242 Py_DECREF(new_fields)_Py_DECREF(((PyObject*)(new_fields)));
2243 return -1;
2244 }
2245 else if (ret != 0) {
2246 PyErr_SetString(PyExc_ValueError, "Duplicate field names given.");
2247 Py_DECREF(new_names)_Py_DECREF(((PyObject*)(new_names)));
2248 Py_DECREF(new_fields)_Py_DECREF(((PyObject*)(new_fields)));
2249 return -1;
2250 }
2251 if (PyDict_SetItem(new_fields, new_key, item) < 0) {
2252 Py_DECREF(new_names)_Py_DECREF(((PyObject*)(new_names)));
2253 Py_DECREF(new_fields)_Py_DECREF(((PyObject*)(new_fields)));
2254 return -1;
2255 }
2256 }
2257
2258 /* Replace names */
2259 Py_DECREF(self->names)_Py_DECREF(((PyObject*)(self->names)));
2260 self->names = new_names;
2261
2262 /* Replace fields */
2263 Py_DECREF(self->fields)_Py_DECREF(((PyObject*)(self->fields)));
2264 self->fields = new_fields;
2265
2266 return 0;
2267}
2268
2269static 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
2316static PyObject *
2317arraydescr_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, &copy,
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 */
2402static 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 */
2455static PyObject *
2456arraydescr_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 */
2574static 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 */
2609static PyObject *
2610arraydescr_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)) {
1
Assuming the condition is false
2
Taking false branch
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
3
Assuming field 'ob_size' is equal to 1
5
Taking false branch
2625 || !(PyTuple_Check(PyTuple_GET_ITEM(args, 0))((((((PyObject*)(((((void) (0)), (PyTupleObject *)(args))->
ob_item[0])))->ob_type))->tp_flags & ((1UL <<
26))) != 0)
)) {
4
Assuming the condition is true
2626 PyErr_BadInternalCall()_PyErr_BadInternalCall("numpy/core/src/multiarray/descriptor.c"
, 2626)
;
2627 return NULL((void*)0);
2628 }
2629 switch (PyTuple_GET_SIZE(PyTuple_GET_ITEM(args,0))(((PyVarObject*)((((void) (0)), (PyTupleObject *)(((((void) (
0)), (PyTupleObject *)(args))->ob_item[0])))))->ob_size
)
) {
6
Control jumps to 'case 6:' at line 2655
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__",
7
Assuming the condition is false
8
Taking false branch
2657 &version,
2658 &endian_obj, &subarray, &fields,
2659 &elsize, &alignment)) {
2660 return NULL((void*)0);
2661 }
2662 break;
9
Execution continues on line 2685
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) {
10
Assuming 'version' is >= 0
11
Assuming 'version' is <= 4
12
Taking false branch
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) {
13
Assuming 'version' is equal to 1
2695 if (fields != Py_None(&_Py_NoneStruct)) {
14
Assuming the condition is true
15
Taking true branch
2696 PyObject *key, *list;
2697 key = PyLong_FromLong(-1);
2698 list = PyDict_GetItemWithError(fields, key);
16
Calling 'PyDict_GetItemWithError'
18
Returning from 'PyDict_GetItemWithError'
27
PyObject ownership leak with reference count of 1
2699 if (!list) {
19
Assuming 'list' is non-null
20
Taking false branch
2700 if (!PyErr_Occurred()) {
2701 /* fields was missing the name it claimed to contain */
2702 PyErr_BadInternalCall()_PyErr_BadInternalCall("numpy/core/src/multiarray/descriptor.c"
, 2702)
;
2703 }
2704 return NULL((void*)0);
2705 }
2706 Py_INCREF(list)_Py_INCREF(((PyObject*)(list)));
21
Calling '_Py_INCREF'
23
Returning from '_Py_INCREF'
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)
) {
24
Assuming the condition is false
25
Assuming the condition is false
26
Taking false branch
2718 PyObject *tmp = NULL((void*)0);
2719 char *str;
2720 Py_ssize_t len;
2721
2722 if (PyUnicode_Check(endian_obj)((((((PyObject*)(endian_obj))->ob_type))->tp_flags &
((1UL << 28))) != 0)
) {
2723 tmp = PyUnicode_AsASCIIString(endian_obj);
2724 if (tmp == NULL((void*)0)) {
2725 return NULL((void*)0);
2726 }
2727 endian_obj = tmp;
2728 }
2729
2730 if (PyBytes_AsStringAndSize(endian_obj, &str, &len) < 0) {
2731 Py_XDECREF(tmp)_Py_XDECREF(((PyObject*)(tmp)));
2732 return NULL((void*)0);
2733 }
2734 if (len != 1) {
2735 PyErr_SetString(PyExc_ValueError,
2736 "endian is not 1-char string in Numpy dtype unpickling");
2737 Py_XDECREF(tmp)_Py_XDECREF(((PyObject*)(tmp)));
2738 return NULL((void*)0);
2739 }
2740 endian = str[0];
2741 Py_XDECREF(tmp)_Py_XDECREF(((PyObject*)(tmp)));
2742 }
2743 else {
2744 PyErr_SetString(PyExc_ValueError,
2745 "endian is not a string in Numpy dtype unpickling");
2746 return NULL((void*)0);
2747 }
2748
2749 if ((fields == Py_None(&_Py_NoneStruct) && names != Py_None(&_Py_NoneStruct)) ||
2750 (names == Py_None(&_Py_NoneStruct) && fields != Py_None(&_Py_NoneStruct))) {
2751 PyErr_Format(PyExc_ValueError,
2752 "inconsistent fields and names in Numpy dtype unpickling");
2753 return NULL((void*)0);
2754 }
2755
2756 if (names != Py_None(&_Py_NoneStruct) && !PyTuple_Check(names)((((((PyObject*)(names))->ob_type))->tp_flags & ((1UL
<< 26))) != 0)
) {
2757 PyErr_Format(PyExc_ValueError,
2758 "non-tuple names in Numpy dtype unpickling");
2759 return NULL((void*)0);
2760 }
2761
2762 if (fields != Py_None(&_Py_NoneStruct) && !PyDict_Check(fields)((((((PyObject*)(fields))->ob_type))->tp_flags & ((
1UL << 29))) != 0)
) {
2763 PyErr_Format(PyExc_ValueError,
2764 "non-dict fields in Numpy dtype unpickling");
2765 return NULL((void*)0);
2766 }
2767
2768 if (endian != '|' && PyArray_IsNativeByteOrder(endian)((endian) != '>')) {
2769 endian = '=';
2770 }
2771 self->byteorder = endian;
2772 if (self->subarray) {
2773 Py_XDECREF(self->subarray->base)_Py_XDECREF(((PyObject*)(self->subarray->base)));
2774 Py_XDECREF(self->subarray->shape)_Py_XDECREF(((PyObject*)(self->subarray->shape)));
2775 PyArray_freePyMem_RawFree(self->subarray);
2776 }
2777 self->subarray = NULL((void*)0);
2778
2779 if (subarray != Py_None(&_Py_NoneStruct)) {
2780 PyObject *subarray_shape;
2781
2782 /*
2783 * Ensure that subarray[0] is an ArrayDescr and
2784 * that subarray_shape obtained from subarray[1] is a tuple of integers.
2785 */
2786 if (!(PyTuple_Check(subarray)((((((PyObject*)(subarray))->ob_type))->tp_flags & (
(1UL << 26))) != 0)
&&
2787 PyTuple_Size(subarray) == 2 &&
2788 PyArray_DescrCheck(PyTuple_GET_ITEM(subarray, 0))((((PyObject*)(((((void) (0)), (PyTupleObject *)(subarray))->
ob_item[0])))->ob_type) == (&(*(PyTypeObject *)(&PyArrayDescr_TypeFull
))) || PyType_IsSubtype((((PyObject*)(((((void) (0)), (PyTupleObject
*)(subarray))->ob_item[0])))->ob_type), (&(*(PyTypeObject
*)(&PyArrayDescr_TypeFull)))))
)) {
2789 PyErr_Format(PyExc_ValueError,
2790 "incorrect subarray in __setstate__");
2791 return NULL((void*)0);
2792 }
2793 subarray_shape = PyTuple_GET_ITEM(subarray, 1)((((void) (0)), (PyTupleObject *)(subarray))->ob_item[1]);
2794 if (PyNumber_Check(subarray_shape)) {
2795 PyObject *tmp;
2796 tmp = PyNumber_Long(subarray_shape);
2797 if (tmp == NULL((void*)0)) {
2798 return NULL((void*)0);
2799 }
2800 subarray_shape = Py_BuildValue_Py_BuildValue_SizeT("(O)", tmp);
2801 Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp)));
2802 if (subarray_shape == NULL((void*)0)) {
2803 return NULL((void*)0);
2804 }
2805 }
2806 else if (_is_tuple_of_integers(subarray_shape)) {
2807 Py_INCREF(subarray_shape)_Py_INCREF(((PyObject*)(subarray_shape)));
2808 }
2809 else {
2810 PyErr_Format(PyExc_ValueError,
2811 "incorrect subarray shape in __setstate__");
2812 return NULL((void*)0);
2813 }
2814
2815 self->subarray = PyArray_mallocPyMem_RawMalloc(sizeof(PyArray_ArrayDescr));
2816 if (!PyDataType_HASSUBARRAY(self)((self)->subarray != ((void*)0))) {
2817 return PyErr_NoMemory();
2818 }
2819 self->subarray->base = (PyArray_Descr *)PyTuple_GET_ITEM(subarray, 0)((((void) (0)), (PyTupleObject *)(subarray))->ob_item[0]);
2820 Py_INCREF(self->subarray->base)_Py_INCREF(((PyObject*)(self->subarray->base)));
2821 self->subarray->shape = subarray_shape;
2822 }
2823
2824 if (fields != Py_None(&_Py_NoneStruct)) {
2825 /*
2826 * Ensure names are of appropriate string type
2827 */
2828 Py_ssize_t i;
2829 int names_ok = 1;
2830 PyObject *name;
2831
2832 for (i = 0; i < PyTuple_GET_SIZE(names)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(names))))->
ob_size)
; ++i) {
2833 name = PyTuple_GET_ITEM(names, i)((((void) (0)), (PyTupleObject *)(names))->ob_item[i]);
2834 if (!PyUnicode_Check(name)((((((PyObject*)(name))->ob_type))->tp_flags & ((1UL
<< 28))) != 0)
) {
2835 names_ok = 0;
2836 break;
2837 }
2838 }
2839
2840 if (names_ok) {
2841 Py_XDECREF(self->fields)_Py_XDECREF(((PyObject*)(self->fields)));
2842 self->fields = fields;
2843 Py_INCREF(fields)_Py_INCREF(((PyObject*)(fields)));
2844 Py_XDECREF(self->names)_Py_XDECREF(((PyObject*)(self->names)));
2845 self->names = names;
2846 if (incref_names) {
2847 Py_INCREF(names)_Py_INCREF(((PyObject*)(names)));
2848 }
2849 }
2850 else {
2851 /*
2852 * To support pickle.load(f, encoding='bytes') for loading Py2
2853 * generated pickles on Py3, we need to be more lenient and convert
2854 * field names from byte strings to unicode.
2855 */
2856 PyObject *tmp, *new_name, *field;
2857
2858 tmp = PyDict_New();
2859 if (tmp == NULL((void*)0)) {
2860 return NULL((void*)0);
2861 }
2862 Py_XDECREF(self->fields)_Py_XDECREF(((PyObject*)(self->fields)));
2863 self->fields = tmp;
2864
2865 tmp = PyTuple_New(PyTuple_GET_SIZE(names)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(names))))->
ob_size)
);
2866 if (tmp == NULL((void*)0)) {
2867 return NULL((void*)0);
2868 }
2869 Py_XDECREF(self->names)_Py_XDECREF(((PyObject*)(self->names)));
2870 self->names = tmp;
2871
2872 for (i = 0; i < PyTuple_GET_SIZE(names)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(names))))->
ob_size)
; ++i) {
2873 name = PyTuple_GET_ITEM(names, i)((((void) (0)), (PyTupleObject *)(names))->ob_item[i]);
2874 field = PyDict_GetItemWithError(fields, name);
2875 if (!field) {
2876 if (!PyErr_Occurred()) {
2877 /* fields was missing the name it claimed to contain */
2878 PyErr_BadInternalCall()_PyErr_BadInternalCall("numpy/core/src/multiarray/descriptor.c"
, 2878)
;
2879 }
2880 return NULL((void*)0);
2881 }
2882
2883 if (PyUnicode_Check(name)((((((PyObject*)(name))->ob_type))->tp_flags & ((1UL
<< 28))) != 0)
) {
2884 new_name = name;
2885 Py_INCREF(new_name)_Py_INCREF(((PyObject*)(new_name)));
2886 }
2887 else {
2888 new_name = PyUnicode_FromEncodedObject(name, "ASCII", "strict");
2889 if (new_name == NULL((void*)0)) {
2890 return NULL((void*)0);
2891 }
2892 }
2893
2894 PyTuple_SET_ITEM(self->names, i, new_name)PyTuple_SetItem(self->names, i, new_name);
2895 if (PyDict_SetItem(self->fields, new_name, field) != 0) {
2896 return NULL((void*)0);
2897 }
2898 }
2899 }
2900 }
2901
2902 if (PyTypeNum_ISEXTENDED(self->type_num)((((self->type_num) >=NPY_STRING) && ((self->
type_num) <=NPY_VOID)) || (((self->type_num) >= NPY_USERDEF
) && ((self->type_num) < NPY_USERDEF+ NPY_NUMUSERTYPES
)))
) {
2903 self->elsize = elsize;
2904 self->alignment = alignment;
2905 }
2906
2907 /*
2908 * We use an integer converted to char for backward compatibility with
2909 * pickled arrays. Pickled arrays created with previous versions encoded
2910 * flags as an int even though it actually was a char in the PyArray_Descr
2911 * structure
2912 */
2913 dtypeflags = int_dtypeflags;
2914 if (dtypeflags != int_dtypeflags) {
2915 PyErr_Format(PyExc_ValueError,
2916 "incorrect value for flags variable (overflow)");
2917 return NULL((void*)0);
2918 }
2919 else {
2920 self->flags = dtypeflags;
2921 }
2922
2923 if (version < 3) {
2924 self->flags = _descr_find_object(self);
2925 }
2926
2927 /*
2928 * We have a borrowed reference to metadata so no need
2929 * to alter reference count when throwing away Py_None.
2930 */
2931 if (metadata == Py_None(&_Py_NoneStruct)) {
2932 metadata = NULL((void*)0);
2933 }
2934
2935 if (PyDataType_ISDATETIME(self)(((((PyArray_Descr*)(self))->type_num) >=NPY_DATETIME) &&
((((PyArray_Descr*)(self))->type_num) <=NPY_TIMEDELTA)
)
&& (metadata != NULL((void*)0))) {
2936 PyObject *old_metadata;
2937 PyArray_DatetimeMetaData temp_dt_data;
2938
2939 if ((! PyTuple_Check(metadata)((((((PyObject*)(metadata))->ob_type))->tp_flags & (
(1UL << 26))) != 0)
) || (PyTuple_Size(metadata) != 2)) {
2940 PyErr_Format(PyExc_ValueError,
2941 "Invalid datetime dtype (metadata, c_metadata): %R",
2942 metadata);
2943 return NULL((void*)0);
2944 }
2945
2946 if (convert_datetime_metadata_tuple_to_datetime_metadata(
2947 PyTuple_GET_ITEM(metadata, 1)((((void) (0)), (PyTupleObject *)(metadata))->ob_item[1]),
2948 &temp_dt_data,
2949 NPY_TRUE1) < 0) {
2950 return NULL((void*)0);
2951 }
2952
2953 old_metadata = self->metadata;
2954 self->metadata = PyTuple_GET_ITEM(metadata, 0)((((void) (0)), (PyTupleObject *)(metadata))->ob_item[0]);
2955 memcpy((char *) &((PyArray_DatetimeDTypeMetaData *)self->c_metadata)->meta,
2956 (char *) &temp_dt_data,
2957 sizeof(PyArray_DatetimeMetaData));
2958 Py_XINCREF(self->metadata)_Py_XINCREF(((PyObject*)(self->metadata)));
2959 Py_XDECREF(old_metadata)_Py_XDECREF(((PyObject*)(old_metadata)));
2960 }
2961 else {
2962 PyObject *old_metadata = self->metadata;
2963 self->metadata = metadata;
2964 Py_XINCREF(self->metadata)_Py_XINCREF(((PyObject*)(self->metadata)));
2965 Py_XDECREF(old_metadata)_Py_XDECREF(((PyObject*)(old_metadata)));
2966 }
2967
2968 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
2969}
2970
2971/*NUMPY_API
2972 *
2973 * Get type-descriptor from an object forcing alignment if possible
2974 * None goes to DEFAULT type.
2975 *
2976 * any object with the .fields attribute and/or .itemsize attribute (if the
2977 *.fields attribute does not give the total size -- i.e. a partial record
2978 * naming). If itemsize is given it must be >= size computed from fields
2979 *
2980 * The .fields attribute must return a convertible dictionary if present.
2981 * Result inherits from NPY_VOID.
2982*/
2983NPY_NO_EXPORT__attribute__((visibility("hidden"))) int
2984PyArray_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 */
2995NPY_NO_EXPORT__attribute__((visibility("hidden"))) int
2996PyArray_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 */
3027NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyArray_Descr *
3028PyArray_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
3106static PyObject *
3107arraydescr_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
3118static 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 */
3143NPY_NO_EXPORT__attribute__((visibility("hidden"))) int
3144is_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 */
3196static PyObject *
3197arraydescr_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 */
3212static PyObject *
3213arraydescr_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
3226static PyObject *
3227arraydescr_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
3266static int
3267descr_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
3274static PyNumberMethods descr_as_number = {
3275 .nb_bool = (inquiry)descr_nonzero,
3276};
3277
3278/*************************************************************************
3279 **************** Implement Mapping Protocol ***************************
3280 *************************************************************************/
3281
3282static Py_ssize_t
3283descr_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
3295static PyObject *
3296descr_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
3313static 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
3325static 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
3341static 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
3356static 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
3374NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyArray_Descr *
3375arraydescr_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
3463fail:
3464 Py_XDECREF(fields)_Py_XDECREF(((PyObject*)(fields)));
3465 Py_XDECREF(names)_Py_XDECREF(((PyObject*)(names)));
3466 return NULL((void*)0);
3467}
3468
3469static PyObject *
3470descr_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
3498static 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
3511static 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 */
3524NPY_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};

/opt/pyrefcon/lib/pyrefcon/models/models/PyDict_GetItemWithError.model

1#ifndef PyDict_GetItemWithError
2struct _object;
3typedef struct _object PyObject;
4PyObject* clang_analyzer_PyObject_Borrow_Reference();
5PyObject* PyDict_GetItemWithError(PyObject *p, PyObject *key) {
6 return clang_analyzer_PyObject_Borrow_Reference();
17
Setting reference count to borrowed
7}
8#else
9#warning "API PyDict_GetItemWithError is defined as a macro."
10#endif

/opt/pyrefcon/lib/pyrefcon/models/models/_Py_INCREF.model

1void _Py_INCREF(PyObject *op) { ++op->ob_refcnt; }
22
Setting reference count to 1