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; } |