From da2268feecd4b956161ed7fdd05da125606189cc Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Mon, 24 Apr 2006 04:37:15 +0000 Subject: Fix contextlib.nested to cope with exit methods raising and handling exceptions --- Lib/contextlib.py | 5 ++++- Lib/test/test_contextlib.py | 23 +++++++++++++++++++++++ Misc/NEWS | 6 ++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Lib/contextlib.py b/Lib/contextlib.py index aa5335d..157b4cc 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 97470c7..c23e428 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 4d58aa1..c6fe5b1 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 -- cgit v0.12