[Scipy-svn] r3853 - in trunk/scipy: linsolve/umfpack/tests misc/tests stats/models testing
scipy-svn@scip...
scipy-svn@scip...
Mon Jan 21 14:41:22 CST 2008
Author: matthew.brett@gmail.com
Date: 2008-01-21 14:40:25 -0600 (Mon, 21 Jan 2008)
New Revision: 3853
Modified:
trunk/scipy/linsolve/umfpack/tests/test_umfpack.py
trunk/scipy/misc/tests/test_pilutil.py
trunk/scipy/stats/models/setup.py
trunk/scipy/testing/decorators.py
trunk/scipy/testing/utils.py
Log:
Fancy decorator work to do conditional SkipTest exceptions for optional dependencies
Modified: trunk/scipy/linsolve/umfpack/tests/test_umfpack.py
===================================================================
--- trunk/scipy/linsolve/umfpack/tests/test_umfpack.py 2008-01-19 19:43:04 UTC (rev 3852)
+++ trunk/scipy/linsolve/umfpack/tests/test_umfpack.py 2008-01-21 20:40:25 UTC (rev 3853)
@@ -14,10 +14,17 @@
from scipy.sparse import csc_matrix, dok_matrix, spdiags
import numpy as nm
-import scipy.linsolve.umfpack as um
-
+try:
+ import scipy.linsolve.umfpack as um
+except (ImportError, AttributeError):
+ _have_umfpack = False
+else:
+ _have_umfpack = um.umfpack._um is not None
+
# Allow disabling of nose tests if umfpack not present
-TestCase.__test__ = um.umfpack._um is not None
+# See end of file for application
+_umfpack_skip = dec.skipif(not _have_umfpack,
+ 'UMFPACK appears not to be compiled')
class TestSolvers(TestCase):
"""Tests inverting a sparse linear system"""
@@ -165,6 +172,9 @@
self.complex_matrices = [x.astype(nm.complex128)
for x in self.real_matrices]
+# Skip methods if umfpack not present
+for cls in [TestSolvers, TestFactorization]:
+ decorate_methods(cls, _umfpack_skip)
if __name__ == "__main__":
nose.run(argv=['', __file__])
Modified: trunk/scipy/misc/tests/test_pilutil.py
===================================================================
--- trunk/scipy/misc/tests/test_pilutil.py 2008-01-19 19:43:04 UTC (rev 3852)
+++ trunk/scipy/misc/tests/test_pilutil.py 2008-01-21 20:40:25 UTC (rev 3853)
@@ -11,8 +11,10 @@
else:
_have_PIL = True
import scipy.misc.pilutil as pilutil
-TestCase.__test__ = _have_PIL
+# Function / method decorator for skipping PIL tests on import failure
+_pilskip = dec.skipif(not _have_PIL, 'Need to import PIL for this test')
+
datapath = os.path.dirname(__file__)
class TestPILUtil(TestCase):
@@ -28,14 +30,13 @@
assert_equal(pilutil.bytescale(x),x)
assert_equal(pilutil.bytescale(y),[0,127,255])
-
def tst_fromimage(filename, irange):
img = pilutil.fromimage(PIL.Image.open(filename))
imin,imax = irange
assert img.min() >= imin
assert img.max() <= imax
-@dec.setastest(_have_PIL)
+@_pilskip
def test_fromimage():
''' Test generator for parametric tests '''
data = {'icon.png':(0,255),
@@ -44,5 +45,7 @@
for fn, irange in data.iteritems():
yield tst_fromimage, os.path.join(datapath,'data',fn), irange
+decorate_methods(TestPILUtil, _pilskip)
+
if __name__ == "__main__":
nose.run(argv=['', __file__])
Modified: trunk/scipy/stats/models/setup.py
===================================================================
--- trunk/scipy/stats/models/setup.py 2008-01-19 19:43:04 UTC (rev 3852)
+++ trunk/scipy/stats/models/setup.py 2008-01-21 20:40:25 UTC (rev 3853)
@@ -8,7 +8,6 @@
config.add_data_dir('tests')
try:
- import sys
from scipy.stats.models.bspline_module import mod
n, s, d = weave_ext(mod)
config.add_extension(n, s, **d)
Modified: trunk/scipy/testing/decorators.py
===================================================================
--- trunk/scipy/testing/decorators.py 2008-01-19 19:43:04 UTC (rev 3852)
+++ trunk/scipy/testing/decorators.py 2008-01-21 20:40:25 UTC (rev 3853)
@@ -1,5 +1,10 @@
"""Decorators for labeling test objects."""
+try:
+ import nose
+except ImportError:
+ pass
+
def slow(t):
"""Labels a test as 'slow'.
@@ -25,9 +30,33 @@
>>> @setastest(False)
>>> def func_with_test_in_name(arg1, arg2): pass
...
- >>>
+ >>>
+
+ Note that this decorator cannot use the nose namespace, because it
+ can be called from a non-test.
'''
def set_test(t):
t.__test__ = tf
return t
return set_test
+
+def skipif(skip_condition, msg=None):
+ ''' Make function raise SkipTest exception if skip_condition is true
+
+ Parameters
+ ---------
+ skip_condition : bool
+ Flag to determine whether to skip test (True) or not (False)
+ msg : string
+ Message to give on raising a SkipTest exception
+ '''
+ if msg is None:
+ msg = 'Test skipped due to test condition (see code)'
+ def skip_decorator(f):
+ def skipper(*args, **kwargs):
+ if skip_condition:
+ raise nose.SkipTest, msg
+ else:
+ return f(*args, **kwargs)
+ return nose.tools.make_decorator(f)(skipper)
+ return skip_decorator
Modified: trunk/scipy/testing/utils.py
===================================================================
--- trunk/scipy/testing/utils.py 2008-01-19 19:43:04 UTC (rev 3852)
+++ trunk/scipy/testing/utils.py 2008-01-21 20:40:25 UTC (rev 3853)
@@ -1,10 +1,13 @@
"""Simple testing utilities
"""
-__all__ = ['set_local_path', 'restore_path', 'measure', 'info', 'warn', 'error']
+__all__ = ['set_local_path', 'restore_path', 'measure', 'info', 'warn',\
+ 'error', 'decorate_methods']
import os
import sys
+import re
+from inspect import isfunction
from numpy.distutils.misc_util import yellow_text, red_text
from numpy.testing.utils import jiffies
@@ -58,3 +61,38 @@
def error(message):
print >> sys.stderr,red_text('Error: %s' % (message))
sys.stderr.flush()
+
+def decorate_methods(cls, decorator, testmatch=None):
+ ''' Apply decorator to all methods in class matching testmatch
+
+ Parameters
+ ----------
+ cls : class
+ Class to decorate methods for
+ decorator : function
+ Decorator to apply to methods
+ testmatch : compiled regexp or string to compile to regexp
+ Decorators are applied if testmatch.search(methodname)
+ is not None. Default value is
+ re.compile(r'(?:^|[\\b_\\.%s-])[Tt]est' % os.sep)
+ (the default for nose)
+ '''
+ if testmatch is None:
+ testmatch = re.compile(r'(?:^|[\\b_\\.%s-])[Tt]est' % os.sep)
+ else:
+ testmatch = re.compile(testmatch)
+ cls_attr = cls.__dict__
+ methods = filter(isfunction, cls_attr.values())
+ for function in methods:
+ try:
+ if hasattr(function, 'compat_func_name'):
+ funcname = function.compat_func_name
+ else:
+ funcname = function.__name__
+ except AttributeError:
+ # not a function
+ continue
+ if testmatch.search(funcname) and not funcname.startswith('_'):
+ setattr(cls, funcname, decorator(function))
+ return
+
More information about the Scipy-svn
mailing list