summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatti Picus <matti.picus@gmail.com>2020-12-29 11:00:14 +0200
committerGitHub <noreply@github.com>2020-12-29 11:00:14 +0200
commit717df4e93234a1a290aa1b472b5c1c4e600009cd (patch)
tree4a55bd33af1e0857e4909b6a9b21c81efee710bd
parenta481a044c8cbd679ca736341056314ffd71d54a4 (diff)
parentdd25816ccb9701af74895c95d3f0f2d31abbdf01 (diff)
downloadnumpy-717df4e93234a1a290aa1b472b5c1c4e600009cd.tar.gz
Merge pull request #18051 from rpolley/deprecate-np-testing-dec-2
DEP: deprecate np.testing.dec
-rw-r--r--numpy/core/tests/test_deprecations.py214
-rw-r--r--numpy/testing/_private/decorators.py47
-rw-r--r--numpy/testing/tests/test_decorators.py210
3 files changed, 260 insertions, 211 deletions
diff --git a/numpy/core/tests/test_deprecations.py b/numpy/core/tests/test_deprecations.py
index ed238da9f..7760281ff 100644
--- a/numpy/core/tests/test_deprecations.py
+++ b/numpy/core/tests/test_deprecations.py
@@ -13,7 +13,7 @@ import sys
import numpy as np
from numpy.testing import (
- assert_raises, assert_warns, assert_, assert_array_equal
+ assert_raises, assert_warns, assert_, assert_array_equal, SkipTest, KnownFailureException
)
from numpy.core._multiarray_tests import fromstring_null_term_c_api
@@ -871,3 +871,215 @@ class TestDeprecatedUnpickleObjectScalar(_DeprecationTestCase):
def test_deprecated(self):
ctor = np.core.multiarray.scalar
self.assert_deprecated(lambda: ctor(np.dtype("O"), 1))
+
+try:
+ with warnings.catch_warnings():
+ warnings.simplefilter("always")
+ import nose # noqa: F401
+except ImportError:
+ HAVE_NOSE = False
+else:
+ HAVE_NOSE = True
+
+
+@pytest.mark.skipif(not HAVE_NOSE, reason="Needs nose")
+class TestNoseDecoratorsDeprecated(_DeprecationTestCase):
+ class DidntSkipException(Exception):
+ pass
+
+ def test_slow(self):
+ def _test_slow():
+ @np.testing.dec.slow
+ def slow_func(x, y, z):
+ pass
+
+ assert_(slow_func.slow)
+ self.assert_deprecated(_test_slow)
+
+ def test_setastest(self):
+ def _test_setastest():
+ @np.testing.dec.setastest()
+ def f_default(a):
+ pass
+
+ @np.testing.dec.setastest(True)
+ def f_istest(a):
+ pass
+
+ @np.testing.dec.setastest(False)
+ def f_isnottest(a):
+ pass
+
+ assert_(f_default.__test__)
+ assert_(f_istest.__test__)
+ assert_(not f_isnottest.__test__)
+ self.assert_deprecated(_test_setastest, num=3)
+
+ def test_skip_functions_hardcoded(self):
+ def _test_skip_functions_hardcoded():
+ @np.testing.dec.skipif(True)
+ def f1(x):
+ raise self.DidntSkipException
+
+ try:
+ f1('a')
+ except self.DidntSkipException:
+ raise Exception('Failed to skip')
+ except SkipTest().__class__:
+ pass
+
+ @np.testing.dec.skipif(False)
+ def f2(x):
+ raise self.DidntSkipException
+
+ try:
+ f2('a')
+ except self.DidntSkipException:
+ pass
+ except SkipTest().__class__:
+ raise Exception('Skipped when not expected to')
+ self.assert_deprecated(_test_skip_functions_hardcoded, num=2)
+
+ def test_skip_functions_callable(self):
+ def _test_skip_functions_callable():
+ def skip_tester():
+ return skip_flag == 'skip me!'
+
+ @np.testing.dec.skipif(skip_tester)
+ def f1(x):
+ raise self.DidntSkipException
+
+ try:
+ skip_flag = 'skip me!'
+ f1('a')
+ except self.DidntSkipException:
+ raise Exception('Failed to skip')
+ except SkipTest().__class__:
+ pass
+
+ @np.testing.dec.skipif(skip_tester)
+ def f2(x):
+ raise self.DidntSkipException
+
+ try:
+ skip_flag = 'five is right out!'
+ f2('a')
+ except self.DidntSkipException:
+ pass
+ except SkipTest().__class__:
+ raise Exception('Skipped when not expected to')
+ self.assert_deprecated(_test_skip_functions_callable, num=2)
+
+ def test_skip_generators_hardcoded(self):
+ def _test_skip_generators_hardcoded():
+ @np.testing.dec.knownfailureif(True, "This test is known to fail")
+ def g1(x):
+ yield from range(x)
+
+ try:
+ for j in g1(10):
+ pass
+ except KnownFailureException().__class__:
+ pass
+ else:
+ raise Exception('Failed to mark as known failure')
+
+ @np.testing.dec.knownfailureif(False, "This test is NOT known to fail")
+ def g2(x):
+ yield from range(x)
+ raise self.DidntSkipException('FAIL')
+
+ try:
+ for j in g2(10):
+ pass
+ except KnownFailureException().__class__:
+ raise Exception('Marked incorrectly as known failure')
+ except self.DidntSkipException:
+ pass
+ self.assert_deprecated(_test_skip_generators_hardcoded, num=2)
+
+ def test_skip_generators_callable(self):
+ def _test_skip_generators_callable():
+ def skip_tester():
+ return skip_flag == 'skip me!'
+
+ @np.testing.dec.knownfailureif(skip_tester, "This test is known to fail")
+ def g1(x):
+ yield from range(x)
+
+ try:
+ skip_flag = 'skip me!'
+ for j in g1(10):
+ pass
+ except KnownFailureException().__class__:
+ pass
+ else:
+ raise Exception('Failed to mark as known failure')
+
+ @np.testing.dec.knownfailureif(skip_tester, "This test is NOT known to fail")
+ def g2(x):
+ yield from range(x)
+ raise self.DidntSkipException('FAIL')
+
+ try:
+ skip_flag = 'do not skip'
+ for j in g2(10):
+ pass
+ except KnownFailureException().__class__:
+ raise Exception('Marked incorrectly as known failure')
+ except self.DidntSkipException:
+ pass
+ self.assert_deprecated(_test_skip_generators_callable, num=2)
+
+ def test_deprecated(self):
+ def _test_deprecated():
+ @np.testing.dec.deprecated(True)
+ def non_deprecated_func():
+ pass
+
+ @np.testing.dec.deprecated()
+ def deprecated_func():
+ import warnings
+ warnings.warn("TEST: deprecated func", DeprecationWarning, stacklevel=1)
+
+ @np.testing.dec.deprecated()
+ def deprecated_func2():
+ import warnings
+ warnings.warn("AHHHH", stacklevel=1)
+ raise ValueError
+
+ @np.testing.dec.deprecated()
+ def deprecated_func3():
+ import warnings
+ warnings.warn("AHHHH", stacklevel=1)
+
+ # marked as deprecated, but does not raise DeprecationWarning
+ assert_raises(AssertionError, non_deprecated_func)
+ # should be silent
+ deprecated_func()
+ 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)
+ self.assert_deprecated(_test_deprecated, num=4)
+
+ def test_parametrize(self):
+ def _test_parametrize():
+ # dec.parametrize assumes that it is being run by nose. Because
+ # we are running under pytest, we need to explicitly check the
+ # results.
+ @np.testing.dec.parametrize('base, power, expected',
+ [(1, 1, 1),
+ (2, 1, 2),
+ (2, 2, 4)])
+ def check_parametrize(base, power, expected):
+ assert_(base**power == expected)
+
+ count = 0
+ for test in check_parametrize():
+ test[0](*test[1:])
+ count += 1
+ assert_(count == 3)
+ self.assert_deprecated(_test_parametrize)
diff --git a/numpy/testing/_private/decorators.py b/numpy/testing/_private/decorators.py
index 4c87d1a49..cb49d9a73 100644
--- a/numpy/testing/_private/decorators.py
+++ b/numpy/testing/_private/decorators.py
@@ -14,6 +14,7 @@ function name, setup and teardown functions and so on - see
"""
import collections.abc
+import warnings
from .utils import SkipTest, assert_warns, HAS_REFCOUNT
@@ -23,6 +24,10 @@ __all__ = ['slow', 'setastest', 'skipif', 'knownfailureif', 'deprecated',
def slow(t):
"""
+ .. deprecated:: 1.21
+ This decorator is retained for compatibility with the nose testing framework, which is being phased out.
+ Please use the nose2 or pytest frameworks instead.
+
Label a test as 'slow'.
The exact definition of a slow test is obviously both subjective and
@@ -52,12 +57,19 @@ def slow(t):
print('Big, slow test')
"""
+ # Numpy 1.21, 2020-12-20
+ warnings.warn('the np.testing.dec decorators are included for nose support, and are '
+ 'deprecated since NumPy v1.21. Use the nose2 or pytest frameworks instead.', DeprecationWarning, stacklevel=2)
t.slow = True
return t
def setastest(tf=True):
"""
+ .. deprecated:: 1.21
+ This decorator is retained for compatibility with the nose testing framework, which is being phased out.
+ Please use the nose2 or pytest frameworks instead.
+
Signals to nose that this function is or is not a test.
Parameters
@@ -84,6 +96,9 @@ def setastest(tf=True):
pass
"""
+ # Numpy 1.21, 2020-12-20
+ warnings.warn('the np.testing.dec decorators are included for nose support, and are '
+ 'deprecated since NumPy v1.21. Use the nose2 or pytest frameworks instead.', DeprecationWarning, stacklevel=2)
def set_test(t):
t.__test__ = tf
return t
@@ -91,6 +106,10 @@ def setastest(tf=True):
def skipif(skip_condition, msg=None):
"""
+ .. deprecated:: 1.21
+ This decorator is retained for compatibility with the nose testing framework, which is being phased out.
+ Please use the nose2 or pytest frameworks instead.
+
Make function raise SkipTest exception if a given condition is true.
If the condition is a callable, it is used at runtime to dynamically
@@ -123,6 +142,10 @@ def skipif(skip_condition, msg=None):
# import time overhead at actual test-time.
import nose
+ # Numpy 1.21, 2020-12-20
+ warnings.warn('the np.testing.dec decorators are included for nose support, and are '
+ 'deprecated since NumPy v1.21. Use the nose2 or pytest frameworks instead.', DeprecationWarning, stacklevel=2)
+
# Allow for both boolean or callable skip conditions.
if isinstance(skip_condition, collections.abc.Callable):
skip_val = lambda: skip_condition()
@@ -167,6 +190,10 @@ def skipif(skip_condition, msg=None):
def knownfailureif(fail_condition, msg=None):
"""
+ .. deprecated:: 1.21
+ This decorator is retained for compatibility with the nose testing framework, which is being phased out.
+ Please use the nose2 or pytest frameworks instead.
+
Make function raise KnownFailureException exception if given condition is true.
If the condition is a callable, it is used at runtime to dynamically
@@ -195,6 +222,10 @@ def knownfailureif(fail_condition, msg=None):
function in order to transmit function name, and various other metadata.
"""
+ # Numpy 1.21, 2020-12-20
+ warnings.warn('the np.testing.dec decorators are included for nose support, and are '
+ 'deprecated since NumPy v1.21. Use the nose2 or pytest frameworks instead.', DeprecationWarning, stacklevel=2)
+
if msg is None:
msg = 'Test skipped due to known failure'
@@ -221,6 +252,10 @@ def knownfailureif(fail_condition, msg=None):
def deprecated(conditional=True):
"""
+ .. deprecated:: 1.21
+ This decorator is retained for compatibility with the nose testing framework, which is being phased out.
+ Please use the nose2 or pytest frameworks instead.
+
Filter deprecation warnings while running the test suite.
This decorator can be used to filter DeprecationWarning's, to avoid
@@ -249,6 +284,10 @@ def deprecated(conditional=True):
# import time overhead at actual test-time.
import nose
+ # Numpy 1.21, 2020-12-20
+ warnings.warn('the np.testing.dec decorators are included for nose support, and are '
+ 'deprecated since NumPy v1.21. Use the nose2 or pytest frameworks instead.', DeprecationWarning, stacklevel=2)
+
def _deprecated_imp(*args, **kwargs):
# Poor man's replacement for the with statement
with assert_warns(DeprecationWarning):
@@ -267,6 +306,10 @@ def deprecated(conditional=True):
def parametrize(vars, input):
"""
+ .. deprecated:: 1.21
+ This decorator is retained for compatibility with the nose testing framework, which is being phased out.
+ Please use the nose2 or pytest frameworks instead.
+
Pytest compatibility class. This implements the simplest level of
pytest.mark.parametrize for use in nose as an aid in making the transition
to pytest. It achieves that by adding a dummy var parameter and ignoring
@@ -279,6 +322,10 @@ def parametrize(vars, input):
"""
from .parameterized import parameterized
+ # Numpy 1.21, 2020-12-20
+ warnings.warn('the np.testing.dec decorators are included for nose support, and are '
+ 'deprecated since NumPy v1.21. Use the nose2 or pytest frameworks instead.', DeprecationWarning, stacklevel=2)
+
return parameterized(input)
_needs_refcount = skipif(not HAS_REFCOUNT, "python has no sys.getrefcount")
diff --git a/numpy/testing/tests/test_decorators.py b/numpy/testing/tests/test_decorators.py
deleted file mode 100644
index b60d6dfbc..000000000
--- a/numpy/testing/tests/test_decorators.py
+++ /dev/null
@@ -1,210 +0,0 @@
-"""
-Test the decorators from ``testing.decorators``.
-
-"""
-import warnings
-import pytest
-
-from numpy.testing import (
- assert_, assert_raises, dec, SkipTest, KnownFailureException,
- )
-
-
-try:
- with warnings.catch_warnings():
- warnings.simplefilter("always")
- import nose # noqa: F401
-except ImportError:
- HAVE_NOSE = False
-else:
- HAVE_NOSE = True
-
-
-@pytest.mark.skipif(not HAVE_NOSE, reason="Needs nose")
-class TestNoseDecorators:
- # These tests are run in a class for simplicity while still
- # getting a report on each, skipped or success.
-
- class DidntSkipException(Exception):
- pass
-
- def test_slow(self):
- @dec.slow
- def slow_func(x, y, z):
- pass
-
- assert_(slow_func.slow)
-
- def test_setastest(self):
- @dec.setastest()
- def f_default(a):
- pass
-
- @dec.setastest(True)
- def f_istest(a):
- pass
-
- @dec.setastest(False)
- def f_isnottest(a):
- pass
-
- assert_(f_default.__test__)
- assert_(f_istest.__test__)
- assert_(not f_isnottest.__test__)
-
- def test_skip_functions_hardcoded(self):
- @dec.skipif(True)
- def f1(x):
- raise self.DidntSkipException
-
- try:
- f1('a')
- except self.DidntSkipException:
- raise Exception('Failed to skip')
- except SkipTest().__class__:
- pass
-
- @dec.skipif(False)
- def f2(x):
- raise self.DidntSkipException
-
- try:
- f2('a')
- except self.DidntSkipException:
- pass
- except SkipTest().__class__:
- raise Exception('Skipped when not expected to')
-
- def test_skip_functions_callable(self):
- def skip_tester():
- return skip_flag == 'skip me!'
-
- @dec.skipif(skip_tester)
- def f1(x):
- raise self.DidntSkipException
-
- try:
- skip_flag = 'skip me!'
- f1('a')
- except self.DidntSkipException:
- raise Exception('Failed to skip')
- except SkipTest().__class__:
- pass
-
- @dec.skipif(skip_tester)
- def f2(x):
- raise self.DidntSkipException
-
- try:
- skip_flag = 'five is right out!'
- f2('a')
- except self.DidntSkipException:
- pass
- except SkipTest().__class__:
- raise Exception('Skipped when not expected to')
-
- def test_skip_generators_hardcoded(self):
- @dec.knownfailureif(True, "This test is known to fail")
- def g1(x):
- yield from range(x)
-
- try:
- for j in g1(10):
- pass
- except KnownFailureException().__class__:
- pass
- else:
- raise Exception('Failed to mark as known failure')
-
- @dec.knownfailureif(False, "This test is NOT known to fail")
- def g2(x):
- yield from range(x)
- raise self.DidntSkipException('FAIL')
-
- try:
- for j in g2(10):
- pass
- except KnownFailureException().__class__:
- raise Exception('Marked incorrectly as known failure')
- except self.DidntSkipException:
- pass
-
- def test_skip_generators_callable(self):
- def skip_tester():
- return skip_flag == 'skip me!'
-
- @dec.knownfailureif(skip_tester, "This test is known to fail")
- def g1(x):
- yield from range(x)
-
- try:
- skip_flag = 'skip me!'
- for j in g1(10):
- pass
- except KnownFailureException().__class__:
- pass
- else:
- raise Exception('Failed to mark as known failure')
-
- @dec.knownfailureif(skip_tester, "This test is NOT known to fail")
- def g2(x):
- yield from range(x)
- raise self.DidntSkipException('FAIL')
-
- try:
- skip_flag = 'do not skip'
- for j in g2(10):
- pass
- except KnownFailureException().__class__:
- raise Exception('Marked incorrectly as known failure')
- except self.DidntSkipException:
- pass
-
- def test_deprecated(self):
- @dec.deprecated(True)
- def non_deprecated_func():
- pass
-
- @dec.deprecated()
- def deprecated_func():
- import warnings
- warnings.warn("TEST: deprecated func", DeprecationWarning)
-
- @dec.deprecated()
- def deprecated_func2():
- import warnings
- warnings.warn("AHHHH")
- raise ValueError
-
- @dec.deprecated()
- def deprecated_func3():
- import warnings
- warnings.warn("AHHHH")
-
- # marked as deprecated, but does not raise DeprecationWarning
- assert_raises(AssertionError, non_deprecated_func)
- # should be silent
- deprecated_func()
- 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)
-
- def test_parametrize(self):
- # dec.parametrize assumes that it is being run by nose. Because
- # we are running under pytest, we need to explicitly check the
- # results.
- @dec.parametrize('base, power, expected',
- [(1, 1, 1),
- (2, 1, 2),
- (2, 2, 4)])
- def check_parametrize(base, power, expected):
- assert_(base**power == expected)
-
- count = 0
- for test in check_parametrize():
- test[0](*test[1:])
- count += 1
- assert_(count == 3)