Bug Summary

File:numpy/core/src/multiarray/nditer_pywrap.c
Warning:line 1596, column 27
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 nditer_pywrap.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/nditer_pywrap.c

numpy/core/src/multiarray/nditer_pywrap.c

1/*
2 * This file implements the CPython wrapper of NpyIter
3 *
4 * Copyright (c) 2010 by Mark Wiebe (mwwiebe@gmail.com)
5 * The University of British Columbia
6 *
7 * See LICENSE.txt for the license.
8 */
9#define PY_SSIZE_T_CLEAN
10#include "Python.h"
11#include "structmember.h"
12
13#define NPY_NO_DEPRECATED_API0x0000000E NPY_API_VERSION0x0000000E
14#define _MULTIARRAYMODULE
15#include <numpy/arrayobject.h>
16#include "npy_config.h"
17#include "npy_pycompat.h"
18#include "alloc.h"
19#include "common.h"
20#include "conversion_utils.h"
21#include "ctors.h"
22
23/* Functions not part of the public NumPy C API */
24npy_bool npyiter_has_writeback(NpyIter *iter);
25
26
27typedef struct NewNpyArrayIterObject_tag NewNpyArrayIterObject;
28
29struct NewNpyArrayIterObject_tag {
30 PyObject_HEADPyObject ob_base;
31 /* The iterator */
32 NpyIter *iter;
33 /* Flag indicating iteration started/stopped */
34 char started, finished;
35 /* Child to update for nested iteration */
36 NewNpyArrayIterObject *nested_child;
37 /* Cached values from the iterator */
38 NpyIter_IterNextFunc *iternext;
39 NpyIter_GetMultiIndexFunc *get_multi_index;
40 char **dataptrs;
41 PyArray_Descr **dtypes;
42 PyArrayObject **operands;
43 npy_intp *innerstrides, *innerloopsizeptr;
44 char readflags[NPY_MAXARGS32];
45 char writeflags[NPY_MAXARGS32];
46};
47
48static int npyiter_cache_values(NewNpyArrayIterObject *self)
49{
50 NpyIter *iter = self->iter;
51
52 /* iternext and get_multi_index functions */
53 self->iternext = NpyIter_GetIterNext(iter, NULL((void*)0));
54 if (self->iternext == NULL((void*)0)) {
55 return -1;
56 }
57
58 if (NpyIter_HasMultiIndex(iter) && !NpyIter_HasDelayedBufAlloc(iter)) {
59 self->get_multi_index = NpyIter_GetGetMultiIndex(iter, NULL((void*)0));
60 }
61 else {
62 self->get_multi_index = NULL((void*)0);
63 }
64
65 /* Internal data pointers */
66 self->dataptrs = NpyIter_GetDataPtrArray(iter);
67 self->dtypes = NpyIter_GetDescrArray(iter);
68 self->operands = NpyIter_GetOperandArray(iter);
69
70 if (NpyIter_HasExternalLoop(iter)) {
71 self->innerstrides = NpyIter_GetInnerStrideArray(iter);
72 self->innerloopsizeptr = NpyIter_GetInnerLoopSizePtr(iter);
73 }
74 else {
75 self->innerstrides = NULL((void*)0);
76 self->innerloopsizeptr = NULL((void*)0);
77 }
78
79 /* The read/write settings */
80 NpyIter_GetReadFlags(iter, self->readflags);
81 NpyIter_GetWriteFlags(iter, self->writeflags);
82 return 0;
83}
84
85static PyObject *
86npyiter_new(PyTypeObject *subtype, PyObject *NPY_UNUSED(args)(__NPY_UNUSED_TAGGEDargs) __attribute__ ((__unused__)),
87 PyObject *NPY_UNUSED(kwds)(__NPY_UNUSED_TAGGEDkwds) __attribute__ ((__unused__)))
88{
89 NewNpyArrayIterObject *self;
90
91 self = (NewNpyArrayIterObject *)subtype->tp_alloc(subtype, 0);
92 if (self != NULL((void*)0)) {
93 self->iter = NULL((void*)0);
94 self->nested_child = NULL((void*)0);
95 }
96
97 return (PyObject *)self;
98}
99
100static int
101NpyIter_GlobalFlagsConverter(PyObject *flags_in, npy_uint32 *flags)
102{
103 npy_uint32 tmpflags = 0;
104 int iflags, nflags;
105
106 PyObject *f;
107 char *str = NULL((void*)0);
108 Py_ssize_t length = 0;
109 npy_uint32 flag;
110
111 if (flags_in == NULL((void*)0) || flags_in == Py_None(&_Py_NoneStruct)) {
112 return 1;
113 }
114
115 if (!PyTuple_Check(flags_in)((((((PyObject*)(flags_in))->ob_type))->tp_flags & (
(1UL << 26))) != 0)
&& !PyList_Check(flags_in)((((((PyObject*)(flags_in))->ob_type))->tp_flags & (
(1UL << 25))) != 0)
) {
116 PyErr_SetString(PyExc_ValueError,
117 "Iterator global flags must be a list or tuple of strings");
118 return 0;
119 }
120
121 nflags = PySequence_Size(flags_in);
122
123 for (iflags = 0; iflags < nflags; ++iflags) {
124 f = PySequence_GetItem(flags_in, iflags);
125 if (f == NULL((void*)0)) {
126 return 0;
127 }
128
129 if (PyUnicode_Check(f)((((((PyObject*)(f))->ob_type))->tp_flags & ((1UL <<
28))) != 0)
) {
130 /* accept unicode input */
131 PyObject *f_str;
132 f_str = PyUnicode_AsASCIIString(f);
133 if (f_str == NULL((void*)0)) {
134 Py_DECREF(f)_Py_DECREF(((PyObject*)(f)));
135 return 0;
136 }
137 Py_DECREF(f)_Py_DECREF(((PyObject*)(f)));
138 f = f_str;
139 }
140
141 if (PyBytes_AsStringAndSize(f, &str, &length) < 0) {
142 Py_DECREF(f)_Py_DECREF(((PyObject*)(f)));
143 return 0;
144 }
145 /* Use switch statements to quickly isolate the right flag */
146 flag = 0;
147 switch (str[0]) {
148 case 'b':
149 if (strcmp(str, "buffered") == 0) {
150 flag = NPY_ITER_BUFFERED0x00000200;
151 }
152 break;
153 case 'c':
154 if (length >= 6) switch (str[5]) {
155 case 'e':
156 if (strcmp(str, "c_index") == 0) {
157 flag = NPY_ITER_C_INDEX0x00000001;
158 }
159 break;
160 case 'i':
161 if (strcmp(str, "copy_if_overlap") == 0) {
162 flag = NPY_ITER_COPY_IF_OVERLAP0x00002000;
163 }
164 break;
165 case 'n':
166 if (strcmp(str, "common_dtype") == 0) {
167 flag = NPY_ITER_COMMON_DTYPE0x00000010;
168 }
169 break;
170 }
171 break;
172 case 'd':
173 if (strcmp(str, "delay_bufalloc") == 0) {
174 flag = NPY_ITER_DELAY_BUFALLOC0x00000800;
175 }
176 break;
177 case 'e':
178 if (strcmp(str, "external_loop") == 0) {
179 flag = NPY_ITER_EXTERNAL_LOOP0x00000008;
180 }
181 break;
182 case 'f':
183 if (strcmp(str, "f_index") == 0) {
184 flag = NPY_ITER_F_INDEX0x00000002;
185 }
186 break;
187 case 'g':
188 /*
189 * Documentation is grow_inner, but initial implementation
190 * was growinner, so allowing for either.
191 */
192 if (strcmp(str, "grow_inner") == 0 ||
193 strcmp(str, "growinner") == 0) {
194 flag = NPY_ITER_GROWINNER0x00000400;
195 }
196 break;
197 case 'm':
198 if (strcmp(str, "multi_index") == 0) {
199 flag = NPY_ITER_MULTI_INDEX0x00000004;
200 }
201 break;
202 case 'r':
203 if (strcmp(str, "ranged") == 0) {
204 flag = NPY_ITER_RANGED0x00000100;
205 }
206 else if (strcmp(str, "refs_ok") == 0) {
207 flag = NPY_ITER_REFS_OK0x00000020;
208 }
209 else if (strcmp(str, "reduce_ok") == 0) {
210 flag = NPY_ITER_REDUCE_OK0x00000080;
211 }
212 break;
213 case 'z':
214 if (strcmp(str, "zerosize_ok") == 0) {
215 flag = NPY_ITER_ZEROSIZE_OK0x00000040;
216 }
217 break;
218 }
219 if (flag == 0) {
220 PyErr_Format(PyExc_ValueError,
221 "Unexpected iterator global flag \"%s\"", str);
222 Py_DECREF(f)_Py_DECREF(((PyObject*)(f)));
223 return 0;
224 }
225 else {
226 tmpflags |= flag;
227 }
228 Py_DECREF(f)_Py_DECREF(((PyObject*)(f)));
229 }
230
231 *flags |= tmpflags;
232 return 1;
233}
234
235static int
236NpyIter_OpFlagsConverter(PyObject *op_flags_in,
237 npy_uint32 *op_flags)
238{
239 int iflags, nflags;
240 npy_uint32 flag;
241
242 if (!PyTuple_Check(op_flags_in)((((((PyObject*)(op_flags_in))->ob_type))->tp_flags &
((1UL << 26))) != 0)
&& !PyList_Check(op_flags_in)((((((PyObject*)(op_flags_in))->ob_type))->tp_flags &
((1UL << 25))) != 0)
) {
243 PyErr_SetString(PyExc_ValueError,
244 "op_flags must be a tuple or array of per-op flag-tuples");
245 return 0;
246 }
247
248 nflags = PySequence_Size(op_flags_in);
249
250 *op_flags = 0;
251 for (iflags = 0; iflags < nflags; ++iflags) {
252 PyObject *f;
253 char *str = NULL((void*)0);
254 Py_ssize_t length = 0;
255
256 f = PySequence_GetItem(op_flags_in, iflags);
257 if (f == NULL((void*)0)) {
258 return 0;
259 }
260
261 if (PyUnicode_Check(f)((((((PyObject*)(f))->ob_type))->tp_flags & ((1UL <<
28))) != 0)
) {
262 /* accept unicode input */
263 PyObject *f_str;
264 f_str = PyUnicode_AsASCIIString(f);
265 if (f_str == NULL((void*)0)) {
266 Py_DECREF(f)_Py_DECREF(((PyObject*)(f)));
267 return 0;
268 }
269 Py_DECREF(f)_Py_DECREF(((PyObject*)(f)));
270 f = f_str;
271 }
272
273 if (PyBytes_AsStringAndSize(f, &str, &length) < 0) {
274 PyErr_Clear();
275 Py_DECREF(f)_Py_DECREF(((PyObject*)(f)));
276 PyErr_SetString(PyExc_ValueError,
277 "op_flags must be a tuple or array of per-op flag-tuples");
278 return 0;
279 }
280
281 /* Use switch statements to quickly isolate the right flag */
282 flag = 0;
283 switch (str[0]) {
284 case 'a':
285 if (length > 2) switch(str[2]) {
286 case 'i':
287 if (strcmp(str, "aligned") == 0) {
288 flag = NPY_ITER_ALIGNED0x00100000;
289 }
290 break;
291 case 'l':
292 if (strcmp(str, "allocate") == 0) {
293 flag = NPY_ITER_ALLOCATE0x01000000;
294 }
295 break;
296 case 'r':
297 if (strcmp(str, "arraymask") == 0) {
298 flag = NPY_ITER_ARRAYMASK0x20000000;
299 }
300 break;
301 }
302 break;
303 case 'c':
304 if (strcmp(str, "copy") == 0) {
305 flag = NPY_ITER_COPY0x00400000;
306 }
307 if (strcmp(str, "contig") == 0) {
308 flag = NPY_ITER_CONTIG0x00200000;
309 }
310 break;
311 case 'n':
312 switch (str[1]) {
313 case 'b':
314 if (strcmp(str, "nbo") == 0) {
315 flag = NPY_ITER_NBO0x00080000;
316 }
317 break;
318 case 'o':
319 if (strcmp(str, "no_subtype") == 0) {
320 flag = NPY_ITER_NO_SUBTYPE0x02000000;
321 }
322 else if (strcmp(str, "no_broadcast") == 0) {
323 flag = NPY_ITER_NO_BROADCAST0x08000000;
324 }
325 break;
326 }
327 break;
328 case 'o':
329 if (strcmp(str, "overlap_assume_elementwise") == 0) {
330 flag = NPY_ITER_OVERLAP_ASSUME_ELEMENTWISE0x40000000;
331 }
332 break;
333 case 'r':
334 if (length > 4) switch (str[4]) {
335 case 'o':
336 if (strcmp(str, "readonly") == 0) {
337 flag = NPY_ITER_READONLY0x00020000;
338 }
339 break;
340 case 'w':
341 if (strcmp(str, "readwrite") == 0) {
342 flag = NPY_ITER_READWRITE0x00010000;
343 }
344 break;
345 }
346 break;
347 case 'u':
348 switch (str[1]) {
349 case 'p':
350 if (strcmp(str, "updateifcopy") == 0) {
351 flag = NPY_ITER_UPDATEIFCOPY0x00800000;
352 }
353 break;
354 }
355 break;
356 case 'v':
357 if (strcmp(str, "virtual") == 0) {
358 flag = NPY_ITER_VIRTUAL0x04000000;
359 }
360 break;
361 case 'w':
362 if (length > 5) switch (str[5]) {
363 case 'o':
364 if (strcmp(str, "writeonly") == 0) {
365 flag = NPY_ITER_WRITEONLY0x00040000;
366 }
367 break;
368 case 'm':
369 if (strcmp(str, "writemasked") == 0) {
370 flag = NPY_ITER_WRITEMASKED0x10000000;
371 }
372 break;
373 }
374 break;
375 }
376 if (flag == 0) {
377 PyErr_Format(PyExc_ValueError,
378 "Unexpected per-op iterator flag \"%s\"", str);
379 Py_DECREF(f)_Py_DECREF(((PyObject*)(f)));
380 return 0;
381 }
382 else {
383 *op_flags |= flag;
384 }
385 Py_DECREF(f)_Py_DECREF(((PyObject*)(f)));
386 }
387
388 return 1;
389}
390
391static int
392npyiter_convert_op_flags_array(PyObject *op_flags_in,
393 npy_uint32 *op_flags_array, npy_intp nop)
394{
395 npy_intp iop;
396
397 if (!PyTuple_Check(op_flags_in)((((((PyObject*)(op_flags_in))->ob_type))->tp_flags &
((1UL << 26))) != 0)
&& !PyList_Check(op_flags_in)((((((PyObject*)(op_flags_in))->ob_type))->tp_flags &
((1UL << 25))) != 0)
) {
398 PyErr_SetString(PyExc_ValueError,
399 "op_flags must be a tuple or array of per-op flag-tuples");
400 return 0;
401 }
402
403 if (PySequence_Size(op_flags_in) != nop) {
404 goto try_single_flags;
405 }
406
407 for (iop = 0; iop < nop; ++iop) {
408 PyObject *f = PySequence_GetItem(op_flags_in, iop);
409 if (f == NULL((void*)0)) {
410 return 0;
411 }
412 /* If the first item is a string, try as one set of flags */
413 if (iop == 0 && (PyBytes_Check(f)((((((PyObject*)(f))->ob_type))->tp_flags & ((1UL <<
27))) != 0)
|| PyUnicode_Check(f)((((((PyObject*)(f))->ob_type))->tp_flags & ((1UL <<
28))) != 0)
)) {
414 Py_DECREF(f)_Py_DECREF(((PyObject*)(f)));
415 goto try_single_flags;
416 }
417 if (NpyIter_OpFlagsConverter(f,
418 &op_flags_array[iop]) != 1) {
419 Py_DECREF(f)_Py_DECREF(((PyObject*)(f)));
420 return 0;
421 }
422
423 Py_DECREF(f)_Py_DECREF(((PyObject*)(f)));
424 }
425
426 return 1;
427
428try_single_flags:
429 if (NpyIter_OpFlagsConverter(op_flags_in,
430 &op_flags_array[0]) != 1) {
431 return 0;
432 }
433
434 for (iop = 1; iop < nop; ++iop) {
435 op_flags_array[iop] = op_flags_array[0];
436 }
437
438 return 1;
439}
440
441static int
442npyiter_convert_dtypes(PyObject *op_dtypes_in,
443 PyArray_Descr **op_dtypes,
444 npy_intp nop)
445{
446 npy_intp iop;
447
448 /*
449 * If the input isn't a tuple of dtypes, try converting it as-is
450 * to a dtype, and replicating to all operands.
451 */
452 if ((!PyTuple_Check(op_dtypes_in)((((((PyObject*)(op_dtypes_in))->ob_type))->tp_flags &
((1UL << 26))) != 0)
&& !PyList_Check(op_dtypes_in)((((((PyObject*)(op_dtypes_in))->ob_type))->tp_flags &
((1UL << 25))) != 0)
) ||
453 PySequence_Size(op_dtypes_in) != nop) {
454 goto try_single_dtype;
455 }
456
457 for (iop = 0; iop < nop; ++iop) {
458 PyObject *dtype = PySequence_GetItem(op_dtypes_in, iop);
459 if (dtype == NULL((void*)0)) {
460 npy_intp i;
461 for (i = 0; i < iop; ++i ) {
462 Py_XDECREF(op_dtypes[i])_Py_XDECREF(((PyObject*)(op_dtypes[i])));
463 }
464 return 0;
465 }
466
467 /* Try converting the object to a descr */
468 if (PyArray_DescrConverter2(dtype, &op_dtypes[iop]) != 1) {
469 npy_intp i;
470 for (i = 0; i < iop; ++i ) {
471 Py_XDECREF(op_dtypes[i])_Py_XDECREF(((PyObject*)(op_dtypes[i])));
472 }
473 Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype)));
474 PyErr_Clear();
475 goto try_single_dtype;
476 }
477
478 Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype)));
479 }
480
481 return 1;
482
483try_single_dtype:
484 if (PyArray_DescrConverter2(op_dtypes_in, &op_dtypes[0]) == 1) {
485 for (iop = 1; iop < nop; ++iop) {
486 op_dtypes[iop] = op_dtypes[0];
487 Py_XINCREF(op_dtypes[iop])_Py_XINCREF(((PyObject*)(op_dtypes[iop])));
488 }
489 return 1;
490 }
491
492 return 0;
493}
494
495static int
496npyiter_convert_op_axes(PyObject *op_axes_in, int nop,
497 int **op_axes, int *oa_ndim)
498{
499 PyObject *a;
500 int iop;
501
502 if ((!PyTuple_Check(op_axes_in)((((((PyObject*)(op_axes_in))->ob_type))->tp_flags &
((1UL << 26))) != 0)
&& !PyList_Check(op_axes_in)((((((PyObject*)(op_axes_in))->ob_type))->tp_flags &
((1UL << 25))) != 0)
) ||
503 PySequence_Size(op_axes_in) != nop) {
504 PyErr_SetString(PyExc_ValueError,
505 "op_axes must be a tuple/list matching the number of ops");
506 return 0;
507 }
508
509 *oa_ndim = -1;
510
511 /* Copy the tuples into op_axes */
512 for (iop = 0; iop < nop; ++iop) {
513 int idim;
514 a = PySequence_GetItem(op_axes_in, iop);
515 if (a == NULL((void*)0)) {
516 return 0;
517 }
518 if (a == Py_None(&_Py_NoneStruct)) {
519 op_axes[iop] = NULL((void*)0);
520 } else {
521 if (!PyTuple_Check(a)((((((PyObject*)(a))->ob_type))->tp_flags & ((1UL <<
26))) != 0)
&& !PyList_Check(a)((((((PyObject*)(a))->ob_type))->tp_flags & ((1UL <<
25))) != 0)
) {
522 PyErr_SetString(PyExc_ValueError,
523 "Each entry of op_axes must be None "
524 "or a tuple/list");
525 Py_DECREF(a)_Py_DECREF(((PyObject*)(a)));
526 return 0;
527 }
528 if (*oa_ndim == -1) {
529 *oa_ndim = PySequence_Size(a);
530 if (*oa_ndim > NPY_MAXDIMS32) {
531 PyErr_SetString(PyExc_ValueError,
532 "Too many dimensions in op_axes");
533 Py_DECREF(a)_Py_DECREF(((PyObject*)(a)));
534 return 0;
535 }
536 }
537 if (PySequence_Size(a) != *oa_ndim) {
538 PyErr_SetString(PyExc_ValueError,
539 "Each entry of op_axes must have the same size");
540 Py_DECREF(a)_Py_DECREF(((PyObject*)(a)));
541 return 0;
542 }
543 for (idim = 0; idim < *oa_ndim; ++idim) {
544 PyObject *v = PySequence_GetItem(a, idim);
545 if (v == NULL((void*)0)) {
546 Py_DECREF(a)_Py_DECREF(((PyObject*)(a)));
547 return 0;
548 }
549 /* numpy.newaxis is None */
550 if (v == Py_None(&_Py_NoneStruct)) {
551 op_axes[iop][idim] = -1;
552 }
553 else {
554 op_axes[iop][idim] = PyArray_PyIntAsInt(v);
555 if (op_axes[iop][idim]==-1 &&
556 PyErr_Occurred()) {
557 Py_DECREF(a)_Py_DECREF(((PyObject*)(a)));
558 Py_DECREF(v)_Py_DECREF(((PyObject*)(v)));
559 return 0;
560 }
561 }
562 Py_DECREF(v)_Py_DECREF(((PyObject*)(v)));
563 }
564 }
565 Py_DECREF(a)_Py_DECREF(((PyObject*)(a)));
566 }
567
568 if (*oa_ndim == -1) {
569 PyErr_SetString(PyExc_ValueError,
570 "If op_axes is provided, at least one list of axes "
571 "must be contained within it");
572 return 0;
573 }
574
575 return 1;
576}
577
578/*
579 * Converts the operand array and op_flags array into the form
580 * NpyIter_AdvancedNew needs. Sets nop, and on success, each
581 * op[i] owns a reference to an array object.
582 */
583static int
584npyiter_convert_ops(PyObject *op_in, PyObject *op_flags_in,
585 PyArrayObject **op, npy_uint32 *op_flags,
586 int *nop_out)
587{
588 int iop, nop;
589
590 /* nop and op */
591 if (PyTuple_Check(op_in)((((((PyObject*)(op_in))->ob_type))->tp_flags & ((1UL
<< 26))) != 0)
|| PyList_Check(op_in)((((((PyObject*)(op_in))->ob_type))->tp_flags & ((1UL
<< 25))) != 0)
) {
592 nop = PySequence_Size(op_in);
593 if (nop == 0) {
594 PyErr_SetString(PyExc_ValueError,
595 "Must provide at least one operand");
596 return 0;
597 }
598 if (nop > NPY_MAXARGS32) {
599 PyErr_SetString(PyExc_ValueError, "Too many operands");
600 return 0;
601 }
602
603 for (iop = 0; iop < nop; ++iop) {
604 PyObject *item = PySequence_GetItem(op_in, iop);
605 if (item == NULL((void*)0)) {
606 npy_intp i;
607 for (i = 0; i < iop; ++i) {
608 Py_XDECREF(op[i])_Py_XDECREF(((PyObject*)(op[i])));
609 }
610 return 0;
611 }
612 else if (item == Py_None(&_Py_NoneStruct)) {
613 Py_DECREF(item)_Py_DECREF(((PyObject*)(item)));
614 item = NULL((void*)0);
615 }
616 /* This is converted to an array after op flags are retrieved */
617 op[iop] = (PyArrayObject *)item;
618 }
619 }
620 else {
621 nop = 1;
622 /* Is converted to an array after op flags are retrieved */
623 Py_INCREF(op_in)_Py_INCREF(((PyObject*)(op_in)));
624 op[0] = (PyArrayObject *)op_in;
625 }
626
627 *nop_out = nop;
628
629 /* op_flags */
630 if (op_flags_in == NULL((void*)0) || op_flags_in == Py_None(&_Py_NoneStruct)) {
631 for (iop = 0; iop < nop; ++iop) {
632 /*
633 * By default, make NULL operands writeonly and flagged for
634 * allocation, and everything else readonly. To write
635 * to a provided operand, you must specify the write flag manually.
636 */
637 if (op[iop] == NULL((void*)0)) {
638 op_flags[iop] = NPY_ITER_WRITEONLY0x00040000 | NPY_ITER_ALLOCATE0x01000000;
639 }
640 else {
641 op_flags[iop] = NPY_ITER_READONLY0x00020000;
642 }
643 }
644 }
645 else if (npyiter_convert_op_flags_array(op_flags_in,
646 op_flags, nop) != 1) {
647 for (iop = 0; iop < nop; ++iop) {
648 Py_XDECREF(op[iop])_Py_XDECREF(((PyObject*)(op[iop])));
649 }
650 *nop_out = 0;
651 return 0;
652 }
653
654 /* Now that we have the flags - convert all the ops to arrays */
655 for (iop = 0; iop < nop; ++iop) {
656 if (op[iop] != NULL((void*)0)) {
657 PyArrayObject *ao;
658 int fromanyflags = 0;
659
660 if (op_flags[iop]&(NPY_ITER_READWRITE0x00010000|NPY_ITER_WRITEONLY0x00040000)) {
661 fromanyflags |= NPY_ARRAY_WRITEBACKIFCOPY0x2000;
662 }
663 ao = (PyArrayObject *)PyArray_FROM_OF((PyObject *)op[iop],PyArray_CheckFromAny((PyObject *)op[iop], ((void*)0), 0, 0, fromanyflags
, ((void*)0))
664 fromanyflags)PyArray_CheckFromAny((PyObject *)op[iop], ((void*)0), 0, 0, fromanyflags
, ((void*)0))
;
665 if (ao == NULL((void*)0)) {
666 if (PyErr_Occurred() &&
667 PyErr_ExceptionMatches(PyExc_TypeError)) {
668 PyErr_SetString(PyExc_TypeError,
669 "Iterator operand is flagged as writeable, "
670 "but is an object which cannot be written "
671 "back to via WRITEBACKIFCOPY");
672 }
673 for (iop = 0; iop < nop; ++iop) {
674 Py_DECREF(op[iop])_Py_DECREF(((PyObject*)(op[iop])));
675 }
676 *nop_out = 0;
677 return 0;
678 }
679 Py_DECREF(op[iop])_Py_DECREF(((PyObject*)(op[iop])));
680 op[iop] = ao;
681 }
682 }
683
684 return 1;
685}
686
687static int
688npyiter_init(NewNpyArrayIterObject *self, PyObject *args, PyObject *kwds)
689{
690 static char *kwlist[] = {"op", "flags", "op_flags", "op_dtypes",
691 "order", "casting", "op_axes", "itershape",
692 "buffersize",
693 NULL((void*)0)};
694
695 PyObject *op_in = NULL((void*)0), *op_flags_in = NULL((void*)0),
696 *op_dtypes_in = NULL((void*)0), *op_axes_in = NULL((void*)0);
697
698 int iop, nop = 0;
699 PyArrayObject *op[NPY_MAXARGS32];
700 npy_uint32 flags = 0;
701 NPY_ORDER order = NPY_KEEPORDER;
702 NPY_CASTING casting = NPY_SAFE_CASTING;
703 npy_uint32 op_flags[NPY_MAXARGS32];
704 PyArray_Descr *op_request_dtypes[NPY_MAXARGS32];
705 int oa_ndim = -1;
706 int op_axes_arrays[NPY_MAXARGS32][NPY_MAXDIMS32];
707 int *op_axes[NPY_MAXARGS32];
708 PyArray_Dims itershape = {NULL((void*)0), -1};
709 int buffersize = 0;
710
711 if (self->iter != NULL((void*)0)) {
712 PyErr_SetString(PyExc_ValueError,
713 "Iterator was already initialized");
714 return -1;
715 }
716
717 if (!PyArg_ParseTupleAndKeywords_PyArg_ParseTupleAndKeywords_SizeT(args, kwds, "O|O&OOO&O&OO&i:nditer", kwlist,
718 &op_in,
719 NpyIter_GlobalFlagsConverter, &flags,
720 &op_flags_in,
721 &op_dtypes_in,
722 PyArray_OrderConverter, &order,
723 PyArray_CastingConverter, &casting,
724 &op_axes_in,
725 PyArray_OptionalIntpConverter, &itershape,
726 &buffersize)) {
727 npy_free_cache_dim_obj(itershape);
728 return -1;
729 }
730
731 /* Set the dtypes and ops to all NULL to start */
732 memset(op_request_dtypes, 0, sizeof(op_request_dtypes));
733
734 /* op and op_flags */
735 if (npyiter_convert_ops(op_in, op_flags_in, op, op_flags, &nop)
736 != 1) {
737 goto fail;
738 }
739
740 /* op_request_dtypes */
741 if (op_dtypes_in != NULL((void*)0) && op_dtypes_in != Py_None(&_Py_NoneStruct) &&
742 npyiter_convert_dtypes(op_dtypes_in,
743 op_request_dtypes, nop) != 1) {
744 goto fail;
745 }
746
747 /* op_axes */
748 if (op_axes_in != NULL((void*)0) && op_axes_in != Py_None(&_Py_NoneStruct)) {
749 /* Initialize to point to the op_axes arrays */
750 for (iop = 0; iop < nop; ++iop) {
751 op_axes[iop] = op_axes_arrays[iop];
752 }
753
754 if (npyiter_convert_op_axes(op_axes_in, nop,
755 op_axes, &oa_ndim) != 1) {
756 goto fail;
757 }
758 }
759
760 if (itershape.len != -1) {
761 if (oa_ndim == -1) {
762 oa_ndim = itershape.len;
763 memset(op_axes, 0, sizeof(op_axes[0]) * nop);
764 }
765 else if (oa_ndim != itershape.len) {
766 PyErr_SetString(PyExc_ValueError,
767 "'op_axes' and 'itershape' must have the same number "
768 "of entries equal to the iterator ndim");
769 goto fail;
770 }
771 }
772
773 self->iter = NpyIter_AdvancedNew(nop, op, flags, order, casting, op_flags,
774 op_request_dtypes,
775 oa_ndim, oa_ndim >= 0 ? op_axes : NULL((void*)0),
776 itershape.ptr,
777 buffersize);
778
779 if (self->iter == NULL((void*)0)) {
780 goto fail;
781 }
782
783 /* Cache some values for the member functions to use */
784 if (npyiter_cache_values(self) < 0) {
785 goto fail;
786 }
787
788 if (NpyIter_GetIterSize(self->iter) == 0) {
789 self->started = 1;
790 self->finished = 1;
791 }
792 else {
793 self->started = 0;
794 self->finished = 0;
795 }
796
797 npy_free_cache_dim_obj(itershape);
798
799 /* Release the references we got to the ops and dtypes */
800 for (iop = 0; iop < nop; ++iop) {
801 Py_XDECREF(op[iop])_Py_XDECREF(((PyObject*)(op[iop])));
802 Py_XDECREF(op_request_dtypes[iop])_Py_XDECREF(((PyObject*)(op_request_dtypes[iop])));
803 }
804
805 return 0;
806
807fail:
808 npy_free_cache_dim_obj(itershape);
809 for (iop = 0; iop < nop; ++iop) {
810 Py_XDECREF(op[iop])_Py_XDECREF(((PyObject*)(op[iop])));
811 Py_XDECREF(op_request_dtypes[iop])_Py_XDECREF(((PyObject*)(op_request_dtypes[iop])));
812 }
813 return -1;
814}
815
816NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject *
817NpyIter_NestedIters(PyObject *NPY_UNUSED(self)(__NPY_UNUSED_TAGGEDself) __attribute__ ((__unused__)),
818 PyObject *args, PyObject *kwds)
819{
820 static char *kwlist[] = {"op", "axes", "flags", "op_flags",
821 "op_dtypes", "order",
822 "casting", "buffersize",
823 NULL((void*)0)};
824
825 PyObject *op_in = NULL((void*)0), *axes_in = NULL((void*)0),
826 *op_flags_in = NULL((void*)0), *op_dtypes_in = NULL((void*)0);
827
828 int iop, nop = 0, inest, nnest = 0;
829 PyArrayObject *op[NPY_MAXARGS32];
830 npy_uint32 flags = 0, flags_inner;
831 NPY_ORDER order = NPY_KEEPORDER;
832 NPY_CASTING casting = NPY_SAFE_CASTING;
833 npy_uint32 op_flags[NPY_MAXARGS32], op_flags_inner[NPY_MAXARGS32];
834 PyArray_Descr *op_request_dtypes[NPY_MAXARGS32],
835 *op_request_dtypes_inner[NPY_MAXARGS32];
836 int op_axes_data[NPY_MAXDIMS32];
837 int *nested_op_axes[NPY_MAXDIMS32];
838 int nested_naxes[NPY_MAXDIMS32], iaxes, naxes;
839 int negones[NPY_MAXDIMS32];
840 char used_axes[NPY_MAXDIMS32];
841 int buffersize = 0;
842
843 PyObject *ret = NULL((void*)0);
844
845 if (!PyArg_ParseTupleAndKeywords_PyArg_ParseTupleAndKeywords_SizeT(args, kwds, "OO|O&OOO&O&i", kwlist,
846 &op_in,
847 &axes_in,
848 NpyIter_GlobalFlagsConverter, &flags,
849 &op_flags_in,
850 &op_dtypes_in,
851 PyArray_OrderConverter, &order,
852 PyArray_CastingConverter, &casting,
853 &buffersize)) {
854 return NULL((void*)0);
855 }
856
857 /* axes */
858 if (!PyTuple_Check(axes_in)((((((PyObject*)(axes_in))->ob_type))->tp_flags & (
(1UL << 26))) != 0)
&& !PyList_Check(axes_in)((((((PyObject*)(axes_in))->ob_type))->tp_flags & (
(1UL << 25))) != 0)
) {
859 PyErr_SetString(PyExc_ValueError,
860 "axes must be a tuple of axis arrays");
861 return NULL((void*)0);
862 }
863 nnest = PySequence_Size(axes_in);
864 if (nnest < 2) {
865 PyErr_SetString(PyExc_ValueError,
866 "axes must have at least 2 entries for nested iteration");
867 return NULL((void*)0);
868 }
869 naxes = 0;
870 memset(used_axes, 0, NPY_MAXDIMS32);
871 for (inest = 0; inest < nnest; ++inest) {
872 PyObject *item = PySequence_GetItem(axes_in, inest);
873 npy_intp i;
874 if (item == NULL((void*)0)) {
875 return NULL((void*)0);
876 }
877 if (!PyTuple_Check(item)((((((PyObject*)(item))->ob_type))->tp_flags & ((1UL
<< 26))) != 0)
&& !PyList_Check(item)((((((PyObject*)(item))->ob_type))->tp_flags & ((1UL
<< 25))) != 0)
) {
878 PyErr_SetString(PyExc_ValueError,
879 "Each item in axes must be a an integer tuple");
880 Py_DECREF(item)_Py_DECREF(((PyObject*)(item)));
881 return NULL((void*)0);
882 }
883 nested_naxes[inest] = PySequence_Size(item);
884 if (naxes + nested_naxes[inest] > NPY_MAXDIMS32) {
885 PyErr_SetString(PyExc_ValueError,
886 "Too many axes given");
887 Py_DECREF(item)_Py_DECREF(((PyObject*)(item)));
888 return NULL((void*)0);
889 }
890 for (i = 0; i < nested_naxes[inest]; ++i) {
891 PyObject *v = PySequence_GetItem(item, i);
892 npy_intp axis;
893 if (v == NULL((void*)0)) {
894 Py_DECREF(item)_Py_DECREF(((PyObject*)(item)));
895 return NULL((void*)0);
896 }
897 axis = PyLong_AsLong(v);
898 Py_DECREF(v)_Py_DECREF(((PyObject*)(v)));
899 if (axis < 0 || axis >= NPY_MAXDIMS32) {
900 PyErr_SetString(PyExc_ValueError,
901 "An axis is out of bounds");
902 Py_DECREF(item)_Py_DECREF(((PyObject*)(item)));
903 return NULL((void*)0);
904 }
905 /*
906 * This check is very important, without it out of bounds
907 * data accesses are possible.
908 */
909 if (used_axes[axis] != 0) {
910 PyErr_SetString(PyExc_ValueError,
911 "An axis is used more than once");
912 Py_DECREF(item)_Py_DECREF(((PyObject*)(item)));
913 return NULL((void*)0);
914 }
915 used_axes[axis] = 1;
916 op_axes_data[naxes+i] = axis;
917 }
918 nested_op_axes[inest] = &op_axes_data[naxes];
919 naxes += nested_naxes[inest];
920 Py_DECREF(item)_Py_DECREF(((PyObject*)(item)));
921 }
922
923 /* op and op_flags */
924 if (npyiter_convert_ops(op_in, op_flags_in, op, op_flags, &nop)
925 != 1) {
926 return NULL((void*)0);
927 }
928
929 /* Set the dtypes to all NULL to start as well */
930 memset(op_request_dtypes, 0, sizeof(op_request_dtypes[0])*nop);
931 memset(op_request_dtypes_inner, 0,
932 sizeof(op_request_dtypes_inner[0])*nop);
933
934 /* op_request_dtypes */
935 if (op_dtypes_in != NULL((void*)0) && op_dtypes_in != Py_None(&_Py_NoneStruct) &&
936 npyiter_convert_dtypes(op_dtypes_in,
937 op_request_dtypes, nop) != 1) {
938 goto fail;
939 }
940
941 ret = PyTuple_New(nnest);
942 if (ret == NULL((void*)0)) {
943 goto fail;
944 }
945
946 /* For broadcasting allocated arrays */
947 for (iaxes = 0; iaxes < naxes; ++iaxes) {
948 negones[iaxes] = -1;
949 }
950
951 /*
952 * Clear any unnecessary ALLOCATE flags, so we can use them
953 * to indicate exactly the allocated outputs. Also, separate
954 * the inner loop flags.
955 */
956 for (iop = 0; iop < nop; ++iop) {
957 if ((op_flags[iop]&NPY_ITER_ALLOCATE0x01000000) && op[iop] != NULL((void*)0)) {
958 op_flags[iop] &= ~NPY_ITER_ALLOCATE0x01000000;
959 }
960
961 /*
962 * Clear any flags allowing copies or output allocation for
963 * the inner loop.
964 */
965 op_flags_inner[iop] = op_flags[iop] & ~(NPY_ITER_COPY0x00400000|
966 NPY_ITER_UPDATEIFCOPY0x00800000|
967 NPY_ITER_ALLOCATE0x01000000);
968 /*
969 * If buffering is enabled and copying is not,
970 * clear the nbo_aligned flag and strip the data type
971 * for the outer loops.
972 */
973 if ((flags&(NPY_ITER_BUFFERED0x00000200)) &&
974 !(op_flags[iop]&(NPY_ITER_COPY0x00400000|
975 NPY_ITER_UPDATEIFCOPY0x00800000|
976 NPY_ITER_ALLOCATE0x01000000))) {
977 op_flags[iop] &= ~(NPY_ITER_NBO0x00080000|NPY_ITER_ALIGNED0x00100000|NPY_ITER_CONTIG0x00200000);
978 op_request_dtypes_inner[iop] = op_request_dtypes[iop];
979 op_request_dtypes[iop] = NULL((void*)0);
980 }
981 }
982
983 /* Only the inner loop gets the buffering and no inner flags */
984 flags_inner = flags&~NPY_ITER_COMMON_DTYPE0x00000010;
985 flags &= ~(NPY_ITER_EXTERNAL_LOOP0x00000008|
986 NPY_ITER_BUFFERED0x00000200);
987
988 for (inest = 0; inest < nnest; ++inest) {
989 NewNpyArrayIterObject *iter;
990 int *op_axes_nop[NPY_MAXARGS32];
991
992 /*
993 * All the operands' op_axes are the same, except for
994 * allocated outputs.
995 */
996 for (iop = 0; iop < nop; ++iop) {
997 if (op_flags[iop]&NPY_ITER_ALLOCATE0x01000000) {
998 if (inest == 0) {
999 op_axes_nop[iop] = NULL((void*)0);
1000 }
1001 else {
1002 op_axes_nop[iop] = negones;
1003 }
1004 }
1005 else {
1006 op_axes_nop[iop] = nested_op_axes[inest];
1007 }
1008 }
1009
1010 /*
1011 printf("\n");
1012 for (iop = 0; iop < nop; ++iop) {
1013 npy_intp i;
1014
1015 for (i = 0; i < nested_naxes[inest]; ++i) {
1016 printf("%d ", (int)op_axes_nop[iop][i]);
1017 }
1018 printf("\n");
1019 }
1020 */
1021
1022 /* Allocate the iterator */
1023 iter = (NewNpyArrayIterObject *)npyiter_new(&NpyIter_Type, NULL((void*)0), NULL((void*)0));
1024 if (iter == NULL((void*)0)) {
1025 Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret)));
1026 goto fail;
1027 }
1028
1029 if (inest < nnest-1) {
1030 iter->iter = NpyIter_AdvancedNew(nop, op, flags, order,
1031 casting, op_flags, op_request_dtypes,
1032 nested_naxes[inest], op_axes_nop,
1033 NULL((void*)0),
1034 0);
1035 }
1036 else {
1037 iter->iter = NpyIter_AdvancedNew(nop, op, flags_inner, order,
1038 casting, op_flags_inner,
1039 op_request_dtypes_inner,
1040 nested_naxes[inest], op_axes_nop,
1041 NULL((void*)0),
1042 buffersize);
1043 }
1044
1045 if (iter->iter == NULL((void*)0)) {
1046 Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret)));
1047 goto fail;
1048 }
1049
1050 /* Cache some values for the member functions to use */
1051 if (npyiter_cache_values(iter) < 0) {
1052 Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret)));
1053 goto fail;
1054 }
1055
1056 if (NpyIter_GetIterSize(iter->iter) == 0) {
1057 iter->started = 1;
1058 iter->finished = 1;
1059 }
1060 else {
1061 iter->started = 0;
1062 iter->finished = 0;
1063 }
1064
1065 /*
1066 * If there are any allocated outputs or any copies were made,
1067 * adjust op so that the other iterators use the same ones.
1068 */
1069 if (inest == 0) {
1070 PyArrayObject **operands = NpyIter_GetOperandArray(iter->iter);
1071 for (iop = 0; iop < nop; ++iop) {
1072 if (op[iop] != operands[iop]) {
1073 Py_XDECREF(op[iop])_Py_XDECREF(((PyObject*)(op[iop])));
1074 op[iop] = operands[iop];
1075 Py_INCREF(op[iop])_Py_INCREF(((PyObject*)(op[iop])));
1076 }
1077
1078 /*
1079 * Clear any flags allowing copies for
1080 * the rest of the iterators
1081 */
1082 op_flags[iop] &= ~(NPY_ITER_COPY0x00400000|
1083 NPY_ITER_UPDATEIFCOPY0x00800000);
1084 }
1085 /* Clear the common dtype flag for the rest of the iterators */
1086 flags &= ~NPY_ITER_COMMON_DTYPE0x00000010;
1087 }
1088
1089 PyTuple_SET_ITEM(ret, inest, (PyObject *)iter)PyTuple_SetItem(ret, inest, (PyObject *)iter);
1090 }
1091
1092 /* Release our references to the ops and dtypes */
1093 for (iop = 0; iop < nop; ++iop) {
1094 Py_XDECREF(op[iop])_Py_XDECREF(((PyObject*)(op[iop])));
1095 Py_XDECREF(op_request_dtypes[iop])_Py_XDECREF(((PyObject*)(op_request_dtypes[iop])));
1096 Py_XDECREF(op_request_dtypes_inner[iop])_Py_XDECREF(((PyObject*)(op_request_dtypes_inner[iop])));
1097 }
1098
1099 /* Set up the nested child references */
1100 for (inest = 0; inest < nnest-1; ++inest) {
1101 NewNpyArrayIterObject *iter;
1102 iter = (NewNpyArrayIterObject *)PyTuple_GET_ITEM(ret, inest)((((void) (0)), (PyTupleObject *)(ret))->ob_item[inest]);
1103 /*
1104 * Indicates which iterator to reset with new base pointers
1105 * each iteration step.
1106 */
1107 iter->nested_child =
1108 (NewNpyArrayIterObject *)PyTuple_GET_ITEM(ret, inest+1)((((void) (0)), (PyTupleObject *)(ret))->ob_item[inest+1]);
1109 Py_INCREF(iter->nested_child)_Py_INCREF(((PyObject*)(iter->nested_child)));
1110 /*
1111 * Need to do a nested reset so all the iterators point
1112 * at the right data
1113 */
1114 if (NpyIter_ResetBasePointers(iter->nested_child->iter,
1115 iter->dataptrs, NULL((void*)0)) != NPY_SUCCEED1) {
1116 Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret)));
1117 return NULL((void*)0);
1118 }
1119 }
1120
1121 return ret;
1122
1123fail:
1124 for (iop = 0; iop < nop; ++iop) {
1125 Py_XDECREF(op[iop])_Py_XDECREF(((PyObject*)(op[iop])));
1126 Py_XDECREF(op_request_dtypes[iop])_Py_XDECREF(((PyObject*)(op_request_dtypes[iop])));
1127 Py_XDECREF(op_request_dtypes_inner[iop])_Py_XDECREF(((PyObject*)(op_request_dtypes_inner[iop])));
1128 }
1129 return NULL((void*)0);
1130}
1131
1132
1133static void
1134npyiter_dealloc(NewNpyArrayIterObject *self)
1135{
1136 if (self->iter) {
1137 /* Store error, so that WriteUnraisable cannot clear an existing one */
1138 PyObject *exc, *val, *tb;
1139 PyErr_Fetch(&exc, &val, &tb);
1140 if (npyiter_has_writeback(self->iter)) {
1141 if (PyErr_WarnEx(PyExc_RuntimeWarning,
1142 "Temporary data has not been written back to one of the "
1143 "operands. Typically nditer is used as a context manager "
1144 "otherwise 'close' must be called before reading iteration "
1145 "results.", 1) < 0) {
1146 PyObject *s;
1147
1148 s = PyUnicode_FromString("npyiter_dealloc");
1149 if (s) {
1150 PyErr_WriteUnraisable(s);
1151 Py_DECREF(s)_Py_DECREF(((PyObject*)(s)));
1152 }
1153 else {
1154 PyErr_WriteUnraisable(Py_None(&_Py_NoneStruct));
1155 }
1156 }
1157 }
1158 if (!NpyIter_Deallocate(self->iter)) {
1159 PyErr_WriteUnraisable(Py_None(&_Py_NoneStruct));
1160 }
1161 self->iter = NULL((void*)0);
1162 Py_XDECREF(self->nested_child)_Py_XDECREF(((PyObject*)(self->nested_child)));
1163 self->nested_child = NULL((void*)0);
1164 PyErr_Restore(exc, val, tb);
1165 }
1166 Py_TYPE(self)(((PyObject*)(self))->ob_type)->tp_free((PyObject*)self);
1167}
1168
1169static int
1170npyiter_resetbasepointers(NewNpyArrayIterObject *self)
1171{
1172 while (self->nested_child) {
1173 if (NpyIter_ResetBasePointers(self->nested_child->iter,
1174 self->dataptrs, NULL((void*)0)) != NPY_SUCCEED1) {
1175 return NPY_FAIL0;
1176 }
1177 self = self->nested_child;
1178 if (NpyIter_GetIterSize(self->iter) == 0) {
1179 self->started = 1;
1180 self->finished = 1;
1181 }
1182 else {
1183 self->started = 0;
1184 self->finished = 0;
1185 }
1186 }
1187
1188 return NPY_SUCCEED1;
1189}
1190
1191static PyObject *
1192npyiter_reset(NewNpyArrayIterObject *self)
1193{
1194 if (self->iter == NULL((void*)0)) {
1195 PyErr_SetString(PyExc_ValueError,
1196 "Iterator is invalid");
1197 return NULL((void*)0);
1198 }
1199
1200 if (NpyIter_Reset(self->iter, NULL((void*)0)) != NPY_SUCCEED1) {
1201 return NULL((void*)0);
1202 }
1203 if (NpyIter_GetIterSize(self->iter) == 0) {
1204 self->started = 1;
1205 self->finished = 1;
1206 }
1207 else {
1208 self->started = 0;
1209 self->finished = 0;
1210 }
1211
1212 if (self->get_multi_index == NULL((void*)0) && NpyIter_HasMultiIndex(self->iter)) {
1213 self->get_multi_index = NpyIter_GetGetMultiIndex(self->iter, NULL((void*)0));
1214 }
1215
1216 /* If there is nesting, the nested iterators should be reset */
1217 if (npyiter_resetbasepointers(self) != NPY_SUCCEED1) {
1218 return NULL((void*)0);
1219 }
1220
1221 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
1222}
1223
1224/*
1225 * Makes a copy of the iterator. Note that the nesting is not
1226 * copied.
1227 */
1228static PyObject *
1229npyiter_copy(NewNpyArrayIterObject *self)
1230{
1231 NewNpyArrayIterObject *iter;
1232
1233 if (self->iter == NULL((void*)0)) {
1234 PyErr_SetString(PyExc_ValueError,
1235 "Iterator is invalid");
1236 return NULL((void*)0);
1237 }
1238
1239 /* Allocate the iterator */
1240 iter = (NewNpyArrayIterObject *)npyiter_new(&NpyIter_Type, NULL((void*)0), NULL((void*)0));
1241 if (iter == NULL((void*)0)) {
1242 return NULL((void*)0);
1243 }
1244
1245 /* Copy the C iterator */
1246 iter->iter = NpyIter_Copy(self->iter);
1247 if (iter->iter == NULL((void*)0)) {
1248 Py_DECREF(iter)_Py_DECREF(((PyObject*)(iter)));
1249 return NULL((void*)0);
1250 }
1251
1252 /* Cache some values for the member functions to use */
1253 if (npyiter_cache_values(iter) < 0) {
1254 Py_DECREF(iter)_Py_DECREF(((PyObject*)(iter)));
1255 return NULL((void*)0);
1256 }
1257
1258 iter->started = self->started;
1259 iter->finished = self->finished;
1260
1261 return (PyObject *)iter;
1262}
1263
1264static PyObject *
1265npyiter_iternext(NewNpyArrayIterObject *self)
1266{
1267 if (self->iter != NULL((void*)0) && self->iternext != NULL((void*)0) &&
1268 !self->finished && self->iternext(self->iter)) {
1269 /* If there is nesting, the nested iterators should be reset */
1270 if (npyiter_resetbasepointers(self) != NPY_SUCCEED1) {
1271 return NULL((void*)0);
1272 }
1273
1274 Py_RETURN_TRUEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_TrueStruct
)))), ((PyObject *) &_Py_TrueStruct)
;
1275 }
1276 else {
1277 if (PyErr_Occurred()) {
1278 /* casting error, buffer cleanup will occur at reset or dealloc */
1279 return NULL((void*)0);
1280 }
1281 self->finished = 1;
1282 Py_RETURN_FALSEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_FalseStruct
)))), ((PyObject *) &_Py_FalseStruct)
;
1283 }
1284}
1285
1286static PyObject *
1287npyiter_remove_axis(NewNpyArrayIterObject *self, PyObject *args)
1288{
1289 int axis = 0;
1290
1291 if (self->iter == NULL((void*)0)) {
1292 PyErr_SetString(PyExc_ValueError,
1293 "Iterator is invalid");
1294 return NULL((void*)0);
1295 }
1296
1297 if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "i:remove_axis", &axis)) {
1298 return NULL((void*)0);
1299 }
1300
1301 if (NpyIter_RemoveAxis(self->iter, axis) != NPY_SUCCEED1) {
1302 return NULL((void*)0);
1303 }
1304 /* RemoveAxis invalidates cached values */
1305 if (npyiter_cache_values(self) < 0) {
1306 return NULL((void*)0);
1307 }
1308 /* RemoveAxis also resets the iterator */
1309 if (NpyIter_GetIterSize(self->iter) == 0) {
1310 self->started = 1;
1311 self->finished = 1;
1312 }
1313 else {
1314 self->started = 0;
1315 self->finished = 0;
1316 }
1317
1318 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
1319}
1320
1321static PyObject *
1322npyiter_remove_multi_index(NewNpyArrayIterObject *self)
1323{
1324 if (self->iter == NULL((void*)0)) {
1325 PyErr_SetString(PyExc_ValueError,
1326 "Iterator is invalid");
1327 return NULL((void*)0);
1328 }
1329
1330 NpyIter_RemoveMultiIndex(self->iter);
1331 /* RemoveMultiIndex invalidates cached values */
1332 npyiter_cache_values(self);
1333 /* RemoveMultiIndex also resets the iterator */
1334 if (NpyIter_GetIterSize(self->iter) == 0) {
1335 self->started = 1;
1336 self->finished = 1;
1337 }
1338 else {
1339 self->started = 0;
1340 self->finished = 0;
1341 }
1342
1343 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
1344}
1345
1346static PyObject *
1347npyiter_enable_external_loop(NewNpyArrayIterObject *self)
1348{
1349 if (self->iter == NULL((void*)0)) {
1350 PyErr_SetString(PyExc_ValueError,
1351 "Iterator is invalid");
1352 return NULL((void*)0);
1353 }
1354
1355 NpyIter_EnableExternalLoop(self->iter);
1356 /* EnableExternalLoop invalidates cached values */
1357 npyiter_cache_values(self);
1358 /* EnableExternalLoop also resets the iterator */
1359 if (NpyIter_GetIterSize(self->iter) == 0) {
1360 self->started = 1;
1361 self->finished = 1;
1362 }
1363 else {
1364 self->started = 0;
1365 self->finished = 0;
1366 }
1367
1368 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
1369}
1370
1371static PyObject *
1372npyiter_debug_print(NewNpyArrayIterObject *self)
1373{
1374 if (self->iter != NULL((void*)0)) {
1375 NpyIter_DebugPrint(self->iter);
1376 }
1377 else {
1378 printf("Iterator: (nil)\n")__printf_chk (2 - 1, "Iterator: (nil)\n");
1379 }
1380
1381 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
1382}
1383
1384NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject *
1385npyiter_seq_item(NewNpyArrayIterObject *self, Py_ssize_t i);
1386
1387static PyObject *npyiter_value_get(NewNpyArrayIterObject *self)
1388{
1389 PyObject *ret;
1390
1391 npy_intp iop, nop;
1392
1393 if (self->iter == NULL((void*)0) || self->finished) {
1394 PyErr_SetString(PyExc_ValueError,
1395 "Iterator is past the end");
1396 return NULL((void*)0);
1397 }
1398
1399 nop = NpyIter_GetNOp(self->iter);
1400
1401 /* Return an array or tuple of arrays with the values */
1402 if (nop == 1) {
1403 ret = npyiter_seq_item(self, 0);
1404 }
1405 else {
1406 ret = PyTuple_New(nop);
1407 if (ret == NULL((void*)0)) {
1408 return NULL((void*)0);
1409 }
1410 for (iop = 0; iop < nop; ++iop) {
1411 PyObject *a = npyiter_seq_item(self, iop);
1412 if (a == NULL((void*)0)) {
1413 Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret)));
1414 return NULL((void*)0);
1415 }
1416 PyTuple_SET_ITEM(ret, iop, a)PyTuple_SetItem(ret, iop, a);
1417 }
1418 }
1419
1420 return ret;
1421}
1422
1423static PyObject *npyiter_operands_get(NewNpyArrayIterObject *self)
1424{
1425 PyObject *ret;
1426
1427 npy_intp iop, nop;
1428 PyArrayObject **operands;
1429
1430 if (self->iter == NULL((void*)0)) {
1431 PyErr_SetString(PyExc_ValueError,
1432 "Iterator is invalid");
1433 return NULL((void*)0);
1434 }
1435 nop = NpyIter_GetNOp(self->iter);
1436 operands = self->operands;
1437
1438 ret = PyTuple_New(nop);
1439 if (ret == NULL((void*)0)) {
1440 return NULL((void*)0);
1441 }
1442 for (iop = 0; iop < nop; ++iop) {
1443 PyObject *operand = (PyObject *)operands[iop];
1444
1445 Py_INCREF(operand)_Py_INCREF(((PyObject*)(operand)));
1446 PyTuple_SET_ITEM(ret, iop, operand)PyTuple_SetItem(ret, iop, operand);
1447 }
1448
1449 return ret;
1450}
1451
1452static PyObject *npyiter_itviews_get(NewNpyArrayIterObject *self)
1453{
1454 PyObject *ret;
1455
1456 npy_intp iop, nop;
1457
1458 if (self->iter == NULL((void*)0)) {
1459 PyErr_SetString(PyExc_ValueError,
1460 "Iterator is invalid");
1461 return NULL((void*)0);
1462 }
1463 nop = NpyIter_GetNOp(self->iter);
1464
1465 ret = PyTuple_New(nop);
1466 if (ret == NULL((void*)0)) {
1467 return NULL((void*)0);
1468 }
1469 for (iop = 0; iop < nop; ++iop) {
1470 PyArrayObject *view = NpyIter_GetIterView(self->iter, iop);
1471
1472 if (view == NULL((void*)0)) {
1473 Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret)));
1474 return NULL((void*)0);
1475 }
1476 PyTuple_SET_ITEM(ret, iop, (PyObject *)view)PyTuple_SetItem(ret, iop, (PyObject *)view);
1477 }
1478
1479 return ret;
1480}
1481
1482static PyObject *
1483npyiter_next(NewNpyArrayIterObject *self)
1484{
1485 if (self->iter == NULL((void*)0) || self->iternext == NULL((void*)0) ||
1486 self->finished) {
1487 return NULL((void*)0);
1488 }
1489
1490 /*
1491 * Use the started flag for the Python iteration protocol to work
1492 * when buffering is enabled.
1493 */
1494 if (self->started) {
1495 if (!self->iternext(self->iter)) {
1496 /*
1497 * A casting error may be set here (or no error causing a
1498 * StopIteration). Buffers may only be cleaned up later.
1499 */
1500 self->finished = 1;
1501 return NULL((void*)0);
1502 }
1503
1504 /* If there is nesting, the nested iterators should be reset */
1505 if (npyiter_resetbasepointers(self) != NPY_SUCCEED1) {
1506 return NULL((void*)0);
1507 }
1508 }
1509 self->started = 1;
1510
1511 return npyiter_value_get(self);
1512};
1513
1514static PyObject *npyiter_shape_get(NewNpyArrayIterObject *self)
1515{
1516 npy_intp ndim, shape[NPY_MAXDIMS32];
1517
1518 if (self->iter == NULL((void*)0) || self->finished) {
1519 PyErr_SetString(PyExc_ValueError,
1520 "Iterator is past the end");
1521 return NULL((void*)0);
1522 }
1523
1524 if (NpyIter_GetShape(self->iter, shape) == NPY_SUCCEED1) {
1525 ndim = NpyIter_GetNDim(self->iter);
1526 return PyArray_IntTupleFromIntp(ndim, shape);
1527 }
1528
1529 return NULL((void*)0);
1530}
1531
1532static PyObject *npyiter_multi_index_get(NewNpyArrayIterObject *self)
1533{
1534 npy_intp ndim, multi_index[NPY_MAXDIMS32];
1535
1536 if (self->iter == NULL((void*)0) || self->finished) {
1537 PyErr_SetString(PyExc_ValueError,
1538 "Iterator is past the end");
1539 return NULL((void*)0);
1540 }
1541
1542 if (self->get_multi_index != NULL((void*)0)) {
1543 ndim = NpyIter_GetNDim(self->iter);
1544 self->get_multi_index(self->iter, multi_index);
1545 return PyArray_IntTupleFromIntp(ndim, multi_index);
1546 }
1547 else {
1548 if (!NpyIter_HasMultiIndex(self->iter)) {
1549 PyErr_SetString(PyExc_ValueError,
1550 "Iterator is not tracking a multi-index");
1551 return NULL((void*)0);
1552 }
1553 else if (NpyIter_HasDelayedBufAlloc(self->iter)) {
1554 PyErr_SetString(PyExc_ValueError,
1555 "Iterator construction used delayed buffer allocation, "
1556 "and no reset has been done yet");
1557 return NULL((void*)0);
1558 }
1559 else {
1560 PyErr_SetString(PyExc_ValueError,
1561 "Iterator is in an invalid state");
1562 return NULL((void*)0);
1563 }
1564 }
1565}
1566
1567static int
1568npyiter_multi_index_set(NewNpyArrayIterObject *self, PyObject *value)
1569{
1570 npy_intp idim, ndim, multi_index[NPY_MAXDIMS32];
1571
1572 if (value == NULL((void*)0)) {
1
Assuming 'value' is not equal to NULL
2
Taking false branch
1573 PyErr_SetString(PyExc_AttributeError,
1574 "Cannot delete nditer multi_index");
1575 return -1;
1576 }
1577 if (self->iter == NULL((void*)0)) {
3
Assuming field 'iter' is not equal to NULL
4
Taking false branch
1578 PyErr_SetString(PyExc_ValueError,
1579 "Iterator is invalid");
1580 return -1;
1581 }
1582
1583 if (NpyIter_HasMultiIndex(self->iter)) {
5
Taking true branch
1584 ndim = NpyIter_GetNDim(self->iter);
1585 if (!PySequence_Check(value)) {
6
Assuming the condition is false
7
Taking false branch
1586 PyErr_SetString(PyExc_ValueError,
1587 "multi_index must be set with a sequence");
1588 return -1;
1589 }
1590 if (PySequence_Size(value) != ndim) {
8
Assuming the condition is false
9
Taking false branch
1591 PyErr_SetString(PyExc_ValueError,
1592 "Wrong number of indices");
1593 return -1;
1594 }
1595 for (idim = 0; idim < ndim; ++idim) {
10
Assuming 'idim' is < 'ndim'
11
Loop condition is true. Entering loop body
1596 PyObject *v = PySequence_GetItem(value, idim);
12
Calling 'PySequence_GetItem'
14
Returning from 'PySequence_GetItem'
16
PyObject ownership leak with reference count of 1
1597 multi_index[idim] = PyLong_AsLong(v);
1598 if (error_converting(multi_index[idim])(((multi_index[idim]) == -1) && PyErr_Occurred())) {
15
Assuming the condition is false
1599 Py_XDECREF(v)_Py_XDECREF(((PyObject*)(v)));
1600 return -1;
1601 }
1602 }
1603 if (NpyIter_GotoMultiIndex(self->iter, multi_index) != NPY_SUCCEED1) {
1604 return -1;
1605 }
1606 self->started = 0;
1607 self->finished = 0;
1608
1609 /* If there is nesting, the nested iterators should be reset */
1610 if (npyiter_resetbasepointers(self) != NPY_SUCCEED1) {
1611 return -1;
1612 }
1613
1614 return 0;
1615 }
1616 else {
1617 PyErr_SetString(PyExc_ValueError,
1618 "Iterator is not tracking a multi-index");
1619 return -1;
1620 }
1621}
1622
1623static PyObject *npyiter_index_get(NewNpyArrayIterObject *self)
1624{
1625 if (self->iter == NULL((void*)0) || self->finished) {
1626 PyErr_SetString(PyExc_ValueError,
1627 "Iterator is past the end");
1628 return NULL((void*)0);
1629 }
1630
1631 if (NpyIter_HasIndex(self->iter)) {
1632 npy_intp ind = *NpyIter_GetIndexPtr(self->iter);
1633 return PyLong_FromLong(ind);
1634 }
1635 else {
1636 PyErr_SetString(PyExc_ValueError,
1637 "Iterator does not have an index");
1638 return NULL((void*)0);
1639 }
1640}
1641
1642static int npyiter_index_set(NewNpyArrayIterObject *self, PyObject *value)
1643{
1644 if (value == NULL((void*)0)) {
1645 PyErr_SetString(PyExc_AttributeError,
1646 "Cannot delete nditer index");
1647 return -1;
1648 }
1649 if (self->iter == NULL((void*)0)) {
1650 PyErr_SetString(PyExc_ValueError,
1651 "Iterator is invalid");
1652 return -1;
1653 }
1654
1655 if (NpyIter_HasIndex(self->iter)) {
1656 npy_intp ind;
1657 ind = PyLong_AsLong(value);
1658 if (error_converting(ind)(((ind) == -1) && PyErr_Occurred())) {
1659 return -1;
1660 }
1661 if (NpyIter_GotoIndex(self->iter, ind) != NPY_SUCCEED1) {
1662 return -1;
1663 }
1664 self->started = 0;
1665 self->finished = 0;
1666
1667 /* If there is nesting, the nested iterators should be reset */
1668 if (npyiter_resetbasepointers(self) != NPY_SUCCEED1) {
1669 return -1;
1670 }
1671
1672 return 0;
1673 }
1674 else {
1675 PyErr_SetString(PyExc_ValueError,
1676 "Iterator does not have an index");
1677 return -1;
1678 }
1679}
1680
1681static PyObject *npyiter_iterindex_get(NewNpyArrayIterObject *self)
1682{
1683 if (self->iter == NULL((void*)0) || self->finished) {
1684 PyErr_SetString(PyExc_ValueError,
1685 "Iterator is past the end");
1686 return NULL((void*)0);
1687 }
1688
1689 return PyLong_FromLong(NpyIter_GetIterIndex(self->iter));
1690}
1691
1692static int npyiter_iterindex_set(NewNpyArrayIterObject *self, PyObject *value)
1693{
1694 npy_intp iterindex;
1695
1696 if (value == NULL((void*)0)) {
1697 PyErr_SetString(PyExc_AttributeError,
1698 "Cannot delete nditer iterindex");
1699 return -1;
1700 }
1701 if (self->iter == NULL((void*)0)) {
1702 PyErr_SetString(PyExc_ValueError,
1703 "Iterator is invalid");
1704 return -1;
1705 }
1706
1707 iterindex = PyLong_AsLong(value);
1708 if (error_converting(iterindex)(((iterindex) == -1) && PyErr_Occurred())) {
1709 return -1;
1710 }
1711 if (NpyIter_GotoIterIndex(self->iter, iterindex) != NPY_SUCCEED1) {
1712 return -1;
1713 }
1714 self->started = 0;
1715 self->finished = 0;
1716
1717 /* If there is nesting, the nested iterators should be reset */
1718 if (npyiter_resetbasepointers(self) != NPY_SUCCEED1) {
1719 return -1;
1720 }
1721
1722 return 0;
1723}
1724
1725static PyObject *npyiter_iterrange_get(NewNpyArrayIterObject *self)
1726{
1727 npy_intp istart = 0, iend = 0;
1728 PyObject *ret;
1729
1730 if (self->iter == NULL((void*)0)) {
1731 PyErr_SetString(PyExc_ValueError,
1732 "Iterator is invalid");
1733 return NULL((void*)0);
1734 }
1735
1736 NpyIter_GetIterIndexRange(self->iter, &istart, &iend);
1737
1738 ret = PyTuple_New(2);
1739 if (ret == NULL((void*)0)) {
1740 return NULL((void*)0);
1741 }
1742
1743 PyTuple_SET_ITEM(ret, 0, PyLong_FromLong(istart))PyTuple_SetItem(ret, 0, PyLong_FromLong(istart));
1744 PyTuple_SET_ITEM(ret, 1, PyLong_FromLong(iend))PyTuple_SetItem(ret, 1, PyLong_FromLong(iend));
1745
1746 return ret;
1747}
1748
1749static int npyiter_iterrange_set(NewNpyArrayIterObject *self, PyObject *value)
1750{
1751 npy_intp istart = 0, iend = 0;
1752
1753 if (value == NULL((void*)0)) {
1754 PyErr_SetString(PyExc_AttributeError,
1755 "Cannot delete nditer iterrange");
1756 return -1;
1757 }
1758 if (self->iter == NULL((void*)0)) {
1759 PyErr_SetString(PyExc_ValueError,
1760 "Iterator is invalid");
1761 return -1;
1762 }
1763
1764 if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(value, "nn", &istart, &iend)) {
1765 return -1;
1766 }
1767
1768 if (NpyIter_ResetToIterIndexRange(self->iter, istart, iend, NULL((void*)0))
1769 != NPY_SUCCEED1) {
1770 return -1;
1771 }
1772 if (istart < iend) {
1773 self->started = self->finished = 0;
1774 }
1775 else {
1776 self->started = self->finished = 1;
1777 }
1778
1779 if (self->get_multi_index == NULL((void*)0) && NpyIter_HasMultiIndex(self->iter)) {
1780 self->get_multi_index = NpyIter_GetGetMultiIndex(self->iter, NULL((void*)0));
1781 }
1782
1783 /* If there is nesting, the nested iterators should be reset */
1784 if (npyiter_resetbasepointers(self) != NPY_SUCCEED1) {
1785 return -1;
1786 }
1787
1788 return 0;
1789}
1790
1791static PyObject *npyiter_has_delayed_bufalloc_get(NewNpyArrayIterObject *self)
1792{
1793 if (self->iter == NULL((void*)0)) {
1794 PyErr_SetString(PyExc_ValueError,
1795 "Iterator is invalid");
1796 return NULL((void*)0);
1797 }
1798
1799 if (NpyIter_HasDelayedBufAlloc(self->iter)) {
1800 Py_RETURN_TRUEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_TrueStruct
)))), ((PyObject *) &_Py_TrueStruct)
;
1801 }
1802 else {
1803 Py_RETURN_FALSEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_FalseStruct
)))), ((PyObject *) &_Py_FalseStruct)
;
1804 }
1805}
1806
1807static PyObject *npyiter_iterationneedsapi_get(NewNpyArrayIterObject *self)
1808{
1809 if (self->iter == NULL((void*)0)) {
1810 PyErr_SetString(PyExc_ValueError,
1811 "Iterator is invalid");
1812 return NULL((void*)0);
1813 }
1814
1815 if (NpyIter_IterationNeedsAPI(self->iter)) {
1816 Py_RETURN_TRUEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_TrueStruct
)))), ((PyObject *) &_Py_TrueStruct)
;
1817 }
1818 else {
1819 Py_RETURN_FALSEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_FalseStruct
)))), ((PyObject *) &_Py_FalseStruct)
;
1820 }
1821}
1822
1823static PyObject *npyiter_has_multi_index_get(NewNpyArrayIterObject *self)
1824{
1825 if (self->iter == NULL((void*)0)) {
1826 PyErr_SetString(PyExc_ValueError,
1827 "Iterator is invalid");
1828 return NULL((void*)0);
1829 }
1830
1831 if (NpyIter_HasMultiIndex(self->iter)) {
1832 Py_RETURN_TRUEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_TrueStruct
)))), ((PyObject *) &_Py_TrueStruct)
;
1833 }
1834 else {
1835 Py_RETURN_FALSEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_FalseStruct
)))), ((PyObject *) &_Py_FalseStruct)
;
1836 }
1837}
1838
1839static PyObject *npyiter_has_index_get(NewNpyArrayIterObject *self)
1840{
1841 if (self->iter == NULL((void*)0)) {
1842 PyErr_SetString(PyExc_ValueError,
1843 "Iterator is invalid");
1844 return NULL((void*)0);
1845 }
1846
1847 if (NpyIter_HasIndex(self->iter)) {
1848 Py_RETURN_TRUEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_TrueStruct
)))), ((PyObject *) &_Py_TrueStruct)
;
1849 }
1850 else {
1851 Py_RETURN_FALSEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_FalseStruct
)))), ((PyObject *) &_Py_FalseStruct)
;
1852 }
1853}
1854
1855static PyObject *npyiter_dtypes_get(NewNpyArrayIterObject *self)
1856{
1857 PyObject *ret;
1858
1859 npy_intp iop, nop;
1860 PyArray_Descr **dtypes;
1861
1862 if (self->iter == NULL((void*)0)) {
1863 PyErr_SetString(PyExc_ValueError,
1864 "Iterator is invalid");
1865 return NULL((void*)0);
1866 }
1867 nop = NpyIter_GetNOp(self->iter);
1868
1869 ret = PyTuple_New(nop);
1870 if (ret == NULL((void*)0)) {
1871 return NULL((void*)0);
1872 }
1873 dtypes = self->dtypes;
1874 for (iop = 0; iop < nop; ++iop) {
1875 PyArray_Descr *dtype = dtypes[iop];
1876
1877 Py_INCREF(dtype)_Py_INCREF(((PyObject*)(dtype)));
1878 PyTuple_SET_ITEM(ret, iop, (PyObject *)dtype)PyTuple_SetItem(ret, iop, (PyObject *)dtype);
1879 }
1880
1881 return ret;
1882}
1883
1884static PyObject *npyiter_ndim_get(NewNpyArrayIterObject *self)
1885{
1886 if (self->iter == NULL((void*)0)) {
1887 PyErr_SetString(PyExc_ValueError,
1888 "Iterator is invalid");
1889 return NULL((void*)0);
1890 }
1891
1892 return PyLong_FromLong(NpyIter_GetNDim(self->iter));
1893}
1894
1895static PyObject *npyiter_nop_get(NewNpyArrayIterObject *self)
1896{
1897 if (self->iter == NULL((void*)0)) {
1898 PyErr_SetString(PyExc_ValueError,
1899 "Iterator is invalid");
1900 return NULL((void*)0);
1901 }
1902
1903 return PyLong_FromLong(NpyIter_GetNOp(self->iter));
1904}
1905
1906static PyObject *npyiter_itersize_get(NewNpyArrayIterObject *self)
1907{
1908 if (self->iter == NULL((void*)0)) {
1909 PyErr_SetString(PyExc_ValueError,
1910 "Iterator is invalid");
1911 return NULL((void*)0);
1912 }
1913
1914 return PyLong_FromLong(NpyIter_GetIterSize(self->iter));
1915}
1916
1917static PyObject *npyiter_finished_get(NewNpyArrayIterObject *self)
1918{
1919 if (self->iter == NULL((void*)0) || !self->finished) {
1920 Py_RETURN_FALSEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_FalseStruct
)))), ((PyObject *) &_Py_FalseStruct)
;
1921 }
1922 else {
1923 Py_RETURN_TRUEreturn _Py_INCREF(((PyObject*)(((PyObject *) &_Py_TrueStruct
)))), ((PyObject *) &_Py_TrueStruct)
;
1924 }
1925}
1926
1927NPY_NO_EXPORT__attribute__((visibility("hidden"))) Py_ssize_t
1928npyiter_seq_length(NewNpyArrayIterObject *self)
1929{
1930 if (self->iter == NULL((void*)0)) {
1931 return 0;
1932 }
1933 else {
1934 return NpyIter_GetNOp(self->iter);
1935 }
1936}
1937
1938NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject *
1939npyiter_seq_item(NewNpyArrayIterObject *self, Py_ssize_t i)
1940{
1941 npy_intp ret_ndim;
1942 npy_intp nop, innerloopsize, innerstride;
1943 char *dataptr;
1944 PyArray_Descr *dtype;
1945 int has_external_loop;
1946 Py_ssize_t i_orig = i;
1947
1948 if (self->iter == NULL((void*)0) || self->finished) {
1949 PyErr_SetString(PyExc_ValueError,
1950 "Iterator is past the end");
1951 return NULL((void*)0);
1952 }
1953
1954 if (NpyIter_HasDelayedBufAlloc(self->iter)) {
1955 PyErr_SetString(PyExc_ValueError,
1956 "Iterator construction used delayed buffer allocation, "
1957 "and no reset has been done yet");
1958 return NULL((void*)0);
1959 }
1960 nop = NpyIter_GetNOp(self->iter);
1961
1962 /* Negative indexing */
1963 if (i < 0) {
1964 i += nop;
1965 }
1966
1967 if (i < 0 || i >= nop) {
1968 PyErr_Format(PyExc_IndexError,
1969 "Iterator operand index %zd is out of bounds", i_orig);
1970 return NULL((void*)0);
1971 }
1972
1973#if 0
1974 /*
1975 * This check is disabled because it prevents things like
1976 * np.add(it[0], it[1], it[2]), where it[2] is a write-only
1977 * parameter. When write-only, the value of it[i] is
1978 * likely random junk, as if it were allocated with an
1979 * np.empty(...) call.
1980 */
1981 if (!self->readflags[i]) {
1982 PyErr_Format(PyExc_RuntimeError,
1983 "Iterator operand %zd is write-only", i);
1984 return NULL((void*)0);
1985 }
1986#endif
1987
1988 dataptr = self->dataptrs[i];
1989 dtype = self->dtypes[i];
1990 has_external_loop = NpyIter_HasExternalLoop(self->iter);
1991
1992 if (has_external_loop) {
1993 innerloopsize = *self->innerloopsizeptr;
1994 innerstride = self->innerstrides[i];
1995 ret_ndim = 1;
1996 }
1997 else {
1998 innerloopsize = 1;
1999 innerstride = 0;
2000 /* If the iterator is going over every element, return array scalars */
2001 ret_ndim = 0;
2002 }
2003
2004 Py_INCREF(dtype)_Py_INCREF(((PyObject*)(dtype)));
2005 return PyArray_NewFromDescrAndBase(
2006 &PyArray_Type, dtype,
2007 ret_ndim, &innerloopsize, &innerstride, dataptr,
2008 self->writeflags[i] ? NPY_ARRAY_WRITEABLE0x0400 : 0,
2009 NULL((void*)0), (PyObject *)self);
2010}
2011
2012NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject *
2013npyiter_seq_slice(NewNpyArrayIterObject *self,
2014 Py_ssize_t ilow, Py_ssize_t ihigh)
2015{
2016 PyObject *ret;
2017 npy_intp nop;
2018 Py_ssize_t i;
2019
2020 if (self->iter == NULL((void*)0) || self->finished) {
2021 PyErr_SetString(PyExc_ValueError,
2022 "Iterator is past the end");
2023 return NULL((void*)0);
2024 }
2025
2026 if (NpyIter_HasDelayedBufAlloc(self->iter)) {
2027 PyErr_SetString(PyExc_ValueError,
2028 "Iterator construction used delayed buffer allocation, "
2029 "and no reset has been done yet");
2030 return NULL((void*)0);
2031 }
2032 nop = NpyIter_GetNOp(self->iter);
2033 if (ilow < 0) {
2034 ilow = 0;
2035 }
2036 else if (ilow >= nop) {
2037 ilow = nop-1;
2038 }
2039 if (ihigh < ilow) {
2040 ihigh = ilow;
2041 }
2042 else if (ihigh > nop) {
2043 ihigh = nop;
2044 }
2045
2046 ret = PyTuple_New(ihigh-ilow);
2047 if (ret == NULL((void*)0)) {
2048 return NULL((void*)0);
2049 }
2050 for (i = ilow; i < ihigh ; ++i) {
2051 PyObject *item = npyiter_seq_item(self, i);
2052 if (item == NULL((void*)0)) {
2053 Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret)));
2054 return NULL((void*)0);
2055 }
2056 PyTuple_SET_ITEM(ret, i-ilow, item)PyTuple_SetItem(ret, i-ilow, item);
2057 }
2058 return ret;
2059}
2060
2061NPY_NO_EXPORT__attribute__((visibility("hidden"))) int
2062npyiter_seq_ass_item(NewNpyArrayIterObject *self, Py_ssize_t i, PyObject *v)
2063{
2064
2065 npy_intp nop, innerloopsize, innerstride;
2066 char *dataptr;
2067 PyArray_Descr *dtype;
2068 PyArrayObject *tmp;
2069 int ret, has_external_loop;
2070 Py_ssize_t i_orig = i;
2071
2072
2073 if (v == NULL((void*)0)) {
2074 PyErr_SetString(PyExc_TypeError,
2075 "Cannot delete iterator elements");
2076 return -1;
2077 }
2078
2079 if (self->iter == NULL((void*)0) || self->finished) {
2080 PyErr_SetString(PyExc_ValueError,
2081 "Iterator is past the end");
2082 return -1;
2083 }
2084
2085 if (NpyIter_HasDelayedBufAlloc(self->iter)) {
2086 PyErr_SetString(PyExc_ValueError,
2087 "Iterator construction used delayed buffer allocation, "
2088 "and no reset has been done yet");
2089 return -1;
2090 }
2091 nop = NpyIter_GetNOp(self->iter);
2092
2093 /* Negative indexing */
2094 if (i < 0) {
2095 i += nop;
2096 }
2097
2098 if (i < 0 || i >= nop) {
2099 PyErr_Format(PyExc_IndexError,
2100 "Iterator operand index %zd is out of bounds", i_orig);
2101 return -1;
2102 }
2103 if (!self->writeflags[i]) {
2104 PyErr_Format(PyExc_RuntimeError,
2105 "Iterator operand %zd is not writeable", i_orig);
2106 return -1;
2107 }
2108
2109 dataptr = self->dataptrs[i];
2110 dtype = self->dtypes[i];
2111 has_external_loop = NpyIter_HasExternalLoop(self->iter);
2112
2113 if (has_external_loop) {
2114 innerloopsize = *self->innerloopsizeptr;
2115 innerstride = self->innerstrides[i];
2116 }
2117 else {
2118 innerloopsize = 1;
2119 innerstride = 0;
2120 }
2121
2122 /* TODO - there should be a better way than this... */
2123 Py_INCREF(dtype)_Py_INCREF(((PyObject*)(dtype)));
2124 tmp = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, dtype,
2125 1, &innerloopsize,
2126 &innerstride, dataptr,
2127 NPY_ARRAY_WRITEABLE0x0400, NULL((void*)0));
2128 if (tmp == NULL((void*)0)) {
2129 return -1;
2130 }
2131
2132 ret = PyArray_CopyObject(tmp, v);
2133 Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp)));
2134 return ret;
2135}
2136
2137static int
2138npyiter_seq_ass_slice(NewNpyArrayIterObject *self, Py_ssize_t ilow,
2139 Py_ssize_t ihigh, PyObject *v)
2140{
2141 npy_intp nop;
2142 Py_ssize_t i;
2143
2144 if (v == NULL((void*)0)) {
2145 PyErr_SetString(PyExc_TypeError,
2146 "Cannot delete iterator elements");
2147 return -1;
2148 }
2149
2150 if (self->iter == NULL((void*)0) || self->finished) {
2151 PyErr_SetString(PyExc_ValueError,
2152 "Iterator is past the end");
2153 return -1;
2154 }
2155
2156 if (NpyIter_HasDelayedBufAlloc(self->iter)) {
2157 PyErr_SetString(PyExc_ValueError,
2158 "Iterator construction used delayed buffer allocation, "
2159 "and no reset has been done yet");
2160 return -1;
2161 }
2162 nop = NpyIter_GetNOp(self->iter);
2163 if (ilow < 0) {
2164 ilow = 0;
2165 }
2166 else if (ilow >= nop) {
2167 ilow = nop-1;
2168 }
2169 if (ihigh < ilow) {
2170 ihigh = ilow;
2171 }
2172 else if (ihigh > nop) {
2173 ihigh = nop;
2174 }
2175
2176 if (!PySequence_Check(v) || PySequence_Size(v) != ihigh-ilow) {
2177 PyErr_SetString(PyExc_ValueError,
2178 "Wrong size to assign to iterator slice");
2179 return -1;
2180 }
2181
2182 for (i = ilow; i < ihigh ; ++i) {
2183 PyObject *item = PySequence_GetItem(v, i-ilow);
2184 if (item == NULL((void*)0)) {
2185 return -1;
2186 }
2187 if (npyiter_seq_ass_item(self, i, item) < 0) {
2188 Py_DECREF(item)_Py_DECREF(((PyObject*)(item)));
2189 return -1;
2190 }
2191 Py_DECREF(item)_Py_DECREF(((PyObject*)(item)));
2192 }
2193
2194 return 0;
2195}
2196
2197static PyObject *
2198npyiter_subscript(NewNpyArrayIterObject *self, PyObject *op)
2199{
2200 if (self->iter == NULL((void*)0) || self->finished) {
2201 PyErr_SetString(PyExc_ValueError,
2202 "Iterator is past the end");
2203 return NULL((void*)0);
2204 }
2205
2206 if (NpyIter_HasDelayedBufAlloc(self->iter)) {
2207 PyErr_SetString(PyExc_ValueError,
2208 "Iterator construction used delayed buffer allocation, "
2209 "and no reset has been done yet");
2210 return NULL((void*)0);
2211 }
2212
2213 if (PyLong_Check(op)((((((PyObject*)(op))->ob_type))->tp_flags & ((1UL <<
24))) != 0)
||
2214 (PyIndex_Check(op)((op)->ob_type->tp_as_number != ((void*)0) && (
op)->ob_type->tp_as_number->nb_index != ((void*)0))
&& !PySequence_Check(op))) {
2215 npy_intp i = PyArray_PyIntAsIntp(op);
2216 if (error_converting(i)(((i) == -1) && PyErr_Occurred())) {
2217 return NULL((void*)0);
2218 }
2219 return npyiter_seq_item(self, i);
2220 }
2221 else if (PySlice_Check(op)((((PyObject*)(op))->ob_type) == &PySlice_Type)) {
2222 Py_ssize_t istart = 0, iend = 0, istep = 0, islicelength;
2223 if (PySlice_GetIndicesEx(op, NpyIter_GetNOp(self->iter),( PySlice_Unpack((op), (&istart), (&iend), (&istep
)) < 0 ? ((*(&islicelength) = 0), -1) : ((*(&islicelength
) = PySlice_AdjustIndices((NpyIter_GetNOp(self->iter)), (&
istart), (&iend), *(&istep))), 0))
2224 &istart, &iend, &istep, &islicelength)( PySlice_Unpack((op), (&istart), (&iend), (&istep
)) < 0 ? ((*(&islicelength) = 0), -1) : ((*(&islicelength
) = PySlice_AdjustIndices((NpyIter_GetNOp(self->iter)), (&
istart), (&iend), *(&istep))), 0))
< 0) {
2225 return NULL((void*)0);
2226 }
2227 if (istep != 1) {
2228 PyErr_SetString(PyExc_ValueError,
2229 "Iterator slicing only supports a step of 1");
2230 return NULL((void*)0);
2231 }
2232 return npyiter_seq_slice(self, istart, iend);
2233 }
2234
2235 PyErr_SetString(PyExc_TypeError,
2236 "invalid index type for iterator indexing");
2237 return NULL((void*)0);
2238}
2239
2240static int
2241npyiter_ass_subscript(NewNpyArrayIterObject *self, PyObject *op,
2242 PyObject *value)
2243{
2244 if (value == NULL((void*)0)) {
2245 PyErr_SetString(PyExc_TypeError,
2246 "Cannot delete iterator elements");
2247 return -1;
2248 }
2249 if (self->iter == NULL((void*)0) || self->finished) {
2250 PyErr_SetString(PyExc_ValueError,
2251 "Iterator is past the end");
2252 return -1;
2253 }
2254
2255 if (NpyIter_HasDelayedBufAlloc(self->iter)) {
2256 PyErr_SetString(PyExc_ValueError,
2257 "Iterator construction used delayed buffer allocation, "
2258 "and no reset has been done yet");
2259 return -1;
2260 }
2261
2262 if (PyLong_Check(op)((((((PyObject*)(op))->ob_type))->tp_flags & ((1UL <<
24))) != 0)
||
2263 (PyIndex_Check(op)((op)->ob_type->tp_as_number != ((void*)0) && (
op)->ob_type->tp_as_number->nb_index != ((void*)0))
&& !PySequence_Check(op))) {
2264 npy_intp i = PyArray_PyIntAsIntp(op);
2265 if (error_converting(i)(((i) == -1) && PyErr_Occurred())) {
2266 return -1;
2267 }
2268 return npyiter_seq_ass_item(self, i, value);
2269 }
2270 else if (PySlice_Check(op)((((PyObject*)(op))->ob_type) == &PySlice_Type)) {
2271 Py_ssize_t istart = 0, iend = 0, istep = 0, islicelength = 0;
2272 if (PySlice_GetIndicesEx(op, NpyIter_GetNOp(self->iter),( PySlice_Unpack((op), (&istart), (&iend), (&istep
)) < 0 ? ((*(&islicelength) = 0), -1) : ((*(&islicelength
) = PySlice_AdjustIndices((NpyIter_GetNOp(self->iter)), (&
istart), (&iend), *(&istep))), 0))
2273 &istart, &iend, &istep, &islicelength)( PySlice_Unpack((op), (&istart), (&iend), (&istep
)) < 0 ? ((*(&islicelength) = 0), -1) : ((*(&islicelength
) = PySlice_AdjustIndices((NpyIter_GetNOp(self->iter)), (&
istart), (&iend), *(&istep))), 0))
< 0) {
2274 return -1;
2275 }
2276 if (istep != 1) {
2277 PyErr_SetString(PyExc_ValueError,
2278 "Iterator slice assignment only supports a step of 1");
2279 return -1;
2280 }
2281 return npyiter_seq_ass_slice(self, istart, iend, value);
2282 }
2283
2284 PyErr_SetString(PyExc_TypeError,
2285 "invalid index type for iterator indexing");
2286 return -1;
2287}
2288
2289static PyObject *
2290npyiter_enter(NewNpyArrayIterObject *self)
2291{
2292 if (self->iter == NULL((void*)0)) {
2293 PyErr_SetString(PyExc_RuntimeError, "operation on non-initialized iterator");
2294 return NULL((void*)0);
2295 }
2296 Py_INCREF(self)_Py_INCREF(((PyObject*)(self)));
2297 return (PyObject *)self;
2298}
2299
2300static PyObject *
2301npyiter_close(NewNpyArrayIterObject *self)
2302{
2303 NpyIter *iter = self->iter;
2304 int ret;
2305 if (self->iter == NULL((void*)0)) {
2306 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
2307 }
2308 ret = NpyIter_Deallocate(iter);
2309 self->iter = NULL((void*)0);
2310 Py_XDECREF(self->nested_child)_Py_XDECREF(((PyObject*)(self->nested_child)));
2311 self->nested_child = NULL((void*)0);
2312 if (ret != NPY_SUCCEED1) {
2313 return NULL((void*)0);
2314 }
2315 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
2316}
2317
2318static PyObject *
2319npyiter_exit(NewNpyArrayIterObject *self, PyObject *NPY_UNUSED(args)(__NPY_UNUSED_TAGGEDargs) __attribute__ ((__unused__)))
2320{
2321 /* even if called via exception handling, writeback any data */
2322 return npyiter_close(self);
2323}
2324
2325static PyMethodDef npyiter_methods[] = {
2326 {"reset",
2327 (PyCFunction)npyiter_reset,
2328 METH_NOARGS0x0004, NULL((void*)0)},
2329 {"copy",
2330 (PyCFunction)npyiter_copy,
2331 METH_NOARGS0x0004, NULL((void*)0)},
2332 {"__copy__",
2333 (PyCFunction)npyiter_copy,
2334 METH_NOARGS0x0004, NULL((void*)0)},
2335 {"iternext",
2336 (PyCFunction)npyiter_iternext,
2337 METH_NOARGS0x0004, NULL((void*)0)},
2338 {"remove_axis",
2339 (PyCFunction)npyiter_remove_axis,
2340 METH_VARARGS0x0001, NULL((void*)0)},
2341 {"remove_multi_index",
2342 (PyCFunction)npyiter_remove_multi_index,
2343 METH_NOARGS0x0004, NULL((void*)0)},
2344 {"enable_external_loop",
2345 (PyCFunction)npyiter_enable_external_loop,
2346 METH_NOARGS0x0004, NULL((void*)0)},
2347 {"debug_print",
2348 (PyCFunction)npyiter_debug_print,
2349 METH_NOARGS0x0004, NULL((void*)0)},
2350 {"__enter__", (PyCFunction)npyiter_enter,
2351 METH_NOARGS0x0004, NULL((void*)0)},
2352 {"__exit__", (PyCFunction)npyiter_exit,
2353 METH_VARARGS0x0001, NULL((void*)0)},
2354 {"close", (PyCFunction)npyiter_close,
2355 METH_NOARGS0x0004, NULL((void*)0)},
2356 {NULL((void*)0), NULL((void*)0), 0, NULL((void*)0)},
2357};
2358
2359static PyMemberDef npyiter_members[] = {
2360 {NULL((void*)0), 0, 0, 0, NULL((void*)0)},
2361};
2362
2363static PyGetSetDef npyiter_getsets[] = {
2364 {"value",
2365 (getter)npyiter_value_get,
2366 NULL((void*)0), NULL((void*)0), NULL((void*)0)},
2367 {"shape",
2368 (getter)npyiter_shape_get,
2369 NULL((void*)0), NULL((void*)0), NULL((void*)0)},
2370 {"multi_index",
2371 (getter)npyiter_multi_index_get,
2372 (setter)npyiter_multi_index_set,
2373 NULL((void*)0), NULL((void*)0)},
2374 {"index",
2375 (getter)npyiter_index_get,
2376 (setter)npyiter_index_set,
2377 NULL((void*)0), NULL((void*)0)},
2378 {"iterindex",
2379 (getter)npyiter_iterindex_get,
2380 (setter)npyiter_iterindex_set,
2381 NULL((void*)0), NULL((void*)0)},
2382 {"iterrange",
2383 (getter)npyiter_iterrange_get,
2384 (setter)npyiter_iterrange_set,
2385 NULL((void*)0), NULL((void*)0)},
2386 {"operands",
2387 (getter)npyiter_operands_get,
2388 NULL((void*)0), NULL((void*)0), NULL((void*)0)},
2389 {"itviews",
2390 (getter)npyiter_itviews_get,
2391 NULL((void*)0), NULL((void*)0), NULL((void*)0)},
2392 {"has_delayed_bufalloc",
2393 (getter)npyiter_has_delayed_bufalloc_get,
2394 NULL((void*)0), NULL((void*)0), NULL((void*)0)},
2395 {"iterationneedsapi",
2396 (getter)npyiter_iterationneedsapi_get,
2397 NULL((void*)0), NULL((void*)0), NULL((void*)0)},
2398 {"has_multi_index",
2399 (getter)npyiter_has_multi_index_get,
2400 NULL((void*)0), NULL((void*)0), NULL((void*)0)},
2401 {"has_index",
2402 (getter)npyiter_has_index_get,
2403 NULL((void*)0), NULL((void*)0), NULL((void*)0)},
2404 {"dtypes",
2405 (getter)npyiter_dtypes_get,
2406 NULL((void*)0), NULL((void*)0), NULL((void*)0)},
2407 {"ndim",
2408 (getter)npyiter_ndim_get,
2409 NULL((void*)0), NULL((void*)0), NULL((void*)0)},
2410 {"nop",
2411 (getter)npyiter_nop_get,
2412 NULL((void*)0), NULL((void*)0), NULL((void*)0)},
2413 {"itersize",
2414 (getter)npyiter_itersize_get,
2415 NULL((void*)0), NULL((void*)0), NULL((void*)0)},
2416 {"finished",
2417 (getter)npyiter_finished_get,
2418 NULL((void*)0), NULL((void*)0), NULL((void*)0)},
2419
2420 {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)}
2421};
2422
2423NPY_NO_EXPORT__attribute__((visibility("hidden"))) PySequenceMethods npyiter_as_sequence = {
2424 (lenfunc)npyiter_seq_length, /*sq_length*/
2425 (binaryfunc)NULL((void*)0), /*sq_concat*/
2426 (ssizeargfunc)NULL((void*)0), /*sq_repeat*/
2427 (ssizeargfunc)npyiter_seq_item, /*sq_item*/
2428 (ssizessizeargfunc)NULL((void*)0), /*sq_slice*/
2429 (ssizeobjargproc)npyiter_seq_ass_item, /*sq_ass_item*/
2430 (ssizessizeobjargproc)NULL((void*)0), /*sq_ass_slice*/
2431 (objobjproc)NULL((void*)0), /*sq_contains */
2432 (binaryfunc)NULL((void*)0), /*sq_inplace_concat */
2433 (ssizeargfunc)NULL((void*)0), /*sq_inplace_repeat */
2434};
2435
2436NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyMappingMethods npyiter_as_mapping = {
2437 (lenfunc)npyiter_seq_length, /*mp_length*/
2438 (binaryfunc)npyiter_subscript, /*mp_subscript*/
2439 (objobjargproc)npyiter_ass_subscript, /*mp_ass_subscript*/
2440};
2441
2442NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyTypeObject NpyIter_Type = {
2443 PyVarObject_HEAD_INIT(NULL, 0){ { 1, ((void*)0) }, 0 },
2444 .tp_name = "numpy.nditer",
2445 .tp_basicsize = sizeof(NewNpyArrayIterObject),
2446 .tp_dealloc = (destructor)npyiter_dealloc,
2447 .tp_as_sequence = &npyiter_as_sequence,
2448 .tp_as_mapping = &npyiter_as_mapping,
2449 .tp_flags = Py_TPFLAGS_DEFAULT( 0 | (1UL << 18) | 0),
2450 .tp_iternext = (iternextfunc)npyiter_next,
2451 .tp_methods = npyiter_methods,
2452 .tp_members = npyiter_members,
2453 .tp_getset = npyiter_getsets,
2454 .tp_init = (initproc)npyiter_init,
2455 .tp_new = npyiter_new,
2456};

/opt/pyrefcon/lib/pyrefcon/models/models/PySequence_GetItem.model

1#ifndef PySequence_GetItem
2struct _object;
3typedef struct _object PyObject;
4PyObject* clang_analyzer_PyObject_New_Reference();
5PyObject* PySequence_GetItem(PyObject *o, Py_ssize_t i) {
6 return clang_analyzer_PyObject_New_Reference();
13
Setting reference count to 1
7}
8#else
9#warning "API PySequence_GetItem is defined as a macro."
10#endif