@@ -1477,16 +1477,7 @@ _array_from_array_like(PyObject *op,
14771477 }
14781478 }
14791479
1480- /*
1481- * If op supplies the __array__ function.
1482- * The documentation says this should produce a copy, so
1483- * we skip this method if writeable is true, because the intent
1484- * of writeable is to modify the operand.
1485- * XXX: If the implementation is wrong, and/or if actual
1486- * usage requires this behave differently,
1487- * this should be changed!
1488- */
1489- if (!writeable && tmp == Py_NotImplemented ) {
1480+ if (tmp == Py_NotImplemented ) {
14901481tmp = PyArray_FromArrayAttr_int (op ,requested_dtype ,never_copy );
14911482if (tmp == NULL ) {
14921483return NULL ;
@@ -2418,9 +2409,8 @@ PyArray_FromInterface(PyObject *origin)
24182409 * @param descr The desired `arr.dtype`, passed into the `__array__` call,
24192410 * as information but is not checked/enforced!
24202411 * @param never_copy Specifies that a copy is not allowed.
2421- * NOTE: Currently, this means an error is raised instead of calling
2422- * `op.__array__()`. In the future we could call for example call
2423- * `op.__array__(never_copy=True)` instead.
2412+ * NOTE: For false it passes `op.__array__(copy=None)`,
2413+ * for true: `op.__array__(copy=False)`.
24242414 * @returns NotImplemented if `__array__` is not defined or a NumPy array
24252415 * (or subclass). On error, return NULL.
24262416 */
@@ -2438,15 +2428,6 @@ PyArray_FromArrayAttr_int(
24382428 }
24392429return Py_NotImplemented ;
24402430 }
2441- if (never_copy ) {
2442- /* Currently, we must always assume that `__array__` returns a copy */
2443- PyErr_SetString (PyExc_ValueError ,
2444- "Unable to avoid copy while converting from an object "
2445- "implementing the `__array__` protocol. NumPy cannot ensure "
2446- "that no copy will be made." );
2447- Py_DECREF (array_meth );
2448- return NULL ;
2449- }
24502431
24512432if (PyType_Check (op )&& PyObject_HasAttrString (array_meth ,"__get__" )) {
24522433/*
@@ -2458,12 +2439,30 @@ PyArray_FromArrayAttr_int(
24582439Py_DECREF (array_meth );
24592440return Py_NotImplemented ;
24602441 }
2461- if (descr == NULL ) {
2462- new = PyObject_CallFunction (array_meth ,NULL );
2463- }
2464- else {
2465- new = PyObject_CallFunction (array_meth ,"O" ,descr );
2442+
2443+ PyObject * copy = never_copy ?Py_False :Py_None ;
2444+ PyObject * kwargs = PyDict_New ();
2445+ PyDict_SetItemString (kwargs ,"copy" ,copy );
2446+ PyObject * args = descr != NULL ?PyTuple_Pack (1 ,descr ) :PyTuple_New (0 );
2447+
2448+ new = PyObject_Call (array_meth ,args ,kwargs );
2449+
2450+ if (PyErr_Occurred ()) {
2451+ PyObject * type ,* value ,* traceback ;
2452+ PyErr_Fetch (& type ,& value ,& traceback );
2453+ if (PyUnicode_Check (value )&& PyUnicode_CompareWithASCIIString (value ,
2454+ "__array__() got an unexpected keyword argument 'copy'" )== 0 ) {
2455+ if (PyErr_WarnEx (PyExc_UserWarning ,
2456+ "__array__ should implement 'copy' keyword" ,1 )< 0 ) {
2457+ return NULL ;
2458+ }
2459+ new = PyObject_Call (array_meth ,args ,NULL );
2460+ }else {
2461+ PyErr_Restore (type ,value ,traceback );
2462+ return NULL ;
2463+ }
24662464 }
2465+
24672466Py_DECREF (array_meth );
24682467if (new == NULL ) {
24692468return NULL ;