[Python-checkins] r42734 - in python/trunk/Lib: contextlib.py test/test_contextlib.py

guido.van.rossum python-checkins at python.org
Wed Mar 1 18:10:03 CET 2006


Author: guido.van.rossum
Date: Wed Mar  1 18:10:01 2006
New Revision: 42734

Modified:
   python/trunk/Lib/contextlib.py
   python/trunk/Lib/test/test_contextlib.py
Log:
Fix a bug in nested() - if one of the sub-context-managers swallows the
exception, it should not be propagated up.  With unit tests.


Modified: python/trunk/Lib/contextlib.py
==============================================================================
--- python/trunk/Lib/contextlib.py	(original)
+++ python/trunk/Lib/contextlib.py	Wed Mar  1 18:10:01 2006
@@ -91,7 +91,6 @@
     """
     exits = []
     vars = []
-    exc = (None, None, None)
     try:
         try:
             for context in contexts:
@@ -103,6 +102,8 @@
             yield vars
         except:
             exc = sys.exc_info()
+        else:
+            exc = (None, None, None)
     finally:
         while exits:
             exit = exits.pop()
@@ -110,6 +111,8 @@
                 exit(*exc)
             except:
                 exc = sys.exc_info()
+            else:
+                exc = (None, None, None)
         if exc != (None, None, None):
             raise
 

Modified: python/trunk/Lib/test/test_contextlib.py
==============================================================================
--- python/trunk/Lib/test/test_contextlib.py	(original)
+++ python/trunk/Lib/test/test_contextlib.py	Wed Mar  1 18:10:01 2006
@@ -107,6 +107,60 @@
         else:
             self.fail("Didn't raise ZeroDivisionError")
 
+    def test_nested_b_swallows(self):
+        @contextmanager
+        def a():
+            yield
+        @contextmanager
+        def b():
+            try:
+                yield
+            except:
+                # Swallow the exception
+                pass
+        try:
+            with nested(a(), b()):
+                1/0
+        except ZeroDivisionError:
+            self.fail("Didn't swallow ZeroDivisionError")
+
+    def test_nested_break(self):
+        @contextmanager
+        def a():
+            yield
+        state = 0
+        while True:
+            state += 1
+            with nested(a(), a()):
+                break
+            state += 10
+        self.assertEqual(state, 1)
+
+    def test_nested_continue(self):
+        @contextmanager
+        def a():
+            yield
+        state = 0
+        while state < 3:
+            state += 1
+            with nested(a(), a()):
+                continue
+            state += 10
+        self.assertEqual(state, 3)
+
+    def test_nested_return(self):
+        @contextmanager
+        def a():
+            try:
+                yield
+            except:
+                pass
+        def foo():
+            with nested(a(), a()):
+                return 1
+            return 10
+        self.assertEqual(foo(), 1)
+
 class ClosingTestCase(unittest.TestCase):
 
     # XXX This needs more work


More information about the Python-checkins mailing list