Skip to content

Commit

Permalink
BUG: make attaching docstrings to __array_function__ funcs more r…
Browse files Browse the repository at this point in the history
…obust

Closes numpygh-14384
  • Loading branch information
rgommers committed May 11, 2020
1 parent ba9f93d commit ab13855
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 8 deletions.
26 changes: 18 additions & 8 deletions numpy/core/overrides.py
Expand Up @@ -13,8 +13,12 @@
int(os.environ.get('NUMPY_EXPERIMENTAL_ARRAY_FUNCTION', 1)))


add_docstring(
implement_array_function,
# We can't use add_newdoc (which is more robust than add_docstring) here to
# attach these docstrings (cyclic imports), and add_docstring() gives a
# RuntimeError on a reload (e.g. when using the %autoreload magic) - see
# gh-14384. So wrap in a try-except:
try:
add_docstring(implement_array_function,
"""
Implement a function with checks for __array_function__ overrides.
Expand Down Expand Up @@ -46,10 +50,8 @@
TypeError : if no implementation is found.
""")


# exposed for testing purposes; used internally by implement_array_function
add_docstring(
_get_implementing_args,
# exposed for testing purposes; used internally by implement_array_function
add_docstring(_get_implementing_args,
"""
Collect arguments on which to call __array_function__.
Expand All @@ -64,6 +66,8 @@
Sequence of arguments with __array_function__ methods, in the order in
which they should be called.
""")
except (RuntimeError, TypeError):
pass


ArgSpec = collections.namedtuple('ArgSpec', 'args varargs keywords defaults')
Expand Down Expand Up @@ -157,7 +161,10 @@ def array_function_dispatch(dispatcher, module=None, verify=True,
if not ARRAY_FUNCTION_ENABLED:
def decorator(implementation):
if docs_from_dispatcher:
add_docstring(implementation, dispatcher.__doc__)
try:
add_docstring(implementation, dispatcher.__doc__)
except (RuntimeError, TypeError):
pass
if module is not None:
implementation.__module__ = module
return implementation
Expand All @@ -168,7 +175,10 @@ def decorator(implementation):
verify_matching_signatures(implementation, dispatcher)

if docs_from_dispatcher:
add_docstring(implementation, dispatcher.__doc__)
try:
add_docstring(implementation, dispatcher.__doc__)
except (RuntimeError, TypeError):
pass

# Equivalently, we could define this function directly instead of using
# exec. This version has the advantage of giving the helper function a
Expand Down
13 changes: 13 additions & 0 deletions numpy/tests/test_reloading.py
@@ -1,8 +1,11 @@
import sys

from numpy.testing import assert_raises, assert_, assert_equal
from numpy.compat import pickle

from importlib import reload


def test_numpy_reloading():
# gh-7844. Also check that relevant globals retain their identity.
import numpy as np
Expand All @@ -29,3 +32,13 @@ def test_novalue():
assert_equal(repr(np._NoValue), '<no value>')
assert_(pickle.loads(pickle.dumps(np._NoValue,
protocol=proto)) is np._NoValue)

def test_reimport():
# Regression test for gh-14384
import numpy as np

for k in list(sys.modules.keys()):
if "numpy" in k:
del sys.modules[k]

import numpy as np

0 comments on commit ab13855

Please sign in to comment.