Bug Summary

File:numpy/core/src/multiarray/arrayfunction_override.c
Warning:line 407, column 16
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 arrayfunction_override.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/arrayfunction_override.c

numpy/core/src/multiarray/arrayfunction_override.c

1#define NPY_NO_DEPRECATED_API0x0000000E NPY_API_VERSION0x0000000E
2#define _MULTIARRAYMODULE
3
4#include "npy_pycompat.h"
5#include "get_attr_string.h"
6#include "npy_import.h"
7#include "multiarraymodule.h"
8
9
10/* Return the ndarray.__array_function__ method. */
11static PyObject *
12get_ndarray_array_function(void)
13{
14 PyObject* method = PyObject_GetAttrString((PyObject *)&PyArray_Type,
15 "__array_function__");
16 assert(method != NULL)((void) (0));
17 return method;
18}
19
20
21/*
22 * Get an object's __array_function__ method in the fastest way possible.
23 * Never raises an exception. Returns NULL if the method doesn't exist.
24 */
25static PyObject *
26get_array_function(PyObject *obj)
27{
28 static PyObject *ndarray_array_function = NULL((void*)0);
29
30 if (ndarray_array_function == NULL((void*)0)) {
31 ndarray_array_function = get_ndarray_array_function();
32 }
33
34 /* Fast return for ndarray */
35 if (PyArray_CheckExact(obj)(((PyObject*)(obj))->ob_type == &PyArray_Type)) {
36 Py_INCREF(ndarray_array_function)_Py_INCREF(((PyObject*)(ndarray_array_function)));
37 return ndarray_array_function;
38 }
39
40 PyObject *array_function = PyArray_LookupSpecial(obj, "__array_function__");
41 if (array_function == NULL((void*)0) && PyErr_Occurred()) {
42 PyErr_Clear(); /* TODO[gh-14801]: propagate crashes during attribute access? */
43 }
44
45 return array_function;
46}
47
48
49/*
50 * Like list.insert(), but for C arrays of PyObject*. Skips error checking.
51 */
52static void
53pyobject_array_insert(PyObject **array, int length, int index, PyObject *item)
54{
55 for (int j = length; j > index; j--) {
56 array[j] = array[j - 1];
57 }
58 array[index] = item;
59}
60
61
62/*
63 * Collects arguments with __array_function__ and their corresponding methods
64 * in the order in which they should be tried (i.e., skipping redundant types).
65 * `relevant_args` is expected to have been produced by PySequence_Fast.
66 * Returns the number of arguments, or -1 on failure.
67 */
68static int
69get_implementing_args_and_methods(PyObject *relevant_args,
70 PyObject **implementing_args,
71 PyObject **methods)
72{
73 int num_implementing_args = 0;
74
75 PyObject **items = PySequence_Fast_ITEMS(relevant_args)(((((((PyObject*)(relevant_args))->ob_type))->tp_flags &
((1UL << 25))) != 0) ? ((PyListObject *)(relevant_args
))->ob_item : ((PyTupleObject *)(relevant_args))->ob_item
)
;
76 Py_ssize_t length = PySequence_Fast_GET_SIZE(relevant_args)(((((((PyObject*)(relevant_args))->ob_type))->tp_flags &
((1UL << 25))) != 0) ? (((void) (0)), (((PyVarObject*)
(relevant_args))->ob_size)) : (((PyVarObject*)((((void) (0
)), (PyTupleObject *)(relevant_args))))->ob_size))
;
77
78 for (Py_ssize_t i = 0; i < length; i++) {
79 int new_class = 1;
80 PyObject *argument = items[i];
81
82 /* Have we seen this type before? */
83 for (int j = 0; j < num_implementing_args; j++) {
84 if (Py_TYPE(argument)(((PyObject*)(argument))->ob_type) == Py_TYPE(implementing_args[j])(((PyObject*)(implementing_args[j]))->ob_type)) {
85 new_class = 0;
86 break;
87 }
88 }
89 if (new_class) {
90 PyObject *method = get_array_function(argument);
91
92 if (method != NULL((void*)0)) {
93 int arg_index;
94
95 if (num_implementing_args >= NPY_MAXARGS32) {
96 PyErr_Format(
97 PyExc_TypeError,
98 "maximum number (%d) of distinct argument types " \
99 "implementing __array_function__ exceeded",
100 NPY_MAXARGS32);
101 Py_DECREF(method)_Py_DECREF(((PyObject*)(method)));
102 goto fail;
103 }
104
105 /* "subclasses before superclasses, otherwise left to right" */
106 arg_index = num_implementing_args;
107 for (int j = 0; j < num_implementing_args; j++) {
108 PyObject *other_type;
109 other_type = (PyObject *)Py_TYPE(implementing_args[j])(((PyObject*)(implementing_args[j]))->ob_type);
110 if (PyObject_IsInstance(argument, other_type)) {
111 arg_index = j;
112 break;
113 }
114 }
115 Py_INCREF(argument)_Py_INCREF(((PyObject*)(argument)));
116 pyobject_array_insert(implementing_args, num_implementing_args,
117 arg_index, argument);
118 pyobject_array_insert(methods, num_implementing_args,
119 arg_index, method);
120 ++num_implementing_args;
121 }
122 }
123 }
124 return num_implementing_args;
125
126fail:
127 for (int j = 0; j < num_implementing_args; j++) {
128 Py_DECREF(implementing_args[j])_Py_DECREF(((PyObject*)(implementing_args[j])));
129 Py_DECREF(methods[j])_Py_DECREF(((PyObject*)(methods[j])));
130 }
131 return -1;
132}
133
134
135/*
136 * Is this object ndarray.__array_function__?
137 */
138static int
139is_default_array_function(PyObject *obj)
140{
141 static PyObject *ndarray_array_function = NULL((void*)0);
142
143 if (ndarray_array_function == NULL((void*)0)) {
144 ndarray_array_function = get_ndarray_array_function();
145 }
146 return obj == ndarray_array_function;
147}
148
149
150/*
151 * Core implementation of ndarray.__array_function__. This is exposed
152 * separately so we can avoid the overhead of a Python method call from
153 * within `implement_array_function`.
154 */
155NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject *
156array_function_method_impl(PyObject *func, PyObject *types, PyObject *args,
157 PyObject *kwargs)
158{
159 PyObject **items = PySequence_Fast_ITEMS(types)(((((((PyObject*)(types))->ob_type))->tp_flags & ((
1UL << 25))) != 0) ? ((PyListObject *)(types))->ob_item
: ((PyTupleObject *)(types))->ob_item)
;
160 Py_ssize_t length = PySequence_Fast_GET_SIZE(types)(((((((PyObject*)(types))->ob_type))->tp_flags & ((
1UL << 25))) != 0) ? (((void) (0)), (((PyVarObject*)(types
))->ob_size)) : (((PyVarObject*)((((void) (0)), (PyTupleObject
*)(types))))->ob_size))
;
161
162 for (Py_ssize_t j = 0; j < length; j++) {
163 int is_subclass = PyObject_IsSubclass(
164 items[j], (PyObject *)&PyArray_Type);
165 if (is_subclass == -1) {
166 return NULL((void*)0);
167 }
168 if (!is_subclass) {
169 Py_INCREF(Py_NotImplemented)_Py_INCREF(((PyObject*)((&_Py_NotImplementedStruct))));
170 return Py_NotImplemented(&_Py_NotImplementedStruct);
171 }
172 }
173
174 PyObject *implementation = PyObject_GetAttr(func, npy_ma_str_implementation);
175 if (implementation == NULL((void*)0)) {
176 return NULL((void*)0);
177 }
178 PyObject *result = PyObject_Call(implementation, args, kwargs);
179 Py_DECREF(implementation)_Py_DECREF(((PyObject*)(implementation)));
180 return result;
181}
182
183
184/*
185 * Calls __array_function__ on the provided argument, with a fast-path for
186 * ndarray.
187 */
188static PyObject *
189call_array_function(PyObject* argument, PyObject* method,
190 PyObject* public_api, PyObject* types,
191 PyObject* args, PyObject* kwargs)
192{
193 if (is_default_array_function(method)) {
194 return array_function_method_impl(public_api, types, args, kwargs);
195 }
196 else {
197 return PyObject_CallFunctionObjArgs(
198 method, argument, public_api, types, args, kwargs, NULL((void*)0));
199 }
200}
201
202
203/**
204 * Internal handler for the array-function dispatching. The helper returns
205 * either the result, or NotImplemented (as a borrowed reference).
206 *
207 * @param public_api The public API symbol used for dispatching
208 * @param relevant_args Arguments which may implement __array_function__
209 * @param args Original arguments
210 * @param kwargs Original keyword arguments
211 *
212 * @returns The result of the dispatched version, or a borrowed reference
213 * to NotImplemented to indicate the default implementation should
214 * be used.
215 */
216static PyObject *
217array_implement_array_function_internal(
218 PyObject *public_api, PyObject *relevant_args,
219 PyObject *args, PyObject *kwargs)
220{
221 PyObject *implementing_args[NPY_MAXARGS32];
222 PyObject *array_function_methods[NPY_MAXARGS32];
223 PyObject *types = NULL((void*)0);
224
225 PyObject *result = NULL((void*)0);
226
227 static PyObject *errmsg_formatter = NULL((void*)0);
228
229 relevant_args = PySequence_Fast(
230 relevant_args,
231 "dispatcher for __array_function__ did not return an iterable");
232 if (relevant_args == NULL((void*)0)) {
233 return NULL((void*)0);
234 }
235
236 /* Collect __array_function__ implementations */
237 int num_implementing_args = get_implementing_args_and_methods(
238 relevant_args, implementing_args, array_function_methods);
239 if (num_implementing_args == -1) {
240 goto cleanup;
241 }
242
243 /*
244 * Handle the typical case of no overrides. This is merely an optimization
245 * if some arguments are ndarray objects, but is also necessary if no
246 * arguments implement __array_function__ at all (e.g., if they are all
247 * built-in types).
248 */
249 int any_overrides = 0;
250 for (int j = 0; j < num_implementing_args; j++) {
251 if (!is_default_array_function(array_function_methods[j])) {
252 any_overrides = 1;
253 break;
254 }
255 }
256 if (!any_overrides) {
257 /*
258 * When the default implementation should be called, return
259 * `Py_NotImplemented` to indicate this.
260 */
261 result = Py_NotImplemented(&_Py_NotImplementedStruct);
262 goto cleanup;
263 }
264
265 /*
266 * Create a Python object for types.
267 * We use a tuple, because it's the fastest Python collection to create
268 * and has the bonus of being immutable.
269 */
270 types = PyTuple_New(num_implementing_args);
271 if (types == NULL((void*)0)) {
272 goto cleanup;
273 }
274 for (int j = 0; j < num_implementing_args; j++) {
275 PyObject *arg_type = (PyObject *)Py_TYPE(implementing_args[j])(((PyObject*)(implementing_args[j]))->ob_type);
276 Py_INCREF(arg_type)_Py_INCREF(((PyObject*)(arg_type)));
277 PyTuple_SET_ITEM(types, j, arg_type)PyTuple_SetItem(types, j, arg_type);
278 }
279
280 /* Call __array_function__ methods */
281 for (int j = 0; j < num_implementing_args; j++) {
282 PyObject *argument = implementing_args[j];
283 PyObject *method = array_function_methods[j];
284
285 /*
286 * We use `public_api` instead of `implementation` here so
287 * __array_function__ implementations can do equality/identity
288 * comparisons.
289 */
290 result = call_array_function(
291 argument, method, public_api, types, args, kwargs);
292
293 if (result == Py_NotImplemented(&_Py_NotImplementedStruct)) {
294 /* Try the next one */
295 Py_DECREF(result)_Py_DECREF(((PyObject*)(result)));
296 result = NULL((void*)0);
297 }
298 else {
299 /* Either a good result, or an exception was raised. */
300 goto cleanup;
301 }
302 }
303
304 /* No acceptable override found, raise TypeError. */
305 npy_cache_import("numpy.core._internal",
306 "array_function_errmsg_formatter",
307 &errmsg_formatter);
308 if (errmsg_formatter != NULL((void*)0)) {
309 PyObject *errmsg = PyObject_CallFunctionObjArgs(
310 errmsg_formatter, public_api, types, NULL((void*)0));
311 if (errmsg != NULL((void*)0)) {
312 PyErr_SetObject(PyExc_TypeError, errmsg);
313 Py_DECREF(errmsg)_Py_DECREF(((PyObject*)(errmsg)));
314 }
315 }
316
317cleanup:
318 for (int j = 0; j < num_implementing_args; j++) {
319 Py_DECREF(implementing_args[j])_Py_DECREF(((PyObject*)(implementing_args[j])));
320 Py_DECREF(array_function_methods[j])_Py_DECREF(((PyObject*)(array_function_methods[j])));
321 }
322 Py_XDECREF(types)_Py_XDECREF(((PyObject*)(types)));
323 Py_DECREF(relevant_args)_Py_DECREF(((PyObject*)(relevant_args)));
324 return result;
325}
326
327
328/*
329 * Implements the __array_function__ protocol for a Python function, as described in
330 * in NEP-18. See numpy.core.overrides for a full docstring.
331 */
332NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject *
333array_implement_array_function(
334 PyObject *NPY_UNUSED(dummy)(__NPY_UNUSED_TAGGEDdummy) __attribute__ ((__unused__)), PyObject *positional_args)
335{
336 PyObject *implementation, *public_api, *relevant_args, *args, *kwargs;
337
338 if (!PyArg_UnpackTuple(
339 positional_args, "implement_array_function", 5, 5,
340 &implementation, &public_api, &relevant_args, &args, &kwargs)) {
341 return NULL((void*)0);
342 }
343
344 /*
345 * Remove `like=` kwarg, which is NumPy-exclusive and thus not present
346 * in downstream libraries. If `like=` is specified but doesn't
347 * implement `__array_function__`, raise a `TypeError`.
348 */
349 if (kwargs != NULL((void*)0) && PyDict_Contains(kwargs, npy_ma_str_like)) {
350 PyObject *like_arg = PyDict_GetItem(kwargs, npy_ma_str_like);
351 if (like_arg != NULL((void*)0)) {
352 PyObject *tmp_has_override = get_array_function(like_arg);
353 if (tmp_has_override == NULL((void*)0)) {
354 return PyErr_Format(PyExc_TypeError,
355 "The `like` argument must be an array-like that "
356 "implements the `__array_function__` protocol.");
357 }
358 Py_DECREF(tmp_has_override)_Py_DECREF(((PyObject*)(tmp_has_override)));
359 PyDict_DelItem(kwargs, npy_ma_str_like);
360 }
361 }
362
363 PyObject *res = array_implement_array_function_internal(
364 public_api, relevant_args, args, kwargs);
365
366 if (res == Py_NotImplemented(&_Py_NotImplementedStruct)) {
367 return PyObject_Call(implementation, args, kwargs);
368 }
369 return res;
370}
371
372/*
373 * Implements the __array_function__ protocol for C array creation functions
374 * only. Added as an extension to NEP-18 in an effort to bring NEP-35 to
375 * life with minimal dispatch overhead.
376 *
377 * The caller must ensure that `like != NULL`.
378 */
379NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject *
380array_implement_c_array_function_creation(
381 const char *function_name, PyObject *like,
382 PyObject *args, PyObject *kwargs,
383 PyObject *const *fast_args, Py_ssize_t len_args, PyObject *kwnames)
384{
385 PyObject *relevant_args = NULL((void*)0);
386 PyObject *numpy_module = NULL((void*)0);
387 PyObject *public_api = NULL((void*)0);
388 PyObject *result = NULL((void*)0);
389
390 /* If `like` doesn't implement `__array_function__`, raise a `TypeError` */
391 PyObject *tmp_has_override = get_array_function(like);
392 if (tmp_has_override
0.1
'tmp_has_override' is not equal to NULL
0.1
'tmp_has_override' is not equal to NULL
== NULL((void*)0)) {
1
Taking false branch
393 return PyErr_Format(PyExc_TypeError,
394 "The `like` argument must be an array-like that "
395 "implements the `__array_function__` protocol.");
396 }
397 Py_DECREF(tmp_has_override)_Py_DECREF(((PyObject*)(tmp_has_override)));
398
399 if (fast_args != NULL((void*)0)) {
2
Assuming 'fast_args' is not equal to NULL
3
Taking true branch
400 /*
401 * Convert from vectorcall convention, since the protocol requires
402 * the normal convention. We have to do this late to ensure the
403 * normal path where NotImplemented is returned is fast.
404 */
405 assert(args == NULL)((void) (0));
406 assert(kwargs == NULL)((void) (0));
407 args = PyTuple_New(len_args);
4
Calling 'PyTuple_New'
6
Returning from 'PyTuple_New'
17
PyObject ownership leak with reference count of 1
408 if (args == NULL((void*)0)) {
7
Assuming 'args' is not equal to NULL
8
Taking false branch
409 return NULL((void*)0);
410 }
411 for (Py_ssize_t i = 0; i < len_args; i++) {
9
Assuming 'i' is >= 'len_args'
10
Loop condition is false. Execution continues on line 415
412 Py_INCREF(fast_args[i])_Py_INCREF(((PyObject*)(fast_args[i])));
413 PyTuple_SET_ITEM(args, i, fast_args[i])PyTuple_SetItem(args, i, fast_args[i]);
414 }
415 if (kwnames != NULL((void*)0)) {
11
Assuming 'kwnames' is equal to NULL
12
Taking false branch
416 kwargs = PyDict_New();
417 if (kwargs == NULL((void*)0)) {
418 Py_DECREF(args)_Py_DECREF(((PyObject*)(args)));
419 return NULL((void*)0);
420 }
421 Py_ssize_t nkwargs = PyTuple_GET_SIZE(kwnames)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(kwnames))))
->ob_size)
;
422 for (Py_ssize_t i = 0; i < nkwargs; i++) {
423 PyObject *key = PyTuple_GET_ITEM(kwnames, i)((((void) (0)), (PyTupleObject *)(kwnames))->ob_item[i]);
424 PyObject *value = fast_args[i+len_args];
425 if (PyDict_SetItem(kwargs, key, value) < 0) {
426 Py_DECREF(args)_Py_DECREF(((PyObject*)(args)));
427 Py_DECREF(kwargs)_Py_DECREF(((PyObject*)(kwargs)));
428 return NULL((void*)0);
429 }
430 }
431 }
432 }
433
434 relevant_args = PyTuple_Pack(1, like);
435 if (relevant_args == NULL((void*)0)) {
13
Assuming 'relevant_args' is equal to NULL
14
Taking true branch
436 goto finish;
15
Control jumps to line 463
437 }
438 /* The like argument must be present in the keyword arguments, remove it */
439 if (PyDict_DelItem(kwargs, npy_ma_str_like) < 0) {
440 goto finish;
441 }
442
443 numpy_module = PyImport_Import(npy_ma_str_numpy);
444 if (numpy_module == NULL((void*)0)) {
445 goto finish;
446 }
447
448 public_api = PyObject_GetAttrString(numpy_module, function_name);
449 Py_DECREF(numpy_module)_Py_DECREF(((PyObject*)(numpy_module)));
450 if (public_api == NULL((void*)0)) {
451 goto finish;
452 }
453 if (!PyCallable_Check(public_api)) {
454 PyErr_Format(PyExc_RuntimeError,
455 "numpy.%s is not callable.", function_name);
456 goto finish;
457 }
458
459 result = array_implement_array_function_internal(
460 public_api, relevant_args, args, kwargs);
461
462 finish:
463 if (kwnames
15.1
'kwnames' is equal to NULL
15.1
'kwnames' is equal to NULL
!= NULL((void*)0)) {
16
Taking false branch
464 /* args and kwargs were converted from vectorcall convention */
465 Py_XDECREF(args)_Py_XDECREF(((PyObject*)(args)));
466 Py_XDECREF(kwargs)_Py_XDECREF(((PyObject*)(kwargs)));
467 }
468 Py_XDECREF(relevant_args)_Py_XDECREF(((PyObject*)(relevant_args)));
469 Py_XDECREF(public_api)_Py_XDECREF(((PyObject*)(public_api)));
470 return result;
471}
472
473
474/*
475 * Python wrapper for get_implementing_args_and_methods, for testing purposes.
476 */
477NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject *
478array__get_implementing_args(
479 PyObject *NPY_UNUSED(dummy)(__NPY_UNUSED_TAGGEDdummy) __attribute__ ((__unused__)), PyObject *positional_args)
480{
481 PyObject *relevant_args;
482 PyObject *implementing_args[NPY_MAXARGS32];
483 PyObject *array_function_methods[NPY_MAXARGS32];
484 PyObject *result = NULL((void*)0);
485
486 if (!PyArg_ParseTuple(positional_args, "O:array__get_implementing_args",
487 &relevant_args)) {
488 return NULL((void*)0);
489 }
490
491 relevant_args = PySequence_Fast(
492 relevant_args,
493 "dispatcher for __array_function__ did not return an iterable");
494 if (relevant_args == NULL((void*)0)) {
495 return NULL((void*)0);
496 }
497
498 int num_implementing_args = get_implementing_args_and_methods(
499 relevant_args, implementing_args, array_function_methods);
500 if (num_implementing_args == -1) {
501 goto cleanup;
502 }
503
504 /* create a Python object for implementing_args */
505 result = PyList_New(num_implementing_args);
506 if (result == NULL((void*)0)) {
507 goto cleanup;
508 }
509 for (int j = 0; j < num_implementing_args; j++) {
510 PyObject *argument = implementing_args[j];
511 Py_INCREF(argument)_Py_INCREF(((PyObject*)(argument)));
512 PyList_SET_ITEM(result, j, argument)PyList_SetItem(result, j, argument);
513 }
514
515cleanup:
516 for (int j = 0; j < num_implementing_args; j++) {
517 Py_DECREF(implementing_args[j])_Py_DECREF(((PyObject*)(implementing_args[j])));
518 Py_DECREF(array_function_methods[j])_Py_DECREF(((PyObject*)(array_function_methods[j])));
519 }
520 Py_DECREF(relevant_args)_Py_DECREF(((PyObject*)(relevant_args)));
521 return result;
522}

/opt/pyrefcon/lib/pyrefcon/models/models/PyTuple_New.model

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