Source code for mmf.utils.decorators
# Copied from numpy.  Should use numpy version if defined.
"""Decorators for labeling 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 metadata such as function name,
setup and teardown functions and so on - see nose.tools for more
information.
"""
__all__ = ['slow', 'setastest', 'skipif', 'skipknownfailure', 'with_args']
def _import_from_numpy(f):
    """Decorator that tries to get the numpy version first."""
    try:
        f = __import__('numpy.testing.%s'%f.__name__)
    except ImportError:
        pass
    return f
@_import_from_numpy
[docs]def slow(t):
    """Labels 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 consits of
    thousands of tests, so even a second is significant)."""
    t.slow = True
    return t
 
@_import_from_numpy
[docs]def setastest(tf=True):
    ''' Signals to nose that this function is or is not a test
    Parameters
    ----------
    tf : bool
        If True specifies this is a test, not a test otherwise
    
    Examples
    --------
    ::
      @setastest(False)
      def func_with_test_in_name(arg1, arg2): pass
         ...
    This decorator cannot use the nose namespace, because it can be
    called from a non-test module. See also istest and nottest in
    nose.tools
    '''
    def set_test(t):
        t.__test__ = tf
        return t
    return set_test
 
@_import_from_numpy
[docs]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
   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.
    '''
    if msg is None:
        msg = 'Test skipped due to test condition'
    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
        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
 
@_import_from_numpy
[docs]def skipknownfailure(f):
    ''' Decorator to raise SkipTest for test known to fail
    '''
    # 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)
 
@_import_from_numpy
[docs]def with_args(*v, **kw):  
    """Decorator to define a functions argspec:
    Examples
    --------
    >>> def A(x,y): print "A(%r,%r)"%(x,y) # doctest: +SKIP
    >>> def B(y,z): print "A(%r,%r)"%(y,z) # doctest: +SKIP
    >>> @with_args(A,B)
    ... def C(t,args):
    ...     print "C(%r)"%(t)
    ...     with_args(A)(args)
    ...     with_args(B)(args)          # doctest: +SKIP
    >>> C(x=1,y=2,z=3,t=4)              # doctest: +SKIP
    C(4)
    A(1,2)
    B(2,3)
    """
    raise NotImplementedError