Skip to content

Commit

Permalink
Merge pull request numpy#6688 from ev-br/knownf
Browse files Browse the repository at this point in the history
expose KnownFailure and SkipTest exceptions in numpy.testing
  • Loading branch information
charris committed Nov 16, 2015
2 parents 6d3ec65 + 70c5052 commit cbc14f0
Show file tree
Hide file tree
Showing 13 changed files with 72 additions and 59 deletions.
4 changes: 4 additions & 0 deletions doc/release/1.11.0-notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ via ``python runtests.py --bench``. For more details, see ``benchmarks/README.rs
arrays have memory overlap is added. ``np.may_share_memory`` also now
has an option to spend more effort to reduce false positives.

* ``SkipTest`` and ``KnownFailureException`` exception classes are exposed in the
``numpy.testing`` namespace. Raise them in a test function to mark the test to
be skipped or mark it as a known failure, respectively.

Improvements
============

Expand Down
3 changes: 1 addition & 2 deletions numpy/core/tests/test_multiarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@


import numpy as np
from nose import SkipTest
from numpy.compat import asbytes, getexception, strchar, unicode, sixu
from test_print import in_foreign_locale
from numpy.core.multiarray_tests import (
Expand All @@ -29,7 +28,7 @@
TestCase, run_module_suite, assert_, assert_raises,
assert_equal, assert_almost_equal, assert_array_equal,
assert_array_almost_equal, assert_allclose,
assert_array_less, runstring, dec
assert_array_less, runstring, dec, SkipTest
)

# Need to test an object that does not fully implement math interface
Expand Down
8 changes: 4 additions & 4 deletions numpy/core/tests/test_print.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import numpy as np
from numpy.testing import (
run_module_suite, assert_, assert_equal
run_module_suite, assert_, assert_equal, SkipTest
)


Expand Down Expand Up @@ -207,7 +207,7 @@ def test_scalar_format():
def in_foreign_locale(func):
"""
Swap LC_NUMERIC locale to one in which the decimal point is ',' and not '.'
If not possible, raise nose.SkipTest
If not possible, raise SkipTest
"""
if sys.platform == 'win32':
Expand All @@ -225,8 +225,8 @@ def wrapper(*args, **kwargs):
except locale.Error:
pass
else:
raise nose.SkipTest("Skipping locale test, because "
"French locale not found")
raise SkipTest("Skipping locale test, because "
"French locale not found")
return func(*args, **kwargs)
finally:
locale.setlocale(locale.LC_NUMERIC, locale=curloc)
Expand Down
6 changes: 2 additions & 4 deletions numpy/f2py/tests/test_array_from_pyobj.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@
import sys
import copy

import nose

from numpy import (
array, alltrue, ndarray, zeros, dtype, intp, clongdouble
)
from numpy.testing import (
run_module_suite, assert_, assert_equal
run_module_suite, assert_, assert_equal, SkipTest
)
from numpy.core.multiarray import typeinfo
import util
Expand All @@ -28,7 +26,7 @@ def setup():

# Check compiler availability first
if not util.has_c_compiler():
raise nose.SkipTest("No C compiler available")
raise SkipTest("No C compiler available")

if wrap is None:
config_code = """
Expand Down
9 changes: 4 additions & 5 deletions numpy/f2py/tests/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@
import re
import random

import nose

from numpy.compat import asbytes, asstr
import numpy.f2py
from numpy.testing import SkipTest

try:
from hashlib import md5
Expand Down Expand Up @@ -334,7 +333,7 @@ def setUp(self):

# Check compiler availability first
if not has_c_compiler():
raise nose.SkipTest("No C compiler available")
raise SkipTest("No C compiler available")

codes = []
if self.sources:
Expand All @@ -350,9 +349,9 @@ def setUp(self):
elif fn.endswith('.f90'):
needs_f90 = True
if needs_f77 and not has_f77_compiler():
raise nose.SkipTest("No Fortran 77 compiler available")
raise SkipTest("No Fortran 77 compiler available")
if needs_f90 and not has_f90_compiler():
raise nose.SkipTest("No Fortran 90 compiler available")
raise SkipTest("No Fortran 90 compiler available")

# Build the module
if self.code is not None:
Expand Down
8 changes: 3 additions & 5 deletions numpy/lib/tests/test__datasource.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from numpy.compat import asbytes
from numpy.testing import (
run_module_suite, TestCase, assert_
run_module_suite, TestCase, assert_, SkipTest
)
import numpy.lib._datasource as datasource

Expand Down Expand Up @@ -137,8 +137,7 @@ def test_ValidGzipFile(self):
import gzip
except ImportError:
# We don't have the gzip capabilities to test.
import nose
raise nose.SkipTest
raise SkipTest
# Test datasource's internal file_opener for Gzip files.
filepath = os.path.join(self.tmpdir, 'foobar.txt.gz')
fp = gzip.open(filepath, 'w')
Expand All @@ -154,8 +153,7 @@ def test_ValidBz2File(self):
import bz2
except ImportError:
# We don't have the bz2 capabilities to test.
import nose
raise nose.SkipTest
raise SkipTest
# Test datasource's internal file_opener for BZip2 files.
filepath = os.path.join(self.tmpdir, 'foobar.txt.bz2')
fp = bz2.BZ2File(filepath, 'w')
Expand Down
3 changes: 1 addition & 2 deletions numpy/lib/tests/test_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@
from numpy.compat import asbytes, asbytes_nested, sixu
from numpy.testing import (
run_module_suite, assert_, assert_array_equal, assert_raises, raises,
dec
dec, SkipTest
)
from numpy.lib import format

Expand Down Expand Up @@ -812,7 +812,6 @@ def test_bad_header():


def test_large_file_support():
from nose import SkipTest
if (sys.platform == 'win32' or sys.platform == 'cygwin'):
raise SkipTest("Unknown if Windows has sparse filesystems")
# try creating a large sparse file
Expand Down
3 changes: 1 addition & 2 deletions numpy/linalg/tests/test_linalg.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from numpy.testing import (
assert_, assert_equal, assert_raises, assert_array_equal,
assert_almost_equal, assert_allclose, run_module_suite,
dec
dec, SkipTest
)


Expand Down Expand Up @@ -1215,7 +1215,6 @@ def test_xerbla_override():
# Check that our xerbla has been successfully linked in. If it is not,
# the default xerbla routine is called, which prints a message to stdout
# and may, or may not, abort the process depending on the LAPACK package.
from nose import SkipTest

XERBLA_OK = 255

Expand Down
19 changes: 10 additions & 9 deletions numpy/testing/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import warnings
import collections

from .utils import SkipTest

def slow(t):
"""
Expand Down Expand Up @@ -141,14 +142,14 @@ def get_msg(func,msg=None):
def skipper_func(*args, **kwargs):
"""Skipper for normal test functions."""
if skip_val():
raise nose.SkipTest(get_msg(f, msg))
raise SkipTest(get_msg(f, msg))
else:
return f(*args, **kwargs)

def skipper_gen(*args, **kwargs):
"""Skipper for test generators."""
if skip_val():
raise nose.SkipTest(get_msg(f, msg))
raise SkipTest(get_msg(f, msg))
else:
for x in f(*args, **kwargs):
yield x
Expand All @@ -166,7 +167,7 @@ def skipper_gen(*args, **kwargs):

def knownfailureif(fail_condition, msg=None):
"""
Make function raise KnownFailureTest exception if given condition is true.
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
Expand All @@ -178,15 +179,15 @@ def knownfailureif(fail_condition, msg=None):
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 KnownFailureTest exception.
Message to give on raising a KnownFailureException 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.
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
-----
Expand All @@ -207,11 +208,11 @@ 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 KnownFailureTest
from .noseclasses import KnownFailureException

def knownfailer(*args, **kwargs):
if fail_val():
raise KnownFailureTest(msg)
raise KnownFailureException(msg)
else:
return f(*args, **kwargs)
return nose.tools.make_decorator(f)(knownfailer)
Expand Down
19 changes: 9 additions & 10 deletions numpy/testing/noseclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import os
import doctest
import inspect

import nose
from nose.plugins import doctests as npd
Expand All @@ -16,7 +17,8 @@
from nose.util import src
import numpy
from .nosetester import get_package_name
import inspect
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
Expand Down Expand Up @@ -298,27 +300,22 @@ def configure(self, options, config):
if p.name != self.to_unplug]


class KnownFailureTest(Exception):
'''Raise this exception to mark a test as a known failing test.'''
pass


class KnownFailure(ErrorClassPlugin):
class KnownFailurePlugin(ErrorClassPlugin):
'''Plugin that installs a KNOWNFAIL error class for the
KnownFailureClass exception. When KnownFailureTest is raised,
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(KnownFailureTest,
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 KnownFailureTest '
help='Disable special handling of KnownFailure '
'exceptions')

def configure(self, options, conf):
Expand All @@ -329,6 +326,8 @@ def configure(self, options, conf):
if disable:
self.enabled = False

KnownFailure = KnownFailurePlugin # backwards compat


# Class allows us to save the results of the tests in runTests - see runTests
# method docstring for details
Expand Down
8 changes: 4 additions & 4 deletions numpy/testing/nosetester.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ def run_module_suite(file_to_run=None, argv=None):
argv = argv + [file_to_run]

nose = import_nose()
from .noseclasses import KnownFailure
nose.run(argv=argv, addplugins=[KnownFailure()])
from .noseclasses import KnownFailurePlugin
nose.run(argv=argv, addplugins=[KnownFailurePlugin()])


class NoseTester(object):
Expand Down Expand Up @@ -301,8 +301,8 @@ def prepare_test_args(self, label='fast', verbose=1, extra_argv=None,
'--cover-tests', '--cover-erase']
# construct list of plugins
import nose.plugins.builtin
from .noseclasses import KnownFailure, Unplugger
plugins = [KnownFailure()]
from .noseclasses import KnownFailurePlugin, Unplugger
plugins = [KnownFailurePlugin()]
plugins += [p() for p in nose.plugins.builtin.plugins]
# add doctesting if required
doctest_argv = '--with-doctest' in argv
Expand Down
Loading

0 comments on commit cbc14f0

Please sign in to comment.