1from contextlib import contextmanager 2import linecache 3import os 4import StringIO 5import sys 6import unittest 7import subprocess 8from test import test_support 9from test.script_helper import assert_python_ok 10 11import warning_tests 12 13import warnings as original_warnings 14 15py_warnings = test_support.import_fresh_module('warnings', blocked=['_warnings']) 16c_warnings = test_support.import_fresh_module('warnings', fresh=['_warnings']) 17 18@contextmanager 19def warnings_state(module): 20 """Use a specific warnings implementation in warning_tests.""" 21 global __warningregistry__ 22 for to_clear in (sys, warning_tests): 23 try: 24 to_clear.__warningregistry__.clear() 25 except AttributeError: 26 pass 27 try: 28 __warningregistry__.clear() 29 except NameError: 30 pass 31 original_warnings = warning_tests.warnings 32 original_filters = module.filters 33 try: 34 module.filters = original_filters[:] 35 module.simplefilter("once") 36 warning_tests.warnings = module 37 yield 38 finally: 39 warning_tests.warnings = original_warnings 40 module.filters = original_filters 41 42 43class BaseTest(unittest.TestCase): 44 45 """Basic bookkeeping required for testing.""" 46 47 def setUp(self): 48 # The __warningregistry__ needs to be in a pristine state for tests 49 # to work properly. 50 if '__warningregistry__' in globals(): 51 del globals()['__warningregistry__'] 52 if hasattr(warning_tests, '__warningregistry__'): 53 del warning_tests.__warningregistry__ 54 if hasattr(sys, '__warningregistry__'): 55 del sys.__warningregistry__ 56 # The 'warnings' module must be explicitly set so that the proper 57 # interaction between _warnings and 'warnings' can be controlled. 58 sys.modules['warnings'] = self.module 59 super(BaseTest, self).setUp() 60 61 def tearDown(self): 62 sys.modules['warnings'] = original_warnings 63 super(BaseTest, self).tearDown() 64 65class PublicAPITests(BaseTest): 66 67 """Ensures that the correct values are exposed in the 68 public API. 69 """ 70 71 def test_module_all_attribute(self): 72 self.assertTrue(hasattr(self.module, '__all__')) 73 target_api = ["warn", "warn_explicit", "showwarning", 74 "formatwarning", "filterwarnings", "simplefilter", 75 "resetwarnings", "catch_warnings"] 76 self.assertSetEqual(set(self.module.__all__), 77 set(target_api)) 78 79class CPublicAPITests(PublicAPITests, unittest.TestCase): 80 module = c_warnings 81 82class PyPublicAPITests(PublicAPITests, unittest.TestCase): 83 module = py_warnings 84 85class FilterTests(object): 86 87 """Testing the filtering functionality.""" 88 89 def test_error(self): 90 with original_warnings.catch_warnings(module=self.module) as w: 91 self.module.resetwarnings() 92 self.module.filterwarnings("error", category=UserWarning) 93 self.assertRaises(UserWarning, self.module.warn, 94 "FilterTests.test_error") 95 96 def test_ignore(self): 97 with original_warnings.catch_warnings(record=True, 98 module=self.module) as w: 99 self.module.resetwarnings() 100 self.module.filterwarnings("ignore", category=UserWarning) 101 self.module.warn("FilterTests.test_ignore", UserWarning) 102 self.assertEqual(len(w), 0) 103 104 def test_always(self): 105 with original_warnings.catch_warnings(record=True, 106 module=self.module) as w: 107 self.module.resetwarnings() 108 self.module.filterwarnings("always", category=UserWarning) 109 message = "FilterTests.test_always" 110 def f(): 111 self.module.warn(message, UserWarning) 112 f() 113 self.assertEqual(len(w), 1) 114 self.assertEqual(w[-1].message.args[0], message) 115 f() 116 self.assertEqual(len(w), 2) 117 self.assertEqual(w[-1].message.args[0], message) 118 119 def test_default(self): 120 with original_warnings.catch_warnings(record=True, 121 module=self.module) as w: 122 self.module.resetwarnings() 123 self.module.filterwarnings("default", category=UserWarning) 124 message = UserWarning("FilterTests.test_default") 125 for x in xrange(2): 126 self.module.warn(message, UserWarning) 127 if x == 0: 128 self.assertEqual(w[-1].message, message) 129 del w[:] 130 elif x == 1: 131 self.assertEqual(len(w), 0) 132 else: 133 raise ValueError("loop variant unhandled") 134 135 def test_module(self): 136 with original_warnings.catch_warnings(record=True, 137 module=self.module) as w: 138 self.module.resetwarnings() 139 self.module.filterwarnings("module", category=UserWarning) 140 message = UserWarning("FilterTests.test_module") 141 self.module.warn(message, UserWarning) 142 self.assertEqual(w[-1].message, message) 143 del w[:] 144 self.module.warn(message, UserWarning) 145 self.assertEqual(len(w), 0) 146 147 def test_once(self): 148 with original_warnings.catch_warnings(record=True, 149 module=self.module) as w: 150 self.module.resetwarnings() 151 self.module.filterwarnings("once", category=UserWarning) 152 message = UserWarning("FilterTests.test_once") 153 self.module.warn_explicit(message, UserWarning, "test_warnings.py", 154 42) 155 self.assertEqual(w[-1].message, message) 156 del w[:] 157 self.module.warn_explicit(message, UserWarning, "test_warnings.py", 158 13) 159 self.assertEqual(len(w), 0) 160 self.module.warn_explicit(message, UserWarning, "test_warnings2.py", 161 42) 162 self.assertEqual(len(w), 0) 163 164 def test_inheritance(self): 165 with original_warnings.catch_warnings(module=self.module) as w: 166 self.module.resetwarnings() 167 self.module.filterwarnings("error", category=Warning) 168 self.assertRaises(UserWarning, self.module.warn, 169 "FilterTests.test_inheritance", UserWarning) 170 171 def test_ordering(self): 172 with original_warnings.catch_warnings(record=True, 173 module=self.module) as w: 174 self.module.resetwarnings() 175 self.module.filterwarnings("ignore", category=UserWarning) 176 self.module.filterwarnings("error", category=UserWarning, 177 append=True) 178 del w[:] 179 try: 180 self.module.warn("FilterTests.test_ordering", UserWarning) 181 except UserWarning: 182 self.fail("order handling for actions failed") 183 self.assertEqual(len(w), 0) 184 185 def test_filterwarnings(self): 186 # Test filterwarnings(). 187 # Implicitly also tests resetwarnings(). 188 with original_warnings.catch_warnings(record=True, 189 module=self.module) as w: 190 self.module.filterwarnings("error", "", Warning, "", 0) 191 self.assertRaises(UserWarning, self.module.warn, 'convert to error') 192 193 self.module.resetwarnings() 194 text = 'handle normally' 195 self.module.warn(text) 196 self.assertEqual(str(w[-1].message), text) 197 self.assertTrue(w[-1].category is UserWarning) 198 199 self.module.filterwarnings("ignore", "", Warning, "", 0) 200 text = 'filtered out' 201 self.module.warn(text) 202 self.assertNotEqual(str(w[-1].message), text) 203 204 self.module.resetwarnings() 205 self.module.filterwarnings("error", "hex*", Warning, "", 0) 206 self.assertRaises(UserWarning, self.module.warn, 'hex/oct') 207 text = 'nonmatching text' 208 self.module.warn(text) 209 self.assertEqual(str(w[-1].message), text) 210 self.assertTrue(w[-1].category is UserWarning) 211 212 def test_message_matching(self): 213 with original_warnings.catch_warnings(record=True, 214 module=self.module) as w: 215 self.module.simplefilter("ignore", UserWarning) 216 self.module.filterwarnings("error", "match", UserWarning) 217 self.assertRaises(UserWarning, self.module.warn, "match") 218 self.assertRaises(UserWarning, self.module.warn, "match prefix") 219 self.module.warn("suffix match") 220 self.assertEqual(w, []) 221 self.module.warn("something completely different") 222 self.assertEqual(w, []) 223 224class CFilterTests(BaseTest, FilterTests): 225 module = c_warnings 226 227class PyFilterTests(BaseTest, FilterTests): 228 module = py_warnings 229 230 231class WarnTests(unittest.TestCase): 232 233 """Test warnings.warn() and warnings.warn_explicit().""" 234 235 def test_message(self): 236 with original_warnings.catch_warnings(record=True, 237 module=self.module) as w: 238 self.module.simplefilter("once") 239 for i in range(4): 240 text = 'multi %d' %i # Different text on each call. 241 self.module.warn(text) 242 self.assertEqual(str(w[-1].message), text) 243 self.assertTrue(w[-1].category is UserWarning) 244 245 def test_filename(self): 246 with warnings_state(self.module): 247 with original_warnings.catch_warnings(record=True, 248 module=self.module) as w: 249 warning_tests.inner("spam1") 250 self.assertEqual(os.path.basename(w[-1].filename), 251 "warning_tests.py") 252 warning_tests.outer("spam2") 253 self.assertEqual(os.path.basename(w[-1].filename), 254 "warning_tests.py") 255 256 def test_stacklevel(self): 257 # Test stacklevel argument 258 # make sure all messages are different, so the warning won't be skipped 259 with warnings_state(self.module): 260 with original_warnings.catch_warnings(record=True, 261 module=self.module) as w: 262 warning_tests.inner("spam3", stacklevel=1) 263 self.assertEqual(os.path.basename(w[-1].filename), 264 "warning_tests.py") 265 warning_tests.outer("spam4", stacklevel=1) 266 self.assertEqual(os.path.basename(w[-1].filename), 267 "warning_tests.py") 268 269 warning_tests.inner("spam5", stacklevel=2) 270 self.assertEqual(os.path.basename(w[-1].filename), 271 "test_warnings.py") 272 warning_tests.outer("spam6", stacklevel=2) 273 self.assertEqual(os.path.basename(w[-1].filename), 274 "warning_tests.py") 275 warning_tests.outer("spam6.5", stacklevel=3) 276 self.assertEqual(os.path.basename(w[-1].filename), 277 "test_warnings.py") 278 279 warning_tests.inner("spam7", stacklevel=9999) 280 self.assertEqual(os.path.basename(w[-1].filename), 281 "sys") 282 283 def test_missing_filename_not_main(self): 284 # If __file__ is not specified and __main__ is not the module name, 285 # then __file__ should be set to the module name. 286 filename = warning_tests.__file__ 287 try: 288 del warning_tests.__file__ 289 with warnings_state(self.module): 290 with original_warnings.catch_warnings(record=True, 291 module=self.module) as w: 292 warning_tests.inner("spam8", stacklevel=1) 293 self.assertEqual(w[-1].filename, warning_tests.__name__) 294 finally: 295 warning_tests.__file__ = filename 296 297 @unittest.skipUnless(hasattr(sys, 'argv'), 'test needs sys.argv') 298 def test_missing_filename_main_with_argv(self): 299 # If __file__ is not specified and the caller is __main__ and sys.argv 300 # exists, then use sys.argv[0] as the file. 301 filename = warning_tests.__file__ 302 module_name = warning_tests.__name__ 303 try: 304 del warning_tests.__file__ 305 warning_tests.__name__ = '__main__' 306 with warnings_state(self.module): 307 with original_warnings.catch_warnings(record=True, 308 module=self.module) as w: 309 warning_tests.inner('spam9', stacklevel=1) 310 self.assertEqual(w[-1].filename, sys.argv[0]) 311 finally: 312 warning_tests.__file__ = filename 313 warning_tests.__name__ = module_name 314 315 def test_missing_filename_main_without_argv(self): 316 # If __file__ is not specified, the caller is __main__, and sys.argv 317 # is not set, then '__main__' is the file name. 318 filename = warning_tests.__file__ 319 module_name = warning_tests.__name__ 320 argv = sys.argv 321 try: 322 del warning_tests.__file__ 323 warning_tests.__name__ = '__main__' 324 del sys.argv 325 with warnings_state(self.module): 326 with original_warnings.catch_warnings(record=True, 327 module=self.module) as w: 328 warning_tests.inner('spam10', stacklevel=1) 329 self.assertEqual(w[-1].filename, '__main__') 330 finally: 331 warning_tests.__file__ = filename 332 warning_tests.__name__ = module_name 333 sys.argv = argv 334 335 def test_missing_filename_main_with_argv_empty_string(self): 336 # If __file__ is not specified, the caller is __main__, and sys.argv[0] 337 # is the empty string, then '__main__ is the file name. 338 # Tests issue 2743. 339 file_name = warning_tests.__file__ 340 module_name = warning_tests.__name__ 341 argv = sys.argv 342 try: 343 del warning_tests.__file__ 344 warning_tests.__name__ = '__main__' 345 sys.argv = [''] 346 with warnings_state(self.module): 347 with original_warnings.catch_warnings(record=True, 348 module=self.module) as w: 349 warning_tests.inner('spam11', stacklevel=1) 350 self.assertEqual(w[-1].filename, '__main__') 351 finally: 352 warning_tests.__file__ = file_name 353 warning_tests.__name__ = module_name 354 sys.argv = argv 355 356 def test_warn_explicit_type_errors(self): 357 # warn_explicit() should error out gracefully if it is given objects 358 # of the wrong types. 359 # lineno is expected to be an integer. 360 self.assertRaises(TypeError, self.module.warn_explicit, 361 None, UserWarning, None, None) 362 # Either 'message' needs to be an instance of Warning or 'category' 363 # needs to be a subclass. 364 self.assertRaises(TypeError, self.module.warn_explicit, 365 None, None, None, 1) 366 # 'registry' must be a dict or None. 367 self.assertRaises((TypeError, AttributeError), 368 self.module.warn_explicit, 369 None, Warning, None, 1, registry=42) 370 371 def test_bad_str(self): 372 # issue 6415 373 # Warnings instance with a bad format string for __str__ should not 374 # trigger a bus error. 375 class BadStrWarning(Warning): 376 """Warning with a bad format string for __str__.""" 377 def __str__(self): 378 return ("A bad formatted string %(err)" % 379 {"err" : "there is no %(err)s"}) 380 381 with self.assertRaises(ValueError): 382 self.module.warn(BadStrWarning()) 383 384 385class CWarnTests(BaseTest, WarnTests): 386 module = c_warnings 387 388 # As an early adopter, we sanity check the 389 # test_support.import_fresh_module utility function 390 def test_accelerated(self): 391 self.assertFalse(original_warnings is self.module) 392 self.assertFalse(hasattr(self.module.warn, 'func_code')) 393 394class PyWarnTests(BaseTest, WarnTests): 395 module = py_warnings 396 397 # As an early adopter, we sanity check the 398 # test_support.import_fresh_module utility function 399 def test_pure_python(self): 400 self.assertFalse(original_warnings is self.module) 401 self.assertTrue(hasattr(self.module.warn, 'func_code')) 402 403 404class WCmdLineTests(unittest.TestCase): 405 406 def test_improper_input(self): 407 # Uses the private _setoption() function to test the parsing 408 # of command-line warning arguments 409 with original_warnings.catch_warnings(module=self.module): 410 self.assertRaises(self.module._OptionError, 411 self.module._setoption, '1:2:3:4:5:6') 412 self.assertRaises(self.module._OptionError, 413 self.module._setoption, 'bogus::Warning') 414 self.assertRaises(self.module._OptionError, 415 self.module._setoption, 'ignore:2::4:-5') 416 self.module._setoption('error::Warning::0') 417 self.assertRaises(UserWarning, self.module.warn, 'convert to error') 418 419 def test_improper_option(self): 420 # Same as above, but check that the message is printed out when 421 # the interpreter is executed. This also checks that options are 422 # actually parsed at all. 423 rc, out, err = assert_python_ok("-Wxxx", "-c", "pass") 424 self.assertIn(b"Invalid -W option ignored: invalid action: 'xxx'", err) 425 426 def test_warnings_bootstrap(self): 427 # Check that the warnings module does get loaded when -W<some option> 428 # is used (see issue #10372 for an example of silent bootstrap failure). 429 rc, out, err = assert_python_ok("-Wi", "-c", 430 "import sys; sys.modules['warnings'].warn('foo', RuntimeWarning)") 431 # '-Wi' was observed 432 self.assertFalse(out.strip()) 433 self.assertNotIn(b'RuntimeWarning', err) 434 435class CWCmdLineTests(BaseTest, WCmdLineTests): 436 module = c_warnings 437 438class PyWCmdLineTests(BaseTest, WCmdLineTests): 439 module = py_warnings 440 441 442class _WarningsTests(BaseTest): 443 444 """Tests specific to the _warnings module.""" 445 446 module = c_warnings 447 448 def test_filter(self): 449 # Everything should function even if 'filters' is not in warnings. 450 with original_warnings.catch_warnings(module=self.module) as w: 451 self.module.filterwarnings("error", "", Warning, "", 0) 452 self.assertRaises(UserWarning, self.module.warn, 453 'convert to error') 454 del self.module.filters 455 self.assertRaises(UserWarning, self.module.warn, 456 'convert to error') 457 458 def test_onceregistry(self): 459 # Replacing or removing the onceregistry should be okay. 460 global __warningregistry__ 461 message = UserWarning('onceregistry test') 462 try: 463 original_registry = self.module.onceregistry 464 __warningregistry__ = {} 465 with original_warnings.catch_warnings(record=True, 466 module=self.module) as w: 467 self.module.resetwarnings() 468 self.module.filterwarnings("once", category=UserWarning) 469 self.module.warn_explicit(message, UserWarning, "file", 42) 470 self.assertEqual(w[-1].message, message) 471 del w[:] 472 self.module.warn_explicit(message, UserWarning, "file", 42) 473 self.assertEqual(len(w), 0) 474 # Test the resetting of onceregistry. 475 self.module.onceregistry = {} 476 __warningregistry__ = {} 477 self.module.warn('onceregistry test') 478 self.assertEqual(w[-1].message.args, message.args) 479 # Removal of onceregistry is okay. 480 del w[:] 481 del self.module.onceregistry 482 __warningregistry__ = {} 483 self.module.warn_explicit(message, UserWarning, "file", 42) 484 self.assertEqual(len(w), 0) 485 finally: 486 self.module.onceregistry = original_registry 487 488 def test_default_action(self): 489 # Replacing or removing defaultaction should be okay. 490 message = UserWarning("defaultaction test") 491 original = self.module.defaultaction 492 try: 493 with original_warnings.catch_warnings(record=True, 494 module=self.module) as w: 495 self.module.resetwarnings() 496 registry = {} 497 self.module.warn_explicit(message, UserWarning, "<test>", 42, 498 registry=registry) 499 self.assertEqual(w[-1].message, message) 500 self.assertEqual(len(w), 1) 501 self.assertEqual(len(registry), 1) 502 del w[:] 503 # Test removal. 504 del self.module.defaultaction 505 __warningregistry__ = {} 506 registry = {} 507 self.module.warn_explicit(message, UserWarning, "<test>", 43, 508 registry=registry) 509 self.assertEqual(w[-1].message, message) 510 self.assertEqual(len(w), 1) 511 self.assertEqual(len(registry), 1) 512 del w[:] 513 # Test setting. 514 self.module.defaultaction = "ignore" 515 __warningregistry__ = {} 516 registry = {} 517 self.module.warn_explicit(message, UserWarning, "<test>", 44, 518 registry=registry) 519 self.assertEqual(len(w), 0) 520 finally: 521 self.module.defaultaction = original 522 523 def test_showwarning_missing(self): 524 # Test that showwarning() missing is okay. 525 text = 'del showwarning test' 526 with original_warnings.catch_warnings(module=self.module): 527 self.module.filterwarnings("always", category=UserWarning) 528 del self.module.showwarning 529 with test_support.captured_output('stderr') as stream: 530 self.module.warn(text) 531 result = stream.getvalue() 532 self.assertIn(text, result) 533 534 def test_showwarning_not_callable(self): 535 with original_warnings.catch_warnings(module=self.module): 536 self.module.filterwarnings("always", category=UserWarning) 537 old_showwarning = self.module.showwarning 538 self.module.showwarning = 23 539 try: 540 self.assertRaises(TypeError, self.module.warn, "Warning!") 541 finally: 542 self.module.showwarning = old_showwarning 543 544 def test_show_warning_output(self): 545 # With showarning() missing, make sure that output is okay. 546 text = 'test show_warning' 547 with original_warnings.catch_warnings(module=self.module): 548 self.module.filterwarnings("always", category=UserWarning) 549 del self.module.showwarning 550 with test_support.captured_output('stderr') as stream: 551 warning_tests.inner(text) 552 result = stream.getvalue() 553 self.assertEqual(result.count('\n'), 2, 554 "Too many newlines in %r" % result) 555 first_line, second_line = result.split('\n', 1) 556 expected_file = os.path.splitext(warning_tests.__file__)[0] + '.py' 557 first_line_parts = first_line.rsplit(':', 3) 558 path, line, warning_class, message = first_line_parts 559 line = int(line) 560 self.assertEqual(expected_file, path) 561 self.assertEqual(warning_class, ' ' + UserWarning.__name__) 562 self.assertEqual(message, ' ' + text) 563 expected_line = ' ' + linecache.getline(path, line).strip() + '\n' 564 assert expected_line 565 self.assertEqual(second_line, expected_line) 566 567 def test_filename_none(self): 568 # issue #12467: race condition if a warning is emitted at shutdown 569 globals_dict = globals() 570 oldfile = globals_dict['__file__'] 571 try: 572 with original_warnings.catch_warnings(module=self.module, record=True) as w: 573 self.module.filterwarnings("always", category=UserWarning) 574 globals_dict['__file__'] = None 575 self.module.warn('test', UserWarning) 576 self.assertEqual(len(w), 1) 577 self.assertEqual(w[0].category, UserWarning) 578 self.assertEqual(str(w[0].message), 'test') 579 finally: 580 globals_dict['__file__'] = oldfile 581 582 def test_stderr_none(self): 583 rc, stdout, stderr = assert_python_ok("-c", 584 "import sys; sys.stderr = None; " 585 "import warnings; warnings.simplefilter('always'); " 586 "warnings.warn('Warning!')") 587 self.assertEqual(stdout, b'') 588 self.assertNotIn(b'Warning!', stderr) 589 self.assertNotIn(b'Error', stderr) 590 591 def test_issue31285(self): 592 # warn_explicit() shouldn't raise a SystemError in case the return 593 # value of get_source() has a bad splitlines() method. 594 class BadLoader: 595 def get_source(self, fullname): 596 class BadSource(str): 597 def splitlines(self): 598 return 42 599 return BadSource('spam') 600 601 wmod = self.module 602 with original_warnings.catch_warnings(module=wmod): 603 wmod.filterwarnings('default', category=UserWarning) 604 605 with test_support.captured_stderr() as stderr: 606 wmod.warn_explicit( 607 'foo', UserWarning, 'bar', 1, 608 module_globals={'__loader__': BadLoader(), 609 '__name__': 'foobar'}) 610 self.assertIn('UserWarning: foo', stderr.getvalue()) 611 612 @test_support.cpython_only 613 def test_issue31411(self): 614 # warn_explicit() shouldn't raise a SystemError in case 615 # warnings.onceregistry isn't a dictionary. 616 wmod = self.module 617 with original_warnings.catch_warnings(module=wmod): 618 wmod.filterwarnings('once') 619 with test_support.swap_attr(wmod, 'onceregistry', None): 620 with self.assertRaises(TypeError): 621 wmod.warn_explicit('foo', Warning, 'bar', 1, registry=None) 622 623 624class WarningsDisplayTests(unittest.TestCase): 625 626 """Test the displaying of warnings and the ability to overload functions 627 related to displaying warnings.""" 628 629 def test_formatwarning(self): 630 message = "msg" 631 category = Warning 632 file_name = os.path.splitext(warning_tests.__file__)[0] + '.py' 633 line_num = 3 634 file_line = linecache.getline(file_name, line_num).strip() 635 format = "%s:%s: %s: %s\n %s\n" 636 expect = format % (file_name, line_num, category.__name__, message, 637 file_line) 638 self.assertEqual(expect, self.module.formatwarning(message, 639 category, file_name, line_num)) 640 # Test the 'line' argument. 641 file_line += " for the win!" 642 expect = format % (file_name, line_num, category.__name__, message, 643 file_line) 644 self.assertEqual(expect, self.module.formatwarning(message, 645 category, file_name, line_num, file_line)) 646 647 @test_support.requires_unicode 648 def test_formatwarning_unicode_msg(self): 649 message = u"msg" 650 category = Warning 651 file_name = os.path.splitext(warning_tests.__file__)[0] + '.py' 652 line_num = 3 653 file_line = linecache.getline(file_name, line_num).strip() 654 format = "%s:%s: %s: %s\n %s\n" 655 expect = format % (file_name, line_num, category.__name__, message, 656 file_line) 657 self.assertEqual(expect, self.module.formatwarning(message, 658 category, file_name, line_num)) 659 # Test the 'line' argument. 660 file_line += " for the win!" 661 expect = format % (file_name, line_num, category.__name__, message, 662 file_line) 663 self.assertEqual(expect, self.module.formatwarning(message, 664 category, file_name, line_num, file_line)) 665 666 @test_support.requires_unicode 667 @unittest.skipUnless(test_support.FS_NONASCII, 'need test_support.FS_NONASCII') 668 def test_formatwarning_unicode_msg_nonascii_filename(self): 669 message = u"msg" 670 category = Warning 671 unicode_file_name = test_support.FS_NONASCII + u'.py' 672 file_name = unicode_file_name.encode(sys.getfilesystemencoding()) 673 line_num = 3 674 file_line = 'spam' 675 format = "%s:%s: %s: %s\n %s\n" 676 expect = format % (file_name, line_num, category.__name__, str(message), 677 file_line) 678 self.assertEqual(expect, self.module.formatwarning(message, 679 category, file_name, line_num, file_line)) 680 message = u"\xb5sg" 681 expect = format % (unicode_file_name, line_num, category.__name__, message, 682 file_line) 683 self.assertEqual(expect, self.module.formatwarning(message, 684 category, file_name, line_num, file_line)) 685 686 @test_support.requires_unicode 687 def test_formatwarning_unicode_msg_nonascii_fileline(self): 688 message = u"msg" 689 category = Warning 690 file_name = 'file.py' 691 line_num = 3 692 file_line = 'sp\xe4m' 693 format = "%s:%s: %s: %s\n %s\n" 694 expect = format % (file_name, line_num, category.__name__, str(message), 695 file_line) 696 self.assertEqual(expect, self.module.formatwarning(message, 697 category, file_name, line_num, file_line)) 698 message = u"\xb5sg" 699 expect = format % (file_name, line_num, category.__name__, message, 700 unicode(file_line, 'latin1')) 701 self.assertEqual(expect, self.module.formatwarning(message, 702 category, file_name, line_num, file_line)) 703 704 def test_showwarning(self): 705 file_name = os.path.splitext(warning_tests.__file__)[0] + '.py' 706 line_num = 3 707 expected_file_line = linecache.getline(file_name, line_num).strip() 708 message = 'msg' 709 category = Warning 710 file_object = StringIO.StringIO() 711 expect = self.module.formatwarning(message, category, file_name, 712 line_num) 713 self.module.showwarning(message, category, file_name, line_num, 714 file_object) 715 self.assertEqual(file_object.getvalue(), expect) 716 # Test 'line' argument. 717 expected_file_line += "for the win!" 718 expect = self.module.formatwarning(message, category, file_name, 719 line_num, expected_file_line) 720 file_object = StringIO.StringIO() 721 self.module.showwarning(message, category, file_name, line_num, 722 file_object, expected_file_line) 723 self.assertEqual(expect, file_object.getvalue()) 724 725class CWarningsDisplayTests(BaseTest, WarningsDisplayTests): 726 module = c_warnings 727 728class PyWarningsDisplayTests(BaseTest, WarningsDisplayTests): 729 module = py_warnings 730 731 732class CatchWarningTests(BaseTest): 733 734 """Test catch_warnings().""" 735 736 def test_catch_warnings_restore(self): 737 wmod = self.module 738 orig_filters = wmod.filters 739 orig_showwarning = wmod.showwarning 740 # Ensure both showwarning and filters are restored when recording 741 with wmod.catch_warnings(module=wmod, record=True): 742 wmod.filters = wmod.showwarning = object() 743 self.assertTrue(wmod.filters is orig_filters) 744 self.assertTrue(wmod.showwarning is orig_showwarning) 745 # Same test, but with recording disabled 746 with wmod.catch_warnings(module=wmod, record=False): 747 wmod.filters = wmod.showwarning = object() 748 self.assertTrue(wmod.filters is orig_filters) 749 self.assertTrue(wmod.showwarning is orig_showwarning) 750 751 def test_catch_warnings_recording(self): 752 wmod = self.module 753 # Ensure warnings are recorded when requested 754 with wmod.catch_warnings(module=wmod, record=True) as w: 755 self.assertEqual(w, []) 756 self.assertTrue(type(w) is list) 757 wmod.simplefilter("always") 758 wmod.warn("foo") 759 self.assertEqual(str(w[-1].message), "foo") 760 wmod.warn("bar") 761 self.assertEqual(str(w[-1].message), "bar") 762 self.assertEqual(str(w[0].message), "foo") 763 self.assertEqual(str(w[1].message), "bar") 764 del w[:] 765 self.assertEqual(w, []) 766 # Ensure warnings are not recorded when not requested 767 orig_showwarning = wmod.showwarning 768 with wmod.catch_warnings(module=wmod, record=False) as w: 769 self.assertTrue(w is None) 770 self.assertTrue(wmod.showwarning is orig_showwarning) 771 772 def test_catch_warnings_reentry_guard(self): 773 wmod = self.module 774 # Ensure catch_warnings is protected against incorrect usage 775 x = wmod.catch_warnings(module=wmod, record=True) 776 self.assertRaises(RuntimeError, x.__exit__) 777 with x: 778 self.assertRaises(RuntimeError, x.__enter__) 779 # Same test, but with recording disabled 780 x = wmod.catch_warnings(module=wmod, record=False) 781 self.assertRaises(RuntimeError, x.__exit__) 782 with x: 783 self.assertRaises(RuntimeError, x.__enter__) 784 785 def test_catch_warnings_defaults(self): 786 wmod = self.module 787 orig_filters = wmod.filters 788 orig_showwarning = wmod.showwarning 789 # Ensure default behaviour is not to record warnings 790 with wmod.catch_warnings(module=wmod) as w: 791 self.assertTrue(w is None) 792 self.assertTrue(wmod.showwarning is orig_showwarning) 793 self.assertTrue(wmod.filters is not orig_filters) 794 self.assertTrue(wmod.filters is orig_filters) 795 if wmod is sys.modules['warnings']: 796 # Ensure the default module is this one 797 with wmod.catch_warnings() as w: 798 self.assertTrue(w is None) 799 self.assertTrue(wmod.showwarning is orig_showwarning) 800 self.assertTrue(wmod.filters is not orig_filters) 801 self.assertTrue(wmod.filters is orig_filters) 802 803 def test_check_warnings(self): 804 # Explicit tests for the test_support convenience wrapper 805 wmod = self.module 806 if wmod is not sys.modules['warnings']: 807 self.skipTest('module to test is not loaded warnings module') 808 with test_support.check_warnings(quiet=False) as w: 809 self.assertEqual(w.warnings, []) 810 wmod.simplefilter("always") 811 wmod.warn("foo") 812 self.assertEqual(str(w.message), "foo") 813 wmod.warn("bar") 814 self.assertEqual(str(w.message), "bar") 815 self.assertEqual(str(w.warnings[0].message), "foo") 816 self.assertEqual(str(w.warnings[1].message), "bar") 817 w.reset() 818 self.assertEqual(w.warnings, []) 819 820 with test_support.check_warnings(): 821 # defaults to quiet=True without argument 822 pass 823 with test_support.check_warnings(('foo', UserWarning)): 824 wmod.warn("foo") 825 826 with self.assertRaises(AssertionError): 827 with test_support.check_warnings(('', RuntimeWarning)): 828 # defaults to quiet=False with argument 829 pass 830 with self.assertRaises(AssertionError): 831 with test_support.check_warnings(('foo', RuntimeWarning)): 832 wmod.warn("foo") 833 834 835class CCatchWarningTests(CatchWarningTests): 836 module = c_warnings 837 838class PyCatchWarningTests(CatchWarningTests): 839 module = py_warnings 840 841 842class EnvironmentVariableTests(BaseTest): 843 844 def test_single_warning(self): 845 newenv = os.environ.copy() 846 newenv["PYTHONWARNINGS"] = "ignore::DeprecationWarning" 847 p = subprocess.Popen([sys.executable, 848 "-c", "import sys; sys.stdout.write(str(sys.warnoptions))"], 849 stdout=subprocess.PIPE, env=newenv) 850 self.assertEqual(p.communicate()[0], "['ignore::DeprecationWarning']") 851 self.assertEqual(p.wait(), 0) 852 853 def test_comma_separated_warnings(self): 854 newenv = os.environ.copy() 855 newenv["PYTHONWARNINGS"] = ("ignore::DeprecationWarning," 856 "ignore::UnicodeWarning") 857 p = subprocess.Popen([sys.executable, 858 "-c", "import sys; sys.stdout.write(str(sys.warnoptions))"], 859 stdout=subprocess.PIPE, env=newenv) 860 self.assertEqual(p.communicate()[0], 861 "['ignore::DeprecationWarning', 'ignore::UnicodeWarning']") 862 self.assertEqual(p.wait(), 0) 863 864 def test_envvar_and_command_line(self): 865 newenv = os.environ.copy() 866 newenv["PYTHONWARNINGS"] = "ignore::DeprecationWarning" 867 p = subprocess.Popen([sys.executable, "-W" "ignore::UnicodeWarning", 868 "-c", "import sys; sys.stdout.write(str(sys.warnoptions))"], 869 stdout=subprocess.PIPE, env=newenv) 870 self.assertEqual(p.communicate()[0], 871 "['ignore::UnicodeWarning', 'ignore::DeprecationWarning']") 872 self.assertEqual(p.wait(), 0) 873 874class CEnvironmentVariableTests(EnvironmentVariableTests): 875 module = c_warnings 876 877class PyEnvironmentVariableTests(EnvironmentVariableTests): 878 module = py_warnings 879 880 881def test_main(): 882 py_warnings.onceregistry.clear() 883 c_warnings.onceregistry.clear() 884 test_support.run_unittest(CFilterTests, PyFilterTests, 885 CWarnTests, PyWarnTests, 886 CWCmdLineTests, PyWCmdLineTests, 887 _WarningsTests, 888 CWarningsDisplayTests, PyWarningsDisplayTests, 889 CCatchWarningTests, PyCatchWarningTests, 890 CEnvironmentVariableTests, 891 PyEnvironmentVariableTests 892 ) 893 894 895if __name__ == "__main__": 896 test_main() 897