10c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#!/usr/bin/env python
20c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
30c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi"""Unit tests for the with statement specified in PEP 343."""
40c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
50c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
60c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi__author__ = "Mike Bland"
70c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi__email__ = "mbland at acm dot org"
80c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
90c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport sys
100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport unittest
110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom collections import deque
120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom contextlib import GeneratorContextManager, contextmanager
130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom test.test_support import run_unittest
140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass MockContextManager(GeneratorContextManager):
170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self, gen):
180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        GeneratorContextManager.__init__(self, gen)
190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.enter_called = False
200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.exit_called = False
210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.exit_args = None
220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __enter__(self):
240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.enter_called = True
250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return GeneratorContextManager.__enter__(self)
260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __exit__(self, type, value, traceback):
280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.exit_called = True
290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.exit_args = (type, value, traceback)
300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return GeneratorContextManager.__exit__(self, type,
310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                                value, traceback)
320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef mock_contextmanager(func):
350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def helper(*args, **kwds):
360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return MockContextManager(func(*args, **kwds))
370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return helper
380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass MockResource(object):
410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self):
420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.yielded = False
430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.stopped = False
440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi@mock_contextmanager
470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef mock_contextmanager_generator():
480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    mock = MockResource()
490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    try:
500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mock.yielded = True
510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        yield mock
520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    finally:
530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mock.stopped = True
540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Nested(object):
570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self, *managers):
590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.managers = managers
600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.entered = None
610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __enter__(self):
630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.entered is not None:
640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            raise RuntimeError("Context is not reentrant")
650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.entered = deque()
660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        vars = []
670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            for mgr in self.managers:
690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                vars.append(mgr.__enter__())
700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.entered.appendleft(mgr)
710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        except:
720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if not self.__exit__(*sys.exc_info()):
730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                raise
740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return vars
750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __exit__(self, *exc_info):
770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Behave like nested with statements
780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # first in, last out
790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # New exceptions override old ones
800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ex = exc_info
810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for mgr in self.entered:
820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            try:
830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if mgr.__exit__(*ex):
840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ex = (None, None, None)
850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            except:
860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                ex = sys.exc_info()
870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.entered = None
880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if ex is not exc_info:
890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            raise ex[0], ex[1], ex[2]
900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass MockNested(Nested):
930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self, *managers):
940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Nested.__init__(self, *managers)
950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.enter_called = False
960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.exit_called = False
970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.exit_args = None
980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __enter__(self):
1000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.enter_called = True
1010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return Nested.__enter__(self)
1020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __exit__(self, *exc_info):
1040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.exit_called = True
1050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.exit_args = exc_info
1060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return Nested.__exit__(self, *exc_info)
1070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass FailureTestCase(unittest.TestCase):
1100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testNameError(self):
1110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def fooNotDeclared():
1120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with foo: pass
1130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(NameError, fooNotDeclared)
1140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testEnterAttributeError(self):
1160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        class LacksEnter(object):
1170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def __exit__(self, type, value, traceback):
1180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pass
1190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def fooLacksEnter():
1210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            foo = LacksEnter()
1220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with foo: pass
1230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(AttributeError, fooLacksEnter)
1240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testExitAttributeError(self):
1260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        class LacksExit(object):
1270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def __enter__(self):
1280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pass
1290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def fooLacksExit():
1310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            foo = LacksExit()
1320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with foo: pass
1330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(AttributeError, fooLacksExit)
1340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def assertRaisesSyntaxError(self, codestr):
1360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def shouldRaiseSyntaxError(s):
1370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            compile(s, '', 'single')
1380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(SyntaxError, shouldRaiseSyntaxError, codestr)
1390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testAssignmentToNoneError(self):
1410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaisesSyntaxError('with mock as None:\n  pass')
1420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaisesSyntaxError(
1430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'with mock as (None):\n'
1440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            '  pass')
1450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testAssignmentToEmptyTupleError(self):
1470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaisesSyntaxError(
1480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'with mock as ():\n'
1490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            '  pass')
1500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testAssignmentToTupleOnlyContainingNoneError(self):
1520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaisesSyntaxError('with mock as None,:\n  pass')
1530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaisesSyntaxError(
1540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'with mock as (None,):\n'
1550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            '  pass')
1560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testAssignmentToTupleContainingNoneError(self):
1580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaisesSyntaxError(
1590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'with mock as (foo, None, bar):\n'
1600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            '  pass')
1610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testEnterThrows(self):
1630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        class EnterThrows(object):
1640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def __enter__(self):
1650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                raise RuntimeError("Enter threw")
1660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def __exit__(self, *args):
1670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pass
1680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def shouldThrow():
1700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ct = EnterThrows()
1710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.foo = None
1720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with ct as self.foo:
1730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pass
1740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(RuntimeError, shouldThrow)
1750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(self.foo, None)
1760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testExitThrows(self):
1780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        class ExitThrows(object):
1790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def __enter__(self):
1800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                return
1810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def __exit__(self, *args):
1820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                raise RuntimeError(42)
1830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def shouldThrow():
1840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with ExitThrows():
1850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pass
1860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(RuntimeError, shouldThrow)
1870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass ContextmanagerAssertionMixin(object):
1890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    TEST_EXCEPTION = RuntimeError("test exception")
1900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def assertInWithManagerInvariants(self, mock_manager):
1920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(mock_manager.enter_called)
1930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertFalse(mock_manager.exit_called)
1940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(mock_manager.exit_args, None)
1950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def assertAfterWithManagerInvariants(self, mock_manager, exit_args):
1970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(mock_manager.enter_called)
1980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(mock_manager.exit_called)
1990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(mock_manager.exit_args, exit_args)
2000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def assertAfterWithManagerInvariantsNoError(self, mock_manager):
2020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariants(mock_manager,
2030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            (None, None, None))
2040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def assertInWithGeneratorInvariants(self, mock_generator):
2060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(mock_generator.yielded)
2070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertFalse(mock_generator.stopped)
2080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def assertAfterWithGeneratorInvariantsNoError(self, mock_generator):
2100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(mock_generator.yielded)
2110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(mock_generator.stopped)
2120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def raiseTestException(self):
2140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        raise self.TEST_EXCEPTION
2150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def assertAfterWithManagerInvariantsWithError(self, mock_manager,
2170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                                  exc_type=None):
2180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(mock_manager.enter_called)
2190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(mock_manager.exit_called)
2200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if exc_type is None:
2210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(mock_manager.exit_args[1], self.TEST_EXCEPTION)
2220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            exc_type = type(self.TEST_EXCEPTION)
2230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(mock_manager.exit_args[0], exc_type)
2240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Test the __exit__ arguments. Issue #7853
2250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIsInstance(mock_manager.exit_args[1], exc_type)
2260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIsNot(mock_manager.exit_args[2], None)
2270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def assertAfterWithGeneratorInvariantsWithError(self, mock_generator):
2290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(mock_generator.yielded)
2300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(mock_generator.stopped)
2310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass NonexceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin):
2340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testInlineGeneratorSyntax(self):
2350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with mock_contextmanager_generator():
2360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pass
2370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testUnboundGenerator(self):
2390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mock = mock_contextmanager_generator()
2400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with mock:
2410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pass
2420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsNoError(mock)
2430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testInlineGeneratorBoundSyntax(self):
2450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with mock_contextmanager_generator() as foo:
2460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertInWithGeneratorInvariants(foo)
2470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # FIXME: In the future, we'll try to keep the bound names from leaking
2480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithGeneratorInvariantsNoError(foo)
2490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testInlineGeneratorBoundToExistingVariable(self):
2510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        foo = None
2520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with mock_contextmanager_generator() as foo:
2530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertInWithGeneratorInvariants(foo)
2540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithGeneratorInvariantsNoError(foo)
2550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testInlineGeneratorBoundToDottedVariable(self):
2570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with mock_contextmanager_generator() as self.foo:
2580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertInWithGeneratorInvariants(self.foo)
2590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithGeneratorInvariantsNoError(self.foo)
2600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testBoundGenerator(self):
2620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mock = mock_contextmanager_generator()
2630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with mock as foo:
2640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertInWithGeneratorInvariants(foo)
2650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertInWithManagerInvariants(mock)
2660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithGeneratorInvariantsNoError(foo)
2670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsNoError(mock)
2680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testNestedSingleStatements(self):
2700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mock_a = mock_contextmanager_generator()
2710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with mock_a as foo:
2720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            mock_b = mock_contextmanager_generator()
2730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with mock_b as bar:
2740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertInWithManagerInvariants(mock_a)
2750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertInWithManagerInvariants(mock_b)
2760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertInWithGeneratorInvariants(foo)
2770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertInWithGeneratorInvariants(bar)
2780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertAfterWithManagerInvariantsNoError(mock_b)
2790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertAfterWithGeneratorInvariantsNoError(bar)
2800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertInWithManagerInvariants(mock_a)
2810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertInWithGeneratorInvariants(foo)
2820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsNoError(mock_a)
2830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithGeneratorInvariantsNoError(foo)
2840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass NestedNonexceptionalTestCase(unittest.TestCase,
2870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    ContextmanagerAssertionMixin):
2880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testSingleArgInlineGeneratorSyntax(self):
2890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with Nested(mock_contextmanager_generator()):
2900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pass
2910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testSingleArgBoundToNonTuple(self):
2930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        m = mock_contextmanager_generator()
2940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # This will bind all the arguments to nested() into a single list
2950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # assigned to foo.
2960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with Nested(m) as foo:
2970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertInWithManagerInvariants(m)
2980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsNoError(m)
2990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testSingleArgBoundToSingleElementParenthesizedList(self):
3010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        m = mock_contextmanager_generator()
3020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # This will bind all the arguments to nested() into a single list
3030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # assigned to foo.
3040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with Nested(m) as (foo):
3050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertInWithManagerInvariants(m)
3060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsNoError(m)
3070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testSingleArgBoundToMultipleElementTupleError(self):
3090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def shouldThrowValueError():
3100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with Nested(mock_contextmanager_generator()) as (foo, bar):
3110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pass
3120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(ValueError, shouldThrowValueError)
3130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testSingleArgUnbound(self):
3150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mock_contextmanager = mock_contextmanager_generator()
3160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mock_nested = MockNested(mock_contextmanager)
3170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with mock_nested:
3180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertInWithManagerInvariants(mock_contextmanager)
3190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertInWithManagerInvariants(mock_nested)
3200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsNoError(mock_contextmanager)
3210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsNoError(mock_nested)
3220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testMultipleArgUnbound(self):
3240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        m = mock_contextmanager_generator()
3250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        n = mock_contextmanager_generator()
3260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        o = mock_contextmanager_generator()
3270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mock_nested = MockNested(m, n, o)
3280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with mock_nested:
3290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertInWithManagerInvariants(m)
3300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertInWithManagerInvariants(n)
3310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertInWithManagerInvariants(o)
3320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertInWithManagerInvariants(mock_nested)
3330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsNoError(m)
3340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsNoError(n)
3350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsNoError(o)
3360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsNoError(mock_nested)
3370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testMultipleArgBound(self):
3390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mock_nested = MockNested(mock_contextmanager_generator(),
3400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            mock_contextmanager_generator(), mock_contextmanager_generator())
3410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with mock_nested as (m, n, o):
3420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertInWithGeneratorInvariants(m)
3430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertInWithGeneratorInvariants(n)
3440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertInWithGeneratorInvariants(o)
3450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertInWithManagerInvariants(mock_nested)
3460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithGeneratorInvariantsNoError(m)
3470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithGeneratorInvariantsNoError(n)
3480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithGeneratorInvariantsNoError(o)
3490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsNoError(mock_nested)
3500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass ExceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin):
3530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testSingleResource(self):
3540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cm = mock_contextmanager_generator()
3550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def shouldThrow():
3560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with cm as self.resource:
3570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertInWithManagerInvariants(cm)
3580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertInWithGeneratorInvariants(self.resource)
3590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.raiseTestException()
3600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(RuntimeError, shouldThrow)
3610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsWithError(cm)
3620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithGeneratorInvariantsWithError(self.resource)
3630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testExceptionNormalized(self):
3650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cm = mock_contextmanager_generator()
3660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def shouldThrow():
3670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with cm as self.resource:
3680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                # Note this relies on the fact that 1 // 0 produces an exception
3690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                # that is not normalized immediately.
3700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                1 // 0
3710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(ZeroDivisionError, shouldThrow)
3720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsWithError(cm, ZeroDivisionError)
3730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testNestedSingleStatements(self):
3750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mock_a = mock_contextmanager_generator()
3760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mock_b = mock_contextmanager_generator()
3770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def shouldThrow():
3780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with mock_a as self.foo:
3790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                with mock_b as self.bar:
3800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    self.assertInWithManagerInvariants(mock_a)
3810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    self.assertInWithManagerInvariants(mock_b)
3820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    self.assertInWithGeneratorInvariants(self.foo)
3830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    self.assertInWithGeneratorInvariants(self.bar)
3840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    self.raiseTestException()
3850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(RuntimeError, shouldThrow)
3860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsWithError(mock_a)
3870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsWithError(mock_b)
3880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithGeneratorInvariantsWithError(self.foo)
3890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithGeneratorInvariantsWithError(self.bar)
3900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testMultipleResourcesInSingleStatement(self):
3920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cm_a = mock_contextmanager_generator()
3930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cm_b = mock_contextmanager_generator()
3940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mock_nested = MockNested(cm_a, cm_b)
3950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def shouldThrow():
3960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with mock_nested as (self.resource_a, self.resource_b):
3970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertInWithManagerInvariants(cm_a)
3980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertInWithManagerInvariants(cm_b)
3990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertInWithManagerInvariants(mock_nested)
4000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertInWithGeneratorInvariants(self.resource_a)
4010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertInWithGeneratorInvariants(self.resource_b)
4020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.raiseTestException()
4030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(RuntimeError, shouldThrow)
4040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsWithError(cm_a)
4050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsWithError(cm_b)
4060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsWithError(mock_nested)
4070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithGeneratorInvariantsWithError(self.resource_a)
4080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithGeneratorInvariantsWithError(self.resource_b)
4090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testNestedExceptionBeforeInnerStatement(self):
4110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mock_a = mock_contextmanager_generator()
4120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mock_b = mock_contextmanager_generator()
4130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.bar = None
4140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def shouldThrow():
4150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with mock_a as self.foo:
4160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertInWithManagerInvariants(mock_a)
4170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertInWithGeneratorInvariants(self.foo)
4180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.raiseTestException()
4190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                with mock_b as self.bar:
4200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    pass
4210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(RuntimeError, shouldThrow)
4220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsWithError(mock_a)
4230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithGeneratorInvariantsWithError(self.foo)
4240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # The inner statement stuff should never have been touched
4260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(self.bar, None)
4270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertFalse(mock_b.enter_called)
4280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertFalse(mock_b.exit_called)
4290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(mock_b.exit_args, None)
4300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testNestedExceptionAfterInnerStatement(self):
4320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mock_a = mock_contextmanager_generator()
4330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mock_b = mock_contextmanager_generator()
4340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def shouldThrow():
4350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with mock_a as self.foo:
4360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                with mock_b as self.bar:
4370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    self.assertInWithManagerInvariants(mock_a)
4380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    self.assertInWithManagerInvariants(mock_b)
4390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    self.assertInWithGeneratorInvariants(self.foo)
4400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    self.assertInWithGeneratorInvariants(self.bar)
4410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.raiseTestException()
4420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(RuntimeError, shouldThrow)
4430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsWithError(mock_a)
4440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithManagerInvariantsNoError(mock_b)
4450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithGeneratorInvariantsWithError(self.foo)
4460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAfterWithGeneratorInvariantsNoError(self.bar)
4470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testRaisedStopIteration1(self):
4490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # From bug 1462485
4500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        @contextmanager
4510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def cm():
4520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            yield
4530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def shouldThrow():
4550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with cm():
4560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                raise StopIteration("from with")
4570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(StopIteration, shouldThrow)
4590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testRaisedStopIteration2(self):
4610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # From bug 1462485
4620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        class cm(object):
4630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def __enter__(self):
4640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pass
4650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def __exit__(self, type, value, traceback):
4660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pass
4670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def shouldThrow():
4690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with cm():
4700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                raise StopIteration("from with")
4710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(StopIteration, shouldThrow)
4730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testRaisedStopIteration3(self):
4750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Another variant where the exception hasn't been instantiated
4760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # From bug 1705170
4770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        @contextmanager
4780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def cm():
4790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            yield
4800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def shouldThrow():
4820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with cm():
4830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                raise iter([]).next()
4840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(StopIteration, shouldThrow)
4860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testRaisedGeneratorExit1(self):
4880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # From bug 1462485
4890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        @contextmanager
4900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def cm():
4910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            yield
4920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def shouldThrow():
4940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with cm():
4950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                raise GeneratorExit("from with")
4960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(GeneratorExit, shouldThrow)
4980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testRaisedGeneratorExit2(self):
5000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # From bug 1462485
5010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        class cm (object):
5020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def __enter__(self):
5030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pass
5040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def __exit__(self, type, value, traceback):
5050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pass
5060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def shouldThrow():
5080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with cm():
5090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                raise GeneratorExit("from with")
5100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(GeneratorExit, shouldThrow)
5120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testErrorsInBool(self):
5140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # issue4589: __exit__ return code may raise an exception
5150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # when looking at its truth value.
5160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        class cm(object):
5180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def __init__(self, bool_conversion):
5190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                class Bool:
5200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    def __nonzero__(self):
5210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        return bool_conversion()
5220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.exit_result = Bool()
5230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def __enter__(self):
5240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                return 3
5250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def __exit__(self, a, b, c):
5260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                return self.exit_result
5270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def trueAsBool():
5290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with cm(lambda: True):
5300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.fail("Should NOT see this")
5310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        trueAsBool()
5320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def falseAsBool():
5340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with cm(lambda: False):
5350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.fail("Should raise")
5360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(AssertionError, falseAsBool)
5370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def failAsBool():
5390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with cm(lambda: 1 // 0):
5400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.fail("Should NOT see this")
5410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRaises(ZeroDivisionError, failAsBool)
5420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass NonLocalFlowControlTestCase(unittest.TestCase):
5450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testWithBreak(self):
5470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        counter = 0
5480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        while True:
5490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            counter += 1
5500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with mock_contextmanager_generator():
5510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                counter += 10
5520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                break
5530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            counter += 100 # Not reached
5540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(counter, 11)
5550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testWithContinue(self):
5570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        counter = 0
5580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        while True:
5590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            counter += 1
5600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if counter > 2:
5610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                break
5620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with mock_contextmanager_generator():
5630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                counter += 10
5640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                continue
5650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            counter += 100 # Not reached
5660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(counter, 12)
5670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testWithReturn(self):
5690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def foo():
5700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            counter = 0
5710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            while True:
5720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                counter += 1
5730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                with mock_contextmanager_generator():
5740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    counter += 10
5750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    return counter
5760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                counter += 100 # Not reached
5770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(foo(), 11)
5780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testWithYield(self):
5800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def gen():
5810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with mock_contextmanager_generator():
5820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                yield 12
5830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                yield 13
5840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        x = list(gen())
5850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(x, [12, 13])
5860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testWithRaise(self):
5880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        counter = 0
5890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
5900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            counter += 1
5910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with mock_contextmanager_generator():
5920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                counter += 10
5930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                raise RuntimeError
5940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            counter += 100 # Not reached
5950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        except RuntimeError:
5960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(counter, 11)
5970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
5980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.fail("Didn't raise RuntimeError")
5990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass AssignmentTargetTestCase(unittest.TestCase):
6020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testSingleComplexTarget(self):
6040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        targets = {1: [0, 1, 2]}
6050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with mock_contextmanager_generator() as targets[1][0]:
6060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(targets.keys(), [1])
6070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(targets[1][0].__class__, MockResource)
6080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with mock_contextmanager_generator() as targets.values()[0][1]:
6090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(targets.keys(), [1])
6100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(targets[1][1].__class__, MockResource)
6110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with mock_contextmanager_generator() as targets[2]:
6120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            keys = targets.keys()
6130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            keys.sort()
6140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(keys, [1, 2])
6150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        class C: pass
6160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        blah = C()
6170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with mock_contextmanager_generator() as blah.foo:
6180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(hasattr(blah, "foo"), True)
6190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testMultipleComplexTargets(self):
6210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        class C:
6220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def __enter__(self): return 1, 2, 3
6230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def __exit__(self, t, v, tb): pass
6240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        targets = {1: [0, 1, 2]}
6250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with C() as (targets[1][0], targets[1][1], targets[1][2]):
6260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(targets, {1: [1, 2, 3]})
6270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with C() as (targets.values()[0][2], targets.values()[0][1], targets.values()[0][0]):
6280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(targets, {1: [3, 2, 1]})
6290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with C() as (targets[1], targets[2], targets[3]):
6300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(targets, {1: 1, 2: 2, 3: 3})
6310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        class B: pass
6320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        blah = B()
6330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with C() as (blah.one, blah.two, blah.three):
6340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(blah.one, 1)
6350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(blah.two, 2)
6360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(blah.three, 3)
6370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass ExitSwallowsExceptionTestCase(unittest.TestCase):
6400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testExitTrueSwallowsException(self):
6420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        class AfricanSwallow:
6430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def __enter__(self): pass
6440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def __exit__(self, t, v, tb): return True
6450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
6460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with AfricanSwallow():
6470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                1 // 0
6480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        except ZeroDivisionError:
6490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.fail("ZeroDivisionError should have been swallowed")
6500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testExitFalseDoesntSwallowException(self):
6520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        class EuropeanSwallow:
6530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def __enter__(self): pass
6540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def __exit__(self, t, v, tb): return False
6550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
6560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with EuropeanSwallow():
6570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                1 // 0
6580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        except ZeroDivisionError:
6590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pass
6600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
6610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.fail("ZeroDivisionError should have been raised")
6620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass NestedWith(unittest.TestCase):
6650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    class Dummy(object):
6670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def __init__(self, value=None, gobble=False):
6680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if value is None:
6690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                value = self
6700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.value = value
6710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.gobble = gobble
6720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.enter_called = False
6730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.exit_called = False
6740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def __enter__(self):
6760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.enter_called = True
6770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self.value
6780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def __exit__(self, *exc_info):
6800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.exit_called = True
6810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.exc_info = exc_info
6820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if self.gobble:
6830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                return True
6840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    class InitRaises(object):
6860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def __init__(self): raise RuntimeError()
6870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    class EnterRaises(object):
6890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def __enter__(self): raise RuntimeError()
6900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def __exit__(self, *exc_info): pass
6910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    class ExitRaises(object):
6930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def __enter__(self): pass
6940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def __exit__(self, *exc_info): raise RuntimeError()
6950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testNoExceptions(self):
6970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with self.Dummy() as a, self.Dummy() as b:
6980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(a.enter_called)
6990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(b.enter_called)
7000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(a.exit_called)
7010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(b.exit_called)
7020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testExceptionInExprList(self):
7040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
7050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with self.Dummy() as a, self.InitRaises():
7060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pass
7070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        except:
7080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pass
7090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(a.enter_called)
7100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(a.exit_called)
7110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testExceptionInEnter(self):
7130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
7140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            with self.Dummy() as a, self.EnterRaises():
7150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.fail('body of bad with executed')
7160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        except RuntimeError:
7170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pass
7180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
7190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.fail('RuntimeError not reraised')
7200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(a.enter_called)
7210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(a.exit_called)
7220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testExceptionInExit(self):
7240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        body_executed = False
7250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with self.Dummy(gobble=True) as a, self.ExitRaises():
7260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            body_executed = True
7270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(a.enter_called)
7280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(a.exit_called)
7290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(body_executed)
7300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertNotEqual(a.exc_info[0], None)
7310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def testEnterReturnsTuple(self):
7330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with self.Dummy(value=(1,2)) as (a1, a2), \
7340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi             self.Dummy(value=(10, 20)) as (b1, b2):
7350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(1, a1)
7360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(2, a2)
7370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(10, b1)
7380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(20, b2)
7390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef test_main():
7410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    run_unittest(FailureTestCase, NonexceptionalTestCase,
7420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                 NestedNonexceptionalTestCase, ExceptionalTestCase,
7430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                 NonLocalFlowControlTestCase,
7440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                 AssignmentTargetTestCase,
7450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                 ExitSwallowsExceptionTestCase,
7460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                 NestedWith)
7470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiif __name__ == '__main__':
7500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    test_main()
751