diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2017-07-05 15:40:01 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-07-05 15:40:01 -0600 |
commit | 459a8839c09df5c8e89337aae3314d4105f896ea (patch) | |
tree | 74a6067bd79f08a552cdbc5b18ae7a0b5ac8beb6 | |
parent | 34d72cea2cd8d7eb037b4f4f31ca654a09b458ce (diff) | |
parent | 13978dd80c152ca53c8a8b344f59be86a4bd9f44 (diff) | |
download | numpy-459a8839c09df5c8e89337aae3314d4105f896ea.tar.gz |
Merge pull request #9354 from eric-wieser/fix-type-resolver-hang
BUG: Prevent hang traversing ufunc userloop linked list
-rw-r--r-- | numpy/core/src/umath/ufunc_type_resolution.c | 22 | ||||
-rw-r--r-- | numpy/core/tests/test_ufunc.py | 5 |
2 files changed, 15 insertions, 12 deletions
diff --git a/numpy/core/src/umath/ufunc_type_resolution.c b/numpy/core/src/umath/ufunc_type_resolution.c index 0fd3c45c5..b7e12f50f 100644 --- a/numpy/core/src/umath/ufunc_type_resolution.c +++ b/numpy/core/src/umath/ufunc_type_resolution.c @@ -1305,8 +1305,9 @@ find_userloop(PyUFuncObject *ufunc, if (obj == NULL) { continue; } - funcdata = (PyUFunc_Loop1d *)NpyCapsule_AsVoidPtr(obj); - while (funcdata != NULL) { + for (funcdata = (PyUFunc_Loop1d *)NpyCapsule_AsVoidPtr(obj); + funcdata != NULL; + funcdata = funcdata->next) { int *types = funcdata->arg_types; for (j = 0; j < nargs; ++j) { @@ -1320,8 +1321,6 @@ find_userloop(PyUFuncObject *ufunc, *out_innerloopdata = funcdata->data; return 1; } - - funcdata = funcdata->next; } } } @@ -1727,8 +1726,9 @@ linear_search_userloop_type_resolver(PyUFuncObject *self, if (obj == NULL) { continue; } - funcdata = (PyUFunc_Loop1d *)NpyCapsule_AsVoidPtr(obj); - while (funcdata != NULL) { + for (funcdata = (PyUFunc_Loop1d *)NpyCapsule_AsVoidPtr(obj); + funcdata != NULL; + funcdata = funcdata->next) { int *types = funcdata->arg_types; switch (ufunc_loop_matches(self, op, input_casting, output_casting, @@ -1744,8 +1744,6 @@ linear_search_userloop_type_resolver(PyUFuncObject *self, set_ufunc_loop_data_types(self, op, out_dtype, types, funcdata->arg_dtypes); return 1; } - - funcdata = funcdata->next; } } } @@ -1792,8 +1790,10 @@ type_tuple_userloop_type_resolver(PyUFuncObject *self, if (obj == NULL) { continue; } - funcdata = (PyUFunc_Loop1d *)NpyCapsule_AsVoidPtr(obj); - while (funcdata != NULL) { + + for (funcdata = (PyUFunc_Loop1d *)NpyCapsule_AsVoidPtr(obj); + funcdata != NULL; + funcdata = funcdata->next) { int *types = funcdata->arg_types; int matched = 1; @@ -1838,8 +1838,6 @@ type_tuple_userloop_type_resolver(PyUFuncObject *self, case -1: return -1; } - - funcdata = funcdata->next; } } } diff --git a/numpy/core/tests/test_ufunc.py b/numpy/core/tests/test_ufunc.py index 9c49932e0..d7c3374bf 100644 --- a/numpy/core/tests/test_ufunc.py +++ b/numpy/core/tests/test_ufunc.py @@ -1011,6 +1011,11 @@ class TestUfunc(TestCase): dtype=rational) assert_equal(result, expected) + def test_custom_ufunc_forced_sig(self): + # gh-9351 - looking for a non-first userloop would previously hang + assert_raises(TypeError, + np.multiply, rational(1), 1, signature=(rational, int, None)) + def test_custom_array_like(self): class MyThing(object): |