@@ -1349,13 +1349,7 @@ _array_from_array_like(PyObject *op,
13491349 * this should be changed!
13501350 */
13511351 if (!writeable && tmp == Py_NotImplemented ) {
1352- PyObject * array_meth = PyArray_LookupSpecial_OnInstance (op , "__array__" );
1353- int has_get = array_meth && PyType_Check (op ) && PyObject_HasAttrString (array_meth , "__get__" );
1354- if (array_meth != NULL && !has_get && allow_copy ) {
1355- PyErr_SetString (PyExc_ValueError , "Calling __array__ in never copy mode is not allowed." );
1356- return NULL ;
1357- }
1358- tmp = PyArray_FromArrayAttr (op , requested_dtype , context );
1352+ tmp = PyArray_FromArrayAttr_int (op , requested_dtype , allow_copy );
13591353 if (tmp == NULL ) {
13601354 return NULL ;
13611355 }
@@ -2463,18 +2457,30 @@ PyArray_FromInterface(PyObject *origin)
24632457 return NULL ;
24642458}
24652459
2466- /*NUMPY_API
2460+
2461+ /**
2462+ * Check for an __array__ attribute and call it when it exists.
2463+ *
2464+ * .. warning:
2465+ * If returned, `NotImplemented` is borrowed and must not be Decref'd
2466+ *
2467+ * @param op The Python object to convert to an array.
2468+ * @param descr The desired `arr.dtype`, passed into the `__array__` call,
2469+ * as information but is not checked/enforced!
2470+ * @param never_copy Indicator that a copy is not allowed.
2471+ * NOTE: Currently, this means an error is raised instead of calling
2472+ * `op.__array__()`. In the future we could call for example call
2473+ * `op.__array__(never_copy=True)` instead.
2474+ * @returns NotImplemented if `__array__` is not defined or a NumPy array
2475+ * (or subclass). On error, return NULL.
24672476 */
24682477NPY_NO_EXPORT PyObject *
2469- PyArray_FromArrayAttr (PyObject * op , PyArray_Descr * typecode , PyObject * context )
2478+ PyArray_FromArrayAttr_int (
2479+ PyObject * op , PyArray_Descr * descr , int never_copy )
24702480{
24712481 PyObject * new ;
24722482 PyObject * array_meth ;
24732483
2474- if (context != NULL ) {
2475- PyErr_SetString (PyExc_RuntimeError , "'context' must be NULL" );
2476- return NULL ;
2477- }
24782484 array_meth = PyArray_LookupSpecial_OnInstance (op , "__array__" );
24792485 if (array_meth == NULL ) {
24802486 if (PyErr_Occurred ()) {
@@ -2490,6 +2496,16 @@ PyArray_FromArrayAttr(PyObject *op, PyArray_Descr *typecode, PyObject *context)
24902496 }
24912497 return Py_NotImplemented ;
24922498 }
2499+ if (never_copy ) {
2500+ /* Currently, we must always assume that `__array__` returns a copy */
2501+ PyErr_SetString (PyExc_ValueError ,
2502+ "Unable to avoid copy while converting from an object "
2503+ "implementing the `__array__` protocol. NumPy cannot ensure "
2504+ "that no copy will be made." );
2505+ Py_DECREF (array_meth );
2506+ return NULL ;
2507+ }
2508+
24932509 if (PyType_Check (op ) && PyObject_HasAttrString (array_meth , "__get__" )) {
24942510 /*
24952511 * If the input is a class `array_meth` may be a property-like object.
@@ -2500,11 +2516,11 @@ PyArray_FromArrayAttr(PyObject *op, PyArray_Descr *typecode, PyObject *context)
25002516 Py_DECREF (array_meth );
25012517 return Py_NotImplemented ;
25022518 }
2503- if (typecode == NULL ) {
2519+ if (descr == NULL ) {
25042520 new = PyObject_CallFunction (array_meth , NULL );
25052521 }
25062522 else {
2507- new = PyObject_CallFunction (array_meth , "O" , typecode );
2523+ new = PyObject_CallFunction (array_meth , "O" , descr );
25082524 }
25092525 Py_DECREF (array_meth );
25102526 if (new == NULL ) {
@@ -2520,6 +2536,21 @@ PyArray_FromArrayAttr(PyObject *op, PyArray_Descr *typecode, PyObject *context)
25202536 return new ;
25212537}
25222538
2539+
2540+ /*NUMPY_API
2541+ */
2542+ NPY_NO_EXPORT PyObject *
2543+ PyArray_FromArrayAttr (PyObject * op , PyArray_Descr * typecode , PyObject * context )
2544+ {
2545+ if (context != NULL ) {
2546+ PyErr_SetString (PyExc_RuntimeError , "'context' must be NULL" );
2547+ return NULL ;
2548+ }
2549+
2550+ return PyArray_FromArrayAttr_int (op , typecode , 0 );
2551+ }
2552+
2553+
25232554/*NUMPY_API
25242555* new reference -- accepts NULL for mintype
25252556*/
0 commit comments