summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorSebastian Berg <sebastianb@nvidia.com>2023-03-22 12:20:00 +0100
committerGitHub <noreply@github.com>2023-03-22 12:20:00 +0100
commitb35aac2c35ccfd5efadd7f72a090c9ad99308a60 (patch)
treeb1bd47eb0b5f68488379d8ea631aaa9c360a7552 /doc
parent294c7f2c893b7e5ef783fc1cb1912d06404b452b (diff)
parentf3f108d313a8b8a4f7a90fb932867f17dc48b1f6 (diff)
downloadnumpy-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.rst11
-rw-r--r--doc/release/upcoming_changes/23240.compatibility.rst10
-rw-r--r--doc/source/reference/arrays.classes.rst5
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