diff options
author | Sebastian Berg <sebastian@sipsolutions.net> | 2016-06-19 13:00:13 +0200 |
---|---|---|
committer | Charles Harris <charlesr.harris@gmail.com> | 2016-08-28 13:30:43 -0600 |
commit | 3c34457ac9e6c11f9197f513013d8ab1ee9d9236 (patch) | |
tree | 08c646973bbac1d693a6f2e5a99fabc6f4aaca27 /numpy/testing/tests | |
parent | 90668d0e740e30102fa3d0a1a72b485ebe9d99c3 (diff) | |
download | numpy-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.py | 186 |
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(): |