| File: | numpy/core/src/multiarray/ctors.c | 
| Warning: | line 2870, column 13 Calling function '_Py_DECREF' with a PyObject argument whose ownership has been released  | 
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 "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)__builtin_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)__builtin_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)__builtin_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 | } | 
| 1 | #define PY_SSIZE_T_CLEAN | 
| 2 | #include <Python.h> | 
| 3 | |
| 4 | #define NPY_NO_DEPRECATED_API0x0000000E NPY_API_VERSION0x0000000E | 
| 5 | #define _MULTIARRAYMODULE | 
| 6 | #include "numpy/arrayobject.h" | 
| 7 | |
| 8 | #include "npy_config.h" | 
| 9 | #include "npy_pycompat.h" | 
| 10 | #include "common.h" | 
| 11 | |
| 12 | #include "abstractdtypes.h" | 
| 13 | #include "usertypes.h" | 
| 14 | |
| 15 | #include "npy_buffer.h" | 
| 16 | |
| 17 | #include "get_attr_string.h" | 
| 18 | #include "mem_overlap.h" | 
| 19 | #include "array_coercion.h" | 
| 20 | |
| 21 | /* | 
| 22 | * The casting to use for implicit assignment operations resulting from | 
| 23 | * in-place operations (like +=) and out= arguments. (Notice that this | 
| 24 | * variable is misnamed, but it's part of the public API so I'm not sure we | 
| 25 | * can just change it. Maybe someone should try and see if anyone notices. | 
| 26 | */ | 
| 27 | /* | 
| 28 | * In numpy 1.6 and earlier, this was NPY_UNSAFE_CASTING. In a future | 
| 29 | * release, it will become NPY_SAME_KIND_CASTING. Right now, during the | 
| 30 | * transitional period, we continue to follow the NPY_UNSAFE_CASTING rules (to | 
| 31 | * avoid breaking people's code), but we also check for whether the cast would | 
| 32 | * be allowed under the NPY_SAME_KIND_CASTING rules, and if not we issue a | 
| 33 | * warning (that people's code will be broken in a future release.) | 
| 34 | */ | 
| 35 | |
| 36 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) NPY_CASTING NPY_DEFAULT_ASSIGN_CASTING = NPY_SAME_KIND_CASTING; | 
| 37 | |
| 38 | |
| 39 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyArray_Descr * | 
| 40 | _array_find_python_scalar_type(PyObject *op) | 
| 41 | { | 
| 42 |     if (PyFloat_Check(op)((((PyObject*)(op))->ob_type) == (&PyFloat_Type) || PyType_IsSubtype ((((PyObject*)(op))->ob_type), (&PyFloat_Type)))) {  | 
| 43 | return PyArray_DescrFromType(NPY_DOUBLE); | 
| 44 | } | 
| 45 |     else if (PyComplex_Check(op)((((PyObject*)(op))->ob_type) == (&PyComplex_Type) || PyType_IsSubtype ((((PyObject*)(op))->ob_type), (&PyComplex_Type)))) {  | 
| 46 | return PyArray_DescrFromType(NPY_CDOUBLE); | 
| 47 | } | 
| 48 |     else if (PyLong_Check(op)((((((PyObject*)(op))->ob_type))->tp_flags & ((1UL << 24))) != 0)) {  | 
| 49 | return PyArray_PyIntAbstractDType.discover_descr_from_pyobject( | 
| 50 | &PyArray_PyIntAbstractDType, op); | 
| 51 | } | 
| 52 | return NULL((void*)0); | 
| 53 | } | 
| 54 | |
| 55 | |
| 56 | /* | 
| 57 | * Get a suitable string dtype by calling `__str__`. | 
| 58 | * For `np.bytes_`, this assumes an ASCII encoding. | 
| 59 | */ | 
| 60 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyArray_Descr * | 
| 61 | PyArray_DTypeFromObjectStringDiscovery( | 
| 62 | PyObject *obj, PyArray_Descr *last_dtype, int string_type) | 
| 63 | { | 
| 64 | int itemsize; | 
| 65 | |
| 66 | if (string_type == NPY_STRING) { | 
| 67 | PyObject *temp = PyObject_Str(obj); | 
| 68 | if (temp == NULL((void*)0)) { | 
| 69 | return NULL((void*)0); | 
| 70 | } | 
| 71 | /* assume that when we do the encoding elsewhere we'll use ASCII */ | 
| 72 | itemsize = PyUnicode_GetLength(temp); | 
| 73 | Py_DECREF(temp)_Py_DECREF(((PyObject*)(temp))); | 
| 74 | if (itemsize < 0) { | 
| 75 | return NULL((void*)0); | 
| 76 | } | 
| 77 | } | 
| 78 | else if (string_type == NPY_UNICODE) { | 
| 79 | PyObject *temp = PyObject_Str(obj); | 
| 80 | if (temp == NULL((void*)0)) { | 
| 81 | return NULL((void*)0); | 
| 82 | } | 
| 83 | itemsize = PyUnicode_GetLength(temp); | 
| 84 | Py_DECREF(temp)_Py_DECREF(((PyObject*)(temp))); | 
| 85 | if (itemsize < 0) { | 
| 86 | return NULL((void*)0); | 
| 87 | } | 
| 88 | itemsize *= 4; /* convert UCS4 codepoints to bytes */ | 
| 89 | } | 
| 90 | else { | 
| 91 | return NULL((void*)0); | 
| 92 | } | 
| 93 | if (last_dtype != NULL((void*)0) && | 
| 94 | last_dtype->type_num == string_type && | 
| 95 | last_dtype->elsize >= itemsize) { | 
| 96 | Py_INCREF(last_dtype)_Py_INCREF(((PyObject*)(last_dtype))); | 
| 97 | return last_dtype; | 
| 98 | } | 
| 99 | PyArray_Descr *dtype = PyArray_DescrNewFromType(string_type); | 
| 100 | if (dtype == NULL((void*)0)) { | 
| 101 | return NULL((void*)0); | 
| 102 | } | 
| 103 | dtype->elsize = itemsize; | 
| 104 | return dtype; | 
| 105 | } | 
| 106 | |
| 107 | |
| 108 | /* | 
| 109 | * This function is now identical to the new PyArray_DiscoverDTypeAndShape | 
| 110 | * but only returns the the dtype. It should in most cases be slowly phased | 
| 111 | * out. (Which may need some refactoring to PyArray_FromAny to make it simpler) | 
| 112 | */ | 
| 113 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) int | 
| 114 | PyArray_DTypeFromObject(PyObject *obj, int maxdims, PyArray_Descr **out_dtype) | 
| 115 | { | 
| 116 | coercion_cache_obj *cache = NULL((void*)0); | 
| 117 | npy_intp shape[NPY_MAXDIMS32]; | 
| 118 | int ndim; | 
| 119 | |
| 120 | ndim = PyArray_DiscoverDTypeAndShape( | 
| 121 | obj, maxdims, shape, &cache, NULL((void*)0), NULL((void*)0), out_dtype); | 
| 122 | if (ndim < 0) { | 
| 123 | return -1; | 
| 124 | } | 
| 125 | npy_free_coercion_cache(cache); | 
| 126 | return 0; | 
| 127 | } | 
| 128 | |
| 129 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) char * | 
| 130 | index2ptr(PyArrayObject *mp, npy_intp i) | 
| 131 | { | 
| 132 | npy_intp dim0; | 
| 133 | |
| 134 | if (PyArray_NDIM(mp) == 0) { | 
| 135 | PyErr_SetString(PyExc_IndexError, "0-d arrays can't be indexed"); | 
| 136 | return NULL((void*)0); | 
| 137 | } | 
| 138 | dim0 = PyArray_DIMS(mp)[0]; | 
| 139 | if (check_and_adjust_index(&i, dim0, 0, NULL((void*)0)) < 0) | 
| 140 | return NULL((void*)0); | 
| 141 | if (i == 0) { | 
| 142 | return PyArray_DATA(mp); | 
| 143 | } | 
| 144 | return PyArray_BYTES(mp)+i*PyArray_STRIDES(mp)[0]; | 
| 145 | } | 
| 146 | |
| 147 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) int | 
| 148 | _zerofill(PyArrayObject *ret) | 
| 149 | { | 
| 150 | if (PyDataType_REFCHK(PyArray_DESCR(ret))(((PyArray_DESCR(ret))->flags & (0x01)) == (0x01))) { | 
| 151 | PyObject *zero = PyLong_FromLong(0); | 
| 152 | PyArray_FillObjectArray(ret, zero); | 
| 153 | Py_DECREF(zero)_Py_DECREF(((PyObject*)(zero))); | 
| 154 | if (PyErr_Occurred()) { | 
| 155 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | 
| 156 | return -1; | 
| 157 | } | 
| 158 | } | 
| 159 | else { | 
| 160 |         npy_intp n = PyArray_NBYTES(ret)(PyArray_ITEMSIZE(ret) * PyArray_MultiplyList(PyArray_DIMS(ret ), PyArray_NDIM(ret)));  | 
| 161 | memset(PyArray_DATA(ret), 0, n); | 
| 162 | } | 
| 163 | return 0; | 
| 164 | } | 
| 165 | |
| 166 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) npy_bool | 
| 167 | _IsWriteable(PyArrayObject *ap) | 
| 168 | { | 
| 169 | PyObject *base = PyArray_BASE(ap); | 
| 170 | Py_buffer view; | 
| 171 | |
| 172 | /* | 
| 173 | * C-data wrapping arrays may not own their data while not having a base; | 
| 174 | * WRITEBACKIFCOPY arrays have a base, but do own their data. | 
| 175 | */ | 
| 176 | if (base == NULL((void*)0) || PyArray_CHKFLAGS(ap, NPY_ARRAY_OWNDATA0x0004)) { | 
| 177 | /* | 
| 178 | * This is somewhat unsafe for directly wrapped non-writable C-arrays, | 
| 179 | * which do not know whether the memory area is writable or not and | 
| 180 | * do not own their data (but have no base). | 
| 181 | * It would be better if this returned PyArray_ISWRITEABLE(ap). | 
| 182 | * Since it is hard to deprecate, this is deprecated only on the Python | 
| 183 | * side, but not on in PyArray_UpdateFlags. | 
| 184 | */ | 
| 185 | return NPY_TRUE1; | 
| 186 | } | 
| 187 | |
| 188 | /* | 
| 189 | * Get to the final base object. | 
| 190 | * If it is a writeable array, then return True if we can | 
| 191 | * find an array object or a writeable buffer object as | 
| 192 | * the final base object. | 
| 193 | */ | 
| 194 |     while (PyArray_Check(base)((((PyObject*)(base))->ob_type) == (&PyArray_Type) || PyType_IsSubtype ((((PyObject*)(base))->ob_type), (&PyArray_Type)))) {  | 
| 195 | ap = (PyArrayObject *)base; | 
| 196 | base = PyArray_BASE(ap); | 
| 197 | |
| 198 | if (PyArray_ISWRITEABLE(ap)PyArray_CHKFLAGS((ap), 0x0400)) { | 
| 199 | /* | 
| 200 | * If any base is writeable, it must be OK to switch, note that | 
| 201 | * bases are typically collapsed to always point to the most | 
| 202 | * general one. | 
| 203 | */ | 
| 204 | return NPY_TRUE1; | 
| 205 | } | 
| 206 | |
| 207 | if (base == NULL((void*)0) || PyArray_CHKFLAGS(ap, NPY_ARRAY_OWNDATA0x0004)) { | 
| 208 | /* there is no further base to test the writeable flag for */ | 
| 209 | return NPY_FALSE0; | 
| 210 | } | 
| 211 | assert(!PyArray_CHKFLAGS(ap, NPY_ARRAY_OWNDATA))((void) (0)); | 
| 212 | } | 
| 213 | |
| 214 | if (PyObject_GetBuffer(base, &view, PyBUF_WRITABLE0x0001|PyBUF_SIMPLE0) < 0) { | 
| 215 | PyErr_Clear(); | 
| 216 | return NPY_FALSE0; | 
| 217 | } | 
| 218 | PyBuffer_Release(&view); | 
| 219 | return NPY_TRUE1; | 
| 220 | } | 
| 221 | |
| 222 | |
| 223 | /** | 
| 224 | * Convert an array shape to a string such as "(1, 2)". | 
| 225 | * | 
| 226 | * @param Dimensionality of the shape | 
| 227 | * @param npy_intp pointer to shape array | 
| 228 | * @param String to append after the shape `(1, 2)%s`. | 
| 229 | * | 
| 230 | * @return Python unicode string | 
| 231 | */ | 
| 232 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyObject * | 
| 233 | convert_shape_to_string(npy_intp n, npy_intp const *vals, char *ending) | 
| 234 | { | 
| 235 | npy_intp i; | 
| 236 | |
| 237 | /* | 
| 238 | * Negative dimension indicates "newaxis", which can | 
| 239 | * be discarded for printing if it's a leading dimension. | 
| 240 | * Find the first non-"newaxis" dimension. | 
| 241 | */ | 
| 242 | for (i = 0; i < n && vals[i] < 0; i++); | 
| 243 | |
| 244 | if (i == n) { | 
| 245 | return PyUnicode_FromFormat("()%s", ending); | 
| 246 | } | 
| 247 | |
| 248 | PyObject *ret = PyUnicode_FromFormat("%" NPY_INTP_FMT"ld", vals[i++]); | 
| 249 | if (ret == NULL((void*)0)) { | 
| 250 | return NULL((void*)0); | 
| 251 | } | 
| 252 | for (; i < n; ++i) { | 
| 253 | PyObject *tmp; | 
| 254 | |
| 255 | if (vals[i] < 0) { | 
| 256 | tmp = PyUnicode_FromString(",newaxis"); | 
| 257 | } | 
| 258 | else { | 
| 259 | tmp = PyUnicode_FromFormat(",%" NPY_INTP_FMT"ld", vals[i]); | 
| 260 | } | 
| 261 | if (tmp == NULL((void*)0)) { | 
| 262 | Py_DECREF(ret)_Py_DECREF(((PyObject*)(ret))); | 
| 263 | return NULL((void*)0); | 
| 264 | } | 
| 265 | |
| 266 |         Py_SETREF(ret, PyUnicode_Concat(ret, tmp))do { PyObject *_py_tmp = ((PyObject*)(ret)); (ret) = (PyUnicode_Concat (ret, tmp)); _Py_DECREF(((PyObject*)(_py_tmp))); } while (0);  | 
| 267 | Py_DECREF(tmp)_Py_DECREF(((PyObject*)(tmp))); | 
| 268 | if (ret == NULL((void*)0)) { | 
| 269 | return NULL((void*)0); | 
| 270 | } | 
| 271 | } | 
| 272 | |
| 273 | if (i == 1) { | 
| 274 |         Py_SETREF(ret, PyUnicode_FromFormat("(%S,)%s", ret, ending))do { PyObject *_py_tmp = ((PyObject*)(ret)); (ret) = (PyUnicode_FromFormat ("(%S,)%s", ret, ending)); _Py_DECREF(((PyObject*)(_py_tmp))) ; } while (0);  | 
| 275 | } | 
| 276 | else { | 
| 277 |         Py_SETREF(ret, PyUnicode_FromFormat("(%S)%s", ret, ending))do { PyObject *_py_tmp = ((PyObject*)(ret)); (ret) = (PyUnicode_FromFormat ("(%S)%s", ret, ending)); _Py_DECREF(((PyObject*)(_py_tmp))); } while (0);  | 
| 278 | } | 
| 279 | return ret; | 
| 280 | } | 
| 281 | |
| 282 | |
| 283 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) void | 
| 284 | dot_alignment_error(PyArrayObject *a, int i, PyArrayObject *b, int j) | 
| 285 | { | 
| 286 | PyObject *errmsg = NULL((void*)0), *format = NULL((void*)0), *fmt_args = NULL((void*)0), | 
| 287 | *i_obj = NULL((void*)0), *j_obj = NULL((void*)0), | 
| 288 | *shape1 = NULL((void*)0), *shape2 = NULL((void*)0), | 
| 289 | *shape1_i = NULL((void*)0), *shape2_j = NULL((void*)0); | 
| 290 | |
| 291 | format = PyUnicode_FromString("shapes %s and %s not aligned:" | 
| 292 | " %d (dim %d) != %d (dim %d)"); | 
| 293 | |
| 294 | shape1 = convert_shape_to_string(PyArray_NDIM(a), PyArray_DIMS(a), ""); | 
| 295 | shape2 = convert_shape_to_string(PyArray_NDIM(b), PyArray_DIMS(b), ""); | 
| 296 | |
| 297 | i_obj = PyLong_FromLong(i); | 
| 298 | j_obj = PyLong_FromLong(j); | 
| 299 | |
| 300 | shape1_i = PyLong_FromSsize_t(PyArray_DIM(a, i)); | 
| 301 | shape2_j = PyLong_FromSsize_t(PyArray_DIM(b, j)); | 
| 302 | |
| 303 | if (!format || !shape1 || !shape2 || !i_obj || !j_obj || | 
| 304 | !shape1_i || !shape2_j) { | 
| 305 | goto end; | 
| 306 | } | 
| 307 | |
| 308 | fmt_args = PyTuple_Pack(6, shape1, shape2, | 
| 309 | shape1_i, i_obj, shape2_j, j_obj); | 
| 310 | if (fmt_args == NULL((void*)0)) { | 
| 311 | goto end; | 
| 312 | } | 
| 313 | |
| 314 | errmsg = PyUnicode_Format(format, fmt_args); | 
| 315 | if (errmsg != NULL((void*)0)) { | 
| 316 | PyErr_SetObject(PyExc_ValueError, errmsg); | 
| 317 | } | 
| 318 | else { | 
| 319 | PyErr_SetString(PyExc_ValueError, "shapes are not aligned"); | 
| 320 | } | 
| 321 | |
| 322 | end: | 
| 323 | Py_XDECREF(errmsg)_Py_XDECREF(((PyObject*)(errmsg))); | 
| 324 | Py_XDECREF(fmt_args)_Py_XDECREF(((PyObject*)(fmt_args))); | 
| 325 | Py_XDECREF(format)_Py_XDECREF(((PyObject*)(format))); | 
| 326 | Py_XDECREF(i_obj)_Py_XDECREF(((PyObject*)(i_obj))); | 
| 327 | Py_XDECREF(j_obj)_Py_XDECREF(((PyObject*)(j_obj))); | 
| 328 | Py_XDECREF(shape1)_Py_XDECREF(((PyObject*)(shape1))); | 
| 329 | Py_XDECREF(shape2)_Py_XDECREF(((PyObject*)(shape2))); | 
| 330 | Py_XDECREF(shape1_i)_Py_XDECREF(((PyObject*)(shape1_i))); | 
| 331 | Py_XDECREF(shape2_j)_Py_XDECREF(((PyObject*)(shape2_j))); | 
| 332 | } | 
| 333 | |
| 334 | /** | 
| 335 | * unpack tuple of dtype->fields (descr, offset, title[not-needed]) | 
| 336 | * | 
| 337 | * @param "value" should be the tuple. | 
| 338 | * | 
| 339 | * @return "descr" will be set to the field's dtype | 
| 340 | * @return "offset" will be set to the field's offset | 
| 341 | * | 
| 342 | * returns -1 on failure, 0 on success. | 
| 343 | */ | 
| 344 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) int | 
| 345 | _unpack_field(PyObject *value, PyArray_Descr **descr, npy_intp *offset) | 
| 346 | { | 
| 347 | PyObject * off; | 
| 348 |     if (PyTuple_GET_SIZE(value)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(value))))-> ob_size) < 2) {  | 
| 349 | return -1; | 
| 350 | } | 
| 351 | *descr = (PyArray_Descr *)PyTuple_GET_ITEM(value, 0)((((void) (0)), (PyTupleObject *)(value))->ob_item[0]); | 
| 352 | off = PyTuple_GET_ITEM(value, 1)((((void) (0)), (PyTupleObject *)(value))->ob_item[1]); | 
| 353 | |
| 354 |     if (PyLong_Check(off)((((((PyObject*)(off))->ob_type))->tp_flags & ((1UL << 24))) != 0)) {  | 
| 355 | *offset = PyLong_AsSsize_t(off); | 
| 356 | } | 
| 357 | else { | 
| 358 | PyErr_SetString(PyExc_IndexError, "can't convert offset"); | 
| 359 | return -1; | 
| 360 | } | 
| 361 | |
| 362 | return 0; | 
| 363 | } | 
| 364 | |
| 365 | /* | 
| 366 | * check whether arrays with datatype dtype might have object fields. This will | 
| 367 | * only happen for structured dtypes (which may have hidden objects even if the | 
| 368 | * HASOBJECT flag is false), object dtypes, or subarray dtypes whose base type | 
| 369 | * is either of these. | 
| 370 | */ | 
| 371 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) int | 
| 372 | _may_have_objects(PyArray_Descr *dtype) | 
| 373 | { | 
| 374 | PyArray_Descr *base = dtype; | 
| 375 | if (PyDataType_HASSUBARRAY(dtype)((dtype)->subarray != ((void*)0))) { | 
| 376 | base = dtype->subarray->base; | 
| 377 | } | 
| 378 | |
| 379 | return (PyDataType_HASFIELDS(base)(((PyArray_Descr *)(base))->names != ((void*)0)) || | 
| 380 | PyDataType_FLAGCHK(base, NPY_ITEM_HASOBJECT)(((base)->flags & (0x01)) == (0x01)) ); | 
| 381 | } | 
| 382 | |
| 383 | /* | 
| 384 | * Make a new empty array, of the passed size, of a type that takes the | 
| 385 | * priority of ap1 and ap2 into account. | 
| 386 | * | 
| 387 | * If `out` is non-NULL, memory overlap is checked with ap1 and ap2, and an | 
| 388 | * updateifcopy temporary array may be returned. If `result` is non-NULL, the | 
| 389 | * output array to be returned (`out` if non-NULL and the newly allocated array | 
| 390 | * otherwise) is incref'd and put to *result. | 
| 391 | */ | 
| 392 | NPY_NO_EXPORT__attribute__((visibility("hidden"))) PyArrayObject * | 
| 393 | new_array_for_sum(PyArrayObject *ap1, PyArrayObject *ap2, PyArrayObject* out, | 
| 394 | int nd, npy_intp dimensions[], int typenum, PyArrayObject **result) | 
| 395 | { | 
| 396 | PyArrayObject *out_buf; | 
| 397 | |
| 398 | if (out) { | 
| 399 | int d; | 
| 400 | |
| 401 | /* verify that out is usable */ | 
| 402 | if (PyArray_NDIM(out) != nd || | 
| 403 | PyArray_TYPE(out) != typenum || | 
| 404 |             !PyArray_ISCARRAY(out)(PyArray_CHKFLAGS(out, (0x0001 | (0x0100 | 0x0400))) && ((PyArray_DESCR(out)->byteorder) != '>'))) {  | 
| 405 | PyErr_SetString(PyExc_ValueError, | 
| 406 | "output array is not acceptable (must have the right datatype, " | 
| 407 | "number of dimensions, and be a C-Array)"); | 
| 408 | return 0; | 
| 409 | } | 
| 410 | for (d = 0; d < nd; ++d) { | 
| 411 | if (dimensions[d] != PyArray_DIM(out, d)) { | 
| 412 | PyErr_SetString(PyExc_ValueError, | 
| 413 | "output array has wrong dimensions"); | 
| 414 | return 0; | 
| 415 | } | 
| 416 | } | 
| 417 | |
| 418 | /* check for memory overlap */ | 
| 419 | if (!(solve_may_share_memory(out, ap1, 1) == 0 && | 
| 420 | solve_may_share_memory(out, ap2, 1) == 0)) { | 
| 421 | /* allocate temporary output array */ | 
| 422 | out_buf = (PyArrayObject *)PyArray_NewLikeArray(out, NPY_CORDER, | 
| 423 | NULL((void*)0), 0); | 
| 424 | if (out_buf == NULL((void*)0)) { | 
| 425 | return NULL((void*)0); | 
| 426 | } | 
| 427 | |
| 428 | /* set copy-back */ | 
| 429 | Py_INCREF(out)_Py_INCREF(((PyObject*)(out))); | 
| 430 | if (PyArray_SetWritebackIfCopyBase(out_buf, out) < 0) { | 
| 431 | Py_DECREF(out)_Py_DECREF(((PyObject*)(out))); | 
| 432 | Py_DECREF(out_buf)_Py_DECREF(((PyObject*)(out_buf))); | 
| 433 | return NULL((void*)0); | 
| 434 | } | 
| 435 | } | 
| 436 | else { | 
| 437 | Py_INCREF(out)_Py_INCREF(((PyObject*)(out))); | 
| 438 | out_buf = out; | 
| 439 | } | 
| 440 | |
| 441 | if (result) { | 
| 442 | Py_INCREF(out)_Py_INCREF(((PyObject*)(out))); | 
| 443 | *result = out; | 
| 444 | } | 
| 445 | |
| 446 | return out_buf; | 
| 447 | } | 
| 448 | else { | 
| 449 | PyTypeObject *subtype; | 
| 450 | double prior1, prior2; | 
| 451 | /* | 
| 452 | * Need to choose an output array that can hold a sum | 
| 453 | * -- use priority to determine which subtype. | 
| 454 | */ | 
| 455 | if (Py_TYPE(ap2)(((PyObject*)(ap2))->ob_type) != Py_TYPE(ap1)(((PyObject*)(ap1))->ob_type)) { | 
| 456 | prior2 = PyArray_GetPriority((PyObject *)ap2, 0.0); | 
| 457 | prior1 = PyArray_GetPriority((PyObject *)ap1, 0.0); | 
| 458 | subtype = (prior2 > prior1 ? Py_TYPE(ap2)(((PyObject*)(ap2))->ob_type) : Py_TYPE(ap1)(((PyObject*)(ap1))->ob_type)); | 
| 459 | } | 
| 460 | else { | 
| 461 | prior1 = prior2 = 0.0; | 
| 462 | subtype = Py_TYPE(ap1)(((PyObject*)(ap1))->ob_type); | 
| 463 | } | 
| 464 | |
| 465 | out_buf = (PyArrayObject *)PyArray_New(subtype, nd, dimensions, | 
| 466 | typenum, NULL((void*)0), NULL((void*)0), 0, 0, | 
| 467 | (PyObject *) | 
| 468 | (prior2 > prior1 ? ap2 : ap1)); | 
| 469 | |
| 470 | if (out_buf != NULL((void*)0) && result) { | 
| 471 | Py_INCREF(out_buf)_Py_INCREF(((PyObject*)(out_buf))); | 
| 472 | *result = out_buf; | 
| 473 | } | 
| 474 | |
| 475 | return out_buf; | 
| 476 | } | 
| 477 | } | 
| 478 | 
| 1 | void _Py_DECREF(PyObject *op) { --op->ob_refcnt; } |