summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2008-10-16 23:24:44 (GMT)
committerBenjamin Peterson <benjamin@python.org>2008-10-16 23:24:44 (GMT)
commitfcf5d639f508b5a7ebf42d858390a6bd3bbb2c61 (patch)
tree193a1dd1d41e2403c61cd021409c28b843760cc6 /Lib
parentd31fdc547b1805516f6013af672e43cc66bd8c22 (diff)
downloadcpython-fcf5d639f508b5a7ebf42d858390a6bd3bbb2c61.zip
cpython-fcf5d639f508b5a7ebf42d858390a6bd3bbb2c61.tar.gz
cpython-fcf5d639f508b5a7ebf42d858390a6bd3bbb2c61.tar.bz2
forward port r66386
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/support.py32
-rw-r--r--Lib/test/test_import.py13
-rw-r--r--Lib/test/test_structmembers.py14
-rw-r--r--Lib/test/test_sundry.py2
-rw-r--r--Lib/test/test_threading.py2
-rw-r--r--Lib/test/test_warnings.py63
-rw-r--r--Lib/warnings.py15
7 files changed, 111 insertions, 30 deletions
diff --git a/Lib/test/support.py b/Lib/test/support.py
index a23c99b..5f8b1ba 100644
--- a/Lib/test/support.py
+++ b/Lib/test/support.py
@@ -19,7 +19,7 @@ __all__ = ["Error", "TestFailed", "TestSkipped", "ResourceDenied", "import_modul
"is_resource_enabled", "requires", "find_unused_port", "bind_port",
"fcmp", "is_jython", "TESTFN", "HOST", "FUZZ", "findfile", "verify",
"vereq", "sortdict", "check_syntax_error", "open_urlresource",
- "catch_warning", "CleanImport", "EnvironmentVarGuard",
+ "check_warnings", "CleanImport", "EnvironmentVarGuard",
"TransientResource", "captured_output", "captured_stdout",
"TransientResource", "transient_internet", "run_with_locale",
"set_memlimit", "bigmemtest", "bigaddrspacetest", "BasicTestRunner",
@@ -53,7 +53,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)
@@ -368,17 +368,27 @@ def open_urlresource(url, *args, **kw):
return open(fn, *args, **kw)
-def catch_warning(module=warnings, record=True):
- """Guard the warnings filter from being permanently changed and
- optionally record the details of any warnings that are issued.
+class WarningsRecorder(object):
+ """Convenience wrapper for the warnings list returned on
+ entry to the warnings.catch_warnings() context manager.
+ """
+ def __init__(self, warnings_list):
+ self.warnings = warnings_list
- Use like this:
+ def __getattr__(self, attr):
+ if self.warnings:
+ return getattr(self.warnings[-1], attr)
+ elif attr in warnings.WarningMessage._WARNING_DETAILS:
+ return None
+ raise AttributeError("%r has no attribute %r" % (self, attr))
- with catch_warning() as w:
- warnings.warn("foo")
- assert str(w.message) == "foo"
- """
- return warnings.catch_warnings(record=record, module=module)
+ def reset(self):
+ del self.warnings[:]
+
+@contextlib.contextmanager
+def check_warnings():
+ with warnings.catch_warnings(record=True) as w:
+ yield WarningsRecorder(w)
class CleanImport(object):
diff --git a/Lib/test/test_import.py b/Lib/test/test_import.py
index 0dbbbf0..6598d4e 100644
--- a/Lib/test/test_import.py
+++ b/Lib/test/test_import.py
@@ -266,21 +266,24 @@ class RelativeImport(unittest.TestCase):
self.assertTrue(hasattr(relimport, "RelativeImport"))
def test_issue3221(self):
+ # Note for mergers: the 'absolute' tests from the 2.x branch
+ # are missing in Py3k because implicit relative imports are
+ # a thing of the past
def check_relative():
exec("from . import relimport", ns)
- # Check both OK with __package__ and __name__ correct
+ # Check relative import OK with __package__ and __name__ correct
ns = dict(__package__='test', __name__='test.notarealmodule')
check_relative()
- # Check both OK with only __name__ wrong
+ # Check relative import OK with only __name__ wrong
ns = dict(__package__='test', __name__='notarealpkg.notarealmodule')
check_relative()
- # Check relative fails with only __package__ wrong
+ # Check relative import fails with only __package__ wrong
ns = dict(__package__='foo', __name__='test.notarealmodule')
self.assertRaises(SystemError, check_relative)
- # Check relative fails with __package__ and __name__ wrong
+ # Check relative import fails with __package__ and __name__ wrong
ns = dict(__package__='foo', __name__='notarealpkg.notarealmodule')
self.assertRaises(SystemError, check_relative)
- # Check both fail with package set to a non-string
+ # Check relative import fails with package set to a non-string
ns = dict(__package__=object())
self.assertRaises(ValueError, check_relative)
diff --git a/Lib/test/test_structmembers.py b/Lib/test/test_structmembers.py
index 878223a..93e040c 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[-1].category, RuntimeWarning)
+ self.assertEqual(w.category, RuntimeWarning)
def test_byte_max(self):
- with warnings.catch_warnings(record=True) as w:
+ with support.check_warnings() as w:
ts.T_BYTE = CHAR_MAX+1
self.has_warned(w)
def test_byte_min(self):
- with warnings.catch_warnings(record=True) as w:
+ with support.check_warnings() as w:
ts.T_BYTE = CHAR_MIN-1
self.has_warned(w)
def test_ubyte_max(self):
- with warnings.catch_warnings(record=True) as w:
+ with support.check_warnings() as w:
ts.T_UBYTE = UCHAR_MAX+1
self.has_warned(w)
def test_short_max(self):
- with warnings.catch_warnings(record=True) as w:
+ with support.check_warnings() as w:
ts.T_SHORT = SHRT_MAX+1
self.has_warned(w)
def test_short_min(self):
- with warnings.catch_warnings(record=True) as w:
+ with support.check_warnings() as w:
ts.T_SHORT = SHRT_MIN-1
self.has_warned(w)
def test_ushort_max(self):
- with warnings.catch_warnings(record=True) as w:
+ with support.check_warnings() 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 6b425c6..49813a3 100644
--- a/Lib/test/test_sundry.py
+++ b/Lib/test/test_sundry.py
@@ -7,7 +7,7 @@ import warnings
class TestUntestedModules(unittest.TestCase):
def test_at_least_import_untested_modules(self):
- with warnings.catch_warnings(record=True):
+ with warnings.catch_warnings():
import aifc
import bdb
import cgitb
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py
index f26e7bb..956672d 100644
--- a/Lib/test/test_threading.py
+++ b/Lib/test/test_threading.py
@@ -1,7 +1,7 @@
# Very rudimentary test of threading module
import test.support
-from test.support import verbose, catch_warning
+from test.support import verbose
import random
import re
import sys
diff --git a/Lib/test/test_warnings.py b/Lib/test/test_warnings.py
index 199e6fc..4b6feb3 100644
--- a/Lib/test/test_warnings.py
+++ b/Lib/test/test_warnings.py
@@ -214,7 +214,8 @@ class WarnTests(unittest.TestCase):
def test_warn_nonstandard_types(self):
# warn() should handle non-standard types without issue.
for ob in (Warning, None, 42):
- with support.catch_warning(self.module) as w:
+ with original_warnings.catch_warnings(record=True,
+ module=self.module) as w:
self.module.warn(ob)
# Don't directly compare objects since
# ``Warning() != Warning()``.
@@ -526,19 +527,23 @@ class CatchWarningTests(BaseTest):
wmod = self.module
orig_filters = wmod.filters
orig_showwarning = wmod.showwarning
- with support.catch_warning(module=wmod):
+ # Ensure both showwarning and filters are restored when recording
+ with wmod.catch_warnings(module=wmod, record=True):
wmod.filters = wmod.showwarning = object()
self.assert_(wmod.filters is orig_filters)
self.assert_(wmod.showwarning is orig_showwarning)
- with support.catch_warning(module=wmod, record=False):
+ # Same test, but with recording disabled
+ with wmod.catch_warnings(module=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_warnings_recording(self):
wmod = self.module
- with support.catch_warning(module=wmod) as w:
+ # Ensure warnings are recorded when requested
+ with wmod.catch_warnings(module=wmod, record=True) as w:
self.assertEqual(w, [])
+ self.assert_(type(w) is list)
wmod.simplefilter("always")
wmod.warn("foo")
self.assertEqual(str(w[-1].message), "foo")
@@ -548,11 +553,59 @@ class CatchWarningTests(BaseTest):
self.assertEqual(str(w[1].message), "bar")
del w[:]
self.assertEqual(w, [])
+ # Ensure warnings are not recorded when not requested
orig_showwarning = wmod.showwarning
- with support.catch_warning(module=wmod, record=False) as w:
+ with wmod.catch_warnings(module=wmod, record=False) as w:
self.assert_(w is None)
self.assert_(wmod.showwarning is orig_showwarning)
+ def test_catch_warnings_reentry_guard(self):
+ wmod = self.module
+ # Ensure catch_warnings is protected against incorrect usage
+ x = wmod.catch_warnings(module=wmod, record=True)
+ self.assertRaises(RuntimeError, x.__exit__)
+ with x:
+ self.assertRaises(RuntimeError, x.__enter__)
+ # Same test, but with recording disabled
+ x = wmod.catch_warnings(module=wmod, record=False)
+ self.assertRaises(RuntimeError, x.__exit__)
+ with x:
+ self.assertRaises(RuntimeError, x.__enter__)
+
+ def test_catch_warnings_defaults(self):
+ wmod = self.module
+ orig_filters = wmod.filters
+ orig_showwarning = wmod.showwarning
+ # Ensure default behaviour is not to record warnings
+ with wmod.catch_warnings(module=wmod) as w:
+ self.assert_(w is None)
+ self.assert_(wmod.showwarning is orig_showwarning)
+ self.assert_(wmod.filters is not orig_filters)
+ self.assert_(wmod.filters is orig_filters)
+ if wmod is sys.modules['warnings']:
+ # Ensure the default module is this one
+ with wmod.catch_warnings() as w:
+ self.assert_(w is None)
+ self.assert_(wmod.showwarning is orig_showwarning)
+ self.assert_(wmod.filters is not orig_filters)
+ self.assert_(wmod.filters is orig_filters)
+
+ def test_check_warnings(self):
+ # Explicit tests for the test.support convenience wrapper
+ wmod = self.module
+ if wmod is sys.modules['warnings']:
+ with support.check_warnings() 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, [])
+
class CCatchWarningTests(CatchWarningTests):
module = c_warnings
diff --git a/Lib/warnings.py b/Lib/warnings.py
index 0e147db..b87d1be 100644
--- a/Lib/warnings.py
+++ b/Lib/warnings.py
@@ -301,8 +301,21 @@ class catch_warnings(object):
"""
self._record = record
self._module = sys.modules['warnings'] if module is None else module
+ self._entered = False
+
+ def __repr__(self):
+ args = []
+ if self._record:
+ args.append("record=True")
+ if self._module is not sys.modules['warnings']:
+ args.append("module=%r" % self._module)
+ name = type(self).__name__
+ return "%s(%s)" % (name, ", ".join(args))
def __enter__(self):
+ if self._entered:
+ raise RuntimeError("Cannot enter %r twice" % self)
+ self._entered = True
self._filters = self._module.filters
self._module.filters = self._filters[:]
self._showwarning = self._module.showwarning
@@ -316,6 +329,8 @@ class catch_warnings(object):
return None
def __exit__(self, *exc_info):
+ if not self._entered:
+ raise RuntimeError("Cannot exit %r without entering first" % self)
self._module.filters = self._filters
self._module.showwarning = self._showwarning