summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorMatti Picus <matti.picus@gmail.com>2022-03-24 16:35:09 -0600
committerGitHub <noreply@github.com>2022-03-24 16:35:09 -0600
commit2c89e154c5130de2c49c4af7bf8ca83779861ae8 (patch)
tree6c9316f4c78afb4f09bca5dcba6d26c542bbcb03 /numpy
parentc9689ca05a3084483a10c1b1d5570453a12d3ce6 (diff)
parente8e2ea0e020c0f0715f6b233543604f711533628 (diff)
downloadnumpy-2c89e154c5130de2c49c4af7bf8ca83779861ae8.tar.gz
Merge pull request #21231 from seberg/array-prio
BUG: Catch error if array-priority is not float compatible
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c8
-rw-r--r--numpy/core/tests/test_multiarray.py26
2 files changed, 33 insertions, 1 deletions
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c
index f206ce2c6..831e68705 100644
--- a/numpy/core/src/multiarray/multiarraymodule.c
+++ b/numpy/core/src/multiarray/multiarraymodule.c
@@ -129,12 +129,18 @@ PyArray_GetPriority(PyObject *obj, double default_)
ret = PyArray_LookupSpecial_OnInstance(obj, "__array_priority__");
if (ret == NULL) {
if (PyErr_Occurred()) {
- PyErr_Clear(); /* TODO[gh-14801]: propagate crashes during attribute access? */
+ /* TODO[gh-14801]: propagate crashes during attribute access? */
+ PyErr_Clear();
}
return default_;
}
priority = PyFloat_AsDouble(ret);
+ if (error_converting(priority)) {
+ /* TODO[gh-14801]: propagate crashes for bad priority? */
+ PyErr_Clear();
+ return default_;
+ }
Py_DECREF(ret);
return priority;
}
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index 6ba90a97f..8c7f00cb4 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -3694,6 +3694,32 @@ class TestBinop:
check(make_obj(np.ndarray, array_ufunc=None), True, False, False,
check_scalar=False)
+ @pytest.mark.parametrize("priority", [None, "runtime error"])
+ def test_ufunc_binop_bad_array_priority(self, priority):
+ # Mainly checks that this does not crash. The second array has a lower
+ # priority than -1 ("error value"). If the __radd__ actually exists,
+ # bad things can happen (I think via the scalar paths).
+ # In principle both of these can probably just be errors in the future.
+ class BadPriority:
+ @property
+ def __array_priority__(self):
+ if priority == "runtime error":
+ raise RuntimeError("RuntimeError in __array_priority__!")
+ return priority
+
+ def __radd__(self, other):
+ return "result"
+
+ class LowPriority(np.ndarray):
+ __array_priority__ = -1000
+
+ # Priority failure uses the same as scalars (smaller -1000). So the
+ # LowPriority wins with 'result' for each element (inner operation).
+ res = np.arange(3).view(LowPriority) + BadPriority()
+ assert res.shape == (3,)
+ assert res[0] == 'result'
+
+
def test_ufunc_override_normalize_signature(self):
# gh-5674
class SomeClass: