##// END OF EJS Templates
Updated Michele Simionato's decorator.py module to 3.1.2....
Brian Granger -
Show More
@@ -0,0 +1,254 b''
1 ########################## LICENCE ###############################
2 ##
3 ## Copyright (c) 2005, Michele Simionato
4 ## All rights reserved.
5 ##
6 ## Redistributions of source code must retain the above copyright
7 ## notice, this list of conditions and the following disclaimer.
8 ## Redistributions in bytecode form must reproduce the above copyright
9 ## notice, this list of conditions and the following disclaimer in
10 ## the documentation and/or other materials provided with the
11 ## distribution.
12
13 ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
14 ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
15 ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
16 ## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
17 ## HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 ## INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19 ## BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
20 ## OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
22 ## TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
23 ## USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
24 ## DAMAGE.
25
26 """
27 Decorator module, see http://pypi.python.org/pypi/decorator
28 for the documentation.
29 """
30
31 __all__ = ["decorator", "FunctionMaker", "partial",
32 "deprecated", "getinfo", "new_wrapper"]
33
34 import os, sys, re, inspect, string, warnings
35 try:
36 from functools import partial
37 except ImportError: # for Python version < 2.5
38 class partial(object):
39 "A simple replacement of functools.partial"
40 def __init__(self, func, *args, **kw):
41 self.func = func
42 self.args = args
43 self.keywords = kw
44 def __call__(self, *otherargs, **otherkw):
45 kw = self.keywords.copy()
46 kw.update(otherkw)
47 return self.func(*(self.args + otherargs), **kw)
48
49 DEF = re.compile('\s*def\s*([_\w][_\w\d]*)\s*\(')
50
51 # basic functionality
52 class FunctionMaker(object):
53 """
54 An object with the ability to create functions with a given signature.
55 It has attributes name, doc, module, signature, defaults, dict and
56 methods update and make.
57 """
58 def __init__(self, func=None, name=None, signature=None,
59 defaults=None, doc=None, module=None, funcdict=None):
60 if func:
61 # func can be a class or a callable, but not an instance method
62 self.name = func.__name__
63 if self.name == '<lambda>': # small hack for lambda functions
64 self.name = '_lambda_'
65 self.doc = func.__doc__
66 self.module = func.__module__
67 if inspect.isfunction(func):
68 argspec = inspect.getargspec(func)
69 self.args, self.varargs, self.keywords, self.defaults = argspec
70 for i, arg in enumerate(self.args):
71 setattr(self, 'arg%d' % i, arg)
72 self.signature = inspect.formatargspec(
73 formatvalue=lambda val: "", *argspec)[1:-1]
74 self.dict = func.__dict__.copy()
75 if name:
76 self.name = name
77 if signature is not None:
78 self.signature = signature
79 if defaults:
80 self.defaults = defaults
81 if doc:
82 self.doc = doc
83 if module:
84 self.module = module
85 if funcdict:
86 self.dict = funcdict
87 # check existence required attributes
88 assert hasattr(self, 'name')
89 if not hasattr(self, 'signature'):
90 raise TypeError('You are decorating a non function: %s' % func)
91
92 def update(self, func, **kw):
93 "Update the signature of func with the data in self"
94 func.__name__ = self.name
95 func.__doc__ = getattr(self, 'doc', None)
96 func.__dict__ = getattr(self, 'dict', {})
97 func.func_defaults = getattr(self, 'defaults', ())
98 callermodule = sys._getframe(3).f_globals.get('__name__', '?')
99 func.__module__ = getattr(self, 'module', callermodule)
100 func.__dict__.update(kw)
101
102 def make(self, src_templ, evaldict=None, addsource=False, **attrs):
103 "Make a new function from a given template and update the signature"
104 src = src_templ % vars(self) # expand name and signature
105 evaldict = evaldict or {}
106 mo = DEF.match(src)
107 if mo is None:
108 raise SyntaxError('not a valid function template\n%s' % src)
109 name = mo.group(1) # extract the function name
110 reserved_names = set([name] + [
111 arg.strip(' *') for arg in self.signature.split(',')])
112 for n, v in evaldict.iteritems():
113 if n in reserved_names:
114 raise NameError('%s is overridden in\n%s' % (n, src))
115 if not src.endswith('\n'): # add a newline just for safety
116 src += '\n'
117 try:
118 code = compile(src, '<string>', 'single')
119 exec code in evaldict
120 except:
121 print >> sys.stderr, 'Error in generated code:'
122 print >> sys.stderr, src
123 raise
124 func = evaldict[name]
125 if addsource:
126 attrs['__source__'] = src
127 self.update(func, **attrs)
128 return func
129
130 @classmethod
131 def create(cls, obj, body, evaldict, defaults=None,
132 doc=None, module=None, addsource=True,**attrs):
133 """
134 Create a function from the strings name, signature and body.
135 evaldict is the evaluation dictionary. If addsource is true an attribute
136 __source__ is added to the result. The attributes attrs are added,
137 if any.
138 """
139 if isinstance(obj, str): # "name(signature)"
140 name, rest = obj.strip().split('(', 1)
141 signature = rest[:-1] #strip a right parens
142 func = None
143 else: # a function
144 name = None
145 signature = None
146 func = obj
147 fun = cls(func, name, signature, defaults, doc, module)
148 ibody = '\n'.join(' ' + line for line in body.splitlines())
149 return fun.make('def %(name)s(%(signature)s):\n' + ibody,
150 evaldict, addsource, **attrs)
151
152 def decorator(caller, func=None):
153 """
154 decorator(caller) converts a caller function into a decorator;
155 decorator(caller, func) decorates a function using a caller.
156 """
157 if func is not None: # returns a decorated function
158 return FunctionMaker.create(
159 func, "return _call_(_func_, %(signature)s)",
160 dict(_call_=caller, _func_=func), undecorated=func)
161 else: # returns a decorator
162 if isinstance(caller, partial):
163 return partial(decorator, caller)
164 # otherwise assume caller is a function
165 f = inspect.getargspec(caller)[0][0] # first arg
166 return FunctionMaker.create(
167 '%s(%s)' % (caller.__name__, f),
168 'return decorator(_call_, %s)' % f,
169 dict(_call_=caller, decorator=decorator), undecorated=caller,
170 doc=caller.__doc__, module=caller.__module__)
171
172 ###################### deprecated functionality #########################
173
174 @decorator
175 def deprecated(func, *args, **kw):
176 "A decorator for deprecated functions"
177 warnings.warn(
178 ('Calling the deprecated function %r\n'
179 'Downgrade to decorator 2.3 if you want to use this functionality')
180 % func.__name__, DeprecationWarning, stacklevel=3)
181 return func(*args, **kw)
182
183 @deprecated
184 def getinfo(func):
185 """
186 Returns an info dictionary containing:
187 - name (the name of the function : str)
188 - argnames (the names of the arguments : list)
189 - defaults (the values of the default arguments : tuple)
190 - signature (the signature : str)
191 - doc (the docstring : str)
192 - module (the module name : str)
193 - dict (the function __dict__ : str)
194
195 >>> def f(self, x=1, y=2, *args, **kw): pass
196
197 >>> info = getinfo(f)
198
199 >>> info["name"]
200 'f'
201 >>> info["argnames"]
202 ['self', 'x', 'y', 'args', 'kw']
203
204 >>> info["defaults"]
205 (1, 2)
206
207 >>> info["signature"]
208 'self, x, y, *args, **kw'
209 """
210 assert inspect.ismethod(func) or inspect.isfunction(func)
211 regargs, varargs, varkwargs, defaults = inspect.getargspec(func)
212 argnames = list(regargs)
213 if varargs:
214 argnames.append(varargs)
215 if varkwargs:
216 argnames.append(varkwargs)
217 signature = inspect.formatargspec(regargs, varargs, varkwargs, defaults,
218 formatvalue=lambda value: "")[1:-1]
219 return dict(name=func.__name__, argnames=argnames, signature=signature,
220 defaults = func.func_defaults, doc=func.__doc__,
221 module=func.__module__, dict=func.__dict__,
222 globals=func.func_globals, closure=func.func_closure)
223
224 @deprecated
225 def update_wrapper(wrapper, model, infodict=None):
226 "A replacement for functools.update_wrapper"
227 infodict = infodict or getinfo(model)
228 wrapper.__name__ = infodict['name']
229 wrapper.__doc__ = infodict['doc']
230 wrapper.__module__ = infodict['module']
231 wrapper.__dict__.update(infodict['dict'])
232 wrapper.func_defaults = infodict['defaults']
233 wrapper.undecorated = model
234 return wrapper
235
236 @deprecated
237 def new_wrapper(wrapper, model):
238 """
239 An improvement over functools.update_wrapper. The wrapper is a generic
240 callable object. It works by generating a copy of the wrapper with the
241 right signature and by updating the copy, not the original.
242 Moreovoer, 'model' can be a dictionary with keys 'name', 'doc', 'module',
243 'dict', 'defaults'.
244 """
245 if isinstance(model, dict):
246 infodict = model
247 else: # assume model is a function
248 infodict = getinfo(model)
249 assert not '_wrapper_' in infodict["argnames"], (
250 '"_wrapper_" is a reserved argument name!')
251 src = "lambda %(signature)s: _wrapper_(%(signature)s)" % infodict
252 funcopy = eval(src, dict(_wrapper_=wrapper))
253 return update_wrapper(funcopy, model, infodict)
254
@@ -1,254 +1,254 b''
1 """Decorators for labeling test objects.
1 """Decorators for labeling test objects.
2
2
3 Decorators that merely return a modified version of the original function
3 Decorators that merely return a modified version of the original function
4 object are straightforward. Decorators that return a new function object need
4 object are straightforward. Decorators that return a new function object need
5 to use nose.tools.make_decorator(original_function)(decorator) in returning the
5 to use nose.tools.make_decorator(original_function)(decorator) in returning the
6 decorator, in order to preserve metadata such as function name, setup and
6 decorator, in order to preserve metadata such as function name, setup and
7 teardown functions and so on - see nose.tools for more information.
7 teardown functions and so on - see nose.tools for more information.
8
8
9 This module provides a set of useful decorators meant to be ready to use in
9 This module provides a set of useful decorators meant to be ready to use in
10 your own tests. See the bottom of the file for the ready-made ones, and if you
10 your own tests. See the bottom of the file for the ready-made ones, and if you
11 find yourself writing a new one that may be of generic use, add it here.
11 find yourself writing a new one that may be of generic use, add it here.
12
12
13 NOTE: This file contains IPython-specific decorators and imports the
13 NOTE: This file contains IPython-specific decorators and imports the
14 numpy.testing.decorators file, which we've copied verbatim. Any of our own
14 numpy.testing.decorators file, which we've copied verbatim. Any of our own
15 code will be added at the bottom if we end up extending this.
15 code will be added at the bottom if we end up extending this.
16 """
16 """
17
17
18 # Stdlib imports
18 # Stdlib imports
19 import inspect
19 import inspect
20 import sys
20 import sys
21
21
22 # Third-party imports
22 # Third-party imports
23
23
24 # This is Michele Simionato's decorator module, also kept verbatim.
24 # This is Michele Simionato's decorator module, also kept verbatim.
25 from decorator_msim import decorator, update_wrapper
25 from IPython.external.decorator import decorator, update_wrapper
26
26
27 # Grab the numpy-specific decorators which we keep in a file that we
27 # Grab the numpy-specific decorators which we keep in a file that we
28 # occasionally update from upstream: decorators_numpy.py is an IDENTICAL copy
28 # occasionally update from upstream: decorators_numpy.py is an IDENTICAL copy
29 # of numpy.testing.decorators.
29 # of numpy.testing.decorators.
30 from decorators_numpy import *
30 from decorators_numpy import *
31
31
32 ##############################################################################
32 ##############################################################################
33 # Local code begins
33 # Local code begins
34
34
35 # Utility functions
35 # Utility functions
36
36
37 def apply_wrapper(wrapper,func):
37 def apply_wrapper(wrapper,func):
38 """Apply a wrapper to a function for decoration.
38 """Apply a wrapper to a function for decoration.
39
39
40 This mixes Michele Simionato's decorator tool with nose's make_decorator,
40 This mixes Michele Simionato's decorator tool with nose's make_decorator,
41 to apply a wrapper in a decorator so that all nose attributes, as well as
41 to apply a wrapper in a decorator so that all nose attributes, as well as
42 function signature and other properties, survive the decoration cleanly.
42 function signature and other properties, survive the decoration cleanly.
43 This will ensure that wrapped functions can still be well introspected via
43 This will ensure that wrapped functions can still be well introspected via
44 IPython, for example.
44 IPython, for example.
45 """
45 """
46 import nose.tools
46 import nose.tools
47
47
48 return decorator(wrapper,nose.tools.make_decorator(func)(wrapper))
48 return decorator(wrapper,nose.tools.make_decorator(func)(wrapper))
49
49
50
50
51 def make_label_dec(label,ds=None):
51 def make_label_dec(label,ds=None):
52 """Factory function to create a decorator that applies one or more labels.
52 """Factory function to create a decorator that applies one or more labels.
53
53
54 :Parameters:
54 :Parameters:
55 label : string or sequence
55 label : string or sequence
56 One or more labels that will be applied by the decorator to the functions
56 One or more labels that will be applied by the decorator to the functions
57 it decorates. Labels are attributes of the decorated function with their
57 it decorates. Labels are attributes of the decorated function with their
58 value set to True.
58 value set to True.
59
59
60 :Keywords:
60 :Keywords:
61 ds : string
61 ds : string
62 An optional docstring for the resulting decorator. If not given, a
62 An optional docstring for the resulting decorator. If not given, a
63 default docstring is auto-generated.
63 default docstring is auto-generated.
64
64
65 :Returns:
65 :Returns:
66 A decorator.
66 A decorator.
67
67
68 :Examples:
68 :Examples:
69
69
70 A simple labeling decorator:
70 A simple labeling decorator:
71 >>> slow = make_label_dec('slow')
71 >>> slow = make_label_dec('slow')
72 >>> print slow.__doc__
72 >>> print slow.__doc__
73 Labels a test as 'slow'.
73 Labels a test as 'slow'.
74
74
75 And one that uses multiple labels and a custom docstring:
75 And one that uses multiple labels and a custom docstring:
76 >>> rare = make_label_dec(['slow','hard'],
76 >>> rare = make_label_dec(['slow','hard'],
77 ... "Mix labels 'slow' and 'hard' for rare tests.")
77 ... "Mix labels 'slow' and 'hard' for rare tests.")
78 >>> print rare.__doc__
78 >>> print rare.__doc__
79 Mix labels 'slow' and 'hard' for rare tests.
79 Mix labels 'slow' and 'hard' for rare tests.
80
80
81 Now, let's test using this one:
81 Now, let's test using this one:
82 >>> @rare
82 >>> @rare
83 ... def f(): pass
83 ... def f(): pass
84 ...
84 ...
85 >>>
85 >>>
86 >>> f.slow
86 >>> f.slow
87 True
87 True
88 >>> f.hard
88 >>> f.hard
89 True
89 True
90 """
90 """
91
91
92 if isinstance(label,basestring):
92 if isinstance(label,basestring):
93 labels = [label]
93 labels = [label]
94 else:
94 else:
95 labels = label
95 labels = label
96
96
97 # Validate that the given label(s) are OK for use in setattr() by doing a
97 # Validate that the given label(s) are OK for use in setattr() by doing a
98 # dry run on a dummy function.
98 # dry run on a dummy function.
99 tmp = lambda : None
99 tmp = lambda : None
100 for label in labels:
100 for label in labels:
101 setattr(tmp,label,True)
101 setattr(tmp,label,True)
102
102
103 # This is the actual decorator we'll return
103 # This is the actual decorator we'll return
104 def decor(f):
104 def decor(f):
105 for label in labels:
105 for label in labels:
106 setattr(f,label,True)
106 setattr(f,label,True)
107 return f
107 return f
108
108
109 # Apply the user's docstring, or autogenerate a basic one
109 # Apply the user's docstring, or autogenerate a basic one
110 if ds is None:
110 if ds is None:
111 ds = "Labels a test as %r." % label
111 ds = "Labels a test as %r." % label
112 decor.__doc__ = ds
112 decor.__doc__ = ds
113
113
114 return decor
114 return decor
115
115
116
116
117 # Inspired by numpy's skipif, but uses the full apply_wrapper utility to
117 # Inspired by numpy's skipif, but uses the full apply_wrapper utility to
118 # preserve function metadata better and allows the skip condition to be a
118 # preserve function metadata better and allows the skip condition to be a
119 # callable.
119 # callable.
120 def skipif(skip_condition, msg=None):
120 def skipif(skip_condition, msg=None):
121 ''' Make function raise SkipTest exception if skip_condition is true
121 ''' Make function raise SkipTest exception if skip_condition is true
122
122
123 Parameters
123 Parameters
124 ----------
124 ----------
125 skip_condition : bool or callable.
125 skip_condition : bool or callable.
126 Flag to determine whether to skip test. If the condition is a
126 Flag to determine whether to skip test. If the condition is a
127 callable, it is used at runtime to dynamically make the decision. This
127 callable, it is used at runtime to dynamically make the decision. This
128 is useful for tests that may require costly imports, to delay the cost
128 is useful for tests that may require costly imports, to delay the cost
129 until the test suite is actually executed.
129 until the test suite is actually executed.
130 msg : string
130 msg : string
131 Message to give on raising a SkipTest exception
131 Message to give on raising a SkipTest exception
132
132
133 Returns
133 Returns
134 -------
134 -------
135 decorator : function
135 decorator : function
136 Decorator, which, when applied to a function, causes SkipTest
136 Decorator, which, when applied to a function, causes SkipTest
137 to be raised when the skip_condition was True, and the function
137 to be raised when the skip_condition was True, and the function
138 to be called normally otherwise.
138 to be called normally otherwise.
139
139
140 Notes
140 Notes
141 -----
141 -----
142 You will see from the code that we had to further decorate the
142 You will see from the code that we had to further decorate the
143 decorator with the nose.tools.make_decorator function in order to
143 decorator with the nose.tools.make_decorator function in order to
144 transmit function name, and various other metadata.
144 transmit function name, and various other metadata.
145 '''
145 '''
146
146
147 def skip_decorator(f):
147 def skip_decorator(f):
148 # Local import to avoid a hard nose dependency and only incur the
148 # Local import to avoid a hard nose dependency and only incur the
149 # import time overhead at actual test-time.
149 # import time overhead at actual test-time.
150 import nose
150 import nose
151
151
152 # Allow for both boolean or callable skip conditions.
152 # Allow for both boolean or callable skip conditions.
153 if callable(skip_condition):
153 if callable(skip_condition):
154 skip_val = lambda : skip_condition()
154 skip_val = lambda : skip_condition()
155 else:
155 else:
156 skip_val = lambda : skip_condition
156 skip_val = lambda : skip_condition
157
157
158 def get_msg(func,msg=None):
158 def get_msg(func,msg=None):
159 """Skip message with information about function being skipped."""
159 """Skip message with information about function being skipped."""
160 if msg is None: out = 'Test skipped due to test condition.'
160 if msg is None: out = 'Test skipped due to test condition.'
161 else: out = msg
161 else: out = msg
162 return "Skipping test: %s. %s" % (func.__name__,out)
162 return "Skipping test: %s. %s" % (func.__name__,out)
163
163
164 # We need to define *two* skippers because Python doesn't allow both
164 # We need to define *two* skippers because Python doesn't allow both
165 # return with value and yield inside the same function.
165 # return with value and yield inside the same function.
166 def skipper_func(*args, **kwargs):
166 def skipper_func(*args, **kwargs):
167 """Skipper for normal test functions."""
167 """Skipper for normal test functions."""
168 if skip_val():
168 if skip_val():
169 raise nose.SkipTest(get_msg(f,msg))
169 raise nose.SkipTest(get_msg(f,msg))
170 else:
170 else:
171 return f(*args, **kwargs)
171 return f(*args, **kwargs)
172
172
173 def skipper_gen(*args, **kwargs):
173 def skipper_gen(*args, **kwargs):
174 """Skipper for test generators."""
174 """Skipper for test generators."""
175 if skip_val():
175 if skip_val():
176 raise nose.SkipTest(get_msg(f,msg))
176 raise nose.SkipTest(get_msg(f,msg))
177 else:
177 else:
178 for x in f(*args, **kwargs):
178 for x in f(*args, **kwargs):
179 yield x
179 yield x
180
180
181 # Choose the right skipper to use when building the actual generator.
181 # Choose the right skipper to use when building the actual generator.
182 if nose.util.isgenerator(f):
182 if nose.util.isgenerator(f):
183 skipper = skipper_gen
183 skipper = skipper_gen
184 else:
184 else:
185 skipper = skipper_func
185 skipper = skipper_func
186
186
187 return nose.tools.make_decorator(f)(skipper)
187 return nose.tools.make_decorator(f)(skipper)
188
188
189 return skip_decorator
189 return skip_decorator
190
190
191 # A version with the condition set to true, common case just to attacha message
191 # A version with the condition set to true, common case just to attacha message
192 # to a skip decorator
192 # to a skip decorator
193 def skip(msg=None):
193 def skip(msg=None):
194 """Decorator factory - mark a test function for skipping from test suite.
194 """Decorator factory - mark a test function for skipping from test suite.
195
195
196 :Parameters:
196 :Parameters:
197 msg : string
197 msg : string
198 Optional message to be added.
198 Optional message to be added.
199
199
200 :Returns:
200 :Returns:
201 decorator : function
201 decorator : function
202 Decorator, which, when applied to a function, causes SkipTest
202 Decorator, which, when applied to a function, causes SkipTest
203 to be raised, with the optional message added.
203 to be raised, with the optional message added.
204 """
204 """
205
205
206 return skipif(True,msg)
206 return skipif(True,msg)
207
207
208
208
209 #-----------------------------------------------------------------------------
209 #-----------------------------------------------------------------------------
210 # Utility functions for decorators
210 # Utility functions for decorators
211 def numpy_not_available():
211 def numpy_not_available():
212 """Can numpy be imported? Returns true if numpy does NOT import.
212 """Can numpy be imported? Returns true if numpy does NOT import.
213
213
214 This is used to make a decorator to skip tests that require numpy to be
214 This is used to make a decorator to skip tests that require numpy to be
215 available, but delay the 'import numpy' to test execution time.
215 available, but delay the 'import numpy' to test execution time.
216 """
216 """
217 try:
217 try:
218 import numpy
218 import numpy
219 np_not_avail = False
219 np_not_avail = False
220 except ImportError:
220 except ImportError:
221 np_not_avail = True
221 np_not_avail = True
222
222
223 return np_not_avail
223 return np_not_avail
224
224
225 #-----------------------------------------------------------------------------
225 #-----------------------------------------------------------------------------
226 # Decorators for public use
226 # Decorators for public use
227
227
228 skip_doctest = make_label_dec('skip_doctest',
228 skip_doctest = make_label_dec('skip_doctest',
229 """Decorator - mark a function or method for skipping its doctest.
229 """Decorator - mark a function or method for skipping its doctest.
230
230
231 This decorator allows you to mark a function whose docstring you wish to
231 This decorator allows you to mark a function whose docstring you wish to
232 omit from testing, while preserving the docstring for introspection, help,
232 omit from testing, while preserving the docstring for introspection, help,
233 etc.""")
233 etc.""")
234
234
235 # Decorators to skip certain tests on specific platforms.
235 # Decorators to skip certain tests on specific platforms.
236 skip_win32 = skipif(sys.platform == 'win32',
236 skip_win32 = skipif(sys.platform == 'win32',
237 "This test does not run under Windows")
237 "This test does not run under Windows")
238 skip_linux = skipif(sys.platform == 'linux2',
238 skip_linux = skipif(sys.platform == 'linux2',
239 "This test does not run under Linux")
239 "This test does not run under Linux")
240 skip_osx = skipif(sys.platform == 'darwin',"This test does not run under OS X")
240 skip_osx = skipif(sys.platform == 'darwin',"This test does not run under OS X")
241
241
242
242
243 # Decorators to skip tests if not on specific platforms.
243 # Decorators to skip tests if not on specific platforms.
244 skip_if_not_win32 = skipif(sys.platform != 'win32',
244 skip_if_not_win32 = skipif(sys.platform != 'win32',
245 "This test only runs under Windows")
245 "This test only runs under Windows")
246 skip_if_not_linux = skipif(sys.platform != 'linux2',
246 skip_if_not_linux = skipif(sys.platform != 'linux2',
247 "This test only runs under Linux")
247 "This test only runs under Linux")
248 skip_if_not_osx = skipif(sys.platform != 'darwin',
248 skip_if_not_osx = skipif(sys.platform != 'darwin',
249 "This test only runs under OSX")
249 "This test only runs under OSX")
250
250
251 # Other skip decorators
251 # Other skip decorators
252 skipif_not_numpy = skipif(numpy_not_available,"This test requires numpy")
252 skipif_not_numpy = skipif(numpy_not_available,"This test requires numpy")
253
253
254 skipknownfailure = skip('This test is known to fail')
254 skipknownfailure = skip('This test is known to fail')
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now