summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrett Cannon <bcannon@gmail.com>2008-09-09 00:49:16 (GMT)
committerBrett Cannon <bcannon@gmail.com>2008-09-09 00:49:16 (GMT)
commit672237dc6ca1498eabac08554bcbc5bd0fd9ddaa (patch)
tree1847849ac1bcb31cc345ad691242d846350097d6
parent631be01252d99e14ec8632ccb6ee898d11345d22 (diff)
downloadcpython-672237dc6ca1498eabac08554bcbc5bd0fd9ddaa.zip
cpython-672237dc6ca1498eabac08554bcbc5bd0fd9ddaa.tar.gz
cpython-672237dc6ca1498eabac08554bcbc5bd0fd9ddaa.tar.bz2
warnings.catch_warnings() now returns a list or None instead of the custom
WarningsRecorder object. This makes the API simpler to use as no special object must be learned. Closes issue 3781. Review by Benjamin Peterson.
-rw-r--r--Doc/library/warnings.rst112
-rw-r--r--Lib/asynchat.py1
-rw-r--r--Lib/bsddb/test/test_early_close.py6
-rw-r--r--Lib/mimetools.py2
-rw-r--r--Lib/test/test___all__.py4
-rw-r--r--Lib/test/test_exceptions.py6
-rw-r--r--Lib/test/test_hmac.py2
-rw-r--r--Lib/test/test_import.py16
-rw-r--r--Lib/test/test_macostools.py2
-rw-r--r--Lib/test/test_pep352.py14
-rw-r--r--Lib/test/test_py3kwarn.py100
-rw-r--r--Lib/test/test_random.py2
-rw-r--r--Lib/test/test_re.py4
-rw-r--r--Lib/test/test_struct.py4
-rw-r--r--Lib/test/test_structmembers.py14
-rw-r--r--Lib/test/test_sundry.py2
-rw-r--r--Lib/test/test_support.py8
-rw-r--r--Lib/test/test_symtable.py14
-rw-r--r--Lib/test/test_urllib.py2
-rw-r--r--Lib/test/test_urllibnet.py4
-rwxr-xr-xLib/test/test_userstring.py2
-rw-r--r--Lib/test/test_warnings.py142
-rw-r--r--Lib/warnings.py55
-rw-r--r--Misc/NEWS3
24 files changed, 268 insertions, 253 deletions
diff --git a/Doc/library/warnings.rst b/Doc/library/warnings.rst
index 68bc261..e9d0182 100644
--- a/Doc/library/warnings.rst
+++ b/Doc/library/warnings.rst
@@ -158,6 +158,67 @@ ImportWarning can also be enabled explicitly in Python code using::
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,31 +325,22 @@ Available Functions
and calls to :func:`simplefilter`.
-Available Classes
------------------
-
-.. 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.
+Available Context Managers
+--------------------------
- Typical usage of the context manager is like so::
+.. class:: catch_warnings([\*, record=False, module=None])
- 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.
.. note::
@@ -297,19 +349,3 @@ Available Classes
.. 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
diff --git a/Lib/asynchat.py b/Lib/asynchat.py
index a97de93..911833d 100644
--- a/Lib/asynchat.py
+++ b/Lib/asynchat.py
@@ -50,7 +50,6 @@ import socket
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):
diff --git a/Lib/bsddb/test/test_early_close.py b/Lib/bsddb/test/test_early_close.py
index 3d3396c..cc69e47 100644
--- a/Lib/bsddb/test/test_early_close.py
+++ b/Lib/bsddb/test/test_early_close.py
@@ -168,9 +168,9 @@ class DBEnvClosedEarlyCrash(unittest.TestCase):
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) :
diff --git a/Lib/mimetools.py b/Lib/mimetools.py
index fc5a2a5..71ca8f8 100644
--- a/Lib/mimetools.py
+++ b/Lib/mimetools.py
@@ -5,7 +5,7 @@ import os
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
diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py
index 9bd0083..0a8c5d6 100644
--- a/Lib/test/test___all__.py
+++ b/Lib/test/test___all__.py
@@ -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 @@ class AllTest(unittest.TestCase):
def check_all(self, modname):
names = {}
- with catch_warning():
+ with warnings.catch_warnings():
warnings.filterwarnings("ignore", ".* (module|package)",
DeprecationWarning)
try:
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index 0576b62..06a2378 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -4,9 +4,9 @@ import os
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 @@ class ExceptionTests(unittest.TestCase):
except NameError:
pass
- with catch_warning():
+ with warnings.catch_warnings():
ignore_message_warning()
for exc, args, expected in exceptionList:
try:
diff --git a/Lib/test/test_hmac.py b/Lib/test/test_hmac.py
index c57ac7f..d97583f 100644
--- a/Lib/test/test_hmac.py
+++ b/Lib/test/test_hmac.py
@@ -211,7 +211,7 @@ class TestVectorsTestCase(unittest.TestCase):
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)
diff --git a/Lib/test/test_import.py b/Lib/test/test_import.py
index ed9c7af..644a473 100644
--- a/Lib/test/test_import.py
+++ b/Lib/test/test_import.py
@@ -5,7 +5,7 @@ import shutil
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 @@ class ImportTest(unittest.TestCase):
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 @@ class RelativeImport(unittest.TestCase):
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())
diff --git a/Lib/test/test_macostools.py b/Lib/test/test_macostools.py
index da982d0..5c83d28 100644
--- a/Lib/test/test_macostools.py
+++ b/Lib/test/test_macostools.py
@@ -52,7 +52,7 @@ class TestMacostools(unittest.TestCase):
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)
diff --git a/Lib/test/test_pep352.py b/Lib/test/test_pep352.py
index 1867b9e..e335528 100644
--- a/Lib/test/test_pep352.py
+++ b/Lib/test/test_pep352.py
@@ -2,7 +2,7 @@ import unittest
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 @@ class ExceptionClassTests(unittest.TestCase):
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 @@ class ExceptionClassTests(unittest.TestCase):
# 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 @@ class ExceptionClassTests(unittest.TestCase):
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 @@ class ExceptionClassTests(unittest.TestCase):
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 @@ class ExceptionClassTests(unittest.TestCase):
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 @@ class UsageTests(unittest.TestCase):
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"
diff --git a/Lib/test/test_py3kwarn.py b/Lib/test/test_py3kwarn.py
index 780de74..aa1ecbb 100644
--- a/Lib/test/test_py3kwarn.py
+++ b/Lib/test/test_py3kwarn.py
@@ -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 @@ if not sys.py3kwarning:
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 @@ class TestPy3KWarnings(unittest.TestCase):
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 @@ class TestPy3KWarnings(unittest.TestCase):
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 @@ class TestPy3KWarnings(unittest.TestCase):
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 @@ class TestPy3KWarnings(unittest.TestCase):
'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 @@ class TestPy3KWarnings(unittest.TestCase):
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 @@ class TestPy3KWarnings(unittest.TestCase):
__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 @@ class TestPy3KWarnings(unittest.TestCase):
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 @@ class TestPy3KWarnings(unittest.TestCase):
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 @@ class TestStdlibRemovals(unittest.TestCase):
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 @@ class TestStdlibRemovals(unittest.TestCase):
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)
diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py
index 4d570d0..d82d391 100644
--- a/Lib/test/test_random.py
+++ b/Lib/test/test_random.py
@@ -191,7 +191,7 @@ class WichmannHill_TestBasicOps(TestBasicOps):
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)
diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py
index 1da3205..70bd886 100644
--- a/Lib/test/test_re.py
+++ b/Lib/test/test_re.py
@@ -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 @@ class ReTests(unittest.TestCase):
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
diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py
index ec4a2db..232bffc 100644
--- a/Lib/test/test_struct.py
+++ b/Lib/test/test_struct.py
@@ -4,7 +4,7 @@ import struct
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 bigendian_to_native(value):
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")
diff --git a/Lib/test/test_structmembers.py b/Lib/test/test_structmembers.py
index 6c1a947..e0e7e56 100644
--- a/Lib/test/test_structmembers.py
+++ b/Lib/test/test_structmembers.py
@@ -66,35 +66,35 @@ class ReadWriteTests(unittest.TestCase):
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)
diff --git a/Lib/test/test_sundry.py b/Lib/test/test_sundry.py
index 404a405..49ec12c 100644
--- a/Lib/test/test_sundry.py
+++ b/Lib/test/test_sundry.py
@@ -8,7 +8,7 @@ import warnings
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
diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py
index 695bd6d..0bf22cf 100644
--- a/Lib/test/test_support.py
+++ b/Lib/test/test_support.py
@@ -18,7 +18,7 @@ __all__ = ["Error", "TestFailed", "TestSkipped", "ResourceDenied", "import_modul
"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 @@ class ResourceDenied(TestSkipped):
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 @@ def open_urlresource(url):
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.
diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py
index 05b237a..b20f2b4 100644
--- a/Lib/test/test_symtable.py
+++ b/Lib/test/test_symtable.py
@@ -44,7 +44,7 @@ def find_block(block, name):
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 @@ class SymtableTest(unittest.TestCase):
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")
diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py
index 1dcbbed..7b351b8 100644
--- a/Lib/test/test_urllib.py
+++ b/Lib/test/test_urllib.py
@@ -641,7 +641,7 @@ class Pathname_Tests(unittest.TestCase):
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(
diff --git a/Lib/test/test_urllibnet.py b/Lib/test/test_urllibnet.py
index 0404b77..58fe282 100644
--- a/Lib/test/test_urllibnet.py
+++ b/Lib/test/test_urllibnet.py
@@ -182,8 +182,8 @@ class urlretrieveNetworkTests(unittest.TestCase):
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,
diff --git a/Lib/test/test_userstring.py b/Lib/test/test_userstring.py
index cae610e..4bb0c45 100755
--- a/Lib/test/test_userstring.py
+++ b/Lib/test/test_userstring.py
@@ -135,7 +135,7 @@ class MutableStringTest(UserStringTest):
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)
diff --git a/Lib/test/test_warnings.py b/Lib/test/test_warnings.py
index 9980f24..388b5e9 100644
--- a/Lib/test/test_warnings.py
+++ b/Lib/test/test_warnings.py
@@ -72,64 +72,69 @@ class FilterTests(object):
"""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 @@ class FilterTests(object):
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 @@ class FilterTests(object):
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 @@ class WarnTests(unittest.TestCase):
"""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 @@ class WarnTests(unittest.TestCase):
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 @@ class WarnTests(unittest.TestCase):
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 @@ class WarnTests(unittest.TestCase):
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 @@ class WarnTests(unittest.TestCase):
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 @@ class WCmdLineTests(unittest.TestCase):
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 @@ class _WarningsTests(BaseTest):
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 @@ class _WarningsTests(BaseTest):
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 @@ class _WarningsTests(BaseTest):
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 @@ class _WarningsTests(BaseTest):
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 @@ class PyWarningsDisplayTests(BaseTest, WarningsDisplayTests):
module = py_warnings
-
class CatchWarningTests(BaseTest):
"""Test catch_warnings()."""
@@ -511,12 +533,12 @@ class CatchWarningTests(BaseTest):
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 @@ class ShowwarningDeprecationTests(BaseTest):
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,
diff --git a/Lib/warnings.py b/Lib/warnings.py
index 9ec04be..04e7b58 100644
--- a/Lib/warnings.py
+++ b/Lib/warnings.py
@@ -8,7 +8,7 @@ import sys
import types
__all__ = ["warn", "showwarning", "formatwarning", "filterwarnings",
- "resetwarnings"]
+ "resetwarnings", "catch_warnings"]
def warnpy3k(message, category=None, stacklevel=1):
@@ -304,37 +304,20 @@ class WarningMessage(object):
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.
+
+ 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().
- 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 '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.
"""
@@ -346,17 +329,21 @@ class catch_warnings(object):
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._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
diff --git a/Misc/NEWS b/Misc/NEWS
index b2da2c5..b7da5f1 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -60,6 +60,9 @@ C-API
Library
-------
+- Issue 3781: Clean up the API for warnings.catch_warnings() by having it
+ return a list or None rather than a custom object.
+
- Issue #1638033: Cookie.Morsel gained the httponly attribute.
- Issue #3535: zipfile couldn't read some zip files larger than 2GB.