summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
authorNick Coghlan <ncoghlan@gmail.com>2008-07-13 12:23:47 (GMT)
committerNick Coghlan <ncoghlan@gmail.com>2008-07-13 12:23:47 (GMT)
commit38469e271929399c12d6770d91958d8abac7433a (patch)
treeb347e1d7a9b8176cae5bc57b7f9f5180c7438064 /Lib/test
parent3d0b9f095a1ccda7d6c04a9a1d05d245d8b82e26 (diff)
downloadcpython-38469e271929399c12d6770d91958d8abac7433a.zip
cpython-38469e271929399c12d6770d91958d8abac7433a.tar.gz
cpython-38469e271929399c12d6770d91958d8abac7433a.tar.bz2
Make test.test_support.catch_warnings more robust as discussed on python-dev. Also add explicit tests for itto test_warnings.
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/test_py3kwarn.py30
-rw-r--r--Lib/test/test_struct.py11
-rw-r--r--Lib/test/test_support.py71
-rw-r--r--Lib/test/test_warnings.py45
4 files changed, 94 insertions, 63 deletions
diff --git a/Lib/test/test_py3kwarn.py b/Lib/test/test_py3kwarn.py
index a289cc7..0d01572 100644
--- a/Lib/test/test_py3kwarn.py
+++ b/Lib/test/test_py3kwarn.py
@@ -26,41 +26,30 @@ class TestPy3KWarnings(unittest.TestCase):
with catch_warning() as w:
safe_exec("True = False")
self.assertWarning(None, w, expected)
- with catch_warning() as w:
safe_exec("False = True")
self.assertWarning(None, w, expected)
- with catch_warning() as w:
try:
safe_exec("obj.False = True")
except NameError: pass
self.assertWarning(None, w, expected)
- with catch_warning() as w:
try:
safe_exec("obj.True = False")
except NameError: pass
self.assertWarning(None, w, expected)
- with catch_warning() as w:
safe_exec("def False(): pass")
self.assertWarning(None, w, expected)
- with catch_warning() as w:
safe_exec("def True(): pass")
self.assertWarning(None, w, expected)
- with catch_warning() as w:
safe_exec("class False: pass")
self.assertWarning(None, w, expected)
- with catch_warning() as w:
safe_exec("class True: pass")
self.assertWarning(None, w, expected)
- with catch_warning() as w:
safe_exec("def f(True=43): pass")
self.assertWarning(None, w, expected)
- with catch_warning() as w:
safe_exec("def f(False=None): pass")
self.assertWarning(None, w, expected)
- with catch_warning() as w:
safe_exec("f(False=True)")
self.assertWarning(None, w, expected)
- with catch_warning() as w:
safe_exec("f(True=1)")
self.assertWarning(None, w, expected)
@@ -69,25 +58,20 @@ class TestPy3KWarnings(unittest.TestCase):
expected = 'type inequality comparisons not supported in 3.x'
with catch_warning() as w:
self.assertWarning(int < str, w, expected)
- with catch_warning() as w:
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:
self.assertWarning(str < [], w, expected)
- with catch_warning() as w:
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:
self.assertWarning({} < {2:3}, w, expected)
- with catch_warning() as w:
self.assertWarning({} <= {}, w, expected)
- with catch_warning() as w:
self.assertWarning({} > {2:3}, w, expected)
- with catch_warning() as w:
self.assertWarning({2:3} >= {}, w, expected)
def test_cell_inequality_comparisons(self):
@@ -100,7 +84,6 @@ class TestPy3KWarnings(unittest.TestCase):
cell1, = f(1).func_closure
with catch_warning() as w:
self.assertWarning(cell0 == cell1, w, expected)
- with catch_warning() as w:
self.assertWarning(cell0 < cell1, w, expected)
def test_code_inequality_comparisons(self):
@@ -111,11 +94,8 @@ class TestPy3KWarnings(unittest.TestCase):
pass
with catch_warning() as w:
self.assertWarning(f.func_code < g.func_code, w, expected)
- with catch_warning() as w:
self.assertWarning(f.func_code <= g.func_code, w, expected)
- with catch_warning() as w:
self.assertWarning(f.func_code >= g.func_code, w, expected)
- with catch_warning() as w:
self.assertWarning(f.func_code > g.func_code, w, expected)
def test_builtin_function_or_method_comparisons(self):
@@ -125,11 +105,8 @@ class TestPy3KWarnings(unittest.TestCase):
meth = {}.get
with catch_warning() as w:
self.assertWarning(func < meth, w, expected)
- with catch_warning() as w:
self.assertWarning(func > meth, w, expected)
- with catch_warning() as w:
self.assertWarning(meth <= func, w, expected)
- with catch_warning() as w:
self.assertWarning(meth >= func, w, expected)
def assertWarning(self, _, warning, expected_message):
@@ -142,11 +119,8 @@ class TestPy3KWarnings(unittest.TestCase):
with catch_warning() as w:
self.assertWarning(lst.sort(cmp=cmp), w, expected)
- with catch_warning() as w:
self.assertWarning(sorted(lst, cmp=cmp), w, expected)
- with catch_warning() as w:
self.assertWarning(lst.sort(cmp), w, expected)
- with catch_warning() as w:
self.assertWarning(sorted(lst, cmp), w, expected)
def test_sys_exc_clear(self):
@@ -229,7 +203,7 @@ class TestStdlibRemovals(unittest.TestCase):
"""Make sure the specified module, when imported, raises a
DeprecationWarning and specifies itself in the message."""
with CleanImport(module_name):
- with catch_warning(record=False) as w:
+ with catch_warning(record=False):
warnings.filterwarnings("error", ".+ removed",
DeprecationWarning)
try:
@@ -290,7 +264,7 @@ class TestStdlibRemovals(unittest.TestCase):
def test_main():
- with catch_warning(record=True):
+ with catch_warning():
warnings.simplefilter("always")
run_unittest(TestPy3KWarnings,
TestStdlibRemovals)
diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py
index 7fd058b..5e4f0cc 100644
--- a/Lib/test/test_struct.py
+++ b/Lib/test/test_struct.py
@@ -35,12 +35,9 @@ def with_warning_restore(func):
@wraps(func)
def decorator(*args, **kw):
with catch_warning():
- # Grrr, we need this function to warn every time. Without removing
- # the warningregistry, running test_tarfile then test_struct would fail
- # on 64-bit platforms.
- globals = func.func_globals
- if '__warningregistry__' in globals:
- del globals['__warningregistry__']
+ # We need this function to warn every time, so stick an
+ # unqualifed 'always' at the head of the filter list
+ warnings.simplefilter("always")
warnings.filterwarnings("error", category=DeprecationWarning)
return func(*args, **kw)
return decorator
@@ -53,7 +50,7 @@ def deprecated_err(func, *args):
pass
except DeprecationWarning:
if not PY_STRUCT_OVERFLOW_MASKING:
- raise TestFailed, "%s%s expected to raise struct.error" % (
+ raise TestFailed, "%s%s expected to raise DeprecationWarning" % (
func.__name__, args)
else:
raise TestFailed, "%s%s did not raise error" % (
diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py
index 848c7d1..02a8cca 100644
--- a/Lib/test/test_support.py
+++ b/Lib/test/test_support.py
@@ -383,36 +383,49 @@ def open_urlresource(url):
class WarningMessage(object):
- "Holds the result of the latest showwarning() call"
+ "Holds the result of a single showwarning() call"
+ _WARNING_DETAILS = "message category filename lineno line".split()
+ def __init__(self, message, category, filename, lineno, line=None):
+ for attr in self._WARNING_DETAILS:
+ setattr(self, attr, locals()[attr])
+ self._category_name = category.__name__ if category else None
+
+ def __str__(self):
+ return ("{message : %r, category : %r, filename : %r, lineno : %s, "
+ "line : %r}" % (self.message, self._category_name,
+ self.filename, self.lineno, self.line))
+
+class WarningRecorder(object):
+ "Records the result of any showwarning calls"
def __init__(self):
- self.message = None
- self.category = None
- self.filename = None
- self.lineno = None
-
- def _showwarning(self, message, category, filename, lineno, file=None,
- line=None):
- self.message = message
- self.category = category
- self.filename = filename
- self.lineno = lineno
- self.line = line
+ self.warnings = []
+ self._set_last(None)
+
+ def _showwarning(self, message, category, filename, lineno,
+ file=None, line=None):
+ wm = WarningMessage(message, category, filename, lineno, line)
+ self.warnings.append(wm)
+ self._set_last(wm)
+
+ def _set_last(self, last_warning):
+ if last_warning is None:
+ for attr in WarningMessage._WARNING_DETAILS:
+ setattr(self, attr, None)
+ else:
+ for attr in WarningMessage._WARNING_DETAILS:
+ setattr(self, attr, getattr(last_warning, attr))
def reset(self):
- self._showwarning(*((None,)*6))
+ self.warnings = []
+ self._set_last(None)
def __str__(self):
- return ("{message : %r, category : %r, filename : %r, lineno : %s, "
- "line : %r}" % (self.message,
- self.category.__name__ if self.category else None,
- self.filename, self.lineno, self.line))
-
+ return '[%s]' % (', '.join(map(str, self.warnings)))
@contextlib.contextmanager
def catch_warning(module=warnings, record=True):
- """
- Guard the warnings filter from being permanently changed and record the
- data of the last warning that has been issued.
+ """Guard the warnings filter from being permanently changed and
+ optionally record the details of any warnings that are issued.
Use like this:
@@ -420,13 +433,17 @@ def catch_warning(module=warnings, record=True):
warnings.warn("foo")
assert str(w.message) == "foo"
"""
- original_filters = module.filters[:]
+ original_filters = module.filters
original_showwarning = module.showwarning
if record:
- warning_obj = WarningMessage()
- module.showwarning = warning_obj._showwarning
+ recorder = WarningRecorder()
+ module.showwarning = recorder._showwarning
+ else:
+ recorder = None
try:
- yield warning_obj if record else None
+ # Replace the filters with a copy of the original
+ module.filters = module.filters[:]
+ yield recorder
finally:
module.showwarning = original_showwarning
module.filters = original_filters
@@ -436,7 +453,7 @@ class CleanImport(object):
"""Context manager to force import to return a new module reference.
This is useful for testing module-level behaviours, such as
- the emission of a DepreciationWarning on import.
+ the emission of a DeprecationWarning on import.
Use like this:
diff --git a/Lib/test/test_warnings.py b/Lib/test/test_warnings.py
index ed498e0..7c1706a 100644
--- a/Lib/test/test_warnings.py
+++ b/Lib/test/test_warnings.py
@@ -488,6 +488,49 @@ class PyWarningsDisplayTests(BaseTest, WarningsDisplayTests):
module = py_warnings
+
+class WarningsSupportTests(object):
+ """Test the warning tools from test support module"""
+
+ def test_catch_warning_restore(self):
+ wmod = self.module
+ orig_filters = wmod.filters
+ orig_showwarning = wmod.showwarning
+ with test_support.catch_warning(wmod):
+ wmod.filters = wmod.showwarning = object()
+ self.assert_(wmod.filters is orig_filters)
+ self.assert_(wmod.showwarning is orig_showwarning)
+ with test_support.catch_warning(wmod, record=False):
+ wmod.filters = wmod.showwarning = object()
+ self.assert_(wmod.filters is orig_filters)
+ self.assert_(wmod.showwarning is orig_showwarning)
+
+ def test_catch_warning_recording(self):
+ wmod = self.module
+ with test_support.catch_warning(wmod) as w:
+ self.assertEqual(w.warnings, [])
+ wmod.simplefilter("always")
+ wmod.warn("foo")
+ self.assertEqual(str(w.message), "foo")
+ wmod.warn("bar")
+ self.assertEqual(str(w.message), "bar")
+ self.assertEqual(str(w.warnings[0].message), "foo")
+ self.assertEqual(str(w.warnings[1].message), "bar")
+ w.reset()
+ self.assertEqual(w.warnings, [])
+ orig_showwarning = wmod.showwarning
+ with test_support.catch_warning(wmod, record=False) as w:
+ self.assert_(w is None)
+ self.assert_(wmod.showwarning is orig_showwarning)
+
+
+class CWarningsSupportTests(BaseTest, WarningsSupportTests):
+ module = c_warnings
+
+class PyWarningsSupportTests(BaseTest, WarningsSupportTests):
+ module = py_warnings
+
+
class ShowwarningDeprecationTests(BaseTest):
"""Test the deprecation of the old warnings.showwarning() API works."""
@@ -513,7 +556,6 @@ class PyShowwarningDeprecationTests(ShowwarningDeprecationTests):
module = py_warnings
-
def test_main():
py_warnings.onceregistry.clear()
c_warnings.onceregistry.clear()
@@ -524,6 +566,7 @@ def test_main():
CWCmdLineTests, PyWCmdLineTests,
_WarningsTests,
CWarningsDisplayTests, PyWarningsDisplayTests,
+ CWarningsSupportTests, PyWarningsSupportTests,
CShowwarningDeprecationTests,
PyShowwarningDeprecationTests,
)