summaryrefslogtreecommitdiff
path: root/numpy/testing/tests
diff options
context:
space:
mode:
authorSebastian Berg <sebastian@sipsolutions.net>2016-06-19 13:00:13 +0200
committerCharles Harris <charlesr.harris@gmail.com>2016-08-28 13:30:43 -0600
commit3c34457ac9e6c11f9197f513013d8ab1ee9d9236 (patch)
tree08c646973bbac1d693a6f2e5a99fabc6f4aaca27 /numpy/testing/tests
parent90668d0e740e30102fa3d0a1a72b485ebe9d99c3 (diff)
downloadnumpy-3c34457ac9e6c11f9197f513013d8ab1ee9d9236.tar.gz
ENH,TST: Add new warning suppression/filtering context
This context has a couple of advantages over the typical one, and can ensure that warnings are cleanly filtered without side effect for later tests.
Diffstat (limited to 'numpy/testing/tests')
-rw-r--r--numpy/testing/tests/test_utils.py186
1 files changed, 182 insertions, 4 deletions
diff --git a/numpy/testing/tests/test_utils.py b/numpy/testing/tests/test_utils.py
index 842d55b37..6ba0b5a75 100644
--- a/numpy/testing/tests/test_utils.py
+++ b/numpy/testing/tests/test_utils.py
@@ -10,7 +10,7 @@ from numpy.testing import (
assert_array_almost_equal, build_err_msg, raises, assert_raises,
assert_warns, assert_no_warnings, assert_allclose, assert_approx_equal,
assert_array_almost_equal_nulp, assert_array_max_ulp,
- clear_and_catch_warnings, run_module_suite,
+ clear_and_catch_warnings, suppress_warnings, run_module_suite,
assert_string_equal, assert_, tempdir, temppath,
)
import unittest
@@ -795,14 +795,16 @@ class TestStringEqual(unittest.TestCase):
lambda: assert_string_equal("foo", "hello"))
-def assert_warn_len_equal(mod, n_in_context):
+def assert_warn_len_equal(mod, n_in_context, py3_n_in_context=None):
mod_warns = mod.__warningregistry__
# Python 3.4 appears to clear any pre-existing warnings of the same type,
# when raising warnings inside a catch_warnings block. So, there is a
# warning generated by the tests within the context manager, but no
# previous warnings.
if 'version' in mod_warns:
- assert_equal(len(mod_warns), 2) # including 'version'
+ if py3_n_in_context is None:
+ py3_n_in_context = n_in_context
+ assert_equal(len(mod_warns)-1, py3_n_in_context)
else:
assert_equal(len(mod_warns), n_in_context)
@@ -840,7 +842,183 @@ def test_clear_and_catch_warnings():
with clear_and_catch_warnings():
warnings.simplefilter('ignore')
warnings.warn('Another warning')
- assert_warn_len_equal(my_mod, 2)
+ assert_warn_len_equal(my_mod, 2, 1)
+
+
+def test_suppress_warnings_module():
+ # Initial state of module, no warnings
+ my_mod = _get_fresh_mod()
+ assert_equal(getattr(my_mod, '__warningregistry__', {}), {})
+
+ def warn_other_module():
+ # Apply along axis is implemented in python; stacklevel=2 means
+ # we end up inside its module, not ours.
+ def warn(arr):
+ warnings.warn("Some warning 2", stacklevel=2)
+ return arr
+ np.apply_along_axis(warn, 0, [0])
+
+ # Test module based warning suppression:
+ with suppress_warnings() as sup:
+ sup.record(UserWarning)
+ # suppress warning from other module (may have .pyc ending),
+ # if apply_along_axis is moved, had to be changed.
+ sup.filter(module=np.lib.shape_base)
+ warnings.warn("Some warning")
+ warn_other_module()
+ # Check that the suppression did test the file correctly (this module
+ # got filtered)
+ assert_(len(sup.log) == 1)
+ assert_(sup.log[0].message.args[0] == "Some warning")
+
+ assert_warn_len_equal(my_mod, 0)
+ sup = suppress_warnings()
+ # Will have to be changed if apply_along_axis is moved:
+ sup.filter(module=my_mod)
+ with sup:
+ warnings.warn('Some warning')
+ assert_warn_len_equal(my_mod, 0)
+ # And test repeat works:
+ sup.filter(module=my_mod)
+ with sup:
+ warnings.warn('Some warning')
+ assert_warn_len_equal(my_mod, 0)
+
+ # Without specified modules, don't clear warnings during context
+ with suppress_warnings():
+ warnings.simplefilter('ignore')
+ warnings.warn('Some warning')
+ assert_warn_len_equal(my_mod, 1)
+
+
+def test_suppress_warnings_type():
+ # Initial state of module, no warnings
+ my_mod = _get_fresh_mod()
+ assert_equal(getattr(my_mod, '__warningregistry__', {}), {})
+
+ # Test module based warning suppression:
+ with suppress_warnings() as sup:
+ sup.filter(UserWarning)
+ warnings.warn('Some warning')
+ assert_warn_len_equal(my_mod, 0)
+ sup = suppress_warnings()
+ sup.filter(UserWarning)
+ with sup:
+ warnings.warn('Some warning')
+ assert_warn_len_equal(my_mod, 0)
+ # And test repeat works:
+ sup.filter(module=my_mod)
+ with sup:
+ warnings.warn('Some warning')
+ assert_warn_len_equal(my_mod, 0)
+
+ # Without specified modules, don't clear warnings during context
+ with suppress_warnings():
+ warnings.simplefilter('ignore')
+ warnings.warn('Some warning')
+ assert_warn_len_equal(my_mod, 1)
+
+
+def test_suppress_warnings_decorate_no_record():
+ sup = suppress_warnings()
+ sup.filter(UserWarning)
+
+ @sup
+ def warn(category):
+ warnings.warn('Some warning', category)
+
+ with warnings.catch_warnings(record=True) as w:
+ warnings.simplefilter("always")
+ warn(UserWarning) # should be supppressed
+ warn(RuntimeWarning)
+ assert_(len(w) == 1)
+
+
+def test_suppress_warnings_record():
+ sup = suppress_warnings()
+ log1 = sup.record()
+
+ with sup:
+ log2 = sup.record(message='Some other warning 2')
+ sup.filter(message='Some warning')
+ warnings.warn('Some warning')
+ warnings.warn('Some other warning')
+ warnings.warn('Some other warning 2')
+
+ assert_(len(sup.log) == 2)
+ assert_(len(log1) == 1)
+ assert_(len(log2) == 1)
+ assert_(log2[0].message.args[0] == 'Some other warning 2')
+
+ # Do it again, with the same context to see if some warnings survived:
+ with sup:
+ log2 = sup.record(message='Some other warning 2')
+ sup.filter(message='Some warning')
+ warnings.warn('Some warning')
+ warnings.warn('Some other warning')
+ warnings.warn('Some other warning 2')
+
+ assert_(len(sup.log) == 2)
+ assert_(len(log1) == 1)
+ assert_(len(log2) == 1)
+ assert_(log2[0].message.args[0] == 'Some other warning 2')
+
+ # Test nested:
+ with suppress_warnings() as sup:
+ sup.record()
+ with suppress_warnings() as sup2:
+ sup2.record(message='Some warning')
+ warnings.warn('Some warning')
+ warnings.warn('Some other warning')
+ assert_(len(sup2.log) == 1)
+ assert_(len(sup.log) == 1)
+
+
+def test_suppress_warnings_forwarding():
+ def warn_other_module():
+ # Apply along axis is implemented in python; stacklevel=2 means
+ # we end up inside its module, not ours.
+ def warn(arr):
+ warnings.warn("Some warning", stacklevel=2)
+ return arr
+ np.apply_along_axis(warn, 0, [0])
+
+ with suppress_warnings() as sup:
+ sup.record()
+ with suppress_warnings("always"):
+ for i in range(2):
+ warnings.warn("Some warning")
+
+ assert_(len(sup.log) == 2)
+
+ with suppress_warnings() as sup:
+ sup.record()
+ with suppress_warnings("location"):
+ for i in range(2):
+ warnings.warn("Some warning")
+ warnings.warn("Some warning")
+
+ assert_(len(sup.log) == 2)
+
+ with suppress_warnings() as sup:
+ sup.record()
+ with suppress_warnings("module"):
+ for i in range(2):
+ warnings.warn("Some warning")
+ warnings.warn("Some warning")
+ warn_other_module()
+
+ assert_(len(sup.log) == 2)
+
+ with suppress_warnings() as sup:
+ sup.record()
+ with suppress_warnings("once"):
+ for i in range(2):
+ warnings.warn("Some warning")
+ warnings.warn("Some other warning")
+ warn_other_module()
+
+ assert_(len(sup.log) == 2)
def test_tempdir():