summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/__init__.py58
-rw-r--r--numpy/_globals.py62
-rw-r--r--numpy/tests/test_reloading.py14
3 files changed, 81 insertions, 53 deletions
diff --git a/numpy/__init__.py b/numpy/__init__.py
index 4be750c19..5384d61ab 100644
--- a/numpy/__init__.py
+++ b/numpy/__init__.py
@@ -109,56 +109,8 @@ from __future__ import division, absolute_import, print_function
import sys
import warnings
-# Disallow reloading numpy. Doing that does nothing to change previously
-# loaded modules, which would need to be reloaded separately, but it does
-# change the identity of the warnings and sentinal classes defined below
-# with dire consequences when checking for identity.
-if '_is_loaded' in globals():
- raise RuntimeError('Reloading numpy is not supported')
-_is_loaded = True
-
-
-# Define some global warnings and the _NoValue sentinal. Defining them here
-# means that their identity will change if numpy is reloaded, hence if that is
-# to be allowed they should be moved into their own, non-reloadable module.
-# Note that these should be defined (or imported) before the other imports.
-class ModuleDeprecationWarning(DeprecationWarning):
- """Module deprecation warning.
-
- The nose tester turns ordinary Deprecation warnings into test failures.
- That makes it hard to deprecate whole modules, because they get
- imported by default. So this is a special Deprecation warning that the
- nose tester will let pass without making tests fail.
-
- """
- pass
-
-
-class VisibleDeprecationWarning(UserWarning):
- """Visible deprecation warning.
-
- By default, python will not show deprecation warnings, so this class
- can be used when a very visible warning is helpful, for example because
- the usage is most likely a user bug.
-
- """
- pass
-
-
-class _NoValue:
- """Special keyword value.
-
- This class may be used as the default value assigned to a deprecated
- keyword in order to check if it has been given a user defined value.
- """
- pass
-
-
-# oldnumeric and numarray were removed in 1.9. In case some packages import
-# but do not use them, we define them here for backward compatibility.
-oldnumeric = 'removed'
-numarray = 'removed'
-
+from ._globals import ModuleDeprecationWarning, VisibleDeprecationWarning
+from ._globals import _NoValue
# We first need to detect if we're being called as part of the numpy setup
# procedure itself in a reliable manner.
@@ -177,6 +129,7 @@ else:
its source directory; please exit the numpy source tree, and relaunch
your python interpreter from there."""
raise ImportError(msg)
+
from .version import git_revision as __git_revision__
from .version import version as __version__
@@ -239,3 +192,8 @@ else:
warnings.filterwarnings("ignore", message="numpy.dtype size changed")
warnings.filterwarnings("ignore", message="numpy.ufunc size changed")
warnings.filterwarnings("ignore", message="numpy.ndarray size changed")
+
+ # oldnumeric and numarray were removed in 1.9. In case some packages import
+ # but do not use them, we define them here for backward compatibility.
+ oldnumeric = 'removed'
+ numarray = 'removed'
diff --git a/numpy/_globals.py b/numpy/_globals.py
new file mode 100644
index 000000000..64a84da96
--- /dev/null
+++ b/numpy/_globals.py
@@ -0,0 +1,62 @@
+"""
+Module defining global singleton classes.
+
+This module raises a RuntimeError if an attempt to reload it is made. In that
+way the identities of the classes defined here are fixed and will remain so
+even if numpy itself is reloaded. In particular, a function like the following
+will still work correctly after numpy is reloaded::
+
+ def foo(arg=np._NoValue):
+ if arg is np._NoValue:
+ ...
+
+That was not the case when the singleton classes were defined in the numpy
+``__init__.py`` file. See gh-7844 for a discussion of the reload problem that
+motivated this module.
+
+"""
+from __future__ import division, absolute_import, print_function
+
+
+__ALL__ = [
+ 'ModuleDeprecationWarning', 'VisibleDeprecationWarning', '_NoValue'
+ ]
+
+
+# Disallow reloading this module so as to preserve the identities of the
+# classes defined here.
+if '_is_loaded' in globals():
+ raise RuntimeError('Reloading numpy._globals is not allowed')
+_is_loaded = True
+
+
+class ModuleDeprecationWarning(DeprecationWarning):
+ """Module deprecation warning.
+
+ The nose tester turns ordinary Deprecation warnings into test failures.
+ That makes it hard to deprecate whole modules, because they get
+ imported by default. So this is a special Deprecation warning that the
+ nose tester will let pass without making tests fail.
+
+ """
+ pass
+
+
+class VisibleDeprecationWarning(UserWarning):
+ """Visible deprecation warning.
+
+ By default, python will not show deprecation warnings, so this class
+ can be used when a very visible warning is helpful, for example because
+ the usage is most likely a user bug.
+
+ """
+ pass
+
+
+class _NoValue:
+ """Special keyword value.
+
+ This class may be used as the default value assigned to a deprecated
+ keyword in order to check if it has been given a user defined value.
+ """
+ pass
diff --git a/numpy/tests/test_reloading.py b/numpy/tests/test_reloading.py
index 141e11f6c..ca651c874 100644
--- a/numpy/tests/test_reloading.py
+++ b/numpy/tests/test_reloading.py
@@ -2,7 +2,6 @@ from __future__ import division, absolute_import, print_function
import sys
-import numpy as np
from numpy.testing import assert_raises, assert_, run_module_suite
if sys.version_info[:2] >= (3, 4):
@@ -10,13 +9,22 @@ if sys.version_info[:2] >= (3, 4):
else:
from imp import reload
-def test_reloading_exception():
+def test_numpy_reloading():
# gh-7844. Also check that relevant globals retain their identity.
+ import numpy as np
+ import numpy._globals
+
_NoValue = np._NoValue
VisibleDeprecationWarning = np.VisibleDeprecationWarning
ModuleDeprecationWarning = np.ModuleDeprecationWarning
- assert_raises(RuntimeError, reload, np)
+ reload(np)
+ assert_(_NoValue is np._NoValue)
+ assert_(ModuleDeprecationWarning is np.ModuleDeprecationWarning)
+ assert_(VisibleDeprecationWarning is np.VisibleDeprecationWarning)
+
+ assert_raises(RuntimeError, reload, numpy._globals)
+ reload(np)
assert_(_NoValue is np._NoValue)
assert_(ModuleDeprecationWarning is np.ModuleDeprecationWarning)
assert_(VisibleDeprecationWarning is np.VisibleDeprecationWarning)