* Return the correct descriptor given an array object and a DType class. * * This is identical to casting the arrays descriptor/dtype to the new * DType class * * @param arr The array object. * @param DType The DType class to cast to (or NULL for convenience) * @param out_descr The output descriptor will set. The result can be NULL * when the array is of object dtype and has no elem
| 773 | * @return -1 on failure, 0 on success. |
| 774 | */ |
| 775 | static int |
| 776 | find_descriptor_from_array( |
| 777 | PyArrayObject *arr, PyArray_DTypeMeta *DType, PyArray_Descr **out_descr) |
| 778 | { |
| 779 | enum _dtype_discovery_flags flags = 0; |
| 780 | *out_descr = NULL; |
| 781 | |
| 782 | if (DType == NULL) { |
| 783 | *out_descr = PyArray_DESCR(arr); |
| 784 | Py_INCREF(*out_descr); |
| 785 | return 0; |
| 786 | } |
| 787 | |
| 788 | if (NPY_UNLIKELY(NPY_DT_is_parametric(DType) && PyArray_ISOBJECT(arr))) { |
| 789 | /* |
| 790 | * We have one special case, if (and only if) the input array is of |
| 791 | * object DType and the dtype is not fixed already but parametric. |
| 792 | * Then, we allow inspection of all elements, treating them as |
| 793 | * elements. We do this recursively, so nested 0-D arrays can work, |
| 794 | * but nested higher dimensional arrays will lead to an error. |
| 795 | */ |
| 796 | assert(DType->type_num != NPY_OBJECT); /* not parametric */ |
| 797 | |
| 798 | PyArrayIterObject *iter; |
| 799 | iter = (PyArrayIterObject *)PyArray_IterNew((PyObject *)arr); |
| 800 | if (iter == NULL) { |
| 801 | return -1; |
| 802 | } |
| 803 | while (iter->index < iter->size) { |
| 804 | PyArray_DTypeMeta *item_DType; |
| 805 | /* |
| 806 | * Note: If the array contains typed objects we may need to use |
| 807 | * the dtype to use casting for finding the correct instance. |
| 808 | */ |
| 809 | PyObject *elem = PyArray_GETITEM(arr, iter->dataptr); |
| 810 | if (elem == NULL) { |
| 811 | Py_DECREF(iter); |
| 812 | return -1; |
| 813 | } |
| 814 | item_DType = discover_dtype_from_pyobject(elem, &flags, DType); |
| 815 | if (item_DType == NULL) { |
| 816 | Py_DECREF(iter); |
| 817 | Py_DECREF(elem); |
| 818 | return -1; |
| 819 | } |
| 820 | if (item_DType == (PyArray_DTypeMeta *)Py_None) { |
| 821 | Py_SETREF(item_DType, NULL); |
| 822 | } |
| 823 | int flat_max_dims = 0; |
| 824 | if (handle_scalar(elem, 0, &flat_max_dims, out_descr, |
| 825 | NULL, DType, &flags, item_DType) < 0) { |
| 826 | Py_DECREF(iter); |
| 827 | Py_DECREF(elem); |
| 828 | Py_XDECREF(*out_descr); |
| 829 | Py_XDECREF(item_DType); |
| 830 | return -1; |
| 831 | } |
| 832 | Py_XDECREF(item_DType); |
no test coverage detected