This week I'm still working on the pull request for ufunc overrides, however I think it is finally nearing completion. The implementation is working as described and all tests are passing. I'm looking forward to working on SciPy again.
The main aspects I've been working on are ufunc overrides method resolution order, and argument normalization.
Method Resolution Order (MRO)¶
Python functions in certain cases have a special MRO which is a bit more
complicated than the default left to right. Whenever ther right argument is a
subtype of the left argument its special method corresponding to the calling
function is called first. So for example,
add(a, b) would normally call
a.__add__(b) but if
b is a subtype of
b.__radd__(a) is called.
However there are no examples in the Python standard library of a ternary or
greater function from which we can copy. So we have tried to generalize this
concept to a higher order.
The MRO algorithm is succinctly stated by @njsmith as:
While there remain untried inputs, pick the leftmost one which does not have a proper subtype still remaining to be checked.
Where inputs are the inputs to the ufunc. Trying an input refers to calling
__numpy_ufunc__ method (if it has one) and seeing that it does not return
So Basically if a ufunc has three inputs (
a, b, as) in that order, where
is a subtype of
a. They will be tried in the order
b > as > a.
Many of NumPy's ufuncs can take a
out argument, which specifies where the
output of the ufunc is assigned. The
out argument can be passed as either a
positional, or keyword argument. So naïvely checking a ufuncs arguments for
__numpy_ufunc__ and then passing said arguments unaltered is not always
sensible. So given
nargs - the number of args, and
nin - the number of
inputs, we can check for an
out positional argument and move it to the
keyword arguments. The normalized arguments are then passed the