1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

""" 

Decorators for labeling and modifying behavior of 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 meta-data such as 

function name, setup and teardown functions and so on - see 

``nose.tools`` for more information. 

 

""" 

from __future__ import division, absolute_import, print_function 

 

try: 

# Accessing collections abstract classes from collections 

# has been deprecated since Python 3.3 

import collections.abc as collections_abc 

except ImportError: 

import collections as collections_abc 

 

from .utils import SkipTest, assert_warns, HAS_REFCOUNT 

 

__all__ = ['slow', 'setastest', 'skipif', 'knownfailureif', 'deprecated', 

'parametrize', '_needs_refcount',] 

 

 

def slow(t): 

""" 

Label 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 consists of 

thousands of tests, so even a second is significant). 

 

Parameters 

---------- 

t : callable 

The test to label as slow. 

 

Returns 

------- 

t : callable 

The decorated test `t`. 

 

Examples 

-------- 

The `numpy.testing` module includes ``import decorators as dec``. 

A test can be decorated as slow like this:: 

 

from numpy.testing import * 

 

@dec.slow 

def test_big(self): 

print('Big, slow test') 

 

""" 

 

t.slow = True 

return t 

 

def setastest(tf=True): 

""" 

Signals to nose that this function is or is not a test. 

 

Parameters 

---------- 

tf : bool 

If True, specifies that the decorated callable is a test. 

If False, specifies that the decorated callable is not a test. 

Default is True. 

 

Notes 

----- 

This decorator can't use the nose namespace, because it can be 

called from a non-test module. See also ``istest`` and ``nottest`` in 

``nose.tools``. 

 

Examples 

-------- 

`setastest` can be used in the following way:: 

 

from numpy.testing import dec 

 

@dec.setastest(False) 

def func_with_test_in_name(arg1, arg2): 

pass 

 

""" 

def set_test(t): 

t.__test__ = tf 

return t 

return set_test 

 

def skipif(skip_condition, msg=None): 

""" 

Make function raise SkipTest exception if a 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 

imports, to delay the cost until the test suite is actually executed. 

 

Parameters 

---------- 

skip_condition : bool or callable 

Flag to determine whether to skip the decorated test. 

msg : str, optional 

Message to give on raising a SkipTest 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. 

 

Notes 

----- 

The decorator itself is decorated with the ``nose.tools.make_decorator`` 

function in order to transmit function name, and various other metadata. 

 

""" 

 

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 

 

# Allow for both boolean or callable skip conditions. 

if isinstance(skip_condition, collections_abc.Callable): 

skip_val = lambda: skip_condition() 

else: 

skip_val = lambda: skip_condition 

 

def get_msg(func,msg=None): 

"""Skip message with information about function being skipped.""" 

if msg is None: 

out = 'Test skipped due to test condition' 

else: 

out = msg 

 

return "Skipping test: %s: %s" % (func.__name__, out) 

 

# We need to define *two* skippers because Python doesn't allow both 

# return with value and yield inside the same function. 

def skipper_func(*args, **kwargs): 

"""Skipper for normal test functions.""" 

if skip_val(): 

raise SkipTest(get_msg(f, msg)) 

else: 

return f(*args, **kwargs) 

 

def skipper_gen(*args, **kwargs): 

"""Skipper for test generators.""" 

if skip_val(): 

raise SkipTest(get_msg(f, msg)) 

else: 

for x in f(*args, **kwargs): 

yield x 

 

# Choose the right skipper to use when building the actual decorator. 

if nose.util.isgenerator(f): 

skipper = skipper_gen 

else: 

skipper = skipper_func 

 

return nose.tools.make_decorator(f)(skipper) 

 

return skip_decorator 

 

 

def knownfailureif(fail_condition, msg=None): 

""" 

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 

imports, to delay the cost until the test suite is actually executed. 

 

Parameters 

---------- 

fail_condition : bool or callable 

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 KnownFailureException exception. 

Default is None. 

 

Returns 

------- 

decorator : function 

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 

----- 

The decorator itself is decorated 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 known failure' 

 

# Allow for both boolean or callable known failure conditions. 

if isinstance(fail_condition, collections_abc.Callable): 

fail_val = lambda: fail_condition() 

else: 

fail_val = lambda: fail_condition 

 

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 KnownFailureException 

 

def knownfailer(*args, **kwargs): 

if fail_val(): 

raise KnownFailureException(msg) 

else: 

return f(*args, **kwargs) 

return nose.tools.make_decorator(f)(knownfailer) 

 

return knownfail_decorator 

 

def deprecated(conditional=True): 

""" 

Filter deprecation warnings while running the test suite. 

 

This decorator can be used to filter DeprecationWarning's, to avoid 

printing them during the test suite run, while checking that the test 

actually raises a DeprecationWarning. 

 

Parameters 

---------- 

conditional : bool or callable, optional 

Flag to determine whether to mark test as deprecated or not. If the 

condition is a callable, it is used at runtime to dynamically make the 

decision. Default is True. 

 

Returns 

------- 

decorator : function 

The `deprecated` decorator itself. 

 

Notes 

----- 

.. versionadded:: 1.4.0 

 

""" 

def deprecate_decorator(f): 

# Local import to avoid a hard nose dependency and only incur the 

# import time overhead at actual test-time. 

import nose 

 

def _deprecated_imp(*args, **kwargs): 

# Poor man's replacement for the with statement 

with assert_warns(DeprecationWarning): 

f(*args, **kwargs) 

 

if isinstance(conditional, collections_abc.Callable): 

cond = conditional() 

else: 

cond = conditional 

if cond: 

return nose.tools.make_decorator(f)(_deprecated_imp) 

else: 

return f 

return deprecate_decorator 

 

 

def parametrize(vars, input): 

""" 

Pytest compatibility class. This implements the simplest level of 

pytest.mark.parametrize for use in nose as an aid in making the transition 

to pytest. It achieves that by adding a dummy var parameter and ignoring 

the doc_func parameter of the base class. It does not support variable 

substitution by name, nor does it support nesting or classes. See the 

pytest documentation for usage. 

 

.. versionadded:: 1.14.0 

 

""" 

from .parameterized import parameterized 

 

return parameterized(input) 

 

_needs_refcount = skipif(not HAS_REFCOUNT, "python has no sys.getrefcount")