diff options
-rw-r--r-- | numpy/core/src/multiarray/compiled_base.c | 11 | ||||
-rw-r--r-- | numpy/tests/test_reloading.py | 26 |
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 |