# Buggy code
def array_function_dispatch(dispatcher, module=None, verify=True):
    """Decorator for adding dispatch with the __array_function__ protocol."""

    def decorator(implementation):
        # TODO: only do this check when the appropriate flag is enabled or for
        # a dev install. We want this check for testing but don't want to
        # slow down all numpy imports.
        if verify:
            verify_matching_signatures(implementation, dispatcher)

        @functools.wraps(implementation)
        def public_api(*args, **kwargs):
            relevant_args = dispatcher(*args, **kwargs)
            return array_function_implementation_or_override(
                implementation, public_api, relevant_args, args, kwargs
            )

        if module is not None:
            public_api.__module__ = module

        return public_api

    return decorator


# Traceback (TypeError)
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'>]

# Fixed code
def array_function_dispatch(dispatcher, module=None, verify=True):
    """Decorator for adding dispatch with the __array_function__ protocol."""

    def decorator(implementation):
        # TODO: only do this check when the appropriate flag is enabled or for
        # a dev install. We want this check for testing but don't want to
        # slow down all numpy imports.
        if verify:
            verify_matching_signatures(implementation, dispatcher)

        @functools.wraps(implementation)
        def public_api(*args, **kwargs):
            relevant_args = dispatcher(*args, **kwargs)
            return array_function_implementation_or_override(
                implementation, public_api, relevant_args, args, kwargs
            )

        if module is not None:
            public_api.__module__ = module

        # TODO: remove this when we drop Python 2 support (functools.wraps
        # adds __wrapped__ automatically in later versions)
        public_api.__wrapped__ = implementation

        return public_api

    return decorator