diff options
| author | Charles Harris <charlesr.harris@gmail.com> | 2021-12-08 18:45:51 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-12-08 18:45:51 -0700 |
| commit | d565c4bf853b6e43c1ff83d72d0df0686cc934cf (patch) | |
| tree | 114b02ed8bacc14217970ac5ce766903bf569b67 /numpy | |
| parent | 6ae1a58e508a1f843ec3736488c67ac0bb793c16 (diff) | |
| parent | 5c7bda86395bbe648fa1e5205f66da21350ba6b0 (diff) | |
| download | numpy-d565c4bf853b6e43c1ff83d72d0df0686cc934cf.tar.gz | |
Merge pull request #20547 from seberg/revert-reduce-stuff
REV: Revert adding a default ufunc promoter
Diffstat (limited to 'numpy')
| -rw-r--r-- | numpy/core/src/umath/dispatching.c | 24 | ||||
| -rw-r--r-- | numpy/core/src/umath/ufunc_object.c | 68 | ||||
| -rw-r--r-- | numpy/core/tests/test_datetime.py | 8 |
3 files changed, 33 insertions, 67 deletions
diff --git a/numpy/core/src/umath/dispatching.c b/numpy/core/src/umath/dispatching.c index 4c6b09b80..934434370 100644 --- a/numpy/core/src/umath/dispatching.c +++ b/numpy/core/src/umath/dispatching.c @@ -592,17 +592,19 @@ legacy_promote_using_legacy_type_resolver(PyUFuncObject *ufunc, Py_INCREF(operation_DTypes[i]); Py_DECREF(out_descrs[i]); } - if (ufunc->type_resolver == &PyUFunc_SimpleBinaryComparisonTypeResolver) { - /* - * In this one case, the deprecation means that we actually override - * the signature. - */ - for (int i = 0; i < nargs; i++) { - if (signature[i] != NULL && signature[i] != operation_DTypes[i]) { - Py_INCREF(operation_DTypes[i]); - Py_SETREF(signature[i], operation_DTypes[i]); - *out_cacheable = 0; - } + /* + * The PyUFunc_SimpleBinaryComparisonTypeResolver has a deprecation + * warning (ignoring `dtype=`) and cannot be cached. + * All datetime ones *should* have a warning, but currently don't, + * but ignore all signature passing also. So they can also + * not be cached, and they mutate the signature which of course is wrong, + * but not doing it would confuse the code later. + */ + for (int i = 0; i < nargs; i++) { + if (signature[i] != NULL && signature[i] != operation_DTypes[i]) { + Py_INCREF(operation_DTypes[i]); + Py_SETREF(signature[i], operation_DTypes[i]); + *out_cacheable = 0; } } return 0; diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c index 9107323b0..1b310b471 100644 --- a/numpy/core/src/umath/ufunc_object.c +++ b/numpy/core/src/umath/ufunc_object.c @@ -2737,7 +2737,7 @@ reducelike_promote_and_resolve(PyUFuncObject *ufunc, } PyArrayMethodObject *ufuncimpl = promote_and_get_ufuncimpl(ufunc, - ops, signature, operation_DTypes, NPY_FALSE, NPY_FALSE, NPY_TRUE); + ops, signature, operation_DTypes, NPY_FALSE, NPY_TRUE, NPY_TRUE); /* Output can currently get cleared, others XDECREF in case of error */ Py_XDECREF(operation_DTypes[1]); if (out != NULL) { @@ -5194,60 +5194,18 @@ PyUFunc_FromFuncAndDataAndSignatureAndIdentity(PyUFuncGenericFunction *func, voi return NULL; } } - - PyObject *promoter = NULL; - if (ufunc->ntypes == 1) { - npy_bool all_object = NPY_TRUE; - for (int i = 0; i < ufunc->nargs; i++) { - if (ufunc->types[i] != NPY_OBJECT) { - all_object = NPY_FALSE; - break; - } - } - if (all_object) { - promoter = PyCapsule_New(&object_only_ufunc_promoter, - "numpy._ufunc_promoter", NULL); - if (promoter == NULL) { - Py_DECREF(ufunc); - return NULL; - } - } - } - if (promoter == NULL && ufunc->nin > 1) { - promoter = PyCapsule_New(&default_ufunc_promoter, - "numpy._ufunc_promoter", NULL); - if (promoter == NULL) { - Py_DECREF(ufunc); - return NULL; - } - } - if (promoter != NULL) { - /* Always install default promoter using the common DType */ - PyObject *dtype_tuple = PyTuple_New(ufunc->nargs); - if (dtype_tuple == NULL) { - Py_DECREF(promoter); - Py_DECREF(ufunc); - return NULL; - } - for (int i = 0; i < ufunc->nargs; i++) { - Py_INCREF(Py_None); - PyTuple_SET_ITEM(dtype_tuple, i, Py_None); - } - PyObject *info = PyTuple_Pack(2, dtype_tuple, promoter); - Py_DECREF(dtype_tuple); - Py_DECREF(promoter); - if (info == NULL) { - Py_DECREF(ufunc); - return NULL; - } - - int res = PyUFunc_AddLoop((PyUFuncObject *)ufunc, info, 0); - Py_DECREF(info); - if (res < 0) { - Py_DECREF(ufunc); - return NULL; - } - } + /* + * TODO: I tried adding a default promoter here (either all object for + * some special cases, or all homogeneous). Those are reasonable + * defaults, but short-cut a deprecated SciPy loop, where the + * homogeneous loop `ddd->d` was deprecated, but an inhomogeneous + * one `dld->d` should be picked. + * The default promoter *is* a reasonable default, but switched that + * behaviour. + * Another problem appeared due to buggy type-resolution for + * datetimes, this meant that `timedelta.sum(dtype="f8")` returned + * datetimes (and not floats or error), arguably wrong, but... + */ return (PyObject *)ufunc; } diff --git a/numpy/core/tests/test_datetime.py b/numpy/core/tests/test_datetime.py index c6a3d4e79..baae77a35 100644 --- a/numpy/core/tests/test_datetime.py +++ b/numpy/core/tests/test_datetime.py @@ -2029,11 +2029,17 @@ class TestDateTime: assert_equal(np.maximum.reduce(a), np.timedelta64(7, 's')) + def test_timedelta_correct_mean(self): + # test mainly because it worked only via a bug in that allowed: + # `timedelta.sum(dtype="f8")` to ignore the dtype request. + a = np.arange(1000, dtype="m8[s]") + assert_array_equal(a.mean(), a.sum() / len(a)) + def test_datetime_no_subtract_reducelike(self): # subtracting two datetime64 works, but we cannot reduce it, since # the result of that subtraction will have a different dtype. arr = np.array(["2021-12-02", "2019-05-12"], dtype="M8[ms]") - msg = r"ufunc 'subtract' did not contain a loop with signature " + msg = r"the resolved dtypes are not compatible" with pytest.raises(TypeError, match=msg): np.subtract.reduce(arr) |
