summaryrefslogtreecommitdiff
path: root/numpy/core/overrides.py
diff options
context:
space:
mode:
authorStephan Hoyer <shoyer@google.com>2019-05-13 08:09:26 -0700
committerStephan Hoyer <shoyer@google.com>2019-05-13 08:09:26 -0700
commit07452c86c78a1cf213a764d17f060b4887ec3681 (patch)
tree12c7ae7b14552bd28334277e7e244b603ca4300a /numpy/core/overrides.py
parent804f71bb42fef775a85a52366dc4bd1a22c130a8 (diff)
parent4ad33d21b1a30f931e23307e9f9355b70f633bed (diff)
downloadnumpy-07452c86c78a1cf213a764d17f060b4887ec3681.tar.gz
Merge branch 'master' into implement-numpy-implementation
Diffstat (limited to 'numpy/core/overrides.py')
-rw-r--r--numpy/core/overrides.py24
1 files changed, 22 insertions, 2 deletions
diff --git a/numpy/core/overrides.py b/numpy/core/overrides.py
index d4697b8a6..ad4d1c721 100644
--- a/numpy/core/overrides.py
+++ b/numpy/core/overrides.py
@@ -1,6 +1,7 @@
"""Implementation of __array_function__ overrides from NEP-18."""
import collections
import functools
+import textwrap
from numpy.core._multiarray_umath import (
add_docstring, implement_array_function, _get_implementing_args)
@@ -143,11 +144,30 @@ def array_function_dispatch(dispatcher, module=None, verify=True,
if docs_from_dispatcher:
add_docstring(implementation, dispatcher.__doc__)
+ # Equivalently, we could define this function directly instead of using
+ # exec. This version has the advantage of giving the helper function a
+ # more interpettable name. Otherwise, the original function does not
+ # show up at all in many cases, e.g., if it's written in C or if the
+ # dispatcher gets an invalid keyword argument.
+ source = textwrap.dedent("""
@functools.wraps(implementation)
- def public_api(*args, **kwargs):
+ def {name}(*args, **kwargs):
relevant_args = dispatcher(*args, **kwargs)
return implement_array_function(
- implementation, public_api, relevant_args, args, kwargs)
+ implementation, {name}, relevant_args, args, kwargs)
+ """).format(name=implementation.__name__)
+
+ source_object = compile(
+ source, filename='<__array_function__ internals>', mode='exec')
+ scope = {
+ 'implementation': implementation,
+ 'dispatcher': dispatcher,
+ 'functools': functools,
+ 'implement_array_function': implement_array_function,
+ }
+ exec(source_object, scope)
+
+ public_api = scope[implementation.__name__]
if module is not None:
public_api.__module__ = module