summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorGagandeep Singh <gdp.1807@gmail.com>2021-11-10 12:32:03 +0530
committerGagandeep Singh <gdp.1807@gmail.com>2021-11-10 12:32:24 +0530
commit2cf561ba0284dd4dd70d0396262974495cb4edfa (patch)
tree5effd55f4dab9f6c00e1d63c867f2db992bbe93a /numpy
parent7658ad93ba845fd1e7cd6ef81f266b5d18fd565d (diff)
downloadnumpy-2cf561ba0284dd4dd70d0396262974495cb4edfa.tar.gz
Prohibited calling ``__array__`` method in never copy mode
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/multiarray/array_coercion.c13
-rw-r--r--numpy/core/src/multiarray/array_coercion.h2
-rw-r--r--numpy/core/src/multiarray/arrayobject.c2
-rw-r--r--numpy/core/src/multiarray/common.c2
-rw-r--r--numpy/core/src/multiarray/ctors.c14
-rw-r--r--numpy/core/src/multiarray/ctors.h3
-rw-r--r--numpy/core/tests/test_multiarray.py3
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))])