diff options
author | Stephan Hoyer <shoyer@google.com> | 2018-12-01 11:43:16 -0800 |
---|---|---|
committer | Stephan Hoyer <shoyer@google.com> | 2018-12-01 11:49:28 -0800 |
commit | bc143e02a20a23ca8c1b426f41201160eca0e376 (patch) | |
tree | 7fc7a7506375ba7848bf4f803333da0e23bcb405 /numpy/core/overrides.py | |
parent | b3a435305082699c26445630d9c79587d51ba9f1 (diff) | |
download | numpy-bc143e02a20a23ca8c1b426f41201160eca0e376.tar.gz |
MAINT: remove wrapper functions from numpy.core.multiarray
The original motivation for the style of these wrapper functions, introduced
in gh-12175, was to preserve introspection. But it turns out NumPy's functions
defined in C don't support introspection anyways, so the extra wrapper
functions are entirely pointless.
This version reverts the additional wrapper functions, which put default
arguments in two places and introduced slow-down due to the overhead of
another function call.
I've retained docstrings in multiarray.py, since it's definitely more readable
to keep docstrings and dispatchers together rather than leaving docstrings in
_add_newdocs.py.
One bonus of this approach is that dispatcher functions have the same name
as their implementations, so `np.concatenate(unknown=True)` gives an
error message mentioning "concatenate" rather than "_concatenate_dispatcher":
`TypeError: concatenate() got an unexpected keyword argument 'unknown'`
Diffstat (limited to 'numpy/core/overrides.py')
-rw-r--r-- | numpy/core/overrides.py | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/numpy/core/overrides.py b/numpy/core/overrides.py index 1cc1ff8d8..e8b1c6cd0 100644 --- a/numpy/core/overrides.py +++ b/numpy/core/overrides.py @@ -6,7 +6,7 @@ import collections import functools import os -from numpy.core._multiarray_umath import ndarray +from numpy.core._multiarray_umath import add_docstring, ndarray from numpy.compat._inspect import getargspec @@ -168,7 +168,8 @@ def set_module(module): return decorator -def array_function_dispatch(dispatcher, module=None, verify=True): +def array_function_dispatch(dispatcher, module=None, verify=True, + docs_from_dispatcher=False): """Decorator for adding dispatch with the __array_function__ protocol. See NEP-18 for example usage. @@ -198,12 +199,21 @@ def array_function_dispatch(dispatcher, module=None, verify=True): if not ENABLE_ARRAY_FUNCTION: # __array_function__ requires an explicit opt-in for now - return set_module(module) + def decorator(implementation): + if module is not None: + implementation.__module__ = module + if docs_from_dispatcher: + add_docstring(implementation, dispatcher.__doc__) + return implementation + return decorator def decorator(implementation): if verify: verify_matching_signatures(implementation, dispatcher) + if docs_from_dispatcher: + add_docstring(implementation, dispatcher.__doc__) + @functools.wraps(implementation) def public_api(*args, **kwargs): relevant_args = dispatcher(*args, **kwargs) @@ -220,3 +230,14 @@ def array_function_dispatch(dispatcher, module=None, verify=True): return public_api return decorator + + +def array_function_from_dispatcher( + implementation, module=None, verify=True, copy_docs=True): + """Like array_function_dispatcher, but with function arguments flipped.""" + + def decorator(dispatcher): + return array_function_dispatch( + dispatcher, module, verify=verify, + docs_from_dispatcher=copy_docs)(implementation) + return decorator |