diff options
author | Matti Picus <matti.picus@gmail.com> | 2022-03-24 16:35:09 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-24 16:35:09 -0600 |
commit | 2c89e154c5130de2c49c4af7bf8ca83779861ae8 (patch) | |
tree | 6c9316f4c78afb4f09bca5dcba6d26c542bbcb03 /numpy | |
parent | c9689ca05a3084483a10c1b1d5570453a12d3ce6 (diff) | |
parent | e8e2ea0e020c0f0715f6b233543604f711533628 (diff) | |
download | numpy-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.c | 8 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 26 |
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: |