[Numpy-svn] r5792 - in branches/1.2.x/numpy: core/tests testing

numpy-svn@scip... numpy-svn@scip...
Sat Sep 6 05:48:42 CDT 2008


Author: alan.mcintyre
Date: 2008-09-06 05:48:38 -0500 (Sat, 06 Sep 2008)
New Revision: 5792

Modified:
   branches/1.2.x/numpy/core/tests/test_umath.py
   branches/1.2.x/numpy/testing/decorators.py
   branches/1.2.x/numpy/testing/noseclasses.py
   branches/1.2.x/numpy/testing/nosetester.py
Log:
Backports for:
  rev 5769 - Replaced numpy.testing.decorators.skipknownfailure with 
             knownfailureif, which allows flagging tests as known failures
             rather than skips.  Updated test_umath to use knownfailureif.
  rev 5770 - Renamed classes in nosetester.py/noseclasses.py to
             conform to PEP 8.
  rev 5772 - Removed debugging code from noseclasses.py


Modified: branches/1.2.x/numpy/core/tests/test_umath.py
===================================================================
--- branches/1.2.x/numpy/core/tests/test_umath.py	2008-09-05 23:38:44 UTC (rev 5791)
+++ branches/1.2.x/numpy/core/tests/test_umath.py	2008-09-06 10:48:38 UTC (rev 5792)
@@ -229,6 +229,7 @@
         yield _check_branch_cut, np.arccosh, [-2j, 2j, 2], [1,  1,  1j], 1, 1
         yield _check_branch_cut, np.arctanh, [-2j, 2j, 0], [1,  1,  1j], 1, 1
 
+    @dec.knownfailureif(True, "These branch cuts are known to fail")
     def test_branch_cuts_failing(self):
         # XXX: signed zeros are not OK for sqrt or for the arc* functions
         yield _check_branch_cut, np.sqrt,  -0.5, 1j, 1, -1, True
@@ -238,7 +239,6 @@
         yield _check_branch_cut, np.arcsinh, [-2j,  2j], [-1,   1], -1, 1, True
         yield _check_branch_cut, np.arccosh, [ -1, 0.5], [1j,  1j], 1, -1, True
         yield _check_branch_cut, np.arctanh, [ -2,   2], [1j, -1j], 1, -1, True
-    test_branch_cuts_failing = dec.skipknownfailure(test_branch_cuts_failing)
 
     def test_against_cmath(self):
         import cmath, sys

Modified: branches/1.2.x/numpy/testing/decorators.py
===================================================================
--- branches/1.2.x/numpy/testing/decorators.py	2008-09-05 23:38:44 UTC (rev 5791)
+++ branches/1.2.x/numpy/testing/decorators.py	2008-09-06 10:48:38 UTC (rev 5792)
@@ -83,12 +83,41 @@
         return nose.tools.make_decorator(f)(skipper)
     return skip_decorator
 
-def skipknownfailure(f):
-    ''' Decorator to raise SkipTest for test known to fail
+def knownfailureif(skip_condition, msg=None):
+    ''' Make function raise KnownFailureTest exception if skip_condition is true
+
+    Parameters
+    ---------
+    skip_condition : bool
+        Flag to determine whether to mark test as known failure (True) 
+        or not (False)
+    msg : string
+        Message to give on raising a KnownFailureTest exception
+
+   Returns
+   -------
+   decorator : function
+       Decorator, which, when applied to a function, causes SkipTest
+       to be raised when the skip_condition was True, and the function
+       to be called normally otherwise.
+
+    Notes
+    -----
+    You will see from the code that we had to further decorate the
+    decorator with the nose.tools.make_decorator function in order to
+    transmit function name, and various other metadata.
     '''
-    # Local import to avoid a hard nose dependency and only incur the
-    # import time overhead at actual test-time.
-    import nose
-    def skipper(*args, **kwargs):
-        raise nose.SkipTest, 'This test is known to fail'
-    return nose.tools.make_decorator(f)(skipper)
+    if msg is None:
+        msg = 'Test skipped due to known failure'
+    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
+        from noseclasses import KnownFailureTest
+        def skipper(*args, **kwargs):
+            if skip_condition:
+                raise KnownFailureTest, msg
+            else:
+                return f(*args, **kwargs)
+        return nose.tools.make_decorator(f)(skipper)
+    return skip_decorator

Modified: branches/1.2.x/numpy/testing/noseclasses.py
===================================================================
--- branches/1.2.x/numpy/testing/noseclasses.py	2008-09-05 23:38:44 UTC (rev 5791)
+++ branches/1.2.x/numpy/testing/noseclasses.py	2008-09-06 10:48:38 UTC (rev 5792)
@@ -7,6 +7,7 @@
 import doctest
 
 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, tolist
 import numpy
@@ -16,14 +17,14 @@
 _doctest_ignore = ['generate_numpy_api.py', 'scons_support.py',
                    'setupscons.py', 'setup.py']
 
-# All the classes in this module begin with 'numpy' to clearly distinguish them
-# from the plethora of very similar names from nose/unittest/doctest
+# 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, http://bugs.python.org/issue3158)
-class numpyDocTestFinder(doctest.DocTestFinder):
+class NumpyDocTestFinder(doctest.DocTestFinder):
 
     def _from_module(self, module, object):
         """
@@ -113,7 +114,7 @@
                                globs, seen)
 
 
-class numpyDocTestCase(npd.DocTestCase):
+class NumpyDocTestCase(npd.DocTestCase):
     """Proxy for DocTestCase: provides an address() method that
     returns the correct address for the doctest case. Otherwise
     acts as a proxy to the test case. To provide hints for address(),
@@ -137,7 +138,7 @@
 # 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):
+class NumpyOutputChecker(doctest.OutputChecker):
     def check_output(self, want, got, optionflags):
         ret = doctest.OutputChecker.check_output(self, want, got,
                                                  optionflags)
@@ -151,7 +152,7 @@
 # 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):
+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
@@ -164,7 +165,7 @@
 
 print_state = numpy.get_printoptions()
 
-class numpyDoctest(npd.Doctest):
+class NumpyDoctest(npd.Doctest):
     name = 'numpydoctest'   # call nosetests with --with-numpydoctest
     enabled = True
 
@@ -175,7 +176,7 @@
         Plugin.configure(self, options, config)
         self.doctest_tests = True
 #        self.extension = tolist(options.doctestExtension)
-        self.finder = numpyDocTestFinder()
+        self.finder = NumpyDocTestFinder()
         self.parser = doctest.DocTestParser()
 
     # Turn on whitespace normalization, set a minimal execution context
@@ -223,15 +224,12 @@
                 p2 = p[-1]
                 test.globs[p2] = __import__(pkg_name, test.globs, {}, [p2])
 
-                print 'additional import for %s: from %s import %s' % (test.filename, p1, p2)
-                print '    (%s): %r' % (pkg_name, test.globs[p2])
-
             # always use whitespace and ellipsis options
             optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
 
-            yield numpyDocTestCase(test,
+            yield NumpyDocTestCase(test,
                                    optionflags=optionflags,
-                                   checker=numpyOutputChecker())
+                                   checker=NumpyOutputChecker())
 
 
     # Add an afterContext method to nose.plugins.doctests.Doctest in order
@@ -246,3 +244,35 @@
         if bn in _doctest_ignore:
             return False
         return npd.Doctest.wantFile(self, file)
+
+
+class KnownFailureTest(Exception):
+    '''Raise this exception to mark a test as a known failing test.'''
+    pass
+
+
+class KnownFailure(ErrorClassPlugin):
+    '''Plugin that installs a KNOWNFAIL error class for the 
+    KnownFailureClass exception.  When KnownFailureTest 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,
+                           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 '
+                               '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

Modified: branches/1.2.x/numpy/testing/nosetester.py
===================================================================
--- branches/1.2.x/numpy/testing/nosetester.py	2008-09-05 23:38:44 UTC (rev 5791)
+++ branches/1.2.x/numpy/testing/nosetester.py	2008-09-06 10:48:38 UTC (rev 5792)
@@ -266,8 +266,8 @@
 
         # construct list of plugins, omitting the existing doctest plugin
         import nose.plugins.builtin
-        from noseclasses import numpyDoctest
-        plugins = [numpyDoctest()]
+        from noseclasses import NumpyDoctest, KnownFailure
+        plugins = [NumpyDoctest(), KnownFailure()]
         for p in nose.plugins.builtin.plugins:
             plug = p()
             if plug.name == 'doctest':



More information about the Numpy-svn mailing list