summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2023-01-18 17:04:13 -0700
committerCharles Harris <charlesr.harris@gmail.com>2023-01-19 14:35:44 -0700
commitf75bb0edb0e6eec2564de4bf798242984860a19b (patch)
tree147d9a0804a8d0afb8d409d8f0595b688be3f5f6
parentb2badd70786145eb21cec02109b23e6520c6ffea (diff)
downloadnumpy-f75bb0edb0e6eec2564de4bf798242984860a19b.tar.gz
MAINT: Remove all nose testing support.
NumPy switched to using pytest in 2018 and nose has been unmaintained for many years. We have kept NumPy's nose support to avoid breaking downstream projects who might have been using it and not yet switched to pytest or some other testing framework. With the arrival of Python 3.12, unpatched nose will raise an error. It it time to move on. Decorators removed - raises - slow - setastest - skipif - knownfailif - deprecated - parametrize - _needs_refcount These are not to be confused with pytest versions with similar names, e.g., pytest.mark.slow, pytest.mark.skipif, pytest.mark.parametrize. Functions removed - Tester - import_nose - run_module_suite
-rw-r--r--doc/release/upcoming_changes/23041.expired.rst27
-rw-r--r--numpy/__init__.py12
-rw-r--r--numpy/_pyinstaller/hook-numpy.py1
-rw-r--r--numpy/core/_add_newdocs.py1
-rw-r--r--numpy/core/tests/test_deprecations.py212
-rw-r--r--numpy/testing/__init__.py7
-rw-r--r--numpy/testing/__init__.pyi6
-rw-r--r--numpy/testing/_private/decorators.py331
-rw-r--r--numpy/testing/_private/noseclasses.py364
-rw-r--r--numpy/testing/_private/nosetester.py545
-rw-r--r--numpy/testing/_private/parameterized.py432
-rw-r--r--numpy/testing/_private/utils.py61
-rw-r--r--numpy/testing/tests/test_doctesting.py57
-rw-r--r--numpy/testing/tests/test_utils.py37
-rw-r--r--numpy/tests/test_public_api.py3
-rw-r--r--numpy/typing/tests/data/reveal/testing.pyi2
16 files changed, 36 insertions, 2062 deletions
diff --git a/doc/release/upcoming_changes/23041.expired.rst b/doc/release/upcoming_changes/23041.expired.rst
new file mode 100644
index 000000000..6270083f0
--- /dev/null
+++ b/doc/release/upcoming_changes/23041.expired.rst
@@ -0,0 +1,27 @@
+Nose suppport has been removed
+------------------------------
+NumPy switched to using pytest in 2018 and nose has been unmaintained for many
+years. We have kept NumPy's nose support to avoid breaking downstream projects
+who might have been using it and not yet switched to pytest or some other
+testing framework. With the arrival of Python 3.12, unpatched nose will raise
+an error. It is time to move on.
+
+Decorators removed
+^^^^^^^^^^^^^^^^^^
+- raises
+- slow
+- setastest
+- skipif
+- knownfailif
+- deprecated
+- parametrize
+- _needs_refcount
+
+These are not to be confused with pytest versions with similar names, e.g.,
+pytest.mark.slow, pytest.mark.skipif, pytest.mark.parametrize.
+
+Functions removed
+^^^^^^^^^^^^^^^^^
+- Tester
+- import_nose
+- run_module_suite
diff --git a/numpy/__init__.py b/numpy/__init__.py
index ea2b98163..052ba7327 100644
--- a/numpy/__init__.py
+++ b/numpy/__init__.py
@@ -307,24 +307,18 @@ else:
if attr in __former_attrs__:
raise AttributeError(__former_attrs__[attr])
- # Importing Tester requires importing all of UnitTest which is not a
- # cheap import Since it is mainly used in test suits, we lazy import it
- # here to save on the order of 10 ms of import time for most users
- #
- # The previous way Tester was imported also had a side effect of adding
- # the full `numpy.testing` namespace
if attr == 'testing':
import numpy.testing as testing
return testing
elif attr == 'Tester':
- from .testing import Tester
- return Tester
+ "Removed in NumPy 1.25.0"
+ raise RuntimeError("Tester was removed in NumPy 1.25.")
raise AttributeError("module {!r} has no attribute "
"{!r}".format(__name__, attr))
def __dir__():
- public_symbols = globals().keys() | {'Tester', 'testing'}
+ public_symbols = globals().keys() | {'testing'}
public_symbols -= {
"core", "matrixlib",
# These were moved in 1.25 and may be deprecated eventually:
diff --git a/numpy/_pyinstaller/hook-numpy.py b/numpy/_pyinstaller/hook-numpy.py
index 69992bdeb..c0d018efc 100644
--- a/numpy/_pyinstaller/hook-numpy.py
+++ b/numpy/_pyinstaller/hook-numpy.py
@@ -29,7 +29,6 @@ hiddenimports = ['numpy.core._dtype_ctypes']
excludedimports = [
"scipy",
"pytest",
- "nose",
"f2py",
"setuptools",
"numpy.f2py",
diff --git a/numpy/core/_add_newdocs.py b/numpy/core/_add_newdocs.py
index 3bbc3c5ed..37457c766 100644
--- a/numpy/core/_add_newdocs.py
+++ b/numpy/core/_add_newdocs.py
@@ -11,6 +11,7 @@ NOTE: Many of the methods of ndarray have corresponding functions.
from numpy.core.function_base import add_newdoc
from numpy.core.overrides import array_function_like_doc
+import numpy.core._multiarray_tests
###############################################################################
#
diff --git a/numpy/core/tests/test_deprecations.py b/numpy/core/tests/test_deprecations.py
index 83777cc9c..e1a1acd01 100644
--- a/numpy/core/tests/test_deprecations.py
+++ b/numpy/core/tests/test_deprecations.py
@@ -679,218 +679,6 @@ class TestDeprecatedUnpickleObjectScalar(_DeprecationTestCase):
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)
-
class TestSingleElementSignature(_DeprecationTestCase):
# Deprecated 2021-04-01, NumPy 1.21
diff --git a/numpy/testing/__init__.py b/numpy/testing/__init__.py
index 9e3355ef2..8a34221e4 100644
--- a/numpy/testing/__init__.py
+++ b/numpy/testing/__init__.py
@@ -10,14 +10,11 @@ from unittest import TestCase
from . import _private
from ._private.utils import *
from ._private.utils import (_assert_valid_refcount, _gen_alignment_data)
-from ._private import extbuild, decorators as dec
-from ._private.nosetester import (
- run_module_suite, NoseTester as Tester
- )
+from ._private import extbuild
from . import overrides
__all__ = (
- _private.utils.__all__ + ['TestCase', 'run_module_suite', 'overrides']
+ _private.utils.__all__ + ['TestCase', 'overrides']
)
from numpy._pytesttester import PytestTester
diff --git a/numpy/testing/__init__.pyi b/numpy/testing/__init__.pyi
index a981d6113..d65860ccb 100644
--- a/numpy/testing/__init__.pyi
+++ b/numpy/testing/__init__.pyi
@@ -18,7 +18,6 @@ from numpy.testing._private.utils import (
jiffies as jiffies,
memusage as memusage,
print_assert_equal as print_assert_equal,
- raises as raises,
rundocs as rundocs,
runstring as runstring,
verbose as verbose,
@@ -49,8 +48,3 @@ from numpy.testing._private.utils import (
__all__: list[str]
__path__: list[str]
test: PytestTester
-
-def run_module_suite(
- file_to_run: None | str = ...,
- argv: None | list[str] = ...,
-) -> None: ...
diff --git a/numpy/testing/_private/decorators.py b/numpy/testing/_private/decorators.py
deleted file mode 100644
index cb49d9a73..000000000
--- a/numpy/testing/_private/decorators.py
+++ /dev/null
@@ -1,331 +0,0 @@
-"""
-Decorators for labeling and modifying behavior of test objects.
-
-Decorators that merely return a modified version of the original
-function object are straightforward. Decorators that return a new
-function object need to use
-::
-
- nose.tools.make_decorator(original_function)(decorator)
-
-in returning the decorator, in order to preserve meta-data such as
-function name, setup and teardown functions and so on - see
-``nose.tools`` for more information.
-
-"""
-import collections.abc
-import warnings
-
-from .utils import SkipTest, assert_warns, HAS_REFCOUNT
-
-__all__ = ['slow', 'setastest', 'skipif', 'knownfailureif', 'deprecated',
- 'parametrize', '_needs_refcount',]
-
-
-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
- hardware-dependent, but in general any individual test that requires more
- than a second or two should be labeled as slow (the whole suite consists of
- thousands of tests, so even a second is significant).
-
- Parameters
- ----------
- t : callable
- The test to label as slow.
-
- Returns
- -------
- t : callable
- The decorated test `t`.
-
- Examples
- --------
- The `numpy.testing` module includes ``import decorators as dec``.
- A test can be decorated as slow like this::
-
- from numpy.testing import *
-
- @dec.slow
- 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
- ----------
- tf : bool
- If True, specifies that the decorated callable is a test.
- If False, specifies that the decorated callable is not a test.
- Default is True.
-
- Notes
- -----
- This decorator can't use the nose namespace, because it can be
- called from a non-test module. See also ``istest`` and ``nottest`` in
- ``nose.tools``.
-
- Examples
- --------
- `setastest` can be used in the following way::
-
- from numpy.testing import dec
-
- @dec.setastest(False)
- 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
- make the decision. This is useful for tests that may require costly
- imports, to delay the cost until the test suite is actually executed.
-
- Parameters
- ----------
- skip_condition : bool or callable
- Flag to determine whether to skip the decorated test.
- msg : str, optional
- Message to give on raising a SkipTest exception. Default is None.
-
- Returns
- -------
- decorator : function
- Decorator which, when applied to a function, causes SkipTest
- to be raised when `skip_condition` is True, and the function
- to be called normally otherwise.
-
- Notes
- -----
- The decorator itself is decorated with the ``nose.tools.make_decorator``
- function in order to transmit function name, and various other metadata.
-
- """
-
- def skip_decorator(f):
- # Local import to avoid a hard nose dependency and only incur the
- # 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()
- else:
- skip_val = lambda: skip_condition
-
- def get_msg(func,msg=None):
- """Skip message with information about function being skipped."""
- if msg is None:
- out = 'Test skipped due to test condition'
- else:
- out = msg
-
- return f'Skipping test: {func.__name__}: {out}'
-
- # We need to define *two* skippers because Python doesn't allow both
- # return with value and yield inside the same function.
- def skipper_func(*args, **kwargs):
- """Skipper for normal test functions."""
- if skip_val():
- raise SkipTest(get_msg(f, msg))
- else:
- return f(*args, **kwargs)
-
- def skipper_gen(*args, **kwargs):
- """Skipper for test generators."""
- if skip_val():
- raise SkipTest(get_msg(f, msg))
- else:
- yield from f(*args, **kwargs)
-
- # Choose the right skipper to use when building the actual decorator.
- if nose.util.isgenerator(f):
- skipper = skipper_gen
- else:
- skipper = skipper_func
-
- return nose.tools.make_decorator(f)(skipper)
-
- return skip_decorator
-
-
-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
- make the decision. This is useful for tests that may require costly
- imports, to delay the cost until the test suite is actually executed.
-
- Parameters
- ----------
- fail_condition : bool or callable
- Flag to determine whether to mark the decorated test as a known
- failure (if True) or not (if False).
- msg : str, optional
- Message to give on raising a KnownFailureException exception.
- Default is None.
-
- Returns
- -------
- decorator : function
- Decorator, which, when applied to a function, causes
- KnownFailureException to be raised when `fail_condition` is True,
- and the function to be called normally otherwise.
-
- Notes
- -----
- The decorator itself is decorated with the ``nose.tools.make_decorator``
- 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'
-
- # Allow for both boolean or callable known failure conditions.
- if isinstance(fail_condition, collections.abc.Callable):
- fail_val = lambda: fail_condition()
- else:
- fail_val = lambda: fail_condition
-
- def knownfail_decorator(f):
- # Local import to avoid a hard nose dependency and only incur the
- # import time overhead at actual test-time.
- import nose
- from .noseclasses import KnownFailureException
-
- def knownfailer(*args, **kwargs):
- if fail_val():
- raise KnownFailureException(msg)
- else:
- return f(*args, **kwargs)
- return nose.tools.make_decorator(f)(knownfailer)
-
- return knownfail_decorator
-
-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
- printing them during the test suite run, while checking that the test
- actually raises a DeprecationWarning.
-
- Parameters
- ----------
- conditional : bool or callable, optional
- Flag to determine whether to mark test as deprecated or not. If the
- condition is a callable, it is used at runtime to dynamically make the
- decision. Default is True.
-
- Returns
- -------
- decorator : function
- The `deprecated` decorator itself.
-
- Notes
- -----
- .. versionadded:: 1.4.0
-
- """
- def deprecate_decorator(f):
- # Local import to avoid a hard nose dependency and only incur the
- # 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):
- f(*args, **kwargs)
-
- if isinstance(conditional, collections.abc.Callable):
- cond = conditional()
- else:
- cond = conditional
- if cond:
- return nose.tools.make_decorator(f)(_deprecated_imp)
- else:
- return f
- return deprecate_decorator
-
-
-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
- the doc_func parameter of the base class. It does not support variable
- substitution by name, nor does it support nesting or classes. See the
- pytest documentation for usage.
-
- .. versionadded:: 1.14.0
-
- """
- 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/_private/noseclasses.py b/numpy/testing/_private/noseclasses.py
deleted file mode 100644
index 48fa4dc1f..000000000
--- a/numpy/testing/_private/noseclasses.py
+++ /dev/null
@@ -1,364 +0,0 @@
-# These classes implement a doctest runner plugin for nose, a "known failure"
-# error class, and a customized TestProgram for NumPy.
-
-# Because this module imports nose directly, it should not
-# be used except by nosetester.py to avoid a general NumPy
-# dependency on nose.
-import os
-import sys
-import doctest
-import inspect
-
-import numpy
-import nose
-from nose.plugins import doctests as npd
-from nose.plugins.errorclass import ErrorClass, ErrorClassPlugin
-from nose.plugins.base import Plugin
-from nose.util import src
-from .nosetester import get_package_name
-from .utils import KnownFailureException, KnownFailureTest
-
-
-# Some of the classes in this module begin with 'Numpy' to clearly distinguish
-# them from the plethora of very similar names from nose/unittest/doctest
-
-#-----------------------------------------------------------------------------
-# Modified version of the one in the stdlib, that fixes a python bug (doctests
-# not found in extension modules, https://bugs.python.org/issue3158)
-class NumpyDocTestFinder(doctest.DocTestFinder):
-
- def _from_module(self, module, object):
- """
- Return true if the given object is defined in the given
- module.
- """
- if module is None:
- return True
- elif inspect.isfunction(object):
- return module.__dict__ is object.__globals__
- elif inspect.isbuiltin(object):
- return module.__name__ == object.__module__
- elif inspect.isclass(object):
- return module.__name__ == object.__module__
- elif inspect.ismethod(object):
- # This one may be a bug in cython that fails to correctly set the
- # __module__ attribute of methods, but since the same error is easy
- # to make by extension code writers, having this safety in place
- # isn't such a bad idea
- return module.__name__ == object.__self__.__class__.__module__
- elif inspect.getmodule(object) is not None:
- return module is inspect.getmodule(object)
- elif hasattr(object, '__module__'):
- return module.__name__ == object.__module__
- elif isinstance(object, property):
- return True # [XX] no way not be sure.
- else:
- raise ValueError("object must be a class or function")
-
- def _find(self, tests, obj, name, module, source_lines, globs, seen):
- """
- Find tests for the given object and any contained objects, and
- add them to `tests`.
- """
-
- doctest.DocTestFinder._find(self, tests, obj, name, module,
- source_lines, globs, seen)
-
- # Below we re-run pieces of the above method with manual modifications,
- # because the original code is buggy and fails to correctly identify
- # doctests in extension modules.
-
- # Local shorthands
- from inspect import (
- isroutine, isclass, ismodule, isfunction, ismethod
- )
-
- # Look for tests in a module's contained objects.
- if ismodule(obj) and self._recurse:
- for valname, val in obj.__dict__.items():
- valname1 = f'{name}.{valname}'
- if ( (isroutine(val) or isclass(val))
- and self._from_module(module, val)):
-
- self._find(tests, val, valname1, module, source_lines,
- globs, seen)
-
- # Look for tests in a class's contained objects.
- if isclass(obj) and self._recurse:
- for valname, val in obj.__dict__.items():
- # Special handling for staticmethod/classmethod.
- if isinstance(val, staticmethod):
- val = getattr(obj, valname)
- if isinstance(val, classmethod):
- val = getattr(obj, valname).__func__
-
- # Recurse to methods, properties, and nested classes.
- if ((isfunction(val) or isclass(val) or
- ismethod(val) or isinstance(val, property)) and
- self._from_module(module, val)):
- valname = f'{name}.{valname}'
- self._find(tests, val, valname, module, source_lines,
- globs, seen)
-
-
-# second-chance checker; if the default comparison doesn't
-# pass, then see if the expected output string contains flags that
-# tell us to ignore the output
-class NumpyOutputChecker(doctest.OutputChecker):
- def check_output(self, want, got, optionflags):
- ret = doctest.OutputChecker.check_output(self, want, got,
- optionflags)
- if not ret:
- if "#random" in want:
- return True
-
- # it would be useful to normalize endianness so that
- # bigendian machines don't fail all the tests (and there are
- # actually some bigendian examples in the doctests). Let's try
- # making them all little endian
- got = got.replace("'>", "'<")
- want = want.replace("'>", "'<")
-
- # try to normalize out 32 and 64 bit default int sizes
- for sz in [4, 8]:
- got = got.replace("'<i%d'" % sz, "int")
- want = want.replace("'<i%d'" % sz, "int")
-
- ret = doctest.OutputChecker.check_output(self, want,
- got, optionflags)
-
- return ret
-
-
-# Subclass nose.plugins.doctests.DocTestCase to work around a bug in
-# its constructor that blocks non-default arguments from being passed
-# down into doctest.DocTestCase
-class NumpyDocTestCase(npd.DocTestCase):
- def __init__(self, test, optionflags=0, setUp=None, tearDown=None,
- checker=None, obj=None, result_var='_'):
- self._result_var = result_var
- self._nose_obj = obj
- doctest.DocTestCase.__init__(self, test,
- optionflags=optionflags,
- setUp=setUp, tearDown=tearDown,
- checker=checker)
-
-
-print_state = numpy.get_printoptions()
-
-class NumpyDoctest(npd.Doctest):
- name = 'numpydoctest' # call nosetests with --with-numpydoctest
- score = 1000 # load late, after doctest builtin
-
- # always use whitespace and ellipsis options for doctests
- doctest_optflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
-
- # files that should be ignored for doctests
- doctest_ignore = ['generate_numpy_api.py',
- 'setup.py']
-
- # Custom classes; class variables to allow subclassing
- doctest_case_class = NumpyDocTestCase
- out_check_class = NumpyOutputChecker
- test_finder_class = NumpyDocTestFinder
-
- # Don't use the standard doctest option handler; hard-code the option values
- def options(self, parser, env=os.environ):
- Plugin.options(self, parser, env)
- # Test doctests in 'test' files / directories. Standard plugin default
- # is False
- self.doctest_tests = True
- # Variable name; if defined, doctest results stored in this variable in
- # the top-level namespace. None is the standard default
- self.doctest_result_var = None
-
- def configure(self, options, config):
- # parent method sets enabled flag from command line --with-numpydoctest
- Plugin.configure(self, options, config)
- self.finder = self.test_finder_class()
- self.parser = doctest.DocTestParser()
- if self.enabled:
- # Pull standard doctest out of plugin list; there's no reason to run
- # both. In practice the Unplugger plugin above would cover us when
- # run from a standard numpy.test() call; this is just in case
- # someone wants to run our plugin outside the numpy.test() machinery
- config.plugins.plugins = [p for p in config.plugins.plugins
- if p.name != 'doctest']
-
- def set_test_context(self, test):
- """ Configure `test` object to set test context
-
- We set the numpy / scipy standard doctest namespace
-
- Parameters
- ----------
- test : test object
- with ``globs`` dictionary defining namespace
-
- Returns
- -------
- None
-
- Notes
- -----
- `test` object modified in place
- """
- # set the namespace for tests
- pkg_name = get_package_name(os.path.dirname(test.filename))
-
- # Each doctest should execute in an environment equivalent to
- # starting Python and executing "import numpy as np", and,
- # for SciPy packages, an additional import of the local
- # package (so that scipy.linalg.basic.py's doctests have an
- # implicit "from scipy import linalg" as well).
- #
- # Note: __file__ allows the doctest in NoseTester to run
- # without producing an error
- test.globs = {'__builtins__':__builtins__,
- '__file__':'__main__',
- '__name__':'__main__',
- 'np':numpy}
- # add appropriate scipy import for SciPy tests
- if 'scipy' in pkg_name:
- p = pkg_name.split('.')
- p2 = p[-1]
- test.globs[p2] = __import__(pkg_name, test.globs, {}, [p2])
-
- # Override test loading to customize test context (with set_test_context
- # method), set standard docstring options, and install our own test output
- # checker
- def loadTestsFromModule(self, module):
- if not self.matches(module.__name__):
- npd.log.debug("Doctest doesn't want module %s", module)
- return
- try:
- tests = self.finder.find(module)
- except AttributeError:
- # nose allows module.__test__ = False; doctest does not and
- # throws AttributeError
- return
- if not tests:
- return
- tests.sort()
- module_file = src(module.__file__)
- for test in tests:
- if not test.examples:
- continue
- if not test.filename:
- test.filename = module_file
- # Set test namespace; test altered in place
- self.set_test_context(test)
- yield self.doctest_case_class(test,
- optionflags=self.doctest_optflags,
- checker=self.out_check_class(),
- result_var=self.doctest_result_var)
-
- # Add an afterContext method to nose.plugins.doctests.Doctest in order
- # to restore print options to the original state after each doctest
- def afterContext(self):
- numpy.set_printoptions(**print_state)
-
- # Ignore NumPy-specific build files that shouldn't be searched for tests
- def wantFile(self, file):
- bn = os.path.basename(file)
- if bn in self.doctest_ignore:
- return False
- return npd.Doctest.wantFile(self, file)
-
-
-class Unplugger:
- """ Nose plugin to remove named plugin late in loading
-
- By default it removes the "doctest" plugin.
- """
- name = 'unplugger'
- enabled = True # always enabled
- score = 4000 # load late in order to be after builtins
-
- def __init__(self, to_unplug='doctest'):
- self.to_unplug = to_unplug
-
- def options(self, parser, env):
- pass
-
- def configure(self, options, config):
- # Pull named plugin out of plugins list
- config.plugins.plugins = [p for p in config.plugins.plugins
- if p.name != self.to_unplug]
-
-
-class KnownFailurePlugin(ErrorClassPlugin):
- '''Plugin that installs a KNOWNFAIL error class for the
- KnownFailureClass exception. When KnownFailure is raised,
- the exception will be logged in the knownfail attribute of the
- result, 'K' or 'KNOWNFAIL' (verbose) will be output, and the
- exception will not be counted as an error or failure.'''
- enabled = True
- knownfail = ErrorClass(KnownFailureException,
- label='KNOWNFAIL',
- isfailure=False)
-
- def options(self, parser, env=os.environ):
- env_opt = 'NOSE_WITHOUT_KNOWNFAIL'
- parser.add_option('--no-knownfail', action='store_true',
- dest='noKnownFail', default=env.get(env_opt, False),
- help='Disable special handling of KnownFailure '
- 'exceptions')
-
- def configure(self, options, conf):
- if not self.can_configure:
- return
- self.conf = conf
- disable = getattr(options, 'noKnownFail', False)
- if disable:
- self.enabled = False
-
-KnownFailure = KnownFailurePlugin # backwards compat
-
-
-class FPUModeCheckPlugin(Plugin):
- """
- Plugin that checks the FPU mode before and after each test,
- raising failures if the test changed the mode.
- """
-
- def prepareTestCase(self, test):
- from numpy.core._multiarray_tests import get_fpu_mode
-
- def run(result):
- old_mode = get_fpu_mode()
- test.test(result)
- new_mode = get_fpu_mode()
-
- if old_mode != new_mode:
- try:
- raise AssertionError(
- "FPU mode changed from {0:#x} to {1:#x} during the "
- "test".format(old_mode, new_mode))
- except AssertionError:
- result.addFailure(test, sys.exc_info())
-
- return run
-
-
-# Class allows us to save the results of the tests in runTests - see runTests
-# method docstring for details
-class NumpyTestProgram(nose.core.TestProgram):
- def runTests(self):
- """Run Tests. Returns true on success, false on failure, and
- sets self.success to the same value.
-
- Because nose currently discards the test result object, but we need
- to return it to the user, override TestProgram.runTests to retain
- the result
- """
- if self.testRunner is None:
- self.testRunner = nose.core.TextTestRunner(stream=self.config.stream,
- verbosity=self.config.verbosity,
- config=self.config)
- plug_runner = self.config.plugins.prepareTestRunner(self.testRunner)
- if plug_runner is not None:
- self.testRunner = plug_runner
- self.result = self.testRunner.run(self.test)
- self.success = self.result.wasSuccessful()
- return self.success
diff --git a/numpy/testing/_private/nosetester.py b/numpy/testing/_private/nosetester.py
deleted file mode 100644
index bccec8236..000000000
--- a/numpy/testing/_private/nosetester.py
+++ /dev/null
@@ -1,545 +0,0 @@
-"""
-Nose test running.
-
-This module implements ``test()`` and ``bench()`` functions for NumPy modules.
-
-"""
-import os
-import sys
-import warnings
-import numpy as np
-
-from .utils import import_nose, suppress_warnings
-
-
-__all__ = ['get_package_name', 'run_module_suite', 'NoseTester',
- '_numpy_tester', 'get_package_name', 'import_nose',
- 'suppress_warnings']
-
-
-def get_package_name(filepath):
- """
- Given a path where a package is installed, determine its name.
-
- Parameters
- ----------
- filepath : str
- Path to a file. If the determination fails, "numpy" is returned.
-
- Examples
- --------
- >>> np.testing.nosetester.get_package_name('nonsense')
- 'numpy'
-
- """
-
- fullpath = filepath[:]
- pkg_name = []
- while 'site-packages' in filepath or 'dist-packages' in filepath:
- filepath, p2 = os.path.split(filepath)
- if p2 in ('site-packages', 'dist-packages'):
- break
- pkg_name.append(p2)
-
- # if package name determination failed, just default to numpy/scipy
- if not pkg_name:
- if 'scipy' in fullpath:
- return 'scipy'
- else:
- return 'numpy'
-
- # otherwise, reverse to get correct order and return
- pkg_name.reverse()
-
- # don't include the outer egg directory
- if pkg_name[0].endswith('.egg'):
- pkg_name.pop(0)
-
- return '.'.join(pkg_name)
-
-
-def run_module_suite(file_to_run=None, argv=None):
- """
- Run a test module.
-
- Equivalent to calling ``$ nosetests <argv> <file_to_run>`` from
- the command line
-
- Parameters
- ----------
- file_to_run : str, optional
- Path to test module, or None.
- By default, run the module from which this function is called.
- argv : list of strings
- Arguments to be passed to the nose test runner. ``argv[0]`` is
- ignored. All command line arguments accepted by ``nosetests``
- will work. If it is the default value None, sys.argv is used.
-
- .. versionadded:: 1.9.0
-
- Examples
- --------
- Adding the following::
-
- if __name__ == "__main__" :
- run_module_suite(argv=sys.argv)
-
- at the end of a test module will run the tests when that module is
- called in the python interpreter.
-
- Alternatively, calling::
-
- >>> run_module_suite(file_to_run="numpy/tests/test_matlib.py") # doctest: +SKIP
-
- from an interpreter will run all the test routine in 'test_matlib.py'.
- """
- if file_to_run is None:
- f = sys._getframe(1)
- file_to_run = f.f_locals.get('__file__', None)
- if file_to_run is None:
- raise AssertionError
-
- if argv is None:
- argv = sys.argv + [file_to_run]
- else:
- argv = argv + [file_to_run]
-
- nose = import_nose()
- from .noseclasses import KnownFailurePlugin
- nose.run(argv=argv, addplugins=[KnownFailurePlugin()])
-
-
-class NoseTester:
- """
- Nose test runner.
-
- This class is made available as numpy.testing.Tester, and a test function
- is typically added to a package's __init__.py like so::
-
- from numpy.testing import Tester
- test = Tester().test
-
- Calling this test function finds and runs all tests associated with the
- package and all its sub-packages.
-
- Attributes
- ----------
- package_path : str
- Full path to the package to test.
- package_name : str
- Name of the package to test.
-
- Parameters
- ----------
- package : module, str or None, optional
- The package to test. If a string, this should be the full path to
- the package. If None (default), `package` is set to the module from
- which `NoseTester` is initialized.
- raise_warnings : None, str or sequence of warnings, optional
- This specifies which warnings to configure as 'raise' instead
- of being shown once during the test execution. Valid strings are:
-
- - "develop" : equals ``(Warning,)``
- - "release" : equals ``()``, don't raise on any warnings.
-
- Default is "release".
- depth : int, optional
- If `package` is None, then this can be used to initialize from the
- module of the caller of (the caller of (...)) the code that
- initializes `NoseTester`. Default of 0 means the module of the
- immediate caller; higher values are useful for utility routines that
- want to initialize `NoseTester` objects on behalf of other code.
-
- """
- def __init__(self, package=None, raise_warnings="release", depth=0,
- check_fpu_mode=False):
- # Back-compat: 'None' used to mean either "release" or "develop"
- # depending on whether this was a release or develop version of
- # numpy. Those semantics were fine for testing numpy, but not so
- # helpful for downstream projects like scipy that use
- # numpy.testing. (They want to set this based on whether *they* are a
- # release or develop version, not whether numpy is.) So we continue to
- # accept 'None' for back-compat, but it's now just an alias for the
- # default "release".
- if raise_warnings is None:
- raise_warnings = "release"
-
- package_name = None
- if package is None:
- f = sys._getframe(1 + depth)
- package_path = f.f_locals.get('__file__', None)
- if package_path is None:
- raise AssertionError
- package_path = os.path.dirname(package_path)
- package_name = f.f_locals.get('__name__', None)
- elif isinstance(package, type(os)):
- package_path = os.path.dirname(package.__file__)
- package_name = getattr(package, '__name__', None)
- else:
- package_path = str(package)
-
- self.package_path = package_path
-
- # Find the package name under test; this name is used to limit coverage
- # reporting (if enabled).
- if package_name is None:
- package_name = get_package_name(package_path)
- self.package_name = package_name
-
- # Set to "release" in constructor in maintenance branches.
- self.raise_warnings = raise_warnings
-
- # Whether to check for FPU mode changes
- self.check_fpu_mode = check_fpu_mode
-
- def _test_argv(self, label, verbose, extra_argv):
- ''' Generate argv for nosetest command
-
- Parameters
- ----------
- label : {'fast', 'full', '', attribute identifier}, optional
- see ``test`` docstring
- verbose : int, optional
- Verbosity value for test outputs, in the range 1-10. Default is 1.
- extra_argv : list, optional
- List with any extra arguments to pass to nosetests.
-
- Returns
- -------
- argv : list
- command line arguments that will be passed to nose
- '''
- argv = [__file__, self.package_path, '-s']
- if label and label != 'full':
- if not isinstance(label, str):
- raise TypeError('Selection label should be a string')
- if label == 'fast':
- label = 'not slow'
- argv += ['-A', label]
- argv += ['--verbosity', str(verbose)]
-
- # When installing with setuptools, and also in some other cases, the
- # test_*.py files end up marked +x executable. Nose, by default, does
- # not run files marked with +x as they might be scripts. However, in
- # our case nose only looks for test_*.py files under the package
- # directory, which should be safe.
- argv += ['--exe']
-
- if extra_argv:
- argv += extra_argv
- return argv
-
- def _show_system_info(self):
- nose = import_nose()
-
- import numpy
- print(f'NumPy version {numpy.__version__}')
- relaxed_strides = numpy.ones((10, 1), order="C").flags.f_contiguous
- print("NumPy relaxed strides checking option:", relaxed_strides)
- npdir = os.path.dirname(numpy.__file__)
- print(f'NumPy is installed in {npdir}')
-
- if 'scipy' in self.package_name:
- import scipy
- print(f'SciPy version {scipy.__version__}')
- spdir = os.path.dirname(scipy.__file__)
- print(f'SciPy is installed in {spdir}')
-
- pyversion = sys.version.replace('\n', '')
- print(f'Python version {pyversion}')
- print("nose version %d.%d.%d" % nose.__versioninfo__)
-
- def _get_custom_doctester(self):
- """ Return instantiated plugin for doctests
-
- Allows subclassing of this class to override doctester
-
- A return value of None means use the nose builtin doctest plugin
- """
- from .noseclasses import NumpyDoctest
- return NumpyDoctest()
-
- def prepare_test_args(self, label='fast', verbose=1, extra_argv=None,
- doctests=False, coverage=False, timer=False):
- """
- Run tests for module using nose.
-
- This method does the heavy lifting for the `test` method. It takes all
- the same arguments, for details see `test`.
-
- See Also
- --------
- test
-
- """
- # fail with nice error message if nose is not present
- import_nose()
- # compile argv
- argv = self._test_argv(label, verbose, extra_argv)
- # our way of doing coverage
- if coverage:
- argv += [f'--cover-package={self.package_name}', '--with-coverage',
- '--cover-tests', '--cover-erase']
-
- if timer:
- if timer is True:
- argv += ['--with-timer']
- elif isinstance(timer, int):
- argv += ['--with-timer', '--timer-top-n', str(timer)]
-
- # construct list of plugins
- import nose.plugins.builtin
- from nose.plugins import EntryPointPluginManager
- from .noseclasses import (KnownFailurePlugin, Unplugger,
- FPUModeCheckPlugin)
- plugins = [KnownFailurePlugin()]
- plugins += [p() for p in nose.plugins.builtin.plugins]
- if self.check_fpu_mode:
- plugins += [FPUModeCheckPlugin()]
- argv += ["--with-fpumodecheckplugin"]
- try:
- # External plugins (like nose-timer)
- entrypoint_manager = EntryPointPluginManager()
- entrypoint_manager.loadPlugins()
- plugins += [p for p in entrypoint_manager.plugins]
- except ImportError:
- # Relies on pkg_resources, not a hard dependency
- pass
-
- # add doctesting if required
- doctest_argv = '--with-doctest' in argv
- if doctests == False and doctest_argv:
- doctests = True
- plug = self._get_custom_doctester()
- if plug is None:
- # use standard doctesting
- if doctests and not doctest_argv:
- argv += ['--with-doctest']
- else: # custom doctesting
- if doctest_argv: # in fact the unplugger would take care of this
- argv.remove('--with-doctest')
- plugins += [Unplugger('doctest'), plug]
- if doctests:
- argv += ['--with-' + plug.name]
- return argv, plugins
-
- def test(self, label='fast', verbose=1, extra_argv=None,
- doctests=False, coverage=False, raise_warnings=None,
- timer=False):
- """
- Run tests for module using nose.
-
- Parameters
- ----------
- label : {'fast', 'full', '', attribute identifier}, optional
- Identifies the tests to run. This can be a string to pass to
- the nosetests executable with the '-A' option, or one of several
- special values. Special values are:
-
- * 'fast' - the default - which corresponds to the ``nosetests -A``
- option of 'not slow'.
- * 'full' - fast (as above) and slow tests as in the
- 'no -A' option to nosetests - this is the same as ''.
- * None or '' - run all tests.
- * attribute_identifier - string passed directly to nosetests as '-A'.
-
- verbose : int, optional
- Verbosity value for test outputs, in the range 1-10. Default is 1.
- extra_argv : list, optional
- List with any extra arguments to pass to nosetests.
- doctests : bool, optional
- If True, run doctests in module. Default is False.
- coverage : bool, optional
- If True, report coverage of NumPy code. Default is False.
- (This requires the
- `coverage module <https://pypi.org/project/coverage/>`_).
- raise_warnings : None, str or sequence of warnings, optional
- This specifies which warnings to configure as 'raise' instead
- of being shown once during the test execution. Valid strings are:
-
- * "develop" : equals ``(Warning,)``
- * "release" : equals ``()``, do not raise on any warnings.
- timer : bool or int, optional
- Timing of individual tests with ``nose-timer`` (which needs to be
- installed). If True, time tests and report on all of them.
- If an integer (say ``N``), report timing results for ``N`` slowest
- tests.
-
- Returns
- -------
- result : object
- Returns the result of running the tests as a
- ``nose.result.TextTestResult`` object.
-
- Notes
- -----
- Each NumPy module exposes `test` in its namespace to run all tests for it.
- For example, to run all tests for numpy.lib:
-
- >>> np.lib.test() #doctest: +SKIP
-
- Examples
- --------
- >>> result = np.lib.test() #doctest: +SKIP
- Running unit tests for numpy.lib
- ...
- Ran 976 tests in 3.933s
-
- OK
-
- >>> result.errors #doctest: +SKIP
- []
- >>> result.knownfail #doctest: +SKIP
- []
- """
-
- # cap verbosity at 3 because nose becomes *very* verbose beyond that
- verbose = min(verbose, 3)
-
- from . import utils
- utils.verbose = verbose
-
- argv, plugins = self.prepare_test_args(
- label, verbose, extra_argv, doctests, coverage, timer)
-
- if doctests:
- print(f'Running unit tests and doctests for {self.package_name}')
- else:
- print(f'Running unit tests for {self.package_name}')
-
- self._show_system_info()
-
- # reset doctest state on every run
- import doctest
- doctest.master = None
-
- if raise_warnings is None:
- raise_warnings = self.raise_warnings
-
- _warn_opts = dict(develop=(Warning,),
- release=())
- if isinstance(raise_warnings, str):
- raise_warnings = _warn_opts[raise_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()
- # Set all warnings to 'warn', this is because the default 'once'
- # has the bad property of possibly shadowing later warnings.
- warnings.filterwarnings('always')
- # Force the requested warnings to raise
- for warningtype in raise_warnings:
- warnings.filterwarnings('error', category=warningtype)
- # Filter out annoying import messages.
- 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.
- 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=r"nose\.")
-
- from .noseclasses import NumpyTestProgram
-
- t = NumpyTestProgram(argv=argv, exit=False, plugins=plugins)
-
- return t.result
-
- def bench(self, label='fast', verbose=1, extra_argv=None):
- """
- Run benchmarks for module using nose.
-
- Parameters
- ----------
- label : {'fast', 'full', '', attribute identifier}, optional
- Identifies the benchmarks to run. This can be a string to pass to
- the nosetests executable with the '-A' option, or one of several
- special values. Special values are:
-
- * 'fast' - the default - which corresponds to the ``nosetests -A``
- option of 'not slow'.
- * 'full' - fast (as above) and slow benchmarks as in the
- 'no -A' option to nosetests - this is the same as ''.
- * None or '' - run all tests.
- * attribute_identifier - string passed directly to nosetests as '-A'.
-
- verbose : int, optional
- Verbosity value for benchmark outputs, in the range 1-10. Default is 1.
- extra_argv : list, optional
- List with any extra arguments to pass to nosetests.
-
- Returns
- -------
- success : bool
- Returns True if running the benchmarks works, False if an error
- occurred.
-
- Notes
- -----
- Benchmarks are like tests, but have names starting with "bench" instead
- of "test", and can be found under the "benchmarks" sub-directory of the
- module.
-
- Each NumPy module exposes `bench` in its namespace to run all benchmarks
- for it.
-
- Examples
- --------
- >>> success = np.lib.bench() #doctest: +SKIP
- Running benchmarks for numpy.lib
- ...
- using 562341 items:
- unique:
- 0.11
- unique1d:
- 0.11
- ratio: 1.0
- nUnique: 56230 == 56230
- ...
- OK
-
- >>> success #doctest: +SKIP
- True
-
- """
-
- print(f'Running benchmarks for {self.package_name}')
- self._show_system_info()
-
- argv = self._test_argv(label, verbose, extra_argv)
- argv += ['--match', r'(?:^|[\\b_\\.%s-])[Bb]ench' % os.sep]
-
- # import nose or make informative error
- nose = import_nose()
-
- # get plugin to disable doctests
- from .noseclasses import Unplugger
- add_plugins = [Unplugger('doctest')]
-
- return nose.run(argv=argv, addplugins=add_plugins)
-
-
-def _numpy_tester():
- if hasattr(np, "__version__") and ".dev0" in np.__version__:
- mode = "develop"
- else:
- mode = "release"
- return NoseTester(raise_warnings=mode, depth=1,
- check_fpu_mode=True)
diff --git a/numpy/testing/_private/parameterized.py b/numpy/testing/_private/parameterized.py
deleted file mode 100644
index 3a29a1811..000000000
--- a/numpy/testing/_private/parameterized.py
+++ /dev/null
@@ -1,432 +0,0 @@
-"""
-tl;dr: all code is licensed under simplified BSD, unless stated otherwise.
-
-Unless stated otherwise in the source files, all code is copyright 2010 David
-Wolever <david@wolever.net>. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-EVENT SHALL <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-The views and conclusions contained in the software and documentation are those
-of the authors and should not be interpreted as representing official policies,
-either expressed or implied, of David Wolever.
-
-"""
-import re
-import inspect
-import warnings
-from functools import wraps
-from types import MethodType
-from collections import namedtuple
-
-from unittest import TestCase
-
-_param = namedtuple("param", "args kwargs")
-
-class param(_param):
- """ Represents a single parameter to a test case.
-
- For example::
-
- >>> p = param("foo", bar=16)
- >>> p
- param("foo", bar=16)
- >>> p.args
- ('foo', )
- >>> p.kwargs
- {'bar': 16}
-
- Intended to be used as an argument to ``@parameterized``::
-
- @parameterized([
- param("foo", bar=16),
- ])
- def test_stuff(foo, bar=16):
- pass
- """
-
- def __new__(cls, *args , **kwargs):
- return _param.__new__(cls, args, kwargs)
-
- @classmethod
- def explicit(cls, args=None, kwargs=None):
- """ Creates a ``param`` by explicitly specifying ``args`` and
- ``kwargs``::
-
- >>> param.explicit([1,2,3])
- param(*(1, 2, 3))
- >>> param.explicit(kwargs={"foo": 42})
- param(*(), **{"foo": "42"})
- """
- args = args or ()
- kwargs = kwargs or {}
- return cls(*args, **kwargs)
-
- @classmethod
- def from_decorator(cls, args):
- """ Returns an instance of ``param()`` for ``@parameterized`` argument
- ``args``::
-
- >>> param.from_decorator((42, ))
- param(args=(42, ), kwargs={})
- >>> param.from_decorator("foo")
- param(args=("foo", ), kwargs={})
- """
- if isinstance(args, param):
- return args
- elif isinstance(args, (str,)):
- args = (args, )
- try:
- return cls(*args)
- except TypeError as e:
- if "after * must be" not in str(e):
- raise
- raise TypeError(
- "Parameters must be tuples, but %r is not (hint: use '(%r, )')"
- %(args, args),
- )
-
- def __repr__(self):
- return "param(*%r, **%r)" %self
-
-
-def parameterized_argument_value_pairs(func, p):
- """Return tuples of parameterized arguments and their values.
-
- This is useful if you are writing your own doc_func
- function and need to know the values for each parameter name::
-
- >>> def func(a, foo=None, bar=42, **kwargs): pass
- >>> p = param(1, foo=7, extra=99)
- >>> parameterized_argument_value_pairs(func, p)
- [("a", 1), ("foo", 7), ("bar", 42), ("**kwargs", {"extra": 99})]
-
- If the function's first argument is named ``self`` then it will be
- ignored::
-
- >>> def func(self, a): pass
- >>> p = param(1)
- >>> parameterized_argument_value_pairs(func, p)
- [("a", 1)]
-
- Additionally, empty ``*args`` or ``**kwargs`` will be ignored::
-
- >>> def func(foo, *args): pass
- >>> p = param(1)
- >>> parameterized_argument_value_pairs(func, p)
- [("foo", 1)]
- >>> p = param(1, 16)
- >>> parameterized_argument_value_pairs(func, p)
- [("foo", 1), ("*args", (16, ))]
- """
- argspec = inspect.getargspec(func)
- arg_offset = 1 if argspec.args[:1] == ["self"] else 0
-
- named_args = argspec.args[arg_offset:]
-
- result = list(zip(named_args, p.args))
- named_args = argspec.args[len(result) + arg_offset:]
- varargs = p.args[len(result):]
-
- result.extend([
- (name, p.kwargs.get(name, default))
- for (name, default)
- in zip(named_args, argspec.defaults or [])
- ])
-
- seen_arg_names = {n for (n, _) in result}
- keywords = dict(sorted([
- (name, p.kwargs[name])
- for name in p.kwargs
- if name not in seen_arg_names
- ]))
-
- if varargs:
- result.append(("*%s" %(argspec.varargs, ), tuple(varargs)))
-
- if keywords:
- result.append(("**%s" %(argspec.keywords, ), keywords))
-
- return result
-
-def short_repr(x, n=64):
- """ A shortened repr of ``x`` which is guaranteed to be ``unicode``::
-
- >>> short_repr("foo")
- u"foo"
- >>> short_repr("123456789", n=4)
- u"12...89"
- """
-
- x_repr = repr(x)
- if isinstance(x_repr, bytes):
- try:
- x_repr = str(x_repr, "utf-8")
- except UnicodeDecodeError:
- x_repr = str(x_repr, "latin1")
- if len(x_repr) > n:
- x_repr = x_repr[:n//2] + "..." + x_repr[len(x_repr) - n//2:]
- return x_repr
-
-def default_doc_func(func, num, p):
- if func.__doc__ is None:
- return None
-
- all_args_with_values = parameterized_argument_value_pairs(func, p)
-
- # Assumes that the function passed is a bound method.
- descs = [f'{n}={short_repr(v)}' for n, v in all_args_with_values]
-
- # The documentation might be a multiline string, so split it
- # and just work with the first string, ignoring the period
- # at the end if there is one.
- first, nl, rest = func.__doc__.lstrip().partition("\n")
- suffix = ""
- if first.endswith("."):
- suffix = "."
- first = first[:-1]
- args = "%s[with %s]" %(len(first) and " " or "", ", ".join(descs))
- return "".join([first.rstrip(), args, suffix, nl, rest])
-
-def default_name_func(func, num, p):
- base_name = func.__name__
- name_suffix = "_%s" %(num, )
- if len(p.args) > 0 and isinstance(p.args[0], (str,)):
- name_suffix += "_" + parameterized.to_safe_name(p.args[0])
- return base_name + name_suffix
-
-
-# force nose for numpy purposes.
-_test_runner_override = 'nose'
-_test_runner_guess = False
-_test_runners = set(["unittest", "unittest2", "nose", "nose2", "pytest"])
-_test_runner_aliases = {
- "_pytest": "pytest",
-}
-
-def set_test_runner(name):
- global _test_runner_override
- if name not in _test_runners:
- raise TypeError(
- "Invalid test runner: %r (must be one of: %s)"
- %(name, ", ".join(_test_runners)),
- )
- _test_runner_override = name
-
-def detect_runner():
- """ Guess which test runner we're using by traversing the stack and looking
- for the first matching module. This *should* be reasonably safe, as
- it's done during test discovery where the test runner should be the
- stack frame immediately outside. """
- if _test_runner_override is not None:
- return _test_runner_override
- global _test_runner_guess
- if _test_runner_guess is False:
- stack = inspect.stack()
- for record in reversed(stack):
- frame = record[0]
- module = frame.f_globals.get("__name__").partition(".")[0]
- if module in _test_runner_aliases:
- module = _test_runner_aliases[module]
- if module in _test_runners:
- _test_runner_guess = module
- break
- else:
- _test_runner_guess = None
- return _test_runner_guess
-
-class parameterized:
- """ Parameterize a test case::
-
- class TestInt:
- @parameterized([
- ("A", 10),
- ("F", 15),
- param("10", 42, base=42)
- ])
- def test_int(self, input, expected, base=16):
- actual = int(input, base=base)
- assert_equal(actual, expected)
-
- @parameterized([
- (2, 3, 5)
- (3, 5, 8),
- ])
- def test_add(a, b, expected):
- assert_equal(a + b, expected)
- """
-
- def __init__(self, input, doc_func=None):
- self.get_input = self.input_as_callable(input)
- self.doc_func = doc_func or default_doc_func
-
- def __call__(self, test_func):
- self.assert_not_in_testcase_subclass()
-
- @wraps(test_func)
- def wrapper(test_self=None):
- test_cls = test_self and type(test_self)
-
- original_doc = wrapper.__doc__
- for num, args in enumerate(wrapper.parameterized_input):
- p = param.from_decorator(args)
- unbound_func, nose_tuple = self.param_as_nose_tuple(test_self, test_func, num, p)
- try:
- wrapper.__doc__ = nose_tuple[0].__doc__
- # Nose uses `getattr(instance, test_func.__name__)` to get
- # a method bound to the test instance (as opposed to a
- # method bound to the instance of the class created when
- # tests were being enumerated). Set a value here to make
- # sure nose can get the correct test method.
- if test_self is not None:
- setattr(test_cls, test_func.__name__, unbound_func)
- yield nose_tuple
- finally:
- if test_self is not None:
- delattr(test_cls, test_func.__name__)
- wrapper.__doc__ = original_doc
- wrapper.parameterized_input = self.get_input()
- wrapper.parameterized_func = test_func
- test_func.__name__ = "_parameterized_original_%s" %(test_func.__name__, )
- return wrapper
-
- def param_as_nose_tuple(self, test_self, func, num, p):
- nose_func = wraps(func)(lambda *args: func(*args[:-1], **args[-1]))
- nose_func.__doc__ = self.doc_func(func, num, p)
- # Track the unbound function because we need to setattr the unbound
- # function onto the class for nose to work (see comments above), and
- # Python 3 doesn't let us pull the function out of a bound method.
- unbound_func = nose_func
- if test_self is not None:
- nose_func = MethodType(nose_func, test_self)
- return unbound_func, (nose_func, ) + p.args + (p.kwargs or {}, )
-
- def assert_not_in_testcase_subclass(self):
- parent_classes = self._terrible_magic_get_defining_classes()
- if any(issubclass(cls, TestCase) for cls in parent_classes):
- raise Exception("Warning: '@parameterized' tests won't work "
- "inside subclasses of 'TestCase' - use "
- "'@parameterized.expand' instead.")
-
- def _terrible_magic_get_defining_classes(self):
- """ Returns the list of parent classes of the class currently being defined.
- Will likely only work if called from the ``parameterized`` decorator.
- This function is entirely @brandon_rhodes's fault, as he suggested
- the implementation: http://stackoverflow.com/a/8793684/71522
- """
- stack = inspect.stack()
- if len(stack) <= 4:
- return []
- frame = stack[4]
- code_context = frame[4] and frame[4][0].strip()
- if not (code_context and code_context.startswith("class ")):
- return []
- _, _, parents = code_context.partition("(")
- parents, _, _ = parents.partition(")")
- return eval("[" + parents + "]", frame[0].f_globals, frame[0].f_locals)
-
- @classmethod
- def input_as_callable(cls, input):
- if callable(input):
- return lambda: cls.check_input_values(input())
- input_values = cls.check_input_values(input)
- return lambda: input_values
-
- @classmethod
- def check_input_values(cls, input_values):
- # Explicitly convert non-list inputs to a list so that:
- # 1. A helpful exception will be raised if they aren't iterable, and
- # 2. Generators are unwrapped exactly once (otherwise `nosetests
- # --processes=n` has issues; see:
- # https://github.com/wolever/nose-parameterized/pull/31)
- if not isinstance(input_values, list):
- input_values = list(input_values)
- return [ param.from_decorator(p) for p in input_values ]
-
- @classmethod
- def expand(cls, input, name_func=None, doc_func=None, **legacy):
- """ A "brute force" method of parameterizing test cases. Creates new
- test cases and injects them into the namespace that the wrapped
- function is being defined in. Useful for parameterizing tests in
- subclasses of 'UnitTest', where Nose test generators don't work.
-
- >>> @parameterized.expand([("foo", 1, 2)])
- ... def test_add1(name, input, expected):
- ... actual = add1(input)
- ... assert_equal(actual, expected)
- ...
- >>> locals()
- ... 'test_add1_foo_0': <function ...> ...
- >>>
- """
-
- if "testcase_func_name" in legacy:
- warnings.warn("testcase_func_name= is deprecated; use name_func=",
- DeprecationWarning, stacklevel=2)
- if not name_func:
- name_func = legacy["testcase_func_name"]
-
- if "testcase_func_doc" in legacy:
- warnings.warn("testcase_func_doc= is deprecated; use doc_func=",
- DeprecationWarning, stacklevel=2)
- if not doc_func:
- doc_func = legacy["testcase_func_doc"]
-
- doc_func = doc_func or default_doc_func
- name_func = name_func or default_name_func
-
- def parameterized_expand_wrapper(f, instance=None):
- stack = inspect.stack()
- frame = stack[1]
- frame_locals = frame[0].f_locals
-
- parameters = cls.input_as_callable(input)()
- for num, p in enumerate(parameters):
- name = name_func(f, num, p)
- frame_locals[name] = cls.param_as_standalone_func(p, f, name)
- frame_locals[name].__doc__ = doc_func(f, num, p)
-
- f.__test__ = False
- return parameterized_expand_wrapper
-
- @classmethod
- def param_as_standalone_func(cls, p, func, name):
- @wraps(func)
- def standalone_func(*a):
- return func(*(a + p.args), **p.kwargs)
- standalone_func.__name__ = name
-
- # place_as is used by py.test to determine what source file should be
- # used for this test.
- standalone_func.place_as = func
-
- # Remove __wrapped__ because py.test will try to look at __wrapped__
- # to determine which parameters should be used with this test case,
- # and obviously we don't need it to do any parameterization.
- try:
- del standalone_func.__wrapped__
- except AttributeError:
- pass
- return standalone_func
-
- @classmethod
- def to_safe_name(cls, s):
- return str(re.sub("[^a-zA-Z0-9_]+", "_", s))
diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py
index 2a2126503..351bd2a81 100644
--- a/numpy/testing/_private/utils.py
+++ b/numpy/testing/_private/utils.py
@@ -29,7 +29,7 @@ __all__ = [
'assert_array_equal', 'assert_array_less', 'assert_string_equal',
'assert_array_almost_equal', 'assert_raises', 'build_err_msg',
'decorate_methods', 'jiffies', 'memusage', 'print_assert_equal',
- 'raises', 'rundocs', 'runstring', 'verbose', 'measure',
+ 'rundocs', 'runstring', 'verbose', 'measure',
'assert_', 'assert_array_almost_equal_nulp', 'assert_raises_regex',
'assert_array_max_ulp', 'assert_warns', 'assert_no_warnings',
'assert_allclose', 'IgnoreException', 'clear_and_catch_warnings',
@@ -57,28 +57,6 @@ HAS_LAPACK64 = numpy.linalg.lapack_lite._ilp64
_OLD_PROMOTION = lambda: np._get_promotion_state() == 'legacy'
-def import_nose():
- """ Import nose only when needed.
- """
- nose_is_good = True
- minimum_nose_version = (1, 0, 0)
- try:
- import nose
- except ImportError:
- nose_is_good = False
- else:
- if nose.__versioninfo__ < minimum_nose_version:
- nose_is_good = False
-
- if not nose_is_good:
- msg = ('Need nose >= %d.%d.%d for tests - see '
- 'https://nose.readthedocs.io' %
- minimum_nose_version)
- raise ImportError(msg)
-
- return nose
-
-
def assert_(val, msg=''):
"""
Assert that works in release mode.
@@ -1305,43 +1283,6 @@ def rundocs(filename=None, raise_on_error=True):
raise AssertionError("Some doctests failed:\n%s" % "\n".join(msg))
-def raises(*args):
- """Decorator to check for raised exceptions.
-
- The decorated test function must raise one of the passed exceptions to
- pass. If you want to test many assertions about exceptions in a single
- test, you may want to use `assert_raises` instead.
-
- .. warning::
- This decorator is nose specific, do not use it if you are using a
- different test framework.
-
- Parameters
- ----------
- args : exceptions
- The test passes if any of the passed exceptions is raised.
-
- Raises
- ------
- AssertionError
-
- Examples
- --------
-
- Usage::
-
- @raises(TypeError, ValueError)
- def test_raises_type_error():
- raise TypeError("This test passes")
-
- @raises(Exception)
- def test_that_fails_by_passing():
- pass
-
- """
- nose = import_nose()
- return nose.tools.raises(*args)
-
#
# assert_raises and assert_raises_regex are taken from unittest.
#
diff --git a/numpy/testing/tests/test_doctesting.py b/numpy/testing/tests/test_doctesting.py
deleted file mode 100644
index 92c2156d8..000000000
--- a/numpy/testing/tests/test_doctesting.py
+++ /dev/null
@@ -1,57 +0,0 @@
-""" Doctests for NumPy-specific nose/doctest modifications
-
-"""
-#FIXME: None of these tests is run, because 'check' is not a recognized
-# testing prefix.
-
-# try the #random directive on the output line
-def check_random_directive():
- '''
- >>> 2+2
- <BadExample object at 0x084D05AC> #random: may vary on your system
- '''
-
-# check the implicit "import numpy as np"
-def check_implicit_np():
- '''
- >>> np.array([1,2,3])
- array([1, 2, 3])
- '''
-
-# there's some extraneous whitespace around the correct responses
-def check_whitespace_enabled():
- '''
- # whitespace after the 3
- >>> 1+2
- 3
-
- # whitespace before the 7
- >>> 3+4
- 7
- '''
-
-def check_empty_output():
- """ Check that no output does not cause an error.
-
- This is related to nose bug 445; the numpy plugin changed the
- doctest-result-variable default and therefore hit this bug:
- http://code.google.com/p/python-nose/issues/detail?id=445
-
- >>> a = 10
- """
-
-def check_skip():
- """ Check skip directive
-
- The test below should not run
-
- >>> 1/0 #doctest: +SKIP
- """
-
-
-if __name__ == '__main__':
- # Run tests outside numpy test rig
- import nose
- from numpy.testing.noseclasses import NumpyDoctest
- argv = ['', __file__, '--with-numpydoctest']
- nose.core.TestProgram(argv=argv, addplugins=[NumpyDoctest()])
diff --git a/numpy/testing/tests/test_utils.py b/numpy/testing/tests/test_utils.py
index 052cc3aa1..8f4912fab 100644
--- a/numpy/testing/tests/test_utils.py
+++ b/numpy/testing/tests/test_utils.py
@@ -8,7 +8,7 @@ import weakref
import numpy as np
from numpy.testing import (
assert_equal, assert_array_equal, assert_almost_equal,
- assert_array_almost_equal, assert_array_less, build_err_msg, raises,
+ assert_array_almost_equal, assert_array_less, build_err_msg,
assert_raises, assert_warns, assert_no_warnings, assert_allclose,
assert_approx_equal, assert_array_almost_equal_nulp, assert_array_max_ulp,
clear_and_catch_warnings, suppress_warnings, assert_string_equal, assert_,
@@ -793,41 +793,6 @@ class TestArrayAssertLess:
self._assert_func(-ainf, x)
-@pytest.mark.skip(reason="The raises decorator depends on Nose")
-class TestRaises:
-
- def setup_method(self):
- class MyException(Exception):
- pass
-
- self.e = MyException
-
- def raises_exception(self, e):
- raise e
-
- def does_not_raise_exception(self):
- pass
-
- def test_correct_catch(self):
- raises(self.e)(self.raises_exception)(self.e) # raises?
-
- def test_wrong_exception(self):
- try:
- raises(self.e)(self.raises_exception)(RuntimeError) # raises?
- except RuntimeError:
- return
- else:
- raise AssertionError("should have caught RuntimeError")
-
- def test_catch_no_raise(self):
- try:
- raises(self.e)(self.does_not_raise_exception)() # raises?
- except AssertionError:
- return
- else:
- raise AssertionError("should have raised an AssertionError")
-
-
class TestWarns:
def test_warn(self):
diff --git a/numpy/tests/test_public_api.py b/numpy/tests/test_public_api.py
index 98e59b452..cc6d0a033 100644
--- a/numpy/tests/test_public_api.py
+++ b/numpy/tests/test_public_api.py
@@ -34,7 +34,6 @@ def test_numpy_namespace():
# None of these objects are publicly documented to be part of the main
# NumPy namespace (some are useful though, others need to be cleaned up)
undocumented = {
- 'Tester': 'numpy.testing._private.nosetester.NoseTester',
'_add_newdoc_ufunc': 'numpy.core._multiarray_umath._add_newdoc_ufunc',
'add_docstring': 'numpy.core._multiarray_umath.add_docstring',
'add_newdoc': 'numpy.core.function_base.add_newdoc',
@@ -64,7 +63,7 @@ def test_numpy_namespace():
@pytest.mark.skipif(IS_WASM, reason="can't start subprocess")
-@pytest.mark.parametrize('name', ['testing', 'Tester'])
+@pytest.mark.parametrize('name', ['testing'])
def test_import_lazy_import(name):
"""Make sure we can actually use the modules we lazy load.
diff --git a/numpy/typing/tests/data/reveal/testing.pyi b/numpy/typing/tests/data/reveal/testing.pyi
index 5440af800..5c35731d3 100644
--- a/numpy/typing/tests/data/reveal/testing.pyi
+++ b/numpy/typing/tests/data/reveal/testing.pyi
@@ -113,7 +113,6 @@ reveal_type(np.testing.rundocs()) # E: None
reveal_type(np.testing.rundocs("test.py")) # E: None
reveal_type(np.testing.rundocs(Path("test.py"), raise_on_error=True)) # E: None
-@np.testing.raises(RuntimeError, RuntimeWarning)
def func3(a: int) -> bool: ...
reveal_type(func3) # E: def (a: builtins.int) -> builtins.bool
@@ -175,4 +174,3 @@ reveal_type(np.testing.assert_no_gc_cycles(func3, 5)) # E: None
reveal_type(np.testing.break_cycles()) # E: None
reveal_type(np.testing.TestCase()) # E: unittest.case.TestCase
-reveal_type(np.testing.run_module_suite(file_to_run="numpy/tests/test_matlib.py")) # E: None