]> granicus.if.org Git - python/commitdiff
Fix contextlib.nested to cope with exit methods raising and handling exceptions
authorNick Coghlan <ncoghlan@gmail.com>
Mon, 24 Apr 2006 04:37:15 +0000 (04:37 +0000)
committerNick Coghlan <ncoghlan@gmail.com>
Mon, 24 Apr 2006 04:37:15 +0000 (04:37 +0000)
Lib/contextlib.py
Lib/test/test_contextlib.py
Misc/NEWS

index aa5335d9c4c53e373af270edb91cbcc46831e685..157b4ccb8d09efdfa40767d8c19898882a76a4f5 100644 (file)
@@ -127,7 +127,10 @@ def nested(*contexts):
             except:
                 exc = sys.exc_info()
         if exc != (None, None, None):
-            raise
+            # Don't rely on sys.exc_info() still containing
+            # the right information. Another exception may
+            # have been raised and caught by an exit method
+            raise exc[0], exc[1], exc[2]
 
 
 @contextmanager
index 97470c78fbe49b1ad45ed63ae7c3e82d8e3b2a96..c23e428fcbea6ce774a7d1a5db1ec00848cbdb76 100644 (file)
@@ -146,6 +146,29 @@ class NestedTestCase(unittest.TestCase):
         else:
             self.fail("Didn't raise ZeroDivisionError")
 
+    def test_nested_right_exception(self):
+        state = []
+        @contextmanager
+        def a():
+            yield 1
+        class b(object):
+            def __enter__(self):
+                return 2
+            def __exit__(self, *exc_info):
+                try:
+                    raise Exception()
+                except:
+                    pass
+        try:
+            with nested(a(), b()) as (x, y):
+                1/0
+        except ZeroDivisionError:
+            self.assertEqual((x, y), (1, 2))
+        except Exception:
+            self.fail("Reraised wrong exception")
+        else:
+            self.fail("Didn't raise ZeroDivisionError")
+
     def test_nested_b_swallows(self):
         @contextmanager
         def a():
index 4d58aa15dd362f353c1029b91ee0f4b486f0d20c..c6fe5b17a5fb91ca02e73d791dde39797ec872e3 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -86,6 +86,9 @@ Extension Modules
 Library
 -------
 
+- Fixed contextlib.nested to cope with exceptions being raised and
+  caught inside exit handlers.
+
 - Updated optparse module to Optik 1.5.1 (allow numeric constants in
   hex, octal, or binary; add ``append_const`` action; keep going if
   gettext cannot be imported; added ``OptionParser.destroy()`` method;
@@ -158,6 +161,9 @@ C API
 Tests
 -----
 
+- test_contextlib now checks contextlib.nested can cope with exceptions
+  being raised and caught inside exit handlers.
+
 - test_cmd_line now checks operation of the -m and -c command switches
 
 - The test_contextlib test in 2.5a1 wasn't actually run unless you ran