Bug Summary

File:numpy/core/src/multiarray/usertypes.c
Warning:line 296, column 11
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 usertypes.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/usertypes.c

numpy/core/src/multiarray/usertypes.c

1/*
2 Provide multidimensional arrays as a basic object type in python.
3
4 Based on Original Numeric implementation
5 Copyright (c) 1995, 1996, 1997 Jim Hugunin, hugunin@mit.edu
6
7 with contributions from many Numeric Python developers 1995-2004
8
9 Heavily modified in 2005 with inspiration from Numarray
10
11 by
12
13 Travis Oliphant, oliphant@ee.byu.edu
14 Brigham Young University
15
16
17maintainer email: oliphant.travis@ieee.org
18
19 Numarray design (which provided guidance) by
20 Space Science Telescope Institute
21 (J. Todd Miller, Perry Greenfield, Rick White)
22*/
23#define PY_SSIZE_T_CLEAN
24#include <Python.h>
25#include "structmember.h"
26
27/*#include <stdio.h>*/
28#define NPY_NO_DEPRECATED_API0x0000000E NPY_API_VERSION0x0000000E
29#define _MULTIARRAYMODULE
30#include "numpy/arrayobject.h"
31#include "numpy/arrayscalars.h"
32
33#include "npy_config.h"
34
35#include "common.h"
36
37#include "npy_pycompat.h"
38
39#include "usertypes.h"
40#include "dtypemeta.h"
41#include "scalartypes.h"
42#include "array_method.h"
43#include "convert_datatype.h"
44#include "legacy_dtype_implementation.h"
45
46
47NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyArray_Descr **userdescrs=NULL((void*)0);
48
49static int
50_append_new(int **p_types, int insert)
51{
52 int n = 0;
53 int *newtypes;
54 int *types = *p_types;
55
56 while (types[n] != NPY_NOTYPE) {
57 n++;
58 }
59 newtypes = (int *)realloc(types, (n + 2)*sizeof(int));
60 if (newtypes == NULL((void*)0)) {
61 PyErr_NoMemory();
62 return -1;
63 }
64 newtypes[n] = insert;
65 newtypes[n + 1] = NPY_NOTYPE;
66
67 /* Replace the passed-in pointer */
68 *p_types = newtypes;
69 return 0;
70}
71
72static npy_bool
73_default_nonzero(void *ip, void *arr)
74{
75 int elsize = PyArray_ITEMSIZE(arr);
76 char *ptr = ip;
77 while (elsize--) {
78 if (*ptr++ != 0) {
79 return NPY_TRUE1;
80 }
81 }
82 return NPY_FALSE0;
83}
84
85static void
86_default_copyswapn(void *dst, npy_intp dstride, void *src,
87 npy_intp sstride, npy_intp n, int swap, void *arr)
88{
89 npy_intp i;
90 PyArray_CopySwapFunc *copyswap;
91 char *dstptr = dst;
92 char *srcptr = src;
93
94 copyswap = PyArray_DESCR(arr)->f->copyswap;
95
96 for (i = 0; i < n; i++) {
97 copyswap(dstptr, srcptr, swap, arr);
98 dstptr += dstride;
99 srcptr += sstride;
100 }
101}
102
103/*NUMPY_API
104 Initialize arrfuncs to NULL
105*/
106NPY_NO_EXPORT__attribute__((visibility("hidden"))) void
107PyArray_InitArrFuncs(PyArray_ArrFuncs *f)
108{
109 int i;
110
111 for(i = 0; i < NPY_NTYPES_ABI_COMPATIBLE; i++) {
112 f->cast[i] = NULL((void*)0);
113 }
114 f->getitem = NULL((void*)0);
115 f->setitem = NULL((void*)0);
116 f->copyswapn = NULL((void*)0);
117 f->copyswap = NULL((void*)0);
118 f->compare = NULL((void*)0);
119 f->argmax = NULL((void*)0);
120 f->argmin = NULL((void*)0);
121 f->dotfunc = NULL((void*)0);
122 f->scanfunc = NULL((void*)0);
123 f->fromstr = NULL((void*)0);
124 f->nonzero = NULL((void*)0);
125 f->fill = NULL((void*)0);
126 f->fillwithscalar = NULL((void*)0);
127 for(i = 0; i < NPY_NSORTS(NPY_STABLESORT + 1); i++) {
128 f->sort[i] = NULL((void*)0);
129 f->argsort[i] = NULL((void*)0);
130 }
131 f->castdict = NULL((void*)0);
132 f->scalarkind = NULL((void*)0);
133 f->cancastscalarkindto = NULL((void*)0);
134 f->cancastto = NULL((void*)0);
135 f->fastclip = NULL((void*)0);
136 f->fastputmask = NULL((void*)0);
137 f->fasttake = NULL((void*)0);
138}
139
140
141static int
142test_deprecated_arrfuncs_members(PyArray_ArrFuncs *f) {
143 /* NumPy 1.19, 2020-01-15 */
144 if (f->fastputmask != NULL((void*)0)) {
145 if (DEPRECATE(PyErr_WarnEx(PyExc_DeprecationWarning,"The ->f->fastputmask member of custom dtypes is ignored; "
"setting it may be an error in the future.\n" "The custom dtype you are using must be revised, but "
"results will not be affected.",1)
146 "The ->f->fastputmask member of custom dtypes is ignored; "PyErr_WarnEx(PyExc_DeprecationWarning,"The ->f->fastputmask member of custom dtypes is ignored; "
"setting it may be an error in the future.\n" "The custom dtype you are using must be revised, but "
"results will not be affected.",1)
147 "setting it may be an error in the future.\n"PyErr_WarnEx(PyExc_DeprecationWarning,"The ->f->fastputmask member of custom dtypes is ignored; "
"setting it may be an error in the future.\n" "The custom dtype you are using must be revised, but "
"results will not be affected.",1)
148 "The custom dtype you are using must be revised, but "PyErr_WarnEx(PyExc_DeprecationWarning,"The ->f->fastputmask member of custom dtypes is ignored; "
"setting it may be an error in the future.\n" "The custom dtype you are using must be revised, but "
"results will not be affected.",1)
149 "results will not be affected.")PyErr_WarnEx(PyExc_DeprecationWarning,"The ->f->fastputmask member of custom dtypes is ignored; "
"setting it may be an error in the future.\n" "The custom dtype you are using must be revised, but "
"results will not be affected.",1)
< 0) {
150 return -1;
151 }
152 }
153 /* NumPy 1.19, 2020-01-15 */
154 if (f->fasttake != NULL((void*)0)) {
155 if (DEPRECATE(PyErr_WarnEx(PyExc_DeprecationWarning,"The ->f->fastputmask member of custom dtypes is ignored; "
"setting it may be an error in the future.\n" "The custom dtype you are using must be revised, but "
"results will not be affected.",1)
156 "The ->f->fastputmask member of custom dtypes is ignored; "PyErr_WarnEx(PyExc_DeprecationWarning,"The ->f->fastputmask member of custom dtypes is ignored; "
"setting it may be an error in the future.\n" "The custom dtype you are using must be revised, but "
"results will not be affected.",1)
157 "setting it may be an error in the future.\n"PyErr_WarnEx(PyExc_DeprecationWarning,"The ->f->fastputmask member of custom dtypes is ignored; "
"setting it may be an error in the future.\n" "The custom dtype you are using must be revised, but "
"results will not be affected.",1)
158 "The custom dtype you are using must be revised, but "PyErr_WarnEx(PyExc_DeprecationWarning,"The ->f->fastputmask member of custom dtypes is ignored; "
"setting it may be an error in the future.\n" "The custom dtype you are using must be revised, but "
"results will not be affected.",1)
159 "results will not be affected.")PyErr_WarnEx(PyExc_DeprecationWarning,"The ->f->fastputmask member of custom dtypes is ignored; "
"setting it may be an error in the future.\n" "The custom dtype you are using must be revised, but "
"results will not be affected.",1)
< 0) {
160 return -1;
161 }
162 }
163 /* NumPy 1.19, 2020-01-15 */
164 if (f->fastclip != NULL((void*)0)) {
165 /* fastclip was already deprecated at execution time in 1.17. */
166 if (DEPRECATE(PyErr_WarnEx(PyExc_DeprecationWarning,"The ->f->fastclip member of custom dtypes is deprecated; "
"setting it will be an error in the future.\n" "The custom dtype you are using must be changed to use "
"PyUFunc_RegisterLoopForDescr to attach a custom loop to " "np.core.umath.clip, np.minimum, and np.maximum"
,1)
167 "The ->f->fastclip member of custom dtypes is deprecated; "PyErr_WarnEx(PyExc_DeprecationWarning,"The ->f->fastclip member of custom dtypes is deprecated; "
"setting it will be an error in the future.\n" "The custom dtype you are using must be changed to use "
"PyUFunc_RegisterLoopForDescr to attach a custom loop to " "np.core.umath.clip, np.minimum, and np.maximum"
,1)
168 "setting it will be an error in the future.\n"PyErr_WarnEx(PyExc_DeprecationWarning,"The ->f->fastclip member of custom dtypes is deprecated; "
"setting it will be an error in the future.\n" "The custom dtype you are using must be changed to use "
"PyUFunc_RegisterLoopForDescr to attach a custom loop to " "np.core.umath.clip, np.minimum, and np.maximum"
,1)
169 "The custom dtype you are using must be changed to use "PyErr_WarnEx(PyExc_DeprecationWarning,"The ->f->fastclip member of custom dtypes is deprecated; "
"setting it will be an error in the future.\n" "The custom dtype you are using must be changed to use "
"PyUFunc_RegisterLoopForDescr to attach a custom loop to " "np.core.umath.clip, np.minimum, and np.maximum"
,1)
170 "PyUFunc_RegisterLoopForDescr to attach a custom loop to "PyErr_WarnEx(PyExc_DeprecationWarning,"The ->f->fastclip member of custom dtypes is deprecated; "
"setting it will be an error in the future.\n" "The custom dtype you are using must be changed to use "
"PyUFunc_RegisterLoopForDescr to attach a custom loop to " "np.core.umath.clip, np.minimum, and np.maximum"
,1)
171 "np.core.umath.clip, np.minimum, and np.maximum")PyErr_WarnEx(PyExc_DeprecationWarning,"The ->f->fastclip member of custom dtypes is deprecated; "
"setting it will be an error in the future.\n" "The custom dtype you are using must be changed to use "
"PyUFunc_RegisterLoopForDescr to attach a custom loop to " "np.core.umath.clip, np.minimum, and np.maximum"
,1)
< 0) {
172 return -1;
173 }
174 }
175 return 0;
176}
177
178/*
179 returns typenum to associate with this type >=NPY_USERDEF.
180 needs the userdecrs table and PyArray_NUMUSER variables
181 defined in arraytypes.inc
182*/
183/*NUMPY_API
184 Register Data type
185 Does not change the reference count of descr
186*/
187NPY_NO_EXPORT__attribute__((visibility("hidden"))) int
188PyArray_RegisterDataType(PyArray_Descr *descr)
189{
190 PyArray_Descr *descr2;
191 int typenum;
192 int i;
193 PyArray_ArrFuncs *f;
194
195 /* See if this type is already registered */
196 for (i = 0; i < NPY_NUMUSERTYPES; i++) {
197 descr2 = userdescrs[i];
198 if (descr2 == descr) {
199 return descr->type_num;
200 }
201 }
202 typenum = NPY_USERDEF + NPY_NUMUSERTYPES;
203 descr->type_num = -1;
204 if (PyDataType_ISUNSIZED(descr)((descr)->elsize == 0 && !(((PyArray_Descr *)(descr
))->names != ((void*)0)))
) {
205 PyErr_SetString(PyExc_ValueError, "cannot register a" \
206 "flexible data-type");
207 return -1;
208 }
209 f = descr->f;
210 if (f->nonzero == NULL((void*)0)) {
211 f->nonzero = _default_nonzero;
212 }
213 if (f->copyswapn == NULL((void*)0)) {
214 f->copyswapn = _default_copyswapn;
215 }
216 if (f->copyswap == NULL((void*)0) || f->getitem == NULL((void*)0) ||
217 f->setitem == NULL((void*)0)) {
218 PyErr_SetString(PyExc_ValueError, "a required array function" \
219 " is missing.");
220 return -1;
221 }
222 if (descr->typeobj == NULL((void*)0)) {
223 PyErr_SetString(PyExc_ValueError, "missing typeobject");
224 return -1;
225 }
226 if (descr->flags & (NPY_ITEM_IS_POINTER0x04 | NPY_ITEM_REFCOUNT0x01)) {
227 /*
228 * User dtype can't actually do reference counting, however, there
229 * are existing hacks (e.g. xpress), which use a structured one:
230 * dtype((xpress.var, [('variable', 'O')]))
231 * so we have to support this. But such a structure must be constant
232 * (i.e. fixed at registration time, this is the case for `xpress`).
233 */
234 if (descr->names == NULL((void*)0) || descr->fields == NULL((void*)0) ||
235 !PyDict_CheckExact(descr->fields)((((PyObject*)(descr->fields))->ob_type) == &PyDict_Type
)
) {
236 PyErr_Format(PyExc_ValueError,
237 "Failed to register dtype for %S: Legacy user dtypes "
238 "using `NPY_ITEM_IS_POINTER` or `NPY_ITEM_REFCOUNT` are "
239 "unsupported. It is possible to create such a dtype only "
240 "if it is a structured dtype with names and fields "
241 "hardcoded at registration time.\n"
242 "Please contact the NumPy developers if this used to work "
243 "but now fails.", descr->typeobj);
244 return -1;
245 }
246 }
247
248 if (test_deprecated_arrfuncs_members(f) < 0) {
249 return -1;
250 }
251
252 userdescrs = realloc(userdescrs,
253 (NPY_NUMUSERTYPES+1)*sizeof(void *));
254 if (userdescrs == NULL((void*)0)) {
255 PyErr_SetString(PyExc_MemoryError, "RegisterDataType");
256 return -1;
257 }
258
259 userdescrs[NPY_NUMUSERTYPES++] = descr;
260
261 descr->type_num = typenum;
262 if (dtypemeta_wrap_legacy_descriptor(descr) < 0) {
263 descr->type_num = -1;
264 NPY_NUMUSERTYPES--;
265 return -1;
266 }
267
268 return typenum;
269}
270
271/*NUMPY_API
272 Register Casting Function
273 Replaces any function currently stored.
274*/
275NPY_NO_EXPORT__attribute__((visibility("hidden"))) int
276PyArray_RegisterCastFunc(PyArray_Descr *descr, int totype,
277 PyArray_VectorUnaryFunc *castfunc)
278{
279 PyObject *cobj, *key;
280 int ret;
281
282 if (totype < NPY_NTYPES_ABI_COMPATIBLE) {
1
Assuming 'totype' is >= NPY_NTYPES_ABI_COMPATIBLE
2
Taking false branch
283 descr->f->cast[totype] = castfunc;
284 return 0;
285 }
286 if (totype >= NPY_NTYPES && !PyTypeNum_ISUSERDEF(totype)(((totype) >= NPY_USERDEF) && ((totype) < NPY_USERDEF
+ NPY_NUMUSERTYPES))
) {
3
Assuming 'totype' is < NPY_NTYPES
287 PyErr_SetString(PyExc_TypeError, "invalid type number.");
288 return -1;
289 }
290 if (descr->f->castdict == NULL((void*)0)) {
4
Assuming field 'castdict' is not equal to NULL
5
Taking false branch
291 descr->f->castdict = PyDict_New();
292 if (descr->f->castdict == NULL((void*)0)) {
293 return -1;
294 }
295 }
296 key = PyLong_FromLong(totype);
6
Calling 'PyLong_FromLong'
8
Returning from 'PyLong_FromLong'
11
PyObject ownership leak with reference count of 1
297 if (PyErr_Occurred()) {
9
Assuming the condition is true
10
Taking true branch
298 return -1;
299 }
300 cobj = PyCapsule_New((void *)castfunc, NULL((void*)0), NULL((void*)0));
301 if (cobj == NULL((void*)0)) {
302 Py_DECREF(key)_Py_DECREF(((PyObject*)(key)));
303 return -1;
304 }
305 ret = PyDict_SetItem(descr->f->castdict, key, cobj);
306 Py_DECREF(key)_Py_DECREF(((PyObject*)(key)));
307 Py_DECREF(cobj)_Py_DECREF(((PyObject*)(cobj)));
308 return ret;
309}
310
311/*NUMPY_API
312 * Register a type number indicating that a descriptor can be cast
313 * to it safely
314 */
315NPY_NO_EXPORT__attribute__((visibility("hidden"))) int
316PyArray_RegisterCanCast(PyArray_Descr *descr, int totype,
317 NPY_SCALARKIND scalar)
318{
319 /*
320 * If we were to allow this, the casting lookup table for
321 * built-in types needs to be modified, as cancastto is
322 * not checked for them.
323 */
324 if (!PyTypeNum_ISUSERDEF(descr->type_num)(((descr->type_num) >= NPY_USERDEF) && ((descr->
type_num) < NPY_USERDEF+ NPY_NUMUSERTYPES))
&&
325 !PyTypeNum_ISUSERDEF(totype)(((totype) >= NPY_USERDEF) && ((totype) < NPY_USERDEF
+ NPY_NUMUSERTYPES))
) {
326 PyErr_SetString(PyExc_ValueError,
327 "At least one of the types provided to "
328 "RegisterCanCast must be user-defined.");
329 return -1;
330 }
331
332 if (scalar == NPY_NOSCALAR) {
333 /*
334 * register with cancastto
335 * These lists won't be freed once created
336 * -- they become part of the data-type
337 */
338 if (descr->f->cancastto == NULL((void*)0)) {
339 descr->f->cancastto = (int *)malloc(1*sizeof(int));
340 if (descr->f->cancastto == NULL((void*)0)) {
341 PyErr_NoMemory();
342 return -1;
343 }
344 descr->f->cancastto[0] = NPY_NOTYPE;
345 }
346 return _append_new(&descr->f->cancastto, totype);
347 }
348 else {
349 /* register with cancastscalarkindto */
350 if (descr->f->cancastscalarkindto == NULL((void*)0)) {
351 int i;
352 descr->f->cancastscalarkindto =
353 (int **)malloc(NPY_NSCALARKINDS(NPY_OBJECT_SCALAR + 1)* sizeof(int*));
354 if (descr->f->cancastscalarkindto == NULL((void*)0)) {
355 PyErr_NoMemory();
356 return -1;
357 }
358 for (i = 0; i < NPY_NSCALARKINDS(NPY_OBJECT_SCALAR + 1); i++) {
359 descr->f->cancastscalarkindto[i] = NULL((void*)0);
360 }
361 }
362 if (descr->f->cancastscalarkindto[scalar] == NULL((void*)0)) {
363 descr->f->cancastscalarkindto[scalar] =
364 (int *)malloc(1*sizeof(int));
365 if (descr->f->cancastscalarkindto[scalar] == NULL((void*)0)) {
366 PyErr_NoMemory();
367 return -1;
368 }
369 descr->f->cancastscalarkindto[scalar][0] =
370 NPY_NOTYPE;
371 }
372 return _append_new(&descr->f->cancastscalarkindto[scalar], totype);
373 }
374}
375
376
377/*
378 * Legacy user DTypes implemented the common DType operation
379 * (as used in type promotion/result_type, and e.g. the type for
380 * concatenation), by using "safe cast" logic.
381 *
382 * New DTypes do have this behaviour generally, but we use can-cast
383 * when legacy user dtypes are involved.
384 */
385NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyArray_DTypeMeta *
386legacy_userdtype_common_dtype_function(
387 PyArray_DTypeMeta *cls, PyArray_DTypeMeta *other)
388{
389 int skind1 = NPY_NOSCALAR, skind2 = NPY_NOSCALAR, skind;
390
391 if (!other->legacy) {
392 /* legacy DTypes can always defer to new style ones */
393 Py_INCREF(Py_NotImplemented)_Py_INCREF(((PyObject*)((&_Py_NotImplementedStruct))));
394 return (PyArray_DTypeMeta *)Py_NotImplemented(&_Py_NotImplementedStruct);
395 }
396 /* Defer so that only one of the types handles the cast */
397 if (cls->type_num < other->type_num) {
398 Py_INCREF(Py_NotImplemented)_Py_INCREF(((PyObject*)((&_Py_NotImplementedStruct))));
399 return (PyArray_DTypeMeta *)Py_NotImplemented(&_Py_NotImplementedStruct);
400 }
401
402 /* Check whether casting is possible from one type to the other */
403 if (PyArray_CanCastSafely(cls->type_num, other->type_num)) {
404 Py_INCREF(other)_Py_INCREF(((PyObject*)(other)));
405 return other;
406 }
407 if (PyArray_CanCastSafely(other->type_num, cls->type_num)) {
408 Py_INCREF(cls)_Py_INCREF(((PyObject*)(cls)));
409 return cls;
410 }
411
412 /*
413 * The following code used to be part of PyArray_PromoteTypes().
414 * We can expect that this code is never used.
415 * In principle, it allows for promotion of two different user dtypes
416 * to a single NumPy dtype of the same "kind". In practice
417 * using the same `kind` as NumPy was never possible due to an
418 * simplification where `PyArray_EquivTypes(descr1, descr2)` will
419 * return True if both kind and element size match (e.g. bfloat16 and
420 * float16 would be equivalent).
421 * The option is also very obscure and not used in the examples.
422 */
423
424 /* Convert the 'kind' char into a scalar kind */
425 switch (cls->kind) {
426 case 'b':
427 skind1 = NPY_BOOL_SCALAR;
428 break;
429 case 'u':
430 skind1 = NPY_INTPOS_SCALAR;
431 break;
432 case 'i':
433 skind1 = NPY_INTNEG_SCALAR;
434 break;
435 case 'f':
436 skind1 = NPY_FLOAT_SCALAR;
437 break;
438 case 'c':
439 skind1 = NPY_COMPLEX_SCALAR;
440 break;
441 }
442 switch (other->kind) {
443 case 'b':
444 skind2 = NPY_BOOL_SCALAR;
445 break;
446 case 'u':
447 skind2 = NPY_INTPOS_SCALAR;
448 break;
449 case 'i':
450 skind2 = NPY_INTNEG_SCALAR;
451 break;
452 case 'f':
453 skind2 = NPY_FLOAT_SCALAR;
454 break;
455 case 'c':
456 skind2 = NPY_COMPLEX_SCALAR;
457 break;
458 }
459
460 /* If both are scalars, there may be a promotion possible */
461 if (skind1 != NPY_NOSCALAR && skind2 != NPY_NOSCALAR) {
462
463 /* Start with the larger scalar kind */
464 skind = (skind1 > skind2) ? skind1 : skind2;
465 int ret_type_num = _npy_smallest_type_of_kind_table[skind];
466
467 for (;;) {
468
469 /* If there is no larger type of this kind, try a larger kind */
470 if (ret_type_num < 0) {
471 ++skind;
472 /* Use -1 to signal no promoted type found */
473 if (skind < NPY_NSCALARKINDS(NPY_OBJECT_SCALAR + 1)) {
474 ret_type_num = _npy_smallest_type_of_kind_table[skind];
475 }
476 else {
477 break;
478 }
479 }
480
481 /* If we found a type to which we can promote both, done! */
482 if (PyArray_CanCastSafely(cls->type_num, ret_type_num) &&
483 PyArray_CanCastSafely(other->type_num, ret_type_num)) {
484 return PyArray_DTypeFromTypeNum(ret_type_num);
485 }
486
487 /* Try the next larger type of this kind */
488 ret_type_num = _npy_next_larger_type_table[ret_type_num];
489 }
490 }
491
492 Py_INCREF(Py_NotImplemented)_Py_INCREF(((PyObject*)((&_Py_NotImplementedStruct))));
493 return (PyArray_DTypeMeta *)Py_NotImplemented(&_Py_NotImplementedStruct);
494}
495
496
497/**
498 * This function wraps a legacy cast into an array-method. This is mostly
499 * used for legacy user-dtypes, but for example numeric to/from datetime
500 * casts were only defined that way as well.
501 *
502 * @param from
503 * @param to
504 * @param casting If `NPY_NO_CASTING` will check the legacy registered cast,
505 * otherwise uses the provided cast.
506 */
507NPY_NO_EXPORT__attribute__((visibility("hidden"))) int
508PyArray_AddLegacyWrapping_CastingImpl(
509 PyArray_DTypeMeta *from, PyArray_DTypeMeta *to, NPY_CASTING casting)
510{
511 if (casting < 0) {
512 if (from == to) {
513 casting = NPY_NO_CASTING;
514 }
515 else if (PyArray_LegacyCanCastTypeTo(
516 from->singleton, to->singleton, NPY_SAFE_CASTING)) {
517 casting = NPY_SAFE_CASTING;
518 }
519 else if (PyArray_LegacyCanCastTypeTo(
520 from->singleton, to->singleton, NPY_SAME_KIND_CASTING)) {
521 casting = NPY_SAME_KIND_CASTING;
522 }
523 else {
524 casting = NPY_UNSAFE_CASTING;
525 }
526 }
527
528 PyArray_DTypeMeta *dtypes[2] = {from, to};
529 PyArrayMethod_Spec spec = {
530 /* Name is not actually used, but allows identifying these. */
531 .name = "legacy_cast",
532 .nin = 1,
533 .nout = 1,
534 .casting = casting,
535 .dtypes = dtypes,
536 };
537
538 if (from == to) {
539 spec.flags = NPY_METH_REQUIRES_PYAPI | NPY_METH_SUPPORTS_UNALIGNED;
540 PyType_Slot slots[] = {
541 {NPY_METH_get_loop2, &legacy_cast_get_strided_loop},
542 {NPY_METH_resolve_descriptors1, &legacy_same_dtype_resolve_descriptors},
543 {0, NULL((void*)0)}};
544 spec.slots = slots;
545 return PyArray_AddCastingImplementation_FromSpec(&spec, 1);
546 }
547 else {
548 spec.flags = NPY_METH_REQUIRES_PYAPI;
549 PyType_Slot slots[] = {
550 {NPY_METH_get_loop2, &legacy_cast_get_strided_loop},
551 {NPY_METH_resolve_descriptors1, &simple_cast_resolve_descriptors},
552 {0, NULL((void*)0)}};
553 spec.slots = slots;
554 return PyArray_AddCastingImplementation_FromSpec(&spec, 1);
555 }
556}

/opt/pyrefcon/lib/pyrefcon/models/models/PyLong_FromLong.model

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