* Recursive helper to assign using a coercion cache. This function * must consume the cache depth first, just as the cache was originally * produced. */
| 466 | * produced. |
| 467 | */ |
| 468 | NPY_NO_EXPORT int |
| 469 | PyArray_AssignFromCache_Recursive( |
| 470 | PyArrayObject *self, const int ndim, coercion_cache_obj **cache) |
| 471 | { |
| 472 | /* Consume first cache element by extracting information and freeing it */ |
| 473 | PyObject *obj = (*cache)->arr_or_sequence; |
| 474 | Py_INCREF(obj); |
| 475 | npy_bool sequence = (*cache)->sequence; |
| 476 | int depth = (*cache)->depth; |
| 477 | *cache = npy_unlink_coercion_cache(*cache); |
| 478 | |
| 479 | /* The element is either a sequence, or an array */ |
| 480 | if (!sequence) { |
| 481 | /* Straight forward array assignment */ |
| 482 | assert(PyArray_Check(obj)); |
| 483 | if (PyArray_CopyInto(self, (PyArrayObject *)obj) < 0) { |
| 484 | goto fail; |
| 485 | } |
| 486 | } |
| 487 | else { |
| 488 | assert(depth != ndim); |
| 489 | npy_intp length = PySequence_Length(obj); |
| 490 | if (length != PyArray_DIMS(self)[0]) { |
| 491 | PyErr_SetString(PyExc_RuntimeError, |
| 492 | "Inconsistent object during array creation? " |
| 493 | "Content of sequences changed (length inconsistent)."); |
| 494 | goto fail; |
| 495 | } |
| 496 | |
| 497 | for (npy_intp i = 0; i < length; i++) { |
| 498 | PyObject *value = PySequence_Fast_GET_ITEM(obj, i); |
| 499 | |
| 500 | if (ndim == depth + 1) { |
| 501 | /* |
| 502 | * Straight forward assignment of elements. Note that it is |
| 503 | * possible for such an element to be a 0-D array or array-like. |
| 504 | * `PyArray_Pack` supports arrays as well as we want: We |
| 505 | * support exact NumPy arrays, but at this point ignore others. |
| 506 | * (Please see the `PyArray_Pack` function comment if this |
| 507 | * rightly confuses you.) |
| 508 | */ |
| 509 | char *item; |
| 510 | item = (PyArray_BYTES(self) + i * PyArray_STRIDES(self)[0]); |
| 511 | if (PyArray_Pack(PyArray_DESCR(self), item, value) < 0) { |
| 512 | goto fail; |
| 513 | } |
| 514 | /* If this was an array(-like) we still need to unlike int: */ |
| 515 | if (*cache != NULL && (*cache)->converted_obj == value) { |
| 516 | *cache = npy_unlink_coercion_cache(*cache); |
| 517 | } |
| 518 | } |
| 519 | else { |
| 520 | PyArrayObject *view; |
| 521 | view = (PyArrayObject *)array_item_asarray(self, i); |
| 522 | if (view == NULL) { |
| 523 | goto fail; |
| 524 | } |
| 525 | if (PyArray_AssignFromCache_Recursive(view, ndim, cache) < 0) { |
no test coverage detected