summaryrefslogtreecommitdiff
path: root/numpy/core/overrides.py
diff options
context:
space:
mode:
authorStephan Hoyer <shoyer@google.com>2018-12-01 11:43:16 -0800
committerStephan Hoyer <shoyer@google.com>2018-12-01 11:49:28 -0800
commitbc143e02a20a23ca8c1b426f41201160eca0e376 (patch)
tree7fc7a7506375ba7848bf4f803333da0e23bcb405 /numpy/core/overrides.py
parentb3a435305082699c26445630d9c79587d51ba9f1 (diff)
downloadnumpy-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.py27
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