summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2017-07-05 15:40:01 -0600
committerGitHub <noreply@github.com>2017-07-05 15:40:01 -0600
commit459a8839c09df5c8e89337aae3314d4105f896ea (patch)
tree74a6067bd79f08a552cdbc5b18ae7a0b5ac8beb6 /numpy
parent34d72cea2cd8d7eb037b4f4f31ca654a09b458ce (diff)
parent13978dd80c152ca53c8a8b344f59be86a4bd9f44 (diff)
downloadnumpy-459a8839c09df5c8e89337aae3314d4105f896ea.tar.gz
Merge pull request #9354 from eric-wieser/fix-type-resolver-hang
BUG: Prevent hang traversing ufunc userloop linked list
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/umath/ufunc_type_resolution.c22
-rw-r--r--numpy/core/tests/test_ufunc.py5
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):