1from contextlib import contextmanager 2import linecache 3import os 4from io import StringIO 5import re 6import sys 7import textwrap 8import unittest 9from test import support 10from test.support import import_helper 11from test.support import os_helper 12from test.support import warnings_helper 13from test.support.script_helper import assert_python_ok, assert_python_failure 14 15from test.test_warnings.data import stacklevel as warning_tests 16 17import warnings as original_warnings 18 19 20py_warnings = import_helper.import_fresh_module('warnings', 21 blocked=['_warnings']) 22c_warnings = import_helper.import_fresh_module('warnings', 23 fresh=['_warnings']) 24 25Py_DEBUG = hasattr(sys, 'gettotalrefcount') 26 27@contextmanager 28def warnings_state(module): 29 """Use a specific warnings implementation in warning_tests.""" 30 global __warningregistry__ 31 for to_clear in (sys, warning_tests): 32 try: 33 to_clear.__warningregistry__.clear() 34 except AttributeError: 35 pass 36 try: 37 __warningregistry__.clear() 38 except NameError: 39 pass 40 original_warnings = warning_tests.warnings 41 original_filters = module.filters 42 try: 43 module.filters = original_filters[:] 44 module.simplefilter("once") 45 warning_tests.warnings = module 46 yield 47 finally: 48 warning_tests.warnings = original_warnings 49 module.filters = original_filters 50 51 52class TestWarning(Warning): 53 pass 54 55 56class BaseTest: 57 58 """Basic bookkeeping required for testing.""" 59 60 def setUp(self): 61 self.old_unittest_module = unittest.case.warnings 62 # The __warningregistry__ needs to be in a pristine state for tests 63 # to work properly. 64 if '__warningregistry__' in globals(): 65 del globals()['__warningregistry__'] 66 if hasattr(warning_tests, '__warningregistry__'): 67 del warning_tests.__warningregistry__ 68 if hasattr(sys, '__warningregistry__'): 69 del sys.__warningregistry__ 70 # The 'warnings' module must be explicitly set so that the proper 71 # interaction between _warnings and 'warnings' can be controlled. 72 sys.modules['warnings'] = self.module 73 # Ensure that unittest.TestCase.assertWarns() uses the same warnings 74 # module than warnings.catch_warnings(). Otherwise, 75 # warnings.catch_warnings() will be unable to remove the added filter. 76 unittest.case.warnings = self.module 77 super(BaseTest, self).setUp() 78 79 def tearDown(self): 80 sys.modules['warnings'] = original_warnings 81 unittest.case.warnings = self.old_unittest_module 82 super(BaseTest, self).tearDown() 83 84class PublicAPITests(BaseTest): 85 86 """Ensures that the correct values are exposed in the 87 public API. 88 """ 89 90 def test_module_all_attribute(self): 91 self.assertTrue(hasattr(self.module, '__all__')) 92 target_api = ["warn", "warn_explicit", "showwarning", 93 "formatwarning", "filterwarnings", "simplefilter", 94 "resetwarnings", "catch_warnings"] 95 self.assertSetEqual(set(self.module.__all__), 96 set(target_api)) 97 98class CPublicAPITests(PublicAPITests, unittest.TestCase): 99 module = c_warnings 100 101class PyPublicAPITests(PublicAPITests, unittest.TestCase): 102 module = py_warnings 103 104class FilterTests(BaseTest): 105 106 """Testing the filtering functionality.""" 107 108 def test_error(self): 109 with original_warnings.catch_warnings(module=self.module) as w: 110 self.module.resetwarnings() 111 self.module.filterwarnings("error", category=UserWarning) 112 self.assertRaises(UserWarning, self.module.warn, 113 "FilterTests.test_error") 114 115 def test_error_after_default(self): 116 with original_warnings.catch_warnings(module=self.module) as w: 117 self.module.resetwarnings() 118 message = "FilterTests.test_ignore_after_default" 119 def f(): 120 self.module.warn(message, UserWarning) 121 122 with support.captured_stderr() as stderr: 123 f() 124 stderr = stderr.getvalue() 125 self.assertIn("UserWarning: FilterTests.test_ignore_after_default", 126 stderr) 127 self.assertIn("self.module.warn(message, UserWarning)", 128 stderr) 129 130 self.module.filterwarnings("error", category=UserWarning) 131 self.assertRaises(UserWarning, f) 132 133 def test_ignore(self): 134 with original_warnings.catch_warnings(record=True, 135 module=self.module) as w: 136 self.module.resetwarnings() 137 self.module.filterwarnings("ignore", category=UserWarning) 138 self.module.warn("FilterTests.test_ignore", UserWarning) 139 self.assertEqual(len(w), 0) 140 self.assertEqual(list(__warningregistry__), ['version']) 141 142 def test_ignore_after_default(self): 143 with original_warnings.catch_warnings(record=True, 144 module=self.module) as w: 145 self.module.resetwarnings() 146 message = "FilterTests.test_ignore_after_default" 147 def f(): 148 self.module.warn(message, UserWarning) 149 f() 150 self.module.filterwarnings("ignore", category=UserWarning) 151 f() 152 f() 153 self.assertEqual(len(w), 1) 154 155 def test_always(self): 156 with original_warnings.catch_warnings(record=True, 157 module=self.module) as w: 158 self.module.resetwarnings() 159 self.module.filterwarnings("always", category=UserWarning) 160 message = "FilterTests.test_always" 161 def f(): 162 self.module.warn(message, UserWarning) 163 f() 164 self.assertEqual(len(w), 1) 165 self.assertEqual(w[-1].message.args[0], message) 166 f() 167 self.assertEqual(len(w), 2) 168 self.assertEqual(w[-1].message.args[0], message) 169 170 def test_always_after_default(self): 171 with original_warnings.catch_warnings(record=True, 172 module=self.module) as w: 173 self.module.resetwarnings() 174 message = "FilterTests.test_always_after_ignore" 175 def f(): 176 self.module.warn(message, UserWarning) 177 f() 178 self.assertEqual(len(w), 1) 179 self.assertEqual(w[-1].message.args[0], message) 180 f() 181 self.assertEqual(len(w), 1) 182 self.module.filterwarnings("always", category=UserWarning) 183 f() 184 self.assertEqual(len(w), 2) 185 self.assertEqual(w[-1].message.args[0], message) 186 f() 187 self.assertEqual(len(w), 3) 188 self.assertEqual(w[-1].message.args[0], message) 189 190 def test_default(self): 191 with original_warnings.catch_warnings(record=True, 192 module=self.module) as w: 193 self.module.resetwarnings() 194 self.module.filterwarnings("default", category=UserWarning) 195 message = UserWarning("FilterTests.test_default") 196 for x in range(2): 197 self.module.warn(message, UserWarning) 198 if x == 0: 199 self.assertEqual(w[-1].message, message) 200 del w[:] 201 elif x == 1: 202 self.assertEqual(len(w), 0) 203 else: 204 raise ValueError("loop variant unhandled") 205 206 def test_module(self): 207 with original_warnings.catch_warnings(record=True, 208 module=self.module) as w: 209 self.module.resetwarnings() 210 self.module.filterwarnings("module", category=UserWarning) 211 message = UserWarning("FilterTests.test_module") 212 self.module.warn(message, UserWarning) 213 self.assertEqual(w[-1].message, message) 214 del w[:] 215 self.module.warn(message, UserWarning) 216 self.assertEqual(len(w), 0) 217 218 def test_once(self): 219 with original_warnings.catch_warnings(record=True, 220 module=self.module) as w: 221 self.module.resetwarnings() 222 self.module.filterwarnings("once", category=UserWarning) 223 message = UserWarning("FilterTests.test_once") 224 self.module.warn_explicit(message, UserWarning, "__init__.py", 225 42) 226 self.assertEqual(w[-1].message, message) 227 del w[:] 228 self.module.warn_explicit(message, UserWarning, "__init__.py", 229 13) 230 self.assertEqual(len(w), 0) 231 self.module.warn_explicit(message, UserWarning, "test_warnings2.py", 232 42) 233 self.assertEqual(len(w), 0) 234 235 def test_module_globals(self): 236 with original_warnings.catch_warnings(record=True, 237 module=self.module) as w: 238 self.module.simplefilter("always", UserWarning) 239 240 # bpo-33509: module_globals=None must not crash 241 self.module.warn_explicit('msg', UserWarning, "filename", 42, 242 module_globals=None) 243 self.assertEqual(len(w), 1) 244 245 # Invalid module_globals type 246 with self.assertRaises(TypeError): 247 self.module.warn_explicit('msg', UserWarning, "filename", 42, 248 module_globals=True) 249 self.assertEqual(len(w), 1) 250 251 # Empty module_globals 252 self.module.warn_explicit('msg', UserWarning, "filename", 42, 253 module_globals={}) 254 self.assertEqual(len(w), 2) 255 256 def test_inheritance(self): 257 with original_warnings.catch_warnings(module=self.module) as w: 258 self.module.resetwarnings() 259 self.module.filterwarnings("error", category=Warning) 260 self.assertRaises(UserWarning, self.module.warn, 261 "FilterTests.test_inheritance", UserWarning) 262 263 def test_ordering(self): 264 with original_warnings.catch_warnings(record=True, 265 module=self.module) as w: 266 self.module.resetwarnings() 267 self.module.filterwarnings("ignore", category=UserWarning) 268 self.module.filterwarnings("error", category=UserWarning, 269 append=True) 270 del w[:] 271 try: 272 self.module.warn("FilterTests.test_ordering", UserWarning) 273 except UserWarning: 274 self.fail("order handling for actions failed") 275 self.assertEqual(len(w), 0) 276 277 def test_filterwarnings(self): 278 # Test filterwarnings(). 279 # Implicitly also tests resetwarnings(). 280 with original_warnings.catch_warnings(record=True, 281 module=self.module) as w: 282 self.module.filterwarnings("error", "", Warning, "", 0) 283 self.assertRaises(UserWarning, self.module.warn, 'convert to error') 284 285 self.module.resetwarnings() 286 text = 'handle normally' 287 self.module.warn(text) 288 self.assertEqual(str(w[-1].message), text) 289 self.assertIs(w[-1].category, UserWarning) 290 291 self.module.filterwarnings("ignore", "", Warning, "", 0) 292 text = 'filtered out' 293 self.module.warn(text) 294 self.assertNotEqual(str(w[-1].message), text) 295 296 self.module.resetwarnings() 297 self.module.filterwarnings("error", "hex*", Warning, "", 0) 298 self.assertRaises(UserWarning, self.module.warn, 'hex/oct') 299 text = 'nonmatching text' 300 self.module.warn(text) 301 self.assertEqual(str(w[-1].message), text) 302 self.assertIs(w[-1].category, UserWarning) 303 304 def test_message_matching(self): 305 with original_warnings.catch_warnings(record=True, 306 module=self.module) as w: 307 self.module.simplefilter("ignore", UserWarning) 308 self.module.filterwarnings("error", "match", UserWarning) 309 self.assertRaises(UserWarning, self.module.warn, "match") 310 self.assertRaises(UserWarning, self.module.warn, "match prefix") 311 self.module.warn("suffix match") 312 self.assertEqual(w, []) 313 self.module.warn("something completely different") 314 self.assertEqual(w, []) 315 316 def test_mutate_filter_list(self): 317 class X: 318 def match(self, a): 319 L[:] = [] 320 321 L = [("default",X(),UserWarning,X(),0) for i in range(2)] 322 with original_warnings.catch_warnings(record=True, 323 module=self.module) as w: 324 self.module.filters = L 325 self.module.warn_explicit(UserWarning("b"), None, "f.py", 42) 326 self.assertEqual(str(w[-1].message), "b") 327 328 def test_filterwarnings_duplicate_filters(self): 329 with original_warnings.catch_warnings(module=self.module): 330 self.module.resetwarnings() 331 self.module.filterwarnings("error", category=UserWarning) 332 self.assertEqual(len(self.module.filters), 1) 333 self.module.filterwarnings("ignore", category=UserWarning) 334 self.module.filterwarnings("error", category=UserWarning) 335 self.assertEqual( 336 len(self.module.filters), 2, 337 "filterwarnings inserted duplicate filter" 338 ) 339 self.assertEqual( 340 self.module.filters[0][0], "error", 341 "filterwarnings did not promote filter to " 342 "the beginning of list" 343 ) 344 345 def test_simplefilter_duplicate_filters(self): 346 with original_warnings.catch_warnings(module=self.module): 347 self.module.resetwarnings() 348 self.module.simplefilter("error", category=UserWarning) 349 self.assertEqual(len(self.module.filters), 1) 350 self.module.simplefilter("ignore", category=UserWarning) 351 self.module.simplefilter("error", category=UserWarning) 352 self.assertEqual( 353 len(self.module.filters), 2, 354 "simplefilter inserted duplicate filter" 355 ) 356 self.assertEqual( 357 self.module.filters[0][0], "error", 358 "simplefilter did not promote filter to the beginning of list" 359 ) 360 361 def test_append_duplicate(self): 362 with original_warnings.catch_warnings(module=self.module, 363 record=True) as w: 364 self.module.resetwarnings() 365 self.module.simplefilter("ignore") 366 self.module.simplefilter("error", append=True) 367 self.module.simplefilter("ignore", append=True) 368 self.module.warn("test_append_duplicate", category=UserWarning) 369 self.assertEqual(len(self.module.filters), 2, 370 "simplefilter inserted duplicate filter" 371 ) 372 self.assertEqual(len(w), 0, 373 "appended duplicate changed order of filters" 374 ) 375 376 def test_catchwarnings_with_simplefilter_ignore(self): 377 with original_warnings.catch_warnings(module=self.module): 378 self.module.resetwarnings() 379 self.module.simplefilter("error") 380 with self.module.catch_warnings( 381 module=self.module, action="ignore" 382 ): 383 self.module.warn("This will be ignored") 384 385 def test_catchwarnings_with_simplefilter_error(self): 386 with original_warnings.catch_warnings(module=self.module): 387 self.module.resetwarnings() 388 with self.module.catch_warnings( 389 module=self.module, action="error", category=FutureWarning 390 ): 391 self.module.warn("Other types of warnings are not errors") 392 self.assertRaises(FutureWarning, 393 self.module.warn, FutureWarning("msg")) 394 395class CFilterTests(FilterTests, unittest.TestCase): 396 module = c_warnings 397 398class PyFilterTests(FilterTests, unittest.TestCase): 399 module = py_warnings 400 401 402class WarnTests(BaseTest): 403 404 """Test warnings.warn() and warnings.warn_explicit().""" 405 406 def test_message(self): 407 with original_warnings.catch_warnings(record=True, 408 module=self.module) as w: 409 self.module.simplefilter("once") 410 for i in range(4): 411 text = 'multi %d' %i # Different text on each call. 412 self.module.warn(text) 413 self.assertEqual(str(w[-1].message), text) 414 self.assertIs(w[-1].category, UserWarning) 415 416 # Issue 3639 417 def test_warn_nonstandard_types(self): 418 # warn() should handle non-standard types without issue. 419 for ob in (Warning, None, 42): 420 with original_warnings.catch_warnings(record=True, 421 module=self.module) as w: 422 self.module.simplefilter("once") 423 self.module.warn(ob) 424 # Don't directly compare objects since 425 # ``Warning() != Warning()``. 426 self.assertEqual(str(w[-1].message), str(UserWarning(ob))) 427 428 def test_filename(self): 429 with warnings_state(self.module): 430 with original_warnings.catch_warnings(record=True, 431 module=self.module) as w: 432 warning_tests.inner("spam1") 433 self.assertEqual(os.path.basename(w[-1].filename), 434 "stacklevel.py") 435 warning_tests.outer("spam2") 436 self.assertEqual(os.path.basename(w[-1].filename), 437 "stacklevel.py") 438 439 def test_stacklevel(self): 440 # Test stacklevel argument 441 # make sure all messages are different, so the warning won't be skipped 442 with warnings_state(self.module): 443 with original_warnings.catch_warnings(record=True, 444 module=self.module) as w: 445 warning_tests.inner("spam3", stacklevel=1) 446 self.assertEqual(os.path.basename(w[-1].filename), 447 "stacklevel.py") 448 warning_tests.outer("spam4", stacklevel=1) 449 self.assertEqual(os.path.basename(w[-1].filename), 450 "stacklevel.py") 451 452 warning_tests.inner("spam5", stacklevel=2) 453 self.assertEqual(os.path.basename(w[-1].filename), 454 "__init__.py") 455 warning_tests.outer("spam6", stacklevel=2) 456 self.assertEqual(os.path.basename(w[-1].filename), 457 "stacklevel.py") 458 warning_tests.outer("spam6.5", stacklevel=3) 459 self.assertEqual(os.path.basename(w[-1].filename), 460 "__init__.py") 461 462 warning_tests.inner("spam7", stacklevel=9999) 463 self.assertEqual(os.path.basename(w[-1].filename), 464 "sys") 465 466 def test_stacklevel_import(self): 467 # Issue #24305: With stacklevel=2, module-level warnings should work. 468 import_helper.unload('test.test_warnings.data.import_warning') 469 with warnings_state(self.module): 470 with original_warnings.catch_warnings(record=True, 471 module=self.module) as w: 472 self.module.simplefilter('always') 473 import test.test_warnings.data.import_warning 474 self.assertEqual(len(w), 1) 475 self.assertEqual(w[0].filename, __file__) 476 477 def test_exec_filename(self): 478 filename = "<warnings-test>" 479 codeobj = compile(("import warnings\n" 480 "warnings.warn('hello', UserWarning)"), 481 filename, "exec") 482 with original_warnings.catch_warnings(record=True) as w: 483 self.module.simplefilter("always", category=UserWarning) 484 exec(codeobj) 485 self.assertEqual(w[0].filename, filename) 486 487 def test_warn_explicit_non_ascii_filename(self): 488 with original_warnings.catch_warnings(record=True, 489 module=self.module) as w: 490 self.module.resetwarnings() 491 self.module.filterwarnings("always", category=UserWarning) 492 filenames = ["nonascii\xe9\u20ac"] 493 if not support.is_emscripten: 494 # JavaScript does not like surrogates. 495 # Invalid UTF-8 leading byte 0x80 encountered when 496 # deserializing a UTF-8 string in wasm memory to a JS 497 # string! 498 filenames.append("surrogate\udc80") 499 for filename in filenames: 500 try: 501 os.fsencode(filename) 502 except UnicodeEncodeError: 503 continue 504 self.module.warn_explicit("text", UserWarning, filename, 1) 505 self.assertEqual(w[-1].filename, filename) 506 507 def test_warn_explicit_type_errors(self): 508 # warn_explicit() should error out gracefully if it is given objects 509 # of the wrong types. 510 # lineno is expected to be an integer. 511 self.assertRaises(TypeError, self.module.warn_explicit, 512 None, UserWarning, None, None) 513 # Either 'message' needs to be an instance of Warning or 'category' 514 # needs to be a subclass. 515 self.assertRaises(TypeError, self.module.warn_explicit, 516 None, None, None, 1) 517 # 'registry' must be a dict or None. 518 self.assertRaises((TypeError, AttributeError), 519 self.module.warn_explicit, 520 None, Warning, None, 1, registry=42) 521 522 def test_bad_str(self): 523 # issue 6415 524 # Warnings instance with a bad format string for __str__ should not 525 # trigger a bus error. 526 class BadStrWarning(Warning): 527 """Warning with a bad format string for __str__.""" 528 def __str__(self): 529 return ("A bad formatted string %(err)" % 530 {"err" : "there is no %(err)s"}) 531 532 with self.assertRaises(ValueError): 533 self.module.warn(BadStrWarning()) 534 535 def test_warning_classes(self): 536 class MyWarningClass(Warning): 537 pass 538 539 class NonWarningSubclass: 540 pass 541 542 # passing a non-subclass of Warning should raise a TypeError 543 with self.assertRaises(TypeError) as cm: 544 self.module.warn('bad warning category', '') 545 self.assertIn('category must be a Warning subclass, not ', 546 str(cm.exception)) 547 548 with self.assertRaises(TypeError) as cm: 549 self.module.warn('bad warning category', NonWarningSubclass) 550 self.assertIn('category must be a Warning subclass, not ', 551 str(cm.exception)) 552 553 # check that warning instances also raise a TypeError 554 with self.assertRaises(TypeError) as cm: 555 self.module.warn('bad warning category', MyWarningClass()) 556 self.assertIn('category must be a Warning subclass, not ', 557 str(cm.exception)) 558 559 with original_warnings.catch_warnings(module=self.module): 560 self.module.resetwarnings() 561 self.module.filterwarnings('default') 562 with self.assertWarns(MyWarningClass) as cm: 563 self.module.warn('good warning category', MyWarningClass) 564 self.assertEqual('good warning category', str(cm.warning)) 565 566 with self.assertWarns(UserWarning) as cm: 567 self.module.warn('good warning category', None) 568 self.assertEqual('good warning category', str(cm.warning)) 569 570 with self.assertWarns(MyWarningClass) as cm: 571 self.module.warn('good warning category', MyWarningClass) 572 self.assertIsInstance(cm.warning, Warning) 573 574class CWarnTests(WarnTests, unittest.TestCase): 575 module = c_warnings 576 577 # As an early adopter, we sanity check the 578 # test.import_helper.import_fresh_module utility function 579 def test_accelerated(self): 580 self.assertIsNot(original_warnings, self.module) 581 self.assertFalse(hasattr(self.module.warn, '__code__')) 582 583class PyWarnTests(WarnTests, unittest.TestCase): 584 module = py_warnings 585 586 # As an early adopter, we sanity check the 587 # test.import_helper.import_fresh_module utility function 588 def test_pure_python(self): 589 self.assertIsNot(original_warnings, self.module) 590 self.assertTrue(hasattr(self.module.warn, '__code__')) 591 592 593class WCmdLineTests(BaseTest): 594 595 def test_improper_input(self): 596 # Uses the private _setoption() function to test the parsing 597 # of command-line warning arguments 598 with original_warnings.catch_warnings(module=self.module): 599 self.assertRaises(self.module._OptionError, 600 self.module._setoption, '1:2:3:4:5:6') 601 self.assertRaises(self.module._OptionError, 602 self.module._setoption, 'bogus::Warning') 603 self.assertRaises(self.module._OptionError, 604 self.module._setoption, 'ignore:2::4:-5') 605 with self.assertRaises(self.module._OptionError): 606 self.module._setoption('ignore::123') 607 with self.assertRaises(self.module._OptionError): 608 self.module._setoption('ignore::123abc') 609 with self.assertRaises(self.module._OptionError): 610 self.module._setoption('ignore::===') 611 with self.assertRaisesRegex(self.module._OptionError, 'Wärning'): 612 self.module._setoption('ignore::Wärning') 613 self.module._setoption('error::Warning::0') 614 self.assertRaises(UserWarning, self.module.warn, 'convert to error') 615 616 def test_import_from_module(self): 617 with original_warnings.catch_warnings(module=self.module): 618 self.module._setoption('ignore::Warning') 619 with self.assertRaises(self.module._OptionError): 620 self.module._setoption('ignore::TestWarning') 621 with self.assertRaises(self.module._OptionError): 622 self.module._setoption('ignore::test.test_warnings.bogus') 623 self.module._setoption('error::test.test_warnings.TestWarning') 624 with self.assertRaises(TestWarning): 625 self.module.warn('test warning', TestWarning) 626 627 628class CWCmdLineTests(WCmdLineTests, unittest.TestCase): 629 module = c_warnings 630 631 632class PyWCmdLineTests(WCmdLineTests, unittest.TestCase): 633 module = py_warnings 634 635 def test_improper_option(self): 636 # Same as above, but check that the message is printed out when 637 # the interpreter is executed. This also checks that options are 638 # actually parsed at all. 639 rc, out, err = assert_python_ok("-Wxxx", "-c", "pass") 640 self.assertIn(b"Invalid -W option ignored: invalid action: 'xxx'", err) 641 642 def test_warnings_bootstrap(self): 643 # Check that the warnings module does get loaded when -W<some option> 644 # is used (see issue #10372 for an example of silent bootstrap failure). 645 rc, out, err = assert_python_ok("-Wi", "-c", 646 "import sys; sys.modules['warnings'].warn('foo', RuntimeWarning)") 647 # '-Wi' was observed 648 self.assertFalse(out.strip()) 649 self.assertNotIn(b'RuntimeWarning', err) 650 651 652class _WarningsTests(BaseTest, unittest.TestCase): 653 654 """Tests specific to the _warnings module.""" 655 656 module = c_warnings 657 658 def test_filter(self): 659 # Everything should function even if 'filters' is not in warnings. 660 with original_warnings.catch_warnings(module=self.module) as w: 661 self.module.filterwarnings("error", "", Warning, "", 0) 662 self.assertRaises(UserWarning, self.module.warn, 663 'convert to error') 664 del self.module.filters 665 self.assertRaises(UserWarning, self.module.warn, 666 'convert to error') 667 668 def test_onceregistry(self): 669 # Replacing or removing the onceregistry should be okay. 670 global __warningregistry__ 671 message = UserWarning('onceregistry test') 672 try: 673 original_registry = self.module.onceregistry 674 __warningregistry__ = {} 675 with original_warnings.catch_warnings(record=True, 676 module=self.module) as w: 677 self.module.resetwarnings() 678 self.module.filterwarnings("once", category=UserWarning) 679 self.module.warn_explicit(message, UserWarning, "file", 42) 680 self.assertEqual(w[-1].message, message) 681 del w[:] 682 self.module.warn_explicit(message, UserWarning, "file", 42) 683 self.assertEqual(len(w), 0) 684 # Test the resetting of onceregistry. 685 self.module.onceregistry = {} 686 __warningregistry__ = {} 687 self.module.warn('onceregistry test') 688 self.assertEqual(w[-1].message.args, message.args) 689 # Removal of onceregistry is okay. 690 del w[:] 691 del self.module.onceregistry 692 __warningregistry__ = {} 693 self.module.warn_explicit(message, UserWarning, "file", 42) 694 self.assertEqual(len(w), 0) 695 finally: 696 self.module.onceregistry = original_registry 697 698 def test_default_action(self): 699 # Replacing or removing defaultaction should be okay. 700 message = UserWarning("defaultaction test") 701 original = self.module.defaultaction 702 try: 703 with original_warnings.catch_warnings(record=True, 704 module=self.module) as w: 705 self.module.resetwarnings() 706 registry = {} 707 self.module.warn_explicit(message, UserWarning, "<test>", 42, 708 registry=registry) 709 self.assertEqual(w[-1].message, message) 710 self.assertEqual(len(w), 1) 711 # One actual registry key plus the "version" key 712 self.assertEqual(len(registry), 2) 713 self.assertIn("version", registry) 714 del w[:] 715 # Test removal. 716 del self.module.defaultaction 717 __warningregistry__ = {} 718 registry = {} 719 self.module.warn_explicit(message, UserWarning, "<test>", 43, 720 registry=registry) 721 self.assertEqual(w[-1].message, message) 722 self.assertEqual(len(w), 1) 723 self.assertEqual(len(registry), 2) 724 del w[:] 725 # Test setting. 726 self.module.defaultaction = "ignore" 727 __warningregistry__ = {} 728 registry = {} 729 self.module.warn_explicit(message, UserWarning, "<test>", 44, 730 registry=registry) 731 self.assertEqual(len(w), 0) 732 finally: 733 self.module.defaultaction = original 734 735 def test_showwarning_missing(self): 736 # Test that showwarning() missing is okay. 737 text = 'del showwarning test' 738 with original_warnings.catch_warnings(module=self.module): 739 self.module.filterwarnings("always", category=UserWarning) 740 del self.module.showwarning 741 with support.captured_output('stderr') as stream: 742 self.module.warn(text) 743 result = stream.getvalue() 744 self.assertIn(text, result) 745 746 def test_showwarnmsg_missing(self): 747 # Test that _showwarnmsg() missing is okay. 748 text = 'del _showwarnmsg test' 749 with original_warnings.catch_warnings(module=self.module): 750 self.module.filterwarnings("always", category=UserWarning) 751 752 show = self.module._showwarnmsg 753 try: 754 del self.module._showwarnmsg 755 with support.captured_output('stderr') as stream: 756 self.module.warn(text) 757 result = stream.getvalue() 758 finally: 759 self.module._showwarnmsg = show 760 self.assertIn(text, result) 761 762 def test_showwarning_not_callable(self): 763 with original_warnings.catch_warnings(module=self.module): 764 self.module.filterwarnings("always", category=UserWarning) 765 self.module.showwarning = print 766 with support.captured_output('stdout'): 767 self.module.warn('Warning!') 768 self.module.showwarning = 23 769 self.assertRaises(TypeError, self.module.warn, "Warning!") 770 771 def test_show_warning_output(self): 772 # With showwarning() missing, make sure that output is okay. 773 text = 'test show_warning' 774 with original_warnings.catch_warnings(module=self.module): 775 self.module.filterwarnings("always", category=UserWarning) 776 del self.module.showwarning 777 with support.captured_output('stderr') as stream: 778 warning_tests.inner(text) 779 result = stream.getvalue() 780 self.assertEqual(result.count('\n'), 2, 781 "Too many newlines in %r" % result) 782 first_line, second_line = result.split('\n', 1) 783 expected_file = os.path.splitext(warning_tests.__file__)[0] + '.py' 784 first_line_parts = first_line.rsplit(':', 3) 785 path, line, warning_class, message = first_line_parts 786 line = int(line) 787 self.assertEqual(expected_file, path) 788 self.assertEqual(warning_class, ' ' + UserWarning.__name__) 789 self.assertEqual(message, ' ' + text) 790 expected_line = ' ' + linecache.getline(path, line).strip() + '\n' 791 assert expected_line 792 self.assertEqual(second_line, expected_line) 793 794 def test_filename_none(self): 795 # issue #12467: race condition if a warning is emitted at shutdown 796 globals_dict = globals() 797 oldfile = globals_dict['__file__'] 798 try: 799 catch = original_warnings.catch_warnings(record=True, 800 module=self.module) 801 with catch as w: 802 self.module.filterwarnings("always", category=UserWarning) 803 globals_dict['__file__'] = None 804 original_warnings.warn('test', UserWarning) 805 self.assertTrue(len(w)) 806 finally: 807 globals_dict['__file__'] = oldfile 808 809 def test_stderr_none(self): 810 rc, stdout, stderr = assert_python_ok("-c", 811 "import sys; sys.stderr = None; " 812 "import warnings; warnings.simplefilter('always'); " 813 "warnings.warn('Warning!')") 814 self.assertEqual(stdout, b'') 815 self.assertNotIn(b'Warning!', stderr) 816 self.assertNotIn(b'Error', stderr) 817 818 def test_issue31285(self): 819 # warn_explicit() should neither raise a SystemError nor cause an 820 # assertion failure, in case the return value of get_source() has a 821 # bad splitlines() method. 822 def get_bad_loader(splitlines_ret_val): 823 class BadLoader: 824 def get_source(self, fullname): 825 class BadSource(str): 826 def splitlines(self): 827 return splitlines_ret_val 828 return BadSource('spam') 829 return BadLoader() 830 831 wmod = self.module 832 with original_warnings.catch_warnings(module=wmod): 833 wmod.filterwarnings('default', category=UserWarning) 834 835 with support.captured_stderr() as stderr: 836 wmod.warn_explicit( 837 'foo', UserWarning, 'bar', 1, 838 module_globals={'__loader__': get_bad_loader(42), 839 '__name__': 'foobar'}) 840 self.assertIn('UserWarning: foo', stderr.getvalue()) 841 842 show = wmod._showwarnmsg 843 try: 844 del wmod._showwarnmsg 845 with support.captured_stderr() as stderr: 846 wmod.warn_explicit( 847 'eggs', UserWarning, 'bar', 1, 848 module_globals={'__loader__': get_bad_loader([42]), 849 '__name__': 'foobar'}) 850 self.assertIn('UserWarning: eggs', stderr.getvalue()) 851 finally: 852 wmod._showwarnmsg = show 853 854 @support.cpython_only 855 def test_issue31411(self): 856 # warn_explicit() shouldn't raise a SystemError in case 857 # warnings.onceregistry isn't a dictionary. 858 wmod = self.module 859 with original_warnings.catch_warnings(module=wmod): 860 wmod.filterwarnings('once') 861 with support.swap_attr(wmod, 'onceregistry', None): 862 with self.assertRaises(TypeError): 863 wmod.warn_explicit('foo', Warning, 'bar', 1, registry=None) 864 865 @support.cpython_only 866 def test_issue31416(self): 867 # warn_explicit() shouldn't cause an assertion failure in case of a 868 # bad warnings.filters or warnings.defaultaction. 869 wmod = self.module 870 with original_warnings.catch_warnings(module=wmod): 871 wmod.filters = [(None, None, Warning, None, 0)] 872 with self.assertRaises(TypeError): 873 wmod.warn_explicit('foo', Warning, 'bar', 1) 874 875 wmod.filters = [] 876 with support.swap_attr(wmod, 'defaultaction', None), \ 877 self.assertRaises(TypeError): 878 wmod.warn_explicit('foo', Warning, 'bar', 1) 879 880 @support.cpython_only 881 def test_issue31566(self): 882 # warn() shouldn't cause an assertion failure in case of a bad 883 # __name__ global. 884 with original_warnings.catch_warnings(module=self.module): 885 self.module.filterwarnings('error', category=UserWarning) 886 with support.swap_item(globals(), '__name__', b'foo'), \ 887 support.swap_item(globals(), '__file__', None): 888 self.assertRaises(UserWarning, self.module.warn, 'bar') 889 890 891class WarningsDisplayTests(BaseTest): 892 893 """Test the displaying of warnings and the ability to overload functions 894 related to displaying warnings.""" 895 896 def test_formatwarning(self): 897 message = "msg" 898 category = Warning 899 file_name = os.path.splitext(warning_tests.__file__)[0] + '.py' 900 line_num = 3 901 file_line = linecache.getline(file_name, line_num).strip() 902 format = "%s:%s: %s: %s\n %s\n" 903 expect = format % (file_name, line_num, category.__name__, message, 904 file_line) 905 self.assertEqual(expect, self.module.formatwarning(message, 906 category, file_name, line_num)) 907 # Test the 'line' argument. 908 file_line += " for the win!" 909 expect = format % (file_name, line_num, category.__name__, message, 910 file_line) 911 self.assertEqual(expect, self.module.formatwarning(message, 912 category, file_name, line_num, file_line)) 913 914 def test_showwarning(self): 915 file_name = os.path.splitext(warning_tests.__file__)[0] + '.py' 916 line_num = 3 917 expected_file_line = linecache.getline(file_name, line_num).strip() 918 message = 'msg' 919 category = Warning 920 file_object = StringIO() 921 expect = self.module.formatwarning(message, category, file_name, 922 line_num) 923 self.module.showwarning(message, category, file_name, line_num, 924 file_object) 925 self.assertEqual(file_object.getvalue(), expect) 926 # Test 'line' argument. 927 expected_file_line += "for the win!" 928 expect = self.module.formatwarning(message, category, file_name, 929 line_num, expected_file_line) 930 file_object = StringIO() 931 self.module.showwarning(message, category, file_name, line_num, 932 file_object, expected_file_line) 933 self.assertEqual(expect, file_object.getvalue()) 934 935 def test_formatwarning_override(self): 936 # bpo-35178: Test that a custom formatwarning function gets the 'line' 937 # argument as a positional argument, and not only as a keyword argument 938 def myformatwarning(message, category, filename, lineno, text): 939 return f'm={message}:c={category}:f={filename}:l={lineno}:t={text}' 940 941 file_name = os.path.splitext(warning_tests.__file__)[0] + '.py' 942 line_num = 3 943 file_line = linecache.getline(file_name, line_num).strip() 944 message = 'msg' 945 category = Warning 946 file_object = StringIO() 947 expected = f'm={message}:c={category}:f={file_name}:l={line_num}' + \ 948 f':t={file_line}' 949 with support.swap_attr(self.module, 'formatwarning', myformatwarning): 950 self.module.showwarning(message, category, file_name, line_num, 951 file_object, file_line) 952 self.assertEqual(file_object.getvalue(), expected) 953 954 955class CWarningsDisplayTests(WarningsDisplayTests, unittest.TestCase): 956 module = c_warnings 957 958class PyWarningsDisplayTests(WarningsDisplayTests, unittest.TestCase): 959 module = py_warnings 960 961 def test_tracemalloc(self): 962 self.addCleanup(os_helper.unlink, os_helper.TESTFN) 963 964 with open(os_helper.TESTFN, 'w', encoding="utf-8") as fp: 965 fp.write(textwrap.dedent(""" 966 def func(): 967 f = open(__file__, "rb") 968 # Emit ResourceWarning 969 f = None 970 971 func() 972 """)) 973 974 def run(*args): 975 res = assert_python_ok(*args, PYTHONIOENCODING='utf-8') 976 stderr = res.err.decode('utf-8', 'replace') 977 stderr = '\n'.join(stderr.splitlines()) 978 979 # normalize newlines 980 stderr = re.sub('<.*>', '<...>', stderr) 981 return stderr 982 983 # tracemalloc disabled 984 filename = os.path.abspath(os_helper.TESTFN) 985 stderr = run('-Wd', os_helper.TESTFN) 986 expected = textwrap.dedent(f''' 987 {filename}:5: ResourceWarning: unclosed file <...> 988 f = None 989 ResourceWarning: Enable tracemalloc to get the object allocation traceback 990 ''').strip() 991 self.assertEqual(stderr, expected) 992 993 # tracemalloc enabled 994 stderr = run('-Wd', '-X', 'tracemalloc=2', os_helper.TESTFN) 995 expected = textwrap.dedent(f''' 996 {filename}:5: ResourceWarning: unclosed file <...> 997 f = None 998 Object allocated at (most recent call last): 999 File "{filename}", lineno 7 1000 func() 1001 File "{filename}", lineno 3 1002 f = open(__file__, "rb") 1003 ''').strip() 1004 self.assertEqual(stderr, expected) 1005 1006 1007class CatchWarningTests(BaseTest): 1008 1009 """Test catch_warnings().""" 1010 1011 def test_catch_warnings_restore(self): 1012 wmod = self.module 1013 orig_filters = wmod.filters 1014 orig_showwarning = wmod.showwarning 1015 # Ensure both showwarning and filters are restored when recording 1016 with wmod.catch_warnings(module=wmod, record=True): 1017 wmod.filters = wmod.showwarning = object() 1018 self.assertIs(wmod.filters, orig_filters) 1019 self.assertIs(wmod.showwarning, orig_showwarning) 1020 # Same test, but with recording disabled 1021 with wmod.catch_warnings(module=wmod, record=False): 1022 wmod.filters = wmod.showwarning = object() 1023 self.assertIs(wmod.filters, orig_filters) 1024 self.assertIs(wmod.showwarning, orig_showwarning) 1025 1026 def test_catch_warnings_recording(self): 1027 wmod = self.module 1028 # Ensure warnings are recorded when requested 1029 with wmod.catch_warnings(module=wmod, record=True) as w: 1030 self.assertEqual(w, []) 1031 self.assertIs(type(w), list) 1032 wmod.simplefilter("always") 1033 wmod.warn("foo") 1034 self.assertEqual(str(w[-1].message), "foo") 1035 wmod.warn("bar") 1036 self.assertEqual(str(w[-1].message), "bar") 1037 self.assertEqual(str(w[0].message), "foo") 1038 self.assertEqual(str(w[1].message), "bar") 1039 del w[:] 1040 self.assertEqual(w, []) 1041 # Ensure warnings are not recorded when not requested 1042 orig_showwarning = wmod.showwarning 1043 with wmod.catch_warnings(module=wmod, record=False) as w: 1044 self.assertIsNone(w) 1045 self.assertIs(wmod.showwarning, orig_showwarning) 1046 1047 def test_catch_warnings_reentry_guard(self): 1048 wmod = self.module 1049 # Ensure catch_warnings is protected against incorrect usage 1050 x = wmod.catch_warnings(module=wmod, record=True) 1051 self.assertRaises(RuntimeError, x.__exit__) 1052 with x: 1053 self.assertRaises(RuntimeError, x.__enter__) 1054 # Same test, but with recording disabled 1055 x = wmod.catch_warnings(module=wmod, record=False) 1056 self.assertRaises(RuntimeError, x.__exit__) 1057 with x: 1058 self.assertRaises(RuntimeError, x.__enter__) 1059 1060 def test_catch_warnings_defaults(self): 1061 wmod = self.module 1062 orig_filters = wmod.filters 1063 orig_showwarning = wmod.showwarning 1064 # Ensure default behaviour is not to record warnings 1065 with wmod.catch_warnings(module=wmod) as w: 1066 self.assertIsNone(w) 1067 self.assertIs(wmod.showwarning, orig_showwarning) 1068 self.assertIsNot(wmod.filters, orig_filters) 1069 self.assertIs(wmod.filters, orig_filters) 1070 if wmod is sys.modules['warnings']: 1071 # Ensure the default module is this one 1072 with wmod.catch_warnings() as w: 1073 self.assertIsNone(w) 1074 self.assertIs(wmod.showwarning, orig_showwarning) 1075 self.assertIsNot(wmod.filters, orig_filters) 1076 self.assertIs(wmod.filters, orig_filters) 1077 1078 def test_record_override_showwarning_before(self): 1079 # Issue #28835: If warnings.showwarning() was overridden, make sure 1080 # that catch_warnings(record=True) overrides it again. 1081 text = "This is a warning" 1082 wmod = self.module 1083 my_log = [] 1084 1085 def my_logger(message, category, filename, lineno, file=None, line=None): 1086 nonlocal my_log 1087 my_log.append(message) 1088 1089 # Override warnings.showwarning() before calling catch_warnings() 1090 with support.swap_attr(wmod, 'showwarning', my_logger): 1091 with wmod.catch_warnings(module=wmod, record=True) as log: 1092 self.assertIsNot(wmod.showwarning, my_logger) 1093 1094 wmod.simplefilter("always") 1095 wmod.warn(text) 1096 1097 self.assertIs(wmod.showwarning, my_logger) 1098 1099 self.assertEqual(len(log), 1, log) 1100 self.assertEqual(log[0].message.args[0], text) 1101 self.assertEqual(my_log, []) 1102 1103 def test_record_override_showwarning_inside(self): 1104 # Issue #28835: It is possible to override warnings.showwarning() 1105 # in the catch_warnings(record=True) context manager. 1106 text = "This is a warning" 1107 wmod = self.module 1108 my_log = [] 1109 1110 def my_logger(message, category, filename, lineno, file=None, line=None): 1111 nonlocal my_log 1112 my_log.append(message) 1113 1114 with wmod.catch_warnings(module=wmod, record=True) as log: 1115 wmod.simplefilter("always") 1116 wmod.showwarning = my_logger 1117 wmod.warn(text) 1118 1119 self.assertEqual(len(my_log), 1, my_log) 1120 self.assertEqual(my_log[0].args[0], text) 1121 self.assertEqual(log, []) 1122 1123 def test_check_warnings(self): 1124 # Explicit tests for the test.support convenience wrapper 1125 wmod = self.module 1126 if wmod is not sys.modules['warnings']: 1127 self.skipTest('module to test is not loaded warnings module') 1128 with warnings_helper.check_warnings(quiet=False) as w: 1129 self.assertEqual(w.warnings, []) 1130 wmod.simplefilter("always") 1131 wmod.warn("foo") 1132 self.assertEqual(str(w.message), "foo") 1133 wmod.warn("bar") 1134 self.assertEqual(str(w.message), "bar") 1135 self.assertEqual(str(w.warnings[0].message), "foo") 1136 self.assertEqual(str(w.warnings[1].message), "bar") 1137 w.reset() 1138 self.assertEqual(w.warnings, []) 1139 1140 with warnings_helper.check_warnings(): 1141 # defaults to quiet=True without argument 1142 pass 1143 with warnings_helper.check_warnings(('foo', UserWarning)): 1144 wmod.warn("foo") 1145 1146 with self.assertRaises(AssertionError): 1147 with warnings_helper.check_warnings(('', RuntimeWarning)): 1148 # defaults to quiet=False with argument 1149 pass 1150 with self.assertRaises(AssertionError): 1151 with warnings_helper.check_warnings(('foo', RuntimeWarning)): 1152 wmod.warn("foo") 1153 1154class CCatchWarningTests(CatchWarningTests, unittest.TestCase): 1155 module = c_warnings 1156 1157class PyCatchWarningTests(CatchWarningTests, unittest.TestCase): 1158 module = py_warnings 1159 1160 1161class EnvironmentVariableTests(BaseTest): 1162 1163 def test_single_warning(self): 1164 rc, stdout, stderr = assert_python_ok("-c", 1165 "import sys; sys.stdout.write(str(sys.warnoptions))", 1166 PYTHONWARNINGS="ignore::DeprecationWarning", 1167 PYTHONDEVMODE="") 1168 self.assertEqual(stdout, b"['ignore::DeprecationWarning']") 1169 1170 def test_comma_separated_warnings(self): 1171 rc, stdout, stderr = assert_python_ok("-c", 1172 "import sys; sys.stdout.write(str(sys.warnoptions))", 1173 PYTHONWARNINGS="ignore::DeprecationWarning,ignore::UnicodeWarning", 1174 PYTHONDEVMODE="") 1175 self.assertEqual(stdout, 1176 b"['ignore::DeprecationWarning', 'ignore::UnicodeWarning']") 1177 1178 def test_envvar_and_command_line(self): 1179 rc, stdout, stderr = assert_python_ok("-Wignore::UnicodeWarning", "-c", 1180 "import sys; sys.stdout.write(str(sys.warnoptions))", 1181 PYTHONWARNINGS="ignore::DeprecationWarning", 1182 PYTHONDEVMODE="") 1183 self.assertEqual(stdout, 1184 b"['ignore::DeprecationWarning', 'ignore::UnicodeWarning']") 1185 1186 def test_conflicting_envvar_and_command_line(self): 1187 rc, stdout, stderr = assert_python_failure("-Werror::DeprecationWarning", "-c", 1188 "import sys, warnings; sys.stdout.write(str(sys.warnoptions)); " 1189 "warnings.warn('Message', DeprecationWarning)", 1190 PYTHONWARNINGS="default::DeprecationWarning", 1191 PYTHONDEVMODE="") 1192 self.assertEqual(stdout, 1193 b"['default::DeprecationWarning', 'error::DeprecationWarning']") 1194 self.assertEqual(stderr.splitlines(), 1195 [b"Traceback (most recent call last):", 1196 b" File \"<string>\", line 1, in <module>", 1197 b"DeprecationWarning: Message"]) 1198 1199 def test_default_filter_configuration(self): 1200 pure_python_api = self.module is py_warnings 1201 if Py_DEBUG: 1202 expected_default_filters = [] 1203 else: 1204 if pure_python_api: 1205 main_module_filter = re.compile("__main__") 1206 else: 1207 main_module_filter = "__main__" 1208 expected_default_filters = [ 1209 ('default', None, DeprecationWarning, main_module_filter, 0), 1210 ('ignore', None, DeprecationWarning, None, 0), 1211 ('ignore', None, PendingDeprecationWarning, None, 0), 1212 ('ignore', None, ImportWarning, None, 0), 1213 ('ignore', None, ResourceWarning, None, 0), 1214 ] 1215 expected_output = [str(f).encode() for f in expected_default_filters] 1216 1217 if pure_python_api: 1218 # Disable the warnings acceleration module in the subprocess 1219 code = "import sys; sys.modules.pop('warnings', None); sys.modules['_warnings'] = None; " 1220 else: 1221 code = "" 1222 code += "import warnings; [print(f) for f in warnings.filters]" 1223 1224 rc, stdout, stderr = assert_python_ok("-c", code, __isolated=True) 1225 stdout_lines = [line.strip() for line in stdout.splitlines()] 1226 self.maxDiff = None 1227 self.assertEqual(stdout_lines, expected_output) 1228 1229 1230 @unittest.skipUnless(sys.getfilesystemencoding() != 'ascii', 1231 'requires non-ascii filesystemencoding') 1232 def test_nonascii(self): 1233 PYTHONWARNINGS="ignore:DeprecationWarning" + os_helper.FS_NONASCII 1234 rc, stdout, stderr = assert_python_ok("-c", 1235 "import sys; sys.stdout.write(str(sys.warnoptions))", 1236 PYTHONIOENCODING="utf-8", 1237 PYTHONWARNINGS=PYTHONWARNINGS, 1238 PYTHONDEVMODE="") 1239 self.assertEqual(stdout, str([PYTHONWARNINGS]).encode()) 1240 1241class CEnvironmentVariableTests(EnvironmentVariableTests, unittest.TestCase): 1242 module = c_warnings 1243 1244class PyEnvironmentVariableTests(EnvironmentVariableTests, unittest.TestCase): 1245 module = py_warnings 1246 1247 1248class _DeprecatedTest(BaseTest, unittest.TestCase): 1249 1250 """Test _deprecated().""" 1251 1252 module = original_warnings 1253 1254 def test_warning(self): 1255 version = (3, 11, 0, "final", 0) 1256 test = [(4, 12), (4, 11), (4, 0), (3, 12)] 1257 for remove in test: 1258 msg = rf".*test_warnings.*{remove[0]}\.{remove[1]}" 1259 filter = msg, DeprecationWarning 1260 with self.subTest(remove=remove): 1261 with warnings_helper.check_warnings(filter, quiet=False): 1262 self.module._deprecated("test_warnings", remove=remove, 1263 _version=version) 1264 1265 version = (3, 11, 0, "alpha", 0) 1266 msg = r".*test_warnings.*3\.11" 1267 with warnings_helper.check_warnings((msg, DeprecationWarning), quiet=False): 1268 self.module._deprecated("test_warnings", remove=(3, 11), 1269 _version=version) 1270 1271 def test_RuntimeError(self): 1272 version = (3, 11, 0, "final", 0) 1273 test = [(2, 0), (2, 12), (3, 10)] 1274 for remove in test: 1275 with self.subTest(remove=remove): 1276 with self.assertRaises(RuntimeError): 1277 self.module._deprecated("test_warnings", remove=remove, 1278 _version=version) 1279 for level in ["beta", "candidate", "final"]: 1280 version = (3, 11, 0, level, 0) 1281 with self.subTest(releaselevel=level): 1282 with self.assertRaises(RuntimeError): 1283 self.module._deprecated("test_warnings", remove=(3, 11), 1284 _version=version) 1285 1286 1287class BootstrapTest(unittest.TestCase): 1288 1289 def test_issue_8766(self): 1290 # "import encodings" emits a warning whereas the warnings is not loaded 1291 # or not completely loaded (warnings imports indirectly encodings by 1292 # importing linecache) yet 1293 with os_helper.temp_cwd() as cwd, os_helper.temp_cwd('encodings'): 1294 # encodings loaded by initfsencoding() 1295 assert_python_ok('-c', 'pass', PYTHONPATH=cwd) 1296 1297 # Use -W to load warnings module at startup 1298 assert_python_ok('-c', 'pass', '-W', 'always', PYTHONPATH=cwd) 1299 1300 1301class FinalizationTest(unittest.TestCase): 1302 def test_finalization(self): 1303 # Issue #19421: warnings.warn() should not crash 1304 # during Python finalization 1305 code = """ 1306import warnings 1307warn = warnings.warn 1308 1309class A: 1310 def __del__(self): 1311 warn("test") 1312 1313a=A() 1314 """ 1315 rc, out, err = assert_python_ok("-c", code) 1316 self.assertEqual(err.decode().rstrip(), 1317 '<string>:7: UserWarning: test') 1318 1319 def test_late_resource_warning(self): 1320 # Issue #21925: Emitting a ResourceWarning late during the Python 1321 # shutdown must be logged. 1322 1323 expected = b"sys:1: ResourceWarning: unclosed file " 1324 1325 # don't import the warnings module 1326 # (_warnings will try to import it) 1327 code = "f = open(%a)" % __file__ 1328 rc, out, err = assert_python_ok("-Wd", "-c", code) 1329 self.assertTrue(err.startswith(expected), ascii(err)) 1330 1331 # import the warnings module 1332 code = "import warnings; f = open(%a)" % __file__ 1333 rc, out, err = assert_python_ok("-Wd", "-c", code) 1334 self.assertTrue(err.startswith(expected), ascii(err)) 1335 1336 1337def setUpModule(): 1338 py_warnings.onceregistry.clear() 1339 c_warnings.onceregistry.clear() 1340 1341tearDownModule = setUpModule 1342 1343if __name__ == "__main__": 1344 unittest.main() 1345