From 29a45efa15cf3992ab01b1535d51189319a7592d Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Sun, 19 Jun 2016 13:13:43 +0200 Subject: [PATCH 01/13] MAINT: Simplify deprecation test decorator Also modify the corresponding test to suppress the non Deprecation warnings created to test specificity. --- numpy/testing/decorators.py | 13 +++---------- numpy/testing/tests/test_decorators.py | 14 +++++++++----- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/numpy/testing/decorators.py b/numpy/testing/decorators.py index 6cde298e1cab..17400c0d5b06 100644 --- a/numpy/testing/decorators.py +++ b/numpy/testing/decorators.py @@ -15,10 +15,10 @@ """ from __future__ import division, absolute_import, print_function -import warnings import collections -from .utils import SkipTest +from .utils import SkipTest, assert_warns + def slow(t): """ @@ -251,15 +251,8 @@ def deprecate_decorator(f): def _deprecated_imp(*args, **kwargs): # Poor man's replacement for the with statement - with warnings.catch_warnings(record=True) as l: - warnings.simplefilter('always') + with assert_warns(DeprecationWarning): f(*args, **kwargs) - if not len(l) > 0: - raise AssertionError("No warning raised when calling %s" - % f.__name__) - if not l[0].category is DeprecationWarning: - raise AssertionError("First warning for %s is not a " - "DeprecationWarning( is %s)" % (f.__name__, l[0])) if isinstance(conditional, collections.Callable): cond = conditional() diff --git a/numpy/testing/tests/test_decorators.py b/numpy/testing/tests/test_decorators.py index 7dbb5a8286e9..721c0ef7eded 100644 --- a/numpy/testing/tests/test_decorators.py +++ b/numpy/testing/tests/test_decorators.py @@ -1,8 +1,10 @@ from __future__ import division, absolute_import, print_function +import warnings + from numpy.testing import (dec, assert_, assert_raises, run_module_suite, SkipTest, KnownFailureException) -import nose + def test_slow(): @dec.slow @@ -172,10 +174,12 @@ def deprecated_func3(): assert_raises(AssertionError, non_deprecated_func) # should be silent deprecated_func() - # fails if deprecated decorator just disables test. See #1453. - assert_raises(ValueError, deprecated_func2) - # first warnings is not a DeprecationWarning - assert_raises(AssertionError, deprecated_func3) + with warnings.catch_warnings(record=True): + warnings.simplefilter("always") # do not propagate unrelated warnings + # fails if deprecated decorator just disables test. See #1453. + assert_raises(ValueError, deprecated_func2) + # warning is not a DeprecationWarning + assert_raises(AssertionError, deprecated_func3) if __name__ == '__main__': From 968507bdfb4467d5ec6e3b6999a5717100782c3c Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Sun, 19 Jun 2016 13:12:54 +0200 Subject: [PATCH 02/13] ENH: Make warning testing context managers more specific This means that warnings of different origin then the one tested for behave normally. If the normal behaviour is to igonre them this might decrease specificity in rare cases. In most cases the specificity will be slightly higher. --- doc/release/1.12.0-notes.rst | 12 ++++++++++++ numpy/testing/tests/test_utils.py | 12 +++++------- numpy/testing/utils.py | 11 +++-------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/doc/release/1.12.0-notes.rst b/doc/release/1.12.0-notes.rst index 9a9a50aa8c87..7b315b90bef7 100644 --- a/doc/release/1.12.0-notes.rst +++ b/doc/release/1.12.0-notes.rst @@ -112,6 +112,18 @@ change in implementation some very delicate tests may fail that did not fail before. +``assert_warns`` and ``deprecated`` decorator more specific +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The ``assert_warns`` function and context manager are now more specific +to the given warning category. This increased specificity leads to them +being handled according to the outer warning settings. This means that +no warning may be raised in cases where a wrong category warning is given +and ignored outside the context. Alternatively the increased specificity +may mean that warnings that were incorrectly ignored will now be shown +or raised. See also the new ``suppress_warnings`` context manager. +The same is true for the ``deprecated`` decorator. + + C API ~~~~~ diff --git a/numpy/testing/tests/test_utils.py b/numpy/testing/tests/test_utils.py index c0f609883045..c191aea5ba37 100644 --- a/numpy/testing/tests/test_utils.py +++ b/numpy/testing/tests/test_utils.py @@ -503,23 +503,21 @@ def f(): warnings.warn("yo", DeprecationWarning) failed = False - filters = sys.modules['warnings'].filters[:] - try: + with warnings.catch_warnings(): + warnings.simplefilter("error", DeprecationWarning) try: - # Should raise an AssertionError + # Should raise a DeprecationWarning assert_warns(UserWarning, f) failed = True - except AssertionError: + except DeprecationWarning: pass - finally: - sys.modules['warnings'].filters = filters if failed: raise AssertionError("wrong warning caught by assert_warn") class TestAssertAllclose(unittest.TestCase): - + def test_simple(self): x = 1e-3 y = 1e-9 diff --git a/numpy/testing/utils.py b/numpy/testing/utils.py index c7f4a0aa7353..8789dd13c104 100644 --- a/numpy/testing/utils.py +++ b/numpy/testing/utils.py @@ -1658,16 +1658,12 @@ def __exit__(self): @contextlib.contextmanager def _assert_warns_context(warning_class, name=None): __tracebackhide__ = True # Hide traceback for py.test - with warnings.catch_warnings(record=True) as l: - warnings.simplefilter('always') + with suppress_warnings() as sup: + l = sup.record(warning_class) yield if not len(l) > 0: name_str = " when calling %s" % name if name is not None else "" raise AssertionError("No warning raised" + name_str) - if not l[0].category is warning_class: - name_str = "%s " % name if name is not None else "" - raise AssertionError("First warning %sis not a %s (is %s)" - % (name_str, warning_class, l[0])) def assert_warns(warning_class, *args, **kwargs): @@ -1676,8 +1672,7 @@ def assert_warns(warning_class, *args, **kwargs): A warning of class warning_class should be thrown by the callable when invoked with arguments args and keyword arguments kwargs. - If a different type of warning is thrown, it will not be caught, and the - test case will be deemed to have suffered an error. + If a different type of warning is thrown, it will not be caught. If called with all arguments other than the warning class omitted, may be used as a context manager: From 86b0a5e9c58160bad818ba3a0a6faf38f5ac4d09 Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Sun, 19 Jun 2016 13:39:46 +0200 Subject: [PATCH 03/13] BUG: Suppress common NaT warnings Printing of datetime arrays used to cause warning due to comparison warnings in NaT. This is circumvented by using views to integer values. Part of this should be simplified when the deprecation is over. Also fixes a bug with non-native byteorder. --- numpy/core/arrayprint.py | 9 ++-- numpy/core/tests/test_datetime.py | 72 ++++++++++++++++++------------- numpy/ma/testutils.py | 8 ++-- numpy/testing/utils.py | 13 ++++-- 4 files changed, 61 insertions(+), 41 deletions(-) diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index 282fbd1cfb7f..b05082e9d9db 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -20,7 +20,7 @@ from . import numerictypes as _nt from .umath import maximum, minimum, absolute, not_equal, isnan, isinf from .multiarray import (array, format_longfloat, datetime_as_string, - datetime_data) + datetime_data, dtype) from .fromnumeric import ravel from .numeric import asarray @@ -734,7 +734,9 @@ class TimedeltaFormat(object): def __init__(self, data): if data.dtype.kind == 'm': nat_value = array(['NaT'], dtype=data.dtype)[0] - v = data[not_equal(data, nat_value)].view('i8') + int_dtype = dtype(data.dtype.byteorder + 'i8') + int_view = data.view(int_dtype) + v = int_view[not_equal(int_view, nat_value.view(int_dtype))] if len(v) > 0: # Max str length of non-NaT elements max_str_len = max(len(str(maximum.reduce(v))), @@ -748,7 +750,8 @@ def __init__(self, data): self._nat = "'NaT'".rjust(max_str_len) def __call__(self, x): - if x + 1 == x: + # TODO: After NAT == NAT deprecation should be simplified: + if (x + 1).view('i8') == x.view('i8'): return self._nat else: return self.format % x.astype('i8') diff --git a/numpy/core/tests/test_datetime.py b/numpy/core/tests/test_datetime.py index 601f09c09192..e443b3be0b2e 100644 --- a/numpy/core/tests/test_datetime.py +++ b/numpy/core/tests/test_datetime.py @@ -1,7 +1,6 @@ from __future__ import division, absolute_import, print_function import pickle -import warnings import numpy import numpy as np @@ -9,7 +8,7 @@ from numpy.compat import asbytes from numpy.testing import ( TestCase, run_module_suite, assert_, assert_equal, assert_raises, - assert_warns, dec + assert_warns, dec, suppress_warnings ) # Use pytz to test out various time zones if available @@ -129,10 +128,11 @@ def test_compare_generic_nat(self): # regression tests for GH6452 assert_equal(np.datetime64('NaT'), np.datetime64('2000') + np.timedelta64('NaT')) - # nb. we may want to make NaT != NaT true in the future; this test - # verifies the existing behavior (and that it should not warn) - assert_(np.datetime64('NaT') == np.datetime64('NaT', 'us')) - assert_(np.datetime64('NaT', 'us') == np.datetime64('NaT')) + # nb. we may want to make NaT != NaT true in the future + with suppress_warnings() as sup: + sup.filter(FutureWarning, ".*NAT ==") + assert_(np.datetime64('NaT') == np.datetime64('NaT', 'us')) + assert_(np.datetime64('NaT', 'us') == np.datetime64('NaT')) def test_datetime_scalar_construction(self): # Construct with different units @@ -572,6 +572,12 @@ def test_timedelta_array_str(self): a = np.array([-1, 'NaT', 1234567], dtype='m') assert_equal(str(a), "[ -1 'NaT' 1234567]") + # Test with other byteorder: + a = np.array([-1, 'NaT', 1234567], dtype='>m') + assert_equal(str(a), "[ -1 'NaT' 1234567]") + a = np.array([-1, 'NaT', 1234567], dtype=' Date: Sun, 19 Jun 2016 13:45:06 +0200 Subject: [PATCH 04/13] MAINT: Add missing teardown in deprecation test case --- numpy/core/tests/test_deprecations.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/numpy/core/tests/test_deprecations.py b/numpy/core/tests/test_deprecations.py index 547280b23996..e03edb2ea268 100644 --- a/numpy/core/tests/test_deprecations.py +++ b/numpy/core/tests/test_deprecations.py @@ -644,6 +644,8 @@ def foo(): warnings.warn("foo", category=DeprecationWarning) test_case_instance.assert_deprecated(foo) + test_case_instance.tearDown() + if __name__ == "__main__": run_module_suite() From c1ddf841f6a48248b946a990ae750505b8b91686 Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Sun, 19 Jun 2016 14:01:47 +0200 Subject: [PATCH 05/13] ENH: Remove warning ignoring from nanfuncs Comment mentions a speedup, but it seems unsure why it should be there. Instead use an error state in divide_by_count. Some extra complex warnings had to be ignored (but those seemed correct) --- numpy/lib/nanfunctions.py | 72 +++++++++++++--------------- numpy/lib/tests/test_nanfunctions.py | 62 ++++++++++++------------ numpy/lib/tests/test_twodim_base.py | 2 +- 3 files changed, 66 insertions(+), 70 deletions(-) diff --git a/numpy/lib/nanfunctions.py b/numpy/lib/nanfunctions.py index 9d36406478b7..c2fc92ebf76b 100644 --- a/numpy/lib/nanfunctions.py +++ b/numpy/lib/nanfunctions.py @@ -130,7 +130,7 @@ def _divide_by_count(a, b, out=None): in place. If `a` is a numpy scalar, the division preserves its type. """ - with np.errstate(invalid='ignore'): + with np.errstate(invalid='ignore', divide='ignore'): if isinstance(a, np.ndarray): if out is None: return np.divide(a, b, out=a, casting='unsafe') @@ -815,12 +815,9 @@ def nanmean(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): if out is not None and not issubclass(out.dtype.type, np.inexact): raise TypeError("If a is inexact, then out must be inexact") - # The warning context speeds things up. - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - cnt = np.sum(~mask, axis=axis, dtype=np.intp, keepdims=keepdims) - tot = np.sum(arr, axis=axis, dtype=dtype, out=out, keepdims=keepdims) - avg = _divide_by_count(tot, cnt, out=out) + cnt = np.sum(~mask, axis=axis, dtype=np.intp, keepdims=keepdims) + tot = np.sum(arr, axis=axis, dtype=dtype, out=out, keepdims=keepdims) + avg = _divide_by_count(tot, cnt, out=out) isbad = (cnt == 0) if isbad.any(): @@ -1288,38 +1285,35 @@ def nanvar(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue): if out is not None and not issubclass(out.dtype.type, np.inexact): raise TypeError("If a is inexact, then out must be inexact") - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - - # Compute mean - if type(arr) is np.matrix: - _keepdims = np._NoValue - else: - _keepdims = True - # we need to special case matrix for reverse compatibility - # in order for this to work, these sums need to be called with - # keepdims=True, however matrix now raises an error in this case, but - # the reason that it drops the keepdims kwarg is to force keepdims=True - # so this used to work by serendipity. - cnt = np.sum(~mask, axis=axis, dtype=np.intp, keepdims=_keepdims) - avg = np.sum(arr, axis=axis, dtype=dtype, keepdims=_keepdims) - avg = _divide_by_count(avg, cnt) - - # Compute squared deviation from mean. - np.subtract(arr, avg, out=arr, casting='unsafe') - arr = _copyto(arr, 0, mask) - if issubclass(arr.dtype.type, np.complexfloating): - sqr = np.multiply(arr, arr.conj(), out=arr).real - else: - sqr = np.multiply(arr, arr, out=arr) - - # Compute variance. - var = np.sum(sqr, axis=axis, dtype=dtype, out=out, keepdims=keepdims) - if var.ndim < cnt.ndim: - # Subclasses of ndarray may ignore keepdims, so check here. - cnt = cnt.squeeze(axis) - dof = cnt - ddof - var = _divide_by_count(var, dof) + # Compute mean + if type(arr) is np.matrix: + _keepdims = np._NoValue + else: + _keepdims = True + # we need to special case matrix for reverse compatibility + # in order for this to work, these sums need to be called with + # keepdims=True, however matrix now raises an error in this case, but + # the reason that it drops the keepdims kwarg is to force keepdims=True + # so this used to work by serendipity. + cnt = np.sum(~mask, axis=axis, dtype=np.intp, keepdims=_keepdims) + avg = np.sum(arr, axis=axis, dtype=dtype, keepdims=_keepdims) + avg = _divide_by_count(avg, cnt) + + # Compute squared deviation from mean. + np.subtract(arr, avg, out=arr, casting='unsafe') + arr = _copyto(arr, 0, mask) + if issubclass(arr.dtype.type, np.complexfloating): + sqr = np.multiply(arr, arr.conj(), out=arr).real + else: + sqr = np.multiply(arr, arr, out=arr) + + # Compute variance. + var = np.sum(sqr, axis=axis, dtype=dtype, out=out, keepdims=keepdims) + if var.ndim < cnt.ndim: + # Subclasses of ndarray may ignore keepdims, so check here. + cnt = cnt.squeeze(axis) + dof = cnt - ddof + var = _divide_by_count(var, dof) isbad = (dof <= 0) if np.any(isbad): diff --git a/numpy/lib/tests/test_nanfunctions.py b/numpy/lib/tests/test_nanfunctions.py index 03f9beff6f54..e062bc0327a5 100644 --- a/numpy/lib/tests/test_nanfunctions.py +++ b/numpy/lib/tests/test_nanfunctions.py @@ -5,7 +5,7 @@ import numpy as np from numpy.testing import ( run_module_suite, TestCase, assert_, assert_equal, assert_almost_equal, - assert_warns, assert_no_warnings, assert_raises, assert_array_equal + assert_no_warnings, assert_raises, assert_array_equal, suppress_warnings ) @@ -317,26 +317,30 @@ def test_dtype_from_dtype(self): codes = 'efdgFDG' for nf, rf in zip(self.nanfuncs, self.stdfuncs): for c in codes: - tgt = rf(mat, dtype=np.dtype(c), axis=1).dtype.type - res = nf(mat, dtype=np.dtype(c), axis=1).dtype.type - assert_(res is tgt) - # scalar case - tgt = rf(mat, dtype=np.dtype(c), axis=None).dtype.type - res = nf(mat, dtype=np.dtype(c), axis=None).dtype.type - assert_(res is tgt) + with suppress_warnings() as sup: + sup.filter(np.ComplexWarning) + tgt = rf(mat, dtype=np.dtype(c), axis=1).dtype.type + res = nf(mat, dtype=np.dtype(c), axis=1).dtype.type + assert_(res is tgt) + # scalar case + tgt = rf(mat, dtype=np.dtype(c), axis=None).dtype.type + res = nf(mat, dtype=np.dtype(c), axis=None).dtype.type + assert_(res is tgt) def test_dtype_from_char(self): mat = np.eye(3) codes = 'efdgFDG' for nf, rf in zip(self.nanfuncs, self.stdfuncs): for c in codes: - tgt = rf(mat, dtype=c, axis=1).dtype.type - res = nf(mat, dtype=c, axis=1).dtype.type - assert_(res is tgt) - # scalar case - tgt = rf(mat, dtype=c, axis=None).dtype.type - res = nf(mat, dtype=c, axis=None).dtype.type - assert_(res is tgt) + with suppress_warnings() as sup: + sup.filter(np.ComplexWarning) + tgt = rf(mat, dtype=c, axis=1).dtype.type + res = nf(mat, dtype=c, axis=1).dtype.type + assert_(res is tgt) + # scalar case + tgt = rf(mat, dtype=c, axis=None).dtype.type + res = nf(mat, dtype=c, axis=None).dtype.type + assert_(res is tgt) def test_dtype_from_input(self): codes = 'efdgFDG' @@ -524,16 +528,16 @@ def test_ddof_too_big(self): dsize = [len(d) for d in _rdat] for nf, rf in zip(nanfuncs, stdfuncs): for ddof in range(5): - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') + with suppress_warnings() as sup: + sup.record(RuntimeWarning) + sup.filter(np.ComplexWarning) tgt = [ddof >= d for d in dsize] res = nf(_ndat, axis=1, ddof=ddof) assert_equal(np.isnan(res), tgt) if any(tgt): - assert_(len(w) == 1) - assert_(issubclass(w[0].category, RuntimeWarning)) + assert_(len(sup.log) == 1) else: - assert_(len(w) == 0) + assert_(len(sup.log) == 0) def test_allnans(self): mat = np.array([np.nan]*9).reshape(3, 3) @@ -642,22 +646,20 @@ def test_result_values(self): def test_allnans(self): mat = np.array([np.nan]*9).reshape(3, 3) for axis in [None, 0, 1]: - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') - warnings.simplefilter('ignore', FutureWarning) + with suppress_warnings() as sup: + sup.record(RuntimeWarning) + assert_(np.isnan(np.nanmedian(mat, axis=axis)).all()) if axis is None: - assert_(len(w) == 1) + assert_(len(sup.log) == 1) else: - assert_(len(w) == 3) - assert_(issubclass(w[0].category, RuntimeWarning)) + assert_(len(sup.log) == 3) # Check scalar assert_(np.isnan(np.nanmedian(np.nan))) if axis is None: - assert_(len(w) == 2) + assert_(len(sup.log) == 2) else: - assert_(len(w) == 4) - assert_(issubclass(w[0].category, RuntimeWarning)) + assert_(len(sup.log) == 4) def test_empty(self): mat = np.zeros((0, 3)) @@ -686,7 +688,7 @@ def test_extended_axis_invalid(self): def test_float_special(self): with warnings.catch_warnings(record=True): - warnings.simplefilter('ignore', RuntimeWarning) + warnings.simplefilter('always', RuntimeWarning) a = np.array([[np.inf, np.nan], [np.nan, np.nan]]) assert_equal(np.nanmedian(a, axis=0), [np.inf, np.nan]) assert_equal(np.nanmedian(a, axis=1), [np.inf, np.nan]) diff --git a/numpy/lib/tests/test_twodim_base.py b/numpy/lib/tests/test_twodim_base.py index 31925d5fe7c6..98b8aa39c429 100644 --- a/numpy/lib/tests/test_twodim_base.py +++ b/numpy/lib/tests/test_twodim_base.py @@ -5,7 +5,7 @@ from numpy.testing import ( TestCase, run_module_suite, assert_equal, assert_array_equal, - assert_array_max_ulp, assert_array_almost_equal, assert_raises + assert_array_max_ulp, assert_array_almost_equal, assert_raises, ) from numpy import ( From 308161c80f4450f05f8399343034308bd18b4e1e Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Sun, 19 Jun 2016 14:18:35 +0200 Subject: [PATCH 06/13] TST: Use new warnings context manager in all tests In some places, just remove aparently unnecessary filters. After this, all cases of ignore filters should be removed from the tests, making testing (even multiple runs) normally fully predictable. --- numpy/core/tests/test_einsum.py | 9 +- numpy/core/tests/test_function_base.py | 8 +- numpy/core/tests/test_memmap.py | 16 ++-- numpy/core/tests/test_multiarray.py | 26 +++--- numpy/core/tests/test_nditer.py | 9 +- numpy/core/tests/test_numeric.py | 43 +++++---- numpy/core/tests/test_regression.py | 38 ++++---- numpy/core/tests/test_scalarmath.py | 9 +- numpy/core/tests/test_umath.py | 7 +- numpy/lib/tests/test_function_base.py | 33 +++---- numpy/lib/tests/test_io.py | 29 +++--- numpy/linalg/tests/test_linalg.py | 10 +-- numpy/ma/tests/test_core.py | 88 ++++++++++-------- numpy/ma/tests/test_extras.py | 36 ++++---- numpy/ma/tests/test_mrecords.py | 8 +- numpy/ma/tests/test_old_ma.py | 120 ++++++++++++++----------- numpy/ma/tests/test_regression.py | 8 +- numpy/random/tests/test_random.py | 26 +++--- 18 files changed, 266 insertions(+), 257 deletions(-) diff --git a/numpy/core/tests/test_einsum.py b/numpy/core/tests/test_einsum.py index 77fb75f10b54..c31d281e970a 100644 --- a/numpy/core/tests/test_einsum.py +++ b/numpy/core/tests/test_einsum.py @@ -1,13 +1,12 @@ from __future__ import division, absolute_import, print_function -import warnings - import numpy as np from numpy.testing import ( TestCase, run_module_suite, assert_, assert_equal, assert_array_equal, - assert_raises + assert_raises, suppress_warnings ) + class TestEinSum(TestCase): def test_einsum_errors(self): # Need enough arguments @@ -282,8 +281,8 @@ def check_einsum_sums(self, dtype): assert_equal(np.einsum(a, [0], b, [1]), np.outer(a, b)) # Suppress the complex warnings for the 'as f8' tests - with warnings.catch_warnings(): - warnings.simplefilter('ignore', np.ComplexWarning) + with suppress_warnings() as sup: + sup.filter(np.ComplexWarning) # matvec(a,b) / a.dot(b) where a is matrix, b is vector for n in range(1, 17): diff --git a/numpy/core/tests/test_function_base.py b/numpy/core/tests/test_function_base.py index 0fabb25886e8..9b20c4ff5db1 100644 --- a/numpy/core/tests/test_function_base.py +++ b/numpy/core/tests/test_function_base.py @@ -4,7 +4,7 @@ typecodes, arange, isnan, ndarray, sqrt) from numpy.testing import ( TestCase, run_module_suite, assert_, assert_equal, assert_raises, - assert_array_equal, assert_allclose + assert_array_equal, assert_allclose, suppress_warnings ) @@ -205,8 +205,10 @@ def test_basic(self): def test_corner(self): y = list(linspace(0, 1, 1)) assert_(y == [0.0], y) - y = list(linspace(0, 1, 2.5)) - assert_(y == [0.0, 1.0]) + with suppress_warnings() as sup: + sup.filter(DeprecationWarning, ".*safely interpreted as an integer") + y = list(linspace(0, 1, 2.5)) + assert_(y == [0.0, 1.0]) def test_type(self): t1 = linspace(0, 1, 0).dtype diff --git a/numpy/core/tests/test_memmap.py b/numpy/core/tests/test_memmap.py index 4aa02e26f00b..30c8b7c549db 100644 --- a/numpy/core/tests/test_memmap.py +++ b/numpy/core/tests/test_memmap.py @@ -12,7 +12,7 @@ from numpy import arange, allclose, asarray from numpy.testing import ( TestCase, run_module_suite, assert_, assert_equal, assert_array_equal, - dec + dec, suppress_warnings ) class TestMemmap(TestCase): @@ -146,13 +146,15 @@ def test_ufunc_return_ndarray(self): fp = memmap(self.tmpfp, dtype=self.dtype, shape=self.shape) fp[:] = self.data - for unary_op in [sum, average, product]: - result = unary_op(fp) - assert_(isscalar(result)) - assert_(result.__class__ is self.data[0, 0].__class__) + with suppress_warnings() as sup: + sup.filter(FutureWarning, "np.average currently does not preserve") + for unary_op in [sum, average, product]: + result = unary_op(fp) + assert_(isscalar(result)) + assert_(result.__class__ is self.data[0, 0].__class__) - assert_(unary_op(fp, axis=0).__class__ is ndarray) - assert_(unary_op(fp, axis=1).__class__ is ndarray) + assert_(unary_op(fp, axis=0).__class__ is ndarray) + assert_(unary_op(fp, axis=1).__class__ is ndarray) for binary_op in [add, subtract, multiply]: assert_(binary_op(fp, self.data).__class__ is ndarray) diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index 977378cfa4da..2b585f4dc1cc 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -29,7 +29,7 @@ TestCase, run_module_suite, assert_, assert_raises, assert_equal, assert_almost_equal, assert_array_equal, assert_array_almost_equal, assert_allclose, IS_PYPY, HAS_REFCOUNT, - assert_array_less, runstring, dec, SkipTest, temppath + assert_array_less, runstring, dec, SkipTest, temppath, suppress_warnings ) # Need to test an object that does not fully implement math interface @@ -826,8 +826,8 @@ def test_subarray_comparison(self): # This comparison invokes deprecated behaviour, and will probably # start raising an error eventually. What we really care about in this # test is just that it doesn't return True. - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", category=DeprecationWarning) + with suppress_warnings() as sup: + sup.filter(FutureWarning, "elementwise == comparison failed") assert_equal(x == y, False) x = np.zeros((1,), dtype=[('a', ('f4', (2, 1))), ('b', 'i1')]) @@ -835,8 +835,8 @@ def test_subarray_comparison(self): # This comparison invokes deprecated behaviour, and will probably # start raising an error eventually. What we really care about in this # test is just that it doesn't return True. - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", category=DeprecationWarning) + with suppress_warnings() as sup: + sup.filter(FutureWarning, "elementwise == comparison failed") assert_equal(x == y, False) # Check that structured arrays that are different only in @@ -3818,11 +3818,11 @@ def test_unbuffered_fromfile(self): def fail(*args, **kwargs): raise io.IOError('Can not tell or seek') - f = io.open(self.filename, 'rb', buffering=0) - f.seek = fail - f.tell = fail - y = np.fromfile(self.filename, dtype=self.dtype) - assert_array_equal(y, self.x.flat) + with io.open(self.filename, 'rb', buffering=0) as f: + f.seek = fail + f.tell = fail + y = np.fromfile(self.filename, dtype=self.dtype) + assert_array_equal(y, self.x.flat) def test_largish_file(self): # check the fallocate path on files > 16MB @@ -6039,11 +6039,11 @@ def test_relaxed_strides(self): class TestArrayAttributeDeletion(object): def test_multiarray_writable_attributes_deletion(self): - """ticket #2046, should not seqfault, raise AttributeError""" + # ticket #2046, should not seqfault, raise AttributeError a = np.ones(2) attr = ['shape', 'strides', 'data', 'dtype', 'real', 'imag', 'flat'] - with warnings.catch_warnings(): - warnings.simplefilter('ignore') + with suppress_warnings() as sup: + sup.filter(DeprecationWarning, "Assigning the 'data' attribute") for s in attr: assert_raises(AttributeError, delattr, a, s) diff --git a/numpy/core/tests/test_nditer.py b/numpy/core/tests/test_nditer.py index f83d816242ed..3b5aaa28d2fb 100644 --- a/numpy/core/tests/test_nditer.py +++ b/numpy/core/tests/test_nditer.py @@ -1,7 +1,6 @@ from __future__ import division, absolute_import, print_function import sys -import warnings import numpy as np from numpy import array, arange, nditer, all @@ -9,7 +8,7 @@ from numpy.core.multiarray_tests import test_nditer_too_large from numpy.testing import ( run_module_suite, assert_, assert_equal, assert_array_equal, - assert_raises, dec, HAS_REFCOUNT + assert_raises, dec, HAS_REFCOUNT, suppress_warnings ) @@ -1624,8 +1623,8 @@ def test_iter_buffered_cast_byteswapped(): assert_equal(a, 2*np.arange(10, dtype='f4')) - try: - warnings.simplefilter("ignore", np.ComplexWarning) + with suppress_warnings() as sup: + sup.filter(np.ComplexWarning) a = np.arange(10, dtype='f8').newbyteorder().byteswap() i = nditer(a, ['buffered', 'external_loop'], @@ -1637,8 +1636,6 @@ def test_iter_buffered_cast_byteswapped(): v[...] *= 2 assert_equal(a, 2*np.arange(10, dtype='f8')) - finally: - warnings.simplefilter("default", np.ComplexWarning) def test_iter_buffered_cast_byteswapped_complex(): # Test that buffering can handle a cast which requires swap->cast->copy diff --git a/numpy/core/tests/test_numeric.py b/numpy/core/tests/test_numeric.py index 990d13a3e48a..c31e9e07ca31 100644 --- a/numpy/core/tests/test_numeric.py +++ b/numpy/core/tests/test_numeric.py @@ -12,7 +12,7 @@ from numpy.testing import ( TestCase, run_module_suite, assert_, assert_equal, assert_raises, assert_raises_regex, assert_array_equal, assert_almost_equal, - assert_array_almost_equal, dec, HAS_REFCOUNT + assert_array_almost_equal, dec, HAS_REFCOUNT, suppress_warnings ) @@ -1976,27 +1976,26 @@ def check_function(self, func, fill_value=None): fill_kwarg = {} if fill_value is not None: fill_kwarg = {'fill_value': fill_value} - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - for size, ndims, order, dtype in itertools.product(*par): - shape = ndims * [size] - - # do not fill void type - if fill_kwarg and dtype.str.startswith('|V'): - continue - - arr = func(shape, order=order, dtype=dtype, - **fill_kwarg) - - assert_equal(arr.dtype, dtype) - assert_(getattr(arr.flags, self.orders[order])) - - if fill_value is not None: - if dtype.str.startswith('|S'): - val = str(fill_value) - else: - val = fill_value - assert_equal(arr, dtype.type(val)) + + for size, ndims, order, dtype in itertools.product(*par): + shape = ndims * [size] + + # do not fill void type + if fill_kwarg and dtype.str.startswith('|V'): + continue + + arr = func(shape, order=order, dtype=dtype, + **fill_kwarg) + + assert_equal(arr.dtype, dtype) + assert_(getattr(arr.flags, self.orders[order])) + + if fill_value is not None: + if dtype.str.startswith('|S'): + val = str(fill_value) + else: + val = fill_value + assert_equal(arr, dtype.type(val)) def test_zeros(self): self.check_function(np.zeros) diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py index 022438ab1380..b1d1673dd1c1 100644 --- a/numpy/core/tests/test_regression.py +++ b/numpy/core/tests/test_regression.py @@ -15,7 +15,7 @@ from numpy.testing import ( run_module_suite, TestCase, assert_, assert_equal, assert_almost_equal, assert_array_equal, assert_array_almost_equal, - assert_raises, assert_warns, dec + assert_raises, assert_warns, dec, suppress_warnings ) from numpy.testing.utils import _assert_valid_refcount, HAS_REFCOUNT from numpy.compat import asbytes, asunicode, asbytes_nested, long, sixu @@ -138,8 +138,8 @@ def test_scalar_compare(self,level=rlevel): self.assertTrue(a[0] != 'auto') b = np.linspace(0, 10, 11) # This should return true for now, but will eventually raise an error: - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", category=DeprecationWarning) + with suppress_warnings() as sup: + sup.filter(DeprecationWarning) self.assertTrue(b != 'auto') self.assertTrue(b[0] != 'auto') @@ -811,9 +811,9 @@ def ia(x, s, v): # This might seem odd as compared to the value error below. This # is due to the fact that the new code always uses "nonzero" logic # and the boolean special case is not taken. - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - warnings.simplefilter('ignore', np.VisibleDeprecationWarning) + with suppress_warnings() as sup: + sup.filter(DeprecationWarning) + sup.filter(np.VisibleDeprecationWarning) self.assertRaises(IndexError, ia, x, s, np.zeros(9, dtype=float)) self.assertRaises(IndexError, ia, x, s, np.zeros(11, dtype=float)) # Old special case (different code path): @@ -1518,19 +1518,17 @@ def test_ticket_1539(self): dtypes = [x for x in np.typeDict.values() if (issubclass(x, np.number) and not issubclass(x, np.timedelta64))] - a = np.array([], dtypes[0]) + a = np.array([], np.bool_) # not x[0] because it is unordered failures = [] - # ignore complex warnings - with warnings.catch_warnings(): - warnings.simplefilter('ignore', np.ComplexWarning) - for x in dtypes: - b = a.astype(x) - for y in dtypes: - c = a.astype(y) - try: - np.dot(b, c) - except TypeError: - failures.append((x, y)) + + for x in dtypes: + b = a.astype(x) + for y in dtypes: + c = a.astype(y) + try: + np.dot(b, c) + except TypeError: + failures.append((x, y)) if failures: raise AssertionError("Failures: %r" % failures) @@ -1621,8 +1619,8 @@ def test_complex_scalar_warning(self): for tp in [np.csingle, np.cdouble, np.clongdouble]: x = tp(1+2j) assert_warns(np.ComplexWarning, float, x) - with warnings.catch_warnings(): - warnings.simplefilter('ignore') + with suppress_warnings() as sup: + sup.filter(np.ComplexWarning) assert_equal(float(x), float(x.real)) def test_complex_scalar_complex_cast(self): diff --git a/numpy/core/tests/test_scalarmath.py b/numpy/core/tests/test_scalarmath.py index 1c71565f4e14..6b55f0101432 100644 --- a/numpy/core/tests/test_scalarmath.py +++ b/numpy/core/tests/test_scalarmath.py @@ -2,14 +2,14 @@ import sys import itertools -import warnings import operator import numpy as np from numpy.testing.utils import _gen_alignment_data from numpy.testing import ( TestCase, run_module_suite, assert_, assert_equal, assert_raises, - assert_almost_equal, assert_allclose, assert_array_equal, IS_PYPY + assert_almost_equal, assert_allclose, assert_array_equal, IS_PYPY, + suppress_warnings ) types = [np.bool_, np.byte, np.ubyte, np.short, np.ushort, np.intc, np.uintc, @@ -238,9 +238,8 @@ def test_float_modulus_corner_cases(self): assert_(rem >= -b, 'dt: %s' % dt) # Check nans, inf - with warnings.catch_warnings(): - warnings.simplefilter('always') - warnings.simplefilter('ignore', RuntimeWarning) + with suppress_warnings() as sup: + sup.filter(RuntimeWarning, "invalid value encountered in remainder") for dt in np.typecodes['Float']: fone = np.array(1.0, dtype=dt) fzer = np.array(0.0, dtype=dt) diff --git a/numpy/core/tests/test_umath.py b/numpy/core/tests/test_umath.py index 759e996e31bb..20bcec24121a 100644 --- a/numpy/core/tests/test_umath.py +++ b/numpy/core/tests/test_umath.py @@ -11,7 +11,7 @@ from numpy.testing import ( TestCase, run_module_suite, assert_, assert_equal, assert_raises, assert_array_equal, assert_almost_equal, assert_array_almost_equal, - dec, assert_allclose, assert_no_warnings + dec, assert_allclose, assert_no_warnings, suppress_warnings ) @@ -300,9 +300,8 @@ def test_float_remainder_corner_cases(self): assert_(rem >= -b, 'dt: %s' % dt) # Check nans, inf - with warnings.catch_warnings(): - warnings.simplefilter('always') - warnings.simplefilter('ignore', RuntimeWarning) + with suppress_warnings() as sup: + sup.filter(RuntimeWarning, "invalid value encountered in remainder") for dt in np.typecodes['Float']: fone = np.array(1.0, dtype=dt) fzer = np.array(0.0, dtype=dt) diff --git a/numpy/lib/tests/test_function_base.py b/numpy/lib/tests/test_function_base.py index 0d7b11c44209..4535c1e7febc 100644 --- a/numpy/lib/tests/test_function_base.py +++ b/numpy/lib/tests/test_function_base.py @@ -8,7 +8,7 @@ run_module_suite, TestCase, assert_, assert_equal, assert_array_equal, assert_almost_equal, assert_array_almost_equal, assert_raises, assert_allclose, assert_array_max_ulp, assert_warns, - assert_raises_regex, dec, clear_and_catch_warnings + assert_raises_regex, dec, suppress_warnings ) from numpy.testing.utils import HAS_REFCOUNT import numpy.lib.function_base as nfb @@ -320,7 +320,11 @@ class subclass(np.ndarray): a = np.array([[1,2],[3,4]]).view(subclass) w = np.array([[1,2],[3,4]]).view(subclass) - assert_equal(type(np.average(a, weights=w)), subclass) + with suppress_warnings() as sup: + # Note that the warning is spurious, because the test checks + # for weights while a is ignored. + sup.filter(FutureWarning, "np.average currently does not preserve") + assert_equal(type(np.average(a, weights=w)), subclass) # also test matrices a = np.matrix([[1,2],[3,4]]) @@ -1457,12 +1461,12 @@ def test_empty(self): a, b = histogram([], bins=([0, 1])) assert_array_equal(a, np.array([0])) assert_array_equal(b, np.array([0, 1])) - + def test_error_binnum_type (self): # Tests if right Error is raised if bins argument is float vals = np.linspace(0.0, 1.0, num=100) histogram(vals, 5) - assert_raises(TypeError, histogram, vals, 2.4) + assert_raises(TypeError, histogram, vals, 2.4) def test_finite_range(self): # Normal ranges should be fine @@ -1792,15 +1796,6 @@ def test_dtype_order(self): assert_(a.dtype == np.float64) -class catch_warn_nfb(clear_and_catch_warnings): - - """ - Context manager to catch, reset warnings in function_base module - - """ - class_modules = (nfb,) - - class TestCorrCoef(TestCase): A = np.array( [[0.15391142, 0.18045767, 0.14197213], @@ -1837,10 +1832,10 @@ def test_simple(self): def test_ddof(self): # ddof raises DeprecationWarning - with catch_warn_nfb(): + with suppress_warnings() as sup: warnings.simplefilter("always") assert_warns(DeprecationWarning, corrcoef, self.A, ddof=-1) - warnings.simplefilter("ignore") + sup.filter(DeprecationWarning) # ddof has no or negligible effect on the function assert_almost_equal(corrcoef(self.A, ddof=-1), self.res1) assert_almost_equal(corrcoef(self.A, self.B, ddof=-1), self.res2) @@ -1849,11 +1844,11 @@ def test_ddof(self): def test_bias(self): # bias raises DeprecationWarning - with catch_warn_nfb(): + with suppress_warnings() as sup: warnings.simplefilter("always") assert_warns(DeprecationWarning, corrcoef, self.A, self.B, 1, 0) assert_warns(DeprecationWarning, corrcoef, self.A, bias=0) - warnings.simplefilter("ignore") + sup.filter(DeprecationWarning) # bias has no or negligible effect on the function assert_almost_equal(corrcoef(self.A, bias=1), self.res1) @@ -2316,7 +2311,7 @@ def test_scalar_interpolation_point(self): assert_almost_equal(np.interp(x0, x, y), x0) x0 = np.nan assert_almost_equal(np.interp(x0, x, y), x0) - + def test_complex_interp(self): # test complex interpolation x = np.linspace(0, 1, 5) @@ -2335,7 +2330,7 @@ def test_complex_interp(self): x = [-180, -170, -185, 185, -10, -5, 0, 365] xp = [190, -190, 350, -350] fp = [5+1.0j, 10+2j, 3+3j, 4+4j] - y = [7.5+1.5j, 5.+1.0j, 8.75+1.75j, 6.25+1.25j, 3.+3j, 3.25+3.25j, + y = [7.5+1.5j, 5.+1.0j, 8.75+1.75j, 6.25+1.25j, 3.+3j, 3.25+3.25j, 3.5+3.5j, 3.75+3.75j] assert_almost_equal(np.interp(x, xp, fp, period=360), y) diff --git a/numpy/lib/tests/test_io.py b/numpy/lib/tests/test_io.py index 1474349de66e..333891d461e5 100644 --- a/numpy/lib/tests/test_io.py +++ b/numpy/lib/tests/test_io.py @@ -19,7 +19,7 @@ from numpy.testing import ( TestCase, run_module_suite, assert_warns, assert_, assert_raises_regex, assert_raises, assert_allclose, - assert_array_equal, temppath, dec, IS_PYPY + assert_array_equal, temppath, dec, IS_PYPY, suppress_warnings ) @@ -282,8 +282,8 @@ def test_closing_fid(self): # collector, so we catch the warnings. Because ResourceWarning # is unknown in Python < 3.x, we take the easy way out and # catch all warnings. - with warnings.catch_warnings(): - warnings.simplefilter("ignore") + with suppress_warnings() as sup: + sup.filter(Warning) # TODO: specify exact message for i in range(1, 1025): try: np.load(tmp)["data"] @@ -687,9 +687,8 @@ def test_3d_shaped_dtype(self): assert_array_equal(x, a) def test_empty_file(self): - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", - message="loadtxt: Empty input file:") + with suppress_warnings() as sup: + sup.filter(message="loadtxt: Empty input file:") c = TextIO() x = np.loadtxt(c) assert_equal(x.shape, (0,)) @@ -826,9 +825,8 @@ def test_ndmin_keyword(self): assert_(x.shape == (3,)) # Test ndmin kw with empty file. - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", - message="loadtxt: Empty input file:") + with suppress_warnings() as sup: + sup.filter(message="loadtxt: Empty input file:") f = TextIO() assert_(np.loadtxt(f, ndmin=2).shape == (0, 1,)) assert_(np.loadtxt(f, ndmin=1).shape == (0,)) @@ -974,8 +972,8 @@ def test_skip_footer(self): assert_equal(test, ctrl) def test_skip_footer_with_invalid(self): - with warnings.catch_warnings(): - warnings.filterwarnings("ignore") + with suppress_warnings() as sup: + sup.filter(ConversionWarning) basestr = '1 1\n2 2\n3 3\n4 4\n5 \n6 \n7 \n' # Footer too small to get rid of all invalid values assert_raises(ValueError, np.genfromtxt, @@ -1302,9 +1300,8 @@ def test_usecols_with_named_columns(self): def test_empty_file(self): # Test that an empty file raises the proper warning. - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", - message="genfromtxt: Empty input file:") + with suppress_warnings() as sup: + sup.filter(message="genfromtxt: Empty input file:") data = TextIO() test = np.genfromtxt(data) assert_equal(test, np.array([])) @@ -1751,8 +1748,8 @@ def test_max_rows(self): assert_raises(ValueError, np.genfromtxt, TextIO(data), max_rows=4) # Test with invalid not raise - with warnings.catch_warnings(): - warnings.filterwarnings("ignore") + with suppress_warnings() as sup: + sup.filter(ConversionWarning) test = np.genfromtxt(TextIO(data), max_rows=4, invalid_raise=False) control = np.array([[1., 1.], [2., 2.], [3., 3.], [4., 4.]]) diff --git a/numpy/linalg/tests/test_linalg.py b/numpy/linalg/tests/test_linalg.py index a89378acd929..a353271de9fd 100644 --- a/numpy/linalg/tests/test_linalg.py +++ b/numpy/linalg/tests/test_linalg.py @@ -18,7 +18,7 @@ from numpy.testing import ( assert_, assert_equal, assert_raises, assert_array_equal, assert_almost_equal, assert_allclose, run_module_suite, - dec, SkipTest + dec, SkipTest, suppress_warnings ) @@ -861,8 +861,8 @@ def test_vector_return_type(self): assert_(issubclass(an.dtype.type, np.floating)) assert_almost_equal(an, 0.0) - with warnings.catch_warnings(): - warnings.simplefilter("ignore", RuntimeWarning) + with suppress_warnings() as sup: + sup.filter(RuntimeWarning, "divide by zero encountered") an = norm(at, -1) assert_(issubclass(an.dtype.type, np.floating)) assert_almost_equal(an, 0.0) @@ -906,8 +906,8 @@ def test_matrix_return_type(self): assert_(issubclass(an.dtype.type, np.floating)) assert_almost_equal(an, 2.0) - with warnings.catch_warnings(): - warnings.simplefilter("ignore", RuntimeWarning) + with suppress_warnings() as sup: + sup.filter(RuntimeWarning, "divide by zero encountered") an = norm(at, -1) assert_(issubclass(an.dtype.type, np.floating)) assert_almost_equal(an, 1.0) diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py index b3965000d9d9..6719ed61828f 100644 --- a/numpy/ma/tests/test_core.py +++ b/numpy/ma/tests/test_core.py @@ -19,13 +19,14 @@ import numpy.ma.core import numpy.core.fromnumeric as fromnumeric import numpy.core.umath as umath -from numpy.testing import TestCase, run_module_suite, assert_raises +from numpy.testing import ( + TestCase, run_module_suite, assert_raises, suppress_warnings) from numpy import ndarray from numpy.compat import asbytes, asbytes_nested from numpy.ma.testutils import ( assert_, assert_array_equal, assert_equal, assert_almost_equal, assert_equal_records, fail_if_equal, assert_not_equal, - assert_mask_equal, + assert_mask_equal ) from numpy.ma.core import ( MAError, MaskError, MaskType, MaskedArray, abs, absolute, add, all, @@ -48,6 +49,12 @@ pi = np.pi +suppress_copy_mask_on_assignment = suppress_warnings() +suppress_copy_mask_on_assignment.filter( + numpy.ma.core.MaskedArrayFutureWarning, + "setting an item on a masked array which has a shared mask will not copy") + + class TestMaskedArray(TestCase): # Base test class for MaskedArrays. @@ -366,6 +373,7 @@ def test_matrix_indexing(self): assert_(allequal(array([0, 0, 0, 1, 0], MaskType), x2.mask)) assert_equal(3.0, x2.fill_value) + @suppress_copy_mask_on_assignment def test_copy(self): # Tests of some subtle points of copying and sizing. n = [0, 0, 1, 0, 0] @@ -524,14 +532,14 @@ def test_topython(self): assert_equal(1.0, float(array([[1]]))) self.assertRaises(TypeError, float, array([1, 1])) - with warnings.catch_warnings(): - warnings.simplefilter('ignore', UserWarning) + with suppress_warnings() as sup: + sup.filter(UserWarning, 'Warning: converting a masked element') assert_(np.isnan(float(array([1], mask=[1])))) - a = array([1, 2, 3], mask=[1, 0, 0]) - self.assertRaises(TypeError, lambda:float(a)) - assert_equal(float(a[-1]), 3.) - self.assertTrue(np.isnan(float(a[0]))) + a = array([1, 2, 3], mask=[1, 0, 0]) + self.assertRaises(TypeError, lambda: float(a)) + assert_equal(float(a[-1]), 3.) + self.assertTrue(np.isnan(float(a[0]))) self.assertRaises(TypeError, int, a) assert_equal(int(a[-1]), 3) self.assertRaises(MAError, lambda:int(a[0])) @@ -578,6 +586,7 @@ def test_oddfeatures_2(self): assert_(z[1] is not masked) assert_(z[2] is masked) + @suppress_copy_mask_on_assignment def test_oddfeatures_3(self): # Tests some generic features atest = array([10], mask=True) @@ -1335,24 +1344,28 @@ def test_ne_on_structured(self): def test_eq_w_None(self): # Really, comparisons with None should not be done, but check them # anyway. Note that pep8 will flag these tests. + # Deprecation is in place for arrays, and when it happens this + # test will fail (and have to be changed accordingly). # With partial mask - a = array([1, 2], mask=[0, 1]) - assert_equal(a == None, False) - assert_equal(a.data == None, False) - assert_equal(a.mask == None, False) - assert_equal(a != None, True) - # With nomask - a = array([1, 2], mask=False) - assert_equal(a == None, False) - assert_equal(a != None, True) - # With complete mask - a = array([1, 2], mask=True) - assert_equal(a == None, False) - assert_equal(a != None, True) - # Fully masked, even comparison to None should return "masked" - a = masked - assert_equal(a == None, masked) + with suppress_warnings() as sup: + sup.filter(FutureWarning, "Comparison to `None`") + a = array([1, 2], mask=[0, 1]) + assert_equal(a == None, False) + assert_equal(a.data == None, False) + assert_equal(a.mask == None, False) + assert_equal(a != None, True) + # With nomask + a = array([1, 2], mask=False) + assert_equal(a == None, False) + assert_equal(a != None, True) + # With complete mask + a = array([1, 2], mask=True) + assert_equal(a == None, False) + assert_equal(a != None, True) + # Fully masked, even comparison to None should return "masked" + a = masked + assert_equal(a == None, masked) def test_eq_w_scalar(self): a = array(1) @@ -2416,8 +2429,9 @@ def test_inplace_floor_division_array_type(self): def test_inplace_division_scalar_type(self): # Test of inplace division for t in self.othertypes: - with warnings.catch_warnings(record=True) as w: - warnings.filterwarnings("always") + with suppress_warnings() as sup: + sup.record(UserWarning) + (x, y, xm) = (_.astype(t) for _ in self.uint8data) x = arange(10, dtype=t) * t(2) xm = arange(10, dtype=t) * t(2) @@ -2444,15 +2458,15 @@ def test_inplace_division_scalar_type(self): warnings.warn(str(e)) if issubclass(t, np.integer): - assert_equal(len(w), 2, "Failed on type=%s." % t) + assert_equal(len(sup.log), 2, "Failed on type=%s." % t) else: - assert_equal(len(w), 0, "Failed on type=%s." % t) + assert_equal(len(sup.log), 0, "Failed on type=%s." % t) def test_inplace_division_array_type(self): # Test of inplace division for t in self.othertypes: - with warnings.catch_warnings(record=True) as w: - warnings.filterwarnings("always") + with suppress_warnings() as sup: + sup.record(UserWarning) (x, y, xm) = (_.astype(t) for _ in self.uint8data) m = xm.mask a = arange(10, dtype=t) @@ -2483,9 +2497,9 @@ def test_inplace_division_array_type(self): warnings.warn(str(e)) if issubclass(t, np.integer): - assert_equal(len(w), 2, "Failed on type=%s." % t) + assert_equal(len(sup.log), 2, "Failed on type=%s." % t) else: - assert_equal(len(w), 0, "Failed on type=%s." % t) + assert_equal(len(sup.log), 0, "Failed on type=%s." % t) def test_inplace_pow_type(self): # Test keeping data w/ (inplace) power @@ -2762,6 +2776,7 @@ def test_empty(self): b = a.view(masked_array) assert_(np.may_share_memory(a.mask, b.mask)) + @suppress_copy_mask_on_assignment def test_put(self): # Tests put. d = arange(5) @@ -3347,6 +3362,7 @@ def test_varstd(self): assert_almost_equal(np.sqrt(mXvar0[k]), mX[:, k].compressed().std()) + @suppress_copy_mask_on_assignment def test_varstd_specialcases(self): # Test a special case for var nout = np.array(-1, dtype=float) @@ -3359,15 +3375,11 @@ def test_varstd_specialcases(self): self.assertTrue(method(0) is masked) self.assertTrue(method(-1) is masked) # Using a masked array as explicit output - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - method(out=mout) + method(out=mout) self.assertTrue(mout is not masked) assert_equal(mout.mask, True) # Using a ndarray as explicit output - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - method(out=nout) + method(out=nout) self.assertTrue(np.isnan(nout)) x = array(arange(10), mask=True) diff --git a/numpy/ma/tests/test_extras.py b/numpy/ma/tests/test_extras.py index 33c4b19225e8..45c7e2e8aeef 100644 --- a/numpy/ma/tests/test_extras.py +++ b/numpy/ma/tests/test_extras.py @@ -13,7 +13,7 @@ import numpy as np from numpy.testing import ( - TestCase, run_module_suite, assert_warns, clear_and_catch_warnings + TestCase, run_module_suite, assert_warns, suppress_warnings ) from numpy.ma.testutils import ( assert_, assert_array_equal, assert_equal, assert_almost_equal @@ -826,12 +826,6 @@ def test_2d_w_missing(self): x.shape[0] / frac)) -class catch_warn_mae(clear_and_catch_warnings): - """ Context manager to catch, reset warnings in ma.extras module - """ - class_modules = (mae,) - - class TestCorrcoef(TestCase): def setUp(self): @@ -843,10 +837,10 @@ def test_ddof(self): x, y = self.data, self.data2 expected = np.corrcoef(x) expected2 = np.corrcoef(x, y) - with catch_warn_mae(): + with suppress_warnings() as sup: warnings.simplefilter("always") assert_warns(DeprecationWarning, corrcoef, x, ddof=-1) - warnings.simplefilter("ignore") + sup.filter(DeprecationWarning, "bias and ddof have no effect") # ddof has no or negligible effect on the function assert_almost_equal(np.corrcoef(x, ddof=0), corrcoef(x, ddof=0)) assert_almost_equal(corrcoef(x, ddof=-1), expected) @@ -858,12 +852,12 @@ def test_bias(self): x, y = self.data, self.data2 expected = np.corrcoef(x) # bias raises DeprecationWarning - with catch_warn_mae(): + with suppress_warnings() as sup: warnings.simplefilter("always") assert_warns(DeprecationWarning, corrcoef, x, y, True, False) assert_warns(DeprecationWarning, corrcoef, x, y, True, True) assert_warns(DeprecationWarning, corrcoef, x, bias=False) - warnings.simplefilter("ignore") + sup.filter(DeprecationWarning, "bias and ddof have no effect") # bias has no or negligible effect on the function assert_almost_equal(corrcoef(x, bias=1), expected) @@ -873,8 +867,8 @@ def test_1d_wo_missing(self): assert_almost_equal(np.corrcoef(x), corrcoef(x)) assert_almost_equal(np.corrcoef(x, rowvar=False), corrcoef(x, rowvar=False)) - with catch_warn_mae(): - warnings.simplefilter("ignore") + with suppress_warnings() as sup: + sup.filter(DeprecationWarning, "bias and ddof have no effect") assert_almost_equal(np.corrcoef(x, rowvar=False, bias=True), corrcoef(x, rowvar=False, bias=True)) @@ -884,8 +878,8 @@ def test_2d_wo_missing(self): assert_almost_equal(np.corrcoef(x), corrcoef(x)) assert_almost_equal(np.corrcoef(x, rowvar=False), corrcoef(x, rowvar=False)) - with catch_warn_mae(): - warnings.simplefilter("ignore") + with suppress_warnings() as sup: + sup.filter(DeprecationWarning, "bias and ddof have no effect") assert_almost_equal(np.corrcoef(x, rowvar=False, bias=True), corrcoef(x, rowvar=False, bias=True)) @@ -898,8 +892,8 @@ def test_1d_w_missing(self): assert_almost_equal(np.corrcoef(nx), corrcoef(x)) assert_almost_equal(np.corrcoef(nx, rowvar=False), corrcoef(x, rowvar=False)) - with catch_warn_mae(): - warnings.simplefilter("ignore") + with suppress_warnings() as sup: + sup.filter(DeprecationWarning, "bias and ddof have no effect") assert_almost_equal(np.corrcoef(nx, rowvar=False, bias=True), corrcoef(x, rowvar=False, bias=True)) try: @@ -911,8 +905,8 @@ def test_1d_w_missing(self): assert_almost_equal(np.corrcoef(nx, nx[::-1]), corrcoef(x, x[::-1])) assert_almost_equal(np.corrcoef(nx, nx[::-1], rowvar=False), corrcoef(x, x[::-1], rowvar=False)) - with catch_warn_mae(): - warnings.simplefilter("ignore") + with suppress_warnings() as sup: + sup.filter(DeprecationWarning, "bias and ddof have no effect") # ddof and bias have no or negligible effect on the function assert_almost_equal(np.corrcoef(nx, nx[::-1]), corrcoef(x, x[::-1], bias=1)) @@ -928,8 +922,8 @@ def test_2d_w_missing(self): test = corrcoef(x) control = np.corrcoef(x) assert_almost_equal(test[:-1, :-1], control[:-1, :-1]) - with catch_warn_mae(): - warnings.simplefilter("ignore") + with suppress_warnings() as sup: + sup.filter(DeprecationWarning, "bias and ddof have no effect") # ddof and bias have no or negligible effect on the function assert_almost_equal(corrcoef(x, ddof=-2)[:-1, :-1], control[:-1, :-1]) diff --git a/numpy/ma/tests/test_mrecords.py b/numpy/ma/tests/test_mrecords.py index e97f337f5657..ea5d14de074a 100644 --- a/numpy/ma/tests/test_mrecords.py +++ b/numpy/ma/tests/test_mrecords.py @@ -148,11 +148,9 @@ def test_set_fields(self): rdata = data.view(MaskedRecords) val = ma.array([10, 20, 30], mask=[1, 0, 0]) - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - rdata['num'] = val - assert_equal(rdata.num, val) - assert_equal(rdata.num.mask, [1, 0, 0]) + rdata['num'] = val + assert_equal(rdata.num, val) + assert_equal(rdata.num.mask, [1, 0, 0]) def test_set_fields_mask(self): # Tests setting the mask of a field. diff --git a/numpy/ma/tests/test_old_ma.py b/numpy/ma/tests/test_old_ma.py index ed8304d6327c..2ea53683d1ae 100644 --- a/numpy/ma/tests/test_old_ma.py +++ b/numpy/ma/tests/test_old_ma.py @@ -5,7 +5,8 @@ import numpy as np import numpy.core.umath as umath import numpy.core.fromnumeric as fromnumeric -from numpy.testing import TestCase, run_module_suite, assert_ +from numpy.testing import ( + TestCase, run_module_suite, assert_, suppress_warnings) from numpy.ma.testutils import assert_array_equal from numpy.ma import ( MaskType, MaskedArray, absolute, add, all, allclose, allequal, alltrue, @@ -257,62 +258,73 @@ def test_testCI(self): def test_testCopySize(self): # Tests of some subtle points of copying and sizing. - n = [0, 0, 1, 0, 0] - m = make_mask(n) - m2 = make_mask(m) - self.assertTrue(m is m2) - m3 = make_mask(m, copy=1) - self.assertTrue(m is not m3) - - x1 = np.arange(5) - y1 = array(x1, mask=m) - self.assertTrue(y1._data is not x1) - self.assertTrue(allequal(x1, y1._data)) - self.assertTrue(y1.mask is m) - - y1a = array(y1, copy=0) - self.assertTrue(y1a.mask is y1.mask) - - y2 = array(x1, mask=m, copy=0) - self.assertTrue(y2.mask is m) - self.assertTrue(y2[2] is masked) - y2[2] = 9 - self.assertTrue(y2[2] is not masked) - self.assertTrue(y2.mask is not m) - self.assertTrue(allequal(y2.mask, 0)) - - y3 = array(x1 * 1.0, mask=m) - self.assertTrue(filled(y3).dtype is (x1 * 1.0).dtype) - - x4 = arange(4) - x4[2] = masked - y4 = resize(x4, (8,)) - self.assertTrue(eq(concatenate([x4, x4]), y4)) - self.assertTrue(eq(getmask(y4), [0, 0, 1, 0, 0, 0, 1, 0])) - y5 = repeat(x4, (2, 2, 2, 2), axis=0) - self.assertTrue(eq(y5, [0, 0, 1, 1, 2, 2, 3, 3])) - y6 = repeat(x4, 2, axis=0) - self.assertTrue(eq(y5, y6)) + with suppress_warnings() as sup: + sup.filter( + np.ma.core.MaskedArrayFutureWarning, + "setting an item on a masked array which has a " + "shared mask will not copy") + + n = [0, 0, 1, 0, 0] + m = make_mask(n) + m2 = make_mask(m) + self.assertTrue(m is m2) + m3 = make_mask(m, copy=1) + self.assertTrue(m is not m3) + + x1 = np.arange(5) + y1 = array(x1, mask=m) + self.assertTrue(y1._data is not x1) + self.assertTrue(allequal(x1, y1._data)) + self.assertTrue(y1.mask is m) + + y1a = array(y1, copy=0) + self.assertTrue(y1a.mask is y1.mask) + + y2 = array(x1, mask=m, copy=0) + self.assertTrue(y2.mask is m) + self.assertTrue(y2[2] is masked) + y2[2] = 9 + self.assertTrue(y2[2] is not masked) + self.assertTrue(y2.mask is not m) + self.assertTrue(allequal(y2.mask, 0)) + + y3 = array(x1 * 1.0, mask=m) + self.assertTrue(filled(y3).dtype is (x1 * 1.0).dtype) + + x4 = arange(4) + x4[2] = masked + y4 = resize(x4, (8,)) + self.assertTrue(eq(concatenate([x4, x4]), y4)) + self.assertTrue(eq(getmask(y4), [0, 0, 1, 0, 0, 0, 1, 0])) + y5 = repeat(x4, (2, 2, 2, 2), axis=0) + self.assertTrue(eq(y5, [0, 0, 1, 1, 2, 2, 3, 3])) + y6 = repeat(x4, 2, axis=0) + self.assertTrue(eq(y5, y6)) def test_testPut(self): # Test of put - d = arange(5) - n = [0, 0, 0, 1, 1] - m = make_mask(n) - x = array(d, mask=m) - self.assertTrue(x[3] is masked) - self.assertTrue(x[4] is masked) - x[[1, 4]] = [10, 40] - self.assertTrue(x.mask is not m) - self.assertTrue(x[3] is masked) - self.assertTrue(x[4] is not masked) - self.assertTrue(eq(x, [0, 10, 2, -1, 40])) - - x = array(d, mask=m) - x.put([0, 1, 2], [-1, 100, 200]) - self.assertTrue(eq(x, [-1, 100, 200, 0, 0])) - self.assertTrue(x[3] is masked) - self.assertTrue(x[4] is masked) + with suppress_warnings() as sup: + sup.filter( + np.ma.core.MaskedArrayFutureWarning, + "setting an item on a masked array which has a " + "shared mask will not copy") + d = arange(5) + n = [0, 0, 0, 1, 1] + m = make_mask(n) + x = array(d, mask=m) + self.assertTrue(x[3] is masked) + self.assertTrue(x[4] is masked) + x[[1, 4]] = [10, 40] + self.assertTrue(x.mask is not m) + self.assertTrue(x[3] is masked) + self.assertTrue(x[4] is not masked) + self.assertTrue(eq(x, [0, 10, 2, -1, 40])) + + x = array(d, mask=m) + x.put([0, 1, 2], [-1, 100, 200]) + self.assertTrue(eq(x, [-1, 100, 200, 0, 0])) + self.assertTrue(x[3] is masked) + self.assertTrue(x[4] is masked) def test_testMaPut(self): (x, y, a10, m1, m2, xm, ym, z, zm, xf, s) = self.d diff --git a/numpy/ma/tests/test_regression.py b/numpy/ma/tests/test_regression.py index dba74d357c3d..fc6cdfaff614 100644 --- a/numpy/ma/tests/test_regression.py +++ b/numpy/ma/tests/test_regression.py @@ -4,7 +4,8 @@ import numpy as np from numpy.testing import (assert_, TestCase, assert_array_equal, - assert_allclose, run_module_suite) + assert_allclose, run_module_suite, + suppress_warnings) from numpy.compat import sixu rlevel = 1 @@ -69,8 +70,9 @@ def test_ddof_corrcoef(self): # See gh-3336 x = np.ma.masked_equal([1, 2, 3, 4, 5], 4) y = np.array([2, 2.5, 3.1, 3, 5]) - with warnings.catch_warnings(): - warnings.simplefilter("ignore") + # this test can be removed after deprecation. + with suppress_warnings() as sup: + sup.filter(DeprecationWarning, "bias and ddof have no effect") r0 = np.ma.corrcoef(x, y, ddof=0) r1 = np.ma.corrcoef(x, y, ddof=1) # ddof should not have an effect (it gets cancelled out) diff --git a/numpy/random/tests/test_random.py b/numpy/random/tests/test_random.py index a06de58e33ef..012bf48266d3 100644 --- a/numpy/random/tests/test_random.py +++ b/numpy/random/tests/test_random.py @@ -3,7 +3,8 @@ import numpy as np from numpy.testing import ( TestCase, run_module_suite, assert_, assert_raises, assert_equal, - assert_warns, assert_array_equal, assert_array_almost_equal) + assert_warns, assert_array_equal, assert_array_almost_equal, + suppress_warnings) from numpy import random from numpy.compat import asbytes import sys @@ -260,13 +261,14 @@ def test_randint(self): def test_random_integers(self): np.random.seed(self.seed) - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) + with suppress_warnings() as sup: + w = sup.record(DeprecationWarning) actual = np.random.random_integers(-99, 99, size=(3, 2)) - desired = np.array([[31, 3], - [-52, 41], - [-48, -66]]) - assert_array_equal(actual, desired) + assert_(len(w) == 1) + desired = np.array([[31, 3], + [-52, 41], + [-48, -66]]) + assert_array_equal(actual, desired) def test_random_integers_max_int(self): # Tests whether random_integers can generate the @@ -274,12 +276,14 @@ def test_random_integers_max_int(self): # into a C long. Previous implementations of this # method have thrown an OverflowError when attempting # to generate this integer. - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) + with suppress_warnings() as sup: + w = sup.record(DeprecationWarning) actual = np.random.random_integers(np.iinfo('l').max, np.iinfo('l').max) - desired = np.iinfo('l').max - assert_equal(actual, desired) + assert_(len(w) == 1) + + desired = np.iinfo('l').max + assert_equal(actual, desired) def test_random_integers_deprecated(self): with warnings.catch_warnings(): From 9bf7d1475468e16b7dcac93eb85338930f16ea4d Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Sun, 19 Jun 2016 14:18:21 +0200 Subject: [PATCH 07/13] ENH: Use new context manager for testing Making the outer context manager a suppress warnings gives good control to print warnings only once in release mode and suppress some specific warnings which cannot be easily avoided otherwise. --- doc/release/1.12.0-notes.rst | 11 +++++++-- numpy/testing/nosetester.py | 43 ++++++++++++++++++++++-------------- runtests.py | 2 +- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/doc/release/1.12.0-notes.rst b/doc/release/1.12.0-notes.rst index 7b315b90bef7..ef8131e898da 100644 --- a/doc/release/1.12.0-notes.rst +++ b/doc/release/1.12.0-notes.rst @@ -111,6 +111,13 @@ previous implementation used in ``assert_array_almost_equal``. Due to the change in implementation some very delicate tests may fail that did not fail before. +``NoseTester`` behaviour of warnings during testing +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When ``raise_warnings="develop"`` is given, all uncaught warnings will now +be considered a test failure. Previously only selected ones were raised. +Warnings which are not caught or raised (mostly when in release mode) +will be shown once during the test cycle similar to the default python +settings. ``assert_warns`` and ``deprecated`` decorator more specific ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -193,8 +200,8 @@ precision. New array creation function ``geomspace`` added ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The new function ``geomspace`` generates a geometric sequence. It is similar -to ``logspace``, but with start and stop specified directly: -``geomspace(start, stop)`` behaves the same as +to ``logspace``, but with start and stop specified directly: +``geomspace(start, stop)`` behaves the same as ``logspace(log10(start), log10(stop))``. New context manager for testing warnings diff --git a/numpy/testing/nosetester.py b/numpy/testing/nosetester.py index 6fff240eb897..c30c0eecd85f 100644 --- a/numpy/testing/nosetester.py +++ b/numpy/testing/nosetester.py @@ -135,9 +135,9 @@ class NoseTester(object): which `NoseTester` is initialized. raise_warnings : None, str or sequence of warnings, optional This specifies which warnings to configure as 'raise' instead - of 'warn' during the test execution. Valid strings are: + of being shown once during the test execution. Valid strings are: - - "develop" : equals ``(DeprecationWarning, RuntimeWarning)`` + - "develop" : equals ``(Warning,)`` - "release" : equals ``()``, don't raise on any warnings. Default is "release". @@ -297,8 +297,7 @@ def prepare_test_args(self, label='fast', verbose=1, extra_argv=None, return argv, plugins def test(self, label='fast', verbose=1, extra_argv=None, - doctests=False, coverage=False, - raise_warnings=None): + doctests=False, coverage=False, raise_warnings=None): """ Run tests for module using nose. @@ -324,13 +323,15 @@ def test(self, label='fast', verbose=1, extra_argv=None, If True, report coverage of NumPy code. Default is False. (This requires the `coverage module: `_). - raise_warnings : str or sequence of warnings, optional + raise_warnings : None, str or sequence of warnings, optional This specifies which warnings to configure as 'raise' instead - of 'warn' during the test execution. Valid strings are: + of being shown once during the test execution. Valid strings are: - - "develop" : equals ``(DeprecationWarning, RuntimeWarning)`` + - "develop" : equals ``(Warning,)`` - "release" : equals ``()``, don't raise on any warnings. + The default is to use the class initialization value. + Returns ------- result : object @@ -379,12 +380,12 @@ def test(self, label='fast', verbose=1, extra_argv=None, if raise_warnings is None: raise_warnings = self.raise_warnings - _warn_opts = dict(develop=(DeprecationWarning, RuntimeWarning), + _warn_opts = dict(develop=(Warning,), release=()) if isinstance(raise_warnings, basestring): raise_warnings = _warn_opts[raise_warnings] - with warnings.catch_warnings(): + with suppress_warnings("location") as sup: # Reset the warning filters to the default state, # so that running the tests is more repeatable. warnings.resetwarnings() @@ -395,18 +396,27 @@ def test(self, label='fast', verbose=1, extra_argv=None, for warningtype in raise_warnings: warnings.filterwarnings('error', category=warningtype) # Filter out annoying import messages. - warnings.filterwarnings('ignore', message='Not importing directory') - warnings.filterwarnings("ignore", message="numpy.dtype size changed") - warnings.filterwarnings("ignore", message="numpy.ufunc size changed") - warnings.filterwarnings("ignore", category=np.ModuleDeprecationWarning) - warnings.filterwarnings("ignore", category=FutureWarning) + sup.filter(message='Not importing directory') + sup.filter(message="numpy.dtype size changed") + sup.filter(message="numpy.ufunc size changed") + sup.filter(category=np.ModuleDeprecationWarning) # Filter out boolean '-' deprecation messages. This allows # older versions of scipy to test without a flood of messages. - warnings.filterwarnings("ignore", message=".*boolean negative.*") - warnings.filterwarnings("ignore", message=".*boolean subtract.*") + sup.filter(message=".*boolean negative.*") + sup.filter(message=".*boolean subtract.*") + # Filter out distutils cpu warnings (could be localized to + # distutils tests). ASV has problems with top level import, + # so fetch module for suppression here. + with warnings.catch_warnings(): + warnings.simplefilter("always") + from ..distutils import cpuinfo + sup.filter(category=UserWarning, module=cpuinfo) + # Filter out some deprecation warnings inside nose 1.3.7 when run # on python 3.5b2. See # https://github.com/nose-devs/nose/issues/929 + # Note: it is hard to filter based on module for sup (lineno could + # be implemented). warnings.filterwarnings("ignore", message=".*getargspec.*", category=DeprecationWarning, module="nose\.") @@ -415,6 +425,7 @@ def test(self, label='fast', verbose=1, extra_argv=None, argv, plugins = self.prepare_test_args( label, verbose, extra_argv, doctests, coverage) + t = NumpyTestProgram(argv=argv, exit=False, plugins=plugins) return t.result diff --git a/runtests.py b/runtests.py index b2d287d22a4c..9008950e9c04 100755 --- a/runtests.py +++ b/runtests.py @@ -113,7 +113,7 @@ def main(argv): "Note that you need to commit your changes first!")) parser.add_argument("--raise-warnings", default=None, type=str, choices=('develop', 'release'), - help="if 'develop', some warnings are treated as errors") + help="if 'develop', warnings are treated as errors") parser.add_argument("args", metavar="ARGS", default=[], nargs=REMAINDER, help="Arguments to pass to Nose, Python or shell") args = parser.parse_args(argv) From f078cb484aa46dd6834c92ac25c587fa36cd727a Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Mon, 29 Aug 2016 22:10:10 +0200 Subject: [PATCH 08/13] ENH: Masked array simplify copying back of unchanged values Also silences a spurious warning during tests (the multiplication could give a warning). --- numpy/ma/core.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/numpy/ma/core.py b/numpy/ma/core.py index b01656ec9c52..b1e48c156708 100644 --- a/numpy/ma/core.py +++ b/numpy/ma/core.py @@ -1032,12 +1032,7 @@ def __call__(self, a, b, *args, **kwargs): if m is not nomask and m.any(): # any errors, just abort; impossible to guarantee masked values try: - np.copyto(result, 0, casting='unsafe', where=m) - # avoid using "*" since this may be overlaid - masked_da = umath.multiply(m, da) - # only add back if it can be cast safely - if np.can_cast(masked_da.dtype, result.dtype, casting='safe'): - result += masked_da + np.copyto(result, da, casting='unsafe', where=m) except: pass From 2e86117d7ba2b4b0308b05a67b922f6db19a7c02 Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Mon, 29 Aug 2016 22:20:28 +0200 Subject: [PATCH 09/13] TST: Silence warnings otherwise shown in release mode These are warnings, which when raised as an error for one reason or another are already silenced. --- numpy/core/tests/test_regression.py | 3 ++- numpy/linalg/tests/test_regression.py | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py index b1d1673dd1c1..5966ff688652 100644 --- a/numpy/core/tests/test_regression.py +++ b/numpy/core/tests/test_regression.py @@ -139,7 +139,7 @@ def test_scalar_compare(self,level=rlevel): b = np.linspace(0, 10, 11) # This should return true for now, but will eventually raise an error: with suppress_warnings() as sup: - sup.filter(DeprecationWarning) + sup.filter(FutureWarning) self.assertTrue(b != 'auto') self.assertTrue(b[0] != 'auto') @@ -813,6 +813,7 @@ def ia(x, s, v): # and the boolean special case is not taken. with suppress_warnings() as sup: sup.filter(DeprecationWarning) + sup.filter(FutureWarning) sup.filter(np.VisibleDeprecationWarning) self.assertRaises(IndexError, ia, x, s, np.zeros(9, dtype=float)) self.assertRaises(IndexError, ia, x, s, np.zeros(11, dtype=float)) diff --git a/numpy/linalg/tests/test_regression.py b/numpy/linalg/tests/test_regression.py index 6991628fba0d..d2080b709b4a 100644 --- a/numpy/linalg/tests/test_regression.py +++ b/numpy/linalg/tests/test_regression.py @@ -2,6 +2,8 @@ """ from __future__ import division, absolute_import, print_function +import warnings + import numpy as np from numpy import linalg, arange, float64, array, dot, transpose from numpy.testing import ( @@ -110,8 +112,10 @@ def test_norm_object_array(self): self.assertRaises(ValueError, linalg.norm, testvector, ord='nuc') self.assertRaises(ValueError, linalg.norm, testvector, ord=np.inf) self.assertRaises(ValueError, linalg.norm, testvector, ord=-np.inf) - self.assertRaises((AttributeError, DeprecationWarning), - linalg.norm, testvector, ord=0) + with warnings.catch_warnings(): + warnings.simplefilter("error", DeprecationWarning) + self.assertRaises((AttributeError, DeprecationWarning), + linalg.norm, testvector, ord=0) self.assertRaises(ValueError, linalg.norm, testvector, ord=-1) self.assertRaises(ValueError, linalg.norm, testvector, ord=-2) From b831444bee734537daeaffd1455eb88663ee3763 Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Mon, 29 Aug 2016 23:20:16 +0200 Subject: [PATCH 10/13] MAINT: Close some filehandlers and PIPEs after being done The PIPE in the tests caused a ResourceWarning during testing in python 3. --- numpy/distutils/fcompiler/gnu.py | 1 + numpy/distutils/system_info.py | 11 ++++++----- numpy/distutils/tests/test_system_info.py | 4 +++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/numpy/distutils/fcompiler/gnu.py b/numpy/distutils/fcompiler/gnu.py index 7c3dc416293c..9697aa8dba44 100644 --- a/numpy/distutils/fcompiler/gnu.py +++ b/numpy/distutils/fcompiler/gnu.py @@ -364,6 +364,7 @@ def _can_target(cmd, arch): """Return true if the architecture supports the -arch flag""" newcmd = cmd[:] fid, filename = tempfile.mkstemp(suffix=".f") + fid.close() try: d = os.path.dirname(filename) output = os.path.splitext(filename)[0] + ".o" diff --git a/numpy/distutils/system_info.py b/numpy/distutils/system_info.py index 014223b745ac..c3a62464bb72 100644 --- a/numpy/distutils/system_info.py +++ b/numpy/distutils/system_info.py @@ -242,7 +242,7 @@ def libpaths(paths, bits): # tests are run in debug mode Python 3. tmp = open(os.devnull, 'w') p = sp.Popen(["gcc", "-print-multiarch"], stdout=sp.PIPE, - stderr=tmp) + stderr=tmp) except (OSError, DistutilsError): # OSError if gcc is not installed, or SandboxViolation (DistutilsError # subclass) if an old setuptools bug is triggered (see gh-3160). @@ -971,10 +971,11 @@ def get_mkl_rootdir(self): paths = os.environ.get('LD_LIBRARY_PATH', '').split(os.pathsep) ld_so_conf = '/etc/ld.so.conf' if os.path.isfile(ld_so_conf): - for d in open(ld_so_conf, 'r'): - d = d.strip() - if d: - paths.append(d) + with open(ld_so_conf, 'r') as f: + for d in f: + d = d.strip() + if d: + paths.append(d) intel_mkl_dirs = [] for path in paths: path_atoms = path.split(os.sep) diff --git a/numpy/distutils/tests/test_system_info.py b/numpy/distutils/tests/test_system_info.py index 0f45cd79e2b6..54975cae5f20 100644 --- a/numpy/distutils/tests/test_system_info.py +++ b/numpy/distutils/tests/test_system_info.py @@ -69,7 +69,9 @@ def have_compiler(): return False cmd = [compiler.cc] try: - Popen(cmd, stdout=PIPE, stderr=PIPE) + p = Popen(cmd, stdout=PIPE, stderr=PIPE) + p.stdout.close() + p.stderr.close() except OSError: return False return True From 61694be14e678ae49f35205d5af0aee4882e1a70 Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Tue, 30 Aug 2016 11:46:00 +0200 Subject: [PATCH 11/13] MAINT: Spell out with and without in ma test functions they used to be called `..._w_...` and `..._wo_...`. --- numpy/ma/tests/test_core.py | 16 ++++++++-------- numpy/ma/tests/test_extras.py | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py index 6719ed61828f..cbab5ad5b042 100644 --- a/numpy/ma/tests/test_core.py +++ b/numpy/ma/tests/test_core.py @@ -595,11 +595,11 @@ def test_oddfeatures_3(self): atest[idx] = btest[idx] assert_equal(atest, [20]) - def test_filled_w_object_dtype(self): + def test_filled_with_object_dtype(self): a = np.ma.masked_all(1, dtype='O') assert_equal(a.filled('x')[0], 'x') - def test_filled_w_flexible_dtype(self): + def test_filled_with_flexible_dtype(self): # Test filled w/ flexible dtype flexi = array([(1, 1, 1)], dtype=[('i', int), ('s', '|S8'), ('f', float)]) @@ -612,7 +612,7 @@ def test_filled_w_flexible_dtype(self): assert_equal(flexi.filled(1), np.array([(1, '1', 1.)], dtype=flexi.dtype)) - def test_filled_w_mvoid(self): + def test_filled_with_mvoid(self): # Test filled w/ mvoid ndtype = [('a', int), ('b', float)] a = mvoid((1, 2.), mask=[(0, 1)], dtype=ndtype) @@ -626,7 +626,7 @@ def test_filled_w_mvoid(self): a.fill_value = (-999, -999) assert_equal(tuple(a.filled()), (1, -999)) - def test_filled_w_nested_dtype(self): + def test_filled_with_nested_dtype(self): # Test filled w/ nested dtype ndtype = [('A', int), ('B', [('BA', int), ('BB', int)])] a = array([(1, (1, 1)), (2, (2, 2))], @@ -646,7 +646,7 @@ def test_filled_w_nested_dtype(self): assert_equal(Z.mask.dtype, numpy.dtype([('A', [('f0', '?', (2, 2)), ('f1', '?', (2, 2))], (2, 2))])) - def test_filled_w_f_order(self): + def test_filled_with_f_order(self): # Test filled w/ F-contiguous array a = array(np.array([(0, 1, 2), (4, 5, 6)], order='F'), mask=np.array([(0, 0, 1), (1, 0, 0)], order='F'), @@ -1341,7 +1341,7 @@ def test_ne_on_structured(self): assert_equal(test, [False, True]) assert_equal(test.mask, [False, False]) - def test_eq_w_None(self): + def test_eq_with_None(self): # Really, comparisons with None should not be done, but check them # anyway. Note that pep8 will flag these tests. # Deprecation is in place for arrays, and when it happens this @@ -1367,7 +1367,7 @@ def test_eq_w_None(self): a = masked assert_equal(a == None, masked) - def test_eq_w_scalar(self): + def test_eq_with_scalar(self): a = array(1) assert_equal(a == 1, True) assert_equal(a == 0, False) @@ -3682,7 +3682,7 @@ def test_power(self): assert_almost_equal(x, y) assert_almost_equal(x._data, y._data) - def test_power_w_broadcasting(self): + def test_power_with_broadcasting(self): # Test power w/ broadcasting a2 = np.array([[1., 2., 3.], [4., 5., 6.]]) a2m = array(a2, mask=[[1, 0, 0], [0, 0, 1]]) diff --git a/numpy/ma/tests/test_extras.py b/numpy/ma/tests/test_extras.py index 45c7e2e8aeef..6d56d4dc6c92 100644 --- a/numpy/ma/tests/test_extras.py +++ b/numpy/ma/tests/test_extras.py @@ -764,7 +764,7 @@ class TestCov(TestCase): def setUp(self): self.data = array(np.random.rand(12)) - def test_1d_wo_missing(self): + def test_1d_without_missing(self): # Test cov on 1D variable w/o missing values x = self.data assert_almost_equal(np.cov(x), cov(x)) @@ -772,7 +772,7 @@ def test_1d_wo_missing(self): assert_almost_equal(np.cov(x, rowvar=False, bias=True), cov(x, rowvar=False, bias=True)) - def test_2d_wo_missing(self): + def test_2d_without_missing(self): # Test cov on 1 2D variable w/o missing values x = self.data.reshape(3, 4) assert_almost_equal(np.cov(x), cov(x)) @@ -780,7 +780,7 @@ def test_2d_wo_missing(self): assert_almost_equal(np.cov(x, rowvar=False, bias=True), cov(x, rowvar=False, bias=True)) - def test_1d_w_missing(self): + def test_1d_with_missing(self): # Test cov 1 1D variable w/missing values x = self.data x[-1] = masked @@ -804,7 +804,7 @@ def test_1d_w_missing(self): assert_almost_equal(np.cov(nx, nx[::-1], rowvar=False, bias=True), cov(x, x[::-1], rowvar=False, bias=True)) - def test_2d_w_missing(self): + def test_2d_with_missing(self): # Test cov on 2D variable w/ missing value x = self.data x[-1] = masked @@ -861,7 +861,7 @@ def test_bias(self): # bias has no or negligible effect on the function assert_almost_equal(corrcoef(x, bias=1), expected) - def test_1d_wo_missing(self): + def test_1d_without_missing(self): # Test cov on 1D variable w/o missing values x = self.data assert_almost_equal(np.corrcoef(x), corrcoef(x)) @@ -872,7 +872,7 @@ def test_1d_wo_missing(self): assert_almost_equal(np.corrcoef(x, rowvar=False, bias=True), corrcoef(x, rowvar=False, bias=True)) - def test_2d_wo_missing(self): + def test_2d_without_missing(self): # Test corrcoef on 1 2D variable w/o missing values x = self.data.reshape(3, 4) assert_almost_equal(np.corrcoef(x), corrcoef(x)) @@ -883,7 +883,7 @@ def test_2d_wo_missing(self): assert_almost_equal(np.corrcoef(x, rowvar=False, bias=True), corrcoef(x, rowvar=False, bias=True)) - def test_1d_w_missing(self): + def test_1d_with_missing(self): # Test corrcoef 1 1D variable w/missing values x = self.data x[-1] = masked @@ -913,7 +913,7 @@ def test_1d_w_missing(self): assert_almost_equal(np.corrcoef(nx, nx[::-1]), corrcoef(x, x[::-1], ddof=2)) - def test_2d_w_missing(self): + def test_2d_with_missing(self): # Test corrcoef on 2D variable w/ missing value x = self.data x[-1] = masked From 20ea3a25119834c2224e32caebf4f2fb4966edd3 Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Wed, 31 Aug 2016 21:16:08 +0200 Subject: [PATCH 12/13] TST: Replace catch_warnings when recording is not enforced in test_nanfuncs --- numpy/lib/tests/test_nanfunctions.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/numpy/lib/tests/test_nanfunctions.py b/numpy/lib/tests/test_nanfunctions.py index e062bc0327a5..e4aea44820bf 100644 --- a/numpy/lib/tests/test_nanfunctions.py +++ b/numpy/lib/tests/test_nanfunctions.py @@ -167,8 +167,8 @@ def test_mutation(self): def test_result_values(self): for f, fcmp in zip(self.nanfuncs, [np.greater, np.less]): for row in _ndat: - with warnings.catch_warnings(record=True): - warnings.simplefilter('always') + with suppress_warnings() as sup: + sup.filter(RuntimeWarning, "invalid value encountered in") ind = f(row) val = row[ind] # comparing with NaN is tricky as the result @@ -589,8 +589,8 @@ def test_keepdims(self): w = np.random.random((4, 200)) * np.array(d.shape)[:, None] w = w.astype(np.intp) d[tuple(w)] = np.nan - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always', RuntimeWarning) + with suppress_warnings() as sup: + sup.filter(RuntimeWarning) res = np.nanmedian(d, axis=None, keepdims=True) assert_equal(res.shape, (1, 1, 1, 1)) res = np.nanmedian(d, axis=(0, 1), keepdims=True) @@ -687,8 +687,8 @@ def test_extended_axis_invalid(self): assert_raises(ValueError, np.nanmedian, d, axis=(1, 1)) def test_float_special(self): - with warnings.catch_warnings(record=True): - warnings.simplefilter('always', RuntimeWarning) + with suppress_warnings() as sup: + sup.filter(RuntimeWarning) a = np.array([[np.inf, np.nan], [np.nan, np.nan]]) assert_equal(np.nanmedian(a, axis=0), [np.inf, np.nan]) assert_equal(np.nanmedian(a, axis=1), [np.inf, np.nan]) @@ -725,8 +725,8 @@ def test_keepdims(self): w = np.random.random((4, 200)) * np.array(d.shape)[:, None] w = w.astype(np.intp) d[tuple(w)] = np.nan - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always', RuntimeWarning) + with suppress_warnings() as sup: + sup.filter(RuntimeWarning) res = np.nanpercentile(d, 90, axis=None, keepdims=True) assert_equal(res.shape, (1, 1, 1, 1)) res = np.nanpercentile(d, 90, axis=(0, 1), keepdims=True) @@ -821,8 +821,8 @@ def test_multiple_percentiles(self): large_mat[:, :, 3:] *= 2 for axis in [None, 0, 1]: for keepdim in [False, True]: - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') + with suppress_warnings() as sup: + sup.filter(RuntimeWarning, "All-NaN slice encountered") val = np.percentile(mat, perc, axis=axis, keepdims=keepdim) nan_val = np.nanpercentile(nan_mat, perc, axis=axis, keepdims=keepdim) From 514d13679a55a82a96689679002c4ddc514641ce Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Wed, 31 Aug 2016 21:22:17 +0200 Subject: [PATCH 13/13] TST: Use ComplexWarning suppression only where needed --- numpy/lib/tests/test_nanfunctions.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/numpy/lib/tests/test_nanfunctions.py b/numpy/lib/tests/test_nanfunctions.py index e4aea44820bf..06c0953b5df7 100644 --- a/numpy/lib/tests/test_nanfunctions.py +++ b/numpy/lib/tests/test_nanfunctions.py @@ -318,7 +318,9 @@ def test_dtype_from_dtype(self): for nf, rf in zip(self.nanfuncs, self.stdfuncs): for c in codes: with suppress_warnings() as sup: - sup.filter(np.ComplexWarning) + if nf in {np.nanstd, np.nanvar} and c in 'FDG': + # Giving the warning is a small bug, see gh-8000 + sup.filter(np.ComplexWarning) tgt = rf(mat, dtype=np.dtype(c), axis=1).dtype.type res = nf(mat, dtype=np.dtype(c), axis=1).dtype.type assert_(res is tgt) @@ -333,7 +335,9 @@ def test_dtype_from_char(self): for nf, rf in zip(self.nanfuncs, self.stdfuncs): for c in codes: with suppress_warnings() as sup: - sup.filter(np.ComplexWarning) + if nf in {np.nanstd, np.nanvar} and c in 'FDG': + # Giving the warning is a small bug, see gh-8000 + sup.filter(np.ComplexWarning) tgt = rf(mat, dtype=c, axis=1).dtype.type res = nf(mat, dtype=c, axis=1).dtype.type assert_(res is tgt)