123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748 |
- """Unit tests for the with statement specified in PEP 343."""
- __author__ = "Mike Bland"
- __email__ = "mbland at acm dot org"
- import sys
- import unittest
- from collections import deque
- from contextlib import GeneratorContextManager, contextmanager
- from test.test_support import run_unittest
- class MockContextManager(GeneratorContextManager):
- def __init__(self, gen):
- GeneratorContextManager.__init__(self, gen)
- self.enter_called = False
- self.exit_called = False
- self.exit_args = None
- def __enter__(self):
- self.enter_called = True
- return GeneratorContextManager.__enter__(self)
- def __exit__(self, type, value, traceback):
- self.exit_called = True
- self.exit_args = (type, value, traceback)
- return GeneratorContextManager.__exit__(self, type,
- value, traceback)
- def mock_contextmanager(func):
- def helper(*args, **kwds):
- return MockContextManager(func(*args, **kwds))
- return helper
- class MockResource(object):
- def __init__(self):
- self.yielded = False
- self.stopped = False
- @mock_contextmanager
- def mock_contextmanager_generator():
- mock = MockResource()
- try:
- mock.yielded = True
- yield mock
- finally:
- mock.stopped = True
- class Nested(object):
- def __init__(self, *managers):
- self.managers = managers
- self.entered = None
- def __enter__(self):
- if self.entered is not None:
- raise RuntimeError("Context is not reentrant")
- self.entered = deque()
- vars = []
- try:
- for mgr in self.managers:
- vars.append(mgr.__enter__())
- self.entered.appendleft(mgr)
- except:
- if not self.__exit__(*sys.exc_info()):
- raise
- return vars
- def __exit__(self, *exc_info):
- # Behave like nested with statements
- # first in, last out
- # New exceptions override old ones
- ex = exc_info
- for mgr in self.entered:
- try:
- if mgr.__exit__(*ex):
- ex = (None, None, None)
- except:
- ex = sys.exc_info()
- self.entered = None
- if ex is not exc_info:
- raise ex[0], ex[1], ex[2]
- class MockNested(Nested):
- def __init__(self, *managers):
- Nested.__init__(self, *managers)
- self.enter_called = False
- self.exit_called = False
- self.exit_args = None
- def __enter__(self):
- self.enter_called = True
- return Nested.__enter__(self)
- def __exit__(self, *exc_info):
- self.exit_called = True
- self.exit_args = exc_info
- return Nested.__exit__(self, *exc_info)
- class FailureTestCase(unittest.TestCase):
- def testNameError(self):
- def fooNotDeclared():
- with foo: pass
- self.assertRaises(NameError, fooNotDeclared)
- def testEnterAttributeError(self):
- class LacksEnter(object):
- def __exit__(self, type, value, traceback):
- pass
- def fooLacksEnter():
- foo = LacksEnter()
- with foo: pass
- self.assertRaises(AttributeError, fooLacksEnter)
- def testExitAttributeError(self):
- class LacksExit(object):
- def __enter__(self):
- pass
- def fooLacksExit():
- foo = LacksExit()
- with foo: pass
- self.assertRaises(AttributeError, fooLacksExit)
- def assertRaisesSyntaxError(self, codestr):
- def shouldRaiseSyntaxError(s):
- compile(s, '', 'single')
- self.assertRaises(SyntaxError, shouldRaiseSyntaxError, codestr)
- def testAssignmentToNoneError(self):
- self.assertRaisesSyntaxError('with mock as None:\n pass')
- self.assertRaisesSyntaxError(
- 'with mock as (None):\n'
- ' pass')
- def testAssignmentToEmptyTupleError(self):
- self.assertRaisesSyntaxError(
- 'with mock as ():\n'
- ' pass')
- def testAssignmentToTupleOnlyContainingNoneError(self):
- self.assertRaisesSyntaxError('with mock as None,:\n pass')
- self.assertRaisesSyntaxError(
- 'with mock as (None,):\n'
- ' pass')
- def testAssignmentToTupleContainingNoneError(self):
- self.assertRaisesSyntaxError(
- 'with mock as (foo, None, bar):\n'
- ' pass')
- def testEnterThrows(self):
- class EnterThrows(object):
- def __enter__(self):
- raise RuntimeError("Enter threw")
- def __exit__(self, *args):
- pass
- def shouldThrow():
- ct = EnterThrows()
- self.foo = None
- with ct as self.foo:
- pass
- self.assertRaises(RuntimeError, shouldThrow)
- self.assertEqual(self.foo, None)
- def testExitThrows(self):
- class ExitThrows(object):
- def __enter__(self):
- return
- def __exit__(self, *args):
- raise RuntimeError(42)
- def shouldThrow():
- with ExitThrows():
- pass
- self.assertRaises(RuntimeError, shouldThrow)
- class ContextmanagerAssertionMixin(object):
- TEST_EXCEPTION = RuntimeError("test exception")
- def assertInWithManagerInvariants(self, mock_manager):
- self.assertTrue(mock_manager.enter_called)
- self.assertFalse(mock_manager.exit_called)
- self.assertEqual(mock_manager.exit_args, None)
- def assertAfterWithManagerInvariants(self, mock_manager, exit_args):
- self.assertTrue(mock_manager.enter_called)
- self.assertTrue(mock_manager.exit_called)
- self.assertEqual(mock_manager.exit_args, exit_args)
- def assertAfterWithManagerInvariantsNoError(self, mock_manager):
- self.assertAfterWithManagerInvariants(mock_manager,
- (None, None, None))
- def assertInWithGeneratorInvariants(self, mock_generator):
- self.assertTrue(mock_generator.yielded)
- self.assertFalse(mock_generator.stopped)
- def assertAfterWithGeneratorInvariantsNoError(self, mock_generator):
- self.assertTrue(mock_generator.yielded)
- self.assertTrue(mock_generator.stopped)
- def raiseTestException(self):
- raise self.TEST_EXCEPTION
- def assertAfterWithManagerInvariantsWithError(self, mock_manager,
- exc_type=None):
- self.assertTrue(mock_manager.enter_called)
- self.assertTrue(mock_manager.exit_called)
- if exc_type is None:
- self.assertEqual(mock_manager.exit_args[1], self.TEST_EXCEPTION)
- exc_type = type(self.TEST_EXCEPTION)
- self.assertEqual(mock_manager.exit_args[0], exc_type)
- # Test the __exit__ arguments. Issue #7853
- self.assertIsInstance(mock_manager.exit_args[1], exc_type)
- self.assertIsNot(mock_manager.exit_args[2], None)
- def assertAfterWithGeneratorInvariantsWithError(self, mock_generator):
- self.assertTrue(mock_generator.yielded)
- self.assertTrue(mock_generator.stopped)
- class NonexceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin):
- def testInlineGeneratorSyntax(self):
- with mock_contextmanager_generator():
- pass
- def testUnboundGenerator(self):
- mock = mock_contextmanager_generator()
- with mock:
- pass
- self.assertAfterWithManagerInvariantsNoError(mock)
- def testInlineGeneratorBoundSyntax(self):
- with mock_contextmanager_generator() as foo:
- self.assertInWithGeneratorInvariants(foo)
- # FIXME: In the future, we'll try to keep the bound names from leaking
- self.assertAfterWithGeneratorInvariantsNoError(foo)
- def testInlineGeneratorBoundToExistingVariable(self):
- foo = None
- with mock_contextmanager_generator() as foo:
- self.assertInWithGeneratorInvariants(foo)
- self.assertAfterWithGeneratorInvariantsNoError(foo)
- def testInlineGeneratorBoundToDottedVariable(self):
- with mock_contextmanager_generator() as self.foo:
- self.assertInWithGeneratorInvariants(self.foo)
- self.assertAfterWithGeneratorInvariantsNoError(self.foo)
- def testBoundGenerator(self):
- mock = mock_contextmanager_generator()
- with mock as foo:
- self.assertInWithGeneratorInvariants(foo)
- self.assertInWithManagerInvariants(mock)
- self.assertAfterWithGeneratorInvariantsNoError(foo)
- self.assertAfterWithManagerInvariantsNoError(mock)
- def testNestedSingleStatements(self):
- mock_a = mock_contextmanager_generator()
- with mock_a as foo:
- mock_b = mock_contextmanager_generator()
- with mock_b as bar:
- self.assertInWithManagerInvariants(mock_a)
- self.assertInWithManagerInvariants(mock_b)
- self.assertInWithGeneratorInvariants(foo)
- self.assertInWithGeneratorInvariants(bar)
- self.assertAfterWithManagerInvariantsNoError(mock_b)
- self.assertAfterWithGeneratorInvariantsNoError(bar)
- self.assertInWithManagerInvariants(mock_a)
- self.assertInWithGeneratorInvariants(foo)
- self.assertAfterWithManagerInvariantsNoError(mock_a)
- self.assertAfterWithGeneratorInvariantsNoError(foo)
- class NestedNonexceptionalTestCase(unittest.TestCase,
- ContextmanagerAssertionMixin):
- def testSingleArgInlineGeneratorSyntax(self):
- with Nested(mock_contextmanager_generator()):
- pass
- def testSingleArgBoundToNonTuple(self):
- m = mock_contextmanager_generator()
- # This will bind all the arguments to nested() into a single list
- # assigned to foo.
- with Nested(m) as foo:
- self.assertInWithManagerInvariants(m)
- self.assertAfterWithManagerInvariantsNoError(m)
- def testSingleArgBoundToSingleElementParenthesizedList(self):
- m = mock_contextmanager_generator()
- # This will bind all the arguments to nested() into a single list
- # assigned to foo.
- with Nested(m) as (foo):
- self.assertInWithManagerInvariants(m)
- self.assertAfterWithManagerInvariantsNoError(m)
- def testSingleArgBoundToMultipleElementTupleError(self):
- def shouldThrowValueError():
- with Nested(mock_contextmanager_generator()) as (foo, bar):
- pass
- self.assertRaises(ValueError, shouldThrowValueError)
- def testSingleArgUnbound(self):
- mock_contextmanager = mock_contextmanager_generator()
- mock_nested = MockNested(mock_contextmanager)
- with mock_nested:
- self.assertInWithManagerInvariants(mock_contextmanager)
- self.assertInWithManagerInvariants(mock_nested)
- self.assertAfterWithManagerInvariantsNoError(mock_contextmanager)
- self.assertAfterWithManagerInvariantsNoError(mock_nested)
- def testMultipleArgUnbound(self):
- m = mock_contextmanager_generator()
- n = mock_contextmanager_generator()
- o = mock_contextmanager_generator()
- mock_nested = MockNested(m, n, o)
- with mock_nested:
- self.assertInWithManagerInvariants(m)
- self.assertInWithManagerInvariants(n)
- self.assertInWithManagerInvariants(o)
- self.assertInWithManagerInvariants(mock_nested)
- self.assertAfterWithManagerInvariantsNoError(m)
- self.assertAfterWithManagerInvariantsNoError(n)
- self.assertAfterWithManagerInvariantsNoError(o)
- self.assertAfterWithManagerInvariantsNoError(mock_nested)
- def testMultipleArgBound(self):
- mock_nested = MockNested(mock_contextmanager_generator(),
- mock_contextmanager_generator(), mock_contextmanager_generator())
- with mock_nested as (m, n, o):
- self.assertInWithGeneratorInvariants(m)
- self.assertInWithGeneratorInvariants(n)
- self.assertInWithGeneratorInvariants(o)
- self.assertInWithManagerInvariants(mock_nested)
- self.assertAfterWithGeneratorInvariantsNoError(m)
- self.assertAfterWithGeneratorInvariantsNoError(n)
- self.assertAfterWithGeneratorInvariantsNoError(o)
- self.assertAfterWithManagerInvariantsNoError(mock_nested)
- class ExceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin):
- def testSingleResource(self):
- cm = mock_contextmanager_generator()
- def shouldThrow():
- with cm as self.resource:
- self.assertInWithManagerInvariants(cm)
- self.assertInWithGeneratorInvariants(self.resource)
- self.raiseTestException()
- self.assertRaises(RuntimeError, shouldThrow)
- self.assertAfterWithManagerInvariantsWithError(cm)
- self.assertAfterWithGeneratorInvariantsWithError(self.resource)
- def testExceptionNormalized(self):
- cm = mock_contextmanager_generator()
- def shouldThrow():
- with cm as self.resource:
- # Note this relies on the fact that 1 // 0 produces an exception
- # that is not normalized immediately.
- 1 // 0
- self.assertRaises(ZeroDivisionError, shouldThrow)
- self.assertAfterWithManagerInvariantsWithError(cm, ZeroDivisionError)
- def testNestedSingleStatements(self):
- mock_a = mock_contextmanager_generator()
- mock_b = mock_contextmanager_generator()
- def shouldThrow():
- with mock_a as self.foo:
- with mock_b as self.bar:
- self.assertInWithManagerInvariants(mock_a)
- self.assertInWithManagerInvariants(mock_b)
- self.assertInWithGeneratorInvariants(self.foo)
- self.assertInWithGeneratorInvariants(self.bar)
- self.raiseTestException()
- self.assertRaises(RuntimeError, shouldThrow)
- self.assertAfterWithManagerInvariantsWithError(mock_a)
- self.assertAfterWithManagerInvariantsWithError(mock_b)
- self.assertAfterWithGeneratorInvariantsWithError(self.foo)
- self.assertAfterWithGeneratorInvariantsWithError(self.bar)
- def testMultipleResourcesInSingleStatement(self):
- cm_a = mock_contextmanager_generator()
- cm_b = mock_contextmanager_generator()
- mock_nested = MockNested(cm_a, cm_b)
- def shouldThrow():
- with mock_nested as (self.resource_a, self.resource_b):
- self.assertInWithManagerInvariants(cm_a)
- self.assertInWithManagerInvariants(cm_b)
- self.assertInWithManagerInvariants(mock_nested)
- self.assertInWithGeneratorInvariants(self.resource_a)
- self.assertInWithGeneratorInvariants(self.resource_b)
- self.raiseTestException()
- self.assertRaises(RuntimeError, shouldThrow)
- self.assertAfterWithManagerInvariantsWithError(cm_a)
- self.assertAfterWithManagerInvariantsWithError(cm_b)
- self.assertAfterWithManagerInvariantsWithError(mock_nested)
- self.assertAfterWithGeneratorInvariantsWithError(self.resource_a)
- self.assertAfterWithGeneratorInvariantsWithError(self.resource_b)
- def testNestedExceptionBeforeInnerStatement(self):
- mock_a = mock_contextmanager_generator()
- mock_b = mock_contextmanager_generator()
- self.bar = None
- def shouldThrow():
- with mock_a as self.foo:
- self.assertInWithManagerInvariants(mock_a)
- self.assertInWithGeneratorInvariants(self.foo)
- self.raiseTestException()
- with mock_b as self.bar:
- pass
- self.assertRaises(RuntimeError, shouldThrow)
- self.assertAfterWithManagerInvariantsWithError(mock_a)
- self.assertAfterWithGeneratorInvariantsWithError(self.foo)
- # The inner statement stuff should never have been touched
- self.assertEqual(self.bar, None)
- self.assertFalse(mock_b.enter_called)
- self.assertFalse(mock_b.exit_called)
- self.assertEqual(mock_b.exit_args, None)
- def testNestedExceptionAfterInnerStatement(self):
- mock_a = mock_contextmanager_generator()
- mock_b = mock_contextmanager_generator()
- def shouldThrow():
- with mock_a as self.foo:
- with mock_b as self.bar:
- self.assertInWithManagerInvariants(mock_a)
- self.assertInWithManagerInvariants(mock_b)
- self.assertInWithGeneratorInvariants(self.foo)
- self.assertInWithGeneratorInvariants(self.bar)
- self.raiseTestException()
- self.assertRaises(RuntimeError, shouldThrow)
- self.assertAfterWithManagerInvariantsWithError(mock_a)
- self.assertAfterWithManagerInvariantsNoError(mock_b)
- self.assertAfterWithGeneratorInvariantsWithError(self.foo)
- self.assertAfterWithGeneratorInvariantsNoError(self.bar)
- def testRaisedStopIteration1(self):
- # From bug 1462485
- @contextmanager
- def cm():
- yield
- def shouldThrow():
- with cm():
- raise StopIteration("from with")
- self.assertRaises(StopIteration, shouldThrow)
- def testRaisedStopIteration2(self):
- # From bug 1462485
- class cm(object):
- def __enter__(self):
- pass
- def __exit__(self, type, value, traceback):
- pass
- def shouldThrow():
- with cm():
- raise StopIteration("from with")
- self.assertRaises(StopIteration, shouldThrow)
- def testRaisedStopIteration3(self):
- # Another variant where the exception hasn't been instantiated
- # From bug 1705170
- @contextmanager
- def cm():
- yield
- def shouldThrow():
- with cm():
- raise iter([]).next()
- self.assertRaises(StopIteration, shouldThrow)
- def testRaisedGeneratorExit1(self):
- # From bug 1462485
- @contextmanager
- def cm():
- yield
- def shouldThrow():
- with cm():
- raise GeneratorExit("from with")
- self.assertRaises(GeneratorExit, shouldThrow)
- def testRaisedGeneratorExit2(self):
- # From bug 1462485
- class cm (object):
- def __enter__(self):
- pass
- def __exit__(self, type, value, traceback):
- pass
- def shouldThrow():
- with cm():
- raise GeneratorExit("from with")
- self.assertRaises(GeneratorExit, shouldThrow)
- def testErrorsInBool(self):
- # issue4589: __exit__ return code may raise an exception
- # when looking at its truth value.
- class cm(object):
- def __init__(self, bool_conversion):
- class Bool:
- def __nonzero__(self):
- return bool_conversion()
- self.exit_result = Bool()
- def __enter__(self):
- return 3
- def __exit__(self, a, b, c):
- return self.exit_result
- def trueAsBool():
- with cm(lambda: True):
- self.fail("Should NOT see this")
- trueAsBool()
- def falseAsBool():
- with cm(lambda: False):
- self.fail("Should raise")
- self.assertRaises(AssertionError, falseAsBool)
- def failAsBool():
- with cm(lambda: 1 // 0):
- self.fail("Should NOT see this")
- self.assertRaises(ZeroDivisionError, failAsBool)
- class NonLocalFlowControlTestCase(unittest.TestCase):
- def testWithBreak(self):
- counter = 0
- while True:
- counter += 1
- with mock_contextmanager_generator():
- counter += 10
- break
- counter += 100 # Not reached
- self.assertEqual(counter, 11)
- def testWithContinue(self):
- counter = 0
- while True:
- counter += 1
- if counter > 2:
- break
- with mock_contextmanager_generator():
- counter += 10
- continue
- counter += 100 # Not reached
- self.assertEqual(counter, 12)
- def testWithReturn(self):
- def foo():
- counter = 0
- while True:
- counter += 1
- with mock_contextmanager_generator():
- counter += 10
- return counter
- counter += 100 # Not reached
- self.assertEqual(foo(), 11)
- def testWithYield(self):
- def gen():
- with mock_contextmanager_generator():
- yield 12
- yield 13
- x = list(gen())
- self.assertEqual(x, [12, 13])
- def testWithRaise(self):
- counter = 0
- try:
- counter += 1
- with mock_contextmanager_generator():
- counter += 10
- raise RuntimeError
- counter += 100 # Not reached
- except RuntimeError:
- self.assertEqual(counter, 11)
- else:
- self.fail("Didn't raise RuntimeError")
- class AssignmentTargetTestCase(unittest.TestCase):
- def testSingleComplexTarget(self):
- targets = {1: [0, 1, 2]}
- with mock_contextmanager_generator() as targets[1][0]:
- self.assertEqual(targets.keys(), [1])
- self.assertEqual(targets[1][0].__class__, MockResource)
- with mock_contextmanager_generator() as targets.values()[0][1]:
- self.assertEqual(targets.keys(), [1])
- self.assertEqual(targets[1][1].__class__, MockResource)
- with mock_contextmanager_generator() as targets[2]:
- keys = targets.keys()
- keys.sort()
- self.assertEqual(keys, [1, 2])
- class C: pass
- blah = C()
- with mock_contextmanager_generator() as blah.foo:
- self.assertEqual(hasattr(blah, "foo"), True)
- def testMultipleComplexTargets(self):
- class C:
- def __enter__(self): return 1, 2, 3
- def __exit__(self, t, v, tb): pass
- targets = {1: [0, 1, 2]}
- with C() as (targets[1][0], targets[1][1], targets[1][2]):
- self.assertEqual(targets, {1: [1, 2, 3]})
- with C() as (targets.values()[0][2], targets.values()[0][1], targets.values()[0][0]):
- self.assertEqual(targets, {1: [3, 2, 1]})
- with C() as (targets[1], targets[2], targets[3]):
- self.assertEqual(targets, {1: 1, 2: 2, 3: 3})
- class B: pass
- blah = B()
- with C() as (blah.one, blah.two, blah.three):
- self.assertEqual(blah.one, 1)
- self.assertEqual(blah.two, 2)
- self.assertEqual(blah.three, 3)
- class ExitSwallowsExceptionTestCase(unittest.TestCase):
- def testExitTrueSwallowsException(self):
- class AfricanSwallow:
- def __enter__(self): pass
- def __exit__(self, t, v, tb): return True
- try:
- with AfricanSwallow():
- 1 // 0
- except ZeroDivisionError:
- self.fail("ZeroDivisionError should have been swallowed")
- def testExitFalseDoesntSwallowException(self):
- class EuropeanSwallow:
- def __enter__(self): pass
- def __exit__(self, t, v, tb): return False
- try:
- with EuropeanSwallow():
- 1 // 0
- except ZeroDivisionError:
- pass
- else:
- self.fail("ZeroDivisionError should have been raised")
- class NestedWith(unittest.TestCase):
- class Dummy(object):
- def __init__(self, value=None, gobble=False):
- if value is None:
- value = self
- self.value = value
- self.gobble = gobble
- self.enter_called = False
- self.exit_called = False
- def __enter__(self):
- self.enter_called = True
- return self.value
- def __exit__(self, *exc_info):
- self.exit_called = True
- self.exc_info = exc_info
- if self.gobble:
- return True
- class InitRaises(object):
- def __init__(self): raise RuntimeError()
- class EnterRaises(object):
- def __enter__(self): raise RuntimeError()
- def __exit__(self, *exc_info): pass
- class ExitRaises(object):
- def __enter__(self): pass
- def __exit__(self, *exc_info): raise RuntimeError()
- def testNoExceptions(self):
- with self.Dummy() as a, self.Dummy() as b:
- self.assertTrue(a.enter_called)
- self.assertTrue(b.enter_called)
- self.assertTrue(a.exit_called)
- self.assertTrue(b.exit_called)
- def testExceptionInExprList(self):
- try:
- with self.Dummy() as a, self.InitRaises():
- pass
- except:
- pass
- self.assertTrue(a.enter_called)
- self.assertTrue(a.exit_called)
- def testExceptionInEnter(self):
- try:
- with self.Dummy() as a, self.EnterRaises():
- self.fail('body of bad with executed')
- except RuntimeError:
- pass
- else:
- self.fail('RuntimeError not reraised')
- self.assertTrue(a.enter_called)
- self.assertTrue(a.exit_called)
- def testExceptionInExit(self):
- body_executed = False
- with self.Dummy(gobble=True) as a, self.ExitRaises():
- body_executed = True
- self.assertTrue(a.enter_called)
- self.assertTrue(a.exit_called)
- self.assertTrue(body_executed)
- self.assertNotEqual(a.exc_info[0], None)
- def testEnterReturnsTuple(self):
- with self.Dummy(value=(1,2)) as (a1, a2), \
- self.Dummy(value=(10, 20)) as (b1, b2):
- self.assertEqual(1, a1)
- self.assertEqual(2, a2)
- self.assertEqual(10, b1)
- self.assertEqual(20, b2)
- def test_main():
- run_unittest(FailureTestCase, NonexceptionalTestCase,
- NestedNonexceptionalTestCase, ExceptionalTestCase,
- NonLocalFlowControlTestCase,
- AssignmentTargetTestCase,
- ExitSwallowsExceptionTestCase,
- NestedWith)
- if __name__ == '__main__':
- test_main()
|