# Week-9 Ufunc Overrides

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 `a`

, then `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
its `__numpy_ufunc__`

method (if it has one) and seeing that it does not return
`NotImplemented`

.

So Basically if a ufunc has three inputs (`a, b, as`

) in that order, where `as`

is a subtype of `a`

. They will be tried in the order `b > as > a`

.

### Argument Normalization¶

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
`__numpy_ufunc__`

method.

## Comments

Comments powered by Disqus