summaryrefslogtreecommitdiff
path: root/numpy/core/src/multiarray
diff options
context:
space:
mode:
authorNico Schlömer <nico.schloemer@gmail.com>2023-04-20 18:00:59 +0200
committerGitHub <noreply@github.com>2023-04-20 18:00:59 +0200
commit1acac891f99075128450aacf2a4538de3ff9d028 (patch)
treed7de52ce7cbac0e2ae51eb68ec2ca4289a9eb77f /numpy/core/src/multiarray
parent64e692f741da5bf781870de7f6cd1aa5bb5a4070 (diff)
downloadnumpy-1acac891f99075128450aacf2a4538de3ff9d028.tar.gz
DEP: deprecate scalar conversions for arrays with ndim > 0 (#10615)
This PR reflects some of the progress achieved in issue #10404 and is used to asses the impact of the changes. With the changes in this PR, `float(numpy.array([1.0])` now gives a warning; likewise some other things: ```python import numpy a = numpy.random.rand(10, 1) a[0] = numpy.array([1.0]) # okay a[0] = numpy.array(1.0) # okay a[0] = 1.0 # okay b = numpy.random.rand(10) b[0] = numpy.array([1.0]) # ValueError: setting an array element with a sequence. b[0, ...] = numpy.array([1.0]) # okay b[0] = numpy.array(1.0) # okay b[0] = 1.0 # okay ``` This aligns the behavior of numpy arrays with that of lists: ```python float([3.14]) ``` ``` TypeError: float() argument must be a string or a number, not 'list' ``` ```python import numpy as np a = np.random.rand(5) a[0] = [3.14] ``` ``` ValueError: setting an array element with a sequence. ``` Fixes #10404.
Diffstat (limited to 'numpy/core/src/multiarray')
-rw-r--r--numpy/core/src/multiarray/common.c29
-rw-r--r--numpy/core/src/multiarray/common.h7
-rw-r--r--numpy/core/src/multiarray/methods.c4
-rw-r--r--numpy/core/src/multiarray/number.c6
4 files changed, 39 insertions, 7 deletions
diff --git a/numpy/core/src/multiarray/common.c b/numpy/core/src/multiarray/common.c
index 001d299c7..573d0d606 100644
--- a/numpy/core/src/multiarray/common.c
+++ b/numpy/core/src/multiarray/common.c
@@ -441,3 +441,32 @@ new_array_for_sum(PyArrayObject *ap1, PyArrayObject *ap2, PyArrayObject* out,
}
}
+NPY_NO_EXPORT int
+check_is_convertible_to_scalar(PyArrayObject *v)
+{
+ if (PyArray_NDIM(v) == 0) {
+ return 0;
+ }
+
+ /* Remove this if-else block when the deprecation expires */
+ if (PyArray_SIZE(v) == 1) {
+ /* Numpy 1.25.0, 2023-01-02 */
+ if (DEPRECATE(
+ "Conversion of an array with ndim > 0 to a scalar "
+ "is deprecated, and will error in future. "
+ "Ensure you extract a single element from your array "
+ "before performing this operation. "
+ "(Deprecated NumPy 1.25.)") < 0) {
+ return -1;
+ }
+ return 0;
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "only length-1 arrays can be converted to Python scalars");
+ return -1;
+ }
+
+ PyErr_SetString(PyExc_TypeError,
+ "only 0-dimensional arrays can be converted to Python scalars");
+ return -1;
+}
diff --git a/numpy/core/src/multiarray/common.h b/numpy/core/src/multiarray/common.h
index 127c6250d..cb9fadc4e 100644
--- a/numpy/core/src/multiarray/common.h
+++ b/numpy/core/src/multiarray/common.h
@@ -332,6 +332,13 @@ PyArray_TupleFromItems(int n, PyObject *const *items, int make_null_none)
return tuple;
}
+/*
+ * Returns 0 if the array has rank 0, -1 otherwise. Prints a deprecation
+ * warning for arrays of _size_ 1.
+ */
+NPY_NO_EXPORT int
+check_is_convertible_to_scalar(PyArrayObject *v);
+
#include "ucsnarrow.h"
diff --git a/numpy/core/src/multiarray/methods.c b/numpy/core/src/multiarray/methods.c
index 93b290020..3b2e72820 100644
--- a/numpy/core/src/multiarray/methods.c
+++ b/numpy/core/src/multiarray/methods.c
@@ -2804,9 +2804,7 @@ array_complex(PyArrayObject *self, PyObject *NPY_UNUSED(args))
PyArray_Descr *dtype;
PyObject *c;
- if (PyArray_SIZE(self) != 1) {
- PyErr_SetString(PyExc_TypeError,
- "only length-1 arrays can be converted to Python scalars");
+ if (check_is_convertible_to_scalar(self) < 0) {
return NULL;
}
diff --git a/numpy/core/src/multiarray/number.c b/numpy/core/src/multiarray/number.c
index c208fb203..35e4af79c 100644
--- a/numpy/core/src/multiarray/number.c
+++ b/numpy/core/src/multiarray/number.c
@@ -869,13 +869,11 @@ array_scalar_forward(PyArrayObject *v,
PyObject *(*builtin_func)(PyObject *),
const char *where)
{
- PyObject *scalar;
- if (PyArray_SIZE(v) != 1) {
- PyErr_SetString(PyExc_TypeError, "only size-1 arrays can be"\
- " converted to Python scalars");
+ if (check_is_convertible_to_scalar(v) < 0) {
return NULL;
}
+ PyObject *scalar;
scalar = PyArray_GETITEM(v, PyArray_DATA(v));
if (scalar == NULL) {
return NULL;