test_reloading.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import pickle
  2. import subprocess
  3. import sys
  4. import textwrap
  5. from importlib import reload
  6. import pytest
  7. import numpy.exceptions as ex
  8. from numpy.testing import IS_WASM, assert_, assert_equal, assert_raises
  9. @pytest.mark.thread_unsafe(reason="reloads global module")
  10. def test_numpy_reloading():
  11. # gh-7844. Also check that relevant globals retain their identity.
  12. import numpy as np
  13. import numpy._globals
  14. _NoValue = np._NoValue
  15. VisibleDeprecationWarning = ex.VisibleDeprecationWarning
  16. ModuleDeprecationWarning = ex.ModuleDeprecationWarning
  17. with pytest.warns(UserWarning):
  18. reload(np)
  19. assert_(_NoValue is np._NoValue)
  20. assert_(ModuleDeprecationWarning is ex.ModuleDeprecationWarning)
  21. assert_(VisibleDeprecationWarning is ex.VisibleDeprecationWarning)
  22. assert_raises(RuntimeError, reload, numpy._globals)
  23. with pytest.warns(UserWarning):
  24. reload(np)
  25. assert_(_NoValue is np._NoValue)
  26. assert_(ModuleDeprecationWarning is ex.ModuleDeprecationWarning)
  27. assert_(VisibleDeprecationWarning is ex.VisibleDeprecationWarning)
  28. def test_novalue():
  29. import numpy as np
  30. for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
  31. assert_equal(repr(np._NoValue), '<no value>')
  32. assert_(pickle.loads(pickle.dumps(np._NoValue,
  33. protocol=proto)) is np._NoValue)
  34. @pytest.mark.skipif(IS_WASM, reason="can't start subprocess")
  35. def test_full_reimport():
  36. # Reimporting numpy like this is not safe due to use of global C state,
  37. # and has unexpected side effects. Test that an ImportError is raised.
  38. # When all extension modules are isolated, this should test that clearing
  39. # sys.modules and reimporting numpy works without error.
  40. # Test within a new process, to ensure that we do not mess with the
  41. # global state during the test run (could lead to cryptic test failures).
  42. # This is generally unsafe, especially, since we also reload the C-modules.
  43. code = textwrap.dedent(r"""
  44. import sys
  45. import numpy as np
  46. for k in [k for k in sys.modules if k.startswith('numpy')]:
  47. del sys.modules[k]
  48. try:
  49. import numpy as np
  50. except ImportError as err:
  51. if str(err) != "cannot load module more than once per process":
  52. raise SystemExit(f"Unexpected ImportError: {err}")
  53. else:
  54. raise SystemExit("DID NOT RAISE ImportError")
  55. """)
  56. p = subprocess.run(
  57. (sys.executable, '-c', code),
  58. stdout=subprocess.PIPE,
  59. stderr=subprocess.STDOUT,
  60. encoding='utf-8',
  61. check=False,
  62. )
  63. assert p.returncode == 0, p.stdout