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