diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2021-10-21 16:42:29 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-21 16:42:29 -0600 |
commit | 14d952da1b3095f5c8411761071610038d9fa648 (patch) | |
tree | 934c4051d74fd6063c40aa872f31f7ff18e82223 | |
parent | 7f61ddbf04e89ba78769c93472df8455b38111b9 (diff) | |
parent | fb6a4a69526c69d1f995cfa50105a3b6b2b38a9d (diff) | |
download | numpy-14d952da1b3095f5c8411761071610038d9fa648.tar.gz |
Merge pull request #20159 from seberg/relax-fallback-homogeneous-signature-try
BUG: Relax homogeneous signature fallback in type resolution
-rw-r--r-- | numpy/core/src/umath/ufunc_type_resolution.c | 11 | ||||
-rw-r--r-- | numpy/core/tests/test_ufunc.py | 5 |
2 files changed, 10 insertions, 6 deletions
diff --git a/numpy/core/src/umath/ufunc_type_resolution.c b/numpy/core/src/umath/ufunc_type_resolution.c index aa8d7b982..9ed923cf5 100644 --- a/numpy/core/src/umath/ufunc_type_resolution.c +++ b/numpy/core/src/umath/ufunc_type_resolution.c @@ -2164,6 +2164,10 @@ type_tuple_type_resolver(PyUFuncObject *self, * `signature=(None,)*nin + (dtype,)*nout`. If the signature matches that * exactly (could be relaxed but that is not necessary for backcompat), * we also try `signature=(dtype,)*(nin+nout)`. + * Since reduction pass in `(dtype, None, dtype)` we broaden this to + * replacing all unspecified dtypes with the homogeneous output one. + * Note that this can (and often will) lead to unsafe casting. This is + * normally rejected (but not currently for reductions!). * This used to be the main meaning for `dtype=dtype`, but some calls broke * the expectation, and changing it allows for `dtype=dtype` to be useful * for ufuncs like `np.ldexp` in the future while also normalizing it to @@ -2182,13 +2186,12 @@ type_tuple_type_resolver(PyUFuncObject *self, if (homogeneous_type != NPY_NOTYPE) { for (int i = 0; i < nin; i++) { if (specified_types[i] != NPY_NOTYPE) { - homogeneous_type = NPY_NOTYPE; - break; + /* Never replace a specified type! */ + continue; } specified_types[i] = homogeneous_type; } - } - if (homogeneous_type != NPY_NOTYPE) { + /* Try again with the homogeneous specified types. */ res = type_tuple_type_resolver_core(self, op, input_casting, casting, specified_types, any_object, diff --git a/numpy/core/tests/test_ufunc.py b/numpy/core/tests/test_ufunc.py index 78833a33c..4b06c8668 100644 --- a/numpy/core/tests/test_ufunc.py +++ b/numpy/core/tests/test_ufunc.py @@ -2383,8 +2383,9 @@ def test_reduce_casterrors(offset): out = np.array(-1, dtype=np.intp) count = sys.getrefcount(value) - with pytest.raises(TypeError): - # This is an unsafe cast, but we currently always allow that: + with pytest.raises(ValueError, match="invalid literal"): + # This is an unsafe cast, but we currently always allow that. + # Note that the double loop is picked, but the cast fails. np.add.reduce(arr, dtype=np.intp, out=out) assert count == sys.getrefcount(value) # If an error occurred during casting, the operation is done at most until |