[Python-checkins] r54677 - in python/trunk: Lib/test/test_structmembers.py Lib/test/test_support.py Lib/test/test_warnings.py Misc/NEWS

walter.doerwald python-checkins at python.org
Tue Apr 3 20:33:37 CEST 2007


Author: walter.doerwald
Date: Tue Apr  3 20:33:29 2007
New Revision: 54677

Modified:
   python/trunk/Lib/test/test_structmembers.py
   python/trunk/Lib/test/test_support.py
   python/trunk/Lib/test/test_warnings.py
   python/trunk/Misc/NEWS
Log:
Implement a contextmanager test.test_support.catch_warning that can
be used to catch the last warning issued by the warning framework.

Change test_warnings.py and test_structmembers.py to use this
new contextmanager.


Modified: python/trunk/Lib/test/test_structmembers.py
==============================================================================
--- python/trunk/Lib/test/test_structmembers.py	(original)
+++ python/trunk/Lib/test/test_structmembers.py	Tue Apr  3 20:33:29 2007
@@ -4,7 +4,7 @@
     INT_MAX, INT_MIN, UINT_MAX, \
     LONG_MAX, LONG_MIN, ULONG_MAX
 
-import warnings, exceptions, unittest, test.test_warnings
+import warnings, exceptions, unittest
 from test import test_support
 
 ts=test_structmembersType(1,2,3,4,5,6,7,8,9.99999,10.1010101010)
@@ -39,34 +39,39 @@
         ts.T_ULONG=ULONG_MAX
         self.assertEquals(ts.T_ULONG, ULONG_MAX)
 
-class TestWarnings(test.test_warnings.CatchWarningTest):
-    def has_warned(self):
-        self.assertEqual(test.test_warnings.msg.category,
-                         exceptions.RuntimeWarning.__name__)
+class TestWarnings(unittest.TestCase):
+    def has_warned(self, w):
+        self.assert_(w.category is RuntimeWarning)
 
     def test_byte_max(self):
-        ts.T_BYTE=CHAR_MAX+1
-        self.has_warned()
+        with test_support.catch_warning() as w:
+            ts.T_BYTE=CHAR_MAX+1
+            self.has_warned(w)
 
     def test_byte_min(self):
-        ts.T_BYTE=CHAR_MIN-1
-        self.has_warned()
+        with test_support.catch_warning() as w:
+            ts.T_BYTE=CHAR_MIN-1
+            self.has_warned(w)
 
     def test_ubyte_max(self):
-        ts.T_UBYTE=UCHAR_MAX+1
-        self.has_warned()
+        with test_support.catch_warning() as w:
+            ts.T_UBYTE=UCHAR_MAX+1
+            self.has_warned(w)
 
     def test_short_max(self):
-        ts.T_SHORT=SHRT_MAX+1
-        self.has_warned()
+        with test_support.catch_warning() as w:
+            ts.T_SHORT=SHRT_MAX+1
+            self.has_warned(w)
 
     def test_short_min(self):
-        ts.T_SHORT=SHRT_MIN-1
-        self.has_warned()
+        with test_support.catch_warning() as w:
+            ts.T_SHORT=SHRT_MIN-1
+            self.has_warned(w)
 
     def test_ushort_max(self):
-        ts.T_USHORT=USHRT_MAX+1
-        self.has_warned()
+        with test_support.catch_warning() as w:
+            ts.T_USHORT=USHRT_MAX+1
+            self.has_warned(w)
 
 
 

Modified: python/trunk/Lib/test/test_support.py
==============================================================================
--- python/trunk/Lib/test/test_support.py	(original)
+++ python/trunk/Lib/test/test_support.py	Tue Apr  3 20:33:29 2007
@@ -282,6 +282,42 @@
     finally:
         warnings.filters = original_filters
 
+class WarningMessage(object):
+    "Holds the result of the latest showwarning() call"
+    def __init__(self):
+        self.message = None
+        self.category = None
+        self.filename = None
+        self.lineno = None
+
+    def _showwarning(self, message, category, filename, lineno, file=None):
+        self.message = message
+        self.category = category
+        self.filename = filename
+        self.lineno = lineno
+
+ at contextlib.contextmanager
+def catch_warning():
+    """
+    Guard the warnings filter from being permanently changed and record the
+    data of the last warning that has been issued.
+
+    Use like this:
+
+        with catch_warning as w:
+            warnings.warn("foo")
+            assert str(w.message) == "foo"
+    """
+    warning = WarningMessage()
+    original_filters = warnings.filters[:]
+    original_showwarning = warnings.showwarning
+    warnings.showwarning = warning._showwarning
+    try:
+        yield warning
+    finally:
+        warnings.showwarning = original_showwarning
+        warnings.filters = original_filters
+
 class EnvironmentVarGuard(object):
 
     """Class to help protect the environment variable properly.  Can be used as

Modified: python/trunk/Lib/test/test_warnings.py
==============================================================================
--- python/trunk/Lib/test/test_warnings.py	(original)
+++ python/trunk/Lib/test/test_warnings.py	Tue Apr  3 20:33:29 2007
@@ -5,121 +5,95 @@
 
 import warning_tests
 
-# The warnings module isn't easily tested, because it relies on module
-# globals to store configuration information.  setUp() and tearDown()
-# preserve the current settings to avoid bashing them while running tests.
-
-# To capture the warning messages, a replacement for showwarning() is
-# used to save warning information in a global variable.
-
-class WarningMessage:
-    "Holds results of latest showwarning() call"
-    pass
-
-def showwarning(message, category, filename, lineno, file=None):
-    msg.message = str(message)
-    msg.category = category.__name__
-    msg.filename = os.path.basename(filename)
-    msg.lineno = lineno
-
-class CatchWarningTest(unittest.TestCase):
-    # base class used for catching warnings issued by the
-    # warning framework (this is reused by test_structmembers.py)
-
+class TestModule(unittest.TestCase):
     def setUp(self):
-        global msg
-        msg = WarningMessage()
-        self._filters = warnings.filters[:]
-        self._showwarning = warnings.showwarning
-        warnings.showwarning = showwarning
-        self.ignored = [w[2].__name__ for w in self._filters
+        self.ignored = [w[2].__name__ for w in warnings.filters
             if w[0]=='ignore' and w[1] is None and w[3] is None]
 
-    def tearDown(self):
-        warnings.filters = self._filters[:]
-        warnings.showwarning = self._showwarning
-
-class TestModule(CatchWarningTest):
-
     def test_warn_default_category(self):
-        for i in range(4):
-            text = 'multi %d' %i    # Different text on each call
-            warnings.warn(text)
-            self.assertEqual(msg.message, text)
-            self.assertEqual(msg.category, 'UserWarning')
+        with test_support.catch_warning() as w:
+            for i in range(4):
+                text = 'multi %d' %i    # Different text on each call
+                warnings.warn(text)
+                self.assertEqual(str(w.message), text)
+                self.assert_(w.category is UserWarning)
 
     def test_warn_specific_category(self):
-        text = 'None'
-        for category in [DeprecationWarning, FutureWarning,
-                    PendingDeprecationWarning, RuntimeWarning,
-                    SyntaxWarning, UserWarning, Warning]:
-            if category.__name__ in self.ignored:
-                text = 'filtered out' + category.__name__
-                warnings.warn(text, category)
-                self.assertNotEqual(msg.message, text)
-            else:
-                text = 'unfiltered %s' % category.__name__
-                warnings.warn(text, category)
-                self.assertEqual(msg.message, text)
-                self.assertEqual(msg.category, category.__name__)
+        with test_support.catch_warning() as w:
+            text = 'None'
+            for category in [DeprecationWarning, FutureWarning,
+                        PendingDeprecationWarning, RuntimeWarning,
+                        SyntaxWarning, UserWarning, Warning]:
+                if category.__name__ in self.ignored:
+                    text = 'filtered out' + category.__name__
+                    warnings.warn(text, category)
+                    self.assertNotEqual(w.message, text)
+                else:
+                    text = 'unfiltered %s' % category.__name__
+                    warnings.warn(text, category)
+                    self.assertEqual(str(w.message), text)
+                    self.assert_(w.category is category)
 
     def test_filtering(self):
+        with test_support.catch_warning() as w:
+            warnings.filterwarnings("error", "", Warning, "", 0)
+            self.assertRaises(UserWarning, warnings.warn, 'convert to error')
 
-        warnings.filterwarnings("error", "", Warning, "", 0)
-        self.assertRaises(UserWarning, warnings.warn, 'convert to error')
+            warnings.resetwarnings()
+            text = 'handle normally'
+            warnings.warn(text)
+            self.assertEqual(str(w.message), text)
+            self.assert_(w.category is UserWarning)
+
+            warnings.filterwarnings("ignore", "", Warning, "", 0)
+            text = 'filtered out'
+            warnings.warn(text)
+            self.assertNotEqual(str(w.message), text)
 
-        warnings.resetwarnings()
-        text = 'handle normally'
-        warnings.warn(text)
-        self.assertEqual(msg.message, text)
-        self.assertEqual(msg.category, 'UserWarning')
-
-        warnings.filterwarnings("ignore", "", Warning, "", 0)
-        text = 'filtered out'
-        warnings.warn(text)
-        self.assertNotEqual(msg.message, text)
-
-        warnings.resetwarnings()
-        warnings.filterwarnings("error", "hex*", Warning, "", 0)
-        self.assertRaises(UserWarning, warnings.warn, 'hex/oct')
-        text = 'nonmatching text'
-        warnings.warn(text)
-        self.assertEqual(msg.message, text)
-        self.assertEqual(msg.category, 'UserWarning')
+            warnings.resetwarnings()
+            warnings.filterwarnings("error", "hex*", Warning, "", 0)
+            self.assertRaises(UserWarning, warnings.warn, 'hex/oct')
+            text = 'nonmatching text'
+            warnings.warn(text)
+            self.assertEqual(str(w.message), text)
+            self.assert_(w.category is UserWarning)
 
     def test_options(self):
         # Uses the private _setoption() function to test the parsing
         # of command-line warning arguments
-        self.assertRaises(warnings._OptionError,
-                          warnings._setoption, '1:2:3:4:5:6')
-        self.assertRaises(warnings._OptionError,
-                          warnings._setoption, 'bogus::Warning')
-        self.assertRaises(warnings._OptionError,
-                          warnings._setoption, 'ignore:2::4:-5')
-        warnings._setoption('error::Warning::0')
-        self.assertRaises(UserWarning, warnings.warn, 'convert to error')
+        with test_support.guard_warnings_filter():
+            self.assertRaises(warnings._OptionError,
+                              warnings._setoption, '1:2:3:4:5:6')
+            self.assertRaises(warnings._OptionError,
+                              warnings._setoption, 'bogus::Warning')
+            self.assertRaises(warnings._OptionError,
+                              warnings._setoption, 'ignore:2::4:-5')
+            warnings._setoption('error::Warning::0')
+            self.assertRaises(UserWarning, warnings.warn, 'convert to error')
 
     def test_filename(self):
-        warning_tests.inner("spam1")
-        self.assertEqual(msg.filename, "warning_tests.py")
-        warning_tests.outer("spam2")
-        self.assertEqual(msg.filename, "warning_tests.py")
+        with test_support.catch_warning() as w:
+            warning_tests.inner("spam1")
+            self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
+            warning_tests.outer("spam2")
+            self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
 
     def test_stacklevel(self):
         # Test stacklevel argument
         # make sure all messages are different, so the warning won't be skipped
-        warning_tests.inner("spam3", stacklevel=1)
-        self.assertEqual(msg.filename, "warning_tests.py")
-        warning_tests.outer("spam4", stacklevel=1)
-        self.assertEqual(msg.filename, "warning_tests.py")
-
-        warning_tests.inner("spam5", stacklevel=2)
-        self.assertEqual(msg.filename, "test_warnings.py")
-        warning_tests.outer("spam6", stacklevel=2)
-        self.assertEqual(msg.filename, "warning_tests.py")
+        with test_support.catch_warning() as w:
+            warning_tests.inner("spam3", stacklevel=1)
+            self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
+            warning_tests.outer("spam4", stacklevel=1)
+            self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
+
+            warning_tests.inner("spam5", stacklevel=2)
+            self.assertEqual(os.path.basename(w.filename), "test_warnings.py")
+            warning_tests.outer("spam6", stacklevel=2)
+            self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
 
-        warning_tests.inner("spam7", stacklevel=9999)
-        self.assertEqual(msg.filename, "sys")
+            warning_tests.inner("spam7", stacklevel=9999)
+            self.assertEqual(os.path.basename(w.filename), "sys")
 
 
 def test_main(verbose=None):

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Tue Apr  3 20:33:29 2007
@@ -713,6 +713,9 @@
 - Fix bsddb test_basics.test06_Transactions to check the version
   number properly.
 
+- test.test_support.catch_warning is a new context manager that can be used
+  to catch the warnings issued by the warning framework.
+
 
 Tools
 -----


More information about the Python-checkins mailing list