Index: Doc/library/warnings.rst =================================================================== --- Doc/library/warnings.rst (revision 66300) +++ Doc/library/warnings.rst (working copy) @@ -158,6 +158,67 @@ warnings.simplefilter('default', ImportWarning) +.. _warning-suppress: + +Temporarily Suppressing Warnings +-------------------------------- + +If you are using code that you know will raise a warning, such some deprecated +function, but do not want to see the warning, then suppress the warning using +the :class:`catch_warnings` context manager:: + + import warnings + + def fxn(): + warnings.warn("deprecated", DeprecationWarning) + + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + fxn() + +While within the context manager all warnings will simply be ignored. This +allows you to use known-deprecated code without having to see the warning while +not suppressing the warning for other code that might not be aware of its use +of deprecated code. + + +.. _warning-testing: + +Testing Warnings +---------------- + +To test warnings raised by code, use the :class:`catch_warnings` context +manager. With it you can temporarily mutate the warnings filter to facilitate +your testing. For instance, do the following to capture all raised warnings to +check:: + + import warnings + + def fxn(): + warnings.warn("deprecated", DeprecationWarning) + + with warnings.catch_warnings(record=True) as w: + # Cause all warnings to always be triggered. + warnings.simplefilter("always") + # Trigger a warning. + fxn() + # Verify some things + assert len(w) == 1 + assert isinstance(w[-1].category, DeprecationWarning) + assert "deprecated" in str(w[-1].message) + +One can also cause all warnings to be exceptions by using ``error`` instead of +``always``. One thing to be aware of is that if a warning has already been +raised because of a ``once``/``default`` rule, then no matter what filters are +set the warning will not be seen again unless the warnings registry related to +the warning has been cleared. + +Once the context manager exits, the warnings filter is restored to its state +when the context was entered. This prevents tests from changing the warnings +filter in unexpected ways between tests and leading to indeterminate test +results. + + .. _warning-functions: Available Functions @@ -264,32 +325,23 @@ and calls to :func:`simplefilter`. -Available Classes ------------------ +Available Context Managers +-------------------------- -.. class:: catch_warnings([\*, record=False[, module=None]]) +.. class:: catch_warnings([\*, record=False, module=None]) - A context manager that guards the warnings filter from being permanently - mutated. The manager returns an instance of :class:`WarningsRecorder`. The - *record* argument specifies whether warnings that would typically be - handled by :func:`showwarning` should instead be recorded by the - :class:`WarningsRecorder` instance. This argument is typically set when - testing for expected warnings behavior. The *module* argument may be a - module object that is to be used instead of the :mod:`warnings` module. - This argument should only be set when testing the :mod:`warnings` module - or some similar use-case. + A context manager that copies and, upon exit, restores the warnings filter. + If the *record* argument is False (the default) the context manager returns + :class:`None`. If *record* is true, a list is returned that is populated + with objects as seen by a custom :func:`showwarning` function (which also + suppresses output to ``sys.stdout``). Each object has attributes with the + same names as the arguments to :func:`showwarning`. - Typical usage of the context manager is like so:: + The *module* argument takes a module that will be used instead of the + module returned when you import :mod:`warnings` whose filter will be + protected. This arguments exists primarily for testing the :mod:`warnings` + module itself. - def fxn(): - warn("fxn is deprecated", DeprecationWarning) - return "spam spam bacon spam" - - # The function 'fxn' is known to raise a DeprecationWarning. - with catch_warnings() as w: - warnings.filterwarning('ignore', 'fxn is deprecated', DeprecationWarning) - fxn() # DeprecationWarning is temporarily suppressed. - .. note:: In Python 3.0, the arguments to the constructor for @@ -297,19 +349,3 @@ .. versionadded:: 2.6 - -.. class:: WarningsRecorder() - - A subclass of :class:`list` that stores all warnings passed to - :func:`showwarning` when returned by a :class:`catch_warnings` context - manager created with its *record* argument set to ``True``. Each recorded - warning is represented by an object whose attributes correspond to the - arguments to :func:`showwarning`. As a convenience, a - :class:`WarningsRecorder` instance has the attributes of the last - recorded warning set on the :class:`WarningsRecorder` instance as well. - - .. method:: reset() - - Delete all recorded warnings. - - .. versionadded:: 2.6 Index: Lib/asynchat.py =================================================================== --- Lib/asynchat.py (revision 66300) +++ Lib/asynchat.py (working copy) @@ -50,7 +50,6 @@ import asyncore from collections import deque from sys import py3kwarning -from test.test_support import catch_warning from warnings import filterwarnings, catch_warnings class async_chat (asyncore.dispatcher): Index: Lib/warnings.py =================================================================== --- Lib/warnings.py (revision 66300) +++ Lib/warnings.py (working copy) @@ -8,7 +8,7 @@ import types __all__ = ["warn", "showwarning", "formatwarning", "filterwarnings", - "resetwarnings"] + "resetwarnings", "catch_warnings"] def warnpy3k(message, category=None, stacklevel=1): @@ -304,38 +304,21 @@ self.filename, self.lineno, self.line)) -class WarningsRecorder(list): - - """Record the result of various showwarning() calls.""" - - # Explicitly stated arguments so as to not trigger DeprecationWarning - # about adding 'line'. - def showwarning(self, *args, **kwargs): - self.append(WarningMessage(*args, **kwargs)) - - def __getattr__(self, attr): - """Return attributes from the last caught warning, or raise - AttributeError.""" - try: - return getattr(self[-1], attr) - except IndexError: - raise AttributeError("no recorded warning to read " - "{0!r} attribute from".format(attr)) - - - def reset(self): - del self[:] - - class catch_warnings(object): - """Guard the warnings filter from being permanently changed and optionally - record the details of any warnings that are issued. + """A context manager that copies and restores the warnings filter upon + exiting the context. - Context manager returns an instance of warnings.WarningRecorder which is a - list of WarningMessage instances. Attributes on WarningRecorder are - redirected to the last created WarningMessage instance. + The 'record' argument specifies whether warnings should be captured by a + custom implementation of warnings.showwarning() and be appended to a list + returned by the context manager. Otherwise None is returned by the context + manager. The objects appended to the list are arguments whose attributes + mirror the arguments to showwarning(). + The 'module' argument is to specify an alternative module to the module + named 'warnings' and imported under that name. This argument is only useful + when testing the warnings module itself. + """ def __init__(self, record=False, module=None): @@ -346,17 +329,20 @@ keyword-only. """ - self._recorder = WarningsRecorder() if record else None + self._record = record self._module = sys.modules['warnings'] if module is None else module def __enter__(self): - self._filters = self._module.filters - self._module.filters = self._filters[:] + self._filters = self._module.filters[:] self._showwarning = self._module.showwarning - if self._recorder is not None: - self._recorder.reset() # In case the instance is being reused. - self._module.showwarning = self._recorder.showwarning - return self._recorder + if self._record: + log = [] + def showwarning(*args, **kwargs): + log.append(WarningMessage(*args, **kwargs)) + self._module.showwarning = showwarning + return log + else: + return None def __exit__(self, *exc_info): self._module.filters = self._filters Index: Lib/mimetools.py =================================================================== --- Lib/mimetools.py (revision 66300) +++ Lib/mimetools.py (working copy) @@ -5,7 +5,7 @@ import sys import tempfile from warnings import filterwarnings, catch_warnings -with catch_warnings(record=False): +with catch_warnings(): if sys.py3kwarning: filterwarnings("ignore", ".*rfc822 has been removed", DeprecationWarning) import rfc822 Index: Lib/bsddb/test/test_early_close.py =================================================================== --- Lib/bsddb/test/test_early_close.py (revision 66300) +++ Lib/bsddb/test/test_early_close.py (working copy) @@ -168,9 +168,9 @@ self.assertEquals(("XXX", "yyy"), c1.first()) import warnings # Not interested in warnings about implicit close. - warnings.simplefilter("ignore") - txn.commit() - warnings.resetwarnings() + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + txn.commit() self.assertRaises(db.DBCursorClosedError, c2.first) if db.version() > (4,3,0) : Index: Lib/test/test_pep352.py =================================================================== --- Lib/test/test_pep352.py (revision 66300) +++ Lib/test/test_pep352.py (working copy) @@ -2,7 +2,7 @@ import __builtin__ import exceptions import warnings -from test.test_support import run_unittest, catch_warning +from test.test_support import run_unittest import os from platform import system as platform_system @@ -22,7 +22,7 @@ self.failUnless(issubclass(Exception, object)) def verify_instance_interface(self, ins): - with catch_warning(): + with warnings.catch_warnings(): ignore_message_warning() for attr in ("args", "message", "__str__", "__repr__", "__getitem__"): @@ -95,7 +95,7 @@ # Make sure interface works properly when given a single argument arg = "spam" exc = Exception(arg) - with catch_warning(): + with warnings.catch_warnings(): ignore_message_warning() results = ([len(exc.args), 1], [exc.args[0], arg], [exc.message, arg], @@ -109,7 +109,7 @@ arg_count = 3 args = tuple(range(arg_count)) exc = Exception(*args) - with catch_warning(): + with warnings.catch_warnings(): ignore_message_warning() results = ([len(exc.args), arg_count], [exc.args, args], [exc.message, ''], [str(exc), str(args)], @@ -121,7 +121,7 @@ def test_interface_no_arg(self): # Make sure that with no args that interface is correct exc = Exception() - with catch_warning(): + with warnings.catch_warnings(): ignore_message_warning() results = ([len(exc.args), 0], [exc.args, tuple()], [exc.message, ''], @@ -132,7 +132,7 @@ def test_message_deprecation(self): # As of Python 2.6, BaseException.message is deprecated. - with catch_warning(): + with warnings.catch_warnings(): warnings.resetwarnings() warnings.filterwarnings('error') @@ -219,7 +219,7 @@ def test_catch_string(self): # Catching a string should trigger a DeprecationWarning. - with catch_warning(): + with warnings.catch_warnings(): warnings.resetwarnings() warnings.filterwarnings("error") str_exc = "spam" Index: Lib/test/test_symtable.py =================================================================== --- Lib/test/test_symtable.py (revision 66300) +++ Lib/test/test_symtable.py (working copy) @@ -44,7 +44,7 @@ class SymtableTest(unittest.TestCase): - with test_support.catch_warning(record=False): + with warnings.catch_warnings(): # Ignore warnings about "from blank import *" warnings.simplefilter("ignore", SyntaxWarning) top = symtable.symtable(TEST_CODE, "?", "exec") @@ -60,16 +60,16 @@ def check(w, msg): self.assertEqual(str(w.message), msg) sym = self.top.lookup("glob") - with test_support.catch_warning() as w: + with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always", DeprecationWarning) self.assertFalse(sym.is_vararg()) - check(w, "is_vararg() is obsolete and will be removed") - w.reset() + check(w[-1].message, "is_vararg() is obsolete and will be removed") self.assertFalse(sym.is_keywordarg()) - check(w, "is_keywordarg() is obsolete and will be removed") - w.reset() + check(w[-1].message, + "is_keywordarg() is obsolete and will be removed") self.assertFalse(sym.is_in_tuple()) - check(w, "is_in_tuple() is obsolete and will be removed") + check(w[-1].message, + "is_in_tuple() is obsolete and will be removed") def test_type(self): self.assertEqual(self.top.get_type(), "module") Index: Lib/test/test_exceptions.py =================================================================== --- Lib/test/test_exceptions.py (revision 66300) +++ Lib/test/test_exceptions.py (working copy) @@ -4,9 +4,9 @@ import sys import unittest import pickle, cPickle +import warnings -from test.test_support import (TESTFN, unlink, run_unittest, - catch_warning, captured_output) +from test.test_support import TESTFN, unlink, run_unittest, captured_output from test.test_pep352 import ignore_message_warning # XXX This is not really enough, each *operation* should be tested! @@ -274,7 +274,7 @@ except NameError: pass - with catch_warning(): + with warnings.catch_warnings(): ignore_message_warning() for exc, args, expected in exceptionList: try: Index: Lib/test/test_sundry.py =================================================================== --- Lib/test/test_sundry.py (revision 66300) +++ Lib/test/test_sundry.py (working copy) @@ -8,7 +8,7 @@ class TestUntestedModules(unittest.TestCase): def test_at_least_import_untested_modules(self): - with test_support.catch_warning(): + with warnings.catch_warnings(record=True): import CGIHTTPServer import aifc import audiodev Index: Lib/test/test_warnings.py =================================================================== --- Lib/test/test_warnings.py (revision 66300) +++ Lib/test/test_warnings.py (working copy) @@ -72,64 +72,69 @@ """Testing the filtering functionality.""" def test_error(self): - with test_support.catch_warning(self.module) as w: + with original_warnings.catch_warnings(module=self.module) as w: self.module.resetwarnings() self.module.filterwarnings("error", category=UserWarning) self.assertRaises(UserWarning, self.module.warn, "FilterTests.test_error") def test_ignore(self): - with test_support.catch_warning(module=self.module) as w: + with original_warnings.catch_warnings(record=True, + module=self.module) as w: self.module.resetwarnings() self.module.filterwarnings("ignore", category=UserWarning) self.module.warn("FilterTests.test_ignore", UserWarning) self.assertEquals(len(w), 0) def test_always(self): - with test_support.catch_warning(module=self.module) as w: + with original_warnings.catch_warnings(record=True, + module=self.module) as w: self.module.resetwarnings() self.module.filterwarnings("always", category=UserWarning) message = "FilterTests.test_always" self.module.warn(message, UserWarning) - self.assert_(message, w.message) + self.assert_(message, w[-1].message) self.module.warn(message, UserWarning) - self.assert_(w.message, message) + self.assert_(w[-1].message, message) def test_default(self): - with test_support.catch_warning(self.module) as w: + with original_warnings.catch_warnings(record=True, + module=self.module) as w: self.module.resetwarnings() self.module.filterwarnings("default", category=UserWarning) message = UserWarning("FilterTests.test_default") for x in xrange(2): self.module.warn(message, UserWarning) if x == 0: - self.assertEquals(w.message, message) - w.reset() + self.assertEquals(w[-1].message, message) + del w[:] elif x == 1: - self.assert_(not len(w), "unexpected warning: " + str(w)) + self.assertEquals(len(w), 0) else: raise ValueError("loop variant unhandled") def test_module(self): - with test_support.catch_warning(self.module) as w: + with original_warnings.catch_warnings(record=True, + module=self.module) as w: self.module.resetwarnings() self.module.filterwarnings("module", category=UserWarning) message = UserWarning("FilterTests.test_module") self.module.warn(message, UserWarning) - self.assertEquals(w.message, message) - w.reset() + self.assertEquals(w[-1].message, message) + del w[:] self.module.warn(message, UserWarning) - self.assert_(not len(w), "unexpected message: " + str(w)) + self.assertEquals(len(w), 0) def test_once(self): - with test_support.catch_warning(self.module) as w: + with original_warnings.catch_warnings(record=True, + module=self.module) as w: self.module.resetwarnings() self.module.filterwarnings("once", category=UserWarning) message = UserWarning("FilterTests.test_once") self.module.warn_explicit(message, UserWarning, "test_warnings.py", 42) - self.assertEquals(w.message, message) - w.reset() + self.assertEquals(w[-1].message, message) + del w[:] self.module.warn_explicit(message, UserWarning, "test_warnings.py", 13) self.assertEquals(len(w), 0) @@ -138,19 +143,20 @@ self.assertEquals(len(w), 0) def test_inheritance(self): - with test_support.catch_warning(self.module) as w: + with original_warnings.catch_warnings(module=self.module) as w: self.module.resetwarnings() self.module.filterwarnings("error", category=Warning) self.assertRaises(UserWarning, self.module.warn, "FilterTests.test_inheritance", UserWarning) def test_ordering(self): - with test_support.catch_warning(self.module) as w: + with original_warnings.catch_warnings(record=True, + module=self.module) as w: self.module.resetwarnings() self.module.filterwarnings("ignore", category=UserWarning) self.module.filterwarnings("error", category=UserWarning, append=True) - w.reset() + del w[:] try: self.module.warn("FilterTests.test_ordering", UserWarning) except UserWarning: @@ -160,28 +166,29 @@ def test_filterwarnings(self): # Test filterwarnings(). # Implicitly also tests resetwarnings(). - with test_support.catch_warning(self.module) as w: + with original_warnings.catch_warnings(record=True, + module=self.module) as w: self.module.filterwarnings("error", "", Warning, "", 0) self.assertRaises(UserWarning, self.module.warn, 'convert to error') self.module.resetwarnings() text = 'handle normally' self.module.warn(text) - self.assertEqual(str(w.message), text) - self.assert_(w.category is UserWarning) + self.assertEqual(str(w[-1].message), text) + self.assert_(w[-1].category is UserWarning) self.module.filterwarnings("ignore", "", Warning, "", 0) text = 'filtered out' self.module.warn(text) - self.assertNotEqual(str(w.message), text) + self.assertNotEqual(str(w[-1].message), text) self.module.resetwarnings() self.module.filterwarnings("error", "hex*", Warning, "", 0) self.assertRaises(UserWarning, self.module.warn, 'hex/oct') text = 'nonmatching text' self.module.warn(text) - self.assertEqual(str(w.message), text) - self.assert_(w.category is UserWarning) + self.assertEqual(str(w[-1].message), text) + self.assert_(w[-1].category is UserWarning) class CFilterTests(BaseTest, FilterTests): module = c_warnings @@ -195,40 +202,51 @@ """Test warnings.warn() and warnings.warn_explicit().""" def test_message(self): - with test_support.catch_warning(self.module) as w: + with original_warnings.catch_warnings(record=True, + module=self.module) as w: for i in range(4): text = 'multi %d' %i # Different text on each call. self.module.warn(text) - self.assertEqual(str(w.message), text) - self.assert_(w.category is UserWarning) + self.assertEqual(str(w[-1].message), text) + self.assert_(w[-1].category is UserWarning) def test_filename(self): with warnings_state(self.module): - with test_support.catch_warning(self.module) as w: + with original_warnings.catch_warnings(record=True, + module=self.module) as w: warning_tests.inner("spam1") - self.assertEqual(os.path.basename(w.filename), "warning_tests.py") + self.assertEqual(os.path.basename(w[-1].filename), + "warning_tests.py") warning_tests.outer("spam2") - self.assertEqual(os.path.basename(w.filename), "warning_tests.py") + self.assertEqual(os.path.basename(w[-1].filename), + "warning_tests.py") def test_stacklevel(self): # Test stacklevel argument # make sure all messages are different, so the warning won't be skipped with warnings_state(self.module): - with test_support.catch_warning(self.module) as w: + with original_warnings.catch_warnings(record=True, + module=self.module) as w: warning_tests.inner("spam3", stacklevel=1) - self.assertEqual(os.path.basename(w.filename), "warning_tests.py") + self.assertEqual(os.path.basename(w[-1].filename), + "warning_tests.py") warning_tests.outer("spam4", stacklevel=1) - self.assertEqual(os.path.basename(w.filename), "warning_tests.py") + self.assertEqual(os.path.basename(w[-1].filename), + "warning_tests.py") warning_tests.inner("spam5", stacklevel=2) - self.assertEqual(os.path.basename(w.filename), "test_warnings.py") + self.assertEqual(os.path.basename(w[-1].filename), + "test_warnings.py") warning_tests.outer("spam6", stacklevel=2) - self.assertEqual(os.path.basename(w.filename), "warning_tests.py") + self.assertEqual(os.path.basename(w[-1].filename), + "warning_tests.py") warning_tests.outer("spam6.5", stacklevel=3) - self.assertEqual(os.path.basename(w.filename), "test_warnings.py") + self.assertEqual(os.path.basename(w[-1].filename), + "test_warnings.py") warning_tests.inner("spam7", stacklevel=9999) - self.assertEqual(os.path.basename(w.filename), "sys") + self.assertEqual(os.path.basename(w[-1].filename), + "sys") def test_missing_filename_not_main(self): # If __file__ is not specified and __main__ is not the module name, @@ -237,9 +255,10 @@ try: del warning_tests.__file__ with warnings_state(self.module): - with test_support.catch_warning(self.module) as w: + with original_warnings.catch_warnings(record=True, + module=self.module) as w: warning_tests.inner("spam8", stacklevel=1) - self.assertEqual(w.filename, warning_tests.__name__) + self.assertEqual(w[-1].filename, warning_tests.__name__) finally: warning_tests.__file__ = filename @@ -254,9 +273,10 @@ del warning_tests.__file__ warning_tests.__name__ = '__main__' with warnings_state(self.module): - with test_support.catch_warning(self.module) as w: + with original_warnings.catch_warnings(record=True, + module=self.module) as w: warning_tests.inner('spam9', stacklevel=1) - self.assertEqual(w.filename, sys.argv[0]) + self.assertEqual(w[-1].filename, sys.argv[0]) finally: warning_tests.__file__ = filename warning_tests.__name__ = module_name @@ -272,9 +292,10 @@ warning_tests.__name__ = '__main__' del sys.argv with warnings_state(self.module): - with test_support.catch_warning(self.module) as w: + with original_warnings.catch_warnings(record=True, + module=self.module) as w: warning_tests.inner('spam10', stacklevel=1) - self.assertEqual(w.filename, '__main__') + self.assertEqual(w[-1].filename, '__main__') finally: warning_tests.__file__ = filename warning_tests.__name__ = module_name @@ -292,9 +313,10 @@ warning_tests.__name__ = '__main__' sys.argv = [''] with warnings_state(self.module): - with test_support.catch_warning(self.module) as w: + with original_warnings.catch_warnings(record=True, + module=self.module) as w: warning_tests.inner('spam11', stacklevel=1) - self.assertEqual(w.filename, '__main__') + self.assertEqual(w[-1].filename, '__main__') finally: warning_tests.__file__ = file_name warning_tests.__name__ = module_name @@ -328,7 +350,7 @@ def test_improper_input(self): # Uses the private _setoption() function to test the parsing # of command-line warning arguments - with test_support.catch_warning(self.module): + with original_warnings.catch_warnings(module=self.module): self.assertRaises(self.module._OptionError, self.module._setoption, '1:2:3:4:5:6') self.assertRaises(self.module._OptionError, @@ -353,7 +375,7 @@ def test_filter(self): # Everything should function even if 'filters' is not in warnings. - with test_support.catch_warning(self.module) as w: + with original_warnings.catch_warnings(module=self.module) as w: self.module.filterwarnings("error", "", Warning, "", 0) self.assertRaises(UserWarning, self.module.warn, 'convert to error') @@ -368,21 +390,22 @@ try: original_registry = self.module.onceregistry __warningregistry__ = {} - with test_support.catch_warning(self.module) as w: + with original_warnings.catch_warnings(record=True, + module=self.module) as w: self.module.resetwarnings() self.module.filterwarnings("once", category=UserWarning) self.module.warn_explicit(message, UserWarning, "file", 42) - self.failUnlessEqual(w.message, message) - w.reset() + self.failUnlessEqual(w[-1].message, message) + del w[:] self.module.warn_explicit(message, UserWarning, "file", 42) self.assertEquals(len(w), 0) # Test the resetting of onceregistry. self.module.onceregistry = {} __warningregistry__ = {} self.module.warn('onceregistry test') - self.failUnlessEqual(w.message.args, message.args) + self.failUnlessEqual(w[-1].message.args, message.args) # Removal of onceregistry is okay. - w.reset() + del w[:] del self.module.onceregistry __warningregistry__ = {} self.module.warn_explicit(message, UserWarning, "file", 42) @@ -393,7 +416,7 @@ def test_showwarning_missing(self): # Test that showwarning() missing is okay. text = 'del showwarning test' - with test_support.catch_warning(self.module): + with original_warnings.catch_warnings(module=self.module): self.module.filterwarnings("always", category=UserWarning) del self.module.showwarning with test_support.captured_output('stderr') as stream: @@ -414,7 +437,7 @@ def test_show_warning_output(self): # With showarning() missing, make sure that output is okay. text = 'test show_warning' - with test_support.catch_warning(self.module): + with original_warnings.catch_warnings(module=self.module): self.module.filterwarnings("always", category=UserWarning) del self.module.showwarning with test_support.captured_output('stderr') as stream: @@ -486,7 +509,6 @@ module = py_warnings - class CatchWarningTests(BaseTest): """Test catch_warnings().""" @@ -511,12 +533,12 @@ self.assertRaises(AttributeError, getattr, w, 'message') wmod.simplefilter("always") wmod.warn("foo") - self.assertEqual(str(w.message), "foo") + self.assertEqual(str(w[-1].message), "foo") wmod.warn("bar") - self.assertEqual(str(w.message), "bar") + self.assertEqual(str(w[-1].message), "bar") self.assertEqual(str(w[0].message), "foo") self.assertEqual(str(w[1].message), "bar") - w.reset() + del w[:] self.assertEqual(w, []) orig_showwarning = wmod.showwarning with wmod.catch_warnings(module=wmod, record=False) as w: @@ -545,7 +567,7 @@ def test_deprecation(self): # message, category, filename, lineno[, file[, line]] args = ("message", UserWarning, "file name", 42) - with test_support.catch_warning(module=self.module): + with original_warnings.catch_warnings(module=self.module): self.module.filterwarnings("error", category=DeprecationWarning) self.module.showwarning = self.bad_showwarning self.assertRaises(DeprecationWarning, self.module.warn_explicit, Index: Lib/test/test_macostools.py =================================================================== --- Lib/test/test_macostools.py (revision 66300) +++ Lib/test/test_macostools.py (working copy) @@ -52,7 +52,7 @@ def test_touched(self): # This really only tests that nothing unforeseen happens. import warnings - with test_support.catch_warning(): + with warnings.catch_warnings(): warnings.filterwarnings('ignore', 'macostools.touched*', DeprecationWarning) macostools.touched(test_support.TESTFN) Index: Lib/test/test_hmac.py =================================================================== --- Lib/test/test_hmac.py (revision 66300) +++ Lib/test/test_hmac.py (working copy) @@ -211,7 +211,7 @@ def digest(self): return self._x.digest() - with test_support.catch_warning(): + with warnings.catch_warnings(): warnings.simplefilter('error', RuntimeWarning) try: hmac.HMAC('a', 'b', digestmod=MockCrazyHash) Index: Lib/test/test_py3kwarn.py =================================================================== --- Lib/test/test_py3kwarn.py (revision 66300) +++ Lib/test/test_py3kwarn.py (working copy) @@ -1,7 +1,6 @@ import unittest import sys -from test.test_support import (catch_warning, CleanImport, - TestSkipped, run_unittest) +from test.test_support import CleanImport, TestSkipped, run_unittest import warnings from contextlib import nested @@ -13,11 +12,11 @@ class TestPy3KWarnings(unittest.TestCase): def assertWarning(self, _, warning, expected_message): - self.assertEqual(str(warning.message), expected_message) + self.assertEqual(str(warning[-1].message), expected_message) def test_backquote(self): expected = 'backquote not supported in 3.x; use repr()' - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: exec "`2`" in {} self.assertWarning(None, w, expected) @@ -28,71 +27,55 @@ exec expr in {'f' : f} expected = "assignment to True or False is forbidden in 3.x" - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: safe_exec("True = False") self.assertWarning(None, w, expected) - w.reset() safe_exec("False = True") self.assertWarning(None, w, expected) - w.reset() try: safe_exec("obj.False = True") except NameError: pass self.assertWarning(None, w, expected) - w.reset() try: safe_exec("obj.True = False") except NameError: pass self.assertWarning(None, w, expected) - w.reset() safe_exec("def False(): pass") self.assertWarning(None, w, expected) - w.reset() safe_exec("def True(): pass") self.assertWarning(None, w, expected) - w.reset() safe_exec("class False: pass") self.assertWarning(None, w, expected) - w.reset() safe_exec("class True: pass") self.assertWarning(None, w, expected) - w.reset() safe_exec("def f(True=43): pass") self.assertWarning(None, w, expected) - w.reset() safe_exec("def f(False=None): pass") self.assertWarning(None, w, expected) - w.reset() safe_exec("f(False=True)") self.assertWarning(None, w, expected) - w.reset() safe_exec("f(True=1)") self.assertWarning(None, w, expected) def test_type_inequality_comparisons(self): expected = 'type inequality comparisons not supported in 3.x' - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: self.assertWarning(int < str, w, expected) - w.reset() self.assertWarning(type < object, w, expected) def test_object_inequality_comparisons(self): expected = 'comparing unequal types not supported in 3.x' - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: self.assertWarning(str < [], w, expected) - w.reset() self.assertWarning(object() < (1, 2), w, expected) def test_dict_inequality_comparisons(self): expected = 'dict inequality comparisons not supported in 3.x' - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: self.assertWarning({} < {2:3}, w, expected) - w.reset() self.assertWarning({} <= {}, w, expected) - w.reset() self.assertWarning({} > {2:3}, w, expected) - w.reset() self.assertWarning({2:3} >= {}, w, expected) def test_cell_inequality_comparisons(self): @@ -103,9 +86,8 @@ return g cell0, = f(0).func_closure cell1, = f(1).func_closure - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: self.assertWarning(cell0 == cell1, w, expected) - w.reset() self.assertWarning(cell0 < cell1, w, expected) def test_code_inequality_comparisons(self): @@ -114,13 +96,10 @@ pass def g(x): pass - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: self.assertWarning(f.func_code < g.func_code, w, expected) - w.reset() self.assertWarning(f.func_code <= g.func_code, w, expected) - w.reset() self.assertWarning(f.func_code >= g.func_code, w, expected) - w.reset() self.assertWarning(f.func_code > g.func_code, w, expected) def test_builtin_function_or_method_comparisons(self): @@ -128,13 +107,10 @@ 'inequality comparisons not supported in 3.x') func = eval meth = {}.get - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: self.assertWarning(func < meth, w, expected) - w.reset() self.assertWarning(func > meth, w, expected) - w.reset() self.assertWarning(meth <= func, w, expected) - w.reset() self.assertWarning(meth >= func, w, expected) def test_sort_cmp_arg(self): @@ -142,18 +118,15 @@ lst = range(5) cmp = lambda x,y: -1 - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: self.assertWarning(lst.sort(cmp=cmp), w, expected) - w.reset() self.assertWarning(sorted(lst, cmp=cmp), w, expected) - w.reset() self.assertWarning(lst.sort(cmp), w, expected) - w.reset() self.assertWarning(sorted(lst, cmp), w, expected) def test_sys_exc_clear(self): expected = 'sys.exc_clear() not supported in 3.x; use except clauses' - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: self.assertWarning(sys.exc_clear(), w, expected) def test_methods_members(self): @@ -162,17 +135,17 @@ __methods__ = ['a'] __members__ = ['b'] c = C() - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: self.assertWarning(dir(c), w, expected) def test_softspace(self): expected = 'file.softspace not supported in 3.x' with file(__file__) as f: - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: self.assertWarning(f.softspace, w, expected) def set(): f.softspace = 0 - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: self.assertWarning(set(), w, expected) def test_slice_methods(self): @@ -188,60 +161,59 @@ expected = "in 3.x, __{0}slice__ has been removed; use __{0}item__" for obj in (Spam(), Egg()): - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: self.assertWarning(obj[1:2], w, expected.format('get')) - w.reset() del obj[3:4] self.assertWarning(None, w, expected.format('del')) - w.reset() obj[4:5] = "eggs" self.assertWarning(None, w, expected.format('set')) def test_tuple_parameter_unpacking(self): expected = "tuple parameter unpacking has been removed in 3.x" - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: exec "def f((a, b)): pass" self.assertWarning(None, w, expected) def test_buffer(self): expected = 'buffer() not supported in 3.x' - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: self.assertWarning(buffer('a'), w, expected) def test_file_xreadlines(self): expected = ("f.xreadlines() not supported in 3.x, " "try 'for line in f' instead") with file(__file__) as f: - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: self.assertWarning(f.xreadlines(), w, expected) def test_hash_inheritance(self): - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: # With object as the base class class WarnOnlyCmp(object): def __cmp__(self, other): pass self.assertEqual(len(w), 1) self.assertWarning(None, w, "Overriding __cmp__ blocks inheritance of __hash__ in 3.x") - w.reset() + del w[:] class WarnOnlyEq(object): def __eq__(self, other): pass self.assertEqual(len(w), 1) self.assertWarning(None, w, "Overriding __eq__ blocks inheritance of __hash__ in 3.x") - w.reset() + del w[:] class WarnCmpAndEq(object): def __cmp__(self, other): pass def __eq__(self, other): pass self.assertEqual(len(w), 2) - self.assertWarning(None, w[-2], + self.assertWarning(None, w[:1], "Overriding __cmp__ blocks inheritance of __hash__ in 3.x") self.assertWarning(None, w, "Overriding __eq__ blocks inheritance of __hash__ in 3.x") - w.reset() + del w[:] class NoWarningOnlyHash(object): def __hash__(self): pass self.assertEqual(len(w), 0) + del w[:] # With an intermediate class in the heirarchy class DefinesAllThree(object): def __cmp__(self, other): pass @@ -252,22 +224,22 @@ self.assertEqual(len(w), 1) self.assertWarning(None, w, "Overriding __cmp__ blocks inheritance of __hash__ in 3.x") - w.reset() + del w[:] class WarnOnlyEq(DefinesAllThree): def __eq__(self, other): pass self.assertEqual(len(w), 1) self.assertWarning(None, w, "Overriding __eq__ blocks inheritance of __hash__ in 3.x") - w.reset() + del w[:] class WarnCmpAndEq(DefinesAllThree): def __cmp__(self, other): pass def __eq__(self, other): pass self.assertEqual(len(w), 2) - self.assertWarning(None, w[-2], + self.assertWarning(None, w[:1], "Overriding __cmp__ blocks inheritance of __hash__ in 3.x") self.assertWarning(None, w, "Overriding __eq__ blocks inheritance of __hash__ in 3.x") - w.reset() + del w[:] class NoWarningOnlyHash(DefinesAllThree): def __hash__(self): pass self.assertEqual(len(w), 0) @@ -310,7 +282,7 @@ def check_removal(self, module_name, optional=False): """Make sure the specified module, when imported, raises a DeprecationWarning and specifies itself in the message.""" - with nested(CleanImport(module_name), catch_warning(record=False)): + with nested(CleanImport(module_name), warnings.catch_warnings()): warnings.filterwarnings("error", ".+ removed", DeprecationWarning, __name__) try: @@ -348,36 +320,36 @@ def dumbo(where, names, args): pass for path_mod in ("ntpath", "macpath", "os2emxpath", "posixpath"): mod = __import__(path_mod) - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: mod.walk("crashers", dumbo, None) - self.assertEquals(str(w.message), msg) + self.assertEquals(str(w[-1].message), msg) def test_commands_members(self): import commands members = {"mk2arg" : 2, "mkarg" : 1, "getstatus" : 1} for name, arg_count in members.items(): - with catch_warning(record=False): + with warnings.catch_warnings(): warnings.filterwarnings("error") func = getattr(commands, name) self.assertRaises(DeprecationWarning, func, *([None]*arg_count)) def test_reduce_move(self): from operator import add - with catch_warning(record=False): + with warnings.catch_warnings(): warnings.filterwarnings("error", "reduce") self.assertRaises(DeprecationWarning, reduce, add, range(10)) def test_mutablestring_removal(self): # UserString.MutableString has been removed in 3.0. import UserString - with catch_warning(record=False): + with warnings.catch_warnings(): warnings.filterwarnings("error", ".*MutableString", DeprecationWarning) self.assertRaises(DeprecationWarning, UserString.MutableString) def test_main(): - with catch_warning(): + with warnings.catch_warnings(): warnings.simplefilter("always") run_unittest(TestPy3KWarnings, TestStdlibRemovals) Index: Lib/test/test_re.py =================================================================== --- Lib/test/test_re.py (revision 66300) +++ Lib/test/test_re.py (working copy) @@ -1,7 +1,7 @@ import sys sys.path = ['.'] + sys.path -from test.test_support import verbose, run_unittest, catch_warning +from test.test_support import verbose, run_unittest import re from re import Scanner import sys, os, traceback @@ -447,7 +447,7 @@ self.pickle_test(cPickle) # old pickles expect the _compile() reconstructor in sre module import warnings - with catch_warning(): + with warnings.catch_warnings(): warnings.filterwarnings("ignore", "The sre module is deprecated", DeprecationWarning) from sre import _compile Index: Lib/test/test_urllibnet.py =================================================================== --- Lib/test/test_urllibnet.py (revision 66300) +++ Lib/test/test_urllibnet.py (working copy) @@ -182,8 +182,8 @@ def test_main(): test_support.requires('network') - from warnings import filterwarnings - with test_support.catch_warning(record=False): + from warnings import filterwarnings, catch_warnings + with catch_warnings(): filterwarnings('ignore', '.*urllib\.urlopen.*Python 3.0', DeprecationWarning) test_support.run_unittest(URLTimeoutTest, Index: Lib/test/test_random.py =================================================================== --- Lib/test/test_random.py (revision 66300) +++ Lib/test/test_random.py (working copy) @@ -191,7 +191,7 @@ def test_bigrand(self): # Verify warnings are raised when randrange is too large for random() - with test_support.catch_warning(): + with warnings.catch_warnings(): warnings.filterwarnings("error", "Underlying random") self.assertRaises(UserWarning, self.gen.randrange, 2**60) Index: Lib/test/test_struct.py =================================================================== --- Lib/test/test_struct.py (revision 66300) +++ Lib/test/test_struct.py (working copy) @@ -4,7 +4,7 @@ import warnings from functools import wraps -from test.test_support import TestFailed, verbose, run_unittest, catch_warning +from test.test_support import TestFailed, verbose, run_unittest import sys ISBIGENDIAN = sys.byteorder == "big" @@ -34,7 +34,7 @@ def with_warning_restore(func): @wraps(func) def decorator(*args, **kw): - with catch_warning(): + with warnings.catch_warnings(): # We need this function to warn every time, so stick an # unqualifed 'always' at the head of the filter list warnings.simplefilter("always") Index: Lib/test/test_import.py =================================================================== --- Lib/test/test_import.py (revision 66300) +++ Lib/test/test_import.py (working copy) @@ -5,7 +5,7 @@ import sys import py_compile import warnings -from test.test_support import unlink, TESTFN, unload, run_unittest, catch_warning +from test.test_support import unlink, TESTFN, unload, run_unittest def remove_files(name): @@ -215,7 +215,7 @@ self.assert_(y is test.test_support, y.__name__) def test_import_initless_directory_warning(self): - with catch_warning(): + with warnings.catch_warnings(): # Just a random non-package directory we always expect to be # somewhere in sys.path... warnings.simplefilter('error', ImportWarning) @@ -279,17 +279,17 @@ check_relative() # Check relative fails with only __package__ wrong ns = dict(__package__='foo', __name__='test.notarealmodule') - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: check_absolute() - self.assert_('foo' in str(w.message)) - self.assertEqual(w.category, RuntimeWarning) + self.assert_('foo' in str(w[-1].message)) + self.assertEqual(w[-1].category, RuntimeWarning) self.assertRaises(SystemError, check_relative) # Check relative fails with __package__ and __name__ wrong ns = dict(__package__='foo', __name__='notarealpkg.notarealmodule') - with catch_warning() as w: + with warnings.catch_warnings(record=True) as w: check_absolute() - self.assert_('foo' in str(w.message)) - self.assertEqual(w.category, RuntimeWarning) + self.assert_('foo' in str(w[-1].message)) + self.assertEqual(w[-1].category, RuntimeWarning) self.assertRaises(SystemError, check_relative) # Check both fail with package set to a non-string ns = dict(__package__=object()) Index: Lib/test/test_structmembers.py =================================================================== --- Lib/test/test_structmembers.py (revision 66300) +++ Lib/test/test_structmembers.py (working copy) @@ -66,35 +66,35 @@ class TestWarnings(unittest.TestCase): def has_warned(self, w): - self.assertEqual(w.category, RuntimeWarning) + self.assertEqual(w[-1].category, RuntimeWarning) def test_byte_max(self): - with test_support.catch_warning() as w: + with warnings.catch_warnings(record=True) as w: ts.T_BYTE = CHAR_MAX+1 self.has_warned(w) def test_byte_min(self): - with test_support.catch_warning() as w: + with warnings.catch_warnings(record=True) as w: ts.T_BYTE = CHAR_MIN-1 self.has_warned(w) def test_ubyte_max(self): - with test_support.catch_warning() as w: + with warnings.catch_warnings(record=True) as w: ts.T_UBYTE = UCHAR_MAX+1 self.has_warned(w) def test_short_max(self): - with test_support.catch_warning() as w: + with warnings.catch_warnings(record=True) as w: ts.T_SHORT = SHRT_MAX+1 self.has_warned(w) def test_short_min(self): - with test_support.catch_warning() as w: + with warnings.catch_warnings(record=True) as w: ts.T_SHORT = SHRT_MIN-1 self.has_warned(w) def test_ushort_max(self): - with test_support.catch_warning() as w: + with warnings.catch_warnings(record=True) as w: ts.T_USHORT = USHRT_MAX+1 self.has_warned(w) Index: Lib/test/test___all__.py =================================================================== --- Lib/test/test___all__.py (revision 66300) +++ Lib/test/test___all__.py (working copy) @@ -1,5 +1,5 @@ import unittest -from test.test_support import run_unittest, catch_warning +from test.test_support import run_unittest import sys import warnings @@ -9,7 +9,7 @@ def check_all(self, modname): names = {} - with catch_warning(): + with warnings.catch_warnings(): warnings.filterwarnings("ignore", ".* (module|package)", DeprecationWarning) try: Index: Lib/test/test_urllib.py =================================================================== --- Lib/test/test_urllib.py (revision 66300) +++ Lib/test/test_urllib.py (working copy) @@ -641,7 +641,7 @@ def test_main(): import warnings - with test_support.catch_warning(record=False): + with warnings.catch_warnings(): warnings.filterwarnings('ignore', ".*urllib\.urlopen.*Python 3.0", DeprecationWarning) test_support.run_unittest( Index: Lib/test/test_userstring.py =================================================================== --- Lib/test/test_userstring.py (revision 66300) +++ Lib/test/test_userstring.py (working copy) @@ -135,7 +135,7 @@ self.assertEqual(s, "") def test_main(): - with test_support.catch_warning(record=False): + with warnings.catch_warnings(): warnings.filterwarnings("ignore", ".*MutableString", DeprecationWarning) test_support.run_unittest(UserStringTest, MutableStringTest) Index: Lib/test/test_support.py =================================================================== --- Lib/test/test_support.py (revision 66300) +++ Lib/test/test_support.py (working copy) @@ -18,7 +18,7 @@ "is_resource_enabled", "requires", "find_unused_port", "bind_port", "fcmp", "have_unicode", "is_jython", "TESTFN", "HOST", "FUZZ", "findfile", "verify", "vereq", "sortdict", "check_syntax_error", - "open_urlresource", "catch_warning", "CleanImport", + "open_urlresource", "CleanImport", "EnvironmentVarGuard", "captured_output", "captured_stdout", "TransientResource", "transient_internet", "run_with_locale", "set_memlimit", "bigmemtest", "bigaddrspacetest", @@ -52,7 +52,7 @@ def import_module(name, deprecated=False): """Import the module to be tested, raising TestSkipped if it is not available.""" - with catch_warning(record=False): + with warnings.catch_warnings(): if deprecated: warnings.filterwarnings("ignore", ".+ (module|package)", DeprecationWarning) @@ -381,10 +381,6 @@ return open(fn) -def catch_warning(module=warnings, record=True): - return warnings.catch_warnings(record=record, module=module) - - class CleanImport(object): """Context manager to force import to return a new module reference.