diff options
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/core/src/umath/ufunc_object.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c index 415ff0f07..2674c85d9 100644 --- a/numpy/core/src/umath/ufunc_object.c +++ b/numpy/core/src/umath/ufunc_object.c @@ -2720,6 +2720,21 @@ reducelike_promote_and_resolve(PyUFuncObject *ufunc, * is NULL) so we pass `arr` instead in that case. */ PyArrayObject *ops[3] = {out ? out : arr, arr, out}; + + /* + * TODO: This is a dangerous hack, that works by relying on the GIL, it is + * terrible, terrifying, and trusts that nobody does crazy stuff + * in their type-resolvers. + * By mutating the `out` dimension, we ensure that reduce-likes + * live in a future without value-based promotion even when legacy + * promotion has to be used. + */ + npy_bool evil_ndim_mutating_hack = NPY_FALSE; + if (out != NULL && PyArray_NDIM(out) == 0 && PyArray_NDIM(arr) != 0) { + evil_ndim_mutating_hack = NPY_TRUE; + ((PyArrayObject_fields *)out)->nd = 1; + } + /* * TODO: If `out` is not provided, arguably `initial` could define * the first DType (and maybe also the out one), that way @@ -2740,6 +2755,9 @@ reducelike_promote_and_resolve(PyUFuncObject *ufunc, PyArrayMethodObject *ufuncimpl = promote_and_get_ufuncimpl(ufunc, ops, signature, operation_DTypes, NPY_FALSE, NPY_TRUE, NPY_TRUE); + if (evil_ndim_mutating_hack) { + ((PyArrayObject_fields *)out)->nd = 0; + } /* DTypes may currently get filled in fallbacks and XDECREF for error: */ Py_XDECREF(operation_DTypes[0]); Py_XDECREF(operation_DTypes[1]); |