diff options
| author | Sebastian Berg <sebastianb@nvidia.com> | 2023-03-22 12:20:00 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-22 12:20:00 +0100 |
| commit | b35aac2c35ccfd5efadd7f72a090c9ad99308a60 (patch) | |
| tree | b1bd47eb0b5f68488379d8ea631aaa9c360a7552 /doc | |
| parent | 294c7f2c893b7e5ef783fc1cb1912d06404b452b (diff) | |
| parent | f3f108d313a8b8a4f7a90fb932867f17dc48b1f6 (diff) | |
| download | numpy-b35aac2c35ccfd5efadd7f72a090c9ad99308a60.tar.gz | |
Merge pull request #23240 from byrdie/bugfix/ufunc_where_propagation
ENH: Allow ``where`` argument to override ``__array_ufunc__``
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/neps/nep-0013-ufunc-overrides.rst | 11 | ||||
| -rw-r--r-- | doc/release/upcoming_changes/23240.compatibility.rst | 10 | ||||
| -rw-r--r-- | doc/source/reference/arrays.classes.rst | 5 |
3 files changed, 21 insertions, 5 deletions
diff --git a/doc/neps/nep-0013-ufunc-overrides.rst b/doc/neps/nep-0013-ufunc-overrides.rst index c132113db..d69af6924 100644 --- a/doc/neps/nep-0013-ufunc-overrides.rst +++ b/doc/neps/nep-0013-ufunc-overrides.rst @@ -20,6 +20,8 @@ NEP 13 — A mechanism for overriding Ufuncs :Date: 2017-03-31 :Status: Final +:Updated: 2023-02-19 +:Author: Roy Smart Executive summary ================= @@ -173,12 +175,12 @@ where in all current cases only a single output makes sense). The function dispatch proceeds as follows: -- If one of the input or output arguments implements +- If one of the input, output, or ``where`` arguments implements ``__array_ufunc__``, it is executed instead of the ufunc. - If more than one of the arguments implements ``__array_ufunc__``, they are tried in the following order: subclasses before superclasses, - inputs before outputs, otherwise left to right. + inputs before outputs, outputs before ``where``, otherwise left to right. - The first ``__array_ufunc__`` method returning something else than :obj:`NotImplemented` determines the return value of the Ufunc. @@ -326,7 +328,10 @@ equivalent to:: def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): # Cannot handle items that have __array_ufunc__ (other than our own). outputs = kwargs.get('out', ()) - for item in inputs + outputs: + objs = inputs + outputs + if "where" in kwargs: + objs = objs + (kwargs["where"], ) + for item in objs: if (hasattr(item, '__array_ufunc__') and type(item).__array_ufunc__ is not ndarray.__array_ufunc__): return NotImplemented diff --git a/doc/release/upcoming_changes/23240.compatibility.rst b/doc/release/upcoming_changes/23240.compatibility.rst new file mode 100644 index 000000000..28536a020 --- /dev/null +++ b/doc/release/upcoming_changes/23240.compatibility.rst @@ -0,0 +1,10 @@ +Array-likes that define ``__array_ufunc__`` can now override ufuncs if used as ``where`` +---------------------------------------------------------------------------------------- +If the ``where`` keyword argument of a :class:`numpy.ufunc` is a subclass of +:class:`numpy.ndarray` or is a duck type that defines +:func:`numpy.class.__array_ufunc__` it can override the behavior of the ufunc +using the same mechanism as the input and output arguments. +Note that for this to work properly, the ``where.__array_ufunc__`` +implementation will have to unwrap the ``where`` argument to pass it into the +default implementation of the ``ufunc`` or, for :class:`numpy.ndarray` +subclasses before using ``super().__array_ufunc__``.
\ No newline at end of file diff --git a/doc/source/reference/arrays.classes.rst b/doc/source/reference/arrays.classes.rst index 2cce595e0..34da83670 100644 --- a/doc/source/reference/arrays.classes.rst +++ b/doc/source/reference/arrays.classes.rst @@ -71,10 +71,11 @@ NumPy provides several hooks that classes can customize: The method should return either the result of the operation, or :obj:`NotImplemented` if the operation requested is not implemented. - If one of the input or output arguments has a :func:`__array_ufunc__` + If one of the input, output, or ``where`` arguments has a :func:`__array_ufunc__` method, it is executed *instead* of the ufunc. If more than one of the arguments implements :func:`__array_ufunc__`, they are tried in the - order: subclasses before superclasses, inputs before outputs, otherwise + order: subclasses before superclasses, inputs before outputs, + outputs before ``where``, otherwise left to right. The first routine returning something other than :obj:`NotImplemented` determines the result. If all of the :func:`__array_ufunc__` operations return :obj:`NotImplemented`, a |
