Skip to content

BUG: repr() broken on ndarray subclasses that define __array_function__ unless they support np.array_repr() #12162

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 13, 2018 · 3 comments

Comments

@shoyer
Copy link
Member

shoyer commented Oct 13, 2018

The problem appears to be that ndarray.__repr__ is mapped internally to call np.array_repr():

In [1]: import numpy as np

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

In [3]: repr(np.array(1).view(Sub))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-d6ff958f4fcf> in <module>()
----> 1 repr(np.array(1).view(Sub))

~/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         return public_api
    153

~/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 array_repr at 0x105692e18> on types that implement __array_function__: [<class '__main__.Sub'>]

This is a somewhat poor user experience. We should map ndarray.__repr__ to np.array_repr.__wrapped__ instead.

@tylerjereddy
Copy link
Contributor

Also, perhaps worth noting that array_repr() sometimes calls array_add() to determine the padding in the output, which may lead to confusion.

shoyer added a commit to shoyer/numpy that referenced this issue Oct 18, 2018
``ndarray.__repr__`` and ``ndarray.__str__`` should not rely upon
``__array_function__`` internally, so they are still well defined on subclasses
even if ``array_repr`` and ``array_str`` are not implemented.

Fixes numpygh-12162
@eric-wieser
Copy link
Member

eric-wieser commented Oct 19, 2018

What's special about __repr__ that means it's allowed to work when __array_function__ doesn't support it, yet something like np.reshape is not?

Should @array_function_dispatch(dispatcher, allow_not_implemented=True) be a thing, which causes the base function to run even if all the arguments return NotImplemented? I think this is like the NotImplementedButCoercible proposal, except it's a property of functions not the array-likes.

@shoyer
Copy link
Member Author

shoyer commented Oct 19, 2018

What's special about __repr__ that means it's allowed to work when __array_function__ doesn't support it, yet something like np.reshape is not?

I would expect that any ndarray method should work on subclasses as long as the method isn't overridden, regardless of whether or not __array_function__ is defined.

So np.reshape() isn't special enough, but .reshape() would be.

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

3 participants