summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Berg <sebastian@sipsolutions.net>2021-01-20 15:29:21 -0600
committerSebastian Berg <sebastian@sipsolutions.net>2021-01-20 15:32:54 -0600
commita054ffd20ba2cd865a53e6ab149ae7d24acc97d9 (patch)
tree6d3bf30490c291982a2eabeabb487fbdfd7e0335
parentf10da39336097fca740dd1c407939eb9c6c4ca3e (diff)
downloadnumpy-a054ffd20ba2cd865a53e6ab149ae7d24acc97d9.tar.gz
BUG: Keep ignoring most errors during array-protocol lookup
Closes (the later point) in gh-17965 and reverts parts of gh-17817. Shapely did rely on being able to raise a NotImplementedError which then got ignored in the attribute lookup. Arguably, this should probably just raise an AttributeError to achieve that behaviour, but it means we can't just rip the band-aid off here. Since 1.20 is practically released, just reverting most of the change (leaving only recursion and memory error which are both arguably pretty fatal). Ignoring most errors should be deprecated (and I am happy to do so), but it is not important enough for 1.20 or very important in itself. Closes gh-17965
-rw-r--r--numpy/core/src/multiarray/ctors.c19
-rw-r--r--numpy/core/tests/test_array_coercion.py12
2 files changed, 24 insertions, 7 deletions
diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c
index 58571b678..ef105ff2d 100644
--- a/numpy/core/src/multiarray/ctors.c
+++ b/numpy/core/src/multiarray/ctors.c
@@ -2124,7 +2124,16 @@ PyArray_FromInterface(PyObject *origin)
if (iface == NULL) {
if (PyErr_Occurred()) {
- return NULL;
+ if (PyErr_ExceptionMatches(PyExc_RecursionError) ||
+ PyErr_ExceptionMatches(PyExc_MemoryError)) {
+ /* RecursionError and MemoryError are considered fatal */
+ return NULL;
+ }
+ /*
+ * This probably be deprecated, but at least shapely raised
+ * a NotImplementedError expecting it to be cleared (gh-17965)
+ */
+ PyErr_Clear();
}
return Py_NotImplemented;
}
@@ -2392,7 +2401,13 @@ PyArray_FromArrayAttr(PyObject *op, PyArray_Descr *typecode, PyObject *context)
array_meth = PyArray_LookupSpecial_OnInstance(op, "__array__");
if (array_meth == NULL) {
if (PyErr_Occurred()) {
- return NULL;
+ if (PyErr_ExceptionMatches(PyExc_RecursionError) ||
+ PyErr_ExceptionMatches(PyExc_MemoryError)) {
+ /* RecursionError and MemoryError are considered fatal */
+ return NULL;
+ }
+ /* This probably be deprecated. */
+ PyErr_Clear();
}
return Py_NotImplemented;
}
diff --git a/numpy/core/tests/test_array_coercion.py b/numpy/core/tests/test_array_coercion.py
index 08b32dfcc..8f709dbe1 100644
--- a/numpy/core/tests/test_array_coercion.py
+++ b/numpy/core/tests/test_array_coercion.py
@@ -702,17 +702,19 @@ class TestArrayLikes:
@pytest.mark.parametrize("attribute",
["__array_interface__", "__array__", "__array_struct__"])
- def test_bad_array_like_attributes(self, attribute):
- # Check that errors during attribute retrieval are raised unless
- # they are Attribute errors.
+ @pytest.mark.parametrize("error", [RecursionError, MemoryError])
+ def test_bad_array_like_attributes(self, attribute, error):
+ # RecursionError and MemoryError are considered fatal. All errors
+ # (except AttributeError) should probably be raised in the future,
+ # but shapely made use of it, so it will require a deprecation.
class BadInterface:
def __getattr__(self, attr):
if attr == attribute:
- raise RuntimeError
+ raise error
super().__getattr__(attr)
- with pytest.raises(RuntimeError):
+ with pytest.raises(error):
np.array(BadInterface())
@pytest.mark.parametrize("error", [RecursionError, MemoryError])