diff options
| author | Gagandeep Singh <gdp.1807@gmail.com> | 2021-11-10 12:32:03 +0530 |
|---|---|---|
| committer | Gagandeep Singh <gdp.1807@gmail.com> | 2021-11-10 12:32:24 +0530 |
| commit | 2cf561ba0284dd4dd70d0396262974495cb4edfa (patch) | |
| tree | 5effd55f4dab9f6c00e1d63c867f2db992bbe93a | |
| parent | 7658ad93ba845fd1e7cd6ef81f266b5d18fd565d (diff) | |
| download | numpy-2cf561ba0284dd4dd70d0396262974495cb4edfa.tar.gz | |
Prohibited calling ``__array__`` method in never copy mode
| -rw-r--r-- | numpy/core/src/multiarray/array_coercion.c | 13 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/array_coercion.h | 2 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/arrayobject.c | 2 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/common.c | 2 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/ctors.c | 14 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/ctors.h | 3 | ||||
| -rw-r--r-- | numpy/core/tests/test_multiarray.py | 3 |
7 files changed, 25 insertions, 14 deletions
diff --git a/numpy/core/src/multiarray/array_coercion.c b/numpy/core/src/multiarray/array_coercion.c index 847bdafc3..60525026c 100644 --- a/numpy/core/src/multiarray/array_coercion.c +++ b/numpy/core/src/multiarray/array_coercion.c @@ -865,7 +865,8 @@ PyArray_DiscoverDTypeAndShape_Recursive( PyObject *obj, int curr_dims, int max_dims, PyArray_Descr**out_descr, npy_intp out_shape[NPY_MAXDIMS], coercion_cache_obj ***coercion_cache_tail_ptr, - PyArray_DTypeMeta *fixed_DType, enum _dtype_discovery_flags *flags) + PyArray_DTypeMeta *fixed_DType, enum _dtype_discovery_flags *flags, + int do_copy) { PyArrayObject *arr = NULL; PyObject *seq; @@ -923,7 +924,7 @@ PyArray_DiscoverDTypeAndShape_Recursive( requested_descr = *out_descr; } arr = (PyArrayObject *)_array_from_array_like(obj, - requested_descr, 0, NULL); + requested_descr, 0, NULL, do_copy); if (arr == NULL) { return -1; } @@ -1117,7 +1118,7 @@ PyArray_DiscoverDTypeAndShape_Recursive( max_dims = PyArray_DiscoverDTypeAndShape_Recursive( objects[i], curr_dims + 1, max_dims, out_descr, out_shape, coercion_cache_tail_ptr, fixed_DType, - flags); + flags, do_copy); if (max_dims < 0) { return -1; @@ -1169,7 +1170,7 @@ PyArray_DiscoverDTypeAndShape( npy_intp out_shape[NPY_MAXDIMS], coercion_cache_obj **coercion_cache, PyArray_DTypeMeta *fixed_DType, PyArray_Descr *requested_descr, - PyArray_Descr **out_descr) + PyArray_Descr **out_descr, int do_copy) { coercion_cache_obj **coercion_cache_head = coercion_cache; *coercion_cache = NULL; @@ -1214,7 +1215,7 @@ PyArray_DiscoverDTypeAndShape( int ndim = PyArray_DiscoverDTypeAndShape_Recursive( obj, 0, max_dims, out_descr, out_shape, &coercion_cache, - fixed_DType, &flags); + fixed_DType, &flags, do_copy); if (ndim < 0) { goto fail; } @@ -1499,7 +1500,7 @@ _discover_array_parameters(PyObject *NPY_UNUSED(self), int ndim = PyArray_DiscoverDTypeAndShape( obj, NPY_MAXDIMS, shape, &coercion_cache, - fixed_DType, fixed_descriptor, (PyArray_Descr **)&out_dtype); + fixed_DType, fixed_descriptor, (PyArray_Descr **)&out_dtype, 0); Py_XDECREF(fixed_DType); Py_XDECREF(fixed_descriptor); if (ndim < 0) { diff --git a/numpy/core/src/multiarray/array_coercion.h b/numpy/core/src/multiarray/array_coercion.h index db0e479fe..fe59b731c 100644 --- a/numpy/core/src/multiarray/array_coercion.h +++ b/numpy/core/src/multiarray/array_coercion.h @@ -31,7 +31,7 @@ PyArray_DiscoverDTypeAndShape( npy_intp out_shape[NPY_MAXDIMS], coercion_cache_obj **coercion_cache, PyArray_DTypeMeta *fixed_DType, PyArray_Descr *requested_descr, - PyArray_Descr **out_descr); + PyArray_Descr **out_descr, int do_copy); NPY_NO_EXPORT int PyArray_ExtractDTypeAndDescriptor(PyObject *dtype, diff --git a/numpy/core/src/multiarray/arrayobject.c b/numpy/core/src/multiarray/arrayobject.c index c8aaced4e..1b197d0f2 100644 --- a/numpy/core/src/multiarray/arrayobject.c +++ b/numpy/core/src/multiarray/arrayobject.c @@ -263,7 +263,7 @@ PyArray_CopyObject(PyArrayObject *dest, PyObject *src_object) */ ndim = PyArray_DiscoverDTypeAndShape(src_object, PyArray_NDIM(dest), dims, &cache, - NPY_DTYPE(PyArray_DESCR(dest)), PyArray_DESCR(dest), &dtype); + NPY_DTYPE(PyArray_DESCR(dest)), PyArray_DESCR(dest), &dtype, 0); if (ndim < 0) { return -1; } diff --git a/numpy/core/src/multiarray/common.c b/numpy/core/src/multiarray/common.c index 82d34193d..aa95d285a 100644 --- a/numpy/core/src/multiarray/common.c +++ b/numpy/core/src/multiarray/common.c @@ -119,7 +119,7 @@ PyArray_DTypeFromObject(PyObject *obj, int maxdims, PyArray_Descr **out_dtype) int ndim; ndim = PyArray_DiscoverDTypeAndShape( - obj, maxdims, shape, &cache, NULL, NULL, out_dtype); + obj, maxdims, shape, &cache, NULL, NULL, out_dtype, 0); if (ndim < 0) { return -1; } diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c index 2170a9a99..23d868c2c 100644 --- a/numpy/core/src/multiarray/ctors.c +++ b/numpy/core/src/multiarray/ctors.c @@ -1291,7 +1291,8 @@ fail: */ NPY_NO_EXPORT PyObject * _array_from_array_like(PyObject *op, - PyArray_Descr *requested_dtype, npy_bool writeable, PyObject *context) { + PyArray_Descr *requested_dtype, npy_bool writeable, PyObject *context, + int do_copy) { PyObject* tmp; /* @@ -1347,6 +1348,12 @@ _array_from_array_like(PyObject *op, * this should be changed! */ if (!writeable && tmp == Py_NotImplemented) { + PyObject* array_meth = PyArray_LookupSpecial_OnInstance(op, "__array__"); + PyObject* has_get = array_meth && PyType_Check(op) && PyObject_HasAttrString(array_meth, "__get__"); + if (array_meth != NULL && !has_get && do_copy) { + PyErr_SetString(PyExc_ValueError, "Calling __array__ in never copy mode is not allowed."); + return NULL; + } tmp = PyArray_FromArrayAttr(op, requested_dtype, context); if (tmp == NULL) { return NULL; @@ -1447,7 +1454,7 @@ setArrayFromSequence(PyArrayObject *a, PyObject *s, } /* Try __array__ before using s as a sequence */ - PyObject *tmp = _array_from_array_like(s, NULL, 0, NULL); + PyObject *tmp = _array_from_array_like(s, NULL, 0, NULL, 0); if (tmp == NULL) { goto fail; } @@ -1575,7 +1582,8 @@ PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int min_depth, Py_XDECREF(newtype); ndim = PyArray_DiscoverDTypeAndShape(op, - NPY_MAXDIMS, dims, &cache, fixed_DType, fixed_descriptor, &dtype); + NPY_MAXDIMS, dims, &cache, fixed_DType, fixed_descriptor, &dtype, + flags & NPY_ARRAY_ENSURENOCOPY); Py_XDECREF(fixed_descriptor); Py_XDECREF(fixed_DType); diff --git a/numpy/core/src/multiarray/ctors.h b/numpy/core/src/multiarray/ctors.h index e59e86e8b..4f8bd5a82 100644 --- a/numpy/core/src/multiarray/ctors.h +++ b/numpy/core/src/multiarray/ctors.h @@ -32,7 +32,8 @@ PyArray_New( NPY_NO_EXPORT PyObject * _array_from_array_like(PyObject *op, - PyArray_Descr *requested_dtype, npy_bool writeable, PyObject *context); + PyArray_Descr *requested_dtype, npy_bool writeable, PyObject *context, + int do_copy); NPY_NO_EXPORT PyObject * PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int min_depth, diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index 4ef58d904..18302543a 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -7943,7 +7943,8 @@ class TestArrayCreationCopyArgument(object): assert_array_equal(res, base_arr) assert res is base_arr # numpy trusts the ArrayLike - assert np.array(arr, copy=np._CopyMode.NEVER) is base_arr + with pytest.raises(ValueError): + np.array(arr, copy=np._CopyMode.NEVER) @pytest.mark.parametrize( "arr", [np.ones(()), np.arange(81).reshape((9, 9))]) |
