From: Nick Coghlan Date: Mon, 24 Apr 2006 04:37:15 +0000 (+0000) Subject: Fix contextlib.nested to cope with exit methods raising and handling exceptions X-Git-Tag: v2.5a2~42 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=da2268feecd4b956161ed7fdd05da125606189cc;p=python Fix contextlib.nested to cope with exit methods raising and handling exceptions --- diff --git a/Lib/contextlib.py b/Lib/contextlib.py index aa5335d9c4..157b4ccb8d 100644 --- a/Lib/contextlib.py +++ b/Lib/contextlib.py @@ -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 diff --git a/Lib/test/test_contextlib.py b/Lib/test/test_contextlib.py index 97470c78fb..c23e428fcb 100644 --- a/Lib/test/test_contextlib.py +++ b/Lib/test/test_contextlib.py @@ -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(): diff --git a/Misc/NEWS b/Misc/NEWS index 4d58aa15dd..c6fe5b17a5 100644 --- 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