Thanks to visit codestin.com
Credit goes to github.com

Skip to content

DEP: deprecate np.testing.dec #18051

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
214 changes: 213 additions & 1 deletion numpy/core/tests/test_deprecations.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

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
Expand Down Expand Up @@ -785,3 +785,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)
47 changes: 47 additions & 0 deletions numpy/testing/_private/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

"""
import collections.abc
import warnings

from .utils import SkipTest, assert_warns, HAS_REFCOUNT

Expand All @@ -23,6 +24,10 @@

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
Expand Down Expand Up @@ -52,12 +57,19 @@ def test_big(self):
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
Expand All @@ -84,13 +96,20 @@ def func_with_test_in_name(arg1, arg2):
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
return set_test

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
Expand Down Expand Up @@ -123,6 +142,10 @@ def skip_decorator(f):
# 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()
Expand Down Expand Up @@ -167,6 +190,10 @@ def skipper_gen(*args, **kwargs):

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
Expand Down Expand Up @@ -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'

Expand All @@ -221,6 +252,10 @@ def knownfailer(*args, **kwargs):

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
Expand Down Expand Up @@ -249,6 +284,10 @@ def deprecate_decorator(f):
# 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):
Expand All @@ -267,6 +306,10 @@ def _deprecated_imp(*args, **kwargs):

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
Expand All @@ -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")
Loading