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