Issue #14963: Added test cases for contextlib.ExitStack exception handling behaviour (Initial patch by Alon Horev)

This commit is contained in:
Nick Coghlan 2012-05-31 23:49:26 +10:00
parent 30c35e8154
commit c73e8c2830
3 changed files with 101 additions and 0 deletions

View file

@ -483,6 +483,95 @@ class TestExitStack(unittest.TestCase):
new_stack.close() new_stack.close()
self.assertEqual(result, [1, 2, 3]) self.assertEqual(result, [1, 2, 3])
def test_exit_raise(self):
with self.assertRaises(ZeroDivisionError):
with ExitStack() as stack:
stack.push(lambda *exc: False)
1/0
def test_exit_suppress(self):
with ExitStack() as stack:
stack.push(lambda *exc: True)
1/0
def test_exit_exception_chaining_reference(self):
# Sanity check to make sure that ExitStack chaining matches
# actual nested with statements
class RaiseExc:
def __init__(self, exc):
self.exc = exc
def __enter__(self):
return self
def __exit__(self, *exc_details):
raise self.exc
class SuppressExc:
def __enter__(self):
return self
def __exit__(self, *exc_details):
type(self).saved_details = exc_details
return True
try:
with RaiseExc(IndexError):
with RaiseExc(KeyError):
with RaiseExc(AttributeError):
with SuppressExc():
with RaiseExc(ValueError):
1 / 0
except IndexError as exc:
self.assertIsInstance(exc.__context__, KeyError)
self.assertIsInstance(exc.__context__.__context__, AttributeError)
# Inner exceptions were suppressed
self.assertIsNone(exc.__context__.__context__.__context__)
else:
self.fail("Expected IndexError, but no exception was raised")
# Check the inner exceptions
inner_exc = SuppressExc.saved_details[1]
self.assertIsInstance(inner_exc, ValueError)
self.assertIsInstance(inner_exc.__context__, ZeroDivisionError)
def test_exit_exception_chaining(self):
# Ensure exception chaining matches the reference behaviour
def raise_exc(exc):
raise exc
saved_details = None
def suppress_exc(*exc_details):
nonlocal saved_details
saved_details = exc_details
return True
try:
with ExitStack() as stack:
stack.callback(raise_exc, IndexError)
stack.callback(raise_exc, KeyError)
stack.callback(raise_exc, AttributeError)
stack.push(suppress_exc)
stack.callback(raise_exc, ValueError)
1 / 0
except IndexError as exc:
self.assertIsInstance(exc.__context__, KeyError)
self.assertIsInstance(exc.__context__.__context__, AttributeError)
# Inner exceptions were suppressed, but the with statement
# cleanup code adds the one from the body back in as the
# context of the exception raised by the outer callbacks
# See http://bugs.python.org/issue14969
suite_exc = exc.__context__.__context__.__context__
self.assertIsInstance(suite_exc, ZeroDivisionError)
else:
self.fail("Expected IndexError, but no exception was raised")
# Check the inner exceptions
inner_exc = saved_details[1]
self.assertIsInstance(inner_exc, ValueError)
self.assertIsInstance(inner_exc.__context__, ZeroDivisionError)
def test_exit_exception_chaining_suppress(self):
with ExitStack() as stack:
stack.push(lambda *exc: True)
stack.push(lambda *exc: 1/0)
stack.push(lambda *exc: {}[1])
def test_instance_bypass(self): def test_instance_bypass(self):
class Example(object): pass class Example(object): pass
cm = Example() cm = Example()

View file

@ -460,6 +460,7 @@ Michiel de Hoon
Brian Hooper Brian Hooper
Randall Hopper Randall Hopper
Nadav Horesh Nadav Horesh
Alon Horev
Jan Hosang Jan Hosang
Ken Howard Ken Howard
Brad Howes Brad Howes

View file

@ -2,6 +2,17 @@
Python News Python News
+++++++++++ +++++++++++
What's New in Python 3.3.0 Beta 1?
===================================
*Release date: TBD*
Tests
-----
- Issue #14963 (partial): Add test cases for exception handling behaviour
in contextlib.ContextStack (Initial patch by Alon Horev)
What's New in Python 3.3.0 Alpha 4? What's New in Python 3.3.0 Alpha 4?
=================================== ===================================