1 from contextlib
import contextmanager
7 from test
import test_support
11 import warnings
as original_warnings
13 sys
.modules
['_warnings'] = 0
14 del sys
.modules
['warnings']
16 import warnings
as py_warnings
18 del sys
.modules
['_warnings']
19 del sys
.modules
['warnings']
21 import warnings
as c_warnings
23 sys
.modules
['warnings'] = original_warnings
27 def warnings_state(module
):
28 """Use a specific warnings implementation in warning_tests."""
29 global __warningregistry__
30 for to_clear
in (sys
, warning_tests
):
32 to_clear
.__warningregistry
__.clear()
33 except AttributeError:
36 __warningregistry__
.clear()
39 original_warnings
= warning_tests
.warnings
41 warning_tests
.warnings
= module
44 warning_tests
.warnings
= original_warnings
47 class BaseTest(unittest
.TestCase
):
49 """Basic bookkeeping required for testing."""
52 # The __warningregistry__ needs to be in a pristine state for tests
54 if '__warningregistry__' in globals():
55 del globals()['__warningregistry__']
56 if hasattr(warning_tests
, '__warningregistry__'):
57 del warning_tests
.__warningregistry
__
58 if hasattr(sys
, '__warningregistry__'):
59 del sys
.__warningregistry
__
60 # The 'warnings' module must be explicitly set so that the proper
61 # interaction between _warnings and 'warnings' can be controlled.
62 sys
.modules
['warnings'] = self
.module
63 super(BaseTest
, self
).setUp()
66 sys
.modules
['warnings'] = original_warnings
67 super(BaseTest
, self
).tearDown()
70 class FilterTests(object):
72 """Testing the filtering functionality."""
75 with test_support
.catch_warning(self
.module
) as w
:
76 self
.module
.resetwarnings()
77 self
.module
.filterwarnings("error", category
=UserWarning)
78 self
.assertRaises(UserWarning, self
.module
.warn
,
79 "FilterTests.test_error")
81 def test_ignore(self
):
82 with test_support
.catch_warning(module
=self
.module
) as w
:
83 self
.module
.resetwarnings()
84 self
.module
.filterwarnings("ignore", category
=UserWarning)
85 self
.module
.warn("FilterTests.test_ignore", UserWarning)
86 self
.assertEquals(len(w
), 0)
88 def test_always(self
):
89 with test_support
.catch_warning(module
=self
.module
) as w
:
90 self
.module
.resetwarnings()
91 self
.module
.filterwarnings("always", category
=UserWarning)
92 message
= "FilterTests.test_always"
93 self
.module
.warn(message
, UserWarning)
94 self
.assert_(message
, w
.message
)
95 self
.module
.warn(message
, UserWarning)
96 self
.assert_(w
.message
, message
)
98 def test_default(self
):
99 with test_support
.catch_warning(self
.module
) as w
:
100 self
.module
.resetwarnings()
101 self
.module
.filterwarnings("default", category
=UserWarning)
102 message
= UserWarning("FilterTests.test_default")
104 self
.module
.warn(message
, UserWarning)
106 self
.assertEquals(w
.message
, message
)
109 self
.assert_(not len(w
), "unexpected warning: " + str(w
))
111 raise ValueError("loop variant unhandled")
113 def test_module(self
):
114 with test_support
.catch_warning(self
.module
) as w
:
115 self
.module
.resetwarnings()
116 self
.module
.filterwarnings("module", category
=UserWarning)
117 message
= UserWarning("FilterTests.test_module")
118 self
.module
.warn(message
, UserWarning)
119 self
.assertEquals(w
.message
, message
)
121 self
.module
.warn(message
, UserWarning)
122 self
.assert_(not len(w
), "unexpected message: " + str(w
))
125 with test_support
.catch_warning(self
.module
) as w
:
126 self
.module
.resetwarnings()
127 self
.module
.filterwarnings("once", category
=UserWarning)
128 message
= UserWarning("FilterTests.test_once")
129 self
.module
.warn_explicit(message
, UserWarning, "test_warnings.py",
131 self
.assertEquals(w
.message
, message
)
133 self
.module
.warn_explicit(message
, UserWarning, "test_warnings.py",
135 self
.assertEquals(len(w
), 0)
136 self
.module
.warn_explicit(message
, UserWarning, "test_warnings2.py",
138 self
.assertEquals(len(w
), 0)
140 def test_inheritance(self
):
141 with test_support
.catch_warning(self
.module
) as w
:
142 self
.module
.resetwarnings()
143 self
.module
.filterwarnings("error", category
=Warning)
144 self
.assertRaises(UserWarning, self
.module
.warn
,
145 "FilterTests.test_inheritance", UserWarning)
147 def test_ordering(self
):
148 with test_support
.catch_warning(self
.module
) as w
:
149 self
.module
.resetwarnings()
150 self
.module
.filterwarnings("ignore", category
=UserWarning)
151 self
.module
.filterwarnings("error", category
=UserWarning,
155 self
.module
.warn("FilterTests.test_ordering", UserWarning)
157 self
.fail("order handling for actions failed")
158 self
.assertEquals(len(w
), 0)
160 def test_filterwarnings(self
):
161 # Test filterwarnings().
162 # Implicitly also tests resetwarnings().
163 with test_support
.catch_warning(self
.module
) as w
:
164 self
.module
.filterwarnings("error", "", Warning, "", 0)
165 self
.assertRaises(UserWarning, self
.module
.warn
, 'convert to error')
167 self
.module
.resetwarnings()
168 text
= 'handle normally'
169 self
.module
.warn(text
)
170 self
.assertEqual(str(w
.message
), text
)
171 self
.assert_(w
.category
is UserWarning)
173 self
.module
.filterwarnings("ignore", "", Warning, "", 0)
174 text
= 'filtered out'
175 self
.module
.warn(text
)
176 self
.assertNotEqual(str(w
.message
), text
)
178 self
.module
.resetwarnings()
179 self
.module
.filterwarnings("error", "hex*", Warning, "", 0)
180 self
.assertRaises(UserWarning, self
.module
.warn
, 'hex/oct')
181 text
= 'nonmatching text'
182 self
.module
.warn(text
)
183 self
.assertEqual(str(w
.message
), text
)
184 self
.assert_(w
.category
is UserWarning)
186 class CFilterTests(BaseTest
, FilterTests
):
189 class PyFilterTests(BaseTest
, FilterTests
):
193 class WarnTests(unittest
.TestCase
):
195 """Test warnings.warn() and warnings.warn_explicit()."""
197 def test_message(self
):
198 with test_support
.catch_warning(self
.module
) as w
:
200 text
= 'multi %d' %i # Different text on each call.
201 self
.module
.warn(text
)
202 self
.assertEqual(str(w
.message
), text
)
203 self
.assert_(w
.category
is UserWarning)
205 def test_filename(self
):
206 with
warnings_state(self
.module
):
207 with test_support
.catch_warning(self
.module
) as w
:
208 warning_tests
.inner("spam1")
209 self
.assertEqual(os
.path
.basename(w
.filename
), "warning_tests.py")
210 warning_tests
.outer("spam2")
211 self
.assertEqual(os
.path
.basename(w
.filename
), "warning_tests.py")
213 def test_stacklevel(self
):
214 # Test stacklevel argument
215 # make sure all messages are different, so the warning won't be skipped
216 with
warnings_state(self
.module
):
217 with test_support
.catch_warning(self
.module
) as w
:
218 warning_tests
.inner("spam3", stacklevel
=1)
219 self
.assertEqual(os
.path
.basename(w
.filename
), "warning_tests.py")
220 warning_tests
.outer("spam4", stacklevel
=1)
221 self
.assertEqual(os
.path
.basename(w
.filename
), "warning_tests.py")
223 warning_tests
.inner("spam5", stacklevel
=2)
224 self
.assertEqual(os
.path
.basename(w
.filename
), "test_warnings.py")
225 warning_tests
.outer("spam6", stacklevel
=2)
226 self
.assertEqual(os
.path
.basename(w
.filename
), "warning_tests.py")
227 warning_tests
.outer("spam6.5", stacklevel
=3)
228 self
.assertEqual(os
.path
.basename(w
.filename
), "test_warnings.py")
230 warning_tests
.inner("spam7", stacklevel
=9999)
231 self
.assertEqual(os
.path
.basename(w
.filename
), "sys")
233 def test_missing_filename_not_main(self
):
234 # If __file__ is not specified and __main__ is not the module name,
235 # then __file__ should be set to the module name.
236 filename
= warning_tests
.__file
__
238 del warning_tests
.__file
__
239 with
warnings_state(self
.module
):
240 with test_support
.catch_warning(self
.module
) as w
:
241 warning_tests
.inner("spam8", stacklevel
=1)
242 self
.assertEqual(w
.filename
, warning_tests
.__name
__)
244 warning_tests
.__file
__ = filename
246 def test_missing_filename_main_with_argv(self
):
247 # If __file__ is not specified and the caller is __main__ and sys.argv
248 # exists, then use sys.argv[0] as the file.
249 if not hasattr(sys
, 'argv'):
251 filename
= warning_tests
.__file
__
252 module_name
= warning_tests
.__name
__
254 del warning_tests
.__file
__
255 warning_tests
.__name
__ = '__main__'
256 with
warnings_state(self
.module
):
257 with test_support
.catch_warning(self
.module
) as w
:
258 warning_tests
.inner('spam9', stacklevel
=1)
259 self
.assertEqual(w
.filename
, sys
.argv
[0])
261 warning_tests
.__file
__ = filename
262 warning_tests
.__name
__ = module_name
264 def test_missing_filename_main_without_argv(self
):
265 # If __file__ is not specified, the caller is __main__, and sys.argv
266 # is not set, then '__main__' is the file name.
267 filename
= warning_tests
.__file
__
268 module_name
= warning_tests
.__name
__
271 del warning_tests
.__file
__
272 warning_tests
.__name
__ = '__main__'
274 with
warnings_state(self
.module
):
275 with test_support
.catch_warning(self
.module
) as w
:
276 warning_tests
.inner('spam10', stacklevel
=1)
277 self
.assertEqual(w
.filename
, '__main__')
279 warning_tests
.__file
__ = filename
280 warning_tests
.__name
__ = module_name
283 def test_missing_filename_main_with_argv_empty_string(self
):
284 # If __file__ is not specified, the caller is __main__, and sys.argv[0]
285 # is the empty string, then '__main__ is the file name.
287 file_name
= warning_tests
.__file
__
288 module_name
= warning_tests
.__name
__
291 del warning_tests
.__file
__
292 warning_tests
.__name
__ = '__main__'
294 with
warnings_state(self
.module
):
295 with test_support
.catch_warning(self
.module
) as w
:
296 warning_tests
.inner('spam11', stacklevel
=1)
297 self
.assertEqual(w
.filename
, '__main__')
299 warning_tests
.__file
__ = file_name
300 warning_tests
.__name
__ = module_name
303 def test_warn_explicit_type_errors(self
):
304 # warn_explicit() shoud error out gracefully if it is given objects
305 # of the wrong types.
306 # lineno is expected to be an integer.
307 self
.assertRaises(TypeError, self
.module
.warn_explicit
,
308 None, UserWarning, None, None)
309 # Either 'message' needs to be an instance of Warning or 'category'
310 # needs to be a subclass.
311 self
.assertRaises(TypeError, self
.module
.warn_explicit
,
313 # 'registry' must be a dict or None.
314 self
.assertRaises((TypeError, AttributeError),
315 self
.module
.warn_explicit
,
316 None, Warning, None, 1, registry
=42)
319 class CWarnTests(BaseTest
, WarnTests
):
322 class PyWarnTests(BaseTest
, WarnTests
):
326 class WCmdLineTests(unittest
.TestCase
):
328 def test_improper_input(self
):
329 # Uses the private _setoption() function to test the parsing
330 # of command-line warning arguments
331 with test_support
.catch_warning(self
.module
):
332 self
.assertRaises(self
.module
._OptionError
,
333 self
.module
._setoption
, '1:2:3:4:5:6')
334 self
.assertRaises(self
.module
._OptionError
,
335 self
.module
._setoption
, 'bogus::Warning')
336 self
.assertRaises(self
.module
._OptionError
,
337 self
.module
._setoption
, 'ignore:2::4:-5')
338 self
.module
._setoption
('error::Warning::0')
339 self
.assertRaises(UserWarning, self
.module
.warn
, 'convert to error')
341 class CWCmdLineTests(BaseTest
, WCmdLineTests
):
344 class PyWCmdLineTests(BaseTest
, WCmdLineTests
):
348 class _WarningsTests(BaseTest
):
350 """Tests specific to the _warnings module."""
354 def test_filter(self
):
355 # Everything should function even if 'filters' is not in warnings.
356 with test_support
.catch_warning(self
.module
) as w
:
357 self
.module
.filterwarnings("error", "", Warning, "", 0)
358 self
.assertRaises(UserWarning, self
.module
.warn
,
360 del self
.module
.filters
361 self
.assertRaises(UserWarning, self
.module
.warn
,
364 def test_onceregistry(self
):
365 # Replacing or removing the onceregistry should be okay.
366 global __warningregistry__
367 message
= UserWarning('onceregistry test')
369 original_registry
= self
.module
.onceregistry
370 __warningregistry__
= {}
371 with test_support
.catch_warning(self
.module
) as w
:
372 self
.module
.resetwarnings()
373 self
.module
.filterwarnings("once", category
=UserWarning)
374 self
.module
.warn_explicit(message
, UserWarning, "file", 42)
375 self
.failUnlessEqual(w
.message
, message
)
377 self
.module
.warn_explicit(message
, UserWarning, "file", 42)
378 self
.assertEquals(len(w
), 0)
379 # Test the resetting of onceregistry.
380 self
.module
.onceregistry
= {}
381 __warningregistry__
= {}
382 self
.module
.warn('onceregistry test')
383 self
.failUnlessEqual(w
.message
.args
, message
.args
)
384 # Removal of onceregistry is okay.
386 del self
.module
.onceregistry
387 __warningregistry__
= {}
388 self
.module
.warn_explicit(message
, UserWarning, "file", 42)
389 self
.assertEquals(len(w
), 0)
391 self
.module
.onceregistry
= original_registry
393 def test_showwarning_missing(self
):
394 # Test that showwarning() missing is okay.
395 text
= 'del showwarning test'
396 with test_support
.catch_warning(self
.module
):
397 self
.module
.filterwarnings("always", category
=UserWarning)
398 del self
.module
.showwarning
399 with test_support
.captured_output('stderr') as stream
:
400 self
.module
.warn(text
)
401 result
= stream
.getvalue()
402 self
.failUnless(text
in result
)
404 def test_showwarning_not_callable(self
):
405 self
.module
.filterwarnings("always", category
=UserWarning)
406 old_showwarning
= self
.module
.showwarning
407 self
.module
.showwarning
= 23
409 self
.assertRaises(TypeError, self
.module
.warn
, "Warning!")
411 self
.module
.showwarning
= old_showwarning
412 self
.module
.resetwarnings()
414 def test_show_warning_output(self
):
415 # With showarning() missing, make sure that output is okay.
416 text
= 'test show_warning'
417 with test_support
.catch_warning(self
.module
):
418 self
.module
.filterwarnings("always", category
=UserWarning)
419 del self
.module
.showwarning
420 with test_support
.captured_output('stderr') as stream
:
421 warning_tests
.inner(text
)
422 result
= stream
.getvalue()
423 self
.failUnlessEqual(result
.count('\n'), 2,
424 "Too many newlines in %r" % result
)
425 first_line
, second_line
= result
.split('\n', 1)
426 expected_file
= os
.path
.splitext(warning_tests
.__file
__)[0] + '.py'
427 first_line_parts
= first_line
.rsplit(':', 3)
428 path
, line
, warning_class
, message
= first_line_parts
430 self
.failUnlessEqual(expected_file
, path
)
431 self
.failUnlessEqual(warning_class
, ' ' + UserWarning.__name
__)
432 self
.failUnlessEqual(message
, ' ' + text
)
433 expected_line
= ' ' + linecache
.getline(path
, line
).strip() + '\n'
435 self
.failUnlessEqual(second_line
, expected_line
)
438 class WarningsDisplayTests(unittest
.TestCase
):
440 """Test the displaying of warnings and the ability to overload functions
441 related to displaying warnings."""
443 def test_formatwarning(self
):
446 file_name
= os
.path
.splitext(warning_tests
.__file
__)[0] + '.py'
448 file_line
= linecache
.getline(file_name
, line_num
).strip()
449 format
= "%s:%s: %s: %s\n %s\n"
450 expect
= format
% (file_name
, line_num
, category
.__name
__, message
,
452 self
.failUnlessEqual(expect
, self
.module
.formatwarning(message
,
453 category
, file_name
, line_num
))
454 # Test the 'line' argument.
455 file_line
+= " for the win!"
456 expect
= format
% (file_name
, line_num
, category
.__name
__, message
,
458 self
.failUnlessEqual(expect
, self
.module
.formatwarning(message
,
459 category
, file_name
, line_num
, file_line
))
461 def test_showwarning(self
):
462 file_name
= os
.path
.splitext(warning_tests
.__file
__)[0] + '.py'
464 expected_file_line
= linecache
.getline(file_name
, line_num
).strip()
467 file_object
= StringIO
.StringIO()
468 expect
= self
.module
.formatwarning(message
, category
, file_name
,
470 self
.module
.showwarning(message
, category
, file_name
, line_num
,
472 self
.failUnlessEqual(file_object
.getvalue(), expect
)
473 # Test 'line' argument.
474 expected_file_line
+= "for the win!"
475 expect
= self
.module
.formatwarning(message
, category
, file_name
,
476 line_num
, expected_file_line
)
477 file_object
= StringIO
.StringIO()
478 self
.module
.showwarning(message
, category
, file_name
, line_num
,
479 file_object
, expected_file_line
)
480 self
.failUnlessEqual(expect
, file_object
.getvalue())
482 class CWarningsDisplayTests(BaseTest
, WarningsDisplayTests
):
485 class PyWarningsDisplayTests(BaseTest
, WarningsDisplayTests
):
490 class CatchWarningTests(BaseTest
):
492 """Test catch_warnings()."""
494 def test_catch_warnings_restore(self
):
496 orig_filters
= wmod
.filters
497 orig_showwarning
= wmod
.showwarning
498 with wmod
.catch_warnings(record
=True, module
=wmod
):
499 wmod
.filters
= wmod
.showwarning
= object()
500 self
.assert_(wmod
.filters
is orig_filters
)
501 self
.assert_(wmod
.showwarning
is orig_showwarning
)
502 with wmod
.catch_warnings(module
=wmod
, record
=False):
503 wmod
.filters
= wmod
.showwarning
= object()
504 self
.assert_(wmod
.filters
is orig_filters
)
505 self
.assert_(wmod
.showwarning
is orig_showwarning
)
507 def test_catch_warnings_recording(self
):
509 with wmod
.catch_warnings(module
=wmod
, record
=True) as w
:
510 self
.assertEqual(w
, [])
511 self
.assertRaises(AttributeError, getattr, w
, 'message')
512 wmod
.simplefilter("always")
514 self
.assertEqual(str(w
.message
), "foo")
516 self
.assertEqual(str(w
.message
), "bar")
517 self
.assertEqual(str(w
[0].message
), "foo")
518 self
.assertEqual(str(w
[1].message
), "bar")
520 self
.assertEqual(w
, [])
521 orig_showwarning
= wmod
.showwarning
522 with wmod
.catch_warnings(module
=wmod
, record
=False) as w
:
523 self
.assert_(w
is None)
524 self
.assert_(wmod
.showwarning
is orig_showwarning
)
526 class CCatchWarningTests(CatchWarningTests
):
529 class PyCatchWarningTests(CatchWarningTests
):
533 class ShowwarningDeprecationTests(BaseTest
):
535 """Test the deprecation of the old warnings.showwarning() API works."""
538 def bad_showwarning(message
, category
, filename
, lineno
, file=None):
542 def ok_showwarning(*args
):
545 def test_deprecation(self
):
546 # message, category, filename, lineno[, file[, line]]
547 args
= ("message", UserWarning, "file name", 42)
548 with test_support
.catch_warning(module
=self
.module
):
549 self
.module
.filterwarnings("error", category
=DeprecationWarning)
550 self
.module
.showwarning
= self
.bad_showwarning
551 self
.assertRaises(DeprecationWarning, self
.module
.warn_explicit
,
553 self
.module
.showwarning
= self
.ok_showwarning
555 self
.module
.warn_explicit(*args
)
556 except DeprecationWarning as exc
:
557 self
.fail('showwarning(*args) should not trigger a '
558 'DeprecationWarning')
560 class CShowwarningDeprecationTests(ShowwarningDeprecationTests
):
564 class PyShowwarningDeprecationTests(ShowwarningDeprecationTests
):
569 py_warnings
.onceregistry
.clear()
570 c_warnings
.onceregistry
.clear()
571 test_support
.run_unittest(CFilterTests
, PyFilterTests
,
572 CWarnTests
, PyWarnTests
,
573 CWCmdLineTests
, PyWCmdLineTests
,
575 CWarningsDisplayTests
, PyWarningsDisplayTests
,
576 CCatchWarningTests
, PyCatchWarningTests
,
577 CShowwarningDeprecationTests
,
578 PyShowwarningDeprecationTests
,
582 if __name__
== "__main__":