summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/core/src/multiarray/compiled_base.c11
-rw-r--r--numpy/tests/test_reloading.py26
2 files changed, 34 insertions, 3 deletions
diff --git a/numpy/core/src/multiarray/compiled_base.c b/numpy/core/src/multiarray/compiled_base.c
index 308e72009..5cf18049d 100644
--- a/numpy/core/src/multiarray/compiled_base.c
+++ b/numpy/core/src/multiarray/compiled_base.c
@@ -1425,7 +1425,7 @@ arr_add_docstring(PyObject *NPY_UNUSED(dummy), PyObject *args)
#else
char *docstr;
#endif
- static char *msg = "already has a docstring";
+ static char *msg = "already has a different docstring";
PyObject *tp_dict = PyArrayDescr_Type.tp_dict;
PyObject *myobj;
static PyTypeObject *PyMemberDescr_TypePtr = NULL;
@@ -1482,7 +1482,7 @@ arr_add_docstring(PyObject *NPY_UNUSED(dummy), PyObject *args)
if (!(doc)) { \
doc = docstr; \
} \
- else { \
+ else if (strcmp(doc, docstr) != 0) { \
PyErr_Format(PyExc_RuntimeError, "%s method %s", name, msg); \
return NULL; \
} \
@@ -1507,7 +1507,12 @@ arr_add_docstring(PyObject *NPY_UNUSED(dummy), PyObject *args)
PyObject *doc_attr;
doc_attr = PyObject_GetAttrString(obj, "__doc__");
- if (doc_attr != NULL && doc_attr != Py_None) {
+ if (doc_attr != NULL && doc_attr != Py_None &&
+ (PyUnicode_Compare(doc_attr, str) != 0)) {
+ if (PyErr_Occurred()) {
+ /* error during PyUnicode_Compare */
+ return NULL;
+ }
PyErr_Format(PyExc_RuntimeError, "object %s", msg);
return NULL;
}
diff --git a/numpy/tests/test_reloading.py b/numpy/tests/test_reloading.py
index 860832be8..61ae91b00 100644
--- a/numpy/tests/test_reloading.py
+++ b/numpy/tests/test_reloading.py
@@ -1,8 +1,12 @@
from numpy.testing import assert_raises, assert_, assert_equal
from numpy.compat import pickle
+import sys
+import subprocess
+import textwrap
from importlib import reload
+
def test_numpy_reloading():
# gh-7844. Also check that relevant globals retain their identity.
import numpy as np
@@ -29,3 +33,25 @@ def test_novalue():
assert_equal(repr(np._NoValue), '<no value>')
assert_(pickle.loads(pickle.dumps(np._NoValue,
protocol=proto)) is np._NoValue)
+
+
+def test_full_reimport():
+ """At the time of writing this, it is *not* truly supported, but
+ apparently enough users rely on it, for it to be an annoying change
+ when it started failing previously.
+ """
+ # Test within a new process, to ensure that we do not mess with the
+ # global state during the test run (could lead to cryptic test failures).
+ # This is generally unsafe, especially, since we also reload the C-modules.
+ code = textwrap.dedent(r"""
+ import sys
+ import numpy as np
+
+ for k in list(sys.modules.keys()):
+ if "numpy" in k:
+ del sys.modules[k]
+
+ import numpy as np
+ """)
+ p = subprocess.run([sys.executable, '-c', code])
+ assert p.returncode == 0