Skip to content

__array_function__ errors should more clearly identify the non-implemented function #12213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
shoyer opened this issue Oct 18, 2018 · 1 comment

Comments

@shoyer
Copy link
Member

shoyer commented Oct 18, 2018

xref #12028

Here's what you currently see if __array_function__ returns NotImplemented:

In [1]: import numpy as np

In [2]: class MyArray:
   ...:     def __array_function__(*args, **kwargs):
   ...:         return NotImplemented
   ...:

In [3]: np.sum(MyArray())
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-c8a80bb1d37e> in <module>()
----> 1 np.sum(MyArray())

~/dev/numpy/numpy/core/overrides.py in public_api(*args, **kwargs)
    149             relevant_args = dispatcher(*args, **kwargs)
    150             return array_function_implementation_or_override(
--> 151                 implementation, public_api, relevant_args, args, kwargs)
    152
    153         # TODO: remove this when we drop Python 2 support (functools.wraps

~/dev/numpy/numpy/core/overrides.py in array_function_implementation_or_override(implementation, public_api, relevant_args, args, kwargs)
    108     raise TypeError('no implementation found for {} on types that implement '
    109                     '__array_function__: {}'
--> 110                     .format(public_api, list(map(type, overloaded_args))))
    111
    112

TypeError: no implementation found for <function sum at 0x10e070bf8> on types that implement __array_function__: [<class '__main__.MyArray'>]

This error message should look something like this instead: TypeError: no implementation found for 'numpy.sum' on types that implement __array_function__: [<class '__main__.MyArray'>]

I think we will need to add a name parameter to array_function_override to do this properly. The best we could hope for with introspection is to use __module__ and __name__ to come up with something like numpy.core.fromnumeric.sum. This would be better what we currently have and could be a reasonable default, but we really don't want people reaching directly into internal modules like fromnumeric.

@shoyer
Copy link
Member Author

shoyer commented Oct 19, 2018

Interestingly, it looks like IPython has special code for printing functions based on __module__ rather than repr() or str:

>>> np.sum
<function numpy.core.fromnumeric.sum>

We could probably reproduce this inside __array_function__. Along with manually updating the __module__ attribute this would probably give us what we want. Usage would look something like:

@array_function_dispatch(_sum_dispatcher, module='numpy')
def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, initial=np._NoValue):
    ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant