diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2015-06-12 13:33:40 -0600 |
---|---|---|
committer | Charles Harris <charlesr.harris@gmail.com> | 2015-06-12 15:20:19 -0600 |
commit | 8f172ddbb90357e80bafa2cd7df4b307ce15600b (patch) | |
tree | 584fe3bc99eba768060257657a22a1ebc6369a1f | |
parent | 30d755d8737505717d54ed32501261bb94130a7f (diff) | |
download | numpy-8f172ddbb90357e80bafa2cd7df4b307ce15600b.tar.gz |
BUG: Make type_tuple_type_resolver more robust.
When a loop match fails on account of casting, continue searching the
loops until success or all loops have been examined. The failure to do
this was causing true_divide to fail with float inputs and dtype=float
because the first loop found was (int8, int8, float64), leading to a
casting error as float cannot be safely cast to int8. Versions of numpy
previous to 1.10 will still fail silently if this is backported as the
casting rules were less strict, so that would also need fixing.
Closes #3484.
-rw-r--r-- | numpy/core/src/umath/ufunc_type_resolution.c | 33 |
1 files changed, 13 insertions, 20 deletions
diff --git a/numpy/core/src/umath/ufunc_type_resolution.c b/numpy/core/src/umath/ufunc_type_resolution.c index fe2e8cac3..601ffadbf 100644 --- a/numpy/core/src/umath/ufunc_type_resolution.c +++ b/numpy/core/src/umath/ufunc_type_resolution.c @@ -2106,7 +2106,6 @@ type_tuple_type_resolver(PyUFuncObject *self, for (i = 0; i < self->ntypes; ++i) { char *orig_types = self->types + i*self->nargs; - int matched = 1; /* Copy the types into an int array for matching */ for (j = 0; j < nop; ++j) { @@ -2116,17 +2115,17 @@ type_tuple_type_resolver(PyUFuncObject *self, if (n_specified == nop) { for (j = 0; j < nop; ++j) { if (types[j] != specified_types[j] && - specified_types[j] != NPY_NOTYPE) { - matched = 0; + specified_types[j] != NPY_NOTYPE) { break; } } - } else { - if (types[nin] != specified_types[0]) { - matched = 0; + if (j < nop) { + /* no match */ + continue; } } - if (!matched) { + else if (types[nin] != specified_types[0]) { + /* no match */ continue; } @@ -2136,29 +2135,23 @@ type_tuple_type_resolver(PyUFuncObject *self, types, NULL, &no_castable_output, &err_src_typecode, &err_dst_typecode)) { - /* Error */ case -1: + /* Error */ return -1; - /* It worked */ + case 0: + /* Cannot cast inputs */ + continue; case 1: + /* Success */ set_ufunc_loop_data_types(self, op, out_dtype, types, NULL); return 0; - /* Didn't work */ - case 0: - PyErr_Format(PyExc_TypeError, - "found a loop for ufunc '%s' " - "matching the type-tuple, " - "but the inputs and/or outputs could not be " - "cast according to the casting rule", - ufunc_name); - return -1; } } /* If no function was found, throw an error */ PyErr_Format(PyExc_TypeError, - "No loop matching the specified signature was found " - "for ufunc %s", ufunc_name); + "No loop matching the specified signature and casting\n" + "was found for ufunc %s", ufunc_name); return -1; } |