[Numpy-discussion] Implementations of ndarray.__array_function__ (and ndarray.__array_ufunc__)

Marten van Kerkwijk m.h.vankerkwijk at gmail.com
Sun Nov 4 11:44:06 EST 2018

Hi again,

Another thought about __array_function__, this time about the
implementation for ndarray. In it, we currently check whether any of the
types define a (different) __array_function__, and, if so, give up. This
seems too strict: I think that, at least in principle, subclasses should be
allowed through even if they override __array_function__.

This thought was triggered by Travis pointing to the Liskov substitution
principle [1], that code written for a given type should just work on a
(properly written) subclass. This suggests `ndarray` should not exclude
subclasses even if they override __array_function__, since if the subclass
does not work that way, it can already ensure an error is raised since it
knows it is called first.

Indeed, this is also how python itself works: if, eg., I subclass list as
class MyList(list):
    def __radd__(self, other):
        return NotImplemented
then any `list + mylist` will just concatenate the lists, even though
`MyList.__radd__` explicitly tells it cannot do it (it returning
`NotImplemented` means that  `list.__add__` gets a change).

The reason that we do not already follow this logic may be that currently
`ndarray.__array_function__` ends by calling the public function, which
will lead to infinite recursion if there is a subclass that overrides
__array_function__ and returns NotImplemented. However, inside
ndarray.__array_function__, there is no real reason to call the public
function - one might as well just call the implementation, in which case
this is not a problem.

Does the above make sense? I realize that the same would be true for
`__array_ufunc__`, though there the situation is slightly trickier since it
is not as easy to bypass any further override checks. Nevertheless, it does
seem like it would be correct to do the same there. (And if we agree this
is the case, I'd quite happily implement it -- with the merger of
multiarray and umath it has become much easier to do.)

All the best,


[1] https://en.wikipedia.org/wiki/Liskov_substitution_principle
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20181104/b52ff32f/attachment.html>

More information about the NumPy-Discussion mailing list