| File: | numpy/core/src/multiarray/number.c |
| Warning: | line 270, column 12 PyObject ownership leak with reference count of 1 |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | #define PY_SSIZE_T_CLEAN | ||||||||
| 2 | #include <Python.h> | ||||||||
| 3 | #include "structmember.h" | ||||||||
| 4 | |||||||||
| 5 | #define NPY_NO_DEPRECATED_API0x0000000E NPY_API_VERSION0x0000000E | ||||||||
| 6 | #define _MULTIARRAYMODULE | ||||||||
| 7 | #include "numpy/arrayobject.h" | ||||||||
| 8 | #include "lowlevel_strided_loops.h" | ||||||||
| 9 | |||||||||
| 10 | #include "npy_config.h" | ||||||||
| 11 | |||||||||
| 12 | #include "npy_pycompat.h" | ||||||||
| 13 | |||||||||
| 14 | #include "common.h" | ||||||||
| 15 | #include "number.h" | ||||||||
| 16 | |||||||||
| 17 | #include "calculation.h" | ||||||||
| 18 | #include "array_assign.h" | ||||||||
| 19 | |||||||||
| 20 | static double | ||||||||
| 21 | power_of_ten(int n) | ||||||||
| 22 | { | ||||||||
| 23 | static const double p10[] = {1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8}; | ||||||||
| 24 | double ret; | ||||||||
| 25 | if (n < 9) { | ||||||||
| 26 | ret = p10[n]; | ||||||||
| 27 | } | ||||||||
| 28 | else { | ||||||||
| 29 | ret = 1e9; | ||||||||
| 30 | while (n-- > 9) { | ||||||||
| 31 | ret *= 10.; | ||||||||
| 32 | } | ||||||||
| 33 | } | ||||||||
| 34 | return ret; | ||||||||
| 35 | } | ||||||||
| 36 | |||||||||
| 37 | /*NUMPY_API | ||||||||
| 38 | * ArgMax | ||||||||
| 39 | */ | ||||||||
| 40 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
| 41 | PyArray_ArgMax(PyArrayObject *op, int axis, PyArrayObject *out) | ||||||||
| 42 | { | ||||||||
| 43 | PyArrayObject *ap = NULL((void*)0), *rp = NULL((void*)0); | ||||||||
| 44 | PyArray_ArgFunc* arg_func; | ||||||||
| 45 | char *ip; | ||||||||
| 46 | npy_intp *rptr; | ||||||||
| 47 | npy_intp i, n, m; | ||||||||
| 48 | int elsize; | ||||||||
| 49 | NPY_BEGIN_THREADS_DEFPyThreadState *_save=((void*)0);; | ||||||||
| 50 | |||||||||
| 51 | if ((ap = (PyArrayObject *)PyArray_CheckAxis(op, &axis, 0)) == NULL((void*)0)) { | ||||||||
| 52 | return NULL((void*)0); | ||||||||
| 53 | } | ||||||||
| 54 | /* | ||||||||
| 55 | * We need to permute the array so that axis is placed at the end. | ||||||||
| 56 | * And all other dimensions are shifted left. | ||||||||
| 57 | */ | ||||||||
| 58 | if (axis != PyArray_NDIM(ap)-1) { | ||||||||
| 59 | PyArray_Dims newaxes; | ||||||||
| 60 | npy_intp dims[NPY_MAXDIMS32]; | ||||||||
| 61 | int j; | ||||||||
| 62 | |||||||||
| 63 | newaxes.ptr = dims; | ||||||||
| 64 | newaxes.len = PyArray_NDIM(ap); | ||||||||
| 65 | for (j = 0; j < axis; j++) { | ||||||||
| 66 | dims[j] = j; | ||||||||
| 67 | } | ||||||||
| 68 | for (j = axis; j < PyArray_NDIM(ap) - 1; j++) { | ||||||||
| 69 | dims[j] = j + 1; | ||||||||
| 70 | } | ||||||||
| 71 | dims[PyArray_NDIM(ap) - 1] = axis; | ||||||||
| 72 | op = (PyArrayObject *)PyArray_Transpose(ap, &newaxes); | ||||||||
| 73 | Py_DECREF(ap)_Py_DECREF(((PyObject*)(ap))); | ||||||||
| 74 | if (op == NULL((void*)0)) { | ||||||||
| 75 | return NULL((void*)0); | ||||||||
| 76 | } | ||||||||
| 77 | } | ||||||||
| 78 | else { | ||||||||
| 79 | op = ap; | ||||||||
| 80 | } | ||||||||
| 81 | |||||||||
| 82 | /* Will get native-byte order contiguous copy. */ | ||||||||
| 83 | ap = (PyArrayObject *)PyArray_ContiguousFromAny((PyObject *)op,PyArray_FromAny((PyObject *)op, PyArray_DescrFromType(PyArray_DESCR (op)->type_num), 1, 0, ((0x0001 | (0x0100 | 0x0400))), ((void *)0)) | ||||||||
| 84 | PyArray_DESCR(op)->type_num, 1, 0)PyArray_FromAny((PyObject *)op, PyArray_DescrFromType(PyArray_DESCR (op)->type_num), 1, 0, ((0x0001 | (0x0100 | 0x0400))), ((void *)0)); | ||||||||
| 85 | Py_DECREF(op)_Py_DECREF(((PyObject*)(op))); | ||||||||
| 86 | if (ap == NULL((void*)0)) { | ||||||||
| 87 | return NULL((void*)0); | ||||||||
| 88 | } | ||||||||
| 89 | arg_func = PyArray_DESCR(ap)->f->argmax; | ||||||||
| 90 | if (arg_func == NULL((void*)0)) { | ||||||||
| 91 | PyErr_SetString(PyExc_TypeError, | ||||||||
| 92 | "data type not ordered"); | ||||||||
| 93 | goto fail; | ||||||||
| 94 | } | ||||||||
| 95 | elsize = PyArray_DESCR(ap)->elsize; | ||||||||
| 96 | m = PyArray_DIMS(ap)[PyArray_NDIM(ap)-1]; | ||||||||
| 97 | if (m == 0) { | ||||||||
| 98 | PyErr_SetString(PyExc_ValueError, | ||||||||
| 99 | "attempt to get argmax of an empty sequence"); | ||||||||
| 100 | goto fail; | ||||||||
| 101 | } | ||||||||
| 102 | |||||||||
| 103 | if (!out) { | ||||||||
| 104 | rp = (PyArrayObject *)PyArray_NewFromDescr( | ||||||||
| 105 | Py_TYPE(ap)(((PyObject*)(ap))->ob_type), PyArray_DescrFromType(NPY_INTPNPY_LONG), | ||||||||
| 106 | PyArray_NDIM(ap) - 1, PyArray_DIMS(ap), NULL((void*)0), NULL((void*)0), | ||||||||
| 107 | 0, (PyObject *)ap); | ||||||||
| 108 | if (rp == NULL((void*)0)) { | ||||||||
| 109 | goto fail; | ||||||||
| 110 | } | ||||||||
| 111 | } | ||||||||
| 112 | else { | ||||||||
| 113 | if ((PyArray_NDIM(out) != PyArray_NDIM(ap) - 1) || | ||||||||
| 114 | !PyArray_CompareLists(PyArray_DIMS(out), PyArray_DIMS(ap), | ||||||||
| 115 | PyArray_NDIM(out))) { | ||||||||
| 116 | PyErr_SetString(PyExc_ValueError, | ||||||||
| 117 | "output array does not match result of np.argmax."); | ||||||||
| 118 | goto fail; | ||||||||
| 119 | } | ||||||||
| 120 | rp = (PyArrayObject *)PyArray_FromArray(out, | ||||||||
| 121 | PyArray_DescrFromType(NPY_INTPNPY_LONG), | ||||||||
| 122 | NPY_ARRAY_CARRAY(0x0001 | (0x0100 | 0x0400)) | NPY_ARRAY_WRITEBACKIFCOPY0x2000); | ||||||||
| 123 | if (rp == NULL((void*)0)) { | ||||||||
| 124 | goto fail; | ||||||||
| 125 | } | ||||||||
| 126 | } | ||||||||
| 127 | |||||||||
| 128 | NPY_BEGIN_THREADS_DESCR(PyArray_DESCR(ap))do {if (!(((((PyArray_DESCR(ap)))->flags & (0x10)) == ( 0x10)))) do {_save = PyEval_SaveThread();} while (0);;} while (0);; | ||||||||
| 129 | n = PyArray_SIZE(ap)PyArray_MultiplyList(PyArray_DIMS(ap), PyArray_NDIM(ap))/m; | ||||||||
| 130 | rptr = (npy_intp *)PyArray_DATA(rp); | ||||||||
| 131 | for (ip = PyArray_DATA(ap), i = 0; i < n; i++, ip += elsize*m) { | ||||||||
| 132 | arg_func(ip, m, rptr, ap); | ||||||||
| 133 | rptr += 1; | ||||||||
| 134 | } | ||||||||
| 135 | NPY_END_THREADS_DESCR(PyArray_DESCR(ap))do {if (!(((((PyArray_DESCR(ap)))->flags & (0x10)) == ( 0x10)))) do { if (_save) { PyEval_RestoreThread(_save); _save = ((void*)0);} } while (0);; } while (0);; | ||||||||
| 136 | |||||||||
| 137 | Py_DECREF(ap)_Py_DECREF(((PyObject*)(ap))); | ||||||||
| 138 | /* Trigger the UPDATEIFCOPY/WRTIEBACKIFCOPY if necessary */ | ||||||||
| 139 | if (out != NULL((void*)0) && out != rp) { | ||||||||
| 140 | PyArray_ResolveWritebackIfCopy(rp); | ||||||||
| 141 | Py_DECREF(rp)_Py_DECREF(((PyObject*)(rp))); | ||||||||
| 142 | rp = out; | ||||||||
| 143 | Py_INCREF(rp)_Py_INCREF(((PyObject*)(rp))); | ||||||||
| 144 | } | ||||||||
| 145 | return (PyObject *)rp; | ||||||||
| 146 | |||||||||
| 147 | fail: | ||||||||
| 148 | Py_DECREF(ap)_Py_DECREF(((PyObject*)(ap))); | ||||||||
| 149 | Py_XDECREF(rp)_Py_XDECREF(((PyObject*)(rp))); | ||||||||
| 150 | return NULL((void*)0); | ||||||||
| 151 | } | ||||||||
| 152 | |||||||||
| 153 | /*NUMPY_API | ||||||||
| 154 | * ArgMin | ||||||||
| 155 | */ | ||||||||
| 156 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
| 157 | PyArray_ArgMin(PyArrayObject *op, int axis, PyArrayObject *out) | ||||||||
| 158 | { | ||||||||
| 159 | PyArrayObject *ap = NULL((void*)0), *rp = NULL((void*)0); | ||||||||
| 160 | PyArray_ArgFunc* arg_func; | ||||||||
| 161 | char *ip; | ||||||||
| 162 | npy_intp *rptr; | ||||||||
| 163 | npy_intp i, n, m; | ||||||||
| 164 | int elsize; | ||||||||
| 165 | NPY_BEGIN_THREADS_DEFPyThreadState *_save=((void*)0);; | ||||||||
| 166 | |||||||||
| 167 | if ((ap = (PyArrayObject *)PyArray_CheckAxis(op, &axis, 0)) == NULL((void*)0)) { | ||||||||
| 168 | return NULL((void*)0); | ||||||||
| 169 | } | ||||||||
| 170 | /* | ||||||||
| 171 | * We need to permute the array so that axis is placed at the end. | ||||||||
| 172 | * And all other dimensions are shifted left. | ||||||||
| 173 | */ | ||||||||
| 174 | if (axis != PyArray_NDIM(ap)-1) { | ||||||||
| 175 | PyArray_Dims newaxes; | ||||||||
| 176 | npy_intp dims[NPY_MAXDIMS32]; | ||||||||
| 177 | int i; | ||||||||
| 178 | |||||||||
| 179 | newaxes.ptr = dims; | ||||||||
| 180 | newaxes.len = PyArray_NDIM(ap); | ||||||||
| 181 | for (i = 0; i < axis; i++) { | ||||||||
| 182 | dims[i] = i; | ||||||||
| 183 | } | ||||||||
| 184 | for (i = axis; i < PyArray_NDIM(ap) - 1; i++) { | ||||||||
| 185 | dims[i] = i + 1; | ||||||||
| 186 | } | ||||||||
| 187 | dims[PyArray_NDIM(ap) - 1] = axis; | ||||||||
| 188 | op = (PyArrayObject *)PyArray_Transpose(ap, &newaxes); | ||||||||
| 189 | Py_DECREF(ap)_Py_DECREF(((PyObject*)(ap))); | ||||||||
| 190 | if (op == NULL((void*)0)) { | ||||||||
| 191 | return NULL((void*)0); | ||||||||
| 192 | } | ||||||||
| 193 | } | ||||||||
| 194 | else { | ||||||||
| 195 | op = ap; | ||||||||
| 196 | } | ||||||||
| 197 | |||||||||
| 198 | /* Will get native-byte order contiguous copy. */ | ||||||||
| 199 | ap = (PyArrayObject *)PyArray_ContiguousFromAny((PyObject *)op,PyArray_FromAny((PyObject *)op, PyArray_DescrFromType(PyArray_DESCR (op)->type_num), 1, 0, ((0x0001 | (0x0100 | 0x0400))), ((void *)0)) | ||||||||
| 200 | PyArray_DESCR(op)->type_num, 1, 0)PyArray_FromAny((PyObject *)op, PyArray_DescrFromType(PyArray_DESCR (op)->type_num), 1, 0, ((0x0001 | (0x0100 | 0x0400))), ((void *)0)); | ||||||||
| 201 | Py_DECREF(op)_Py_DECREF(((PyObject*)(op))); | ||||||||
| 202 | if (ap == NULL((void*)0)) { | ||||||||
| 203 | return NULL((void*)0); | ||||||||
| 204 | } | ||||||||
| 205 | arg_func = PyArray_DESCR(ap)->f->argmin; | ||||||||
| 206 | if (arg_func == NULL((void*)0)) { | ||||||||
| 207 | PyErr_SetString(PyExc_TypeError, | ||||||||
| 208 | "data type not ordered"); | ||||||||
| 209 | goto fail; | ||||||||
| 210 | } | ||||||||
| 211 | elsize = PyArray_DESCR(ap)->elsize; | ||||||||
| 212 | m = PyArray_DIMS(ap)[PyArray_NDIM(ap)-1]; | ||||||||
| 213 | if (m == 0) { | ||||||||
| 214 | PyErr_SetString(PyExc_ValueError, | ||||||||
| 215 | "attempt to get argmin of an empty sequence"); | ||||||||
| 216 | goto fail; | ||||||||
| 217 | } | ||||||||
| 218 | |||||||||
| 219 | if (!out) { | ||||||||
| 220 | rp = (PyArrayObject *)PyArray_NewFromDescr( | ||||||||
| 221 | Py_TYPE(ap)(((PyObject*)(ap))->ob_type), PyArray_DescrFromType(NPY_INTPNPY_LONG), | ||||||||
| 222 | PyArray_NDIM(ap) - 1, PyArray_DIMS(ap), NULL((void*)0), NULL((void*)0), | ||||||||
| 223 | 0, (PyObject *)ap); | ||||||||
| 224 | if (rp == NULL((void*)0)) { | ||||||||
| 225 | goto fail; | ||||||||
| 226 | } | ||||||||
| 227 | } | ||||||||
| 228 | else { | ||||||||
| 229 | if ((PyArray_NDIM(out) != PyArray_NDIM(ap) - 1) || | ||||||||
| 230 | !PyArray_CompareLists(PyArray_DIMS(out), PyArray_DIMS(ap), | ||||||||
| 231 | PyArray_NDIM(out))) { | ||||||||
| 232 | PyErr_SetString(PyExc_ValueError, | ||||||||
| 233 | "output array does not match result of np.argmin."); | ||||||||
| 234 | goto fail; | ||||||||
| 235 | } | ||||||||
| 236 | rp = (PyArrayObject *)PyArray_FromArray(out, | ||||||||
| 237 | PyArray_DescrFromType(NPY_INTPNPY_LONG), | ||||||||
| 238 | NPY_ARRAY_CARRAY(0x0001 | (0x0100 | 0x0400)) | NPY_ARRAY_WRITEBACKIFCOPY0x2000); | ||||||||
| 239 | if (rp == NULL((void*)0)) { | ||||||||
| 240 | goto fail; | ||||||||
| 241 | } | ||||||||
| 242 | } | ||||||||
| 243 | |||||||||
| 244 | NPY_BEGIN_THREADS_DESCR(PyArray_DESCR(ap))do {if (!(((((PyArray_DESCR(ap)))->flags & (0x10)) == ( 0x10)))) do {_save = PyEval_SaveThread();} while (0);;} while (0);; | ||||||||
| 245 | n = PyArray_SIZE(ap)PyArray_MultiplyList(PyArray_DIMS(ap), PyArray_NDIM(ap))/m; | ||||||||
| 246 | rptr = (npy_intp *)PyArray_DATA(rp); | ||||||||
| 247 | for (ip = PyArray_DATA(ap), i = 0; i < n; i++, ip += elsize*m) { | ||||||||
| 248 | arg_func(ip, m, rptr, ap); | ||||||||
| 249 | rptr += 1; | ||||||||
| 250 | } | ||||||||
| 251 | NPY_END_THREADS_DESCR(PyArray_DESCR(ap))do {if (!(((((PyArray_DESCR(ap)))->flags & (0x10)) == ( 0x10)))) do { if (_save) { PyEval_RestoreThread(_save); _save = ((void*)0);} } while (0);; } while (0);; | ||||||||
| 252 | |||||||||
| 253 | Py_DECREF(ap)_Py_DECREF(((PyObject*)(ap))); | ||||||||
| 254 | /* Trigger the UPDATEIFCOPY/WRITEBACKIFCOPY if necessary */ | ||||||||
| 255 | if (out != NULL((void*)0) && out != rp) { | ||||||||
| 256 | PyArray_ResolveWritebackIfCopy(rp); | ||||||||
| 257 | Py_DECREF(rp)_Py_DECREF(((PyObject*)(rp))); | ||||||||
| 258 | rp = out; | ||||||||
| 259 | Py_INCREF(rp)_Py_INCREF(((PyObject*)(rp))); | ||||||||
| 260 | } | ||||||||
| 261 | return (PyObject *)rp; | ||||||||
| 262 | |||||||||
| 263 | fail: | ||||||||
| 264 | Py_DECREF(ap)_Py_DECREF(((PyObject*)(ap))); | ||||||||
| 265 | Py_XDECREF(rp)_Py_XDECREF(((PyObject*)(rp))); | ||||||||
| 266 | return NULL((void*)0); | ||||||||
| 267 | } | ||||||||
| 268 | |||||||||
| 269 | /*NUMPY_API | ||||||||
| 270 | * Max | ||||||||
| 271 | */ | ||||||||
| 272 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
| 273 | PyArray_Max(PyArrayObject *ap, int axis, PyArrayObject *out) | ||||||||
| 274 | { | ||||||||
| 275 | PyArrayObject *arr; | ||||||||
| 276 | PyObject *ret; | ||||||||
| 277 | |||||||||
| 278 | arr = (PyArrayObject *)PyArray_CheckAxis(ap, &axis, 0); | ||||||||
| 279 | if (arr == NULL((void*)0)) { | ||||||||
| 280 | return NULL((void*)0); | ||||||||
| 281 | } | ||||||||
| 282 | ret = PyArray_GenericReduceFunction(arr, n_ops.maximum, axis, | ||||||||
| 283 | PyArray_DESCR(arr)->type_num, out); | ||||||||
| 284 | Py_DECREF(arr)_Py_DECREF(((PyObject*)(arr))); | ||||||||
| 285 | return ret; | ||||||||
| 286 | } | ||||||||
| 287 | |||||||||
| 288 | /*NUMPY_API | ||||||||
| 289 | * Min | ||||||||
| 290 | */ | ||||||||
| 291 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
| 292 | PyArray_Min(PyArrayObject *ap, int axis, PyArrayObject *out) | ||||||||
| 293 | { | ||||||||
| 294 | PyArrayObject *arr; | ||||||||
| 295 | PyObject *ret; | ||||||||
| 296 | |||||||||
| 297 | arr=(PyArrayObject *)PyArray_CheckAxis(ap, &axis, 0); | ||||||||
| 298 | if (arr == NULL((void*)0)) { | ||||||||
| 299 | return NULL((void*)0); | ||||||||
| 300 | } | ||||||||
| 301 | ret = PyArray_GenericReduceFunction(arr, n_ops.minimum, axis, | ||||||||
| 302 | PyArray_DESCR(arr)->type_num, out); | ||||||||
| 303 | Py_DECREF(arr)_Py_DECREF(((PyObject*)(arr))); | ||||||||
| 304 | return ret; | ||||||||
| 305 | } | ||||||||
| 306 | |||||||||
| 307 | /*NUMPY_API | ||||||||
| 308 | * Ptp | ||||||||
| 309 | */ | ||||||||
| 310 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
| 311 | PyArray_Ptp(PyArrayObject *ap, int axis, PyArrayObject *out) | ||||||||
| 312 | { | ||||||||
| 313 | PyArrayObject *arr; | ||||||||
| 314 | PyObject *ret; | ||||||||
| 315 | PyObject *obj1 = NULL((void*)0), *obj2 = NULL((void*)0); | ||||||||
| 316 | |||||||||
| 317 | arr=(PyArrayObject *)PyArray_CheckAxis(ap, &axis, 0); | ||||||||
| 318 | if (arr == NULL((void*)0)) { | ||||||||
| 319 | return NULL((void*)0); | ||||||||
| 320 | } | ||||||||
| 321 | obj1 = PyArray_Max(arr, axis, out); | ||||||||
| 322 | if (obj1 == NULL((void*)0)) { | ||||||||
| 323 | goto fail; | ||||||||
| 324 | } | ||||||||
| 325 | obj2 = PyArray_Min(arr, axis, NULL((void*)0)); | ||||||||
| 326 | if (obj2 == NULL((void*)0)) { | ||||||||
| 327 | goto fail; | ||||||||
| 328 | } | ||||||||
| 329 | Py_DECREF(arr)_Py_DECREF(((PyObject*)(arr))); | ||||||||
| 330 | if (out) { | ||||||||
| 331 | ret = PyObject_CallFunction_PyObject_CallFunction_SizeT(n_ops.subtract, "OOO", out, obj2, out); | ||||||||
| 332 | } | ||||||||
| 333 | else { | ||||||||
| 334 | ret = PyNumber_Subtract(obj1, obj2); | ||||||||
| 335 | } | ||||||||
| 336 | Py_DECREF(obj1)_Py_DECREF(((PyObject*)(obj1))); | ||||||||
| 337 | Py_DECREF(obj2)_Py_DECREF(((PyObject*)(obj2))); | ||||||||
| 338 | return ret; | ||||||||
| 339 | |||||||||
| 340 | fail: | ||||||||
| 341 | Py_XDECREF(arr)_Py_XDECREF(((PyObject*)(arr))); | ||||||||
| 342 | Py_XDECREF(obj1)_Py_XDECREF(((PyObject*)(obj1))); | ||||||||
| 343 | Py_XDECREF(obj2)_Py_XDECREF(((PyObject*)(obj2))); | ||||||||
| 344 | return NULL((void*)0); | ||||||||
| 345 | } | ||||||||
| 346 | |||||||||
| 347 | |||||||||
| 348 | |||||||||
| 349 | /*NUMPY_API | ||||||||
| 350 | * Set variance to 1 to by-pass square-root calculation and return variance | ||||||||
| 351 | * Std | ||||||||
| 352 | */ | ||||||||
| 353 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
| 354 | PyArray_Std(PyArrayObject *self, int axis, int rtype, PyArrayObject *out, | ||||||||
| 355 | int variance) | ||||||||
| 356 | { | ||||||||
| 357 | return __New_PyArray_Std(self, axis, rtype, out, variance, 0); | ||||||||
| |||||||||
| 358 | } | ||||||||
| 359 | |||||||||
| 360 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
| 361 | __New_PyArray_Std(PyArrayObject *self, int axis, int rtype, PyArrayObject *out, | ||||||||
| 362 | int variance, int num) | ||||||||
| 363 | { | ||||||||
| 364 | PyObject *obj1 = NULL((void*)0), *obj2 = NULL((void*)0), *obj3 = NULL((void*)0); | ||||||||
| 365 | PyArrayObject *arr1 = NULL((void*)0), *arr2 = NULL((void*)0), *arrnew = NULL((void*)0); | ||||||||
| 366 | PyObject *ret = NULL((void*)0), *newshape = NULL((void*)0); | ||||||||
| 367 | int i, n; | ||||||||
| 368 | npy_intp val; | ||||||||
| 369 | |||||||||
| 370 | arrnew = (PyArrayObject *)PyArray_CheckAxis(self, &axis, 0); | ||||||||
| 371 | if (arrnew
| ||||||||
| 372 | return NULL((void*)0); | ||||||||
| 373 | } | ||||||||
| 374 | /* Compute and reshape mean */ | ||||||||
| 375 | arr1 = (PyArrayObject *)PyArray_EnsureAnyArray( | ||||||||
| 376 | PyArray_Mean(arrnew, axis, rtype, NULL((void*)0))); | ||||||||
| 377 | if (arr1
| ||||||||
| 378 | Py_DECREF(arrnew)_Py_DECREF(((PyObject*)(arrnew))); | ||||||||
| 379 | return NULL((void*)0); | ||||||||
| 380 | } | ||||||||
| 381 | n = PyArray_NDIM(arrnew); | ||||||||
| 382 | newshape = PyTuple_New(n); | ||||||||
| 383 | if (newshape == NULL((void*)0)) { | ||||||||
| 384 | Py_DECREF(arr1)_Py_DECREF(((PyObject*)(arr1))); | ||||||||
| 385 | Py_DECREF(arrnew)_Py_DECREF(((PyObject*)(arrnew))); | ||||||||
| 386 | return NULL((void*)0); | ||||||||
| 387 | } | ||||||||
| 388 | for (i = 0; i < n; i++) { | ||||||||
| 389 | if (i == axis) { | ||||||||
| 390 | val = 1; | ||||||||
| 391 | } | ||||||||
| 392 | else { | ||||||||
| 393 | val = PyArray_DIM(arrnew,i); | ||||||||
| 394 | } | ||||||||
| 395 | PyTuple_SET_ITEM(newshape, i, PyLong_FromSsize_t(val))PyTuple_SetItem(newshape, i, PyLong_FromSsize_t(val)); | ||||||||
| 396 | } | ||||||||
| 397 | arr2 = (PyArrayObject *)PyArray_Reshape(arr1, newshape); | ||||||||
| 398 | Py_DECREF(arr1)_Py_DECREF(((PyObject*)(arr1))); | ||||||||
| 399 | Py_DECREF(newshape)_Py_DECREF(((PyObject*)(newshape))); | ||||||||
| 400 | if (arr2 == NULL((void*)0)) { | ||||||||
| 401 | Py_DECREF(arrnew)_Py_DECREF(((PyObject*)(arrnew))); | ||||||||
| 402 | return NULL((void*)0); | ||||||||
| 403 | } | ||||||||
| 404 | |||||||||
| 405 | /* Compute x = x - mx */ | ||||||||
| 406 | arr1 = (PyArrayObject *)PyArray_EnsureAnyArray( | ||||||||
| 407 | PyNumber_Subtract((PyObject *)arrnew, (PyObject *)arr2)); | ||||||||
| 408 | Py_DECREF(arr2)_Py_DECREF(((PyObject*)(arr2))); | ||||||||
| 409 | if (arr1
| ||||||||
| 410 | Py_DECREF(arrnew)_Py_DECREF(((PyObject*)(arrnew))); | ||||||||
| 411 | return NULL((void*)0); | ||||||||
| 412 | } | ||||||||
| 413 | /* Compute x * x */ | ||||||||
| 414 | if (PyArray_ISCOMPLEX(arr1)(((PyArray_TYPE(arr1)) >= NPY_CFLOAT) && ((PyArray_TYPE (arr1)) <= NPY_CLONGDOUBLE))) { | ||||||||
| 415 | obj3 = PyArray_Conjugate(arr1, NULL((void*)0)); | ||||||||
| 416 | } | ||||||||
| 417 | else { | ||||||||
| 418 | obj3 = (PyObject *)arr1; | ||||||||
| 419 | Py_INCREF(arr1)_Py_INCREF(((PyObject*)(arr1))); | ||||||||
| 420 | } | ||||||||
| 421 | if (obj3
| ||||||||
| 422 | Py_DECREF(arrnew)_Py_DECREF(((PyObject*)(arrnew))); | ||||||||
| 423 | return NULL((void*)0); | ||||||||
| 424 | } | ||||||||
| 425 | arr2 = (PyArrayObject *)PyArray_EnsureAnyArray( | ||||||||
| 426 | PyArray_GenericBinaryFunction((PyObject *)arr1, obj3, | ||||||||
| 427 | n_ops.multiply)); | ||||||||
| 428 | Py_DECREF(arr1)_Py_DECREF(((PyObject*)(arr1))); | ||||||||
| 429 | Py_DECREF(obj3)_Py_DECREF(((PyObject*)(obj3))); | ||||||||
| 430 | if (arr2
| ||||||||
| 431 | Py_DECREF(arrnew)_Py_DECREF(((PyObject*)(arrnew))); | ||||||||
| 432 | return NULL((void*)0); | ||||||||
| 433 | } | ||||||||
| 434 | if (PyArray_ISCOMPLEX(arr2)(((PyArray_TYPE(arr2)) >= NPY_CFLOAT) && ((PyArray_TYPE (arr2)) <= NPY_CLONGDOUBLE))) { | ||||||||
| 435 | obj3 = PyObject_GetAttrString((PyObject *)arr2, "real"); | ||||||||
| 436 | switch(rtype) { | ||||||||
| 437 | case NPY_CDOUBLE: | ||||||||
| 438 | rtype = NPY_DOUBLE; | ||||||||
| 439 | break; | ||||||||
| 440 | case NPY_CFLOAT: | ||||||||
| 441 | rtype = NPY_FLOAT; | ||||||||
| 442 | break; | ||||||||
| 443 | case NPY_CLONGDOUBLE: | ||||||||
| 444 | rtype = NPY_LONGDOUBLE; | ||||||||
| 445 | break; | ||||||||
| 446 | } | ||||||||
| 447 | } | ||||||||
| 448 | else { | ||||||||
| 449 | obj3 = (PyObject *)arr2; | ||||||||
| 450 | Py_INCREF(arr2)_Py_INCREF(((PyObject*)(arr2))); | ||||||||
| 451 | } | ||||||||
| 452 | if (obj3 == NULL((void*)0)) { | ||||||||
| 453 | Py_DECREF(arrnew)_Py_DECREF(((PyObject*)(arrnew))); | ||||||||
| 454 | return NULL((void*)0); | ||||||||
| 455 | } | ||||||||
| 456 | /* Compute add.reduce(x*x,axis) */ | ||||||||
| 457 | obj1 = PyArray_GenericReduceFunction((PyArrayObject *)obj3, n_ops.add, | ||||||||
| 458 | axis, rtype, NULL((void*)0)); | ||||||||
| 459 | Py_DECREF(obj3)_Py_DECREF(((PyObject*)(obj3))); | ||||||||
| 460 | Py_DECREF(arr2)_Py_DECREF(((PyObject*)(arr2))); | ||||||||
| 461 | if (obj1 == NULL((void*)0)) { | ||||||||
| 462 | Py_DECREF(arrnew)_Py_DECREF(((PyObject*)(arrnew))); | ||||||||
| 463 | return NULL((void*)0); | ||||||||
| 464 | } | ||||||||
| 465 | n = PyArray_DIM(arrnew,axis); | ||||||||
| 466 | Py_DECREF(arrnew)_Py_DECREF(((PyObject*)(arrnew))); | ||||||||
| 467 | n = (n-num); | ||||||||
| 468 | if (n == 0) { | ||||||||
| 469 | n = 1; | ||||||||
| 470 | } | ||||||||
| 471 | obj2 = PyFloat_FromDouble(1.0/((double )n)); | ||||||||
| 472 | if (obj2 == NULL((void*)0)) { | ||||||||
| 473 | Py_DECREF(obj1)_Py_DECREF(((PyObject*)(obj1))); | ||||||||
| 474 | return NULL((void*)0); | ||||||||
| 475 | } | ||||||||
| 476 | ret = PyNumber_Multiply(obj1, obj2); | ||||||||
| 477 | Py_DECREF(obj1)_Py_DECREF(((PyObject*)(obj1))); | ||||||||
| 478 | Py_DECREF(obj2)_Py_DECREF(((PyObject*)(obj2))); | ||||||||
| 479 | |||||||||
| 480 | if (!variance) { | ||||||||
| 481 | arr1 = (PyArrayObject *)PyArray_EnsureAnyArray(ret); | ||||||||
| 482 | /* sqrt() */ | ||||||||
| 483 | ret = PyArray_GenericUnaryFunction(arr1, n_ops.sqrt); | ||||||||
| 484 | Py_DECREF(arr1)_Py_DECREF(((PyObject*)(arr1))); | ||||||||
| 485 | } | ||||||||
| 486 | if (ret == NULL((void*)0)) { | ||||||||
| 487 | return NULL((void*)0); | ||||||||
| 488 | } | ||||||||
| 489 | if (PyArray_CheckExact(self)(((PyObject*)(self))->ob_type == &PyArray_Type)) { | ||||||||
| 490 | goto finish; | ||||||||
| 491 | } | ||||||||
| 492 | if (PyArray_Check(self)((((PyObject*)(self))->ob_type) == (&PyArray_Type) || PyType_IsSubtype ((((PyObject*)(self))->ob_type), (&PyArray_Type))) && Py_TYPE(self)(((PyObject*)(self))->ob_type) == Py_TYPE(ret)(((PyObject*)(ret))->ob_type)) { | ||||||||
| 493 | goto finish; | ||||||||
| 494 | } | ||||||||
| 495 | arr1 = (PyArrayObject *)PyArray_EnsureArray(ret); | ||||||||
| 496 | if (arr1 == NULL((void*)0)) { | ||||||||
| 497 | return NULL((void*)0); | ||||||||
| 498 | } | ||||||||
| 499 | ret = PyArray_View(arr1, NULL((void*)0), Py_TYPE(self)(((PyObject*)(self))->ob_type)); | ||||||||
| 500 | Py_DECREF(arr1)_Py_DECREF(((PyObject*)(arr1))); | ||||||||
| 501 | |||||||||
| 502 | finish: | ||||||||
| 503 | if (out) { | ||||||||
| 504 | if (PyArray_AssignArray(out, (PyArrayObject *)ret, | ||||||||
| 505 | NULL((void*)0), NPY_DEFAULT_ASSIGN_CASTING) < 0) { | ||||||||
| 506 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | ||||||||
| 507 | return NULL((void*)0); | ||||||||
| 508 | } | ||||||||
| 509 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | ||||||||
| 510 | Py_INCREF(out)_Py_INCREF(((PyObject*)(out))); | ||||||||
| 511 | return (PyObject *)out; | ||||||||
| 512 | } | ||||||||
| 513 | return ret; | ||||||||
| 514 | } | ||||||||
| 515 | |||||||||
| 516 | |||||||||
| 517 | /*NUMPY_API | ||||||||
| 518 | *Sum | ||||||||
| 519 | */ | ||||||||
| 520 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
| 521 | PyArray_Sum(PyArrayObject *self, int axis, int rtype, PyArrayObject *out) | ||||||||
| 522 | { | ||||||||
| 523 | PyObject *arr, *ret; | ||||||||
| 524 | |||||||||
| 525 | arr = PyArray_CheckAxis(self, &axis, 0); | ||||||||
| 526 | if (arr == NULL((void*)0)) { | ||||||||
| 527 | return NULL((void*)0); | ||||||||
| 528 | } | ||||||||
| 529 | ret = PyArray_GenericReduceFunction((PyArrayObject *)arr, n_ops.add, axis, | ||||||||
| 530 | rtype, out); | ||||||||
| 531 | Py_DECREF(arr)_Py_DECREF(((PyObject*)(arr))); | ||||||||
| 532 | return ret; | ||||||||
| 533 | } | ||||||||
| 534 | |||||||||
| 535 | /*NUMPY_API | ||||||||
| 536 | * Prod | ||||||||
| 537 | */ | ||||||||
| 538 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
| 539 | PyArray_Prod(PyArrayObject *self, int axis, int rtype, PyArrayObject *out) | ||||||||
| 540 | { | ||||||||
| 541 | PyObject *arr, *ret; | ||||||||
| 542 | |||||||||
| 543 | arr = PyArray_CheckAxis(self, &axis, 0); | ||||||||
| 544 | if (arr == NULL((void*)0)) { | ||||||||
| 545 | return NULL((void*)0); | ||||||||
| 546 | } | ||||||||
| 547 | ret = PyArray_GenericReduceFunction((PyArrayObject *)arr, | ||||||||
| 548 | n_ops.multiply, axis, | ||||||||
| 549 | rtype, out); | ||||||||
| 550 | Py_DECREF(arr)_Py_DECREF(((PyObject*)(arr))); | ||||||||
| 551 | return ret; | ||||||||
| 552 | } | ||||||||
| 553 | |||||||||
| 554 | /*NUMPY_API | ||||||||
| 555 | *CumSum | ||||||||
| 556 | */ | ||||||||
| 557 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
| 558 | PyArray_CumSum(PyArrayObject *self, int axis, int rtype, PyArrayObject *out) | ||||||||
| 559 | { | ||||||||
| 560 | PyObject *arr, *ret; | ||||||||
| 561 | |||||||||
| 562 | arr = PyArray_CheckAxis(self, &axis, 0); | ||||||||
| 563 | if (arr == NULL((void*)0)) { | ||||||||
| 564 | return NULL((void*)0); | ||||||||
| 565 | } | ||||||||
| 566 | ret = PyArray_GenericAccumulateFunction((PyArrayObject *)arr, | ||||||||
| 567 | n_ops.add, axis, | ||||||||
| 568 | rtype, out); | ||||||||
| 569 | Py_DECREF(arr)_Py_DECREF(((PyObject*)(arr))); | ||||||||
| 570 | return ret; | ||||||||
| 571 | } | ||||||||
| 572 | |||||||||
| 573 | /*NUMPY_API | ||||||||
| 574 | * CumProd | ||||||||
| 575 | */ | ||||||||
| 576 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
| 577 | PyArray_CumProd(PyArrayObject *self, int axis, int rtype, PyArrayObject *out) | ||||||||
| 578 | { | ||||||||
| 579 | PyObject *arr, *ret; | ||||||||
| 580 | |||||||||
| 581 | arr = PyArray_CheckAxis(self, &axis, 0); | ||||||||
| 582 | if (arr == NULL((void*)0)) { | ||||||||
| 583 | return NULL((void*)0); | ||||||||
| 584 | } | ||||||||
| 585 | |||||||||
| 586 | ret = PyArray_GenericAccumulateFunction((PyArrayObject *)arr, | ||||||||
| 587 | n_ops.multiply, axis, | ||||||||
| 588 | rtype, out); | ||||||||
| 589 | Py_DECREF(arr)_Py_DECREF(((PyObject*)(arr))); | ||||||||
| 590 | return ret; | ||||||||
| 591 | } | ||||||||
| 592 | |||||||||
| 593 | /*NUMPY_API | ||||||||
| 594 | * Round | ||||||||
| 595 | */ | ||||||||
| 596 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
| 597 | PyArray_Round(PyArrayObject *a, int decimals, PyArrayObject *out) | ||||||||
| 598 | { | ||||||||
| 599 | PyObject *f, *ret = NULL((void*)0), *tmp, *op1, *op2; | ||||||||
| 600 | int ret_int=0; | ||||||||
| 601 | PyArray_Descr *my_descr; | ||||||||
| 602 | if (out && (PyArray_SIZE(out)PyArray_MultiplyList(PyArray_DIMS(out), PyArray_NDIM(out)) != PyArray_SIZE(a)PyArray_MultiplyList(PyArray_DIMS(a), PyArray_NDIM(a)))) { | ||||||||
| 603 | PyErr_SetString(PyExc_ValueError, | ||||||||
| 604 | "invalid output shape"); | ||||||||
| 605 | return NULL((void*)0); | ||||||||
| 606 | } | ||||||||
| 607 | if (PyArray_ISCOMPLEX(a)(((PyArray_TYPE(a)) >= NPY_CFLOAT) && ((PyArray_TYPE (a)) <= NPY_CLONGDOUBLE))) { | ||||||||
| 608 | PyObject *part; | ||||||||
| 609 | PyObject *round_part; | ||||||||
| 610 | PyObject *arr; | ||||||||
| 611 | int res; | ||||||||
| 612 | |||||||||
| 613 | if (out) { | ||||||||
| 614 | arr = (PyObject *)out; | ||||||||
| 615 | Py_INCREF(arr)_Py_INCREF(((PyObject*)(arr))); | ||||||||
| 616 | } | ||||||||
| 617 | else { | ||||||||
| 618 | arr = PyArray_Copy(a)PyArray_NewCopy(a, NPY_CORDER); | ||||||||
| 619 | if (arr == NULL((void*)0)) { | ||||||||
| 620 | return NULL((void*)0); | ||||||||
| 621 | } | ||||||||
| 622 | } | ||||||||
| 623 | |||||||||
| 624 | /* arr.real = a.real.round(decimals) */ | ||||||||
| 625 | part = PyObject_GetAttrString((PyObject *)a, "real"); | ||||||||
| 626 | if (part == NULL((void*)0)) { | ||||||||
| 627 | Py_DECREF(arr)_Py_DECREF(((PyObject*)(arr))); | ||||||||
| 628 | return NULL((void*)0); | ||||||||
| 629 | } | ||||||||
| 630 | part = PyArray_EnsureAnyArray(part); | ||||||||
| 631 | round_part = PyArray_Round((PyArrayObject *)part, | ||||||||
| 632 | decimals, NULL((void*)0)); | ||||||||
| 633 | Py_DECREF(part)_Py_DECREF(((PyObject*)(part))); | ||||||||
| 634 | if (round_part == NULL((void*)0)) { | ||||||||
| 635 | Py_DECREF(arr)_Py_DECREF(((PyObject*)(arr))); | ||||||||
| 636 | return NULL((void*)0); | ||||||||
| 637 | } | ||||||||
| 638 | res = PyObject_SetAttrString(arr, "real", round_part); | ||||||||
| 639 | Py_DECREF(round_part)_Py_DECREF(((PyObject*)(round_part))); | ||||||||
| 640 | if (res < 0) { | ||||||||
| 641 | Py_DECREF(arr)_Py_DECREF(((PyObject*)(arr))); | ||||||||
| 642 | return NULL((void*)0); | ||||||||
| 643 | } | ||||||||
| 644 | |||||||||
| 645 | /* arr.imag = a.imag.round(decimals) */ | ||||||||
| 646 | part = PyObject_GetAttrString((PyObject *)a, "imag"); | ||||||||
| 647 | if (part == NULL((void*)0)) { | ||||||||
| 648 | Py_DECREF(arr)_Py_DECREF(((PyObject*)(arr))); | ||||||||
| 649 | return NULL((void*)0); | ||||||||
| 650 | } | ||||||||
| 651 | part = PyArray_EnsureAnyArray(part); | ||||||||
| 652 | round_part = PyArray_Round((PyArrayObject *)part, | ||||||||
| 653 | decimals, NULL((void*)0)); | ||||||||
| 654 | Py_DECREF(part)_Py_DECREF(((PyObject*)(part))); | ||||||||
| 655 | if (round_part == NULL((void*)0)) { | ||||||||
| 656 | Py_DECREF(arr)_Py_DECREF(((PyObject*)(arr))); | ||||||||
| 657 | return NULL((void*)0); | ||||||||
| 658 | } | ||||||||
| 659 | res = PyObject_SetAttrString(arr, "imag", round_part); | ||||||||
| 660 | Py_DECREF(round_part)_Py_DECREF(((PyObject*)(round_part))); | ||||||||
| 661 | if (res < 0) { | ||||||||
| 662 | Py_DECREF(arr)_Py_DECREF(((PyObject*)(arr))); | ||||||||
| 663 | return NULL((void*)0); | ||||||||
| 664 | } | ||||||||
| 665 | return arr; | ||||||||
| 666 | } | ||||||||
| 667 | /* do the most common case first */ | ||||||||
| 668 | if (decimals >= 0) { | ||||||||
| 669 | if (PyArray_ISINTEGER(a)(((PyArray_TYPE(a)) >= NPY_BYTE) && ((PyArray_TYPE (a)) <= NPY_ULONGLONG))) { | ||||||||
| 670 | if (out) { | ||||||||
| 671 | if (PyArray_AssignArray(out, a, | ||||||||
| 672 | NULL((void*)0), NPY_DEFAULT_ASSIGN_CASTING) < 0) { | ||||||||
| 673 | return NULL((void*)0); | ||||||||
| 674 | } | ||||||||
| 675 | Py_INCREF(out)_Py_INCREF(((PyObject*)(out))); | ||||||||
| 676 | return (PyObject *)out; | ||||||||
| 677 | } | ||||||||
| 678 | else { | ||||||||
| 679 | Py_INCREF(a)_Py_INCREF(((PyObject*)(a))); | ||||||||
| 680 | return (PyObject *)a; | ||||||||
| 681 | } | ||||||||
| 682 | } | ||||||||
| 683 | if (decimals == 0) { | ||||||||
| 684 | if (out) { | ||||||||
| 685 | return PyObject_CallFunction_PyObject_CallFunction_SizeT(n_ops.rint, "OO", a, out); | ||||||||
| 686 | } | ||||||||
| 687 | return PyObject_CallFunction_PyObject_CallFunction_SizeT(n_ops.rint, "O", a); | ||||||||
| 688 | } | ||||||||
| 689 | op1 = n_ops.multiply; | ||||||||
| 690 | op2 = n_ops.true_divide; | ||||||||
| 691 | } | ||||||||
| 692 | else { | ||||||||
| 693 | op1 = n_ops.true_divide; | ||||||||
| 694 | op2 = n_ops.multiply; | ||||||||
| 695 | decimals = -decimals; | ||||||||
| 696 | } | ||||||||
| 697 | if (!out) { | ||||||||
| 698 | if (PyArray_ISINTEGER(a)(((PyArray_TYPE(a)) >= NPY_BYTE) && ((PyArray_TYPE (a)) <= NPY_ULONGLONG))) { | ||||||||
| 699 | ret_int = 1; | ||||||||
| 700 | my_descr = PyArray_DescrFromType(NPY_DOUBLE); | ||||||||
| 701 | } | ||||||||
| 702 | else { | ||||||||
| 703 | Py_INCREF(PyArray_DESCR(a))_Py_INCREF(((PyObject*)(PyArray_DESCR(a)))); | ||||||||
| 704 | my_descr = PyArray_DESCR(a); | ||||||||
| 705 | } | ||||||||
| 706 | out = (PyArrayObject *)PyArray_Empty(PyArray_NDIM(a), PyArray_DIMS(a), | ||||||||
| 707 | my_descr, | ||||||||
| 708 | PyArray_ISFORTRAN(a)(PyArray_CHKFLAGS(a, 0x0002) && (!PyArray_CHKFLAGS(a, 0x0001)))); | ||||||||
| 709 | if (out == NULL((void*)0)) { | ||||||||
| 710 | return NULL((void*)0); | ||||||||
| 711 | } | ||||||||
| 712 | } | ||||||||
| 713 | else { | ||||||||
| 714 | Py_INCREF(out)_Py_INCREF(((PyObject*)(out))); | ||||||||
| 715 | } | ||||||||
| 716 | f = PyFloat_FromDouble(power_of_ten(decimals)); | ||||||||
| 717 | if (f == NULL((void*)0)) { | ||||||||
| 718 | return NULL((void*)0); | ||||||||
| 719 | } | ||||||||
| 720 | ret = PyObject_CallFunction_PyObject_CallFunction_SizeT(op1, "OOO", a, f, out); | ||||||||
| 721 | if (ret == NULL((void*)0)) { | ||||||||
| 722 | goto finish; | ||||||||
| 723 | } | ||||||||
| 724 | tmp = PyObject_CallFunction_PyObject_CallFunction_SizeT(n_ops.rint, "OO", ret, ret); | ||||||||
| 725 | if (tmp == NULL((void*)0)) { | ||||||||
| 726 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | ||||||||
| 727 | ret = NULL((void*)0); | ||||||||
| 728 | goto finish; | ||||||||
| 729 | } | ||||||||
| 730 | Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp))); | ||||||||
| 731 | tmp = PyObject_CallFunction_PyObject_CallFunction_SizeT(op2, "OOO", ret, f, ret); | ||||||||
| 732 | if (tmp == NULL((void*)0)) { | ||||||||
| 733 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | ||||||||
| 734 | ret = NULL((void*)0); | ||||||||
| 735 | goto finish; | ||||||||
| 736 | } | ||||||||
| 737 | Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp))); | ||||||||
| 738 | |||||||||
| 739 | finish: | ||||||||
| 740 | Py_DECREF(f)_Py_DECREF(((PyObject*)(f))); | ||||||||
| 741 | Py_DECREF(out)_Py_DECREF(((PyObject*)(out))); | ||||||||
| 742 | if (ret_int) { | ||||||||
| 743 | Py_INCREF(PyArray_DESCR(a))_Py_INCREF(((PyObject*)(PyArray_DESCR(a)))); | ||||||||
| 744 | tmp = PyArray_CastToType((PyArrayObject *)ret, | ||||||||
| 745 | PyArray_DESCR(a), PyArray_ISFORTRAN(a)(PyArray_CHKFLAGS(a, 0x0002) && (!PyArray_CHKFLAGS(a, 0x0001)))); | ||||||||
| 746 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | ||||||||
| 747 | return tmp; | ||||||||
| 748 | } | ||||||||
| 749 | return ret; | ||||||||
| 750 | } | ||||||||
| 751 | |||||||||
| 752 | |||||||||
| 753 | /*NUMPY_API | ||||||||
| 754 | * Mean | ||||||||
| 755 | */ | ||||||||
| 756 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
| 757 | PyArray_Mean(PyArrayObject *self, int axis, int rtype, PyArrayObject *out) | ||||||||
| 758 | { | ||||||||
| 759 | PyObject *obj1 = NULL((void*)0), *obj2 = NULL((void*)0), *ret; | ||||||||
| 760 | PyArrayObject *arr; | ||||||||
| 761 | |||||||||
| 762 | arr = (PyArrayObject *)PyArray_CheckAxis(self, &axis, 0); | ||||||||
| 763 | if (arr == NULL((void*)0)) { | ||||||||
| 764 | return NULL((void*)0); | ||||||||
| 765 | } | ||||||||
| 766 | obj1 = PyArray_GenericReduceFunction(arr, n_ops.add, axis, | ||||||||
| 767 | rtype, out); | ||||||||
| 768 | obj2 = PyFloat_FromDouble((double)PyArray_DIM(arr,axis)); | ||||||||
| 769 | Py_DECREF(arr)_Py_DECREF(((PyObject*)(arr))); | ||||||||
| 770 | if (obj1 == NULL((void*)0) || obj2 == NULL((void*)0)) { | ||||||||
| 771 | Py_XDECREF(obj1)_Py_XDECREF(((PyObject*)(obj1))); | ||||||||
| 772 | Py_XDECREF(obj2)_Py_XDECREF(((PyObject*)(obj2))); | ||||||||
| 773 | return NULL((void*)0); | ||||||||
| 774 | } | ||||||||
| 775 | if (!out) { | ||||||||
| 776 | ret = PyNumber_TrueDivide(obj1, obj2); | ||||||||
| 777 | } | ||||||||
| 778 | else { | ||||||||
| 779 | ret = PyObject_CallFunction_PyObject_CallFunction_SizeT(n_ops.divide, "OOO", out, obj2, out); | ||||||||
| 780 | } | ||||||||
| 781 | Py_DECREF(obj1)_Py_DECREF(((PyObject*)(obj1))); | ||||||||
| 782 | Py_DECREF(obj2)_Py_DECREF(((PyObject*)(obj2))); | ||||||||
| 783 | return ret; | ||||||||
| 784 | } | ||||||||
| 785 | |||||||||
| 786 | /*NUMPY_API | ||||||||
| 787 | * Any | ||||||||
| 788 | */ | ||||||||
| 789 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
| 790 | PyArray_Any(PyArrayObject *self, int axis, PyArrayObject *out) | ||||||||
| 791 | { | ||||||||
| 792 | PyObject *arr, *ret; | ||||||||
| 793 | |||||||||
| 794 | arr = PyArray_CheckAxis(self, &axis, 0); | ||||||||
| 795 | if (arr == NULL((void*)0)) { | ||||||||
| 796 | return NULL((void*)0); | ||||||||
| 797 | } | ||||||||
| 798 | ret = PyArray_GenericReduceFunction((PyArrayObject *)arr, | ||||||||
| 799 | n_ops.logical_or, axis, | ||||||||
| 800 | NPY_BOOL, out); | ||||||||
| 801 | Py_DECREF(arr)_Py_DECREF(((PyObject*)(arr))); | ||||||||
| 802 | return ret; | ||||||||
| 803 | } | ||||||||
| 804 | |||||||||
| 805 | /*NUMPY_API | ||||||||
| 806 | * All | ||||||||
| 807 | */ | ||||||||
| 808 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
| 809 | PyArray_All(PyArrayObject *self, int axis, PyArrayObject *out) | ||||||||
| 810 | { | ||||||||
| 811 | PyObject *arr, *ret; | ||||||||
| 812 | |||||||||
| 813 | arr = PyArray_CheckAxis(self, &axis, 0); | ||||||||
| 814 | if (arr == NULL((void*)0)) { | ||||||||
| 815 | return NULL((void*)0); | ||||||||
| 816 | } | ||||||||
| 817 | ret = PyArray_GenericReduceFunction((PyArrayObject *)arr, | ||||||||
| 818 | n_ops.logical_and, axis, | ||||||||
| 819 | NPY_BOOL, out); | ||||||||
| 820 | Py_DECREF(arr)_Py_DECREF(((PyObject*)(arr))); | ||||||||
| 821 | return ret; | ||||||||
| 822 | } | ||||||||
| 823 | |||||||||
| 824 | |||||||||
| 825 | static PyObject * | ||||||||
| 826 | _GenericBinaryOutFunction(PyArrayObject *m1, PyObject *m2, PyArrayObject *out, | ||||||||
| 827 | PyObject *op) | ||||||||
| 828 | { | ||||||||
| 829 | if (out == NULL((void*)0)) { | ||||||||
| 830 | return PyObject_CallFunction_PyObject_CallFunction_SizeT(op, "OO", m1, m2); | ||||||||
| 831 | } | ||||||||
| 832 | else { | ||||||||
| 833 | PyObject *args, *ret; | ||||||||
| 834 | static PyObject *kw = NULL((void*)0); | ||||||||
| 835 | |||||||||
| 836 | if (kw == NULL((void*)0)) { | ||||||||
| 837 | kw = Py_BuildValue_Py_BuildValue_SizeT("{s:s}", "casting", "unsafe"); | ||||||||
| 838 | if (kw == NULL((void*)0)) { | ||||||||
| 839 | return NULL((void*)0); | ||||||||
| 840 | } | ||||||||
| 841 | } | ||||||||
| 842 | |||||||||
| 843 | args = Py_BuildValue_Py_BuildValue_SizeT("OOO", m1, m2, out); | ||||||||
| 844 | if (args == NULL((void*)0)) { | ||||||||
| 845 | return NULL((void*)0); | ||||||||
| 846 | } | ||||||||
| 847 | |||||||||
| 848 | ret = PyObject_Call(op, args, kw); | ||||||||
| 849 | |||||||||
| 850 | Py_DECREF(args)_Py_DECREF(((PyObject*)(args))); | ||||||||
| 851 | |||||||||
| 852 | return ret; | ||||||||
| 853 | } | ||||||||
| 854 | } | ||||||||
| 855 | |||||||||
| 856 | static PyObject * | ||||||||
| 857 | _slow_array_clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *out) | ||||||||
| 858 | { | ||||||||
| 859 | PyObject *res1=NULL((void*)0), *res2=NULL((void*)0); | ||||||||
| 860 | |||||||||
| 861 | if (max != NULL((void*)0)) { | ||||||||
| 862 | res1 = _GenericBinaryOutFunction(self, max, out, n_ops.minimum); | ||||||||
| 863 | if (res1 == NULL((void*)0)) { | ||||||||
| 864 | return NULL((void*)0); | ||||||||
| 865 | } | ||||||||
| 866 | } | ||||||||
| 867 | else { | ||||||||
| 868 | res1 = (PyObject *)self; | ||||||||
| 869 | Py_INCREF(res1)_Py_INCREF(((PyObject*)(res1))); | ||||||||
| 870 | } | ||||||||
| 871 | |||||||||
| 872 | if (min != NULL((void*)0)) { | ||||||||
| 873 | res2 = _GenericBinaryOutFunction((PyArrayObject *)res1, | ||||||||
| 874 | min, out, n_ops.maximum); | ||||||||
| 875 | if (res2 == NULL((void*)0)) { | ||||||||
| 876 | Py_XDECREF(res1)_Py_XDECREF(((PyObject*)(res1))); | ||||||||
| 877 | return NULL((void*)0); | ||||||||
| 878 | } | ||||||||
| 879 | } | ||||||||
| 880 | else { | ||||||||
| 881 | res2 = res1; | ||||||||
| 882 | Py_INCREF(res2)_Py_INCREF(((PyObject*)(res2))); | ||||||||
| 883 | } | ||||||||
| 884 | Py_DECREF(res1)_Py_DECREF(((PyObject*)(res1))); | ||||||||
| 885 | return res2; | ||||||||
| 886 | } | ||||||||
| 887 | |||||||||
| 888 | /*NUMPY_API | ||||||||
| 889 | * Clip | ||||||||
| 890 | */ | ||||||||
| 891 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
| 892 | PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *out) | ||||||||
| 893 | { | ||||||||
| 894 | PyArray_FastClipFunc *func; | ||||||||
| 895 | int outgood = 0, ingood = 0; | ||||||||
| 896 | PyArrayObject *maxa = NULL((void*)0); | ||||||||
| 897 | PyArrayObject *mina = NULL((void*)0); | ||||||||
| 898 | PyArrayObject *newout = NULL((void*)0), *newin = NULL((void*)0); | ||||||||
| 899 | PyArray_Descr *indescr = NULL((void*)0), *newdescr = NULL((void*)0); | ||||||||
| 900 | char *max_data, *min_data; | ||||||||
| 901 | PyObject *zero; | ||||||||
| 902 | |||||||||
| 903 | /* Treat None the same as NULL */ | ||||||||
| 904 | if (min == Py_None(&_Py_NoneStruct)) { | ||||||||
| 905 | min = NULL((void*)0); | ||||||||
| 906 | } | ||||||||
| 907 | if (max == Py_None(&_Py_NoneStruct)) { | ||||||||
| 908 | max = NULL((void*)0); | ||||||||
| 909 | } | ||||||||
| 910 | |||||||||
| 911 | if ((max == NULL((void*)0)) && (min == NULL((void*)0))) { | ||||||||
| 912 | PyErr_SetString(PyExc_ValueError, | ||||||||
| 913 | "array_clip: must set either max or min"); | ||||||||
| 914 | return NULL((void*)0); | ||||||||
| 915 | } | ||||||||
| 916 | |||||||||
| 917 | func = PyArray_DESCR(self)->f->fastclip; | ||||||||
| 918 | if (func == NULL((void*)0)) { | ||||||||
| 919 | if (min == NULL((void*)0)) { | ||||||||
| 920 | return PyObject_CallFunctionObjArgs(n_ops.minimum, self, max, out, NULL((void*)0)); | ||||||||
| 921 | } | ||||||||
| 922 | else if (max == NULL((void*)0)) { | ||||||||
| 923 | return PyObject_CallFunctionObjArgs(n_ops.maximum, self, min, out, NULL((void*)0)); | ||||||||
| 924 | } | ||||||||
| 925 | else { | ||||||||
| 926 | return PyObject_CallFunctionObjArgs(n_ops.clip, self, min, max, out, NULL((void*)0)); | ||||||||
| 927 | } | ||||||||
| 928 | } | ||||||||
| 929 | |||||||||
| 930 | /* | ||||||||
| 931 | * NumPy 1.17.0, 2019-02-24 | ||||||||
| 932 | * NumPy 1.19.0, 2020-01-15 | ||||||||
| 933 | * | ||||||||
| 934 | * Setting `->f->fastclip to anything but NULL has been deprecated in 1.19 | ||||||||
| 935 | * the code path below was previously deprecated since 1.17. | ||||||||
| 936 | * (the deprecation moved to registration time instead of execution time) | ||||||||
| 937 | * everything below can be removed once this deprecation completes | ||||||||
| 938 | */ | ||||||||
| 939 | |||||||||
| 940 | if (func == NULL((void*)0) | ||||||||
| 941 | || (min != NULL((void*)0) && !PyArray_CheckAnyScalar(min)(((((((PyObject*)(min))->ob_type) == (&PyFloat_Type) || PyType_IsSubtype((((PyObject*)(min))->ob_type), (&PyFloat_Type ))) || ((((PyObject*)(min))->ob_type) == (&PyComplex_Type ) || PyType_IsSubtype((((PyObject*)(min))->ob_type), (& PyComplex_Type))) || ((((((PyObject*)(min))->ob_type))-> tp_flags & ((1UL << 24))) != 0) || ((((PyObject*)(min ))->ob_type) == &PyBool_Type)) || ((((((PyObject*)(min ))->ob_type))->tp_flags & ((1UL << 27))) != 0 ) || ((((((PyObject*)(min))->ob_type))->tp_flags & ( (1UL << 28))) != 0)) || ((((((PyObject*)(min))->ob_type ) == (&PyGenericArrType_Type) || PyType_IsSubtype((((PyObject *)(min))->ob_type), (&PyGenericArrType_Type)))) || ((( ((PyObject*)(min))->ob_type) == (&PyArray_Type) || PyType_IsSubtype ((((PyObject*)(min))->ob_type), (&PyArray_Type))) && (PyArray_NDIM((PyArrayObject *)min) == 0))))) | ||||||||
| 942 | || (max != NULL((void*)0) && !PyArray_CheckAnyScalar(max)(((((((PyObject*)(max))->ob_type) == (&PyFloat_Type) || PyType_IsSubtype((((PyObject*)(max))->ob_type), (&PyFloat_Type ))) || ((((PyObject*)(max))->ob_type) == (&PyComplex_Type ) || PyType_IsSubtype((((PyObject*)(max))->ob_type), (& PyComplex_Type))) || ((((((PyObject*)(max))->ob_type))-> tp_flags & ((1UL << 24))) != 0) || ((((PyObject*)(max ))->ob_type) == &PyBool_Type)) || ((((((PyObject*)(max ))->ob_type))->tp_flags & ((1UL << 27))) != 0 ) || ((((((PyObject*)(max))->ob_type))->tp_flags & ( (1UL << 28))) != 0)) || ((((((PyObject*)(max))->ob_type ) == (&PyGenericArrType_Type) || PyType_IsSubtype((((PyObject *)(max))->ob_type), (&PyGenericArrType_Type)))) || ((( ((PyObject*)(max))->ob_type) == (&PyArray_Type) || PyType_IsSubtype ((((PyObject*)(max))->ob_type), (&PyArray_Type))) && (PyArray_NDIM((PyArrayObject *)max) == 0))))) | ||||||||
| 943 | || PyArray_ISBYTESWAPPED(self)(!((PyArray_DESCR(self)->byteorder) != '>')) | ||||||||
| 944 | || (out && PyArray_ISBYTESWAPPED(out)(!((PyArray_DESCR(out)->byteorder) != '>')))) { | ||||||||
| 945 | return _slow_array_clip(self, min, max, out); | ||||||||
| 946 | } | ||||||||
| 947 | /* Use the fast scalar clip function */ | ||||||||
| 948 | |||||||||
| 949 | /* First we need to figure out the correct type */ | ||||||||
| 950 | if (min != NULL((void*)0)) { | ||||||||
| 951 | indescr = PyArray_DescrFromObject(min, NULL((void*)0)); | ||||||||
| 952 | if (indescr == NULL((void*)0)) { | ||||||||
| 953 | goto fail; | ||||||||
| 954 | } | ||||||||
| 955 | } | ||||||||
| 956 | if (max != NULL((void*)0)) { | ||||||||
| 957 | newdescr = PyArray_DescrFromObject(max, indescr); | ||||||||
| 958 | Py_XDECREF(indescr)_Py_XDECREF(((PyObject*)(indescr))); | ||||||||
| 959 | indescr = NULL((void*)0); | ||||||||
| 960 | if (newdescr == NULL((void*)0)) { | ||||||||
| 961 | goto fail; | ||||||||
| 962 | } | ||||||||
| 963 | } | ||||||||
| 964 | else { | ||||||||
| 965 | /* Steal the reference */ | ||||||||
| 966 | newdescr = indescr; | ||||||||
| 967 | indescr = NULL((void*)0); | ||||||||
| 968 | } | ||||||||
| 969 | |||||||||
| 970 | |||||||||
| 971 | /* | ||||||||
| 972 | * Use the scalar descriptor only if it is of a bigger | ||||||||
| 973 | * KIND than the input array (and then find the | ||||||||
| 974 | * type that matches both). | ||||||||
| 975 | */ | ||||||||
| 976 | if (PyArray_ScalarKind(newdescr->type_num, NULL((void*)0)) > | ||||||||
| 977 | PyArray_ScalarKind(PyArray_DESCR(self)->type_num, NULL((void*)0))) { | ||||||||
| 978 | indescr = PyArray_PromoteTypes(newdescr, PyArray_DESCR(self)); | ||||||||
| 979 | if (indescr == NULL((void*)0)) { | ||||||||
| 980 | goto fail; | ||||||||
| 981 | } | ||||||||
| 982 | func = indescr->f->fastclip; | ||||||||
| 983 | if (func == NULL((void*)0)) { | ||||||||
| 984 | Py_DECREF(indescr)_Py_DECREF(((PyObject*)(indescr))); | ||||||||
| 985 | return _slow_array_clip(self, min, max, out); | ||||||||
| 986 | } | ||||||||
| 987 | } | ||||||||
| 988 | else { | ||||||||
| 989 | indescr = PyArray_DESCR(self); | ||||||||
| 990 | Py_INCREF(indescr)_Py_INCREF(((PyObject*)(indescr))); | ||||||||
| 991 | } | ||||||||
| 992 | Py_DECREF(newdescr)_Py_DECREF(((PyObject*)(newdescr))); | ||||||||
| 993 | newdescr = NULL((void*)0); | ||||||||
| 994 | |||||||||
| 995 | if (!PyDataType_ISNOTSWAPPED(indescr)((((PyArray_Descr *)(indescr))->byteorder) != '>')) { | ||||||||
| 996 | PyArray_Descr *descr2; | ||||||||
| 997 | descr2 = PyArray_DescrNewByteorder(indescr, '='); | ||||||||
| 998 | Py_DECREF(indescr)_Py_DECREF(((PyObject*)(indescr))); | ||||||||
| 999 | indescr = NULL((void*)0); | ||||||||
| 1000 | if (descr2 == NULL((void*)0)) { | ||||||||
| 1001 | goto fail; | ||||||||
| 1002 | } | ||||||||
| 1003 | indescr = descr2; | ||||||||
| 1004 | } | ||||||||
| 1005 | |||||||||
| 1006 | /* Convert max to an array */ | ||||||||
| 1007 | if (max != NULL((void*)0)) { | ||||||||
| 1008 | Py_INCREF(indescr)_Py_INCREF(((PyObject*)(indescr))); | ||||||||
| 1009 | maxa = (PyArrayObject *)PyArray_FromAny(max, indescr, 0, 0, | ||||||||
| 1010 | NPY_ARRAY_DEFAULT((0x0001 | (0x0100 | 0x0400))), NULL((void*)0)); | ||||||||
| 1011 | if (maxa == NULL((void*)0)) { | ||||||||
| 1012 | goto fail; | ||||||||
| 1013 | } | ||||||||
| 1014 | } | ||||||||
| 1015 | |||||||||
| 1016 | /* | ||||||||
| 1017 | * If we are unsigned, then make sure min is not < 0 | ||||||||
| 1018 | * This is to match the behavior of _slow_array_clip | ||||||||
| 1019 | * | ||||||||
| 1020 | * We allow min and max to go beyond the limits | ||||||||
| 1021 | * for other data-types in which case they | ||||||||
| 1022 | * are interpreted as their modular counterparts. | ||||||||
| 1023 | */ | ||||||||
| 1024 | if (min != NULL((void*)0)) { | ||||||||
| 1025 | if (PyArray_ISUNSIGNED(self)(((PyArray_TYPE(self)) == NPY_UBYTE) || ((PyArray_TYPE(self)) == NPY_USHORT) || ((PyArray_TYPE(self)) == NPY_UINT) || ((PyArray_TYPE (self)) == NPY_ULONG) || ((PyArray_TYPE(self)) == NPY_ULONGLONG ))) { | ||||||||
| 1026 | int cmp; | ||||||||
| 1027 | zero = PyLong_FromLong(0); | ||||||||
| 1028 | cmp = PyObject_RichCompareBool(min, zero, Py_LT0); | ||||||||
| 1029 | if (cmp == -1) { | ||||||||
| 1030 | Py_DECREF(zero)_Py_DECREF(((PyObject*)(zero))); | ||||||||
| 1031 | goto fail; | ||||||||
| 1032 | } | ||||||||
| 1033 | if (cmp == 1) { | ||||||||
| 1034 | min = zero; | ||||||||
| 1035 | } | ||||||||
| 1036 | else { | ||||||||
| 1037 | Py_DECREF(zero)_Py_DECREF(((PyObject*)(zero))); | ||||||||
| 1038 | Py_INCREF(min)_Py_INCREF(((PyObject*)(min))); | ||||||||
| 1039 | } | ||||||||
| 1040 | } | ||||||||
| 1041 | else { | ||||||||
| 1042 | Py_INCREF(min)_Py_INCREF(((PyObject*)(min))); | ||||||||
| 1043 | } | ||||||||
| 1044 | |||||||||
| 1045 | /* Convert min to an array */ | ||||||||
| 1046 | Py_INCREF(indescr)_Py_INCREF(((PyObject*)(indescr))); | ||||||||
| 1047 | mina = (PyArrayObject *)PyArray_FromAny(min, indescr, 0, 0, | ||||||||
| 1048 | NPY_ARRAY_DEFAULT((0x0001 | (0x0100 | 0x0400))), NULL((void*)0)); | ||||||||
| 1049 | Py_DECREF(min)_Py_DECREF(((PyObject*)(min))); | ||||||||
| 1050 | if (mina == NULL((void*)0)) { | ||||||||
| 1051 | goto fail; | ||||||||
| 1052 | } | ||||||||
| 1053 | } | ||||||||
| 1054 | |||||||||
| 1055 | /* | ||||||||
| 1056 | * Check to see if input is single-segment, aligned, | ||||||||
| 1057 | * and in native byteorder | ||||||||
| 1058 | */ | ||||||||
| 1059 | if (PyArray_ISONESEGMENT(self)(PyArray_CHKFLAGS(self, 0x0001) || PyArray_CHKFLAGS(self, 0x0002 )) && | ||||||||
| 1060 | PyArray_CHKFLAGS(self, NPY_ARRAY_ALIGNED0x0100) && | ||||||||
| 1061 | PyArray_ISNOTSWAPPED(self)((PyArray_DESCR(self)->byteorder) != '>') && | ||||||||
| 1062 | (PyArray_DESCR(self) == indescr)) { | ||||||||
| 1063 | ingood = 1; | ||||||||
| 1064 | } | ||||||||
| 1065 | if (!ingood) { | ||||||||
| 1066 | int flags; | ||||||||
| 1067 | |||||||||
| 1068 | if (PyArray_ISFORTRAN(self)(PyArray_CHKFLAGS(self, 0x0002) && (!PyArray_CHKFLAGS (self, 0x0001)))) { | ||||||||
| 1069 | flags = NPY_ARRAY_FARRAY(0x0002 | (0x0100 | 0x0400)); | ||||||||
| 1070 | } | ||||||||
| 1071 | else { | ||||||||
| 1072 | flags = NPY_ARRAY_CARRAY(0x0001 | (0x0100 | 0x0400)); | ||||||||
| 1073 | } | ||||||||
| 1074 | Py_INCREF(indescr)_Py_INCREF(((PyObject*)(indescr))); | ||||||||
| 1075 | newin = (PyArrayObject *)PyArray_FromArray(self, indescr, flags); | ||||||||
| 1076 | if (newin == NULL((void*)0)) { | ||||||||
| 1077 | goto fail; | ||||||||
| 1078 | } | ||||||||
| 1079 | } | ||||||||
| 1080 | else { | ||||||||
| 1081 | newin = self; | ||||||||
| 1082 | Py_INCREF(newin)_Py_INCREF(((PyObject*)(newin))); | ||||||||
| 1083 | } | ||||||||
| 1084 | |||||||||
| 1085 | /* | ||||||||
| 1086 | * At this point, newin is a single-segment, aligned, and correct | ||||||||
| 1087 | * byte-order array of the correct type | ||||||||
| 1088 | * | ||||||||
| 1089 | * if ingood == 0, then it is a copy, otherwise, | ||||||||
| 1090 | * it is the original input. | ||||||||
| 1091 | */ | ||||||||
| 1092 | |||||||||
| 1093 | /* | ||||||||
| 1094 | * If we have already made a copy of the data, then use | ||||||||
| 1095 | * that as the output array | ||||||||
| 1096 | */ | ||||||||
| 1097 | if (out == NULL((void*)0) && !ingood) { | ||||||||
| 1098 | out = newin; | ||||||||
| 1099 | } | ||||||||
| 1100 | |||||||||
| 1101 | /* | ||||||||
| 1102 | * Now, we know newin is a usable array for fastclip, | ||||||||
| 1103 | * we need to make sure the output array is available | ||||||||
| 1104 | * and usable | ||||||||
| 1105 | */ | ||||||||
| 1106 | if (out == NULL((void*)0)) { | ||||||||
| 1107 | Py_INCREF(indescr)_Py_INCREF(((PyObject*)(indescr))); | ||||||||
| 1108 | out = (PyArrayObject*)PyArray_NewFromDescr(Py_TYPE(self)(((PyObject*)(self))->ob_type), | ||||||||
| 1109 | indescr, PyArray_NDIM(self), | ||||||||
| 1110 | PyArray_DIMS(self), | ||||||||
| 1111 | NULL((void*)0), NULL((void*)0), | ||||||||
| 1112 | PyArray_ISFORTRAN(self)(PyArray_CHKFLAGS(self, 0x0002) && (!PyArray_CHKFLAGS (self, 0x0001))), | ||||||||
| 1113 | (PyObject *)self); | ||||||||
| 1114 | if (out == NULL((void*)0)) { | ||||||||
| 1115 | goto fail; | ||||||||
| 1116 | } | ||||||||
| 1117 | |||||||||
| 1118 | outgood = 1; | ||||||||
| 1119 | } | ||||||||
| 1120 | else Py_INCREF(out)_Py_INCREF(((PyObject*)(out))); | ||||||||
| 1121 | /* Input is good at this point */ | ||||||||
| 1122 | if (out == newin) { | ||||||||
| 1123 | outgood = 1; | ||||||||
| 1124 | } | ||||||||
| 1125 | |||||||||
| 1126 | |||||||||
| 1127 | /* make sure the shape of the output array is the same */ | ||||||||
| 1128 | if (!PyArray_SAMESHAPE(newin, out)((PyArray_NDIM(newin) == PyArray_NDIM(out)) && PyArray_CompareLists (PyArray_DIMS(newin), PyArray_DIMS(out), PyArray_NDIM(newin)) )) { | ||||||||
| 1129 | PyErr_SetString(PyExc_ValueError, "clip: Output array must have the" | ||||||||
| 1130 | "same shape as the input."); | ||||||||
| 1131 | goto fail; | ||||||||
| 1132 | } | ||||||||
| 1133 | |||||||||
| 1134 | if (!outgood && PyArray_EQUIVALENTLY_ITERABLE(( ( PyArray_NDIM(self) == PyArray_NDIM(out) && PyArray_CompareLists (PyArray_DIMS(self), PyArray_DIMS(out), PyArray_NDIM(self)) && (PyArray_FLAGS(self)&(0x0001| 0x0002)) & (PyArray_FLAGS (out)&(0x0001| 0x0002)) ) && PyArray_EQUIVALENTLY_ITERABLE_OVERLAP_OK ( self, out, 1, 0)) | ||||||||
| 1135 | self, out, PyArray_TRIVIALLY_ITERABLE_OP_READ,( ( PyArray_NDIM(self) == PyArray_NDIM(out) && PyArray_CompareLists (PyArray_DIMS(self), PyArray_DIMS(out), PyArray_NDIM(self)) && (PyArray_FLAGS(self)&(0x0001| 0x0002)) & (PyArray_FLAGS (out)&(0x0001| 0x0002)) ) && PyArray_EQUIVALENTLY_ITERABLE_OVERLAP_OK ( self, out, 1, 0)) | ||||||||
| 1136 | PyArray_TRIVIALLY_ITERABLE_OP_NOREAD)( ( PyArray_NDIM(self) == PyArray_NDIM(out) && PyArray_CompareLists (PyArray_DIMS(self), PyArray_DIMS(out), PyArray_NDIM(self)) && (PyArray_FLAGS(self)&(0x0001| 0x0002)) & (PyArray_FLAGS (out)&(0x0001| 0x0002)) ) && PyArray_EQUIVALENTLY_ITERABLE_OVERLAP_OK ( self, out, 1, 0)) && | ||||||||
| 1137 | PyArray_CHKFLAGS(out, NPY_ARRAY_ALIGNED0x0100) && | ||||||||
| 1138 | PyArray_ISNOTSWAPPED(out)((PyArray_DESCR(out)->byteorder) != '>') && | ||||||||
| 1139 | PyArray_EquivTypes(PyArray_DESCR(out), indescr)) { | ||||||||
| 1140 | outgood = 1; | ||||||||
| 1141 | } | ||||||||
| 1142 | |||||||||
| 1143 | /* | ||||||||
| 1144 | * Do we still not have a suitable output array? | ||||||||
| 1145 | * Create one, now. No matter why the array is not suitable a copy has | ||||||||
| 1146 | * to be made. This may be just to avoid memory overlap though. | ||||||||
| 1147 | */ | ||||||||
| 1148 | if (!outgood) { | ||||||||
| 1149 | int oflags; | ||||||||
| 1150 | if (PyArray_ISFORTRAN(self)(PyArray_CHKFLAGS(self, 0x0002) && (!PyArray_CHKFLAGS (self, 0x0001)))) { | ||||||||
| 1151 | oflags = NPY_ARRAY_FARRAY(0x0002 | (0x0100 | 0x0400)); | ||||||||
| 1152 | } | ||||||||
| 1153 | else { | ||||||||
| 1154 | oflags = NPY_ARRAY_CARRAY(0x0001 | (0x0100 | 0x0400)); | ||||||||
| 1155 | } | ||||||||
| 1156 | oflags |= (NPY_ARRAY_WRITEBACKIFCOPY0x2000 | NPY_ARRAY_FORCECAST0x0010 | | ||||||||
| 1157 | NPY_ARRAY_ENSURECOPY0x0020); | ||||||||
| 1158 | Py_INCREF(indescr)_Py_INCREF(((PyObject*)(indescr))); | ||||||||
| 1159 | newout = (PyArrayObject*)PyArray_FromArray(out, indescr, oflags); | ||||||||
| 1160 | if (newout == NULL((void*)0)) { | ||||||||
| 1161 | goto fail; | ||||||||
| 1162 | } | ||||||||
| 1163 | } | ||||||||
| 1164 | else { | ||||||||
| 1165 | newout = out; | ||||||||
| 1166 | Py_INCREF(newout)_Py_INCREF(((PyObject*)(newout))); | ||||||||
| 1167 | } | ||||||||
| 1168 | |||||||||
| 1169 | /* Now we can call the fast-clip function */ | ||||||||
| 1170 | min_data = max_data = NULL((void*)0); | ||||||||
| 1171 | if (mina != NULL((void*)0)) { | ||||||||
| 1172 | min_data = PyArray_DATA(mina); | ||||||||
| 1173 | } | ||||||||
| 1174 | if (maxa != NULL((void*)0)) { | ||||||||
| 1175 | max_data = PyArray_DATA(maxa); | ||||||||
| 1176 | } | ||||||||
| 1177 | func(PyArray_DATA(newin), PyArray_SIZE(newin)PyArray_MultiplyList(PyArray_DIMS(newin), PyArray_NDIM(newin) ), min_data, max_data, PyArray_DATA(newout)); | ||||||||
| 1178 | |||||||||
| 1179 | /* Clean up temporary variables */ | ||||||||
| 1180 | Py_XDECREF(indescr)_Py_XDECREF(((PyObject*)(indescr))); | ||||||||
| 1181 | Py_XDECREF(newdescr)_Py_XDECREF(((PyObject*)(newdescr))); | ||||||||
| 1182 | Py_XDECREF(mina)_Py_XDECREF(((PyObject*)(mina))); | ||||||||
| 1183 | Py_XDECREF(maxa)_Py_XDECREF(((PyObject*)(maxa))); | ||||||||
| 1184 | Py_DECREF(newin)_Py_DECREF(((PyObject*)(newin))); | ||||||||
| 1185 | /* Copy back into out if out was not already a nice array. */ | ||||||||
| 1186 | PyArray_ResolveWritebackIfCopy(newout); | ||||||||
| 1187 | Py_DECREF(newout)_Py_DECREF(((PyObject*)(newout))); | ||||||||
| 1188 | return (PyObject *)out; | ||||||||
| 1189 | |||||||||
| 1190 | fail: | ||||||||
| 1191 | Py_XDECREF(indescr)_Py_XDECREF(((PyObject*)(indescr))); | ||||||||
| 1192 | Py_XDECREF(newdescr)_Py_XDECREF(((PyObject*)(newdescr))); | ||||||||
| 1193 | Py_XDECREF(maxa)_Py_XDECREF(((PyObject*)(maxa))); | ||||||||
| 1194 | Py_XDECREF(mina)_Py_XDECREF(((PyObject*)(mina))); | ||||||||
| 1195 | Py_XDECREF(newin)_Py_XDECREF(((PyObject*)(newin))); | ||||||||
| 1196 | PyArray_DiscardWritebackIfCopy(newout); | ||||||||
| 1197 | Py_XDECREF(newout)_Py_XDECREF(((PyObject*)(newout))); | ||||||||
| 1198 | return NULL((void*)0); | ||||||||
| 1199 | } | ||||||||
| 1200 | |||||||||
| 1201 | |||||||||
| 1202 | /*NUMPY_API | ||||||||
| 1203 | * Conjugate | ||||||||
| 1204 | */ | ||||||||
| 1205 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
| 1206 | PyArray_Conjugate(PyArrayObject *self, PyArrayObject *out) | ||||||||
| 1207 | { | ||||||||
| 1208 | if (PyArray_ISCOMPLEX(self)(((PyArray_TYPE(self)) >= NPY_CFLOAT) && ((PyArray_TYPE (self)) <= NPY_CLONGDOUBLE)) || PyArray_ISOBJECT(self)((PyArray_TYPE(self)) == NPY_OBJECT) || | ||||||||
| 1209 | PyArray_ISUSERDEF(self)(((PyArray_TYPE(self)) >= NPY_USERDEF) && ((PyArray_TYPE (self)) < NPY_USERDEF+ NPY_NUMUSERTYPES))) { | ||||||||
| 1210 | if (out == NULL((void*)0)) { | ||||||||
| 1211 | return PyArray_GenericUnaryFunction(self, | ||||||||
| 1212 | n_ops.conjugate); | ||||||||
| 1213 | } | ||||||||
| 1214 | else { | ||||||||
| 1215 | return PyArray_GenericBinaryFunction((PyObject *)self, | ||||||||
| 1216 | (PyObject *)out, | ||||||||
| 1217 | n_ops.conjugate); | ||||||||
| 1218 | } | ||||||||
| 1219 | } | ||||||||
| 1220 | else { | ||||||||
| 1221 | PyArrayObject *ret; | ||||||||
| 1222 | if (!PyArray_ISNUMBER(self)(((PyArray_TYPE(self)) <= NPY_CLONGDOUBLE) || ((PyArray_TYPE (self)) == NPY_HALF))) { | ||||||||
| 1223 | /* 2017-05-04, 1.13 */ | ||||||||
| 1224 | if (DEPRECATE("attempting to conjugate non-numeric dtype; this "PyErr_WarnEx(PyExc_DeprecationWarning,"attempting to conjugate non-numeric dtype; this " "will error in the future to match the behavior of " "np.conjugate" ,1) | ||||||||
| 1225 | "will error in the future to match the behavior of "PyErr_WarnEx(PyExc_DeprecationWarning,"attempting to conjugate non-numeric dtype; this " "will error in the future to match the behavior of " "np.conjugate" ,1) | ||||||||
| 1226 | "np.conjugate")PyErr_WarnEx(PyExc_DeprecationWarning,"attempting to conjugate non-numeric dtype; this " "will error in the future to match the behavior of " "np.conjugate" ,1) < 0) { | ||||||||
| 1227 | return NULL((void*)0); | ||||||||
| 1228 | } | ||||||||
| 1229 | } | ||||||||
| 1230 | if (out) { | ||||||||
| 1231 | if (PyArray_AssignArray(out, self, | ||||||||
| 1232 | NULL((void*)0), NPY_DEFAULT_ASSIGN_CASTING) < 0) { | ||||||||
| 1233 | return NULL((void*)0); | ||||||||
| 1234 | } | ||||||||
| 1235 | ret = out; | ||||||||
| 1236 | } | ||||||||
| 1237 | else { | ||||||||
| 1238 | ret = self; | ||||||||
| 1239 | } | ||||||||
| 1240 | Py_INCREF(ret)_Py_INCREF(((PyObject*)(ret))); | ||||||||
| 1241 | return (PyObject *)ret; | ||||||||
| 1242 | } | ||||||||
| 1243 | } | ||||||||
| 1244 | |||||||||
| 1245 | /*NUMPY_API | ||||||||
| 1246 | * Trace | ||||||||
| 1247 | */ | ||||||||
| 1248 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | ||||||||
| 1249 | PyArray_Trace(PyArrayObject *self, int offset, int axis1, int axis2, | ||||||||
| 1250 | int rtype, PyArrayObject *out) | ||||||||
| 1251 | { | ||||||||
| 1252 | PyObject *diag = NULL((void*)0), *ret = NULL((void*)0); | ||||||||
| 1253 | |||||||||
| 1254 | diag = PyArray_Diagonal(self, offset, axis1, axis2); | ||||||||
| 1255 | if (diag == NULL((void*)0)) { | ||||||||
| 1256 | return NULL((void*)0); | ||||||||
| 1257 | } | ||||||||
| 1258 | ret = PyArray_GenericReduceFunction((PyArrayObject *)diag, n_ops.add, -1, rtype, out); | ||||||||
| 1259 | Py_DECREF(diag)_Py_DECREF(((PyObject*)(diag))); | ||||||||
| 1260 | return ret; | ||||||||
| 1261 | } |
| 1 | #define PY_SSIZE_T_CLEAN | |||
| 2 | #include <Python.h> | |||
| 3 | #include "structmember.h" | |||
| 4 | ||||
| 5 | /*#include <stdio.h>*/ | |||
| 6 | #define NPY_NO_DEPRECATED_API0x0000000E NPY_API_VERSION0x0000000E | |||
| 7 | #define _MULTIARRAYMODULE | |||
| 8 | #include "numpy/arrayobject.h" | |||
| 9 | ||||
| 10 | #include "npy_config.h" | |||
| 11 | #include "npy_pycompat.h" | |||
| 12 | #include "npy_import.h" | |||
| 13 | #include "common.h" | |||
| 14 | #include "number.h" | |||
| 15 | #include "temp_elide.h" | |||
| 16 | ||||
| 17 | #include "binop_override.h" | |||
| 18 | #include "ufunc_override.h" | |||
| 19 | #include "abstractdtypes.h" | |||
| 20 | #include "common_dtype.h" | |||
| 21 | #include "convert_datatype.h" | |||
| 22 | ||||
| 23 | /************************************************************************* | |||
| 24 | **************** Implement Number Protocol **************************** | |||
| 25 | *************************************************************************/ | |||
| 26 | ||||
| 27 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) NumericOps n_ops; /* NB: static objects initialized to zero */ | |||
| 28 | ||||
| 29 | /* | |||
| 30 | * Forward declarations. Might want to move functions around instead | |||
| 31 | */ | |||
| 32 | static PyObject * | |||
| 33 | array_inplace_add(PyArrayObject *m1, PyObject *m2); | |||
| 34 | static PyObject * | |||
| 35 | array_inplace_subtract(PyArrayObject *m1, PyObject *m2); | |||
| 36 | static PyObject * | |||
| 37 | array_inplace_multiply(PyArrayObject *m1, PyObject *m2); | |||
| 38 | static PyObject * | |||
| 39 | array_inplace_true_divide(PyArrayObject *m1, PyObject *m2); | |||
| 40 | static PyObject * | |||
| 41 | array_inplace_floor_divide(PyArrayObject *m1, PyObject *m2); | |||
| 42 | static PyObject * | |||
| 43 | array_inplace_bitwise_and(PyArrayObject *m1, PyObject *m2); | |||
| 44 | static PyObject * | |||
| 45 | array_inplace_bitwise_or(PyArrayObject *m1, PyObject *m2); | |||
| 46 | static PyObject * | |||
| 47 | array_inplace_bitwise_xor(PyArrayObject *m1, PyObject *m2); | |||
| 48 | static PyObject * | |||
| 49 | array_inplace_left_shift(PyArrayObject *m1, PyObject *m2); | |||
| 50 | static PyObject * | |||
| 51 | array_inplace_right_shift(PyArrayObject *m1, PyObject *m2); | |||
| 52 | static PyObject * | |||
| 53 | array_inplace_remainder(PyArrayObject *m1, PyObject *m2); | |||
| 54 | static PyObject * | |||
| 55 | array_inplace_power(PyArrayObject *a1, PyObject *o2, PyObject *NPY_UNUSED(modulo)(__NPY_UNUSED_TAGGEDmodulo) __attribute__ ((__unused__))); | |||
| 56 | ||||
| 57 | /* | |||
| 58 | * Dictionary can contain any of the numeric operations, by name. | |||
| 59 | * Those not present will not be changed | |||
| 60 | */ | |||
| 61 | ||||
| 62 | /* FIXME - macro contains a return */ | |||
| 63 | #define SET(op) temp = _PyDict_GetItemStringWithError(dict, #op); \ | |||
| 64 | if (temp == NULL((void*)0) && PyErr_Occurred()) { \ | |||
| 65 | return -1; \ | |||
| 66 | } \ | |||
| 67 | else if (temp != NULL((void*)0)) { \ | |||
| 68 | if (!(PyCallable_Check(temp))) { \ | |||
| 69 | return -1; \ | |||
| 70 | } \ | |||
| 71 | Py_INCREF(temp)_Py_INCREF(((PyObject*)(temp))); \ | |||
| 72 | Py_XDECREF(n_ops.op)_Py_XDECREF(((PyObject*)(n_ops.op))); \ | |||
| 73 | n_ops.op = temp; \ | |||
| 74 | } | |||
| 75 | ||||
| 76 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) int | |||
| 77 | _PyArray_SetNumericOps(PyObject *dict) | |||
| 78 | { | |||
| 79 | PyObject *temp = NULL((void*)0); | |||
| 80 | SET(add); | |||
| 81 | SET(subtract); | |||
| 82 | SET(multiply); | |||
| 83 | SET(divide); | |||
| 84 | SET(remainder); | |||
| 85 | SET(divmod); | |||
| 86 | SET(power); | |||
| 87 | SET(square); | |||
| 88 | SET(reciprocal); | |||
| 89 | SET(_ones_like); | |||
| 90 | SET(sqrt); | |||
| 91 | SET(cbrt); | |||
| 92 | SET(negative); | |||
| 93 | SET(positive); | |||
| 94 | SET(absolute); | |||
| 95 | SET(invert); | |||
| 96 | SET(left_shift); | |||
| 97 | SET(right_shift); | |||
| 98 | SET(bitwise_and); | |||
| 99 | SET(bitwise_or); | |||
| 100 | SET(bitwise_xor); | |||
| 101 | SET(less); | |||
| 102 | SET(less_equal); | |||
| 103 | SET(equal); | |||
| 104 | SET(not_equal); | |||
| 105 | SET(greater); | |||
| 106 | SET(greater_equal); | |||
| 107 | SET(floor_divide); | |||
| 108 | SET(true_divide); | |||
| 109 | SET(logical_or); | |||
| 110 | SET(logical_and); | |||
| 111 | SET(floor); | |||
| 112 | SET(ceil); | |||
| 113 | SET(maximum); | |||
| 114 | SET(minimum); | |||
| 115 | SET(rint); | |||
| 116 | SET(conjugate); | |||
| 117 | SET(matmul); | |||
| 118 | SET(clip); | |||
| 119 | return 0; | |||
| 120 | } | |||
| 121 | ||||
| 122 | /*NUMPY_API | |||
| 123 | *Set internal structure with number functions that all arrays will use | |||
| 124 | */ | |||
| 125 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) int | |||
| 126 | PyArray_SetNumericOps(PyObject *dict) | |||
| 127 | { | |||
| 128 | /* 2018-09-09, 1.16 */ | |||
| 129 | if (DEPRECATE("PyArray_SetNumericOps is deprecated. Use "PyErr_WarnEx(PyExc_DeprecationWarning,"PyArray_SetNumericOps is deprecated. Use " "PyUFunc_ReplaceLoopBySignature to replace ufunc inner loop functions " "instead.",1) | |||
| 130 | "PyUFunc_ReplaceLoopBySignature to replace ufunc inner loop functions "PyErr_WarnEx(PyExc_DeprecationWarning,"PyArray_SetNumericOps is deprecated. Use " "PyUFunc_ReplaceLoopBySignature to replace ufunc inner loop functions " "instead.",1) | |||
| 131 | "instead.")PyErr_WarnEx(PyExc_DeprecationWarning,"PyArray_SetNumericOps is deprecated. Use " "PyUFunc_ReplaceLoopBySignature to replace ufunc inner loop functions " "instead.",1) < 0) { | |||
| 132 | return -1; | |||
| 133 | } | |||
| 134 | return _PyArray_SetNumericOps(dict); | |||
| 135 | } | |||
| 136 | ||||
| 137 | /* Note - macro contains goto */ | |||
| 138 | #define GET(op) if (n_ops.op && \ | |||
| 139 | (PyDict_SetItemString(dict, #op, n_ops.op)==-1)) \ | |||
| 140 | goto fail; | |||
| 141 | ||||
| 142 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | |||
| 143 | _PyArray_GetNumericOps(void) | |||
| 144 | { | |||
| 145 | PyObject *dict; | |||
| 146 | if ((dict = PyDict_New())==NULL((void*)0)) | |||
| 147 | return NULL((void*)0); | |||
| 148 | GET(add); | |||
| 149 | GET(subtract); | |||
| 150 | GET(multiply); | |||
| 151 | GET(divide); | |||
| 152 | GET(remainder); | |||
| 153 | GET(divmod); | |||
| 154 | GET(power); | |||
| 155 | GET(square); | |||
| 156 | GET(reciprocal); | |||
| 157 | GET(_ones_like); | |||
| 158 | GET(sqrt); | |||
| 159 | GET(negative); | |||
| 160 | GET(positive); | |||
| 161 | GET(absolute); | |||
| 162 | GET(invert); | |||
| 163 | GET(left_shift); | |||
| 164 | GET(right_shift); | |||
| 165 | GET(bitwise_and); | |||
| 166 | GET(bitwise_or); | |||
| 167 | GET(bitwise_xor); | |||
| 168 | GET(less); | |||
| 169 | GET(less_equal); | |||
| 170 | GET(equal); | |||
| 171 | GET(not_equal); | |||
| 172 | GET(greater); | |||
| 173 | GET(greater_equal); | |||
| 174 | GET(floor_divide); | |||
| 175 | GET(true_divide); | |||
| 176 | GET(logical_or); | |||
| 177 | GET(logical_and); | |||
| 178 | GET(floor); | |||
| 179 | GET(ceil); | |||
| 180 | GET(maximum); | |||
| 181 | GET(minimum); | |||
| 182 | GET(rint); | |||
| 183 | GET(conjugate); | |||
| 184 | GET(matmul); | |||
| 185 | GET(clip); | |||
| 186 | return dict; | |||
| 187 | ||||
| 188 | fail: | |||
| 189 | Py_DECREF(dict)_Py_DECREF(((PyObject*)(dict))); | |||
| 190 | return NULL((void*)0); | |||
| 191 | } | |||
| 192 | ||||
| 193 | /*NUMPY_API | |||
| 194 | Get dictionary showing number functions that all arrays will use | |||
| 195 | */ | |||
| 196 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | |||
| 197 | PyArray_GetNumericOps(void) | |||
| 198 | { | |||
| 199 | /* 2018-09-09, 1.16 */ | |||
| 200 | if (DEPRECATE("PyArray_GetNumericOps is deprecated.")PyErr_WarnEx(PyExc_DeprecationWarning,"PyArray_GetNumericOps is deprecated." ,1) < 0) { | |||
| 201 | return NULL((void*)0); | |||
| 202 | } | |||
| 203 | return _PyArray_GetNumericOps(); | |||
| 204 | } | |||
| 205 | ||||
| 206 | static PyObject * | |||
| 207 | _get_keywords(int rtype, PyArrayObject *out) | |||
| 208 | { | |||
| 209 | PyObject *kwds = NULL((void*)0); | |||
| 210 | if (rtype != NPY_NOTYPE || out != NULL((void*)0)) { | |||
| 211 | kwds = PyDict_New(); | |||
| 212 | if (rtype != NPY_NOTYPE) { | |||
| 213 | PyArray_Descr *descr; | |||
| 214 | descr = PyArray_DescrFromType(rtype); | |||
| 215 | if (descr) { | |||
| 216 | PyDict_SetItemString(kwds, "dtype", (PyObject *)descr); | |||
| 217 | Py_DECREF(descr)_Py_DECREF(((PyObject*)(descr))); | |||
| 218 | } | |||
| 219 | } | |||
| 220 | if (out != NULL((void*)0)) { | |||
| 221 | PyDict_SetItemString(kwds, "out", (PyObject *)out); | |||
| 222 | } | |||
| 223 | } | |||
| 224 | return kwds; | |||
| 225 | } | |||
| 226 | ||||
| 227 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | |||
| 228 | PyArray_GenericReduceFunction(PyArrayObject *m1, PyObject *op, int axis, | |||
| 229 | int rtype, PyArrayObject *out) | |||
| 230 | { | |||
| 231 | PyObject *args, *ret = NULL((void*)0), *meth; | |||
| 232 | PyObject *kwds; | |||
| 233 | ||||
| 234 | args = Py_BuildValue_Py_BuildValue_SizeT("(Oi)", m1, axis); | |||
| 235 | kwds = _get_keywords(rtype, out); | |||
| 236 | meth = PyObject_GetAttrString(op, "reduce"); | |||
| 237 | if (meth && PyCallable_Check(meth)) { | |||
| 238 | ret = PyObject_Call(meth, args, kwds); | |||
| 239 | } | |||
| 240 | Py_DECREF(args)_Py_DECREF(((PyObject*)(args))); | |||
| 241 | Py_DECREF(meth)_Py_DECREF(((PyObject*)(meth))); | |||
| 242 | Py_XDECREF(kwds)_Py_XDECREF(((PyObject*)(kwds))); | |||
| 243 | return ret; | |||
| 244 | } | |||
| 245 | ||||
| 246 | ||||
| 247 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | |||
| 248 | PyArray_GenericAccumulateFunction(PyArrayObject *m1, PyObject *op, int axis, | |||
| 249 | int rtype, PyArrayObject *out) | |||
| 250 | { | |||
| 251 | PyObject *args, *ret = NULL((void*)0), *meth; | |||
| 252 | PyObject *kwds; | |||
| 253 | ||||
| 254 | args = Py_BuildValue_Py_BuildValue_SizeT("(Oi)", m1, axis); | |||
| 255 | kwds = _get_keywords(rtype, out); | |||
| 256 | meth = PyObject_GetAttrString(op, "accumulate"); | |||
| 257 | if (meth && PyCallable_Check(meth)) { | |||
| 258 | ret = PyObject_Call(meth, args, kwds); | |||
| 259 | } | |||
| 260 | Py_DECREF(args)_Py_DECREF(((PyObject*)(args))); | |||
| 261 | Py_DECREF(meth)_Py_DECREF(((PyObject*)(meth))); | |||
| 262 | Py_XDECREF(kwds)_Py_XDECREF(((PyObject*)(kwds))); | |||
| 263 | return ret; | |||
| 264 | } | |||
| 265 | ||||
| 266 | ||||
| 267 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | |||
| 268 | PyArray_GenericBinaryFunction(PyObject *m1, PyObject *m2, PyObject *op) | |||
| 269 | { | |||
| 270 | return PyObject_CallFunctionObjArgs(op, m1, m2, NULL((void*)0)); | |||
| ||||
| 271 | } | |||
| 272 | ||||
| 273 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | |||
| 274 | PyArray_GenericUnaryFunction(PyArrayObject *m1, PyObject *op) | |||
| 275 | { | |||
| 276 | return PyObject_CallFunctionObjArgs(op, m1, NULL((void*)0)); | |||
| 277 | } | |||
| 278 | ||||
| 279 | static PyObject * | |||
| 280 | PyArray_GenericInplaceBinaryFunction(PyArrayObject *m1, | |||
| 281 | PyObject *m2, PyObject *op) | |||
| 282 | { | |||
| 283 | return PyObject_CallFunctionObjArgs(op, m1, m2, m1, NULL((void*)0)); | |||
| 284 | } | |||
| 285 | ||||
| 286 | static PyObject * | |||
| 287 | PyArray_GenericInplaceUnaryFunction(PyArrayObject *m1, PyObject *op) | |||
| 288 | { | |||
| 289 | return PyObject_CallFunctionObjArgs(op, m1, m1, NULL((void*)0)); | |||
| 290 | } | |||
| 291 | ||||
| 292 | static PyObject * | |||
| 293 | array_add(PyObject *m1, PyObject *m2) | |||
| 294 | { | |||
| 295 | PyObject *res; | |||
| 296 | ||||
| 297 | BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_add, array_add); | |||
| 298 | if (try_binary_elide(m1, m2, &array_inplace_add, &res, 1)) { | |||
| 299 | return res; | |||
| 300 | } | |||
| 301 | return PyArray_GenericBinaryFunction(m1, m2, n_ops.add); | |||
| 302 | } | |||
| 303 | ||||
| 304 | static PyObject * | |||
| 305 | array_subtract(PyObject *m1, PyObject *m2) | |||
| 306 | { | |||
| 307 | PyObject *res; | |||
| 308 | ||||
| 309 | BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_subtract, array_subtract); | |||
| 310 | if (try_binary_elide(m1, m2, &array_inplace_subtract, &res, 0)) { | |||
| 311 | return res; | |||
| 312 | } | |||
| 313 | return PyArray_GenericBinaryFunction(m1, m2, n_ops.subtract); | |||
| 314 | } | |||
| 315 | ||||
| 316 | static PyObject * | |||
| 317 | array_multiply(PyObject *m1, PyObject *m2) | |||
| 318 | { | |||
| 319 | PyObject *res; | |||
| 320 | ||||
| 321 | BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_multiply, array_multiply); | |||
| 322 | if (try_binary_elide(m1, m2, &array_inplace_multiply, &res, 1)) { | |||
| 323 | return res; | |||
| 324 | } | |||
| 325 | return PyArray_GenericBinaryFunction(m1, m2, n_ops.multiply); | |||
| 326 | } | |||
| 327 | ||||
| 328 | static PyObject * | |||
| 329 | array_remainder(PyObject *m1, PyObject *m2) | |||
| 330 | { | |||
| 331 | BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_remainder, array_remainder); | |||
| 332 | return PyArray_GenericBinaryFunction(m1, m2, n_ops.remainder); | |||
| 333 | } | |||
| 334 | ||||
| 335 | static PyObject * | |||
| 336 | array_divmod(PyObject *m1, PyObject *m2) | |||
| 337 | { | |||
| 338 | BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_divmod, array_divmod); | |||
| 339 | return PyArray_GenericBinaryFunction(m1, m2, n_ops.divmod); | |||
| 340 | } | |||
| 341 | ||||
| 342 | /* Need this to be version dependent on account of the slot check */ | |||
| 343 | static PyObject * | |||
| 344 | array_matrix_multiply(PyObject *m1, PyObject *m2) | |||
| 345 | { | |||
| 346 | BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_matrix_multiply, array_matrix_multiply); | |||
| 347 | return PyArray_GenericBinaryFunction(m1, m2, n_ops.matmul); | |||
| 348 | } | |||
| 349 | ||||
| 350 | static PyObject * | |||
| 351 | array_inplace_matrix_multiply( | |||
| 352 | PyArrayObject *NPY_UNUSED(m1)(__NPY_UNUSED_TAGGEDm1) __attribute__ ((__unused__)), PyObject *NPY_UNUSED(m2)(__NPY_UNUSED_TAGGEDm2) __attribute__ ((__unused__))) | |||
| 353 | { | |||
| 354 | PyErr_SetString(PyExc_TypeError, | |||
| 355 | "In-place matrix multiplication is not (yet) supported. " | |||
| 356 | "Use 'a = a @ b' instead of 'a @= b'."); | |||
| 357 | return NULL((void*)0); | |||
| 358 | } | |||
| 359 | ||||
| 360 | /* | |||
| 361 | * Determine if object is a scalar and if so, convert the object | |||
| 362 | * to a double and place it in the out_exponent argument | |||
| 363 | * and return the "scalar kind" as a result. If the object is | |||
| 364 | * not a scalar (or if there are other error conditions) | |||
| 365 | * return NPY_NOSCALAR, and out_exponent is undefined. | |||
| 366 | */ | |||
| 367 | static NPY_SCALARKIND | |||
| 368 | is_scalar_with_conversion(PyObject *o2, double* out_exponent) | |||
| 369 | { | |||
| 370 | PyObject *temp; | |||
| 371 | const int optimize_fpexps = 1; | |||
| 372 | ||||
| 373 | if (PyLong_Check(o2)((((((PyObject*)(o2))->ob_type))->tp_flags & ((1UL << 24))) != 0)) { | |||
| 374 | long tmp = PyLong_AsLong(o2); | |||
| 375 | if (error_converting(tmp)(((tmp) == -1) && PyErr_Occurred())) { | |||
| 376 | PyErr_Clear(); | |||
| 377 | return NPY_NOSCALAR; | |||
| 378 | } | |||
| 379 | *out_exponent = (double)tmp; | |||
| 380 | return NPY_INTPOS_SCALAR; | |||
| 381 | } | |||
| 382 | ||||
| 383 | if (optimize_fpexps && PyFloat_Check(o2)((((PyObject*)(o2))->ob_type) == (&PyFloat_Type) || PyType_IsSubtype ((((PyObject*)(o2))->ob_type), (&PyFloat_Type)))) { | |||
| 384 | *out_exponent = PyFloat_AsDouble(o2); | |||
| 385 | return NPY_FLOAT_SCALAR; | |||
| 386 | } | |||
| 387 | ||||
| 388 | if (PyArray_Check(o2)((((PyObject*)(o2))->ob_type) == (&PyArray_Type) || PyType_IsSubtype ((((PyObject*)(o2))->ob_type), (&PyArray_Type)))) { | |||
| 389 | if ((PyArray_NDIM((PyArrayObject *)o2) == 0) && | |||
| 390 | ((PyArray_ISINTEGER((PyArrayObject *)o2)(((PyArray_TYPE((PyArrayObject *)o2)) >= NPY_BYTE) && ((PyArray_TYPE((PyArrayObject *)o2)) <= NPY_ULONGLONG)) || | |||
| 391 | (optimize_fpexps && PyArray_ISFLOAT((PyArrayObject *)o2)((((PyArray_TYPE((PyArrayObject *)o2)) >= NPY_FLOAT) && ((PyArray_TYPE((PyArrayObject *)o2)) <= NPY_LONGDOUBLE)) || ((PyArray_TYPE((PyArrayObject *)o2)) == NPY_HALF)))))) { | |||
| 392 | temp = Py_TYPE(o2)(((PyObject*)(o2))->ob_type)->tp_as_number->nb_float(o2); | |||
| 393 | if (temp == NULL((void*)0)) { | |||
| 394 | return NPY_NOSCALAR; | |||
| 395 | } | |||
| 396 | *out_exponent = PyFloat_AsDouble(o2); | |||
| 397 | Py_DECREF(temp)_Py_DECREF(((PyObject*)(temp))); | |||
| 398 | if (PyArray_ISINTEGER((PyArrayObject *)o2)(((PyArray_TYPE((PyArrayObject *)o2)) >= NPY_BYTE) && ((PyArray_TYPE((PyArrayObject *)o2)) <= NPY_ULONGLONG))) { | |||
| 399 | return NPY_INTPOS_SCALAR; | |||
| 400 | } | |||
| 401 | else { /* ISFLOAT */ | |||
| 402 | return NPY_FLOAT_SCALAR; | |||
| 403 | } | |||
| 404 | } | |||
| 405 | } | |||
| 406 | else if (PyArray_IsScalar(o2, Integer)(((((PyObject*)(o2))->ob_type) == (&PyIntegerArrType_Type ) || PyType_IsSubtype((((PyObject*)(o2))->ob_type), (& PyIntegerArrType_Type)))) || | |||
| 407 | (optimize_fpexps && PyArray_IsScalar(o2, Floating)(((((PyObject*)(o2))->ob_type) == (&PyFloatingArrType_Type ) || PyType_IsSubtype((((PyObject*)(o2))->ob_type), (& PyFloatingArrType_Type)))))) { | |||
| 408 | temp = Py_TYPE(o2)(((PyObject*)(o2))->ob_type)->tp_as_number->nb_float(o2); | |||
| 409 | if (temp == NULL((void*)0)) { | |||
| 410 | return NPY_NOSCALAR; | |||
| 411 | } | |||
| 412 | *out_exponent = PyFloat_AsDouble(o2); | |||
| 413 | Py_DECREF(temp)_Py_DECREF(((PyObject*)(temp))); | |||
| 414 | ||||
| 415 | if (PyArray_IsScalar(o2, Integer)(((((PyObject*)(o2))->ob_type) == (&PyIntegerArrType_Type ) || PyType_IsSubtype((((PyObject*)(o2))->ob_type), (& PyIntegerArrType_Type))))) { | |||
| 416 | return NPY_INTPOS_SCALAR; | |||
| 417 | } | |||
| 418 | else { /* IsScalar(o2, Floating) */ | |||
| 419 | return NPY_FLOAT_SCALAR; | |||
| 420 | } | |||
| 421 | } | |||
| 422 | else if (PyIndex_Check(o2)((o2)->ob_type->tp_as_number != ((void*)0) && ( o2)->ob_type->tp_as_number->nb_index != ((void*)0))) { | |||
| 423 | PyObject* value = PyNumber_Index(o2); | |||
| 424 | Py_ssize_t val; | |||
| 425 | if (value == NULL((void*)0)) { | |||
| 426 | if (PyErr_Occurred()) { | |||
| 427 | PyErr_Clear(); | |||
| 428 | } | |||
| 429 | return NPY_NOSCALAR; | |||
| 430 | } | |||
| 431 | val = PyLong_AsSsize_t(value); | |||
| 432 | if (error_converting(val)(((val) == -1) && PyErr_Occurred())) { | |||
| 433 | PyErr_Clear(); | |||
| 434 | return NPY_NOSCALAR; | |||
| 435 | } | |||
| 436 | *out_exponent = (double) val; | |||
| 437 | return NPY_INTPOS_SCALAR; | |||
| 438 | } | |||
| 439 | return NPY_NOSCALAR; | |||
| 440 | } | |||
| 441 | ||||
| 442 | /* | |||
| 443 | * optimize float array or complex array to a scalar power | |||
| 444 | * returns 0 on success, -1 if no optimization is possible | |||
| 445 | * the result is in value (can be NULL if an error occurred) | |||
| 446 | */ | |||
| 447 | static int | |||
| 448 | fast_scalar_power(PyObject *o1, PyObject *o2, int inplace, | |||
| 449 | PyObject **value) | |||
| 450 | { | |||
| 451 | double exponent; | |||
| 452 | NPY_SCALARKIND kind; /* NPY_NOSCALAR is not scalar */ | |||
| 453 | ||||
| 454 | if (PyArray_Check(o1)((((PyObject*)(o1))->ob_type) == (&PyArray_Type) || PyType_IsSubtype ((((PyObject*)(o1))->ob_type), (&PyArray_Type))) && | |||
| 455 | !PyArray_ISOBJECT((PyArrayObject *)o1)((PyArray_TYPE((PyArrayObject *)o1)) == NPY_OBJECT) && | |||
| 456 | ((kind=is_scalar_with_conversion(o2, &exponent))>0)) { | |||
| 457 | PyArrayObject *a1 = (PyArrayObject *)o1; | |||
| 458 | PyObject *fastop = NULL((void*)0); | |||
| 459 | if (PyArray_ISFLOAT(a1)((((PyArray_TYPE(a1)) >= NPY_FLOAT) && ((PyArray_TYPE (a1)) <= NPY_LONGDOUBLE)) || ((PyArray_TYPE(a1)) == NPY_HALF )) || PyArray_ISCOMPLEX(a1)(((PyArray_TYPE(a1)) >= NPY_CFLOAT) && ((PyArray_TYPE (a1)) <= NPY_CLONGDOUBLE))) { | |||
| 460 | if (exponent == 1.0) { | |||
| 461 | fastop = n_ops.positive; | |||
| 462 | } | |||
| 463 | else if (exponent == -1.0) { | |||
| 464 | fastop = n_ops.reciprocal; | |||
| 465 | } | |||
| 466 | else if (exponent == 0.0) { | |||
| 467 | fastop = n_ops._ones_like; | |||
| 468 | } | |||
| 469 | else if (exponent == 0.5) { | |||
| 470 | fastop = n_ops.sqrt; | |||
| 471 | } | |||
| 472 | else if (exponent == 2.0) { | |||
| 473 | fastop = n_ops.square; | |||
| 474 | } | |||
| 475 | else { | |||
| 476 | return -1; | |||
| 477 | } | |||
| 478 | ||||
| 479 | if (inplace || can_elide_temp_unary(a1)) { | |||
| 480 | *value = PyArray_GenericInplaceUnaryFunction(a1, fastop); | |||
| 481 | } | |||
| 482 | else { | |||
| 483 | *value = PyArray_GenericUnaryFunction(a1, fastop); | |||
| 484 | } | |||
| 485 | return 0; | |||
| 486 | } | |||
| 487 | /* Because this is called with all arrays, we need to | |||
| 488 | * change the output if the kind of the scalar is different | |||
| 489 | * than that of the input and inplace is not on --- | |||
| 490 | * (thus, the input should be up-cast) | |||
| 491 | */ | |||
| 492 | else if (exponent == 2.0) { | |||
| 493 | fastop = n_ops.square; | |||
| 494 | if (inplace) { | |||
| 495 | *value = PyArray_GenericInplaceUnaryFunction(a1, fastop); | |||
| 496 | } | |||
| 497 | else { | |||
| 498 | /* We only special-case the FLOAT_SCALAR and integer types */ | |||
| 499 | if (kind == NPY_FLOAT_SCALAR && PyArray_ISINTEGER(a1)(((PyArray_TYPE(a1)) >= NPY_BYTE) && ((PyArray_TYPE (a1)) <= NPY_ULONGLONG))) { | |||
| 500 | PyArray_Descr *dtype = PyArray_DescrFromType(NPY_DOUBLE); | |||
| 501 | a1 = (PyArrayObject *)PyArray_CastToType(a1, dtype, | |||
| 502 | PyArray_ISFORTRAN(a1)(PyArray_CHKFLAGS(a1, 0x0002) && (!PyArray_CHKFLAGS(a1 , 0x0001)))); | |||
| 503 | if (a1 != NULL((void*)0)) { | |||
| 504 | /* cast always creates a new array */ | |||
| 505 | *value = PyArray_GenericInplaceUnaryFunction(a1, fastop); | |||
| 506 | Py_DECREF(a1)_Py_DECREF(((PyObject*)(a1))); | |||
| 507 | } | |||
| 508 | } | |||
| 509 | else { | |||
| 510 | *value = PyArray_GenericUnaryFunction(a1, fastop); | |||
| 511 | } | |||
| 512 | } | |||
| 513 | return 0; | |||
| 514 | } | |||
| 515 | } | |||
| 516 | /* no fast operation found */ | |||
| 517 | return -1; | |||
| 518 | } | |||
| 519 | ||||
| 520 | static PyObject * | |||
| 521 | array_power(PyObject *a1, PyObject *o2, PyObject *modulo) | |||
| 522 | { | |||
| 523 | PyObject *value = NULL((void*)0); | |||
| 524 | ||||
| 525 | if (modulo != Py_None(&_Py_NoneStruct)) { | |||
| 526 | /* modular exponentiation is not implemented (gh-8804) */ | |||
| 527 | Py_INCREF(Py_NotImplemented)_Py_INCREF(((PyObject*)((&_Py_NotImplementedStruct)))); | |||
| 528 | return Py_NotImplemented(&_Py_NotImplementedStruct); | |||
| 529 | } | |||
| 530 | ||||
| 531 | BINOP_GIVE_UP_IF_NEEDED(a1, o2, nb_power, array_power); | |||
| 532 | if (fast_scalar_power(a1, o2, 0, &value) != 0) { | |||
| 533 | value = PyArray_GenericBinaryFunction(a1, o2, n_ops.power); | |||
| 534 | } | |||
| 535 | return value; | |||
| 536 | } | |||
| 537 | ||||
| 538 | static PyObject * | |||
| 539 | array_positive(PyArrayObject *m1) | |||
| 540 | { | |||
| 541 | /* | |||
| 542 | * For backwards compatibility, where + just implied a copy, | |||
| 543 | * we cannot just call n_ops.positive. Instead, we do the following | |||
| 544 | * 1. Try n_ops.positive | |||
| 545 | * 2. If we get an exception, check whether __array_ufunc__ is | |||
| 546 | * overridden; if so, we live in the future and we allow the | |||
| 547 | * TypeError to be passed on. | |||
| 548 | * 3. If not, give a deprecation warning and return a copy. | |||
| 549 | */ | |||
| 550 | PyObject *value; | |||
| 551 | if (can_elide_temp_unary(m1)) { | |||
| 552 | value = PyArray_GenericInplaceUnaryFunction(m1, n_ops.positive); | |||
| 553 | } | |||
| 554 | else { | |||
| 555 | value = PyArray_GenericUnaryFunction(m1, n_ops.positive); | |||
| 556 | } | |||
| 557 | if (value == NULL((void*)0)) { | |||
| 558 | /* | |||
| 559 | * We first fetch the error, as it needs to be clear to check | |||
| 560 | * for the override. When the deprecation is removed, | |||
| 561 | * this whole stanza can be deleted. | |||
| 562 | */ | |||
| 563 | PyObject *exc, *val, *tb; | |||
| 564 | PyErr_Fetch(&exc, &val, &tb); | |||
| 565 | if (PyUFunc_HasOverride((PyObject *)m1)) { | |||
| 566 | PyErr_Restore(exc, val, tb); | |||
| 567 | return NULL((void*)0); | |||
| 568 | } | |||
| 569 | Py_XDECREF(exc)_Py_XDECREF(((PyObject*)(exc))); | |||
| 570 | Py_XDECREF(val)_Py_XDECREF(((PyObject*)(val))); | |||
| 571 | Py_XDECREF(tb)_Py_XDECREF(((PyObject*)(tb))); | |||
| 572 | ||||
| 573 | /* 2018-06-28, 1.16.0 */ | |||
| 574 | if (DEPRECATE("Applying '+' to a non-numerical array is "PyErr_WarnEx(PyExc_DeprecationWarning,"Applying '+' to a non-numerical array is " "ill-defined. Returning a copy, but in the future " "this will error." ,1) | |||
| 575 | "ill-defined. Returning a copy, but in the future "PyErr_WarnEx(PyExc_DeprecationWarning,"Applying '+' to a non-numerical array is " "ill-defined. Returning a copy, but in the future " "this will error." ,1) | |||
| 576 | "this will error.")PyErr_WarnEx(PyExc_DeprecationWarning,"Applying '+' to a non-numerical array is " "ill-defined. Returning a copy, but in the future " "this will error." ,1) < 0) { | |||
| 577 | return NULL((void*)0); | |||
| 578 | } | |||
| 579 | value = PyArray_Return((PyArrayObject *)PyArray_Copy(m1)PyArray_NewCopy(m1, NPY_CORDER)); | |||
| 580 | } | |||
| 581 | return value; | |||
| 582 | } | |||
| 583 | ||||
| 584 | static PyObject * | |||
| 585 | array_negative(PyArrayObject *m1) | |||
| 586 | { | |||
| 587 | if (can_elide_temp_unary(m1)) { | |||
| 588 | return PyArray_GenericInplaceUnaryFunction(m1, n_ops.negative); | |||
| 589 | } | |||
| 590 | return PyArray_GenericUnaryFunction(m1, n_ops.negative); | |||
| 591 | } | |||
| 592 | ||||
| 593 | static PyObject * | |||
| 594 | array_absolute(PyArrayObject *m1) | |||
| 595 | { | |||
| 596 | if (can_elide_temp_unary(m1) && !PyArray_ISCOMPLEX(m1)(((PyArray_TYPE(m1)) >= NPY_CFLOAT) && ((PyArray_TYPE (m1)) <= NPY_CLONGDOUBLE))) { | |||
| 597 | return PyArray_GenericInplaceUnaryFunction(m1, n_ops.absolute); | |||
| 598 | } | |||
| 599 | return PyArray_GenericUnaryFunction(m1, n_ops.absolute); | |||
| 600 | } | |||
| 601 | ||||
| 602 | static PyObject * | |||
| 603 | array_invert(PyArrayObject *m1) | |||
| 604 | { | |||
| 605 | if (can_elide_temp_unary(m1)) { | |||
| 606 | return PyArray_GenericInplaceUnaryFunction(m1, n_ops.invert); | |||
| 607 | } | |||
| 608 | return PyArray_GenericUnaryFunction(m1, n_ops.invert); | |||
| 609 | } | |||
| 610 | ||||
| 611 | static PyObject * | |||
| 612 | array_left_shift(PyObject *m1, PyObject *m2) | |||
| 613 | { | |||
| 614 | PyObject *res; | |||
| 615 | ||||
| 616 | BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_lshift, array_left_shift); | |||
| 617 | if (try_binary_elide(m1, m2, &array_inplace_left_shift, &res, 0)) { | |||
| 618 | return res; | |||
| 619 | } | |||
| 620 | return PyArray_GenericBinaryFunction(m1, m2, n_ops.left_shift); | |||
| 621 | } | |||
| 622 | ||||
| 623 | static PyObject * | |||
| 624 | array_right_shift(PyObject *m1, PyObject *m2) | |||
| 625 | { | |||
| 626 | PyObject *res; | |||
| 627 | ||||
| 628 | BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_rshift, array_right_shift); | |||
| 629 | if (try_binary_elide(m1, m2, &array_inplace_right_shift, &res, 0)) { | |||
| 630 | return res; | |||
| 631 | } | |||
| 632 | return PyArray_GenericBinaryFunction(m1, m2, n_ops.right_shift); | |||
| 633 | } | |||
| 634 | ||||
| 635 | static PyObject * | |||
| 636 | array_bitwise_and(PyObject *m1, PyObject *m2) | |||
| 637 | { | |||
| 638 | PyObject *res; | |||
| 639 | ||||
| 640 | BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_and, array_bitwise_and); | |||
| 641 | if (try_binary_elide(m1, m2, &array_inplace_bitwise_and, &res, 1)) { | |||
| 642 | return res; | |||
| 643 | } | |||
| 644 | return PyArray_GenericBinaryFunction(m1, m2, n_ops.bitwise_and); | |||
| 645 | } | |||
| 646 | ||||
| 647 | static PyObject * | |||
| 648 | array_bitwise_or(PyObject *m1, PyObject *m2) | |||
| 649 | { | |||
| 650 | PyObject *res; | |||
| 651 | ||||
| 652 | BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_or, array_bitwise_or); | |||
| 653 | if (try_binary_elide(m1, m2, &array_inplace_bitwise_or, &res, 1)) { | |||
| 654 | return res; | |||
| 655 | } | |||
| 656 | return PyArray_GenericBinaryFunction(m1, m2, n_ops.bitwise_or); | |||
| 657 | } | |||
| 658 | ||||
| 659 | static PyObject * | |||
| 660 | array_bitwise_xor(PyObject *m1, PyObject *m2) | |||
| 661 | { | |||
| 662 | PyObject *res; | |||
| 663 | ||||
| 664 | BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_xor, array_bitwise_xor); | |||
| 665 | if (try_binary_elide(m1, m2, &array_inplace_bitwise_xor, &res, 1)) { | |||
| 666 | return res; | |||
| 667 | } | |||
| 668 | return PyArray_GenericBinaryFunction(m1, m2, n_ops.bitwise_xor); | |||
| 669 | } | |||
| 670 | ||||
| 671 | static PyObject * | |||
| 672 | array_inplace_add(PyArrayObject *m1, PyObject *m2) | |||
| 673 | { | |||
| 674 | INPLACE_GIVE_UP_IF_NEEDED( | |||
| 675 | m1, m2, nb_inplace_add, array_inplace_add); | |||
| 676 | return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.add); | |||
| 677 | } | |||
| 678 | ||||
| 679 | static PyObject * | |||
| 680 | array_inplace_subtract(PyArrayObject *m1, PyObject *m2) | |||
| 681 | { | |||
| 682 | INPLACE_GIVE_UP_IF_NEEDED( | |||
| 683 | m1, m2, nb_inplace_subtract, array_inplace_subtract); | |||
| 684 | return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.subtract); | |||
| 685 | } | |||
| 686 | ||||
| 687 | static PyObject * | |||
| 688 | array_inplace_multiply(PyArrayObject *m1, PyObject *m2) | |||
| 689 | { | |||
| 690 | INPLACE_GIVE_UP_IF_NEEDED( | |||
| 691 | m1, m2, nb_inplace_multiply, array_inplace_multiply); | |||
| 692 | return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.multiply); | |||
| 693 | } | |||
| 694 | ||||
| 695 | static PyObject * | |||
| 696 | array_inplace_remainder(PyArrayObject *m1, PyObject *m2) | |||
| 697 | { | |||
| 698 | INPLACE_GIVE_UP_IF_NEEDED( | |||
| 699 | m1, m2, nb_inplace_remainder, array_inplace_remainder); | |||
| 700 | return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.remainder); | |||
| 701 | } | |||
| 702 | ||||
| 703 | static PyObject * | |||
| 704 | array_inplace_power(PyArrayObject *a1, PyObject *o2, PyObject *NPY_UNUSED(modulo)(__NPY_UNUSED_TAGGEDmodulo) __attribute__ ((__unused__))) | |||
| 705 | { | |||
| 706 | /* modulo is ignored! */ | |||
| 707 | PyObject *value = NULL((void*)0); | |||
| 708 | ||||
| 709 | INPLACE_GIVE_UP_IF_NEEDED( | |||
| 710 | a1, o2, nb_inplace_power, array_inplace_power); | |||
| 711 | if (fast_scalar_power((PyObject *)a1, o2, 1, &value) != 0) { | |||
| 712 | value = PyArray_GenericInplaceBinaryFunction(a1, o2, n_ops.power); | |||
| 713 | } | |||
| 714 | return value; | |||
| 715 | } | |||
| 716 | ||||
| 717 | static PyObject * | |||
| 718 | array_inplace_left_shift(PyArrayObject *m1, PyObject *m2) | |||
| 719 | { | |||
| 720 | INPLACE_GIVE_UP_IF_NEEDED( | |||
| 721 | m1, m2, nb_inplace_lshift, array_inplace_left_shift); | |||
| 722 | return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.left_shift); | |||
| 723 | } | |||
| 724 | ||||
| 725 | static PyObject * | |||
| 726 | array_inplace_right_shift(PyArrayObject *m1, PyObject *m2) | |||
| 727 | { | |||
| 728 | INPLACE_GIVE_UP_IF_NEEDED( | |||
| 729 | m1, m2, nb_inplace_rshift, array_inplace_right_shift); | |||
| 730 | return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.right_shift); | |||
| 731 | } | |||
| 732 | ||||
| 733 | static PyObject * | |||
| 734 | array_inplace_bitwise_and(PyArrayObject *m1, PyObject *m2) | |||
| 735 | { | |||
| 736 | INPLACE_GIVE_UP_IF_NEEDED( | |||
| 737 | m1, m2, nb_inplace_and, array_inplace_bitwise_and); | |||
| 738 | return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.bitwise_and); | |||
| 739 | } | |||
| 740 | ||||
| 741 | static PyObject * | |||
| 742 | array_inplace_bitwise_or(PyArrayObject *m1, PyObject *m2) | |||
| 743 | { | |||
| 744 | INPLACE_GIVE_UP_IF_NEEDED( | |||
| 745 | m1, m2, nb_inplace_or, array_inplace_bitwise_or); | |||
| 746 | return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.bitwise_or); | |||
| 747 | } | |||
| 748 | ||||
| 749 | static PyObject * | |||
| 750 | array_inplace_bitwise_xor(PyArrayObject *m1, PyObject *m2) | |||
| 751 | { | |||
| 752 | INPLACE_GIVE_UP_IF_NEEDED( | |||
| 753 | m1, m2, nb_inplace_xor, array_inplace_bitwise_xor); | |||
| 754 | return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.bitwise_xor); | |||
| 755 | } | |||
| 756 | ||||
| 757 | static PyObject * | |||
| 758 | array_floor_divide(PyObject *m1, PyObject *m2) | |||
| 759 | { | |||
| 760 | PyObject *res; | |||
| 761 | ||||
| 762 | BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_floor_divide, array_floor_divide); | |||
| 763 | if (try_binary_elide(m1, m2, &array_inplace_floor_divide, &res, 0)) { | |||
| 764 | return res; | |||
| 765 | } | |||
| 766 | return PyArray_GenericBinaryFunction(m1, m2, n_ops.floor_divide); | |||
| 767 | } | |||
| 768 | ||||
| 769 | static PyObject * | |||
| 770 | array_true_divide(PyObject *m1, PyObject *m2) | |||
| 771 | { | |||
| 772 | PyObject *res; | |||
| 773 | PyArrayObject *a1 = (PyArrayObject *)m1; | |||
| 774 | ||||
| 775 | BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_true_divide, array_true_divide); | |||
| 776 | if (PyArray_CheckExact(m1)(((PyObject*)(m1))->ob_type == &PyArray_Type) && | |||
| 777 | (PyArray_ISFLOAT(a1)((((PyArray_TYPE(a1)) >= NPY_FLOAT) && ((PyArray_TYPE (a1)) <= NPY_LONGDOUBLE)) || ((PyArray_TYPE(a1)) == NPY_HALF )) || PyArray_ISCOMPLEX(a1)(((PyArray_TYPE(a1)) >= NPY_CFLOAT) && ((PyArray_TYPE (a1)) <= NPY_CLONGDOUBLE))) && | |||
| 778 | try_binary_elide(m1, m2, &array_inplace_true_divide, &res, 0)) { | |||
| 779 | return res; | |||
| 780 | } | |||
| 781 | return PyArray_GenericBinaryFunction(m1, m2, n_ops.true_divide); | |||
| 782 | } | |||
| 783 | ||||
| 784 | static PyObject * | |||
| 785 | array_inplace_floor_divide(PyArrayObject *m1, PyObject *m2) | |||
| 786 | { | |||
| 787 | INPLACE_GIVE_UP_IF_NEEDED( | |||
| 788 | m1, m2, nb_inplace_floor_divide, array_inplace_floor_divide); | |||
| 789 | return PyArray_GenericInplaceBinaryFunction(m1, m2, | |||
| 790 | n_ops.floor_divide); | |||
| 791 | } | |||
| 792 | ||||
| 793 | static PyObject * | |||
| 794 | array_inplace_true_divide(PyArrayObject *m1, PyObject *m2) | |||
| 795 | { | |||
| 796 | INPLACE_GIVE_UP_IF_NEEDED( | |||
| 797 | m1, m2, nb_inplace_true_divide, array_inplace_true_divide); | |||
| 798 | return PyArray_GenericInplaceBinaryFunction(m1, m2, | |||
| 799 | n_ops.true_divide); | |||
| 800 | } | |||
| 801 | ||||
| 802 | ||||
| 803 | static int | |||
| 804 | _array_nonzero(PyArrayObject *mp) | |||
| 805 | { | |||
| 806 | npy_intp n; | |||
| 807 | ||||
| 808 | n = PyArray_SIZE(mp)PyArray_MultiplyList(PyArray_DIMS(mp), PyArray_NDIM(mp)); | |||
| 809 | if (n == 1) { | |||
| 810 | int res; | |||
| 811 | if (Py_EnterRecursiveCall(" while converting array to bool")((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit ) && _Py_CheckRecursiveCall(" while converting array to bool" ))) { | |||
| 812 | return -1; | |||
| 813 | } | |||
| 814 | res = PyArray_DESCR(mp)->f->nonzero(PyArray_DATA(mp), mp); | |||
| 815 | /* nonzero has no way to indicate an error, but one can occur */ | |||
| 816 | if (PyErr_Occurred()) { | |||
| 817 | res = -1; | |||
| 818 | } | |||
| 819 | Py_LeaveRecursiveCall()do{ if((--(PyThreadState_Get()->recursion_depth) < (((_Py_CheckRecursionLimit ) > 200) ? ((_Py_CheckRecursionLimit) - 50) : (3 * ((_Py_CheckRecursionLimit ) >> 2))))) PyThreadState_Get()->overflowed = 0; } while (0); | |||
| 820 | return res; | |||
| 821 | } | |||
| 822 | else if (n == 0) { | |||
| 823 | /* 2017-09-25, 1.14 */ | |||
| 824 | if (DEPRECATE("The truth value of an empty array is ambiguous. "PyErr_WarnEx(PyExc_DeprecationWarning,"The truth value of an empty array is ambiguous. " "Returning False, but in future this will result in an error. " "Use `array.size > 0` to check that an array is not empty." ,1) | |||
| 825 | "Returning False, but in future this will result in an error. "PyErr_WarnEx(PyExc_DeprecationWarning,"The truth value of an empty array is ambiguous. " "Returning False, but in future this will result in an error. " "Use `array.size > 0` to check that an array is not empty." ,1) | |||
| 826 | "Use `array.size > 0` to check that an array is not empty.")PyErr_WarnEx(PyExc_DeprecationWarning,"The truth value of an empty array is ambiguous. " "Returning False, but in future this will result in an error. " "Use `array.size > 0` to check that an array is not empty." ,1) < 0) { | |||
| 827 | return -1; | |||
| 828 | } | |||
| 829 | return 0; | |||
| 830 | } | |||
| 831 | else { | |||
| 832 | PyErr_SetString(PyExc_ValueError, | |||
| 833 | "The truth value of an array " | |||
| 834 | "with more than one element is ambiguous. " | |||
| 835 | "Use a.any() or a.all()"); | |||
| 836 | return -1; | |||
| 837 | } | |||
| 838 | } | |||
| 839 | ||||
| 840 | /* | |||
| 841 | * Convert the array to a scalar if allowed, and apply the builtin function | |||
| 842 | * to it. The where argument is passed onto Py_EnterRecursiveCall when the | |||
| 843 | * array contains python objects. | |||
| 844 | */ | |||
| 845 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | |||
| 846 | array_scalar_forward(PyArrayObject *v, | |||
| 847 | PyObject *(*builtin_func)(PyObject *), | |||
| 848 | const char *where) | |||
| 849 | { | |||
| 850 | PyObject *scalar; | |||
| 851 | if (PyArray_SIZE(v)PyArray_MultiplyList(PyArray_DIMS(v), PyArray_NDIM(v)) != 1) { | |||
| 852 | PyErr_SetString(PyExc_TypeError, "only size-1 arrays can be"\ | |||
| 853 | " converted to Python scalars"); | |||
| 854 | return NULL((void*)0); | |||
| 855 | } | |||
| 856 | ||||
| 857 | scalar = PyArray_GETITEM(v, PyArray_DATA(v)); | |||
| 858 | if (scalar == NULL((void*)0)) { | |||
| 859 | return NULL((void*)0); | |||
| 860 | } | |||
| 861 | ||||
| 862 | /* Need to guard against recursion if our array holds references */ | |||
| 863 | if (PyDataType_REFCHK(PyArray_DESCR(v))(((PyArray_DESCR(v))->flags & (0x01)) == (0x01))) { | |||
| 864 | PyObject *res; | |||
| 865 | if (Py_EnterRecursiveCall(where)((++(PyThreadState_Get()->recursion_depth) > _Py_CheckRecursionLimit ) && _Py_CheckRecursiveCall(where)) != 0) { | |||
| 866 | Py_DECREF(scalar)_Py_DECREF(((PyObject*)(scalar))); | |||
| 867 | return NULL((void*)0); | |||
| 868 | } | |||
| 869 | res = builtin_func(scalar); | |||
| 870 | Py_DECREF(scalar)_Py_DECREF(((PyObject*)(scalar))); | |||
| 871 | Py_LeaveRecursiveCall()do{ if((--(PyThreadState_Get()->recursion_depth) < (((_Py_CheckRecursionLimit ) > 200) ? ((_Py_CheckRecursionLimit) - 50) : (3 * ((_Py_CheckRecursionLimit ) >> 2))))) PyThreadState_Get()->overflowed = 0; } while (0); | |||
| 872 | return res; | |||
| 873 | } | |||
| 874 | else { | |||
| 875 | PyObject *res; | |||
| 876 | res = builtin_func(scalar); | |||
| 877 | Py_DECREF(scalar)_Py_DECREF(((PyObject*)(scalar))); | |||
| 878 | return res; | |||
| 879 | } | |||
| 880 | } | |||
| 881 | ||||
| 882 | ||||
| 883 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | |||
| 884 | array_float(PyArrayObject *v) | |||
| 885 | { | |||
| 886 | return array_scalar_forward(v, &PyNumber_Float, " in ndarray.__float__"); | |||
| 887 | } | |||
| 888 | ||||
| 889 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | |||
| 890 | array_int(PyArrayObject *v) | |||
| 891 | { | |||
| 892 | return array_scalar_forward(v, &PyNumber_Long, " in ndarray.__int__"); | |||
| 893 | } | |||
| 894 | ||||
| 895 | static PyObject * | |||
| 896 | array_index(PyArrayObject *v) | |||
| 897 | { | |||
| 898 | if (!PyArray_ISINTEGER(v)(((PyArray_TYPE(v)) >= NPY_BYTE) && ((PyArray_TYPE (v)) <= NPY_ULONGLONG)) || PyArray_NDIM(v) != 0) { | |||
| 899 | PyErr_SetString(PyExc_TypeError, | |||
| 900 | "only integer scalar arrays can be converted to a scalar index"); | |||
| 901 | return NULL((void*)0); | |||
| 902 | } | |||
| 903 | return PyArray_GETITEM(v, PyArray_DATA(v)); | |||
| 904 | } | |||
| 905 | ||||
| 906 | ||||
| 907 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyNumberMethods array_as_number = { | |||
| 908 | .nb_add = array_add, | |||
| 909 | .nb_subtract = array_subtract, | |||
| 910 | .nb_multiply = array_multiply, | |||
| 911 | .nb_remainder = array_remainder, | |||
| 912 | .nb_divmod = array_divmod, | |||
| 913 | .nb_power = (ternaryfunc)array_power, | |||
| 914 | .nb_negative = (unaryfunc)array_negative, | |||
| 915 | .nb_positive = (unaryfunc)array_positive, | |||
| 916 | .nb_absolute = (unaryfunc)array_absolute, | |||
| 917 | .nb_bool = (inquiry)_array_nonzero, | |||
| 918 | .nb_invert = (unaryfunc)array_invert, | |||
| 919 | .nb_lshift = array_left_shift, | |||
| 920 | .nb_rshift = array_right_shift, | |||
| 921 | .nb_and = array_bitwise_and, | |||
| 922 | .nb_xor = array_bitwise_xor, | |||
| 923 | .nb_or = array_bitwise_or, | |||
| 924 | ||||
| 925 | .nb_int = (unaryfunc)array_int, | |||
| 926 | .nb_float = (unaryfunc)array_float, | |||
| 927 | .nb_index = (unaryfunc)array_index, | |||
| 928 | ||||
| 929 | .nb_inplace_add = (binaryfunc)array_inplace_add, | |||
| 930 | .nb_inplace_subtract = (binaryfunc)array_inplace_subtract, | |||
| 931 | .nb_inplace_multiply = (binaryfunc)array_inplace_multiply, | |||
| 932 | .nb_inplace_remainder = (binaryfunc)array_inplace_remainder, | |||
| 933 | .nb_inplace_power = (ternaryfunc)array_inplace_power, | |||
| 934 | .nb_inplace_lshift = (binaryfunc)array_inplace_left_shift, | |||
| 935 | .nb_inplace_rshift = (binaryfunc)array_inplace_right_shift, | |||
| 936 | .nb_inplace_and = (binaryfunc)array_inplace_bitwise_and, | |||
| 937 | .nb_inplace_xor = (binaryfunc)array_inplace_bitwise_xor, | |||
| 938 | .nb_inplace_or = (binaryfunc)array_inplace_bitwise_or, | |||
| 939 | ||||
| 940 | .nb_floor_divide = array_floor_divide, | |||
| 941 | .nb_true_divide = array_true_divide, | |||
| 942 | .nb_inplace_floor_divide = (binaryfunc)array_inplace_floor_divide, | |||
| 943 | .nb_inplace_true_divide = (binaryfunc)array_inplace_true_divide, | |||
| 944 | ||||
| 945 | .nb_matrix_multiply = array_matrix_multiply, | |||
| 946 | .nb_inplace_matrix_multiply = (binaryfunc)array_inplace_matrix_multiply, | |||
| 947 | }; |
| 1 | #ifndef PyObject_CallFunctionObjArgs |
| 2 | struct _object; |
| 3 | typedef struct _object PyObject; |
| 4 | PyObject* clang_analyzer_PyObject_New_Reference(); |
| 5 | PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ...) { |
| 6 | return clang_analyzer_PyObject_New_Reference(); |
| 7 | } |
| 8 | #else |
| 9 | #warning "API PyObject_CallFunctionObjArgs is defined as a macro." |
| 10 | #endif |
| 1 | #define PY_SSIZE_T_CLEAN |
| 2 | #include <Python.h> |
| 3 | #include "structmember.h" |
| 4 | |
| 5 | #define NPY_NO_DEPRECATED_API0x0000000E NPY_API_VERSION0x0000000E |
| 6 | #define _MULTIARRAYMODULE |
| 7 | #include "numpy/arrayobject.h" |
| 8 | #include "numpy/arrayscalars.h" |
| 9 | |
| 10 | #include "numpy/npy_math.h" |
| 11 | |
| 12 | #include "npy_config.h" |
| 13 | |
| 14 | #include "npy_ctypes.h" |
| 15 | #include "npy_pycompat.h" |
| 16 | #include "multiarraymodule.h" |
| 17 | |
| 18 | #include "common.h" |
| 19 | #include "ctors.h" |
| 20 | #include "convert_datatype.h" |
| 21 | #include "shape.h" |
| 22 | #include "npy_buffer.h" |
| 23 | #include "lowlevel_strided_loops.h" |
| 24 | #include "_datetime.h" |
| 25 | #include "datetime_strings.h" |
| 26 | #include "array_assign.h" |
| 27 | #include "mapping.h" /* for array_item_asarray */ |
| 28 | #include "templ_common.h" /* for npy_mul_with_overflow_intp */ |
| 29 | #include "alloc.h" |
| 30 | #include <assert.h> |
| 31 | |
| 32 | #include "get_attr_string.h" |
| 33 | #include "array_coercion.h" |
| 34 | |
| 35 | /* |
| 36 | * Reading from a file or a string. |
| 37 | * |
| 38 | * As much as possible, we try to use the same code for both files and strings, |
| 39 | * so the semantics for fromstring and fromfile are the same, especially with |
| 40 | * regards to the handling of text representations. |
| 41 | */ |
| 42 | |
| 43 | /* |
| 44 | * Scanning function for next element parsing and separator skipping. |
| 45 | * These functions return: |
| 46 | * - 0 to indicate more data to read |
| 47 | * - -1 when reading stopped at the end of the string/file |
| 48 | * - -2 when reading stopped before the end was reached. |
| 49 | * |
| 50 | * The dtype specific parsing functions may set the python error state |
| 51 | * (they have to get the GIL first) additionally. |
| 52 | */ |
| 53 | typedef int (*next_element)(void **, void *, PyArray_Descr *, void *); |
| 54 | typedef int (*skip_separator)(void **, const char *, void *); |
| 55 | |
| 56 | |
| 57 | static npy_bool |
| 58 | string_is_fully_read(char const* start, char const* end) { |
| 59 | if (end == NULL((void*)0)) { |
| 60 | return *start == '\0'; /* null terminated */ |
| 61 | } |
| 62 | else { |
| 63 | return start >= end; /* fixed length */ |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | |
| 68 | static int |
| 69 | fromstr_next_element(char **s, void *dptr, PyArray_Descr *dtype, |
| 70 | const char *end) |
| 71 | { |
| 72 | char *e = *s; |
| 73 | int r = dtype->f->fromstr(*s, dptr, &e, dtype); |
| 74 | /* |
| 75 | * fromstr always returns 0 for basic dtypes; s points to the end of the |
| 76 | * parsed string. If s is not changed an error occurred or the end was |
| 77 | * reached. |
| 78 | */ |
| 79 | if (*s == e || r < 0) { |
| 80 | /* Nothing read, could be end of string or an error (or both) */ |
| 81 | if (string_is_fully_read(*s, end)) { |
| 82 | return -1; |
| 83 | } |
| 84 | return -2; |
| 85 | } |
| 86 | *s = e; |
| 87 | if (end != NULL((void*)0) && *s > end) { |
| 88 | /* Stop the iteration if we read far enough */ |
| 89 | return -1; |
| 90 | } |
| 91 | return 0; |
| 92 | } |
| 93 | |
| 94 | static int |
| 95 | fromfile_next_element(FILE **fp, void *dptr, PyArray_Descr *dtype, |
| 96 | void *NPY_UNUSED(stream_data)(__NPY_UNUSED_TAGGEDstream_data) __attribute__ ((__unused__))) |
| 97 | { |
| 98 | /* the NULL argument is for backwards-compatibility */ |
| 99 | int r = dtype->f->scanfunc(*fp, dptr, NULL((void*)0), dtype); |
| 100 | /* r can be EOF or the number of items read (0 or 1) */ |
| 101 | if (r == 1) { |
| 102 | return 0; |
| 103 | } |
| 104 | else if (r == EOF(-1)) { |
| 105 | return -1; |
| 106 | } |
| 107 | else { |
| 108 | /* unable to read more, but EOF not reached indicating an error. */ |
| 109 | return -2; |
| 110 | } |
| 111 | } |
| 112 | |
| 113 | /* |
| 114 | * Remove multiple whitespace from the separator, and add a space to the |
| 115 | * beginning and end. This simplifies the separator-skipping code below. |
| 116 | */ |
| 117 | static char * |
| 118 | swab_separator(const char *sep) |
| 119 | { |
| 120 | int skip_space = 0; |
| 121 | char *s, *start; |
| 122 | |
| 123 | s = start = malloc(strlen(sep)+3); |
| 124 | if (s == NULL((void*)0)) { |
| 125 | PyErr_NoMemory(); |
| 126 | return NULL((void*)0); |
| 127 | } |
| 128 | /* add space to front if there isn't one */ |
| 129 | if (*sep != '\0' && !isspace(*sep)((*__ctype_b_loc ())[(int) ((*sep))] & (unsigned short int ) _ISspace)) { |
| 130 | *s = ' '; s++; |
| 131 | } |
| 132 | while (*sep != '\0') { |
| 133 | if (isspace(*sep)((*__ctype_b_loc ())[(int) ((*sep))] & (unsigned short int ) _ISspace)) { |
| 134 | if (skip_space) { |
| 135 | sep++; |
| 136 | } |
| 137 | else { |
| 138 | *s = ' '; |
| 139 | s++; |
| 140 | sep++; |
| 141 | skip_space = 1; |
| 142 | } |
| 143 | } |
| 144 | else { |
| 145 | *s = *sep; |
| 146 | s++; |
| 147 | sep++; |
| 148 | skip_space = 0; |
| 149 | } |
| 150 | } |
| 151 | /* add space to end if there isn't one */ |
| 152 | if (s != start && s[-1] == ' ') { |
| 153 | *s = ' '; |
| 154 | s++; |
| 155 | } |
| 156 | *s = '\0'; |
| 157 | return start; |
| 158 | } |
| 159 | |
| 160 | /* |
| 161 | * Assuming that the separator is the next bit in the string (file), skip it. |
| 162 | * |
| 163 | * Single spaces in the separator are matched to arbitrary-long sequences |
| 164 | * of whitespace in the input. If the separator consists only of spaces, |
| 165 | * it matches one or more whitespace characters. |
| 166 | * |
| 167 | * If we can't match the separator, return -2. |
| 168 | * If we hit the end of the string (file), return -1. |
| 169 | * Otherwise, return 0. |
| 170 | */ |
| 171 | static int |
| 172 | fromstr_skip_separator(char **s, const char *sep, const char *end) |
| 173 | { |
| 174 | char *string = *s; |
| 175 | int result = 0; |
| 176 | |
| 177 | while (1) { |
| 178 | char c = *string; |
| 179 | if (string_is_fully_read(string, end)) { |
| 180 | result = -1; |
| 181 | break; |
| 182 | } |
| 183 | else if (*sep == '\0') { |
| 184 | if (string != *s) { |
| 185 | /* matched separator */ |
| 186 | result = 0; |
| 187 | break; |
| 188 | } |
| 189 | else { |
| 190 | /* separator was whitespace wildcard that didn't match */ |
| 191 | result = -2; |
| 192 | break; |
| 193 | } |
| 194 | } |
| 195 | else if (*sep == ' ') { |
| 196 | /* whitespace wildcard */ |
| 197 | if (!isspace(c)((*__ctype_b_loc ())[(int) ((c))] & (unsigned short int) _ISspace )) { |
| 198 | sep++; |
| 199 | continue; |
| 200 | } |
| 201 | } |
| 202 | else if (*sep != c) { |
| 203 | result = -2; |
| 204 | break; |
| 205 | } |
| 206 | else { |
| 207 | sep++; |
| 208 | } |
| 209 | string++; |
| 210 | } |
| 211 | *s = string; |
| 212 | return result; |
| 213 | } |
| 214 | |
| 215 | static int |
| 216 | fromfile_skip_separator(FILE **fp, const char *sep, void *NPY_UNUSED(stream_data)(__NPY_UNUSED_TAGGEDstream_data) __attribute__ ((__unused__))) |
| 217 | { |
| 218 | int result = 0; |
| 219 | const char *sep_start = sep; |
| 220 | |
| 221 | while (1) { |
| 222 | int c = fgetc(*fp); |
| 223 | |
| 224 | if (c == EOF(-1)) { |
| 225 | result = -1; |
| 226 | break; |
| 227 | } |
| 228 | else if (*sep == '\0') { |
| 229 | ungetc(c, *fp); |
| 230 | if (sep != sep_start) { |
| 231 | /* matched separator */ |
| 232 | result = 0; |
| 233 | break; |
| 234 | } |
| 235 | else { |
| 236 | /* separator was whitespace wildcard that didn't match */ |
| 237 | result = -2; |
| 238 | break; |
| 239 | } |
| 240 | } |
| 241 | else if (*sep == ' ') { |
| 242 | /* whitespace wildcard */ |
| 243 | if (!isspace(c)((*__ctype_b_loc ())[(int) ((c))] & (unsigned short int) _ISspace )) { |
| 244 | sep++; |
| 245 | sep_start++; |
| 246 | ungetc(c, *fp); |
| 247 | } |
| 248 | else if (sep == sep_start) { |
| 249 | sep_start--; |
| 250 | } |
| 251 | } |
| 252 | else if (*sep != c) { |
| 253 | ungetc(c, *fp); |
| 254 | result = -2; |
| 255 | break; |
| 256 | } |
| 257 | else { |
| 258 | sep++; |
| 259 | } |
| 260 | } |
| 261 | return result; |
| 262 | } |
| 263 | |
| 264 | /* |
| 265 | * Change a sub-array field to the base descriptor |
| 266 | * and update the dimensions and strides |
| 267 | * appropriately. Dimensions and strides are added |
| 268 | * to the end. |
| 269 | * |
| 270 | * Strides are only added if given (because data is given). |
| 271 | */ |
| 272 | static int |
| 273 | _update_descr_and_dimensions(PyArray_Descr **des, npy_intp *newdims, |
| 274 | npy_intp *newstrides, int oldnd) |
| 275 | { |
| 276 | PyArray_Descr *old; |
| 277 | int newnd; |
| 278 | int numnew; |
| 279 | npy_intp *mydim; |
| 280 | int i; |
| 281 | int tuple; |
| 282 | |
| 283 | old = *des; |
| 284 | *des = old->subarray->base; |
| 285 | |
| 286 | |
| 287 | mydim = newdims + oldnd; |
| 288 | tuple = PyTuple_Check(old->subarray->shape)((((((PyObject*)(old->subarray->shape))->ob_type))-> tp_flags & ((1UL << 26))) != 0); |
| 289 | if (tuple) { |
| 290 | numnew = PyTuple_GET_SIZE(old->subarray->shape)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(old->subarray ->shape))))->ob_size); |
| 291 | } |
| 292 | else { |
| 293 | numnew = 1; |
| 294 | } |
| 295 | |
| 296 | |
| 297 | newnd = oldnd + numnew; |
| 298 | if (newnd > NPY_MAXDIMS32) { |
| 299 | goto finish; |
| 300 | } |
| 301 | if (tuple) { |
| 302 | for (i = 0; i < numnew; i++) { |
| 303 | mydim[i] = (npy_intp) PyLong_AsLong( |
| 304 | PyTuple_GET_ITEM(old->subarray->shape, i)((((void) (0)), (PyTupleObject *)(old->subarray->shape) )->ob_item[i])); |
| 305 | } |
| 306 | } |
| 307 | else { |
| 308 | mydim[0] = (npy_intp) PyLong_AsLong(old->subarray->shape); |
| 309 | } |
| 310 | |
| 311 | if (newstrides) { |
| 312 | npy_intp tempsize; |
| 313 | npy_intp *mystrides; |
| 314 | |
| 315 | mystrides = newstrides + oldnd; |
| 316 | /* Make new strides -- always C-contiguous */ |
| 317 | tempsize = (*des)->elsize; |
| 318 | for (i = numnew - 1; i >= 0; i--) { |
| 319 | mystrides[i] = tempsize; |
| 320 | tempsize *= mydim[i] ? mydim[i] : 1; |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | finish: |
| 325 | Py_INCREF(*des)_Py_INCREF(((PyObject*)(*des))); |
| 326 | Py_DECREF(old)_Py_DECREF(((PyObject*)(old))); |
| 327 | return newnd; |
| 328 | } |
| 329 | |
| 330 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) void |
| 331 | _unaligned_strided_byte_copy(char *dst, npy_intp outstrides, char *src, |
| 332 | npy_intp instrides, npy_intp N, int elsize) |
| 333 | { |
| 334 | npy_intp i; |
| 335 | char *tout = dst; |
| 336 | char *tin = src; |
| 337 | |
| 338 | #define _COPY_N_SIZE(size) \ |
| 339 | for(i=0; i<N; i++) { \ |
| 340 | memcpy(tout, tin, size); \ |
| 341 | tin += instrides; \ |
| 342 | tout += outstrides; \ |
| 343 | } \ |
| 344 | return |
| 345 | |
| 346 | switch(elsize) { |
| 347 | case 8: |
| 348 | _COPY_N_SIZE(8); |
| 349 | case 4: |
| 350 | _COPY_N_SIZE(4); |
| 351 | case 1: |
| 352 | _COPY_N_SIZE(1); |
| 353 | case 2: |
| 354 | _COPY_N_SIZE(2); |
| 355 | case 16: |
| 356 | _COPY_N_SIZE(16); |
| 357 | default: |
| 358 | _COPY_N_SIZE(elsize); |
| 359 | } |
| 360 | #undef _COPY_N_SIZE |
| 361 | |
| 362 | } |
| 363 | |
| 364 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) void |
| 365 | _strided_byte_swap(void *p, npy_intp stride, npy_intp n, int size) |
| 366 | { |
| 367 | char *a, *b, c = 0; |
| 368 | int j, m; |
| 369 | |
| 370 | switch(size) { |
| 371 | case 1: /* no byteswap necessary */ |
| 372 | break; |
| 373 | case 4: |
| 374 | if (npy_is_aligned((void*)((npy_intp)p | stride), sizeof(npy_uint32))) { |
| 375 | for (a = (char*)p; n > 0; n--, a += stride) { |
| 376 | npy_uint32 * a_ = (npy_uint32 *)a; |
| 377 | *a_ = npy_bswap4(*a_); |
| 378 | } |
| 379 | } |
| 380 | else { |
| 381 | for (a = (char*)p; n > 0; n--, a += stride) { |
| 382 | npy_bswap4_unaligned(a); |
| 383 | } |
| 384 | } |
| 385 | break; |
| 386 | case 8: |
| 387 | if (npy_is_aligned((void*)((npy_intp)p | stride), sizeof(npy_uint64))) { |
| 388 | for (a = (char*)p; n > 0; n--, a += stride) { |
| 389 | npy_uint64 * a_ = (npy_uint64 *)a; |
| 390 | *a_ = npy_bswap8(*a_); |
| 391 | } |
| 392 | } |
| 393 | else { |
| 394 | for (a = (char*)p; n > 0; n--, a += stride) { |
| 395 | npy_bswap8_unaligned(a); |
| 396 | } |
| 397 | } |
| 398 | break; |
| 399 | case 2: |
| 400 | if (npy_is_aligned((void*)((npy_intp)p | stride), sizeof(npy_uint16))) { |
| 401 | for (a = (char*)p; n > 0; n--, a += stride) { |
| 402 | npy_uint16 * a_ = (npy_uint16 *)a; |
| 403 | *a_ = npy_bswap2(*a_); |
| 404 | } |
| 405 | } |
| 406 | else { |
| 407 | for (a = (char*)p; n > 0; n--, a += stride) { |
| 408 | npy_bswap2_unaligned(a); |
| 409 | } |
| 410 | } |
| 411 | break; |
| 412 | default: |
| 413 | m = size/2; |
| 414 | for (a = (char *)p; n > 0; n--, a += stride - m) { |
| 415 | b = a + (size - 1); |
| 416 | for (j = 0; j < m; j++) { |
| 417 | c=*a; *a++ = *b; *b-- = c; |
| 418 | } |
| 419 | } |
| 420 | break; |
| 421 | } |
| 422 | } |
| 423 | |
| 424 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) void |
| 425 | byte_swap_vector(void *p, npy_intp n, int size) |
| 426 | { |
| 427 | _strided_byte_swap(p, (npy_intp) size, n, size); |
| 428 | return; |
| 429 | } |
| 430 | |
| 431 | /* If numitems > 1, then dst must be contiguous */ |
| 432 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) void |
| 433 | copy_and_swap(void *dst, void *src, int itemsize, npy_intp numitems, |
| 434 | npy_intp srcstrides, int swap) |
| 435 | { |
| 436 | if ((numitems == 1) || (itemsize == srcstrides)) { |
| 437 | memcpy(dst, src, itemsize*numitems); |
| 438 | } |
| 439 | else { |
| 440 | npy_intp i; |
| 441 | char *s1 = (char *)src; |
| 442 | char *d1 = (char *)dst; |
| 443 | |
| 444 | for (i = 0; i < numitems; i++) { |
| 445 | memcpy(d1, s1, itemsize); |
| 446 | d1 += itemsize; |
| 447 | s1 += srcstrides; |
| 448 | } |
| 449 | } |
| 450 | |
| 451 | if (swap) { |
| 452 | byte_swap_vector(dst, numitems, itemsize); |
| 453 | } |
| 454 | } |
| 455 | |
| 456 | |
| 457 | /* |
| 458 | * Recursive helper to assign using a coercion cache. This function |
| 459 | * must consume the cache depth first, just as the cache was originally |
| 460 | * produced. |
| 461 | */ |
| 462 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) int |
| 463 | PyArray_AssignFromCache_Recursive( |
| 464 | PyArrayObject *self, const int ndim, coercion_cache_obj **cache) |
| 465 | { |
| 466 | /* Consume first cache element by extracting information and freeing it */ |
| 467 | PyObject *original_obj = (*cache)->converted_obj; |
| 468 | PyObject *obj = (*cache)->arr_or_sequence; |
| 469 | Py_INCREF(obj)_Py_INCREF(((PyObject*)(obj))); |
| 470 | npy_bool sequence = (*cache)->sequence; |
| 471 | int depth = (*cache)->depth; |
| 472 | *cache = npy_unlink_coercion_cache(*cache); |
| 473 | |
| 474 | /* |
| 475 | * The maximum depth is special (specifically for objects), but usually |
| 476 | * unrolled in the sequence branch below. |
| 477 | */ |
| 478 | if (NPY_UNLIKELY(depth == ndim)__builtin_expect(!!(depth == ndim), 0)) { |
| 479 | /* |
| 480 | * We have reached the maximum depth. We should simply assign to the |
| 481 | * element in principle. There is one exception. If this is a 0-D |
| 482 | * array being stored into a 0-D array (but we do not reach here then). |
| 483 | */ |
| 484 | if (PyArray_ISOBJECT(self)((PyArray_TYPE(self)) == NPY_OBJECT)) { |
| 485 | assert(ndim != 0)((void) (0)); /* guaranteed by PyArray_AssignFromCache */ |
| 486 | assert(PyArray_NDIM(self) == 0)((void) (0)); |
| 487 | Py_DECREF(obj)_Py_DECREF(((PyObject*)(obj))); |
| 488 | return PyArray_Pack(PyArray_DESCR(self), PyArray_BYTES(self), |
| 489 | original_obj); |
| 490 | } |
| 491 | if (sequence) { |
| 492 | /* |
| 493 | * Sanity check which may be removed, the error is raised already |
| 494 | * in `PyArray_DiscoverDTypeAndShape`. |
| 495 | */ |
| 496 | assert(0)((void) (0)); |
| 497 | PyErr_SetString(PyExc_RuntimeError, |
| 498 | "setting an array element with a sequence"); |
| 499 | goto fail; |
| 500 | } |
| 501 | else if (original_obj != obj || !PyArray_CheckExact(obj)(((PyObject*)(obj))->ob_type == &PyArray_Type)) { |
| 502 | /* |
| 503 | * If the leave node is an array-like, but not a numpy array, |
| 504 | * we pretend it is an arbitrary scalar. This means that in |
| 505 | * most cases (where the dtype is int or float), we will end |
| 506 | * up using float(array-like), or int(array-like). That does |
| 507 | * not support general casting, but helps Quantity and masked |
| 508 | * arrays, because it allows them to raise an error when |
| 509 | * `__float__()` or `__int__()` is called. |
| 510 | */ |
| 511 | Py_DECREF(obj)_Py_DECREF(((PyObject*)(obj))); |
| 512 | return PyArray_SETITEM(self, PyArray_BYTES(self), original_obj); |
| 513 | } |
| 514 | } |
| 515 | |
| 516 | /* The element is either a sequence, or an array */ |
| 517 | if (!sequence) { |
| 518 | /* Straight forward array assignment */ |
| 519 | assert(PyArray_Check(obj))((void) (0)); |
| 520 | if (PyArray_CopyInto(self, (PyArrayObject *)obj) < 0) { |
| 521 | goto fail; |
| 522 | } |
| 523 | } |
| 524 | else { |
| 525 | assert(depth != ndim)((void) (0)); |
| 526 | npy_intp length = PySequence_LengthPySequence_Size(obj); |
| 527 | if (length != PyArray_DIMS(self)[0]) { |
| 528 | PyErr_SetString(PyExc_RuntimeError, |
| 529 | "Inconsistent object during array creation? " |
| 530 | "Content of sequences changed (length inconsistent)."); |
| 531 | goto fail; |
| 532 | } |
| 533 | |
| 534 | for (npy_intp i = 0; i < length; i++) { |
| 535 | PyObject *value = PySequence_Fast_GET_ITEM(obj, i)(((((((PyObject*)(obj))->ob_type))->tp_flags & ((1UL << 25))) != 0) ? (((PyListObject *)(obj))->ob_item[ i]) : ((((void) (0)), (PyTupleObject *)(obj))->ob_item[i]) ); |
| 536 | |
| 537 | if (*cache == NULL((void*)0) || (*cache)->converted_obj != value || |
| 538 | (*cache)->depth != depth + 1) { |
| 539 | if (ndim != depth + 1) { |
| 540 | PyErr_SetString(PyExc_RuntimeError, |
| 541 | "Inconsistent object during array creation? " |
| 542 | "Content of sequences changed (now too shallow)."); |
| 543 | goto fail; |
| 544 | } |
| 545 | /* Straight forward assignment of elements */ |
| 546 | char *item; |
| 547 | item = (PyArray_BYTES(self) + i * PyArray_STRIDES(self)[0]); |
| 548 | if (PyArray_Pack(PyArray_DESCR(self), item, value) < 0) { |
| 549 | goto fail; |
| 550 | } |
| 551 | } |
| 552 | else { |
| 553 | PyArrayObject *view; |
| 554 | view = (PyArrayObject *)array_item_asarray(self, i); |
| 555 | if (view == NULL((void*)0)) { |
| 556 | goto fail; |
| 557 | } |
| 558 | if (PyArray_AssignFromCache_Recursive(view, ndim, cache) < 0) { |
| 559 | Py_DECREF(view)_Py_DECREF(((PyObject*)(view))); |
| 560 | goto fail; |
| 561 | } |
| 562 | Py_DECREF(view)_Py_DECREF(((PyObject*)(view))); |
| 563 | } |
| 564 | } |
| 565 | } |
| 566 | Py_DECREF(obj)_Py_DECREF(((PyObject*)(obj))); |
| 567 | return 0; |
| 568 | |
| 569 | fail: |
| 570 | Py_DECREF(obj)_Py_DECREF(((PyObject*)(obj))); |
| 571 | return -1; |
| 572 | } |
| 573 | |
| 574 | |
| 575 | /** |
| 576 | * Fills an item based on a coercion cache object. It consumes the cache |
| 577 | * object while doing so. |
| 578 | * |
| 579 | * @param self Array to fill. |
| 580 | * @param cache coercion_cache_object, will be consumed. The cache must not |
| 581 | * contain a single array (must start with a sequence). The array case |
| 582 | * should be handled by `PyArray_FromArray()` before. |
| 583 | * @return 0 on success -1 on failure. |
| 584 | */ |
| 585 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) int |
| 586 | PyArray_AssignFromCache(PyArrayObject *self, coercion_cache_obj *cache) { |
| 587 | int ndim = PyArray_NDIM(self); |
| 588 | /* |
| 589 | * Do not support ndim == 0 now with an array in the cache. |
| 590 | * The ndim == 0 is special because np.array(np.array(0), dtype=object) |
| 591 | * should unpack the inner array. |
| 592 | * Since the single-array case is special, it is handled previously |
| 593 | * in either case. |
| 594 | */ |
| 595 | assert(cache->sequence)((void) (0)); |
| 596 | assert(ndim != 0)((void) (0)); /* guaranteed if cache contains a sequence */ |
| 597 | |
| 598 | if (PyArray_AssignFromCache_Recursive(self, ndim, &cache) < 0) { |
| 599 | /* free the remaining cache. */ |
| 600 | npy_free_coercion_cache(cache); |
| 601 | return -1; |
| 602 | } |
| 603 | |
| 604 | /* |
| 605 | * Sanity check, this is the initial call, and when it returns, the |
| 606 | * cache has to be fully consumed, otherwise something is wrong. |
| 607 | * NOTE: May be nicer to put into a recursion helper. |
| 608 | */ |
| 609 | if (cache != NULL((void*)0)) { |
| 610 | PyErr_SetString(PyExc_RuntimeError, |
| 611 | "Inconsistent object during array creation? " |
| 612 | "Content of sequences changed (cache not consumed)."); |
| 613 | npy_free_coercion_cache(cache); |
| 614 | return -1; |
| 615 | } |
| 616 | return 0; |
| 617 | } |
| 618 | |
| 619 | |
| 620 | static void |
| 621 | raise_memory_error(int nd, npy_intp const *dims, PyArray_Descr *descr) |
| 622 | { |
| 623 | static PyObject *exc_type = NULL((void*)0); |
| 624 | |
| 625 | npy_cache_import( |
| 626 | "numpy.core._exceptions", "_ArrayMemoryError", |
| 627 | &exc_type); |
| 628 | if (exc_type == NULL((void*)0)) { |
| 629 | goto fail; |
| 630 | } |
| 631 | |
| 632 | PyObject *shape = PyArray_IntTupleFromIntp(nd, dims); |
| 633 | if (shape == NULL((void*)0)) { |
| 634 | goto fail; |
| 635 | } |
| 636 | |
| 637 | /* produce an error object */ |
| 638 | PyObject *exc_value = PyTuple_Pack(2, shape, (PyObject *)descr); |
| 639 | Py_DECREF(shape)_Py_DECREF(((PyObject*)(shape))); |
| 640 | if (exc_value == NULL((void*)0)){ |
| 641 | goto fail; |
| 642 | } |
| 643 | PyErr_SetObject(exc_type, exc_value); |
| 644 | Py_DECREF(exc_value)_Py_DECREF(((PyObject*)(exc_value))); |
| 645 | return; |
| 646 | |
| 647 | fail: |
| 648 | /* we couldn't raise the formatted exception for some reason */ |
| 649 | PyErr_WriteUnraisable(NULL((void*)0)); |
| 650 | PyErr_NoMemory(); |
| 651 | } |
| 652 | |
| 653 | /* |
| 654 | * Generic new array creation routine. |
| 655 | * Internal variant with calloc argument for PyArray_Zeros. |
| 656 | * |
| 657 | * steals a reference to descr. On failure or descr->subarray, descr will |
| 658 | * be decrefed. |
| 659 | */ |
| 660 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 661 | PyArray_NewFromDescr_int( |
| 662 | PyTypeObject *subtype, PyArray_Descr *descr, int nd, |
| 663 | npy_intp const *dims, npy_intp const *strides, void *data, |
| 664 | int flags, PyObject *obj, PyObject *base, int zeroed, |
| 665 | int allow_emptystring) |
| 666 | { |
| 667 | PyArrayObject_fields *fa; |
| 668 | npy_intp nbytes; |
| 669 | |
| 670 | if (nd > NPY_MAXDIMS32 || nd < 0) { |
| 671 | PyErr_Format(PyExc_ValueError, |
| 672 | "number of dimensions must be within [0, %d]", NPY_MAXDIMS32); |
| 673 | Py_DECREF(descr)_Py_DECREF(((PyObject*)(descr))); |
| 674 | return NULL((void*)0); |
| 675 | } |
| 676 | |
| 677 | if (descr->subarray) { |
| 678 | PyObject *ret; |
| 679 | npy_intp newdims[2*NPY_MAXDIMS32]; |
| 680 | npy_intp *newstrides = NULL((void*)0); |
| 681 | memcpy(newdims, dims, nd*sizeof(npy_intp)); |
| 682 | if (strides) { |
| 683 | newstrides = newdims + NPY_MAXDIMS32; |
| 684 | memcpy(newstrides, strides, nd*sizeof(npy_intp)); |
| 685 | } |
| 686 | nd =_update_descr_and_dimensions(&descr, newdims, |
| 687 | newstrides, nd); |
| 688 | ret = PyArray_NewFromDescr_int( |
| 689 | subtype, descr, |
| 690 | nd, newdims, newstrides, data, |
| 691 | flags, obj, base, |
| 692 | zeroed, allow_emptystring); |
| 693 | return ret; |
| 694 | } |
| 695 | |
| 696 | /* Check datatype element size */ |
| 697 | nbytes = descr->elsize; |
| 698 | if (PyDataType_ISUNSIZED(descr)((descr)->elsize == 0 && !(((PyArray_Descr *)(descr ))->names != ((void*)0)))) { |
| 699 | if (!PyDataType_ISFLEXIBLE(descr)(((((PyArray_Descr*)(descr))->type_num) >=NPY_STRING) && ((((PyArray_Descr*)(descr))->type_num) <=NPY_VOID))) { |
| 700 | PyErr_SetString(PyExc_TypeError, "Empty data-type"); |
| 701 | Py_DECREF(descr)_Py_DECREF(((PyObject*)(descr))); |
| 702 | return NULL((void*)0); |
| 703 | } |
| 704 | else if (PyDataType_ISSTRING(descr)(((((PyArray_Descr*)(descr))->type_num) == NPY_STRING) || ( (((PyArray_Descr*)(descr))->type_num) == NPY_UNICODE)) && !allow_emptystring && |
| 705 | data == NULL((void*)0)) { |
| 706 | PyArray_DESCR_REPLACE(descr)do { PyArray_Descr *_new_; _new_ = PyArray_DescrNew(descr); _Py_XDECREF (((PyObject*)(descr))); descr = _new_; } while(0); |
| 707 | if (descr == NULL((void*)0)) { |
| 708 | return NULL((void*)0); |
| 709 | } |
| 710 | if (descr->type_num == NPY_STRING) { |
| 711 | nbytes = descr->elsize = 1; |
| 712 | } |
| 713 | else { |
| 714 | nbytes = descr->elsize = sizeof(npy_ucs4); |
| 715 | } |
| 716 | } |
| 717 | } |
| 718 | |
| 719 | fa = (PyArrayObject_fields *) subtype->tp_alloc(subtype, 0); |
| 720 | if (fa == NULL((void*)0)) { |
| 721 | Py_DECREF(descr)_Py_DECREF(((PyObject*)(descr))); |
| 722 | return NULL((void*)0); |
| 723 | } |
| 724 | fa->_buffer_info = NULL((void*)0); |
| 725 | fa->nd = nd; |
| 726 | fa->dimensions = NULL((void*)0); |
| 727 | fa->data = NULL((void*)0); |
| 728 | |
| 729 | if (data == NULL((void*)0)) { |
| 730 | fa->flags = NPY_ARRAY_DEFAULT((0x0001 | (0x0100 | 0x0400))); |
| 731 | if (flags) { |
| 732 | fa->flags |= NPY_ARRAY_F_CONTIGUOUS0x0002; |
| 733 | if (nd > 1) { |
| 734 | fa->flags &= ~NPY_ARRAY_C_CONTIGUOUS0x0001; |
| 735 | } |
| 736 | flags = NPY_ARRAY_F_CONTIGUOUS0x0002; |
| 737 | } |
| 738 | } |
| 739 | else { |
| 740 | fa->flags = (flags & ~NPY_ARRAY_WRITEBACKIFCOPY0x2000); |
| 741 | fa->flags &= ~NPY_ARRAY_UPDATEIFCOPY0x1000; |
| 742 | } |
| 743 | fa->descr = descr; |
| 744 | fa->base = (PyObject *)NULL((void*)0); |
| 745 | fa->weakreflist = (PyObject *)NULL((void*)0); |
| 746 | |
| 747 | if (nd > 0) { |
| 748 | fa->dimensions = npy_alloc_cache_dim(2 * nd); |
| 749 | if (fa->dimensions == NULL((void*)0)) { |
| 750 | PyErr_NoMemory(); |
| 751 | goto fail; |
| 752 | } |
| 753 | fa->strides = fa->dimensions + nd; |
| 754 | |
| 755 | /* Copy dimensions, check them, and find total array size `nbytes` */ |
| 756 | for (int i = 0; i < nd; i++) { |
| 757 | fa->dimensions[i] = dims[i]; |
| 758 | |
| 759 | if (fa->dimensions[i] == 0) { |
| 760 | /* |
| 761 | * Compare to PyArray_OverflowMultiplyList that |
| 762 | * returns 0 in this case. |
| 763 | */ |
| 764 | continue; |
| 765 | } |
| 766 | |
| 767 | if (fa->dimensions[i] < 0) { |
| 768 | PyErr_SetString(PyExc_ValueError, |
| 769 | "negative dimensions are not allowed"); |
| 770 | goto fail; |
| 771 | } |
| 772 | |
| 773 | /* |
| 774 | * Care needs to be taken to avoid integer overflow when multiplying |
| 775 | * the dimensions together to get the total size of the array. |
| 776 | */ |
| 777 | if (npy_mul_with_overflow_intp(&nbytes, nbytes, fa->dimensions[i])) { |
| 778 | PyErr_SetString(PyExc_ValueError, |
| 779 | "array is too big; `arr.size * arr.dtype.itemsize` " |
| 780 | "is larger than the maximum possible size."); |
| 781 | goto fail; |
| 782 | } |
| 783 | } |
| 784 | |
| 785 | /* Fill the strides (or copy them if they were passed in) */ |
| 786 | if (strides == NULL((void*)0)) { |
| 787 | /* fill the strides and set the contiguity flags */ |
| 788 | _array_fill_strides(fa->strides, dims, nd, descr->elsize, |
| 789 | flags, &(fa->flags)); |
| 790 | } |
| 791 | else { |
| 792 | /* User to provided strides (user is responsible for correctness) */ |
| 793 | for (int i = 0; i < nd; i++) { |
| 794 | fa->strides[i] = strides[i]; |
| 795 | } |
| 796 | /* Since the strides were passed in must update contiguity */ |
| 797 | PyArray_UpdateFlags((PyArrayObject *)fa, |
| 798 | NPY_ARRAY_C_CONTIGUOUS0x0001|NPY_ARRAY_F_CONTIGUOUS0x0002); |
| 799 | } |
| 800 | } |
| 801 | else { |
| 802 | fa->dimensions = NULL((void*)0); |
| 803 | fa->strides = NULL((void*)0); |
| 804 | fa->flags |= NPY_ARRAY_C_CONTIGUOUS0x0001|NPY_ARRAY_F_CONTIGUOUS0x0002; |
| 805 | } |
| 806 | |
| 807 | if (data == NULL((void*)0)) { |
| 808 | /* |
| 809 | * Allocate something even for zero-space arrays |
| 810 | * e.g. shape=(0,) -- otherwise buffer exposure |
| 811 | * (a.data) doesn't work as it should. |
| 812 | * Could probably just allocate a few bytes here. -- Chuck |
| 813 | */ |
| 814 | if (nbytes == 0) { |
| 815 | nbytes = descr->elsize ? descr->elsize : 1; |
| 816 | } |
| 817 | /* |
| 818 | * It is bad to have uninitialized OBJECT pointers |
| 819 | * which could also be sub-fields of a VOID array |
| 820 | */ |
| 821 | if (zeroed || PyDataType_FLAGCHK(descr, NPY_NEEDS_INIT)(((descr)->flags & (0x08)) == (0x08))) { |
| 822 | data = npy_alloc_cache_zero(nbytes); |
| 823 | } |
| 824 | else { |
| 825 | data = npy_alloc_cache(nbytes); |
| 826 | } |
| 827 | if (data == NULL((void*)0)) { |
| 828 | raise_memory_error(fa->nd, fa->dimensions, descr); |
| 829 | goto fail; |
| 830 | } |
| 831 | fa->flags |= NPY_ARRAY_OWNDATA0x0004; |
| 832 | } |
| 833 | else { |
| 834 | /* |
| 835 | * If data is passed in, this object won't own it by default. |
| 836 | * Caller must arrange for this to be reset if truly desired |
| 837 | */ |
| 838 | fa->flags &= ~NPY_ARRAY_OWNDATA0x0004; |
| 839 | } |
| 840 | fa->data = data; |
| 841 | |
| 842 | /* |
| 843 | * Always update the aligned flag. Not owned data or input strides may |
| 844 | * not be aligned. Also on some platforms (debian sparc) malloc does not |
| 845 | * provide enough alignment for long double types. |
| 846 | */ |
| 847 | PyArray_UpdateFlags((PyArrayObject *)fa, NPY_ARRAY_ALIGNED0x0100); |
| 848 | |
| 849 | /* Set the base object. It's important to do it here so that |
| 850 | * __array_finalize__ below receives it |
| 851 | */ |
| 852 | if (base != NULL((void*)0)) { |
| 853 | Py_INCREF(base)_Py_INCREF(((PyObject*)(base))); |
| 854 | if (PyArray_SetBaseObject((PyArrayObject *)fa, base) < 0) { |
| 855 | goto fail; |
| 856 | } |
| 857 | } |
| 858 | |
| 859 | /* |
| 860 | * call the __array_finalize__ method if a subtype was requested. |
| 861 | * If obj is NULL use Py_None for the Python callback. |
| 862 | */ |
| 863 | if (subtype != &PyArray_Type) { |
| 864 | PyObject *res, *func; |
| 865 | |
| 866 | func = PyObject_GetAttr((PyObject *)fa, npy_ma_str_array_finalize); |
| 867 | if (func == NULL((void*)0)) { |
| 868 | goto fail; |
| 869 | } |
| 870 | else if (func == Py_None(&_Py_NoneStruct)) { |
| 871 | Py_DECREF(func)_Py_DECREF(((PyObject*)(func))); |
| 872 | } |
| 873 | else { |
| 874 | if (PyCapsule_CheckExact(func)((((PyObject*)(func))->ob_type) == &PyCapsule_Type)) { |
| 875 | /* A C-function is stored here */ |
| 876 | PyArray_FinalizeFunc *cfunc; |
| 877 | cfunc = PyCapsule_GetPointer(func, NULL((void*)0)); |
| 878 | Py_DECREF(func)_Py_DECREF(((PyObject*)(func))); |
| 879 | if (cfunc == NULL((void*)0)) { |
| 880 | goto fail; |
| 881 | } |
| 882 | if (cfunc((PyArrayObject *)fa, obj) < 0) { |
| 883 | goto fail; |
| 884 | } |
| 885 | } |
| 886 | else { |
| 887 | if (obj == NULL((void*)0)) { |
| 888 | obj = Py_None(&_Py_NoneStruct); |
| 889 | } |
| 890 | res = PyObject_CallFunctionObjArgs(func, obj, NULL((void*)0)); |
| 891 | Py_DECREF(func)_Py_DECREF(((PyObject*)(func))); |
| 892 | if (res == NULL((void*)0)) { |
| 893 | goto fail; |
| 894 | } |
| 895 | else { |
| 896 | Py_DECREF(res)_Py_DECREF(((PyObject*)(res))); |
| 897 | } |
| 898 | } |
| 899 | } |
| 900 | } |
| 901 | return (PyObject *)fa; |
| 902 | |
| 903 | fail: |
| 904 | Py_DECREF(fa)_Py_DECREF(((PyObject*)(fa))); |
| 905 | return NULL((void*)0); |
| 906 | } |
| 907 | |
| 908 | |
| 909 | /*NUMPY_API |
| 910 | * Generic new array creation routine. |
| 911 | * |
| 912 | * steals a reference to descr. On failure or when dtype->subarray is |
| 913 | * true, dtype will be decrefed. |
| 914 | */ |
| 915 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 916 | PyArray_NewFromDescr( |
| 917 | PyTypeObject *subtype, PyArray_Descr *descr, |
| 918 | int nd, npy_intp const *dims, npy_intp const *strides, void *data, |
| 919 | int flags, PyObject *obj) |
| 920 | { |
| 921 | return PyArray_NewFromDescrAndBase( |
| 922 | subtype, descr, |
| 923 | nd, dims, strides, data, |
| 924 | flags, obj, NULL((void*)0)); |
| 925 | } |
| 926 | |
| 927 | /* |
| 928 | * Sets the base object using PyArray_SetBaseObject |
| 929 | */ |
| 930 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 931 | PyArray_NewFromDescrAndBase( |
| 932 | PyTypeObject *subtype, PyArray_Descr *descr, |
| 933 | int nd, npy_intp const *dims, npy_intp const *strides, void *data, |
| 934 | int flags, PyObject *obj, PyObject *base) |
| 935 | { |
| 936 | return PyArray_NewFromDescr_int(subtype, descr, nd, |
| 937 | dims, strides, data, |
| 938 | flags, obj, base, 0, 0); |
| 939 | } |
| 940 | |
| 941 | /* |
| 942 | * Creates a new array with the same shape as the provided one, |
| 943 | * with possible memory layout order, data type and shape changes. |
| 944 | * |
| 945 | * prototype - The array the new one should be like. |
| 946 | * order - NPY_CORDER - C-contiguous result. |
| 947 | * NPY_FORTRANORDER - Fortran-contiguous result. |
| 948 | * NPY_ANYORDER - Fortran if prototype is Fortran, C otherwise. |
| 949 | * NPY_KEEPORDER - Keeps the axis ordering of prototype. |
| 950 | * dtype - If not NULL, overrides the data type of the result. |
| 951 | * ndim - If not -1, overrides the shape of the result. |
| 952 | * dims - If ndim is not -1, overrides the shape of the result. |
| 953 | * subok - If 1, use the prototype's array subtype, otherwise |
| 954 | * always create a base-class array. |
| 955 | * |
| 956 | * NOTE: If dtype is not NULL, steals the dtype reference. On failure or when |
| 957 | * dtype->subarray is true, dtype will be decrefed. |
| 958 | */ |
| 959 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 960 | PyArray_NewLikeArrayWithShape(PyArrayObject *prototype, NPY_ORDER order, |
| 961 | PyArray_Descr *dtype, int ndim, npy_intp const *dims, int subok) |
| 962 | { |
| 963 | PyObject *ret = NULL((void*)0); |
| 964 | |
| 965 | if (ndim == -1) { |
| 966 | ndim = PyArray_NDIM(prototype); |
| 967 | dims = PyArray_DIMS(prototype); |
| 968 | } |
| 969 | else if (order == NPY_KEEPORDER && (ndim != PyArray_NDIM(prototype))) { |
| 970 | order = NPY_CORDER; |
| 971 | } |
| 972 | |
| 973 | /* If no override data type, use the one from the prototype */ |
| 974 | if (dtype == NULL((void*)0)) { |
| 975 | dtype = PyArray_DESCR(prototype); |
| 976 | Py_INCREF(dtype)_Py_INCREF(((PyObject*)(dtype))); |
| 977 | } |
| 978 | |
| 979 | /* Handle ANYORDER and simple KEEPORDER cases */ |
| 980 | switch (order) { |
| 981 | case NPY_ANYORDER: |
| 982 | order = PyArray_ISFORTRAN(prototype)(PyArray_CHKFLAGS(prototype, 0x0002) && (!PyArray_CHKFLAGS (prototype, 0x0001))) ? |
| 983 | NPY_FORTRANORDER : NPY_CORDER; |
| 984 | break; |
| 985 | case NPY_KEEPORDER: |
| 986 | if (PyArray_IS_C_CONTIGUOUS(prototype)PyArray_CHKFLAGS((prototype), 0x0001) || ndim <= 1) { |
| 987 | order = NPY_CORDER; |
| 988 | break; |
| 989 | } |
| 990 | else if (PyArray_IS_F_CONTIGUOUS(prototype)PyArray_CHKFLAGS((prototype), 0x0002)) { |
| 991 | order = NPY_FORTRANORDER; |
| 992 | break; |
| 993 | } |
| 994 | break; |
| 995 | default: |
| 996 | break; |
| 997 | } |
| 998 | |
| 999 | /* If it's not KEEPORDER, this is simple */ |
| 1000 | if (order != NPY_KEEPORDER) { |
| 1001 | ret = PyArray_NewFromDescr(subok ? Py_TYPE(prototype)(((PyObject*)(prototype))->ob_type) : &PyArray_Type, |
| 1002 | dtype, |
| 1003 | ndim, |
| 1004 | dims, |
| 1005 | NULL((void*)0), |
| 1006 | NULL((void*)0), |
| 1007 | order, |
| 1008 | subok ? (PyObject *)prototype : NULL((void*)0)); |
| 1009 | } |
| 1010 | /* KEEPORDER needs some analysis of the strides */ |
| 1011 | else { |
| 1012 | npy_intp strides[NPY_MAXDIMS32], stride; |
| 1013 | npy_stride_sort_item strideperm[NPY_MAXDIMS32]; |
| 1014 | int idim; |
| 1015 | |
| 1016 | PyArray_CreateSortedStridePerm(ndim, |
| 1017 | PyArray_STRIDES(prototype), |
| 1018 | strideperm); |
| 1019 | |
| 1020 | /* Build the new strides */ |
| 1021 | stride = dtype->elsize; |
| 1022 | for (idim = ndim-1; idim >= 0; --idim) { |
| 1023 | npy_intp i_perm = strideperm[idim].perm; |
| 1024 | strides[i_perm] = stride; |
| 1025 | stride *= dims[i_perm]; |
| 1026 | } |
| 1027 | |
| 1028 | /* Finally, allocate the array */ |
| 1029 | ret = PyArray_NewFromDescr(subok ? Py_TYPE(prototype)(((PyObject*)(prototype))->ob_type) : &PyArray_Type, |
| 1030 | dtype, |
| 1031 | ndim, |
| 1032 | dims, |
| 1033 | strides, |
| 1034 | NULL((void*)0), |
| 1035 | 0, |
| 1036 | subok ? (PyObject *)prototype : NULL((void*)0)); |
| 1037 | } |
| 1038 | |
| 1039 | return ret; |
| 1040 | } |
| 1041 | |
| 1042 | /*NUMPY_API |
| 1043 | * Creates a new array with the same shape as the provided one, |
| 1044 | * with possible memory layout order and data type changes. |
| 1045 | * |
| 1046 | * prototype - The array the new one should be like. |
| 1047 | * order - NPY_CORDER - C-contiguous result. |
| 1048 | * NPY_FORTRANORDER - Fortran-contiguous result. |
| 1049 | * NPY_ANYORDER - Fortran if prototype is Fortran, C otherwise. |
| 1050 | * NPY_KEEPORDER - Keeps the axis ordering of prototype. |
| 1051 | * dtype - If not NULL, overrides the data type of the result. |
| 1052 | * subok - If 1, use the prototype's array subtype, otherwise |
| 1053 | * always create a base-class array. |
| 1054 | * |
| 1055 | * NOTE: If dtype is not NULL, steals the dtype reference. On failure or when |
| 1056 | * dtype->subarray is true, dtype will be decrefed. |
| 1057 | */ |
| 1058 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 1059 | PyArray_NewLikeArray(PyArrayObject *prototype, NPY_ORDER order, |
| 1060 | PyArray_Descr *dtype, int subok) |
| 1061 | { |
| 1062 | return PyArray_NewLikeArrayWithShape(prototype, order, dtype, -1, NULL((void*)0), subok); |
| 1063 | } |
| 1064 | |
| 1065 | /*NUMPY_API |
| 1066 | * Generic new array creation routine. |
| 1067 | */ |
| 1068 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 1069 | PyArray_New( |
| 1070 | PyTypeObject *subtype, int nd, npy_intp const *dims, int type_num, |
| 1071 | npy_intp const *strides, void *data, int itemsize, int flags, |
| 1072 | PyObject *obj) |
| 1073 | { |
| 1074 | PyArray_Descr *descr; |
| 1075 | PyObject *new; |
| 1076 | |
| 1077 | descr = PyArray_DescrFromType(type_num); |
| 1078 | if (descr == NULL((void*)0)) { |
| 1079 | return NULL((void*)0); |
| 1080 | } |
| 1081 | if (PyDataType_ISUNSIZED(descr)((descr)->elsize == 0 && !(((PyArray_Descr *)(descr ))->names != ((void*)0)))) { |
| 1082 | if (itemsize < 1) { |
| 1083 | PyErr_SetString(PyExc_ValueError, |
| 1084 | "data type must provide an itemsize"); |
| 1085 | Py_DECREF(descr)_Py_DECREF(((PyObject*)(descr))); |
| 1086 | return NULL((void*)0); |
| 1087 | } |
| 1088 | PyArray_DESCR_REPLACE(descr)do { PyArray_Descr *_new_; _new_ = PyArray_DescrNew(descr); _Py_XDECREF (((PyObject*)(descr))); descr = _new_; } while(0); |
| 1089 | descr->elsize = itemsize; |
| 1090 | } |
| 1091 | new = PyArray_NewFromDescr(subtype, descr, nd, dims, strides, |
| 1092 | data, flags, obj); |
| 1093 | return new; |
| 1094 | } |
| 1095 | |
| 1096 | |
| 1097 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyArray_Descr * |
| 1098 | _dtype_from_buffer_3118(PyObject *memoryview) |
| 1099 | { |
| 1100 | PyArray_Descr *descr; |
| 1101 | Py_buffer *view = PyMemoryView_GET_BUFFER(memoryview)(&((PyMemoryViewObject *)(memoryview))->view); |
| 1102 | if (view->format != NULL((void*)0)) { |
| 1103 | descr = _descriptor_from_pep3118_format(view->format); |
| 1104 | if (descr == NULL((void*)0)) { |
| 1105 | return NULL((void*)0); |
| 1106 | } |
| 1107 | } |
| 1108 | else { |
| 1109 | /* If no format is specified, just assume a byte array |
| 1110 | * TODO: void would make more sense here, as it wouldn't null |
| 1111 | * terminate. |
| 1112 | */ |
| 1113 | descr = PyArray_DescrNewFromType(NPY_STRING); |
| 1114 | descr->elsize = view->itemsize; |
| 1115 | } |
| 1116 | return descr; |
| 1117 | } |
| 1118 | |
| 1119 | |
| 1120 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 1121 | _array_from_buffer_3118(PyObject *memoryview) |
| 1122 | { |
| 1123 | /* PEP 3118 */ |
| 1124 | Py_buffer *view; |
| 1125 | PyArray_Descr *descr = NULL((void*)0); |
| 1126 | PyObject *r = NULL((void*)0); |
| 1127 | int nd, flags; |
| 1128 | Py_ssize_t d; |
| 1129 | npy_intp shape[NPY_MAXDIMS32], strides[NPY_MAXDIMS32]; |
| 1130 | |
| 1131 | view = PyMemoryView_GET_BUFFER(memoryview)(&((PyMemoryViewObject *)(memoryview))->view); |
| 1132 | nd = view->ndim; |
| 1133 | descr = _dtype_from_buffer_3118(memoryview); |
| 1134 | |
| 1135 | if (descr == NULL((void*)0)) { |
| 1136 | return NULL((void*)0); |
| 1137 | } |
| 1138 | |
| 1139 | /* Sanity check */ |
| 1140 | if (descr->elsize != view->itemsize) { |
| 1141 | /* Ctypes has bugs in its PEP3118 implementation, which we need to |
| 1142 | * work around. |
| 1143 | * |
| 1144 | * bpo-10746 |
| 1145 | * bpo-32780 |
| 1146 | * bpo-32782 |
| 1147 | * |
| 1148 | * Note that even if the above are fixed in main, we have to drop the |
| 1149 | * early patch versions of python to actually make use of the fixes. |
| 1150 | */ |
| 1151 | if (!npy_ctypes_check(Py_TYPE(view->obj)(((PyObject*)(view->obj))->ob_type))) { |
| 1152 | /* This object has no excuse for a broken PEP3118 buffer */ |
| 1153 | PyErr_Format( |
| 1154 | PyExc_RuntimeError, |
| 1155 | "Item size %zd for PEP 3118 buffer format " |
| 1156 | "string %s does not match the dtype %c item size %d.", |
| 1157 | view->itemsize, view->format, descr->type, |
| 1158 | descr->elsize); |
| 1159 | Py_DECREF(descr)_Py_DECREF(((PyObject*)(descr))); |
| 1160 | return NULL((void*)0); |
| 1161 | } |
| 1162 | |
| 1163 | if (PyErr_Warn(PyErr_WarnEx(PyExc_RuntimeWarning, "A builtin ctypes object gave a PEP3118 format " "string that does not match its itemsize, so a " "best-guess will be made of the data type. " "Newer versions of python may behave correctly.", 1) |
| 1164 | PyExc_RuntimeWarning,PyErr_WarnEx(PyExc_RuntimeWarning, "A builtin ctypes object gave a PEP3118 format " "string that does not match its itemsize, so a " "best-guess will be made of the data type. " "Newer versions of python may behave correctly.", 1) |
| 1165 | "A builtin ctypes object gave a PEP3118 format "PyErr_WarnEx(PyExc_RuntimeWarning, "A builtin ctypes object gave a PEP3118 format " "string that does not match its itemsize, so a " "best-guess will be made of the data type. " "Newer versions of python may behave correctly.", 1) |
| 1166 | "string that does not match its itemsize, so a "PyErr_WarnEx(PyExc_RuntimeWarning, "A builtin ctypes object gave a PEP3118 format " "string that does not match its itemsize, so a " "best-guess will be made of the data type. " "Newer versions of python may behave correctly.", 1) |
| 1167 | "best-guess will be made of the data type. "PyErr_WarnEx(PyExc_RuntimeWarning, "A builtin ctypes object gave a PEP3118 format " "string that does not match its itemsize, so a " "best-guess will be made of the data type. " "Newer versions of python may behave correctly.", 1) |
| 1168 | "Newer versions of python may behave correctly.")PyErr_WarnEx(PyExc_RuntimeWarning, "A builtin ctypes object gave a PEP3118 format " "string that does not match its itemsize, so a " "best-guess will be made of the data type. " "Newer versions of python may behave correctly.", 1) < 0) { |
| 1169 | Py_DECREF(descr)_Py_DECREF(((PyObject*)(descr))); |
| 1170 | return NULL((void*)0); |
| 1171 | } |
| 1172 | |
| 1173 | /* Thankfully, np.dtype(ctypes_type) works in most cases. |
| 1174 | * For an array input, this produces a dtype containing all the |
| 1175 | * dimensions, so the array is now 0d. |
| 1176 | */ |
| 1177 | nd = 0; |
| 1178 | Py_DECREF(descr)_Py_DECREF(((PyObject*)(descr))); |
| 1179 | descr = (PyArray_Descr *)PyObject_CallFunctionObjArgs( |
| 1180 | (PyObject *)&PyArrayDescr_Type(*(PyTypeObject *)(&PyArrayDescr_TypeFull)), Py_TYPE(view->obj)(((PyObject*)(view->obj))->ob_type), NULL((void*)0)); |
| 1181 | if (descr == NULL((void*)0)) { |
| 1182 | return NULL((void*)0); |
| 1183 | } |
| 1184 | if (descr->elsize != view->len) { |
| 1185 | PyErr_SetString( |
| 1186 | PyExc_RuntimeError, |
| 1187 | "For the given ctypes object, neither the item size " |
| 1188 | "computed from the PEP 3118 buffer format nor from " |
| 1189 | "converting the type to a np.dtype matched the actual " |
| 1190 | "size. This is a bug both in python and numpy"); |
| 1191 | Py_DECREF(descr)_Py_DECREF(((PyObject*)(descr))); |
| 1192 | return NULL((void*)0); |
| 1193 | } |
| 1194 | } |
| 1195 | |
| 1196 | if (view->shape != NULL((void*)0)) { |
| 1197 | int k; |
| 1198 | if (nd > NPY_MAXDIMS32 || nd < 0) { |
| 1199 | PyErr_Format(PyExc_RuntimeError, |
| 1200 | "PEP3118 dimensions do not satisfy 0 <= ndim <= NPY_MAXDIMS"); |
| 1201 | goto fail; |
| 1202 | } |
| 1203 | for (k = 0; k < nd; ++k) { |
| 1204 | shape[k] = view->shape[k]; |
| 1205 | } |
| 1206 | if (view->strides != NULL((void*)0)) { |
| 1207 | for (k = 0; k < nd; ++k) { |
| 1208 | strides[k] = view->strides[k]; |
| 1209 | } |
| 1210 | } |
| 1211 | else { |
| 1212 | d = view->len; |
| 1213 | for (k = 0; k < nd; ++k) { |
| 1214 | if (view->shape[k] != 0) { |
| 1215 | d /= view->shape[k]; |
| 1216 | } |
| 1217 | strides[k] = d; |
| 1218 | } |
| 1219 | } |
| 1220 | } |
| 1221 | else { |
| 1222 | if (nd == 1) { |
| 1223 | shape[0] = view->len / view->itemsize; |
| 1224 | strides[0] = view->itemsize; |
| 1225 | } |
| 1226 | else if (nd > 1) { |
| 1227 | PyErr_SetString(PyExc_RuntimeError, |
| 1228 | "ndim computed from the PEP 3118 buffer format " |
| 1229 | "is greater than 1, but shape is NULL."); |
| 1230 | goto fail; |
| 1231 | } |
| 1232 | } |
| 1233 | |
| 1234 | flags = NPY_ARRAY_BEHAVED(0x0100 | 0x0400) & (view->readonly ? ~NPY_ARRAY_WRITEABLE0x0400 : ~0); |
| 1235 | r = PyArray_NewFromDescrAndBase( |
| 1236 | &PyArray_Type, descr, |
| 1237 | nd, shape, strides, view->buf, |
| 1238 | flags, NULL((void*)0), memoryview); |
| 1239 | return r; |
| 1240 | |
| 1241 | |
| 1242 | fail: |
| 1243 | Py_XDECREF(r)_Py_XDECREF(((PyObject*)(r))); |
| 1244 | Py_XDECREF(descr)_Py_XDECREF(((PyObject*)(descr))); |
| 1245 | return NULL((void*)0); |
| 1246 | |
| 1247 | } |
| 1248 | |
| 1249 | |
| 1250 | /** |
| 1251 | * Attempts to extract an array from an array-like object. |
| 1252 | * |
| 1253 | * array-like is defined as either |
| 1254 | * |
| 1255 | * * an object implementing the PEP 3118 buffer interface; |
| 1256 | * * an object with __array_struct__ or __array_interface__ attributes; |
| 1257 | * * an object with an __array__ function. |
| 1258 | * |
| 1259 | * @param op The object to convert to an array |
| 1260 | * @param requested_type a requested dtype instance, may be NULL; The result |
| 1261 | * DType may be used, but is not enforced. |
| 1262 | * @param writeable whether the result must be writeable. |
| 1263 | * @param context Unused parameter, must be NULL (should be removed later). |
| 1264 | * |
| 1265 | * @returns The array object, Py_NotImplemented if op is not array-like, |
| 1266 | * or NULL with an error set. (A new reference to Py_NotImplemented |
| 1267 | * is returned.) |
| 1268 | */ |
| 1269 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 1270 | _array_from_array_like(PyObject *op, |
| 1271 | PyArray_Descr *requested_dtype, npy_bool writeable, PyObject *context) { |
| 1272 | PyObject* tmp; |
| 1273 | |
| 1274 | /* |
| 1275 | * If op supports the PEP 3118 buffer interface. |
| 1276 | * We skip bytes and unicode since they are considered scalars. Unicode |
| 1277 | * would fail but bytes would be incorrectly converted to a uint8 array. |
| 1278 | */ |
| 1279 | if (!PyBytes_Check(op)((((((PyObject*)(op))->ob_type))->tp_flags & ((1UL << 27))) != 0) && !PyUnicode_Check(op)((((((PyObject*)(op))->ob_type))->tp_flags & ((1UL << 28))) != 0)) { |
| 1280 | PyObject *memoryview = PyMemoryView_FromObject(op); |
| 1281 | if (memoryview == NULL((void*)0)) { |
| 1282 | PyErr_Clear(); |
| 1283 | } |
| 1284 | else { |
| 1285 | tmp = _array_from_buffer_3118(memoryview); |
| 1286 | Py_DECREF(memoryview)_Py_DECREF(((PyObject*)(memoryview))); |
| 1287 | if (tmp == NULL((void*)0)) { |
| 1288 | return NULL((void*)0); |
| 1289 | } |
| 1290 | |
| 1291 | if (writeable |
| 1292 | && PyArray_FailUnlessWriteable( |
| 1293 | (PyArrayObject *)tmp, "PEP 3118 buffer") < 0) { |
| 1294 | Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp))); |
| 1295 | return NULL((void*)0); |
| 1296 | } |
| 1297 | |
| 1298 | return tmp; |
| 1299 | } |
| 1300 | } |
| 1301 | |
| 1302 | /* |
| 1303 | * If op supports the __array_struct__ or __array_interface__ interface. |
| 1304 | */ |
| 1305 | tmp = PyArray_FromStructInterface(op); |
| 1306 | if (tmp == NULL((void*)0)) { |
| 1307 | return NULL((void*)0); |
| 1308 | } |
| 1309 | if (tmp == Py_NotImplemented(&_Py_NotImplementedStruct)) { |
| 1310 | /* Until the return, NotImplemented is always a borrowed reference*/ |
| 1311 | tmp = PyArray_FromInterface(op); |
| 1312 | if (tmp == NULL((void*)0)) { |
| 1313 | return NULL((void*)0); |
| 1314 | } |
| 1315 | } |
| 1316 | |
| 1317 | /* |
| 1318 | * If op supplies the __array__ function. |
| 1319 | * The documentation says this should produce a copy, so |
| 1320 | * we skip this method if writeable is true, because the intent |
| 1321 | * of writeable is to modify the operand. |
| 1322 | * XXX: If the implementation is wrong, and/or if actual |
| 1323 | * usage requires this behave differently, |
| 1324 | * this should be changed! |
| 1325 | */ |
| 1326 | if (!writeable && tmp == Py_NotImplemented(&_Py_NotImplementedStruct)) { |
| 1327 | tmp = PyArray_FromArrayAttr(op, requested_dtype, context); |
| 1328 | if (tmp == NULL((void*)0)) { |
| 1329 | return NULL((void*)0); |
| 1330 | } |
| 1331 | } |
| 1332 | |
| 1333 | if (tmp != Py_NotImplemented(&_Py_NotImplementedStruct)) { |
| 1334 | if (writeable && |
| 1335 | PyArray_FailUnlessWriteable((PyArrayObject *)tmp, |
| 1336 | "array interface object") < 0) { |
| 1337 | Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp))); |
| 1338 | return NULL((void*)0); |
| 1339 | } |
| 1340 | return tmp; |
| 1341 | } |
| 1342 | |
| 1343 | /* Until here Py_NotImplemented was borrowed */ |
| 1344 | Py_INCREF(Py_NotImplemented)_Py_INCREF(((PyObject*)((&_Py_NotImplementedStruct)))); |
| 1345 | return Py_NotImplemented(&_Py_NotImplementedStruct); |
| 1346 | } |
| 1347 | |
| 1348 | |
| 1349 | /*NUMPY_API*/ |
| 1350 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) int |
| 1351 | PyArray_GetArrayParamsFromObject(PyObject *NPY_UNUSED(op)(__NPY_UNUSED_TAGGEDop) __attribute__ ((__unused__)), |
| 1352 | PyArray_Descr *NPY_UNUSED(requested_dtype)(__NPY_UNUSED_TAGGEDrequested_dtype) __attribute__ ((__unused__ )), |
| 1353 | npy_bool NPY_UNUSED(writeable)(__NPY_UNUSED_TAGGEDwriteable) __attribute__ ((__unused__)), |
| 1354 | PyArray_Descr **NPY_UNUSED(out_dtype)(__NPY_UNUSED_TAGGEDout_dtype) __attribute__ ((__unused__)), |
| 1355 | int *NPY_UNUSED(out_ndim)(__NPY_UNUSED_TAGGEDout_ndim) __attribute__ ((__unused__)), npy_intp *NPY_UNUSED(out_dims)(__NPY_UNUSED_TAGGEDout_dims) __attribute__ ((__unused__)), |
| 1356 | PyArrayObject **NPY_UNUSED(out_arr)(__NPY_UNUSED_TAGGEDout_arr) __attribute__ ((__unused__)), PyObject *NPY_UNUSED(context)(__NPY_UNUSED_TAGGEDcontext) __attribute__ ((__unused__))) |
| 1357 | { |
| 1358 | /* Deprecated in NumPy 1.19, removed in NumPy 1.20. */ |
| 1359 | PyErr_SetString(PyExc_RuntimeError, |
| 1360 | "PyArray_GetArrayParamsFromObject() C-API function is removed " |
| 1361 | "`PyArray_FromAny()` should be used at this time. New C-API " |
| 1362 | "may be exposed in the future (please do request this if it " |
| 1363 | "would help you)."); |
| 1364 | return -1; |
| 1365 | } |
| 1366 | |
| 1367 | |
| 1368 | /* |
| 1369 | * This function is a legacy implementation to retain subarray dtype |
| 1370 | * behaviour in array coercion. The behaviour here makes sense if tuples |
| 1371 | * of matching dimensionality are being coerced. Due to the difficulty |
| 1372 | * that the result is ill-defined for lists of array-likes, this is deprecated. |
| 1373 | * |
| 1374 | * WARNING: Do not use this function, it exists purely to support a deprecated |
| 1375 | * code path. |
| 1376 | */ |
| 1377 | static int |
| 1378 | setArrayFromSequence(PyArrayObject *a, PyObject *s, |
| 1379 | int dim, PyArrayObject * dst) |
| 1380 | { |
| 1381 | Py_ssize_t i, slen; |
| 1382 | int res = -1; |
| 1383 | |
| 1384 | /* first recursion, view equal destination */ |
| 1385 | if (dst == NULL((void*)0)) |
| 1386 | dst = a; |
| 1387 | |
| 1388 | /* |
| 1389 | * This code is to ensure that the sequence access below will |
| 1390 | * return a lower-dimensional sequence. |
| 1391 | */ |
| 1392 | |
| 1393 | /* INCREF on entry DECREF on exit */ |
| 1394 | Py_INCREF(s)_Py_INCREF(((PyObject*)(s))); |
| 1395 | |
| 1396 | PyObject *seq = NULL((void*)0); |
| 1397 | |
| 1398 | if (PyArray_Check(s)((((PyObject*)(s))->ob_type) == (&PyArray_Type) || PyType_IsSubtype ((((PyObject*)(s))->ob_type), (&PyArray_Type)))) { |
| 1399 | if (!(PyArray_CheckExact(s)(((PyObject*)(s))->ob_type == &PyArray_Type))) { |
| 1400 | /* |
| 1401 | * make sure a base-class array is used so that the dimensionality |
| 1402 | * reduction assumption is correct. |
| 1403 | */ |
| 1404 | /* This will DECREF(s) if replaced */ |
| 1405 | s = PyArray_EnsureArray(s); |
| 1406 | if (s == NULL((void*)0)) { |
| 1407 | goto fail; |
| 1408 | } |
| 1409 | } |
| 1410 | |
| 1411 | /* dst points to correct array subsection */ |
| 1412 | if (PyArray_CopyInto(dst, (PyArrayObject *)s) < 0) { |
| 1413 | goto fail; |
| 1414 | } |
| 1415 | |
| 1416 | Py_DECREF(s)_Py_DECREF(((PyObject*)(s))); |
| 1417 | return 0; |
| 1418 | } |
| 1419 | |
| 1420 | if (dim > PyArray_NDIM(a)) { |
| 1421 | PyErr_Format(PyExc_ValueError, |
| 1422 | "setArrayFromSequence: sequence/array dimensions mismatch."); |
| 1423 | goto fail; |
| 1424 | } |
| 1425 | |
| 1426 | /* Try __array__ before using s as a sequence */ |
| 1427 | PyObject *tmp = _array_from_array_like(s, NULL((void*)0), 0, NULL((void*)0)); |
| 1428 | if (tmp == NULL((void*)0)) { |
| 1429 | goto fail; |
| 1430 | } |
| 1431 | else if (tmp == Py_NotImplemented(&_Py_NotImplementedStruct)) { |
| 1432 | Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp))); |
| 1433 | } |
| 1434 | else { |
| 1435 | int r = PyArray_CopyInto(dst, (PyArrayObject *)tmp); |
| 1436 | Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp))); |
| 1437 | if (r < 0) { |
| 1438 | goto fail; |
| 1439 | } |
| 1440 | Py_DECREF(s)_Py_DECREF(((PyObject*)(s))); |
| 1441 | return 0; |
| 1442 | } |
| 1443 | |
| 1444 | seq = PySequence_Fast(s, "Could not convert object to sequence"); |
| 1445 | if (seq == NULL((void*)0)) { |
| 1446 | goto fail; |
| 1447 | } |
| 1448 | slen = PySequence_Fast_GET_SIZE(seq)(((((((PyObject*)(seq))->ob_type))->tp_flags & ((1UL << 25))) != 0) ? (((void) (0)), (((PyVarObject*)(seq)) ->ob_size)) : (((PyVarObject*)((((void) (0)), (PyTupleObject *)(seq))))->ob_size)); |
| 1449 | |
| 1450 | /* |
| 1451 | * Either the dimensions match, or the sequence has length 1 and can |
| 1452 | * be broadcast to the destination. |
| 1453 | */ |
| 1454 | if (slen != PyArray_DIMS(a)[dim] && slen != 1) { |
| 1455 | PyErr_Format(PyExc_ValueError, |
| 1456 | "cannot copy sequence with size %zd to array axis " |
| 1457 | "with dimension %" NPY_INTP_FMT"ld", slen, PyArray_DIMS(a)[dim]); |
| 1458 | goto fail; |
| 1459 | } |
| 1460 | |
| 1461 | /* Broadcast the one element from the sequence to all the outputs */ |
| 1462 | if (slen == 1) { |
| 1463 | PyObject *o = PySequence_Fast_GET_ITEM(seq, 0)(((((((PyObject*)(seq))->ob_type))->tp_flags & ((1UL << 25))) != 0) ? (((PyListObject *)(seq))->ob_item[ 0]) : ((((void) (0)), (PyTupleObject *)(seq))->ob_item[0]) ); |
| 1464 | npy_intp alen = PyArray_DIM(a, dim); |
| 1465 | |
| 1466 | for (i = 0; i < alen; i++) { |
| 1467 | if ((PyArray_NDIM(a) - dim) > 1) { |
| 1468 | PyArrayObject * tmp = |
| 1469 | (PyArrayObject *)array_item_asarray(dst, i); |
| 1470 | if (tmp == NULL((void*)0)) { |
| 1471 | goto fail; |
| 1472 | } |
| 1473 | |
| 1474 | res = setArrayFromSequence(a, o, dim+1, tmp); |
| 1475 | Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp))); |
| 1476 | } |
| 1477 | else { |
| 1478 | char * b = (PyArray_BYTES(dst) + i * PyArray_STRIDES(dst)[0]); |
| 1479 | res = PyArray_SETITEM(dst, b, o); |
| 1480 | } |
| 1481 | if (res < 0) { |
| 1482 | goto fail; |
| 1483 | } |
| 1484 | } |
| 1485 | } |
| 1486 | /* Copy element by element */ |
| 1487 | else { |
| 1488 | for (i = 0; i < slen; i++) { |
| 1489 | PyObject * o = PySequence_Fast_GET_ITEM(seq, i)(((((((PyObject*)(seq))->ob_type))->tp_flags & ((1UL << 25))) != 0) ? (((PyListObject *)(seq))->ob_item[ i]) : ((((void) (0)), (PyTupleObject *)(seq))->ob_item[i]) ); |
| 1490 | if ((PyArray_NDIM(a) - dim) > 1) { |
| 1491 | PyArrayObject * tmp = |
| 1492 | (PyArrayObject *)array_item_asarray(dst, i); |
| 1493 | if (tmp == NULL((void*)0)) { |
| 1494 | goto fail; |
| 1495 | } |
| 1496 | |
| 1497 | res = setArrayFromSequence(a, o, dim+1, tmp); |
| 1498 | Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp))); |
| 1499 | } |
| 1500 | else { |
| 1501 | char * b = (PyArray_BYTES(dst) + i * PyArray_STRIDES(dst)[0]); |
| 1502 | res = PyArray_SETITEM(dst, b, o); |
| 1503 | } |
| 1504 | if (res < 0) { |
| 1505 | goto fail; |
| 1506 | } |
| 1507 | } |
| 1508 | } |
| 1509 | |
| 1510 | Py_DECREF(seq)_Py_DECREF(((PyObject*)(seq))); |
| 1511 | Py_DECREF(s)_Py_DECREF(((PyObject*)(s))); |
| 1512 | return 0; |
| 1513 | |
| 1514 | fail: |
| 1515 | Py_XDECREF(seq)_Py_XDECREF(((PyObject*)(seq))); |
| 1516 | Py_DECREF(s)_Py_DECREF(((PyObject*)(s))); |
| 1517 | return res; |
| 1518 | } |
| 1519 | |
| 1520 | |
| 1521 | |
| 1522 | /*NUMPY_API |
| 1523 | * Does not check for NPY_ARRAY_ENSURECOPY and NPY_ARRAY_NOTSWAPPED in flags |
| 1524 | * Steals a reference to newtype --- which can be NULL |
| 1525 | */ |
| 1526 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 1527 | PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int min_depth, |
| 1528 | int max_depth, int flags, PyObject *context) |
| 1529 | { |
| 1530 | /* |
| 1531 | * This is the main code to make a NumPy array from a Python |
| 1532 | * Object. It is called from many different places. |
| 1533 | */ |
| 1534 | PyArrayObject *arr = NULL((void*)0), *ret; |
| 1535 | PyArray_Descr *dtype = NULL((void*)0); |
| 1536 | coercion_cache_obj *cache = NULL((void*)0); |
| 1537 | int ndim = 0; |
| 1538 | npy_intp dims[NPY_MAXDIMS32]; |
| 1539 | |
| 1540 | if (context != NULL((void*)0)) { |
| 1541 | PyErr_SetString(PyExc_RuntimeError, "'context' must be NULL"); |
| 1542 | return NULL((void*)0); |
| 1543 | } |
| 1544 | |
| 1545 | PyArray_Descr *fixed_descriptor; |
| 1546 | PyArray_DTypeMeta *fixed_DType; |
| 1547 | if (PyArray_ExtractDTypeAndDescriptor((PyObject *)newtype, |
| 1548 | &fixed_descriptor, &fixed_DType) < 0) { |
| 1549 | Py_XDECREF(newtype)_Py_XDECREF(((PyObject*)(newtype))); |
| 1550 | return NULL((void*)0); |
| 1551 | } |
| 1552 | Py_XDECREF(newtype)_Py_XDECREF(((PyObject*)(newtype))); |
| 1553 | |
| 1554 | ndim = PyArray_DiscoverDTypeAndShape(op, |
| 1555 | NPY_MAXDIMS32, dims, &cache, fixed_DType, fixed_descriptor, &dtype); |
| 1556 | |
| 1557 | Py_XDECREF(fixed_descriptor)_Py_XDECREF(((PyObject*)(fixed_descriptor))); |
| 1558 | Py_XDECREF(fixed_DType)_Py_XDECREF(((PyObject*)(fixed_DType))); |
| 1559 | if (ndim < 0) { |
| 1560 | return NULL((void*)0); |
| 1561 | } |
| 1562 | |
| 1563 | if (NPY_UNLIKELY(fixed_descriptor != NULL && PyDataType_HASSUBARRAY(dtype))__builtin_expect(!!(fixed_descriptor != ((void*)0) && ((dtype)->subarray != ((void*)0))), 0)) { |
| 1564 | /* |
| 1565 | * When a subarray dtype was passed in, its dimensions are appended |
| 1566 | * to the array dimension (causing a dimension mismatch). |
| 1567 | * There is a problem with that, because if we coerce from non-arrays |
| 1568 | * we do this correctly by element (as defined by tuples), but for |
| 1569 | * arrays we first append the dimensions and then assign to the base |
| 1570 | * dtype and then assign which causes the problem. |
| 1571 | * |
| 1572 | * Thus, we check if there is an array included, in that case we |
| 1573 | * give a FutureWarning. |
| 1574 | * When the warning is removed, PyArray_Pack will have to ensure |
| 1575 | * that that it does not append the dimensions when creating the |
| 1576 | * subarrays to assign `arr[0] = obj[0]`. |
| 1577 | */ |
| 1578 | int includes_array = 0; |
| 1579 | if (cache != NULL((void*)0)) { |
| 1580 | /* This is not ideal, but it is a pretty special case */ |
| 1581 | coercion_cache_obj *next = cache; |
| 1582 | while (next != NULL((void*)0)) { |
| 1583 | if (!next->sequence) { |
| 1584 | includes_array = 1; |
| 1585 | break; |
| 1586 | } |
| 1587 | next = next->next; |
| 1588 | } |
| 1589 | } |
| 1590 | if (includes_array) { |
| 1591 | npy_free_coercion_cache(cache); |
| 1592 | |
| 1593 | ret = (PyArrayObject *) PyArray_NewFromDescr( |
| 1594 | &PyArray_Type, dtype, ndim, dims, NULL((void*)0), NULL((void*)0), |
| 1595 | flags & NPY_ARRAY_F_CONTIGUOUS0x0002, NULL((void*)0)); |
| 1596 | if (ret == NULL((void*)0)) { |
| 1597 | return NULL((void*)0); |
| 1598 | } |
| 1599 | assert(PyArray_NDIM(ret) != ndim)((void) (0)); |
| 1600 | |
| 1601 | /* NumPy 1.20, 2020-10-01 */ |
| 1602 | if (DEPRECATE_FUTUREWARNING(PyErr_WarnEx(PyExc_FutureWarning,"creating an array with a subarray dtype will behave " "differently when the `np.array()` (or `asarray`, etc.) " "call includes an array or array object.\n" "If you are converting a single array or a list of arrays," "you can opt-in to the future behaviour using:\n" " np.array(arr, dtype=np.dtype(['f', dtype]))['f']\n" " np.array([arr1, arr2], dtype=np.dtype(['f', dtype]))['f']\n" "\n" "By including a new field and indexing it after the " "conversion.\n" "This may lead to a different result or to current failures " "succeeding. (FutureWarning since NumPy 1.20)",1) |
| 1603 | "creating an array with a subarray dtype will behave "PyErr_WarnEx(PyExc_FutureWarning,"creating an array with a subarray dtype will behave " "differently when the `np.array()` (or `asarray`, etc.) " "call includes an array or array object.\n" "If you are converting a single array or a list of arrays," "you can opt-in to the future behaviour using:\n" " np.array(arr, dtype=np.dtype(['f', dtype]))['f']\n" " np.array([arr1, arr2], dtype=np.dtype(['f', dtype]))['f']\n" "\n" "By including a new field and indexing it after the " "conversion.\n" "This may lead to a different result or to current failures " "succeeding. (FutureWarning since NumPy 1.20)",1) |
| 1604 | "differently when the `np.array()` (or `asarray`, etc.) "PyErr_WarnEx(PyExc_FutureWarning,"creating an array with a subarray dtype will behave " "differently when the `np.array()` (or `asarray`, etc.) " "call includes an array or array object.\n" "If you are converting a single array or a list of arrays," "you can opt-in to the future behaviour using:\n" " np.array(arr, dtype=np.dtype(['f', dtype]))['f']\n" " np.array([arr1, arr2], dtype=np.dtype(['f', dtype]))['f']\n" "\n" "By including a new field and indexing it after the " "conversion.\n" "This may lead to a different result or to current failures " "succeeding. (FutureWarning since NumPy 1.20)",1) |
| 1605 | "call includes an array or array object.\n"PyErr_WarnEx(PyExc_FutureWarning,"creating an array with a subarray dtype will behave " "differently when the `np.array()` (or `asarray`, etc.) " "call includes an array or array object.\n" "If you are converting a single array or a list of arrays," "you can opt-in to the future behaviour using:\n" " np.array(arr, dtype=np.dtype(['f', dtype]))['f']\n" " np.array([arr1, arr2], dtype=np.dtype(['f', dtype]))['f']\n" "\n" "By including a new field and indexing it after the " "conversion.\n" "This may lead to a different result or to current failures " "succeeding. (FutureWarning since NumPy 1.20)",1) |
| 1606 | "If you are converting a single array or a list of arrays,"PyErr_WarnEx(PyExc_FutureWarning,"creating an array with a subarray dtype will behave " "differently when the `np.array()` (or `asarray`, etc.) " "call includes an array or array object.\n" "If you are converting a single array or a list of arrays," "you can opt-in to the future behaviour using:\n" " np.array(arr, dtype=np.dtype(['f', dtype]))['f']\n" " np.array([arr1, arr2], dtype=np.dtype(['f', dtype]))['f']\n" "\n" "By including a new field and indexing it after the " "conversion.\n" "This may lead to a different result or to current failures " "succeeding. (FutureWarning since NumPy 1.20)",1) |
| 1607 | "you can opt-in to the future behaviour using:\n"PyErr_WarnEx(PyExc_FutureWarning,"creating an array with a subarray dtype will behave " "differently when the `np.array()` (or `asarray`, etc.) " "call includes an array or array object.\n" "If you are converting a single array or a list of arrays," "you can opt-in to the future behaviour using:\n" " np.array(arr, dtype=np.dtype(['f', dtype]))['f']\n" " np.array([arr1, arr2], dtype=np.dtype(['f', dtype]))['f']\n" "\n" "By including a new field and indexing it after the " "conversion.\n" "This may lead to a different result or to current failures " "succeeding. (FutureWarning since NumPy 1.20)",1) |
| 1608 | " np.array(arr, dtype=np.dtype(['f', dtype]))['f']\n"PyErr_WarnEx(PyExc_FutureWarning,"creating an array with a subarray dtype will behave " "differently when the `np.array()` (or `asarray`, etc.) " "call includes an array or array object.\n" "If you are converting a single array or a list of arrays," "you can opt-in to the future behaviour using:\n" " np.array(arr, dtype=np.dtype(['f', dtype]))['f']\n" " np.array([arr1, arr2], dtype=np.dtype(['f', dtype]))['f']\n" "\n" "By including a new field and indexing it after the " "conversion.\n" "This may lead to a different result or to current failures " "succeeding. (FutureWarning since NumPy 1.20)",1) |
| 1609 | " np.array([arr1, arr2], dtype=np.dtype(['f', dtype]))['f']\n"PyErr_WarnEx(PyExc_FutureWarning,"creating an array with a subarray dtype will behave " "differently when the `np.array()` (or `asarray`, etc.) " "call includes an array or array object.\n" "If you are converting a single array or a list of arrays," "you can opt-in to the future behaviour using:\n" " np.array(arr, dtype=np.dtype(['f', dtype]))['f']\n" " np.array([arr1, arr2], dtype=np.dtype(['f', dtype]))['f']\n" "\n" "By including a new field and indexing it after the " "conversion.\n" "This may lead to a different result or to current failures " "succeeding. (FutureWarning since NumPy 1.20)",1) |
| 1610 | "\n"PyErr_WarnEx(PyExc_FutureWarning,"creating an array with a subarray dtype will behave " "differently when the `np.array()` (or `asarray`, etc.) " "call includes an array or array object.\n" "If you are converting a single array or a list of arrays," "you can opt-in to the future behaviour using:\n" " np.array(arr, dtype=np.dtype(['f', dtype]))['f']\n" " np.array([arr1, arr2], dtype=np.dtype(['f', dtype]))['f']\n" "\n" "By including a new field and indexing it after the " "conversion.\n" "This may lead to a different result or to current failures " "succeeding. (FutureWarning since NumPy 1.20)",1) |
| 1611 | "By including a new field and indexing it after the "PyErr_WarnEx(PyExc_FutureWarning,"creating an array with a subarray dtype will behave " "differently when the `np.array()` (or `asarray`, etc.) " "call includes an array or array object.\n" "If you are converting a single array or a list of arrays," "you can opt-in to the future behaviour using:\n" " np.array(arr, dtype=np.dtype(['f', dtype]))['f']\n" " np.array([arr1, arr2], dtype=np.dtype(['f', dtype]))['f']\n" "\n" "By including a new field and indexing it after the " "conversion.\n" "This may lead to a different result or to current failures " "succeeding. (FutureWarning since NumPy 1.20)",1) |
| 1612 | "conversion.\n"PyErr_WarnEx(PyExc_FutureWarning,"creating an array with a subarray dtype will behave " "differently when the `np.array()` (or `asarray`, etc.) " "call includes an array or array object.\n" "If you are converting a single array or a list of arrays," "you can opt-in to the future behaviour using:\n" " np.array(arr, dtype=np.dtype(['f', dtype]))['f']\n" " np.array([arr1, arr2], dtype=np.dtype(['f', dtype]))['f']\n" "\n" "By including a new field and indexing it after the " "conversion.\n" "This may lead to a different result or to current failures " "succeeding. (FutureWarning since NumPy 1.20)",1) |
| 1613 | "This may lead to a different result or to current failures "PyErr_WarnEx(PyExc_FutureWarning,"creating an array with a subarray dtype will behave " "differently when the `np.array()` (or `asarray`, etc.) " "call includes an array or array object.\n" "If you are converting a single array or a list of arrays," "you can opt-in to the future behaviour using:\n" " np.array(arr, dtype=np.dtype(['f', dtype]))['f']\n" " np.array([arr1, arr2], dtype=np.dtype(['f', dtype]))['f']\n" "\n" "By including a new field and indexing it after the " "conversion.\n" "This may lead to a different result or to current failures " "succeeding. (FutureWarning since NumPy 1.20)",1) |
| 1614 | "succeeding. (FutureWarning since NumPy 1.20)")PyErr_WarnEx(PyExc_FutureWarning,"creating an array with a subarray dtype will behave " "differently when the `np.array()` (or `asarray`, etc.) " "call includes an array or array object.\n" "If you are converting a single array or a list of arrays," "you can opt-in to the future behaviour using:\n" " np.array(arr, dtype=np.dtype(['f', dtype]))['f']\n" " np.array([arr1, arr2], dtype=np.dtype(['f', dtype]))['f']\n" "\n" "By including a new field and indexing it after the " "conversion.\n" "This may lead to a different result or to current failures " "succeeding. (FutureWarning since NumPy 1.20)",1) < 0) { |
| 1615 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); |
| 1616 | return NULL((void*)0); |
| 1617 | } |
| 1618 | |
| 1619 | if (setArrayFromSequence(ret, op, 0, NULL((void*)0)) < 0) { |
| 1620 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); |
| 1621 | return NULL((void*)0); |
| 1622 | } |
| 1623 | return (PyObject *)ret; |
| 1624 | } |
| 1625 | } |
| 1626 | |
| 1627 | if (dtype == NULL((void*)0)) { |
| 1628 | dtype = PyArray_DescrFromType(NPY_DEFAULT_TYPENPY_DOUBLE); |
| 1629 | } |
| 1630 | |
| 1631 | if (min_depth != 0 && ndim < min_depth) { |
| 1632 | PyErr_SetString(PyExc_ValueError, |
| 1633 | "object of too small depth for desired array"); |
| 1634 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 1635 | npy_free_coercion_cache(cache); |
| 1636 | return NULL((void*)0); |
| 1637 | } |
| 1638 | if (max_depth != 0 && ndim > max_depth) { |
| 1639 | PyErr_SetString(PyExc_ValueError, |
| 1640 | "object too deep for desired array"); |
| 1641 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 1642 | npy_free_coercion_cache(cache); |
| 1643 | return NULL((void*)0); |
| 1644 | } |
| 1645 | |
| 1646 | /* Got the correct parameters, but the cache may already hold the result */ |
| 1647 | if (cache != NULL((void*)0) && !(cache->sequence)) { |
| 1648 | /* |
| 1649 | * There is only a single array-like and it was converted, it |
| 1650 | * may still have the incorrect type, but that is handled below. |
| 1651 | */ |
| 1652 | assert(cache->converted_obj == op)((void) (0)); |
| 1653 | arr = (PyArrayObject *)(cache->arr_or_sequence); |
| 1654 | /* we may need to cast or assert flags (e.g. copy) */ |
| 1655 | PyObject *res = PyArray_FromArray(arr, dtype, flags); |
| 1656 | npy_unlink_coercion_cache(cache); |
| 1657 | return res; |
| 1658 | } |
| 1659 | else if (cache == NULL((void*)0) && PyArray_IsScalar(op, Void)(((((PyObject*)(op))->ob_type) == (&PyVoidArrType_Type ) || PyType_IsSubtype((((PyObject*)(op))->ob_type), (& PyVoidArrType_Type)))) && |
| 1660 | !(((PyVoidScalarObject *)op)->flags & NPY_ARRAY_OWNDATA0x0004) && |
| 1661 | newtype == NULL((void*)0)) { |
| 1662 | /* |
| 1663 | * Special case, we return a *view* into void scalars, mainly to |
| 1664 | * allow things similar to the "reversed" assignment: |
| 1665 | * arr[indx]["field"] = val # instead of arr["field"][indx] = val |
| 1666 | * |
| 1667 | * It is unclear that this is necessary in this particular code path. |
| 1668 | * Note that this path is only activated when the user did _not_ |
| 1669 | * provide a dtype (newtype is NULL). |
| 1670 | */ |
| 1671 | assert(ndim == 0)((void) (0)); |
| 1672 | |
| 1673 | return PyArray_NewFromDescrAndBase( |
| 1674 | &PyArray_Type, dtype, |
| 1675 | 0, NULL((void*)0), NULL((void*)0), |
| 1676 | ((PyVoidScalarObject *)op)->obval, |
| 1677 | ((PyVoidScalarObject *)op)->flags, |
| 1678 | NULL((void*)0), op); |
| 1679 | } |
| 1680 | else if (cache == 0 && newtype != NULL((void*)0) && |
| 1681 | PyDataType_ISSIGNED(newtype)(((((PyArray_Descr*)(newtype))->type_num) == NPY_BYTE) || ( (((PyArray_Descr*)(newtype))->type_num) == NPY_SHORT) || ( (((PyArray_Descr*)(newtype))->type_num) == NPY_INT) || ((( (PyArray_Descr*)(newtype))->type_num) == NPY_LONG) || (((( PyArray_Descr*)(newtype))->type_num) == NPY_LONGLONG)) && PyArray_IsScalar(op, Generic)(((((PyObject*)(op))->ob_type) == (&PyGenericArrType_Type ) || PyType_IsSubtype((((PyObject*)(op))->ob_type), (& PyGenericArrType_Type))))) { |
| 1682 | assert(ndim == 0)((void) (0)); |
| 1683 | /* |
| 1684 | * This is an (possible) inconsistency where: |
| 1685 | * |
| 1686 | * np.array(np.float64(np.nan), dtype=np.int64) |
| 1687 | * |
| 1688 | * behaves differently from: |
| 1689 | * |
| 1690 | * np.array([np.float64(np.nan)], dtype=np.int64) |
| 1691 | * arr1d_int64[0] = np.float64(np.nan) |
| 1692 | * np.array(np.array(np.nan), dtype=np.int64) |
| 1693 | * |
| 1694 | * by not raising an error instead of using typical casting. |
| 1695 | * The error is desirable, but to always error seems like a |
| 1696 | * larger change to be considered at some other time and it is |
| 1697 | * undesirable that 0-D arrays behave differently from scalars. |
| 1698 | * This retains the behaviour, largely due to issues in pandas |
| 1699 | * which relied on a try/except (although hopefully that will |
| 1700 | * have a better solution at some point): |
| 1701 | * https://github.com/pandas-dev/pandas/issues/35481 |
| 1702 | */ |
| 1703 | return PyArray_FromScalar(op, dtype); |
| 1704 | } |
| 1705 | |
| 1706 | /* There was no array (or array-like) passed in directly. */ |
| 1707 | if ((flags & NPY_ARRAY_WRITEBACKIFCOPY0x2000) || |
| 1708 | (flags & NPY_ARRAY_UPDATEIFCOPY0x1000)) { |
| 1709 | PyErr_SetString(PyExc_TypeError, |
| 1710 | "WRITEBACKIFCOPY used for non-array input."); |
| 1711 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 1712 | npy_free_coercion_cache(cache); |
| 1713 | return NULL((void*)0); |
| 1714 | } |
| 1715 | |
| 1716 | /* Create a new array and copy the data */ |
| 1717 | Py_INCREF(dtype)_Py_INCREF(((PyObject*)(dtype))); /* hold on in case of a subarray that is replaced */ |
| 1718 | ret = (PyArrayObject *)PyArray_NewFromDescr( |
| 1719 | &PyArray_Type, dtype, ndim, dims, NULL((void*)0), NULL((void*)0), |
| 1720 | flags&NPY_ARRAY_F_CONTIGUOUS0x0002, NULL((void*)0)); |
| 1721 | if (ret == NULL((void*)0)) { |
| 1722 | npy_free_coercion_cache(cache); |
| 1723 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 1724 | return NULL((void*)0); |
| 1725 | } |
| 1726 | if (ndim == PyArray_NDIM(ret)) { |
| 1727 | /* |
| 1728 | * Appending of dimensions did not occur, so use the actual dtype |
| 1729 | * below. This is relevant for S0 or U0 which can be replaced with |
| 1730 | * S1 or U1, although that should likely change. |
| 1731 | */ |
| 1732 | Py_SETREF(dtype, PyArray_DESCR(ret))do { PyObject *_py_tmp = ((PyObject*)(dtype)); (dtype) = (PyArray_DESCR (ret)); _Py_DECREF(((PyObject*)(_py_tmp))); } while (0); |
| 1733 | Py_INCREF(dtype)_Py_INCREF(((PyObject*)(dtype))); |
| 1734 | } |
| 1735 | |
| 1736 | if (cache == NULL((void*)0)) { |
| 1737 | /* This is a single item. Set it directly. */ |
| 1738 | assert(ndim == 0)((void) (0)); |
| 1739 | |
| 1740 | if (PyArray_Pack(dtype, PyArray_BYTES(ret), op) < 0) { |
| 1741 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 1742 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); |
| 1743 | return NULL((void*)0); |
| 1744 | } |
| 1745 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 1746 | return (PyObject *)ret; |
| 1747 | } |
| 1748 | assert(ndim != 0)((void) (0)); |
| 1749 | assert(op == cache->converted_obj)((void) (0)); |
| 1750 | |
| 1751 | /* Decrease the number of dimensions to the detected ones */ |
| 1752 | int out_ndim = PyArray_NDIM(ret); |
| 1753 | PyArray_Descr *out_descr = PyArray_DESCR(ret); |
| 1754 | ((PyArrayObject_fields *)ret)->nd = ndim; |
| 1755 | ((PyArrayObject_fields *)ret)->descr = dtype; |
| 1756 | |
| 1757 | int success = PyArray_AssignFromCache(ret, cache); |
| 1758 | |
| 1759 | ((PyArrayObject_fields *)ret)->nd = out_ndim; |
| 1760 | ((PyArrayObject_fields *)ret)->descr = out_descr; |
| 1761 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 1762 | if (success < 0) { |
| 1763 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); |
| 1764 | return NULL((void*)0); |
| 1765 | } |
| 1766 | return (PyObject *)ret; |
| 1767 | } |
| 1768 | |
| 1769 | /* |
| 1770 | * flags is any of |
| 1771 | * NPY_ARRAY_C_CONTIGUOUS (formerly CONTIGUOUS), |
| 1772 | * NPY_ARRAY_F_CONTIGUOUS (formerly FORTRAN), |
| 1773 | * NPY_ARRAY_ALIGNED, |
| 1774 | * NPY_ARRAY_WRITEABLE, |
| 1775 | * NPY_ARRAY_NOTSWAPPED, |
| 1776 | * NPY_ARRAY_ENSURECOPY, |
| 1777 | * NPY_ARRAY_UPDATEIFCOPY, |
| 1778 | * NPY_ARRAY_WRITEBACKIFCOPY, |
| 1779 | * NPY_ARRAY_FORCECAST, |
| 1780 | * NPY_ARRAY_ENSUREARRAY, |
| 1781 | * NPY_ARRAY_ELEMENTSTRIDES |
| 1782 | * |
| 1783 | * or'd (|) together |
| 1784 | * |
| 1785 | * Any of these flags present means that the returned array should |
| 1786 | * guarantee that aspect of the array. Otherwise the returned array |
| 1787 | * won't guarantee it -- it will depend on the object as to whether or |
| 1788 | * not it has such features. |
| 1789 | * |
| 1790 | * Note that NPY_ARRAY_ENSURECOPY is enough |
| 1791 | * to guarantee NPY_ARRAY_C_CONTIGUOUS, NPY_ARRAY_ALIGNED and |
| 1792 | * NPY_ARRAY_WRITEABLE and therefore it is redundant to include |
| 1793 | * those as well. |
| 1794 | * |
| 1795 | * NPY_ARRAY_BEHAVED == NPY_ARRAY_ALIGNED | NPY_ARRAY_WRITEABLE |
| 1796 | * NPY_ARRAY_CARRAY = NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_BEHAVED |
| 1797 | * NPY_ARRAY_FARRAY = NPY_ARRAY_F_CONTIGUOUS | NPY_ARRAY_BEHAVED |
| 1798 | * |
| 1799 | * NPY_ARRAY_F_CONTIGUOUS can be set in the FLAGS to request a FORTRAN array. |
| 1800 | * Fortran arrays are always behaved (aligned, |
| 1801 | * notswapped, and writeable) and not (C) CONTIGUOUS (if > 1d). |
| 1802 | * |
| 1803 | * NPY_ARRAY_UPDATEIFCOPY is deprecated in favor of |
| 1804 | * NPY_ARRAY_WRITEBACKIFCOPY in 1.14 |
| 1805 | |
| 1806 | * NPY_ARRAY_WRITEBACKIFCOPY flag sets this flag in the returned |
| 1807 | * array if a copy is made and the base argument points to the (possibly) |
| 1808 | * misbehaved array. Before returning to python, PyArray_ResolveWritebackIfCopy |
| 1809 | * must be called to update the contents of the original array from the copy. |
| 1810 | * |
| 1811 | * NPY_ARRAY_FORCECAST will cause a cast to occur regardless of whether or not |
| 1812 | * it is safe. |
| 1813 | * |
| 1814 | * context is passed through to PyArray_GetArrayParamsFromObject |
| 1815 | */ |
| 1816 | |
| 1817 | /*NUMPY_API |
| 1818 | * steals a reference to descr -- accepts NULL |
| 1819 | */ |
| 1820 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 1821 | PyArray_CheckFromAny(PyObject *op, PyArray_Descr *descr, int min_depth, |
| 1822 | int max_depth, int requires, PyObject *context) |
| 1823 | { |
| 1824 | PyObject *obj; |
| 1825 | if (requires & NPY_ARRAY_NOTSWAPPED0x0200) { |
| 1826 | if (!descr && PyArray_Check(op)((((PyObject*)(op))->ob_type) == (&PyArray_Type) || PyType_IsSubtype ((((PyObject*)(op))->ob_type), (&PyArray_Type))) && |
| 1827 | PyArray_ISBYTESWAPPED((PyArrayObject* )op)(!((PyArray_DESCR((PyArrayObject* )op)->byteorder) != '>' ))) { |
| 1828 | descr = PyArray_DescrNew(PyArray_DESCR((PyArrayObject *)op)); |
| 1829 | } |
| 1830 | else if (descr && !PyArray_ISNBO(descr->byteorder)((descr->byteorder) != '>')) { |
| 1831 | PyArray_DESCR_REPLACE(descr)do { PyArray_Descr *_new_; _new_ = PyArray_DescrNew(descr); _Py_XDECREF (((PyObject*)(descr))); descr = _new_; } while(0); |
| 1832 | } |
| 1833 | if (descr && descr->byteorder != NPY_IGNORE'|') { |
| 1834 | descr->byteorder = NPY_NATIVE'='; |
| 1835 | } |
| 1836 | } |
| 1837 | |
| 1838 | obj = PyArray_FromAny(op, descr, min_depth, max_depth, requires, context); |
| 1839 | if (obj == NULL((void*)0)) { |
| 1840 | return NULL((void*)0); |
| 1841 | } |
| 1842 | if ((requires & NPY_ARRAY_ELEMENTSTRIDES0x0080) && |
| 1843 | !PyArray_ElementStrides(obj)) { |
| 1844 | PyObject *ret; |
| 1845 | ret = PyArray_NewCopy((PyArrayObject *)obj, NPY_ANYORDER); |
| 1846 | Py_DECREF(obj)_Py_DECREF(((PyObject*)(obj))); |
| 1847 | obj = ret; |
| 1848 | } |
| 1849 | return obj; |
| 1850 | } |
| 1851 | |
| 1852 | |
| 1853 | /*NUMPY_API |
| 1854 | * steals reference to newtype --- acc. NULL |
| 1855 | */ |
| 1856 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 1857 | PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int flags) |
| 1858 | { |
| 1859 | |
| 1860 | PyArrayObject *ret = NULL((void*)0); |
| 1861 | int copy = 0; |
| 1862 | int arrflags; |
| 1863 | PyArray_Descr *oldtype; |
| 1864 | NPY_CASTING casting = NPY_SAFE_CASTING; |
| 1865 | |
| 1866 | oldtype = PyArray_DESCR(arr); |
| 1867 | if (newtype == NULL((void*)0)) { |
| 1868 | /* |
| 1869 | * Check if object is of array with Null newtype. |
| 1870 | * If so return it directly instead of checking for casting. |
| 1871 | */ |
| 1872 | if (flags == 0) { |
| 1873 | Py_INCREF(arr)_Py_INCREF(((PyObject*)(arr))); |
| 1874 | return (PyObject *)arr; |
| 1875 | } |
| 1876 | newtype = oldtype; |
| 1877 | Py_INCREF(oldtype)_Py_INCREF(((PyObject*)(oldtype))); |
| 1878 | } |
| 1879 | else if (PyDataType_ISUNSIZED(newtype)((newtype)->elsize == 0 && !(((PyArray_Descr *)(newtype ))->names != ((void*)0)))) { |
| 1880 | PyArray_DESCR_REPLACE(newtype)do { PyArray_Descr *_new_; _new_ = PyArray_DescrNew(newtype); _Py_XDECREF(((PyObject*)(newtype))); newtype = _new_; } while (0); |
| 1881 | if (newtype == NULL((void*)0)) { |
| 1882 | return NULL((void*)0); |
| 1883 | } |
| 1884 | newtype->elsize = oldtype->elsize; |
| 1885 | } |
| 1886 | |
| 1887 | /* If the casting if forced, use the 'unsafe' casting rule */ |
| 1888 | if (flags & NPY_ARRAY_FORCECAST0x0010) { |
| 1889 | casting = NPY_UNSAFE_CASTING; |
| 1890 | } |
| 1891 | |
| 1892 | /* Raise an error if the casting rule isn't followed */ |
| 1893 | if (!PyArray_CanCastArrayTo(arr, newtype, casting)) { |
| 1894 | PyErr_Clear(); |
| 1895 | npy_set_invalid_cast_error( |
| 1896 | PyArray_DESCR(arr), newtype, casting, PyArray_NDIM(arr) == 0); |
| 1897 | Py_DECREF(newtype)_Py_DECREF(((PyObject*)(newtype))); |
| 1898 | return NULL((void*)0); |
| 1899 | } |
| 1900 | |
| 1901 | arrflags = PyArray_FLAGS(arr); |
| 1902 | /* If a guaranteed copy was requested */ |
| 1903 | copy = (flags & NPY_ARRAY_ENSURECOPY0x0020) || |
| 1904 | /* If C contiguous was requested, and arr is not */ |
| 1905 | ((flags & NPY_ARRAY_C_CONTIGUOUS0x0001) && |
| 1906 | (!(arrflags & NPY_ARRAY_C_CONTIGUOUS0x0001))) || |
| 1907 | /* If an aligned array was requested, and arr is not */ |
| 1908 | ((flags & NPY_ARRAY_ALIGNED0x0100) && |
| 1909 | (!(arrflags & NPY_ARRAY_ALIGNED0x0100))) || |
| 1910 | /* If a Fortran contiguous array was requested, and arr is not */ |
| 1911 | ((flags & NPY_ARRAY_F_CONTIGUOUS0x0002) && |
| 1912 | (!(arrflags & NPY_ARRAY_F_CONTIGUOUS0x0002))) || |
| 1913 | /* If a writeable array was requested, and arr is not */ |
| 1914 | ((flags & NPY_ARRAY_WRITEABLE0x0400) && |
| 1915 | (!(arrflags & NPY_ARRAY_WRITEABLE0x0400))) || |
| 1916 | !PyArray_EquivTypes(oldtype, newtype); |
| 1917 | |
| 1918 | if (copy) { |
| 1919 | NPY_ORDER order = NPY_KEEPORDER; |
| 1920 | int subok = 1; |
| 1921 | |
| 1922 | /* Set the order for the copy being made based on the flags */ |
| 1923 | if (flags & NPY_ARRAY_F_CONTIGUOUS0x0002) { |
| 1924 | order = NPY_FORTRANORDER; |
| 1925 | } |
| 1926 | else if (flags & NPY_ARRAY_C_CONTIGUOUS0x0001) { |
| 1927 | order = NPY_CORDER; |
| 1928 | } |
| 1929 | |
| 1930 | if ((flags & NPY_ARRAY_ENSUREARRAY0x0040)) { |
| 1931 | subok = 0; |
| 1932 | } |
| 1933 | ret = (PyArrayObject *)PyArray_NewLikeArray(arr, order, |
| 1934 | newtype, subok); |
| 1935 | if (ret == NULL((void*)0)) { |
| 1936 | return NULL((void*)0); |
| 1937 | } |
| 1938 | |
| 1939 | if (PyArray_CopyInto(ret, arr) < 0) { |
| 1940 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); |
| 1941 | return NULL((void*)0); |
| 1942 | } |
| 1943 | |
| 1944 | if (flags & NPY_ARRAY_UPDATEIFCOPY0x1000) { |
| 1945 | /* This is the ONLY place the NPY_ARRAY_UPDATEIFCOPY flag |
| 1946 | * is still used. |
| 1947 | * Can be deleted once the flag itself is removed |
| 1948 | */ |
| 1949 | |
| 1950 | /* 2017-Nov-10 1.14 */ |
| 1951 | if (DEPRECATE(PyErr_WarnEx(PyExc_DeprecationWarning,"NPY_ARRAY_UPDATEIFCOPY, NPY_ARRAY_INOUT_ARRAY, and " "NPY_ARRAY_INOUT_FARRAY are deprecated, use NPY_WRITEBACKIFCOPY, " "NPY_ARRAY_INOUT_ARRAY2, or NPY_ARRAY_INOUT_FARRAY2 respectively " "instead, and call PyArray_ResolveWritebackIfCopy before the " "array is deallocated, i.e. before the last call to Py_DECREF." ,1) |
| 1952 | "NPY_ARRAY_UPDATEIFCOPY, NPY_ARRAY_INOUT_ARRAY, and "PyErr_WarnEx(PyExc_DeprecationWarning,"NPY_ARRAY_UPDATEIFCOPY, NPY_ARRAY_INOUT_ARRAY, and " "NPY_ARRAY_INOUT_FARRAY are deprecated, use NPY_WRITEBACKIFCOPY, " "NPY_ARRAY_INOUT_ARRAY2, or NPY_ARRAY_INOUT_FARRAY2 respectively " "instead, and call PyArray_ResolveWritebackIfCopy before the " "array is deallocated, i.e. before the last call to Py_DECREF." ,1) |
| 1953 | "NPY_ARRAY_INOUT_FARRAY are deprecated, use NPY_WRITEBACKIFCOPY, "PyErr_WarnEx(PyExc_DeprecationWarning,"NPY_ARRAY_UPDATEIFCOPY, NPY_ARRAY_INOUT_ARRAY, and " "NPY_ARRAY_INOUT_FARRAY are deprecated, use NPY_WRITEBACKIFCOPY, " "NPY_ARRAY_INOUT_ARRAY2, or NPY_ARRAY_INOUT_FARRAY2 respectively " "instead, and call PyArray_ResolveWritebackIfCopy before the " "array is deallocated, i.e. before the last call to Py_DECREF." ,1) |
| 1954 | "NPY_ARRAY_INOUT_ARRAY2, or NPY_ARRAY_INOUT_FARRAY2 respectively "PyErr_WarnEx(PyExc_DeprecationWarning,"NPY_ARRAY_UPDATEIFCOPY, NPY_ARRAY_INOUT_ARRAY, and " "NPY_ARRAY_INOUT_FARRAY are deprecated, use NPY_WRITEBACKIFCOPY, " "NPY_ARRAY_INOUT_ARRAY2, or NPY_ARRAY_INOUT_FARRAY2 respectively " "instead, and call PyArray_ResolveWritebackIfCopy before the " "array is deallocated, i.e. before the last call to Py_DECREF." ,1) |
| 1955 | "instead, and call PyArray_ResolveWritebackIfCopy before the "PyErr_WarnEx(PyExc_DeprecationWarning,"NPY_ARRAY_UPDATEIFCOPY, NPY_ARRAY_INOUT_ARRAY, and " "NPY_ARRAY_INOUT_FARRAY are deprecated, use NPY_WRITEBACKIFCOPY, " "NPY_ARRAY_INOUT_ARRAY2, or NPY_ARRAY_INOUT_FARRAY2 respectively " "instead, and call PyArray_ResolveWritebackIfCopy before the " "array is deallocated, i.e. before the last call to Py_DECREF." ,1) |
| 1956 | "array is deallocated, i.e. before the last call to Py_DECREF.")PyErr_WarnEx(PyExc_DeprecationWarning,"NPY_ARRAY_UPDATEIFCOPY, NPY_ARRAY_INOUT_ARRAY, and " "NPY_ARRAY_INOUT_FARRAY are deprecated, use NPY_WRITEBACKIFCOPY, " "NPY_ARRAY_INOUT_ARRAY2, or NPY_ARRAY_INOUT_FARRAY2 respectively " "instead, and call PyArray_ResolveWritebackIfCopy before the " "array is deallocated, i.e. before the last call to Py_DECREF." ,1) < 0) { |
| 1957 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); |
| 1958 | return NULL((void*)0); |
| 1959 | } |
| 1960 | Py_INCREF(arr)_Py_INCREF(((PyObject*)(arr))); |
| 1961 | if (PyArray_SetWritebackIfCopyBase(ret, arr) < 0) { |
| 1962 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); |
| 1963 | return NULL((void*)0); |
| 1964 | } |
| 1965 | PyArray_ENABLEFLAGS(ret, NPY_ARRAY_UPDATEIFCOPY0x1000); |
| 1966 | PyArray_CLEARFLAGS(ret, NPY_ARRAY_WRITEBACKIFCOPY0x2000); |
| 1967 | } |
| 1968 | else if (flags & NPY_ARRAY_WRITEBACKIFCOPY0x2000) { |
| 1969 | Py_INCREF(arr)_Py_INCREF(((PyObject*)(arr))); |
| 1970 | if (PyArray_SetWritebackIfCopyBase(ret, arr) < 0) { |
| 1971 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); |
| 1972 | return NULL((void*)0); |
| 1973 | } |
| 1974 | } |
| 1975 | } |
| 1976 | /* |
| 1977 | * If no copy then take an appropriate view if necessary, or |
| 1978 | * just return a reference to ret itself. |
| 1979 | */ |
| 1980 | else { |
| 1981 | int needview = ((flags & NPY_ARRAY_ENSUREARRAY0x0040) && |
| 1982 | !PyArray_CheckExact(arr)(((PyObject*)(arr))->ob_type == &PyArray_Type)); |
| 1983 | |
| 1984 | Py_DECREF(newtype)_Py_DECREF(((PyObject*)(newtype))); |
| 1985 | if (needview) { |
| 1986 | PyTypeObject *subtype = NULL((void*)0); |
| 1987 | |
| 1988 | if (flags & NPY_ARRAY_ENSUREARRAY0x0040) { |
| 1989 | subtype = &PyArray_Type; |
| 1990 | } |
| 1991 | |
| 1992 | ret = (PyArrayObject *)PyArray_View(arr, NULL((void*)0), subtype); |
| 1993 | if (ret == NULL((void*)0)) { |
| 1994 | return NULL((void*)0); |
| 1995 | } |
| 1996 | } |
| 1997 | else { |
| 1998 | Py_INCREF(arr)_Py_INCREF(((PyObject*)(arr))); |
| 1999 | ret = arr; |
| 2000 | } |
| 2001 | } |
| 2002 | |
| 2003 | return (PyObject *)ret; |
| 2004 | } |
| 2005 | |
| 2006 | /*NUMPY_API */ |
| 2007 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 2008 | PyArray_FromStructInterface(PyObject *input) |
| 2009 | { |
| 2010 | PyArray_Descr *thetype = NULL((void*)0); |
| 2011 | PyArrayInterface *inter; |
| 2012 | PyObject *attr; |
| 2013 | char endian = NPY_NATBYTE'<'; |
| 2014 | |
| 2015 | attr = PyArray_LookupSpecial_OnInstance(input, "__array_struct__"); |
| 2016 | if (attr == NULL((void*)0)) { |
| 2017 | if (PyErr_Occurred()) { |
| 2018 | return NULL((void*)0); |
| 2019 | } else { |
| 2020 | return Py_NotImplemented(&_Py_NotImplementedStruct); |
| 2021 | } |
| 2022 | } |
| 2023 | if (!PyCapsule_CheckExact(attr)((((PyObject*)(attr))->ob_type) == &PyCapsule_Type)) { |
| 2024 | if (PyType_Check(input)((((((PyObject*)(input))->ob_type))->tp_flags & ((1UL << 31))) != 0) && PyObject_HasAttrString(attr, "__get__")) { |
| 2025 | /* |
| 2026 | * If the input is a class `attr` should be a property-like object. |
| 2027 | * This cannot be interpreted as an array, but is a valid. |
| 2028 | * (Needed due to the lookup being on the instance rather than type) |
| 2029 | */ |
| 2030 | Py_DECREF(attr)_Py_DECREF(((PyObject*)(attr))); |
| 2031 | return Py_NotImplemented(&_Py_NotImplementedStruct); |
| 2032 | } |
| 2033 | goto fail; |
| 2034 | } |
| 2035 | inter = PyCapsule_GetPointer(attr, NULL((void*)0)); |
| 2036 | if (inter == NULL((void*)0)) { |
| 2037 | goto fail; |
| 2038 | } |
| 2039 | if (inter->two != 2) { |
| 2040 | goto fail; |
| 2041 | } |
| 2042 | if ((inter->flags & NPY_ARRAY_NOTSWAPPED0x0200) != NPY_ARRAY_NOTSWAPPED0x0200) { |
| 2043 | endian = NPY_OPPBYTE'>'; |
| 2044 | inter->flags &= ~NPY_ARRAY_NOTSWAPPED0x0200; |
| 2045 | } |
| 2046 | |
| 2047 | if (inter->flags & NPY_ARR_HAS_DESCR0x0800) { |
| 2048 | if (PyArray_DescrConverter(inter->descr, &thetype) == NPY_FAIL0) { |
| 2049 | thetype = NULL((void*)0); |
| 2050 | PyErr_Clear(); |
| 2051 | } |
| 2052 | } |
| 2053 | |
| 2054 | if (thetype == NULL((void*)0)) { |
| 2055 | PyObject *type_str = PyUnicode_FromFormat( |
| 2056 | "%c%c%d", endian, inter->typekind, inter->itemsize); |
| 2057 | if (type_str == NULL((void*)0)) { |
| 2058 | Py_DECREF(attr)_Py_DECREF(((PyObject*)(attr))); |
| 2059 | return NULL((void*)0); |
| 2060 | } |
| 2061 | int ok = PyArray_DescrConverter(type_str, &thetype); |
| 2062 | Py_DECREF(type_str)_Py_DECREF(((PyObject*)(type_str))); |
| 2063 | if (ok != NPY_SUCCEED1) { |
| 2064 | Py_DECREF(attr)_Py_DECREF(((PyObject*)(attr))); |
| 2065 | return NULL((void*)0); |
| 2066 | } |
| 2067 | } |
| 2068 | |
| 2069 | PyObject *ret = PyArray_NewFromDescrAndBase( |
| 2070 | &PyArray_Type, thetype, |
| 2071 | inter->nd, inter->shape, inter->strides, inter->data, |
| 2072 | inter->flags, NULL((void*)0), input); |
| 2073 | Py_DECREF(attr)_Py_DECREF(((PyObject*)(attr))); |
| 2074 | return ret; |
| 2075 | |
| 2076 | fail: |
| 2077 | PyErr_SetString(PyExc_ValueError, "invalid __array_struct__"); |
| 2078 | Py_DECREF(attr)_Py_DECREF(((PyObject*)(attr))); |
| 2079 | return NULL((void*)0); |
| 2080 | } |
| 2081 | |
| 2082 | /* |
| 2083 | * Checks if the object in descr is the default 'descr' member for the |
| 2084 | * __array_interface__ dictionary with 'typestr' member typestr. |
| 2085 | */ |
| 2086 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) int |
| 2087 | _is_default_descr(PyObject *descr, PyObject *typestr) { |
| 2088 | if (!PyList_Check(descr)((((((PyObject*)(descr))->ob_type))->tp_flags & ((1UL << 25))) != 0) || PyList_GET_SIZE(descr)(((void) (0)), (((PyVarObject*)(descr))->ob_size)) != 1) { |
| 2089 | return 0; |
| 2090 | } |
| 2091 | PyObject *tuple = PyList_GET_ITEM(descr, 0)(((PyListObject *)(descr))->ob_item[0]); |
| 2092 | if (!(PyTuple_Check(tuple)((((((PyObject*)(tuple))->ob_type))->tp_flags & ((1UL << 26))) != 0) && PyTuple_GET_SIZE(tuple)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(tuple))))-> ob_size) == 2)) { |
| 2093 | return 0; |
| 2094 | } |
| 2095 | PyObject *name = PyTuple_GET_ITEM(tuple, 0)((((void) (0)), (PyTupleObject *)(tuple))->ob_item[0]); |
| 2096 | if (!(PyUnicode_Check(name)((((((PyObject*)(name))->ob_type))->tp_flags & ((1UL << 28))) != 0) && PyUnicode_GetLength(name) == 0)) { |
| 2097 | return 0; |
| 2098 | } |
| 2099 | PyObject *typestr2 = PyTuple_GET_ITEM(tuple, 1)((((void) (0)), (PyTupleObject *)(tuple))->ob_item[1]); |
| 2100 | return PyObject_RichCompareBool(typestr, typestr2, Py_EQ2); |
| 2101 | } |
| 2102 | |
| 2103 | |
| 2104 | /* |
| 2105 | * A helper function to transition away from ignoring errors during |
| 2106 | * special attribute lookups during array coercion. |
| 2107 | */ |
| 2108 | static NPY_INLINEinline int |
| 2109 | deprecated_lookup_error_clearing(PyTypeObject *type, char *attribute) |
| 2110 | { |
| 2111 | PyObject *exc_type, *exc_value, *traceback; |
| 2112 | PyErr_Fetch(&exc_type, &exc_value, &traceback); |
| 2113 | |
| 2114 | /* DEPRECATED 2021-05-12, NumPy 1.21. */ |
| 2115 | int res = PyErr_WarnFormat(PyExc_DeprecationWarning, 1, |
| 2116 | "An exception was ignored while fetching the attribute `%s` from " |
| 2117 | "an object of type '%s'. With the exception of `AttributeError` " |
| 2118 | "NumPy will always raise this exception in the future. Raise this " |
| 2119 | "deprecation warning to see the original exception. " |
| 2120 | "(Warning added NumPy 1.21)", attribute, type->tp_name); |
| 2121 | |
| 2122 | if (res < 0) { |
| 2123 | npy_PyErr_ChainExceptionsCause(exc_type, exc_value, traceback); |
| 2124 | return -1; |
| 2125 | } |
| 2126 | else { |
| 2127 | /* `PyErr_Fetch` cleared the original error, delete the references */ |
| 2128 | Py_DECREF(exc_type)_Py_DECREF(((PyObject*)(exc_type))); |
| 2129 | Py_XDECREF(exc_value)_Py_XDECREF(((PyObject*)(exc_value))); |
| 2130 | Py_XDECREF(traceback)_Py_XDECREF(((PyObject*)(traceback))); |
| 2131 | return 0; |
| 2132 | } |
| 2133 | } |
| 2134 | |
| 2135 | |
| 2136 | /*NUMPY_API*/ |
| 2137 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 2138 | PyArray_FromInterface(PyObject *origin) |
| 2139 | { |
| 2140 | PyObject *iface = NULL((void*)0); |
| 2141 | PyObject *attr = NULL((void*)0); |
| 2142 | PyObject *base = NULL((void*)0); |
| 2143 | PyArrayObject *ret; |
| 2144 | PyArray_Descr *dtype = NULL((void*)0); |
| 2145 | char *data = NULL((void*)0); |
| 2146 | Py_buffer view; |
| 2147 | int i, n; |
| 2148 | npy_intp dims[NPY_MAXDIMS32], strides[NPY_MAXDIMS32]; |
| 2149 | int dataflags = NPY_ARRAY_BEHAVED(0x0100 | 0x0400); |
| 2150 | |
| 2151 | iface = PyArray_LookupSpecial_OnInstance(origin, "__array_interface__"); |
| 2152 | |
| 2153 | if (iface == NULL((void*)0)) { |
| 2154 | if (PyErr_Occurred()) { |
| 2155 | if (PyErr_ExceptionMatches(PyExc_RecursionError) || |
| 2156 | PyErr_ExceptionMatches(PyExc_MemoryError)) { |
| 2157 | /* RecursionError and MemoryError are considered fatal */ |
| 2158 | return NULL((void*)0); |
| 2159 | } |
| 2160 | if (deprecated_lookup_error_clearing( |
| 2161 | Py_TYPE(origin)(((PyObject*)(origin))->ob_type), "__array_interface__") < 0) { |
| 2162 | return NULL((void*)0); |
| 2163 | } |
| 2164 | } |
| 2165 | return Py_NotImplemented(&_Py_NotImplementedStruct); |
| 2166 | } |
| 2167 | if (!PyDict_Check(iface)((((((PyObject*)(iface))->ob_type))->tp_flags & ((1UL << 29))) != 0)) { |
| 2168 | if (PyType_Check(origin)((((((PyObject*)(origin))->ob_type))->tp_flags & (( 1UL << 31))) != 0) && PyObject_HasAttrString(iface, "__get__")) { |
| 2169 | /* |
| 2170 | * If the input is a class `iface` should be a property-like object. |
| 2171 | * This cannot be interpreted as an array, but is a valid. |
| 2172 | * (Needed due to the lookup being on the instance rather than type) |
| 2173 | */ |
| 2174 | Py_DECREF(iface)_Py_DECREF(((PyObject*)(iface))); |
| 2175 | return Py_NotImplemented(&_Py_NotImplementedStruct); |
| 2176 | } |
| 2177 | |
| 2178 | Py_DECREF(iface)_Py_DECREF(((PyObject*)(iface))); |
| 2179 | PyErr_SetString(PyExc_ValueError, |
| 2180 | "Invalid __array_interface__ value, must be a dict"); |
| 2181 | return NULL((void*)0); |
| 2182 | } |
| 2183 | |
| 2184 | /* Get type string from interface specification */ |
| 2185 | attr = _PyDict_GetItemStringWithError(iface, "typestr"); |
| 2186 | if (attr == NULL((void*)0)) { |
| 2187 | Py_DECREF(iface)_Py_DECREF(((PyObject*)(iface))); |
| 2188 | if (!PyErr_Occurred()) { |
| 2189 | PyErr_SetString(PyExc_ValueError, |
| 2190 | "Missing __array_interface__ typestr"); |
| 2191 | } |
| 2192 | return NULL((void*)0); |
| 2193 | } |
| 2194 | |
| 2195 | /* allow bytes for backwards compatibility */ |
| 2196 | if (!PyBytes_Check(attr)((((((PyObject*)(attr))->ob_type))->tp_flags & ((1UL << 27))) != 0) && !PyUnicode_Check(attr)((((((PyObject*)(attr))->ob_type))->tp_flags & ((1UL << 28))) != 0)) { |
| 2197 | PyErr_SetString(PyExc_TypeError, |
| 2198 | "__array_interface__ typestr must be a string"); |
| 2199 | goto fail; |
| 2200 | } |
| 2201 | |
| 2202 | /* Get dtype from type string */ |
| 2203 | if (PyArray_DescrConverter(attr, &dtype) != NPY_SUCCEED1) { |
| 2204 | goto fail; |
| 2205 | } |
| 2206 | |
| 2207 | /* |
| 2208 | * If the dtype is NPY_VOID, see if there is extra information in |
| 2209 | * the 'descr' attribute. |
| 2210 | */ |
| 2211 | if (dtype->type_num == NPY_VOID) { |
| 2212 | PyObject *descr = _PyDict_GetItemStringWithError(iface, "descr"); |
| 2213 | if (descr == NULL((void*)0) && PyErr_Occurred()) { |
| 2214 | goto fail; |
| 2215 | } |
| 2216 | PyArray_Descr *new_dtype = NULL((void*)0); |
| 2217 | if (descr != NULL((void*)0)) { |
| 2218 | int is_default = _is_default_descr(descr, attr); |
| 2219 | if (is_default < 0) { |
| 2220 | goto fail; |
| 2221 | } |
| 2222 | if (!is_default) { |
| 2223 | if (PyArray_DescrConverter2(descr, &new_dtype) != NPY_SUCCEED1) { |
| 2224 | goto fail; |
| 2225 | } |
| 2226 | if (new_dtype != NULL((void*)0)) { |
| 2227 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 2228 | dtype = new_dtype; |
| 2229 | } |
| 2230 | } |
| 2231 | |
| 2232 | } |
| 2233 | |
| 2234 | } |
| 2235 | |
| 2236 | /* Get shape tuple from interface specification */ |
| 2237 | attr = _PyDict_GetItemStringWithError(iface, "shape"); |
| 2238 | if (attr == NULL((void*)0)) { |
| 2239 | if (PyErr_Occurred()) { |
| 2240 | return NULL((void*)0); |
| 2241 | } |
| 2242 | /* Shape must be specified when 'data' is specified */ |
| 2243 | PyObject *data = _PyDict_GetItemStringWithError(iface, "data"); |
| 2244 | if (data == NULL((void*)0) && PyErr_Occurred()) { |
| 2245 | return NULL((void*)0); |
| 2246 | } |
| 2247 | else if (data != NULL((void*)0)) { |
| 2248 | Py_DECREF(iface)_Py_DECREF(((PyObject*)(iface))); |
| 2249 | PyErr_SetString(PyExc_ValueError, |
| 2250 | "Missing __array_interface__ shape"); |
| 2251 | return NULL((void*)0); |
| 2252 | } |
| 2253 | /* Assume shape as scalar otherwise */ |
| 2254 | else { |
| 2255 | /* NOTE: pointers to data and base should be NULL */ |
| 2256 | n = dims[0] = 0; |
| 2257 | } |
| 2258 | } |
| 2259 | /* Make sure 'shape' is a tuple */ |
| 2260 | else if (!PyTuple_Check(attr)((((((PyObject*)(attr))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { |
| 2261 | PyErr_SetString(PyExc_TypeError, |
| 2262 | "shape must be a tuple"); |
| 2263 | goto fail; |
| 2264 | } |
| 2265 | /* Get dimensions from shape tuple */ |
| 2266 | else { |
| 2267 | n = PyTuple_GET_SIZE(attr)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(attr))))-> ob_size); |
| 2268 | for (i = 0; i < n; i++) { |
| 2269 | PyObject *tmp = PyTuple_GET_ITEM(attr, i)((((void) (0)), (PyTupleObject *)(attr))->ob_item[i]); |
| 2270 | dims[i] = PyArray_PyIntAsIntp(tmp); |
| 2271 | if (error_converting(dims[i])(((dims[i]) == -1) && PyErr_Occurred())) { |
| 2272 | goto fail; |
| 2273 | } |
| 2274 | } |
| 2275 | } |
| 2276 | |
| 2277 | /* Get data buffer from interface specification */ |
| 2278 | attr = _PyDict_GetItemStringWithError(iface, "data"); |
| 2279 | if (attr == NULL((void*)0) && PyErr_Occurred()){ |
| 2280 | return NULL((void*)0); |
| 2281 | } |
| 2282 | |
| 2283 | /* Case for data access through pointer */ |
| 2284 | if (attr && PyTuple_Check(attr)((((((PyObject*)(attr))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { |
| 2285 | PyObject *dataptr; |
| 2286 | if (PyTuple_GET_SIZE(attr)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(attr))))-> ob_size) != 2) { |
| 2287 | PyErr_SetString(PyExc_TypeError, |
| 2288 | "__array_interface__ data must be a 2-tuple with " |
| 2289 | "(data pointer integer, read-only flag)"); |
| 2290 | goto fail; |
| 2291 | } |
| 2292 | dataptr = PyTuple_GET_ITEM(attr, 0)((((void) (0)), (PyTupleObject *)(attr))->ob_item[0]); |
| 2293 | if (PyLong_Check(dataptr)((((((PyObject*)(dataptr))->ob_type))->tp_flags & ( (1UL << 24))) != 0)) { |
| 2294 | data = PyLong_AsVoidPtr(dataptr); |
| 2295 | if (data == NULL((void*)0) && PyErr_Occurred()) { |
| 2296 | goto fail; |
| 2297 | } |
| 2298 | } |
| 2299 | else { |
| 2300 | PyErr_SetString(PyExc_TypeError, |
| 2301 | "first element of __array_interface__ data tuple " |
| 2302 | "must be an integer."); |
| 2303 | goto fail; |
| 2304 | } |
| 2305 | if (PyObject_IsTrue(PyTuple_GET_ITEM(attr,1)((((void) (0)), (PyTupleObject *)(attr))->ob_item[1]))) { |
| 2306 | dataflags &= ~NPY_ARRAY_WRITEABLE0x0400; |
| 2307 | } |
| 2308 | base = origin; |
| 2309 | } |
| 2310 | |
| 2311 | /* Case for data access through buffer */ |
| 2312 | else if (attr) { |
| 2313 | if (attr != Py_None(&_Py_NoneStruct)) { |
| 2314 | base = attr; |
| 2315 | } |
| 2316 | else { |
| 2317 | base = origin; |
| 2318 | } |
| 2319 | if (PyObject_GetBuffer(base, &view, |
| 2320 | PyBUF_WRITABLE0x0001|PyBUF_SIMPLE0) < 0) { |
| 2321 | PyErr_Clear(); |
| 2322 | if (PyObject_GetBuffer(base, &view, |
| 2323 | PyBUF_SIMPLE0) < 0) { |
| 2324 | goto fail; |
| 2325 | } |
| 2326 | dataflags &= ~NPY_ARRAY_WRITEABLE0x0400; |
| 2327 | } |
| 2328 | data = (char *)view.buf; |
| 2329 | /* |
| 2330 | * In Python 3 both of the deprecated functions PyObject_AsWriteBuffer and |
| 2331 | * PyObject_AsReadBuffer that this code replaces release the buffer. It is |
| 2332 | * up to the object that supplies the buffer to guarantee that the buffer |
| 2333 | * sticks around after the release. |
| 2334 | */ |
| 2335 | PyBuffer_Release(&view); |
| 2336 | |
| 2337 | /* Get offset number from interface specification */ |
| 2338 | attr = _PyDict_GetItemStringWithError(iface, "offset"); |
| 2339 | if (attr == NULL((void*)0) && PyErr_Occurred()) { |
| 2340 | goto fail; |
| 2341 | } |
| 2342 | else if (attr) { |
| 2343 | npy_longlong num = PyLong_AsLongLong(attr); |
| 2344 | if (error_converting(num)(((num) == -1) && PyErr_Occurred())) { |
| 2345 | PyErr_SetString(PyExc_TypeError, |
| 2346 | "__array_interface__ offset must be an integer"); |
| 2347 | goto fail; |
| 2348 | } |
| 2349 | data += num; |
| 2350 | } |
| 2351 | } |
| 2352 | |
| 2353 | ret = (PyArrayObject *)PyArray_NewFromDescrAndBase( |
| 2354 | &PyArray_Type, dtype, |
| 2355 | n, dims, NULL((void*)0), data, |
| 2356 | dataflags, NULL((void*)0), base); |
| 2357 | /* |
| 2358 | * Ref to dtype was stolen by PyArray_NewFromDescrAndBase |
| 2359 | * Prevent DECREFing dtype in fail codepath by setting to NULL |
| 2360 | */ |
| 2361 | dtype = NULL((void*)0); |
| 2362 | if (ret == NULL((void*)0)) { |
| 2363 | goto fail; |
| 2364 | } |
| 2365 | if (data == NULL((void*)0)) { |
| 2366 | if (PyArray_SIZE(ret)PyArray_MultiplyList(PyArray_DIMS(ret), PyArray_NDIM(ret)) > 1) { |
| 2367 | PyErr_SetString(PyExc_ValueError, |
| 2368 | "cannot coerce scalar to array with size > 1"); |
| 2369 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); |
| 2370 | goto fail; |
| 2371 | } |
| 2372 | if (PyArray_SETITEM(ret, PyArray_DATA(ret), origin) < 0) { |
| 2373 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); |
| 2374 | goto fail; |
| 2375 | } |
| 2376 | } |
| 2377 | attr = _PyDict_GetItemStringWithError(iface, "strides"); |
| 2378 | if (attr == NULL((void*)0) && PyErr_Occurred()){ |
| 2379 | return NULL((void*)0); |
| 2380 | } |
| 2381 | if (attr != NULL((void*)0) && attr != Py_None(&_Py_NoneStruct)) { |
| 2382 | if (!PyTuple_Check(attr)((((((PyObject*)(attr))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { |
| 2383 | PyErr_SetString(PyExc_TypeError, |
| 2384 | "strides must be a tuple"); |
| 2385 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); |
| 2386 | goto fail; |
| 2387 | } |
| 2388 | if (n != PyTuple_GET_SIZE(attr)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(attr))))-> ob_size)) { |
| 2389 | PyErr_SetString(PyExc_ValueError, |
| 2390 | "mismatch in length of strides and shape"); |
| 2391 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); |
| 2392 | goto fail; |
| 2393 | } |
| 2394 | for (i = 0; i < n; i++) { |
| 2395 | PyObject *tmp = PyTuple_GET_ITEM(attr, i)((((void) (0)), (PyTupleObject *)(attr))->ob_item[i]); |
| 2396 | strides[i] = PyArray_PyIntAsIntp(tmp); |
| 2397 | if (error_converting(strides[i])(((strides[i]) == -1) && PyErr_Occurred())) { |
| 2398 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); |
| 2399 | goto fail; |
| 2400 | } |
| 2401 | } |
| 2402 | if (n) { |
| 2403 | memcpy(PyArray_STRIDES(ret), strides, n*sizeof(npy_intp)); |
| 2404 | } |
| 2405 | } |
| 2406 | PyArray_UpdateFlags(ret, NPY_ARRAY_UPDATE_ALL(0x0001 | 0x0002 | 0x0100)); |
| 2407 | Py_DECREF(iface)_Py_DECREF(((PyObject*)(iface))); |
| 2408 | return (PyObject *)ret; |
| 2409 | |
| 2410 | fail: |
| 2411 | Py_XDECREF(dtype)_Py_XDECREF(((PyObject*)(dtype))); |
| 2412 | Py_XDECREF(iface)_Py_XDECREF(((PyObject*)(iface))); |
| 2413 | return NULL((void*)0); |
| 2414 | } |
| 2415 | |
| 2416 | /*NUMPY_API |
| 2417 | */ |
| 2418 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 2419 | PyArray_FromArrayAttr(PyObject *op, PyArray_Descr *typecode, PyObject *context) |
| 2420 | { |
| 2421 | PyObject *new; |
| 2422 | PyObject *array_meth; |
| 2423 | |
| 2424 | if (context != NULL((void*)0)) { |
| 2425 | PyErr_SetString(PyExc_RuntimeError, "'context' must be NULL"); |
| 2426 | return NULL((void*)0); |
| 2427 | } |
| 2428 | array_meth = PyArray_LookupSpecial_OnInstance(op, "__array__"); |
| 2429 | if (array_meth == NULL((void*)0)) { |
| 2430 | if (PyErr_Occurred()) { |
| 2431 | if (PyErr_ExceptionMatches(PyExc_RecursionError) || |
| 2432 | PyErr_ExceptionMatches(PyExc_MemoryError)) { |
| 2433 | /* RecursionError and MemoryError are considered fatal */ |
| 2434 | return NULL((void*)0); |
| 2435 | } |
| 2436 | if (deprecated_lookup_error_clearing( |
| 2437 | Py_TYPE(op)(((PyObject*)(op))->ob_type), "__array__") < 0) { |
| 2438 | return NULL((void*)0); |
| 2439 | } |
| 2440 | } |
| 2441 | return Py_NotImplemented(&_Py_NotImplementedStruct); |
| 2442 | } |
| 2443 | if (PyType_Check(op)((((((PyObject*)(op))->ob_type))->tp_flags & ((1UL << 31))) != 0) && PyObject_HasAttrString(array_meth, "__get__")) { |
| 2444 | /* |
| 2445 | * If the input is a class `array_meth` may be a property-like object. |
| 2446 | * This cannot be interpreted as an array (called), but is a valid. |
| 2447 | * Trying `array_meth.__call__()` on this should not be useful. |
| 2448 | * (Needed due to the lookup being on the instance rather than type) |
| 2449 | */ |
| 2450 | Py_DECREF(array_meth)_Py_DECREF(((PyObject*)(array_meth))); |
| 2451 | return Py_NotImplemented(&_Py_NotImplementedStruct); |
| 2452 | } |
| 2453 | if (typecode == NULL((void*)0)) { |
| 2454 | new = PyObject_CallFunction_PyObject_CallFunction_SizeT(array_meth, NULL((void*)0)); |
| 2455 | } |
| 2456 | else { |
| 2457 | new = PyObject_CallFunction_PyObject_CallFunction_SizeT(array_meth, "O", typecode); |
| 2458 | } |
| 2459 | Py_DECREF(array_meth)_Py_DECREF(((PyObject*)(array_meth))); |
| 2460 | if (new == NULL((void*)0)) { |
| 2461 | return NULL((void*)0); |
| 2462 | } |
| 2463 | if (!PyArray_Check(new)((((PyObject*)(new))->ob_type) == (&PyArray_Type) || PyType_IsSubtype ((((PyObject*)(new))->ob_type), (&PyArray_Type)))) { |
| 2464 | PyErr_SetString(PyExc_ValueError, |
| 2465 | "object __array__ method not " \ |
| 2466 | "producing an array"); |
| 2467 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); |
| 2468 | return NULL((void*)0); |
| 2469 | } |
| 2470 | return new; |
| 2471 | } |
| 2472 | |
| 2473 | /*NUMPY_API |
| 2474 | * new reference -- accepts NULL for mintype |
| 2475 | */ |
| 2476 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyArray_Descr * |
| 2477 | PyArray_DescrFromObject(PyObject *op, PyArray_Descr *mintype) |
| 2478 | { |
| 2479 | PyArray_Descr *dtype; |
| 2480 | |
| 2481 | dtype = mintype; |
| 2482 | Py_XINCREF(dtype)_Py_XINCREF(((PyObject*)(dtype))); |
| 2483 | |
| 2484 | if (PyArray_DTypeFromObject(op, NPY_MAXDIMS32, &dtype) < 0) { |
| 2485 | return NULL((void*)0); |
| 2486 | } |
| 2487 | |
| 2488 | if (dtype == NULL((void*)0)) { |
| 2489 | return PyArray_DescrFromType(NPY_DEFAULT_TYPENPY_DOUBLE); |
| 2490 | } |
| 2491 | else { |
| 2492 | return dtype; |
| 2493 | } |
| 2494 | } |
| 2495 | |
| 2496 | /* These are also old calls (should use PyArray_NewFromDescr) */ |
| 2497 | |
| 2498 | /* They all zero-out the memory as previously done */ |
| 2499 | |
| 2500 | /* steals reference to descr -- and enforces native byteorder on it.*/ |
| 2501 | |
| 2502 | /*NUMPY_API |
| 2503 | Deprecated, use PyArray_NewFromDescr instead. |
| 2504 | */ |
| 2505 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 2506 | PyArray_FromDimsAndDataAndDescr(int NPY_UNUSED(nd)(__NPY_UNUSED_TAGGEDnd) __attribute__ ((__unused__)), int *NPY_UNUSED(d)(__NPY_UNUSED_TAGGEDd) __attribute__ ((__unused__)), |
| 2507 | PyArray_Descr *descr, |
| 2508 | char *NPY_UNUSED(data)(__NPY_UNUSED_TAGGEDdata) __attribute__ ((__unused__))) |
| 2509 | { |
| 2510 | PyErr_SetString(PyExc_NotImplementedError, |
| 2511 | "PyArray_FromDimsAndDataAndDescr: use PyArray_NewFromDescr."); |
| 2512 | Py_DECREF(descr)_Py_DECREF(((PyObject*)(descr))); |
| 2513 | return NULL((void*)0); |
| 2514 | } |
| 2515 | |
| 2516 | /*NUMPY_API |
| 2517 | Deprecated, use PyArray_SimpleNew instead. |
| 2518 | */ |
| 2519 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 2520 | PyArray_FromDims(int NPY_UNUSED(nd)(__NPY_UNUSED_TAGGEDnd) __attribute__ ((__unused__)), int *NPY_UNUSED(d)(__NPY_UNUSED_TAGGEDd) __attribute__ ((__unused__)), int NPY_UNUSED(type)(__NPY_UNUSED_TAGGEDtype) __attribute__ ((__unused__))) |
| 2521 | { |
| 2522 | PyErr_SetString(PyExc_NotImplementedError, |
| 2523 | "PyArray_FromDims: use PyArray_SimpleNew."); |
| 2524 | return NULL((void*)0); |
| 2525 | } |
| 2526 | |
| 2527 | /* end old calls */ |
| 2528 | |
| 2529 | /*NUMPY_API |
| 2530 | * This is a quick wrapper around |
| 2531 | * PyArray_FromAny(op, NULL, 0, 0, NPY_ARRAY_ENSUREARRAY, NULL) |
| 2532 | * that special cases Arrays and PyArray_Scalars up front |
| 2533 | * It *steals a reference* to the object |
| 2534 | * It also guarantees that the result is PyArray_Type |
| 2535 | * Because it decrefs op if any conversion needs to take place |
| 2536 | * so it can be used like PyArray_EnsureArray(some_function(...)) |
| 2537 | */ |
| 2538 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 2539 | PyArray_EnsureArray(PyObject *op) |
| 2540 | { |
| 2541 | PyObject *new; |
| 2542 | |
| 2543 | if ((op == NULL((void*)0)) || (PyArray_CheckExact(op)(((PyObject*)(op))->ob_type == &PyArray_Type))) { |
| 2544 | new = op; |
| 2545 | Py_XINCREF(new)_Py_XINCREF(((PyObject*)(new))); |
| 2546 | } |
| 2547 | else if (PyArray_Check(op)((((PyObject*)(op))->ob_type) == (&PyArray_Type) || PyType_IsSubtype ((((PyObject*)(op))->ob_type), (&PyArray_Type)))) { |
| 2548 | new = PyArray_View((PyArrayObject *)op, NULL((void*)0), &PyArray_Type); |
| 2549 | } |
| 2550 | else if (PyArray_IsScalar(op, Generic)(((((PyObject*)(op))->ob_type) == (&PyGenericArrType_Type ) || PyType_IsSubtype((((PyObject*)(op))->ob_type), (& PyGenericArrType_Type))))) { |
| 2551 | new = PyArray_FromScalar(op, NULL((void*)0)); |
| 2552 | } |
| 2553 | else { |
| 2554 | new = PyArray_FROM_OF(op, NPY_ARRAY_ENSUREARRAY)PyArray_CheckFromAny(op, ((void*)0), 0, 0, 0x0040, ((void*)0) ); |
| 2555 | } |
| 2556 | Py_XDECREF(op)_Py_XDECREF(((PyObject*)(op))); |
| 2557 | return new; |
| 2558 | } |
| 2559 | |
| 2560 | /*NUMPY_API*/ |
| 2561 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 2562 | PyArray_EnsureAnyArray(PyObject *op) |
| 2563 | { |
| 2564 | if (op && PyArray_Check(op)((((PyObject*)(op))->ob_type) == (&PyArray_Type) || PyType_IsSubtype ((((PyObject*)(op))->ob_type), (&PyArray_Type)))) { |
| 2565 | return op; |
| 2566 | } |
| 2567 | return PyArray_EnsureArray(op); |
| 2568 | } |
| 2569 | |
| 2570 | /* |
| 2571 | * Private implementation of PyArray_CopyAnyInto with an additional order |
| 2572 | * parameter. |
| 2573 | */ |
| 2574 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) int |
| 2575 | PyArray_CopyAsFlat(PyArrayObject *dst, PyArrayObject *src, NPY_ORDER order) |
| 2576 | { |
| 2577 | NpyIter *dst_iter, *src_iter; |
| 2578 | |
| 2579 | NpyIter_IterNextFunc *dst_iternext, *src_iternext; |
| 2580 | char **dst_dataptr, **src_dataptr; |
| 2581 | npy_intp dst_stride, src_stride; |
| 2582 | npy_intp *dst_countptr, *src_countptr; |
| 2583 | npy_uint32 baseflags; |
| 2584 | |
| 2585 | npy_intp dst_count, src_count, count; |
| 2586 | npy_intp dst_size, src_size; |
| 2587 | int needs_api; |
| 2588 | |
| 2589 | NPY_BEGIN_THREADS_DEFPyThreadState *_save=((void*)0);; |
| 2590 | |
| 2591 | if (PyArray_FailUnlessWriteable(dst, "destination array") < 0) { |
| 2592 | return -1; |
| 2593 | } |
| 2594 | |
| 2595 | /* |
| 2596 | * If the shapes match and a particular order is forced |
| 2597 | * for both, use the more efficient CopyInto |
| 2598 | */ |
| 2599 | if (order != NPY_ANYORDER && order != NPY_KEEPORDER && |
| 2600 | PyArray_NDIM(dst) == PyArray_NDIM(src) && |
| 2601 | PyArray_CompareLists(PyArray_DIMS(dst), PyArray_DIMS(src), |
| 2602 | PyArray_NDIM(dst))) { |
| 2603 | return PyArray_CopyInto(dst, src); |
| 2604 | } |
| 2605 | |
| 2606 | dst_size = PyArray_SIZE(dst)PyArray_MultiplyList(PyArray_DIMS(dst), PyArray_NDIM(dst)); |
| 2607 | src_size = PyArray_SIZE(src)PyArray_MultiplyList(PyArray_DIMS(src), PyArray_NDIM(src)); |
| 2608 | if (dst_size != src_size) { |
| 2609 | PyErr_Format(PyExc_ValueError, |
| 2610 | "cannot copy from array of size %" NPY_INTP_FMT"ld" " into an array " |
| 2611 | "of size %" NPY_INTP_FMT"ld", src_size, dst_size); |
| 2612 | return -1; |
| 2613 | } |
| 2614 | |
| 2615 | /* Zero-sized arrays require nothing be done */ |
| 2616 | if (dst_size == 0) { |
| 2617 | return 0; |
| 2618 | } |
| 2619 | |
| 2620 | baseflags = NPY_ITER_EXTERNAL_LOOP0x00000008 | |
| 2621 | NPY_ITER_DONT_NEGATE_STRIDES0x00001000 | |
| 2622 | NPY_ITER_REFS_OK0x00000020; |
| 2623 | |
| 2624 | /* |
| 2625 | * This copy is based on matching C-order traversals of src and dst. |
| 2626 | * By using two iterators, we can find maximal sub-chunks that |
| 2627 | * can be processed at once. |
| 2628 | */ |
| 2629 | dst_iter = NpyIter_New(dst, NPY_ITER_WRITEONLY0x00040000 | baseflags, |
| 2630 | order, |
| 2631 | NPY_NO_CASTING, |
| 2632 | NULL((void*)0)); |
| 2633 | if (dst_iter == NULL((void*)0)) { |
| 2634 | return -1; |
| 2635 | } |
| 2636 | src_iter = NpyIter_New(src, NPY_ITER_READONLY0x00020000 | baseflags, |
| 2637 | order, |
| 2638 | NPY_NO_CASTING, |
| 2639 | NULL((void*)0)); |
| 2640 | if (src_iter == NULL((void*)0)) { |
| 2641 | NpyIter_Deallocate(dst_iter); |
| 2642 | return -1; |
| 2643 | } |
| 2644 | |
| 2645 | /* Get all the values needed for the inner loop */ |
| 2646 | dst_iternext = NpyIter_GetIterNext(dst_iter, NULL((void*)0)); |
| 2647 | dst_dataptr = NpyIter_GetDataPtrArray(dst_iter); |
| 2648 | /* Since buffering is disabled, we can cache the stride */ |
| 2649 | dst_stride = NpyIter_GetInnerStrideArray(dst_iter)[0]; |
| 2650 | dst_countptr = NpyIter_GetInnerLoopSizePtr(dst_iter); |
| 2651 | |
| 2652 | src_iternext = NpyIter_GetIterNext(src_iter, NULL((void*)0)); |
| 2653 | src_dataptr = NpyIter_GetDataPtrArray(src_iter); |
| 2654 | /* Since buffering is disabled, we can cache the stride */ |
| 2655 | src_stride = NpyIter_GetInnerStrideArray(src_iter)[0]; |
| 2656 | src_countptr = NpyIter_GetInnerLoopSizePtr(src_iter); |
| 2657 | |
| 2658 | if (dst_iternext == NULL((void*)0) || src_iternext == NULL((void*)0)) { |
| 2659 | NpyIter_Deallocate(dst_iter); |
| 2660 | NpyIter_Deallocate(src_iter); |
| 2661 | return -1; |
| 2662 | } |
| 2663 | |
| 2664 | needs_api = NpyIter_IterationNeedsAPI(dst_iter) || |
| 2665 | NpyIter_IterationNeedsAPI(src_iter); |
| 2666 | |
| 2667 | /* |
| 2668 | * Because buffering is disabled in the iterator, the inner loop |
| 2669 | * strides will be the same throughout the iteration loop. Thus, |
| 2670 | * we can pass them to this function to take advantage of |
| 2671 | * contiguous strides, etc. |
| 2672 | */ |
| 2673 | NPY_cast_info cast_info; |
| 2674 | if (PyArray_GetDTypeTransferFunction( |
| 2675 | IsUintAligned(src) && IsAligned(src) && |
| 2676 | IsUintAligned(dst) && IsAligned(dst), |
| 2677 | src_stride, dst_stride, |
| 2678 | PyArray_DESCR(src), PyArray_DESCR(dst), |
| 2679 | 0, |
| 2680 | &cast_info, &needs_api) != NPY_SUCCEED1) { |
| 2681 | NpyIter_Deallocate(dst_iter); |
| 2682 | NpyIter_Deallocate(src_iter); |
| 2683 | return -1; |
| 2684 | } |
| 2685 | |
| 2686 | if (!needs_api) { |
| 2687 | NPY_BEGIN_THREADSdo {_save = PyEval_SaveThread();} while (0);; |
| 2688 | } |
| 2689 | |
| 2690 | dst_count = *dst_countptr; |
| 2691 | src_count = *src_countptr; |
| 2692 | char *args[2] = {src_dataptr[0], dst_dataptr[0]}; |
| 2693 | npy_intp strides[2] = {src_stride, dst_stride}; |
| 2694 | |
| 2695 | int res = 0; |
| 2696 | for(;;) { |
| 2697 | /* Transfer the biggest amount that fits both */ |
| 2698 | count = (src_count < dst_count) ? src_count : dst_count; |
| 2699 | if (cast_info.func(&cast_info.context, |
| 2700 | args, &count, strides, cast_info.auxdata) < 0) { |
| 2701 | res = -1; |
| 2702 | break; |
| 2703 | } |
| 2704 | |
| 2705 | /* If we exhausted the dst block, refresh it */ |
| 2706 | if (dst_count == count) { |
| 2707 | res = dst_iternext(dst_iter); |
| 2708 | if (!res) { |
| 2709 | break; |
| 2710 | } |
| 2711 | dst_count = *dst_countptr; |
| 2712 | args[1] = dst_dataptr[0]; |
| 2713 | } |
| 2714 | else { |
| 2715 | dst_count -= count; |
| 2716 | args[1] += count*dst_stride; |
| 2717 | } |
| 2718 | |
| 2719 | /* If we exhausted the src block, refresh it */ |
| 2720 | if (src_count == count) { |
| 2721 | res = src_iternext(src_iter); |
| 2722 | if (!res) { |
| 2723 | break; |
| 2724 | } |
| 2725 | src_count = *src_countptr; |
| 2726 | args[0] = src_dataptr[0]; |
| 2727 | } |
| 2728 | else { |
| 2729 | src_count -= count; |
| 2730 | args[0] += count*src_stride; |
| 2731 | } |
| 2732 | } |
| 2733 | |
| 2734 | NPY_END_THREADSdo { if (_save) { PyEval_RestoreThread(_save); _save = ((void *)0);} } while (0);; |
| 2735 | |
| 2736 | NPY_cast_info_xfree(&cast_info); |
| 2737 | NpyIter_Deallocate(dst_iter); |
| 2738 | NpyIter_Deallocate(src_iter); |
| 2739 | if (res > 0) { |
| 2740 | /* The iteration stopped successfully, do not report an error */ |
| 2741 | return 0; |
| 2742 | } |
| 2743 | return res; |
| 2744 | } |
| 2745 | |
| 2746 | /*NUMPY_API |
| 2747 | * Copy an Array into another array -- memory must not overlap |
| 2748 | * Does not require src and dest to have "broadcastable" shapes |
| 2749 | * (only the same number of elements). |
| 2750 | * |
| 2751 | * TODO: For NumPy 2.0, this could accept an order parameter which |
| 2752 | * only allows NPY_CORDER and NPY_FORDER. Could also rename |
| 2753 | * this to CopyAsFlat to make the name more intuitive. |
| 2754 | * |
| 2755 | * Returns 0 on success, -1 on error. |
| 2756 | */ |
| 2757 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) int |
| 2758 | PyArray_CopyAnyInto(PyArrayObject *dst, PyArrayObject *src) |
| 2759 | { |
| 2760 | return PyArray_CopyAsFlat(dst, src, NPY_CORDER); |
| 2761 | } |
| 2762 | |
| 2763 | /*NUMPY_API |
| 2764 | * Copy an Array into another array. |
| 2765 | * Broadcast to the destination shape if necessary. |
| 2766 | * |
| 2767 | * Returns 0 on success, -1 on failure. |
| 2768 | */ |
| 2769 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) int |
| 2770 | PyArray_CopyInto(PyArrayObject *dst, PyArrayObject *src) |
| 2771 | { |
| 2772 | return PyArray_AssignArray(dst, src, NULL((void*)0), NPY_UNSAFE_CASTING); |
| 2773 | } |
| 2774 | |
| 2775 | /*NUMPY_API |
| 2776 | * Move the memory of one array into another, allowing for overlapping data. |
| 2777 | * |
| 2778 | * Returns 0 on success, negative on failure. |
| 2779 | */ |
| 2780 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) int |
| 2781 | PyArray_MoveInto(PyArrayObject *dst, PyArrayObject *src) |
| 2782 | { |
| 2783 | return PyArray_AssignArray(dst, src, NULL((void*)0), NPY_UNSAFE_CASTING); |
| 2784 | } |
| 2785 | |
| 2786 | /*NUMPY_API |
| 2787 | * PyArray_CheckAxis |
| 2788 | * |
| 2789 | * check that axis is valid |
| 2790 | * convert 0-d arrays to 1-d arrays |
| 2791 | */ |
| 2792 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 2793 | PyArray_CheckAxis(PyArrayObject *arr, int *axis, int flags) |
| 2794 | { |
| 2795 | PyObject *temp1, *temp2; |
| 2796 | int n = PyArray_NDIM(arr); |
| 2797 | |
| 2798 | if (*axis == NPY_MAXDIMS32 || n == 0) { |
| 2799 | if (n != 1) { |
| 2800 | temp1 = PyArray_Ravel(arr,0); |
| 2801 | if (temp1 == NULL((void*)0)) { |
| 2802 | *axis = 0; |
| 2803 | return NULL((void*)0); |
| 2804 | } |
| 2805 | if (*axis == NPY_MAXDIMS32) { |
| 2806 | *axis = PyArray_NDIM((PyArrayObject *)temp1)-1; |
| 2807 | } |
| 2808 | } |
| 2809 | else { |
| 2810 | temp1 = (PyObject *)arr; |
| 2811 | Py_INCREF(temp1)_Py_INCREF(((PyObject*)(temp1))); |
| 2812 | *axis = 0; |
| 2813 | } |
| 2814 | if (!flags && *axis == 0) { |
| 2815 | return temp1; |
| 2816 | } |
| 2817 | } |
| 2818 | else { |
| 2819 | temp1 = (PyObject *)arr; |
| 2820 | Py_INCREF(temp1)_Py_INCREF(((PyObject*)(temp1))); |
| 2821 | } |
| 2822 | if (flags) { |
| 2823 | temp2 = PyArray_CheckFromAny((PyObject *)temp1, NULL((void*)0), |
| 2824 | 0, 0, flags, NULL((void*)0)); |
| 2825 | Py_DECREF(temp1)_Py_DECREF(((PyObject*)(temp1))); |
| 2826 | if (temp2 == NULL((void*)0)) { |
| 2827 | return NULL((void*)0); |
| 2828 | } |
| 2829 | } |
| 2830 | else { |
| 2831 | temp2 = (PyObject *)temp1; |
| 2832 | } |
| 2833 | n = PyArray_NDIM((PyArrayObject *)temp2); |
| 2834 | if (check_and_adjust_axis(axis, n) < 0) { |
| 2835 | Py_DECREF(temp2)_Py_DECREF(((PyObject*)(temp2))); |
| 2836 | return NULL((void*)0); |
| 2837 | } |
| 2838 | return temp2; |
| 2839 | } |
| 2840 | |
| 2841 | /*NUMPY_API |
| 2842 | * Zeros |
| 2843 | * |
| 2844 | * steals a reference to type. On failure or when dtype->subarray is |
| 2845 | * true, dtype will be decrefed. |
| 2846 | * accepts NULL type |
| 2847 | */ |
| 2848 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 2849 | PyArray_Zeros(int nd, npy_intp const *dims, PyArray_Descr *type, int is_f_order) |
| 2850 | { |
| 2851 | PyArrayObject *ret; |
| 2852 | |
| 2853 | if (!type) { |
| 2854 | type = PyArray_DescrFromType(NPY_DEFAULT_TYPENPY_DOUBLE); |
| 2855 | } |
| 2856 | |
| 2857 | ret = (PyArrayObject *)PyArray_NewFromDescr_int( |
| 2858 | &PyArray_Type, type, |
| 2859 | nd, dims, NULL((void*)0), NULL((void*)0), |
| 2860 | is_f_order, NULL((void*)0), NULL((void*)0), |
| 2861 | 1, 0); |
| 2862 | |
| 2863 | if (ret == NULL((void*)0)) { |
| 2864 | return NULL((void*)0); |
| 2865 | } |
| 2866 | |
| 2867 | /* handle objects */ |
| 2868 | if (PyDataType_REFCHK(PyArray_DESCR(ret))(((PyArray_DESCR(ret))->flags & (0x01)) == (0x01))) { |
| 2869 | if (_zerofill(ret) < 0) { |
| 2870 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); |
| 2871 | return NULL((void*)0); |
| 2872 | } |
| 2873 | } |
| 2874 | |
| 2875 | |
| 2876 | return (PyObject *)ret; |
| 2877 | |
| 2878 | } |
| 2879 | |
| 2880 | /*NUMPY_API |
| 2881 | * Empty |
| 2882 | * |
| 2883 | * accepts NULL type |
| 2884 | * steals a reference to type |
| 2885 | */ |
| 2886 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 2887 | PyArray_Empty(int nd, npy_intp const *dims, PyArray_Descr *type, int is_f_order) |
| 2888 | { |
| 2889 | PyArrayObject *ret; |
| 2890 | |
| 2891 | if (!type) type = PyArray_DescrFromType(NPY_DEFAULT_TYPENPY_DOUBLE); |
| 2892 | |
| 2893 | /* |
| 2894 | * PyArray_NewFromDescr steals a ref, |
| 2895 | * but we need to look at type later. |
| 2896 | * */ |
| 2897 | Py_INCREF(type)_Py_INCREF(((PyObject*)(type))); |
| 2898 | |
| 2899 | ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, |
| 2900 | type, nd, dims, |
| 2901 | NULL((void*)0), NULL((void*)0), |
| 2902 | is_f_order, NULL((void*)0)); |
| 2903 | if (ret != NULL((void*)0) && PyDataType_REFCHK(type)(((type)->flags & (0x01)) == (0x01))) { |
| 2904 | PyArray_FillObjectArray(ret, Py_None(&_Py_NoneStruct)); |
| 2905 | if (PyErr_Occurred()) { |
| 2906 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); |
| 2907 | Py_DECREF(type)_Py_DECREF(((PyObject*)(type))); |
| 2908 | return NULL((void*)0); |
| 2909 | } |
| 2910 | } |
| 2911 | |
| 2912 | Py_DECREF(type)_Py_DECREF(((PyObject*)(type))); |
| 2913 | return (PyObject *)ret; |
| 2914 | } |
| 2915 | |
| 2916 | /* |
| 2917 | * Like ceil(value), but check for overflow. |
| 2918 | * |
| 2919 | * Return 0 on success, -1 on failure. In case of failure, set a PyExc_Overflow |
| 2920 | * exception |
| 2921 | */ |
| 2922 | static npy_intp |
| 2923 | _arange_safe_ceil_to_intp(double value) |
| 2924 | { |
| 2925 | double ivalue; |
| 2926 | |
| 2927 | ivalue = npy_ceil(value); |
| 2928 | /* condition inverted to handle NaN */ |
| 2929 | if (npy_isnan(ivalue)) { |
| 2930 | PyErr_SetString(PyExc_ValueError, |
| 2931 | "arange: cannot compute length"); |
| 2932 | return -1; |
| 2933 | } |
| 2934 | if (!((double)NPY_MIN_INTP(-9223372036854775807L -1L) <= ivalue && ivalue <= (double)NPY_MAX_INTP9223372036854775807L)) { |
| 2935 | PyErr_SetString(PyExc_OverflowError, |
| 2936 | "arange: overflow while computing length"); |
| 2937 | return -1; |
| 2938 | } |
| 2939 | |
| 2940 | return (npy_intp)ivalue; |
| 2941 | } |
| 2942 | |
| 2943 | |
| 2944 | /*NUMPY_API |
| 2945 | Arange, |
| 2946 | */ |
| 2947 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 2948 | PyArray_Arange(double start, double stop, double step, int type_num) |
| 2949 | { |
| 2950 | npy_intp length; |
| 2951 | PyArrayObject *range; |
| 2952 | PyArray_ArrFuncs *funcs; |
| 2953 | PyObject *obj; |
| 2954 | int ret; |
| 2955 | double delta, tmp_len; |
| 2956 | NPY_BEGIN_THREADS_DEFPyThreadState *_save=((void*)0);; |
| 2957 | |
| 2958 | delta = stop - start; |
| 2959 | tmp_len = delta/step; |
| 2960 | |
| 2961 | /* Underflow and divide-by-inf check */ |
| 2962 | if (tmp_len == 0.0 && delta != 0.0) { |
| 2963 | if (npy_signbit(tmp_len)) { |
| 2964 | length = 0; |
| 2965 | } |
| 2966 | else { |
| 2967 | length = 1; |
| 2968 | } |
| 2969 | } |
| 2970 | else { |
| 2971 | length = _arange_safe_ceil_to_intp(tmp_len); |
| 2972 | if (error_converting(length)(((length) == -1) && PyErr_Occurred())) { |
| 2973 | return NULL((void*)0); |
| 2974 | } |
| 2975 | } |
| 2976 | |
| 2977 | if (length <= 0) { |
| 2978 | length = 0; |
| 2979 | return PyArray_New(&PyArray_Type, 1, &length, type_num, |
| 2980 | NULL((void*)0), NULL((void*)0), 0, 0, NULL((void*)0)); |
| 2981 | } |
| 2982 | range = (PyArrayObject *)PyArray_New(&PyArray_Type, 1, &length, type_num, |
| 2983 | NULL((void*)0), NULL((void*)0), 0, 0, NULL((void*)0)); |
| 2984 | if (range == NULL((void*)0)) { |
| 2985 | return NULL((void*)0); |
| 2986 | } |
| 2987 | funcs = PyArray_DESCR(range)->f; |
| 2988 | |
| 2989 | /* |
| 2990 | * place start in the buffer and the next value in the second position |
| 2991 | * if length > 2, then call the inner loop, otherwise stop |
| 2992 | */ |
| 2993 | obj = PyFloat_FromDouble(start); |
| 2994 | ret = funcs->setitem(obj, PyArray_DATA(range), range); |
| 2995 | Py_DECREF(obj)_Py_DECREF(((PyObject*)(obj))); |
| 2996 | if (ret < 0) { |
| 2997 | goto fail; |
| 2998 | } |
| 2999 | if (length == 1) { |
| 3000 | return (PyObject *)range; |
| 3001 | } |
| 3002 | obj = PyFloat_FromDouble(start + step); |
| 3003 | ret = funcs->setitem(obj, PyArray_BYTES(range)+PyArray_ITEMSIZE(range), |
| 3004 | range); |
| 3005 | Py_DECREF(obj)_Py_DECREF(((PyObject*)(obj))); |
| 3006 | if (ret < 0) { |
| 3007 | goto fail; |
| 3008 | } |
| 3009 | if (length == 2) { |
| 3010 | return (PyObject *)range; |
| 3011 | } |
| 3012 | if (!funcs->fill) { |
| 3013 | PyErr_SetString(PyExc_ValueError, |
| 3014 | "no fill-function for data-type."); |
| 3015 | Py_DECREF(range)_Py_DECREF(((PyObject*)(range))); |
| 3016 | return NULL((void*)0); |
| 3017 | } |
| 3018 | NPY_BEGIN_THREADS_DESCR(PyArray_DESCR(range))do {if (!(((((PyArray_DESCR(range)))->flags & (0x10)) == (0x10)))) do {_save = PyEval_SaveThread();} while (0);;} while (0);; |
| 3019 | funcs->fill(PyArray_DATA(range), length, range); |
| 3020 | NPY_END_THREADSdo { if (_save) { PyEval_RestoreThread(_save); _save = ((void *)0);} } while (0);; |
| 3021 | if (PyErr_Occurred()) { |
| 3022 | goto fail; |
| 3023 | } |
| 3024 | return (PyObject *)range; |
| 3025 | |
| 3026 | fail: |
| 3027 | Py_DECREF(range)_Py_DECREF(((PyObject*)(range))); |
| 3028 | return NULL((void*)0); |
| 3029 | } |
| 3030 | |
| 3031 | /* |
| 3032 | * the formula is len = (intp) ceil((stop - start) / step); |
| 3033 | */ |
| 3034 | static npy_intp |
| 3035 | _calc_length(PyObject *start, PyObject *stop, PyObject *step, PyObject **next, int cmplx) |
| 3036 | { |
| 3037 | npy_intp len, tmp; |
| 3038 | PyObject *zero, *val; |
| 3039 | int next_is_nonzero, val_is_zero; |
| 3040 | double value; |
| 3041 | |
| 3042 | *next = PyNumber_Subtract(stop, start); |
| 3043 | if (!(*next)) { |
| 3044 | if (PyTuple_Check(stop)((((((PyObject*)(stop))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { |
| 3045 | PyErr_Clear(); |
| 3046 | PyErr_SetString(PyExc_TypeError, |
| 3047 | "arange: scalar arguments expected "\ |
| 3048 | "instead of a tuple."); |
| 3049 | } |
| 3050 | return -1; |
| 3051 | } |
| 3052 | |
| 3053 | zero = PyLong_FromLong(0); |
| 3054 | if (!zero) { |
| 3055 | Py_DECREF(*next)_Py_DECREF(((PyObject*)(*next))); |
| 3056 | *next = NULL((void*)0); |
| 3057 | return -1; |
| 3058 | } |
| 3059 | |
| 3060 | next_is_nonzero = PyObject_RichCompareBool(*next, zero, Py_NE3); |
| 3061 | if (next_is_nonzero == -1) { |
| 3062 | Py_DECREF(zero)_Py_DECREF(((PyObject*)(zero))); |
| 3063 | Py_DECREF(*next)_Py_DECREF(((PyObject*)(*next))); |
| 3064 | *next = NULL((void*)0); |
| 3065 | return -1; |
| 3066 | } |
| 3067 | val = PyNumber_TrueDivide(*next, step); |
| 3068 | Py_DECREF(*next)_Py_DECREF(((PyObject*)(*next))); |
| 3069 | *next = NULL((void*)0); |
| 3070 | |
| 3071 | if (!val) { |
| 3072 | Py_DECREF(zero)_Py_DECREF(((PyObject*)(zero))); |
| 3073 | return -1; |
| 3074 | } |
| 3075 | |
| 3076 | val_is_zero = PyObject_RichCompareBool(val, zero, Py_EQ2); |
| 3077 | Py_DECREF(zero)_Py_DECREF(((PyObject*)(zero))); |
| 3078 | if (val_is_zero == -1) { |
| 3079 | Py_DECREF(val)_Py_DECREF(((PyObject*)(val))); |
| 3080 | return -1; |
| 3081 | } |
| 3082 | |
| 3083 | if (cmplx && PyComplex_Check(val)((((PyObject*)(val))->ob_type) == (&PyComplex_Type) || PyType_IsSubtype((((PyObject*)(val))->ob_type), (&PyComplex_Type )))) { |
| 3084 | value = PyComplex_RealAsDouble(val); |
| 3085 | if (error_converting(value)(((value) == -1) && PyErr_Occurred())) { |
| 3086 | Py_DECREF(val)_Py_DECREF(((PyObject*)(val))); |
| 3087 | return -1; |
| 3088 | } |
| 3089 | len = _arange_safe_ceil_to_intp(value); |
| 3090 | if (error_converting(len)(((len) == -1) && PyErr_Occurred())) { |
| 3091 | Py_DECREF(val)_Py_DECREF(((PyObject*)(val))); |
| 3092 | return -1; |
| 3093 | } |
| 3094 | value = PyComplex_ImagAsDouble(val); |
| 3095 | Py_DECREF(val)_Py_DECREF(((PyObject*)(val))); |
| 3096 | if (error_converting(value)(((value) == -1) && PyErr_Occurred())) { |
| 3097 | return -1; |
| 3098 | } |
| 3099 | tmp = _arange_safe_ceil_to_intp(value); |
| 3100 | if (error_converting(tmp)(((tmp) == -1) && PyErr_Occurred())) { |
| 3101 | return -1; |
| 3102 | } |
| 3103 | len = PyArray_MIN(len, tmp)(((len)<(tmp))?(len):(tmp)); |
| 3104 | } |
| 3105 | else { |
| 3106 | value = PyFloat_AsDouble(val); |
| 3107 | Py_DECREF(val)_Py_DECREF(((PyObject*)(val))); |
| 3108 | if (error_converting(value)(((value) == -1) && PyErr_Occurred())) { |
| 3109 | return -1; |
| 3110 | } |
| 3111 | |
| 3112 | /* Underflow and divide-by-inf check */ |
| 3113 | if (val_is_zero && next_is_nonzero) { |
| 3114 | if (npy_signbit(value)) { |
| 3115 | len = 0; |
| 3116 | } |
| 3117 | else { |
| 3118 | len = 1; |
| 3119 | } |
| 3120 | } |
| 3121 | else { |
| 3122 | len = _arange_safe_ceil_to_intp(value); |
| 3123 | if (error_converting(len)(((len) == -1) && PyErr_Occurred())) { |
| 3124 | return -1; |
| 3125 | } |
| 3126 | } |
| 3127 | } |
| 3128 | |
| 3129 | if (len > 0) { |
| 3130 | *next = PyNumber_Add(start, step); |
| 3131 | if (!*next) { |
| 3132 | return -1; |
| 3133 | } |
| 3134 | } |
| 3135 | return len; |
| 3136 | } |
| 3137 | |
| 3138 | /*NUMPY_API |
| 3139 | * |
| 3140 | * ArangeObj, |
| 3141 | * |
| 3142 | * this doesn't change the references |
| 3143 | */ |
| 3144 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 3145 | PyArray_ArangeObj(PyObject *start, PyObject *stop, PyObject *step, PyArray_Descr *dtype) |
| 3146 | { |
| 3147 | PyArrayObject *range; |
| 3148 | PyArray_ArrFuncs *funcs; |
| 3149 | PyObject *next, *err; |
| 3150 | npy_intp length; |
| 3151 | PyArray_Descr *native = NULL((void*)0); |
| 3152 | int swap; |
| 3153 | NPY_BEGIN_THREADS_DEFPyThreadState *_save=((void*)0);; |
| 3154 | |
| 3155 | /* Datetime arange is handled specially */ |
| 3156 | if ((dtype != NULL((void*)0) && (dtype->type_num == NPY_DATETIME || |
| 3157 | dtype->type_num == NPY_TIMEDELTA)) || |
| 3158 | (dtype == NULL((void*)0) && (is_any_numpy_datetime_or_timedelta(start) || |
| 3159 | is_any_numpy_datetime_or_timedelta(stop) || |
| 3160 | is_any_numpy_datetime_or_timedelta(step)))) { |
| 3161 | return (PyObject *)datetime_arange(start, stop, step, dtype); |
| 3162 | } |
| 3163 | |
| 3164 | if (!dtype) { |
| 3165 | PyArray_Descr *deftype; |
| 3166 | PyArray_Descr *newtype; |
| 3167 | |
| 3168 | /* intentionally made to be at least NPY_LONG */ |
| 3169 | deftype = PyArray_DescrFromType(NPY_LONG); |
| 3170 | newtype = PyArray_DescrFromObject(start, deftype); |
| 3171 | Py_DECREF(deftype)_Py_DECREF(((PyObject*)(deftype))); |
| 3172 | if (newtype == NULL((void*)0)) { |
| 3173 | return NULL((void*)0); |
| 3174 | } |
| 3175 | deftype = newtype; |
| 3176 | if (stop && stop != Py_None(&_Py_NoneStruct)) { |
| 3177 | newtype = PyArray_DescrFromObject(stop, deftype); |
| 3178 | Py_DECREF(deftype)_Py_DECREF(((PyObject*)(deftype))); |
| 3179 | if (newtype == NULL((void*)0)) { |
| 3180 | return NULL((void*)0); |
| 3181 | } |
| 3182 | deftype = newtype; |
| 3183 | } |
| 3184 | if (step && step != Py_None(&_Py_NoneStruct)) { |
| 3185 | newtype = PyArray_DescrFromObject(step, deftype); |
| 3186 | Py_DECREF(deftype)_Py_DECREF(((PyObject*)(deftype))); |
| 3187 | if (newtype == NULL((void*)0)) { |
| 3188 | return NULL((void*)0); |
| 3189 | } |
| 3190 | deftype = newtype; |
| 3191 | } |
| 3192 | dtype = deftype; |
| 3193 | } |
| 3194 | else { |
| 3195 | Py_INCREF(dtype)_Py_INCREF(((PyObject*)(dtype))); |
| 3196 | } |
| 3197 | if (!step || step == Py_None(&_Py_NoneStruct)) { |
| 3198 | step = PyLong_FromLong(1); |
| 3199 | } |
| 3200 | else { |
| 3201 | Py_XINCREF(step)_Py_XINCREF(((PyObject*)(step))); |
| 3202 | } |
| 3203 | if (!stop || stop == Py_None(&_Py_NoneStruct)) { |
| 3204 | stop = start; |
| 3205 | start = PyLong_FromLong(0); |
| 3206 | } |
| 3207 | else { |
| 3208 | Py_INCREF(start)_Py_INCREF(((PyObject*)(start))); |
| 3209 | } |
| 3210 | /* calculate the length and next = start + step*/ |
| 3211 | length = _calc_length(start, stop, step, &next, |
| 3212 | PyTypeNum_ISCOMPLEX(dtype->type_num)(((dtype->type_num) >= NPY_CFLOAT) && ((dtype-> type_num) <= NPY_CLONGDOUBLE))); |
| 3213 | err = PyErr_Occurred(); |
| 3214 | if (err) { |
| 3215 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 3216 | if (err && PyErr_GivenExceptionMatches(err, PyExc_OverflowError)) { |
| 3217 | PyErr_SetString(PyExc_ValueError, "Maximum allowed size exceeded"); |
| 3218 | } |
| 3219 | goto fail; |
| 3220 | } |
| 3221 | if (length <= 0) { |
| 3222 | length = 0; |
| 3223 | range = (PyArrayObject *)PyArray_SimpleNewFromDescr(1, &length, dtype)PyArray_NewFromDescr(&PyArray_Type, dtype, 1, &length , ((void*)0), ((void*)0), 0, ((void*)0)); |
| 3224 | Py_DECREF(step)_Py_DECREF(((PyObject*)(step))); |
| 3225 | Py_DECREF(start)_Py_DECREF(((PyObject*)(start))); |
| 3226 | return (PyObject *)range; |
| 3227 | } |
| 3228 | |
| 3229 | /* |
| 3230 | * If dtype is not in native byte-order then get native-byte |
| 3231 | * order version. And then swap on the way out. |
| 3232 | */ |
| 3233 | if (!PyArray_ISNBO(dtype->byteorder)((dtype->byteorder) != '>')) { |
| 3234 | native = PyArray_DescrNewByteorder(dtype, NPY_NATBYTE'<'); |
| 3235 | swap = 1; |
| 3236 | } |
| 3237 | else { |
| 3238 | native = dtype; |
| 3239 | swap = 0; |
| 3240 | } |
| 3241 | |
| 3242 | range = (PyArrayObject *)PyArray_SimpleNewFromDescr(1, &length, native)PyArray_NewFromDescr(&PyArray_Type, native, 1, &length , ((void*)0), ((void*)0), 0, ((void*)0)); |
| 3243 | if (range == NULL((void*)0)) { |
| 3244 | goto fail; |
| 3245 | } |
| 3246 | |
| 3247 | /* |
| 3248 | * place start in the buffer and the next value in the second position |
| 3249 | * if length > 2, then call the inner loop, otherwise stop |
| 3250 | */ |
| 3251 | funcs = PyArray_DESCR(range)->f; |
| 3252 | if (funcs->setitem(start, PyArray_DATA(range), range) < 0) { |
| 3253 | goto fail; |
| 3254 | } |
| 3255 | if (length == 1) { |
| 3256 | goto finish; |
| 3257 | } |
| 3258 | if (funcs->setitem(next, PyArray_BYTES(range)+PyArray_ITEMSIZE(range), |
| 3259 | range) < 0) { |
| 3260 | goto fail; |
| 3261 | } |
| 3262 | if (length == 2) { |
| 3263 | goto finish; |
| 3264 | } |
| 3265 | if (!funcs->fill) { |
| 3266 | PyErr_SetString(PyExc_ValueError, "no fill-function for data-type."); |
| 3267 | Py_DECREF(range)_Py_DECREF(((PyObject*)(range))); |
| 3268 | goto fail; |
| 3269 | } |
| 3270 | NPY_BEGIN_THREADS_DESCR(PyArray_DESCR(range))do {if (!(((((PyArray_DESCR(range)))->flags & (0x10)) == (0x10)))) do {_save = PyEval_SaveThread();} while (0);;} while (0);; |
| 3271 | funcs->fill(PyArray_DATA(range), length, range); |
| 3272 | NPY_END_THREADSdo { if (_save) { PyEval_RestoreThread(_save); _save = ((void *)0);} } while (0);; |
| 3273 | if (PyErr_Occurred()) { |
| 3274 | goto fail; |
| 3275 | } |
| 3276 | finish: |
| 3277 | /* TODO: This swapping could be handled on the fly by the nditer */ |
| 3278 | if (swap) { |
| 3279 | PyObject *new; |
| 3280 | new = PyArray_Byteswap(range, 1); |
| 3281 | Py_DECREF(new)_Py_DECREF(((PyObject*)(new))); |
| 3282 | Py_DECREF(PyArray_DESCR(range))_Py_DECREF(((PyObject*)(PyArray_DESCR(range)))); |
| 3283 | /* steals the reference */ |
| 3284 | ((PyArrayObject_fields *)range)->descr = dtype; |
| 3285 | } |
| 3286 | Py_DECREF(start)_Py_DECREF(((PyObject*)(start))); |
| 3287 | Py_DECREF(step)_Py_DECREF(((PyObject*)(step))); |
| 3288 | Py_DECREF(next)_Py_DECREF(((PyObject*)(next))); |
| 3289 | return (PyObject *)range; |
| 3290 | |
| 3291 | fail: |
| 3292 | Py_DECREF(start)_Py_DECREF(((PyObject*)(start))); |
| 3293 | Py_DECREF(step)_Py_DECREF(((PyObject*)(step))); |
| 3294 | Py_XDECREF(next)_Py_XDECREF(((PyObject*)(next))); |
| 3295 | return NULL((void*)0); |
| 3296 | } |
| 3297 | |
| 3298 | /* This array creation function does not steal the reference to dtype. */ |
| 3299 | static PyArrayObject * |
| 3300 | array_fromfile_binary(FILE *fp, PyArray_Descr *dtype, npy_intp num, size_t *nread) |
| 3301 | { |
| 3302 | PyArrayObject *r; |
| 3303 | npy_off_toff_t start, numbytes; |
| 3304 | int elsize; |
| 3305 | |
| 3306 | if (num < 0) { |
| 3307 | int fail = 0; |
| 3308 | start = npy_ftellftello(fp); |
| 3309 | if (start < 0) { |
| 3310 | fail = 1; |
| 3311 | } |
| 3312 | if (npy_fseekfseeko(fp, 0, SEEK_END2) < 0) { |
| 3313 | fail = 1; |
| 3314 | } |
| 3315 | numbytes = npy_ftellftello(fp); |
| 3316 | if (numbytes < 0) { |
| 3317 | fail = 1; |
| 3318 | } |
| 3319 | numbytes -= start; |
| 3320 | if (npy_fseekfseeko(fp, start, SEEK_SET0) < 0) { |
| 3321 | fail = 1; |
| 3322 | } |
| 3323 | if (fail) { |
| 3324 | PyErr_SetString(PyExc_IOError, |
| 3325 | "could not seek in file"); |
| 3326 | return NULL((void*)0); |
| 3327 | } |
| 3328 | num = numbytes / dtype->elsize; |
| 3329 | } |
| 3330 | |
| 3331 | /* |
| 3332 | * Array creation may move sub-array dimensions from the dtype to array |
| 3333 | * dimensions, so we need to use the original element size when reading. |
| 3334 | */ |
| 3335 | elsize = dtype->elsize; |
| 3336 | |
| 3337 | Py_INCREF(dtype)_Py_INCREF(((PyObject*)(dtype))); /* do not steal the original dtype. */ |
| 3338 | r = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, dtype, 1, &num, |
| 3339 | NULL((void*)0), NULL((void*)0), 0, NULL((void*)0)); |
| 3340 | if (r == NULL((void*)0)) { |
| 3341 | return NULL((void*)0); |
| 3342 | } |
| 3343 | |
| 3344 | NPY_BEGIN_ALLOW_THREADS{ PyThreadState *_save; _save = PyEval_SaveThread();; |
| 3345 | *nread = fread(PyArray_DATA(r), elsize, num, fp); |
| 3346 | NPY_END_ALLOW_THREADSPyEval_RestoreThread(_save); }; |
| 3347 | return r; |
| 3348 | } |
| 3349 | |
| 3350 | /* |
| 3351 | * Create an array by reading from the given stream, using the passed |
| 3352 | * next_element and skip_separator functions. |
| 3353 | * Does not steal the reference to dtype. |
| 3354 | */ |
| 3355 | #define FROM_BUFFER_SIZE 4096 |
| 3356 | static PyArrayObject * |
| 3357 | array_from_text(PyArray_Descr *dtype, npy_intp num, char const *sep, size_t *nread, |
| 3358 | void *stream, next_element next, skip_separator skip_sep, |
| 3359 | void *stream_data) |
| 3360 | { |
| 3361 | PyArrayObject *r; |
| 3362 | npy_intp i; |
| 3363 | char *dptr, *clean_sep, *tmp; |
| 3364 | int err = 0; |
| 3365 | int stop_reading_flag = 0; /* -1 means end reached; -2 a parsing error */ |
| 3366 | npy_intp thisbuf = 0; |
| 3367 | npy_intp size; |
| 3368 | npy_intp bytes, totalbytes; |
| 3369 | |
| 3370 | size = (num >= 0) ? num : FROM_BUFFER_SIZE; |
| 3371 | |
| 3372 | /* |
| 3373 | * Array creation may move sub-array dimensions from the dtype to array |
| 3374 | * dimensions, so we need to use the original dtype when reading. |
| 3375 | */ |
| 3376 | Py_INCREF(dtype)_Py_INCREF(((PyObject*)(dtype))); |
| 3377 | |
| 3378 | r = (PyArrayObject *) |
| 3379 | PyArray_NewFromDescr(&PyArray_Type, dtype, 1, &size, |
| 3380 | NULL((void*)0), NULL((void*)0), 0, NULL((void*)0)); |
| 3381 | if (r == NULL((void*)0)) { |
| 3382 | return NULL((void*)0); |
| 3383 | } |
| 3384 | |
| 3385 | clean_sep = swab_separator(sep); |
| 3386 | if (clean_sep == NULL((void*)0)) { |
| 3387 | err = 1; |
| 3388 | goto fail; |
| 3389 | } |
| 3390 | |
| 3391 | NPY_BEGIN_ALLOW_THREADS{ PyThreadState *_save; _save = PyEval_SaveThread();; |
| 3392 | totalbytes = bytes = size * dtype->elsize; |
| 3393 | dptr = PyArray_DATA(r); |
| 3394 | for (i = 0; num < 0 || i < num; i++) { |
| 3395 | stop_reading_flag = next(&stream, dptr, dtype, stream_data); |
| 3396 | if (stop_reading_flag < 0) { |
| 3397 | break; |
| 3398 | } |
| 3399 | *nread += 1; |
| 3400 | thisbuf += 1; |
| 3401 | dptr += dtype->elsize; |
| 3402 | if (num < 0 && thisbuf == size) { |
| 3403 | totalbytes += bytes; |
| 3404 | tmp = PyDataMem_RENEW(PyArray_DATA(r), totalbytes); |
| 3405 | if (tmp == NULL((void*)0)) { |
| 3406 | err = 1; |
| 3407 | break; |
| 3408 | } |
| 3409 | ((PyArrayObject_fields *)r)->data = tmp; |
| 3410 | dptr = tmp + (totalbytes - bytes); |
| 3411 | thisbuf = 0; |
| 3412 | } |
| 3413 | stop_reading_flag = skip_sep(&stream, clean_sep, stream_data); |
| 3414 | if (stop_reading_flag < 0) { |
| 3415 | if (num == i + 1) { |
| 3416 | /* if we read as much as requested sep is optional */ |
| 3417 | stop_reading_flag = -1; |
| 3418 | } |
| 3419 | break; |
| 3420 | } |
| 3421 | } |
| 3422 | if (num < 0) { |
| 3423 | const size_t nsize = PyArray_MAX(*nread,1)(((*nread)>(1))?(*nread):(1))*dtype->elsize; |
| 3424 | |
| 3425 | if (nsize != 0) { |
| 3426 | tmp = PyDataMem_RENEW(PyArray_DATA(r), nsize); |
| 3427 | if (tmp == NULL((void*)0)) { |
| 3428 | err = 1; |
| 3429 | } |
| 3430 | else { |
| 3431 | PyArray_DIMS(r)[0] = *nread; |
| 3432 | ((PyArrayObject_fields *)r)->data = tmp; |
| 3433 | } |
| 3434 | } |
| 3435 | } |
| 3436 | NPY_END_ALLOW_THREADSPyEval_RestoreThread(_save); }; |
| 3437 | |
| 3438 | free(clean_sep); |
| 3439 | |
| 3440 | if (stop_reading_flag == -2) { |
| 3441 | if (PyErr_Occurred()) { |
| 3442 | /* If an error is already set (unlikely), do not create new one */ |
| 3443 | Py_DECREF(r)_Py_DECREF(((PyObject*)(r))); |
| 3444 | return NULL((void*)0); |
| 3445 | } |
| 3446 | /* 2019-09-12, NumPy 1.18 */ |
| 3447 | if (DEPRECATE(PyErr_WarnEx(PyExc_DeprecationWarning,"string or file could not be read to its end due to unmatched " "data; this will raise a ValueError in the future.",1) |
| 3448 | "string or file could not be read to its end due to unmatched "PyErr_WarnEx(PyExc_DeprecationWarning,"string or file could not be read to its end due to unmatched " "data; this will raise a ValueError in the future.",1) |
| 3449 | "data; this will raise a ValueError in the future.")PyErr_WarnEx(PyExc_DeprecationWarning,"string or file could not be read to its end due to unmatched " "data; this will raise a ValueError in the future.",1) < 0) { |
| 3450 | goto fail; |
| 3451 | } |
| 3452 | } |
| 3453 | |
| 3454 | fail: |
| 3455 | if (err == 1) { |
| 3456 | PyErr_NoMemory(); |
| 3457 | } |
| 3458 | if (PyErr_Occurred()) { |
| 3459 | Py_DECREF(r)_Py_DECREF(((PyObject*)(r))); |
| 3460 | return NULL((void*)0); |
| 3461 | } |
| 3462 | return r; |
| 3463 | } |
| 3464 | #undef FROM_BUFFER_SIZE |
| 3465 | |
| 3466 | /*NUMPY_API |
| 3467 | * |
| 3468 | * Given a ``FILE *`` pointer ``fp``, and a ``PyArray_Descr``, return an |
| 3469 | * array corresponding to the data encoded in that file. |
| 3470 | * |
| 3471 | * The reference to `dtype` is stolen (it is possible that the passed in |
| 3472 | * dtype is not held on to). |
| 3473 | * |
| 3474 | * The number of elements to read is given as ``num``; if it is < 0, then |
| 3475 | * then as many as possible are read. |
| 3476 | * |
| 3477 | * If ``sep`` is NULL or empty, then binary data is assumed, else |
| 3478 | * text data, with ``sep`` as the separator between elements. Whitespace in |
| 3479 | * the separator matches any length of whitespace in the text, and a match |
| 3480 | * for whitespace around the separator is added. |
| 3481 | * |
| 3482 | * For memory-mapped files, use the buffer interface. No more data than |
| 3483 | * necessary is read by this routine. |
| 3484 | */ |
| 3485 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 3486 | PyArray_FromFile(FILE *fp, PyArray_Descr *dtype, npy_intp num, char *sep) |
| 3487 | { |
| 3488 | PyArrayObject *ret; |
| 3489 | size_t nread = 0; |
| 3490 | |
| 3491 | if (PyDataType_REFCHK(dtype)(((dtype)->flags & (0x01)) == (0x01))) { |
| 3492 | PyErr_SetString(PyExc_ValueError, |
| 3493 | "Cannot read into object array"); |
| 3494 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 3495 | return NULL((void*)0); |
| 3496 | } |
| 3497 | if (dtype->elsize == 0) { |
| 3498 | /* Nothing to read, just create an empty array of the requested type */ |
| 3499 | return PyArray_NewFromDescr_int( |
| 3500 | &PyArray_Type, dtype, |
| 3501 | 1, &num, NULL((void*)0), NULL((void*)0), |
| 3502 | 0, NULL((void*)0), NULL((void*)0), |
| 3503 | 0, 1); |
| 3504 | } |
| 3505 | if ((sep == NULL((void*)0)) || (strlen(sep) == 0)) { |
| 3506 | ret = array_fromfile_binary(fp, dtype, num, &nread); |
| 3507 | } |
| 3508 | else { |
| 3509 | if (dtype->f->scanfunc == NULL((void*)0)) { |
| 3510 | PyErr_SetString(PyExc_ValueError, |
| 3511 | "Unable to read character files of that array type"); |
| 3512 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 3513 | return NULL((void*)0); |
| 3514 | } |
| 3515 | ret = array_from_text(dtype, num, sep, &nread, fp, |
| 3516 | (next_element) fromfile_next_element, |
| 3517 | (skip_separator) fromfile_skip_separator, NULL((void*)0)); |
| 3518 | } |
| 3519 | if (ret == NULL((void*)0)) { |
| 3520 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 3521 | return NULL((void*)0); |
| 3522 | } |
| 3523 | if (((npy_intp) nread) < num) { |
| 3524 | /* |
| 3525 | * Realloc memory for smaller number of elements, use original dtype |
| 3526 | * which may have include a subarray (and is used for `nread`). |
| 3527 | */ |
| 3528 | const size_t nsize = PyArray_MAX(nread,1)(((nread)>(1))?(nread):(1)) * dtype->elsize; |
| 3529 | char *tmp; |
| 3530 | |
| 3531 | if ((tmp = PyDataMem_RENEW(PyArray_DATA(ret), nsize)) == NULL((void*)0)) { |
| 3532 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 3533 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); |
| 3534 | return PyErr_NoMemory(); |
| 3535 | } |
| 3536 | ((PyArrayObject_fields *)ret)->data = tmp; |
| 3537 | PyArray_DIMS(ret)[0] = nread; |
| 3538 | } |
| 3539 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 3540 | return (PyObject *)ret; |
| 3541 | } |
| 3542 | |
| 3543 | /*NUMPY_API*/ |
| 3544 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 3545 | PyArray_FromBuffer(PyObject *buf, PyArray_Descr *type, |
| 3546 | npy_intp count, npy_intp offset) |
| 3547 | { |
| 3548 | PyArrayObject *ret; |
| 3549 | char *data; |
| 3550 | Py_buffer view; |
| 3551 | Py_ssize_t ts; |
| 3552 | npy_intp s, n; |
| 3553 | int itemsize; |
| 3554 | int writeable = 1; |
| 3555 | |
| 3556 | |
| 3557 | if (PyDataType_REFCHK(type)(((type)->flags & (0x01)) == (0x01))) { |
| 3558 | PyErr_SetString(PyExc_ValueError, |
| 3559 | "cannot create an OBJECT array from memory"\ |
| 3560 | " buffer"); |
| 3561 | Py_DECREF(type)_Py_DECREF(((PyObject*)(type))); |
| 3562 | return NULL((void*)0); |
| 3563 | } |
| 3564 | if (PyDataType_ISUNSIZED(type)((type)->elsize == 0 && !(((PyArray_Descr *)(type) )->names != ((void*)0)))) { |
| 3565 | PyErr_SetString(PyExc_ValueError, |
| 3566 | "itemsize cannot be zero in type"); |
| 3567 | Py_DECREF(type)_Py_DECREF(((PyObject*)(type))); |
| 3568 | return NULL((void*)0); |
| 3569 | } |
| 3570 | |
| 3571 | if (PyObject_GetBuffer(buf, &view, PyBUF_WRITABLE0x0001|PyBUF_SIMPLE0) < 0) { |
| 3572 | writeable = 0; |
| 3573 | PyErr_Clear(); |
| 3574 | if (PyObject_GetBuffer(buf, &view, PyBUF_SIMPLE0) < 0) { |
| 3575 | Py_DECREF(type)_Py_DECREF(((PyObject*)(type))); |
| 3576 | return NULL((void*)0); |
| 3577 | } |
| 3578 | } |
| 3579 | data = (char *)view.buf; |
| 3580 | ts = view.len; |
| 3581 | /* |
| 3582 | * In Python 3 both of the deprecated functions PyObject_AsWriteBuffer and |
| 3583 | * PyObject_AsReadBuffer that this code replaces release the buffer. It is |
| 3584 | * up to the object that supplies the buffer to guarantee that the buffer |
| 3585 | * sticks around after the release. |
| 3586 | */ |
| 3587 | PyBuffer_Release(&view); |
| 3588 | |
| 3589 | if ((offset < 0) || (offset > ts)) { |
| 3590 | PyErr_Format(PyExc_ValueError, |
| 3591 | "offset must be non-negative and no greater than buffer "\ |
| 3592 | "length (%" NPY_INTP_FMT"ld" ")", (npy_intp)ts); |
| 3593 | Py_DECREF(type)_Py_DECREF(((PyObject*)(type))); |
| 3594 | return NULL((void*)0); |
| 3595 | } |
| 3596 | |
| 3597 | data += offset; |
| 3598 | s = (npy_intp)ts - offset; |
| 3599 | n = (npy_intp)count; |
| 3600 | itemsize = type->elsize; |
| 3601 | if (n < 0) { |
| 3602 | if (itemsize == 0) { |
| 3603 | PyErr_SetString(PyExc_ValueError, |
| 3604 | "cannot determine count if itemsize is 0"); |
| 3605 | Py_DECREF(type)_Py_DECREF(((PyObject*)(type))); |
| 3606 | return NULL((void*)0); |
| 3607 | } |
| 3608 | if (s % itemsize != 0) { |
| 3609 | PyErr_SetString(PyExc_ValueError, |
| 3610 | "buffer size must be a multiple"\ |
| 3611 | " of element size"); |
| 3612 | Py_DECREF(type)_Py_DECREF(((PyObject*)(type))); |
| 3613 | return NULL((void*)0); |
| 3614 | } |
| 3615 | n = s/itemsize; |
| 3616 | } |
| 3617 | else { |
| 3618 | if (s < n*itemsize) { |
| 3619 | PyErr_SetString(PyExc_ValueError, |
| 3620 | "buffer is smaller than requested"\ |
| 3621 | " size"); |
| 3622 | Py_DECREF(type)_Py_DECREF(((PyObject*)(type))); |
| 3623 | return NULL((void*)0); |
| 3624 | } |
| 3625 | } |
| 3626 | |
| 3627 | ret = (PyArrayObject *)PyArray_NewFromDescrAndBase( |
| 3628 | &PyArray_Type, type, |
| 3629 | 1, &n, NULL((void*)0), data, |
| 3630 | NPY_ARRAY_DEFAULT((0x0001 | (0x0100 | 0x0400))), NULL((void*)0), buf); |
| 3631 | if (ret == NULL((void*)0)) { |
| 3632 | return NULL((void*)0); |
| 3633 | } |
| 3634 | |
| 3635 | if (!writeable) { |
| 3636 | PyArray_CLEARFLAGS(ret, NPY_ARRAY_WRITEABLE0x0400); |
| 3637 | } |
| 3638 | return (PyObject *)ret; |
| 3639 | } |
| 3640 | |
| 3641 | /*NUMPY_API |
| 3642 | * |
| 3643 | * Given a pointer to a string ``data``, a string length ``slen``, and |
| 3644 | * a ``PyArray_Descr``, return an array corresponding to the data |
| 3645 | * encoded in that string. |
| 3646 | * |
| 3647 | * If the dtype is NULL, the default array type is used (double). |
| 3648 | * If non-null, the reference is stolen. |
| 3649 | * |
| 3650 | * If ``slen`` is < 0, then the end of string is used for text data. |
| 3651 | * It is an error for ``slen`` to be < 0 for binary data (since embedded NULLs |
| 3652 | * would be the norm). |
| 3653 | * |
| 3654 | * The number of elements to read is given as ``num``; if it is < 0, then |
| 3655 | * then as many as possible are read. |
| 3656 | * |
| 3657 | * If ``sep`` is NULL or empty, then binary data is assumed, else |
| 3658 | * text data, with ``sep`` as the separator between elements. Whitespace in |
| 3659 | * the separator matches any length of whitespace in the text, and a match |
| 3660 | * for whitespace around the separator is added. |
| 3661 | */ |
| 3662 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 3663 | PyArray_FromString(char *data, npy_intp slen, PyArray_Descr *dtype, |
| 3664 | npy_intp num, char *sep) |
| 3665 | { |
| 3666 | int itemsize; |
| 3667 | PyArrayObject *ret; |
| 3668 | npy_bool binary; |
| 3669 | |
| 3670 | if (dtype == NULL((void*)0)) { |
| 3671 | dtype=PyArray_DescrFromType(NPY_DEFAULT_TYPENPY_DOUBLE); |
| 3672 | if (dtype == NULL((void*)0)) { |
| 3673 | return NULL((void*)0); |
| 3674 | } |
| 3675 | } |
| 3676 | if (PyDataType_FLAGCHK(dtype, NPY_ITEM_IS_POINTER)(((dtype)->flags & (0x04)) == (0x04)) || |
| 3677 | PyDataType_REFCHK(dtype)(((dtype)->flags & (0x01)) == (0x01))) { |
| 3678 | PyErr_SetString(PyExc_ValueError, |
| 3679 | "Cannot create an object array from" \ |
| 3680 | " a string"); |
| 3681 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 3682 | return NULL((void*)0); |
| 3683 | } |
| 3684 | itemsize = dtype->elsize; |
| 3685 | if (itemsize == 0) { |
| 3686 | PyErr_SetString(PyExc_ValueError, "zero-valued itemsize"); |
| 3687 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 3688 | return NULL((void*)0); |
| 3689 | } |
| 3690 | |
| 3691 | binary = ((sep == NULL((void*)0)) || (strlen(sep) == 0)); |
| 3692 | if (binary) { |
| 3693 | if (num < 0 ) { |
| 3694 | if (slen % itemsize != 0) { |
| 3695 | PyErr_SetString(PyExc_ValueError, |
| 3696 | "string size must be a "\ |
| 3697 | "multiple of element size"); |
| 3698 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 3699 | return NULL((void*)0); |
| 3700 | } |
| 3701 | num = slen/itemsize; |
| 3702 | } |
| 3703 | else { |
| 3704 | if (slen < num*itemsize) { |
| 3705 | PyErr_SetString(PyExc_ValueError, |
| 3706 | "string is smaller than " \ |
| 3707 | "requested size"); |
| 3708 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 3709 | return NULL((void*)0); |
| 3710 | } |
| 3711 | } |
| 3712 | /* |
| 3713 | * NewFromDescr may replace dtype to absorb subarray shape |
| 3714 | * into the array, so get size beforehand. |
| 3715 | */ |
| 3716 | npy_intp size_to_copy = num*dtype->elsize; |
| 3717 | ret = (PyArrayObject *) |
| 3718 | PyArray_NewFromDescr(&PyArray_Type, dtype, |
| 3719 | 1, &num, NULL((void*)0), NULL((void*)0), |
| 3720 | 0, NULL((void*)0)); |
| 3721 | if (ret == NULL((void*)0)) { |
| 3722 | return NULL((void*)0); |
| 3723 | } |
| 3724 | memcpy(PyArray_DATA(ret), data, size_to_copy); |
| 3725 | } |
| 3726 | else { |
| 3727 | /* read from character-based string */ |
| 3728 | size_t nread = 0; |
| 3729 | char *end; |
| 3730 | |
| 3731 | if (dtype->f->fromstr == NULL((void*)0)) { |
| 3732 | PyErr_SetString(PyExc_ValueError, |
| 3733 | "don't know how to read " \ |
| 3734 | "character strings with that " \ |
| 3735 | "array type"); |
| 3736 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 3737 | return NULL((void*)0); |
| 3738 | } |
| 3739 | if (slen < 0) { |
| 3740 | end = NULL((void*)0); |
| 3741 | } |
| 3742 | else { |
| 3743 | end = data + slen; |
| 3744 | } |
| 3745 | ret = array_from_text(dtype, num, sep, &nread, |
| 3746 | data, |
| 3747 | (next_element) fromstr_next_element, |
| 3748 | (skip_separator) fromstr_skip_separator, |
| 3749 | end); |
| 3750 | Py_DECREF(dtype)_Py_DECREF(((PyObject*)(dtype))); |
| 3751 | } |
| 3752 | return (PyObject *)ret; |
| 3753 | } |
| 3754 | |
| 3755 | /*NUMPY_API |
| 3756 | * |
| 3757 | * steals a reference to dtype (which cannot be NULL) |
| 3758 | */ |
| 3759 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * |
| 3760 | PyArray_FromIter(PyObject *obj, PyArray_Descr *dtype, npy_intp count) |
| 3761 | { |
| 3762 | PyObject *value; |
| 3763 | PyObject *iter = PyObject_GetIter(obj); |
| 3764 | PyArrayObject *ret = NULL((void*)0); |
| 3765 | npy_intp i, elsize, elcount; |
| 3766 | char *item, *new_data; |
| 3767 | |
| 3768 | if (iter == NULL((void*)0)) { |
| 3769 | goto done; |
| 3770 | } |
| 3771 | if (PyDataType_ISUNSIZED(dtype)((dtype)->elsize == 0 && !(((PyArray_Descr *)(dtype ))->names != ((void*)0)))) { |
| 3772 | PyErr_SetString(PyExc_ValueError, |
| 3773 | "Must specify length when using variable-size data-type."); |
| 3774 | goto done; |
| 3775 | } |
| 3776 | if (count < 0) { |
| 3777 | elcount = PyObject_LengthHint(obj, 0); |
| 3778 | if (elcount < 0) { |
| 3779 | goto done; |
| 3780 | } |
| 3781 | } |
| 3782 | else { |
| 3783 | elcount = count; |
| 3784 | } |
| 3785 | |
| 3786 | elsize = dtype->elsize; |
| 3787 | |
| 3788 | /* |
| 3789 | * We would need to alter the memory RENEW code to decrement any |
| 3790 | * reference counts before throwing away any memory. |
| 3791 | */ |
| 3792 | if (PyDataType_REFCHK(dtype)(((dtype)->flags & (0x01)) == (0x01))) { |
| 3793 | PyErr_SetString(PyExc_ValueError, |
| 3794 | "cannot create object arrays from iterator"); |
| 3795 | goto done; |
| 3796 | } |
| 3797 | |
| 3798 | ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, dtype, 1, |
| 3799 | &elcount, NULL((void*)0),NULL((void*)0), 0, NULL((void*)0)); |
| 3800 | dtype = NULL((void*)0); |
| 3801 | if (ret == NULL((void*)0)) { |
| 3802 | goto done; |
| 3803 | } |
| 3804 | for (i = 0; (i < count || count == -1) && |
| 3805 | (value = PyIter_Next(iter)); i++) { |
| 3806 | if (i >= elcount && elsize != 0) { |
| 3807 | npy_intp nbytes; |
| 3808 | /* |
| 3809 | Grow PyArray_DATA(ret): |
| 3810 | this is similar for the strategy for PyListObject, but we use |
| 3811 | 50% overallocation => 0, 4, 8, 14, 23, 36, 56, 86 ... |
| 3812 | */ |
| 3813 | elcount = (i >> 1) + (i < 4 ? 4 : 2) + i; |
| 3814 | if (!npy_mul_with_overflow_intp(&nbytes, elcount, elsize)) { |
| 3815 | new_data = PyDataMem_RENEW(PyArray_DATA(ret), nbytes); |
| 3816 | } |
| 3817 | else { |
| 3818 | new_data = NULL((void*)0); |
| 3819 | } |
| 3820 | if (new_data == NULL((void*)0)) { |
| 3821 | PyErr_SetString(PyExc_MemoryError, |
| 3822 | "cannot allocate array memory"); |
| 3823 | Py_DECREF(value)_Py_DECREF(((PyObject*)(value))); |
| 3824 | goto done; |
| 3825 | } |
| 3826 | ((PyArrayObject_fields *)ret)->data = new_data; |
| 3827 | } |
| 3828 | PyArray_DIMS(ret)[0] = i + 1; |
| 3829 | |
| 3830 | if (((item = index2ptr(ret, i)) == NULL((void*)0)) || |
| 3831 | PyArray_SETITEM(ret, item, value) == -1) { |
| 3832 | Py_DECREF(value)_Py_DECREF(((PyObject*)(value))); |
| 3833 | goto done; |
| 3834 | } |
| 3835 | Py_DECREF(value)_Py_DECREF(((PyObject*)(value))); |
| 3836 | } |
| 3837 | |
| 3838 | |
| 3839 | if (PyErr_Occurred()) { |
| 3840 | goto done; |
| 3841 | } |
| 3842 | if (i < count) { |
| 3843 | PyErr_SetString(PyExc_ValueError, |
| 3844 | "iterator too short"); |
| 3845 | goto done; |
| 3846 | } |
| 3847 | |
| 3848 | /* |
| 3849 | * Realloc the data so that don't keep extra memory tied up |
| 3850 | * (assuming realloc is reasonably good about reusing space...) |
| 3851 | */ |
| 3852 | if (i == 0 || elsize == 0) { |
| 3853 | /* The size cannot be zero for PyDataMem_RENEW. */ |
| 3854 | goto done; |
| 3855 | } |
| 3856 | new_data = PyDataMem_RENEW(PyArray_DATA(ret), i * elsize); |
| 3857 | if (new_data == NULL((void*)0)) { |
| 3858 | PyErr_SetString(PyExc_MemoryError, |
| 3859 | "cannot allocate array memory"); |
| 3860 | goto done; |
| 3861 | } |
| 3862 | ((PyArrayObject_fields *)ret)->data = new_data; |
| 3863 | |
| 3864 | done: |
| 3865 | Py_XDECREF(iter)_Py_XDECREF(((PyObject*)(iter))); |
| 3866 | Py_XDECREF(dtype)_Py_XDECREF(((PyObject*)(dtype))); |
| 3867 | if (PyErr_Occurred()) { |
| 3868 | Py_XDECREF(ret)_Py_XDECREF(((PyObject*)(ret))); |
| 3869 | return NULL((void*)0); |
| 3870 | } |
| 3871 | return (PyObject *)ret; |
| 3872 | } |
| 3873 | |
| 3874 | /* |
| 3875 | * This is the main array creation routine. |
| 3876 | * |
| 3877 | * Flags argument has multiple related meanings |
| 3878 | * depending on data and strides: |
| 3879 | * |
| 3880 | * If data is given, then flags is flags associated with data. |
| 3881 | * If strides is not given, then a contiguous strides array will be created |
| 3882 | * and the NPY_ARRAY_C_CONTIGUOUS bit will be set. If the flags argument |
| 3883 | * has the NPY_ARRAY_F_CONTIGUOUS bit set, then a FORTRAN-style strides array will be |
| 3884 | * created (and of course the NPY_ARRAY_F_CONTIGUOUS flag bit will be set). |
| 3885 | * |
| 3886 | * If data is not given but created here, then flags will be NPY_ARRAY_DEFAULT |
| 3887 | * and a non-zero flags argument can be used to indicate a FORTRAN style |
| 3888 | * array is desired. |
| 3889 | * |
| 3890 | * Dimensions and itemsize must have been checked for validity. |
| 3891 | */ |
| 3892 | |
| 3893 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) void |
| 3894 | _array_fill_strides(npy_intp *strides, npy_intp const *dims, int nd, size_t itemsize, |
| 3895 | int inflag, int *objflags) |
| 3896 | { |
| 3897 | int i; |
| 3898 | #if NPY_RELAXED_STRIDES_CHECKING1 |
| 3899 | npy_bool not_cf_contig = 0; |
| 3900 | npy_bool nod = 0; /* A dim != 1 was found */ |
| 3901 | |
| 3902 | /* Check if new array is both F- and C-contiguous */ |
| 3903 | for (i = 0; i < nd; i++) { |
| 3904 | if (dims[i] != 1) { |
| 3905 | if (nod) { |
| 3906 | not_cf_contig = 1; |
| 3907 | break; |
| 3908 | } |
| 3909 | nod = 1; |
| 3910 | } |
| 3911 | } |
| 3912 | #endif /* NPY_RELAXED_STRIDES_CHECKING */ |
| 3913 | |
| 3914 | /* Only make Fortran strides if not contiguous as well */ |
| 3915 | if ((inflag & (NPY_ARRAY_F_CONTIGUOUS0x0002|NPY_ARRAY_C_CONTIGUOUS0x0001)) == |
| 3916 | NPY_ARRAY_F_CONTIGUOUS0x0002) { |
| 3917 | for (i = 0; i < nd; i++) { |
| 3918 | strides[i] = itemsize; |
| 3919 | if (dims[i]) { |
| 3920 | itemsize *= dims[i]; |
| 3921 | } |
| 3922 | #if NPY_RELAXED_STRIDES_CHECKING1 |
| 3923 | else { |
| 3924 | not_cf_contig = 0; |
| 3925 | } |
| 3926 | #if NPY_RELAXED_STRIDES_DEBUG0 |
| 3927 | /* For testing purpose only */ |
| 3928 | if (dims[i] == 1) { |
| 3929 | strides[i] = NPY_MAX_INTP9223372036854775807L; |
| 3930 | } |
| 3931 | #endif /* NPY_RELAXED_STRIDES_DEBUG */ |
| 3932 | #endif /* NPY_RELAXED_STRIDES_CHECKING */ |
| 3933 | } |
| 3934 | #if NPY_RELAXED_STRIDES_CHECKING1 |
| 3935 | if (not_cf_contig) { |
| 3936 | #else /* not NPY_RELAXED_STRIDES_CHECKING */ |
| 3937 | if ((nd > 1) && ((strides[0] != strides[nd-1]) || (dims[nd-1] > 1))) { |
| 3938 | #endif /* not NPY_RELAXED_STRIDES_CHECKING */ |
| 3939 | *objflags = ((*objflags)|NPY_ARRAY_F_CONTIGUOUS0x0002) & |
| 3940 | ~NPY_ARRAY_C_CONTIGUOUS0x0001; |
| 3941 | } |
| 3942 | else { |
| 3943 | *objflags |= (NPY_ARRAY_F_CONTIGUOUS0x0002|NPY_ARRAY_C_CONTIGUOUS0x0001); |
| 3944 | } |
| 3945 | } |
| 3946 | else { |
| 3947 | for (i = nd - 1; i >= 0; i--) { |
| 3948 | strides[i] = itemsize; |
| 3949 | if (dims[i]) { |
| 3950 | itemsize *= dims[i]; |
| 3951 | } |
| 3952 | #if NPY_RELAXED_STRIDES_CHECKING1 |
| 3953 | else { |
| 3954 | not_cf_contig = 0; |
| 3955 | } |
| 3956 | #if NPY_RELAXED_STRIDES_DEBUG0 |
| 3957 | /* For testing purpose only */ |
| 3958 | if (dims[i] == 1) { |
| 3959 | strides[i] = NPY_MAX_INTP9223372036854775807L; |
| 3960 | } |
| 3961 | #endif /* NPY_RELAXED_STRIDES_DEBUG */ |
| 3962 | #endif /* NPY_RELAXED_STRIDES_CHECKING */ |
| 3963 | } |
| 3964 | #if NPY_RELAXED_STRIDES_CHECKING1 |
| 3965 | if (not_cf_contig) { |
| 3966 | #else /* not NPY_RELAXED_STRIDES_CHECKING */ |
| 3967 | if ((nd > 1) && ((strides[0] != strides[nd-1]) || (dims[0] > 1))) { |
| 3968 | #endif /* not NPY_RELAXED_STRIDES_CHECKING */ |
| 3969 | *objflags = ((*objflags)|NPY_ARRAY_C_CONTIGUOUS0x0001) & |
| 3970 | ~NPY_ARRAY_F_CONTIGUOUS0x0002; |
| 3971 | } |
| 3972 | else { |
| 3973 | *objflags |= (NPY_ARRAY_C_CONTIGUOUS0x0001|NPY_ARRAY_F_CONTIGUOUS0x0002); |
| 3974 | } |
| 3975 | } |
| 3976 | return; |
| 3977 | } |
| 3978 | |
| 3979 | /* |
| 3980 | * Calls arr_of_subclass.__array_wrap__(towrap), in order to make 'towrap' |
| 3981 | * have the same ndarray subclass as 'arr_of_subclass'. |
| 3982 | */ |
| 3983 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyArrayObject * |
| 3984 | PyArray_SubclassWrap(PyArrayObject *arr_of_subclass, PyArrayObject *towrap) |
| 3985 | { |
| 3986 | PyObject *wrapped = PyObject_CallMethod_PyObject_CallMethod_SizeT((PyObject *)arr_of_subclass, |
| 3987 | "__array_wrap__", "O", towrap); |
| 3988 | if (wrapped == NULL((void*)0)) { |
| 3989 | return NULL((void*)0); |
| 3990 | } |
| 3991 | if (!PyArray_Check(wrapped)((((PyObject*)(wrapped))->ob_type) == (&PyArray_Type) || PyType_IsSubtype((((PyObject*)(wrapped))->ob_type), (& PyArray_Type)))) { |
| 3992 | PyErr_SetString(PyExc_RuntimeError, |
| 3993 | "ndarray subclass __array_wrap__ method returned an " |
| 3994 | "object which was not an instance of an ndarray subclass"); |
| 3995 | Py_DECREF(wrapped)_Py_DECREF(((PyObject*)(wrapped))); |
| 3996 | return NULL((void*)0); |
| 3997 | } |
| 3998 | |
| 3999 | return (PyArrayObject *)wrapped; |
| 4000 | } |