diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2019-05-13 07:39:31 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-13 07:39:31 -0700 |
commit | 4ad33d21b1a30f931e23307e9f9355b70f633bed (patch) | |
tree | 8f86ac612c752dbdd9c38f2f2124156db4cf0a3a /numpy/core/overrides.py | |
parent | 0a4d842b26c107f23fdf0217649b27c6f0ca8041 (diff) | |
parent | 9055d2175f1dc509aa3025ea01546e6de689277f (diff) | |
download | numpy-4ad33d21b1a30f931e23307e9f9355b70f633bed.tar.gz |
Merge pull request #13529 from shoyer/array-function-exec
Use exec() instead array_function_dispatch to improve tracebacks
Diffstat (limited to 'numpy/core/overrides.py')
-rw-r--r-- | numpy/core/overrides.py | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/numpy/core/overrides.py b/numpy/core/overrides.py index 9f91adc83..bb6d8694a 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 |