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
and calls to :func:`simplefilter`.
-Available Classes
------------------
+Available Context Managers
+--------------------------
.. 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.
-
- Typical usage of the context manager is like so::
-
- def fxn():
- warn("fxn is deprecated", DeprecationWarning)
- return "spam spam bacon spam"
+ 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`.
- # 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.
+ 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.
.. versionadded:: 2.6
Constructor arguments turned into keyword-only arguments.
-
-.. 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
"""Testing the filtering functionality."""
def test_error(self):
- with 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 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 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 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 range(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 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 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)
self.assertEquals(len(w), 0)
def test_inheritance(self):
- with 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 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:
def test_filterwarnings(self):
# Test filterwarnings().
# Implicitly also tests resetwarnings().
- with 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
"""Test warnings.warn() and warnings.warn_explicit()."""
def test_message(self):
- with 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)
# Issue 3639
def test_warn_nonstandard_types(self):
self.module.warn(ob)
# Don't directly compare objects since
# ``Warning() != Warning()``.
- self.assertEquals(str(w.message), str(UserWarning(ob)))
+ self.assertEquals(str(w[-1].message), str(UserWarning(ob)))
def test_filename(self):
with warnings_state(self.module):
- with 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 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,
try:
del warning_tests.__file__
with warnings_state(self.module):
- with 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
del warning_tests.__file__
warning_tests.__name__ = '__main__'
with warnings_state(self.module):
- with 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
warning_tests.__name__ = '__main__'
del sys.argv
with warnings_state(self.module):
- with 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
warning_tests.__name__ = '__main__'
sys.argv = ['']
with warnings_state(self.module):
- with 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
def test_improper_input(self):
# Uses the private _setoption() function to test the parsing
# of command-line warning arguments
- with 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,
def test_filter(self):
# Everything should function even if 'filters' is not in warnings.
- with 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')
try:
original_registry = self.module.onceregistry
__warningregistry__ = {}
- with 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)
def test_showwarning_missing(self):
# Test that showwarning() missing is okay.
text = 'del showwarning test'
- with support.catch_warning(self.module):
+ with original_warnings.catch_warnings(module=self.module):
self.module.filterwarnings("always", category=UserWarning)
del self.module.showwarning
with support.captured_output('stderr') as stream:
def test_show_warning_output(self):
# With showarning() missing, make sure that output is okay.
text = 'test show_warning'
- with support.catch_warning(self.module):
+ with original_warnings.catch_warnings(module=self.module):
self.module.filterwarnings("always", category=UserWarning)
del self.module.showwarning
with support.captured_output('stderr') as stream:
class PyWarningsDisplayTests(BaseTest, WarningsDisplayTests):
module = py_warnings
+
class CatchWarningTests(BaseTest):
"""Test catch_warnings()."""
self.assertEqual(w, [])
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 support.catch_warning(module=wmod, record=False) as w: