Skip to content

Commit

Permalink
Merge pull request #18197 from seberg/array-protocol-errors
Browse files Browse the repository at this point in the history
BUG: Keep ignoring most errors during array-protocol lookup
  • Loading branch information
charris committed Jan 21, 2021
2 parents f10da39 + a054ffd commit 72be9ca
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 7 deletions.
19 changes: 17 additions & 2 deletions numpy/core/src/multiarray/ctors.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
12 changes: 7 additions & 5 deletions numpy/core/tests/test_array_coercion.py
Original file line number Diff line number Diff line change
Expand Up @@ -702,17 +702,19 @@ def test_too_large_array_error_paths(self):

@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])
Expand Down

0 comments on commit 72be9ca

Please sign in to comment.