* Check for an __array__ attribute and call it when it exists. * * .. warning: * If returned, `NotImplemented` is borrowed and must not be Decref'd * * @param op The Python object to convert to an array. * @param descr The desired `arr.dtype`, passed into the `__array__` call, * as information but is not checked/enforced! * @param never_copy Specifies that a copy is not allowe
| 2393 | * (or subclass). On error, return NULL. |
| 2394 | */ |
| 2395 | NPY_NO_EXPORT PyObject * |
| 2396 | PyArray_FromArrayAttr_int( |
| 2397 | PyObject *op, PyArray_Descr *descr, int never_copy) |
| 2398 | { |
| 2399 | PyObject *new; |
| 2400 | PyObject *array_meth; |
| 2401 | |
| 2402 | array_meth = PyArray_LookupSpecial_OnInstance(op, npy_ma_str_array); |
| 2403 | if (array_meth == NULL) { |
| 2404 | if (PyErr_Occurred()) { |
| 2405 | return NULL; |
| 2406 | } |
| 2407 | return Py_NotImplemented; |
| 2408 | } |
| 2409 | if (never_copy) { |
| 2410 | /* Currently, we must always assume that `__array__` returns a copy */ |
| 2411 | PyErr_SetString(PyExc_ValueError, |
| 2412 | "Unable to avoid copy while converting from an object " |
| 2413 | "implementing the `__array__` protocol. NumPy cannot ensure " |
| 2414 | "that no copy will be made."); |
| 2415 | Py_DECREF(array_meth); |
| 2416 | return NULL; |
| 2417 | } |
| 2418 | |
| 2419 | if (PyType_Check(op) && PyObject_HasAttrString(array_meth, "__get__")) { |
| 2420 | /* |
| 2421 | * If the input is a class `array_meth` may be a property-like object. |
| 2422 | * This cannot be interpreted as an array (called), but is a valid. |
| 2423 | * Trying `array_meth.__call__()` on this should not be useful. |
| 2424 | * (Needed due to the lookup being on the instance rather than type) |
| 2425 | */ |
| 2426 | Py_DECREF(array_meth); |
| 2427 | return Py_NotImplemented; |
| 2428 | } |
| 2429 | if (descr == NULL) { |
| 2430 | new = PyObject_CallFunction(array_meth, NULL); |
| 2431 | } |
| 2432 | else { |
| 2433 | new = PyObject_CallFunction(array_meth, "O", descr); |
| 2434 | } |
| 2435 | Py_DECREF(array_meth); |
| 2436 | if (new == NULL) { |
| 2437 | return NULL; |
| 2438 | } |
| 2439 | if (!PyArray_Check(new)) { |
| 2440 | PyErr_SetString(PyExc_ValueError, |
| 2441 | "object __array__ method not " \ |
| 2442 | "producing an array"); |
| 2443 | Py_DECREF(new); |
| 2444 | return NULL; |
| 2445 | } |
| 2446 | return new; |
| 2447 | } |
| 2448 | |
| 2449 | |
| 2450 | /*NUMPY_API |
no test coverage detected