1"""Unit tests for the with statement specified in PEP 343.""" 2 3 4__author__ = "Mike Bland" 5__email__ = "mbland at acm dot org" 6 7import sys 8import unittest 9from collections import deque 10from contextlib import GeneratorContextManager, contextmanager 11from test.test_support import run_unittest 12 13 14class MockContextManager(GeneratorContextManager): 15 def __init__(self, gen): 16 GeneratorContextManager.__init__(self, gen) 17 self.enter_called = False 18 self.exit_called = False 19 self.exit_args = None 20 21 def __enter__(self): 22 self.enter_called = True 23 return GeneratorContextManager.__enter__(self) 24 25 def __exit__(self, type, value, traceback): 26 self.exit_called = True 27 self.exit_args = (type, value, traceback) 28 return GeneratorContextManager.__exit__(self, type, 29 value, traceback) 30 31 32def mock_contextmanager(func): 33 def helper(*args, **kwds): 34 return MockContextManager(func(*args, **kwds)) 35 return helper 36 37 38class MockResource(object): 39 def __init__(self): 40 self.yielded = False 41 self.stopped = False 42 43 44@mock_contextmanager 45def mock_contextmanager_generator(): 46 mock = MockResource() 47 try: 48 mock.yielded = True 49 yield mock 50 finally: 51 mock.stopped = True 52 53 54class Nested(object): 55 56 def __init__(self, *managers): 57 self.managers = managers 58 self.entered = None 59 60 def __enter__(self): 61 if self.entered is not None: 62 raise RuntimeError("Context is not reentrant") 63 self.entered = deque() 64 vars = [] 65 try: 66 for mgr in self.managers: 67 vars.append(mgr.__enter__()) 68 self.entered.appendleft(mgr) 69 except: 70 if not self.__exit__(*sys.exc_info()): 71 raise 72 return vars 73 74 def __exit__(self, *exc_info): 75 # Behave like nested with statements 76 # first in, last out 77 # New exceptions override old ones 78 ex = exc_info 79 for mgr in self.entered: 80 try: 81 if mgr.__exit__(*ex): 82 ex = (None, None, None) 83 except: 84 ex = sys.exc_info() 85 self.entered = None 86 if ex is not exc_info: 87 raise ex[0], ex[1], ex[2] 88 89 90class MockNested(Nested): 91 def __init__(self, *managers): 92 Nested.__init__(self, *managers) 93 self.enter_called = False 94 self.exit_called = False 95 self.exit_args = None 96 97 def __enter__(self): 98 self.enter_called = True 99 return Nested.__enter__(self) 100 101 def __exit__(self, *exc_info): 102 self.exit_called = True 103 self.exit_args = exc_info 104 return Nested.__exit__(self, *exc_info) 105 106 107class FailureTestCase(unittest.TestCase): 108 def testNameError(self): 109 def fooNotDeclared(): 110 with foo: pass 111 self.assertRaises(NameError, fooNotDeclared) 112 113 def testEnterAttributeError(self): 114 class LacksEnter(object): 115 def __exit__(self, type, value, traceback): 116 pass 117 118 def fooLacksEnter(): 119 foo = LacksEnter() 120 with foo: pass 121 self.assertRaises(AttributeError, fooLacksEnter) 122 123 def testExitAttributeError(self): 124 class LacksExit(object): 125 def __enter__(self): 126 pass 127 128 def fooLacksExit(): 129 foo = LacksExit() 130 with foo: pass 131 self.assertRaises(AttributeError, fooLacksExit) 132 133 def assertRaisesSyntaxError(self, codestr): 134 def shouldRaiseSyntaxError(s): 135 compile(s, '', 'single') 136 self.assertRaises(SyntaxError, shouldRaiseSyntaxError, codestr) 137 138 def testAssignmentToNoneError(self): 139 self.assertRaisesSyntaxError('with mock as None:\n pass') 140 self.assertRaisesSyntaxError( 141 'with mock as (None):\n' 142 ' pass') 143 144 def testAssignmentToEmptyTupleError(self): 145 self.assertRaisesSyntaxError( 146 'with mock as ():\n' 147 ' pass') 148 149 def testAssignmentToTupleOnlyContainingNoneError(self): 150 self.assertRaisesSyntaxError('with mock as None,:\n pass') 151 self.assertRaisesSyntaxError( 152 'with mock as (None,):\n' 153 ' pass') 154 155 def testAssignmentToTupleContainingNoneError(self): 156 self.assertRaisesSyntaxError( 157 'with mock as (foo, None, bar):\n' 158 ' pass') 159 160 def testEnterThrows(self): 161 class EnterThrows(object): 162 def __enter__(self): 163 raise RuntimeError("Enter threw") 164 def __exit__(self, *args): 165 pass 166 167 def shouldThrow(): 168 ct = EnterThrows() 169 self.foo = None 170 with ct as self.foo: 171 pass 172 self.assertRaises(RuntimeError, shouldThrow) 173 self.assertEqual(self.foo, None) 174 175 def testExitThrows(self): 176 class ExitThrows(object): 177 def __enter__(self): 178 return 179 def __exit__(self, *args): 180 raise RuntimeError(42) 181 def shouldThrow(): 182 with ExitThrows(): 183 pass 184 self.assertRaises(RuntimeError, shouldThrow) 185 186class ContextmanagerAssertionMixin(object): 187 TEST_EXCEPTION = RuntimeError("test exception") 188 189 def assertInWithManagerInvariants(self, mock_manager): 190 self.assertTrue(mock_manager.enter_called) 191 self.assertFalse(mock_manager.exit_called) 192 self.assertEqual(mock_manager.exit_args, None) 193 194 def assertAfterWithManagerInvariants(self, mock_manager, exit_args): 195 self.assertTrue(mock_manager.enter_called) 196 self.assertTrue(mock_manager.exit_called) 197 self.assertEqual(mock_manager.exit_args, exit_args) 198 199 def assertAfterWithManagerInvariantsNoError(self, mock_manager): 200 self.assertAfterWithManagerInvariants(mock_manager, 201 (None, None, None)) 202 203 def assertInWithGeneratorInvariants(self, mock_generator): 204 self.assertTrue(mock_generator.yielded) 205 self.assertFalse(mock_generator.stopped) 206 207 def assertAfterWithGeneratorInvariantsNoError(self, mock_generator): 208 self.assertTrue(mock_generator.yielded) 209 self.assertTrue(mock_generator.stopped) 210 211 def raiseTestException(self): 212 raise self.TEST_EXCEPTION 213 214 def assertAfterWithManagerInvariantsWithError(self, mock_manager, 215 exc_type=None): 216 self.assertTrue(mock_manager.enter_called) 217 self.assertTrue(mock_manager.exit_called) 218 if exc_type is None: 219 self.assertEqual(mock_manager.exit_args[1], self.TEST_EXCEPTION) 220 exc_type = type(self.TEST_EXCEPTION) 221 self.assertEqual(mock_manager.exit_args[0], exc_type) 222 # Test the __exit__ arguments. Issue #7853 223 self.assertIsInstance(mock_manager.exit_args[1], exc_type) 224 self.assertIsNot(mock_manager.exit_args[2], None) 225 226 def assertAfterWithGeneratorInvariantsWithError(self, mock_generator): 227 self.assertTrue(mock_generator.yielded) 228 self.assertTrue(mock_generator.stopped) 229 230 231class NonexceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin): 232 def testInlineGeneratorSyntax(self): 233 with mock_contextmanager_generator(): 234 pass 235 236 def testUnboundGenerator(self): 237 mock = mock_contextmanager_generator() 238 with mock: 239 pass 240 self.assertAfterWithManagerInvariantsNoError(mock) 241 242 def testInlineGeneratorBoundSyntax(self): 243 with mock_contextmanager_generator() as foo: 244 self.assertInWithGeneratorInvariants(foo) 245 # FIXME: In the future, we'll try to keep the bound names from leaking 246 self.assertAfterWithGeneratorInvariantsNoError(foo) 247 248 def testInlineGeneratorBoundToExistingVariable(self): 249 foo = None 250 with mock_contextmanager_generator() as foo: 251 self.assertInWithGeneratorInvariants(foo) 252 self.assertAfterWithGeneratorInvariantsNoError(foo) 253 254 def testInlineGeneratorBoundToDottedVariable(self): 255 with mock_contextmanager_generator() as self.foo: 256 self.assertInWithGeneratorInvariants(self.foo) 257 self.assertAfterWithGeneratorInvariantsNoError(self.foo) 258 259 def testBoundGenerator(self): 260 mock = mock_contextmanager_generator() 261 with mock as foo: 262 self.assertInWithGeneratorInvariants(foo) 263 self.assertInWithManagerInvariants(mock) 264 self.assertAfterWithGeneratorInvariantsNoError(foo) 265 self.assertAfterWithManagerInvariantsNoError(mock) 266 267 def testNestedSingleStatements(self): 268 mock_a = mock_contextmanager_generator() 269 with mock_a as foo: 270 mock_b = mock_contextmanager_generator() 271 with mock_b as bar: 272 self.assertInWithManagerInvariants(mock_a) 273 self.assertInWithManagerInvariants(mock_b) 274 self.assertInWithGeneratorInvariants(foo) 275 self.assertInWithGeneratorInvariants(bar) 276 self.assertAfterWithManagerInvariantsNoError(mock_b) 277 self.assertAfterWithGeneratorInvariantsNoError(bar) 278 self.assertInWithManagerInvariants(mock_a) 279 self.assertInWithGeneratorInvariants(foo) 280 self.assertAfterWithManagerInvariantsNoError(mock_a) 281 self.assertAfterWithGeneratorInvariantsNoError(foo) 282 283 284class NestedNonexceptionalTestCase(unittest.TestCase, 285 ContextmanagerAssertionMixin): 286 def testSingleArgInlineGeneratorSyntax(self): 287 with Nested(mock_contextmanager_generator()): 288 pass 289 290 def testSingleArgBoundToNonTuple(self): 291 m = mock_contextmanager_generator() 292 # This will bind all the arguments to nested() into a single list 293 # assigned to foo. 294 with Nested(m) as foo: 295 self.assertInWithManagerInvariants(m) 296 self.assertAfterWithManagerInvariantsNoError(m) 297 298 def testSingleArgBoundToSingleElementParenthesizedList(self): 299 m = mock_contextmanager_generator() 300 # This will bind all the arguments to nested() into a single list 301 # assigned to foo. 302 with Nested(m) as (foo): 303 self.assertInWithManagerInvariants(m) 304 self.assertAfterWithManagerInvariantsNoError(m) 305 306 def testSingleArgBoundToMultipleElementTupleError(self): 307 def shouldThrowValueError(): 308 with Nested(mock_contextmanager_generator()) as (foo, bar): 309 pass 310 self.assertRaises(ValueError, shouldThrowValueError) 311 312 def testSingleArgUnbound(self): 313 mock_contextmanager = mock_contextmanager_generator() 314 mock_nested = MockNested(mock_contextmanager) 315 with mock_nested: 316 self.assertInWithManagerInvariants(mock_contextmanager) 317 self.assertInWithManagerInvariants(mock_nested) 318 self.assertAfterWithManagerInvariantsNoError(mock_contextmanager) 319 self.assertAfterWithManagerInvariantsNoError(mock_nested) 320 321 def testMultipleArgUnbound(self): 322 m = mock_contextmanager_generator() 323 n = mock_contextmanager_generator() 324 o = mock_contextmanager_generator() 325 mock_nested = MockNested(m, n, o) 326 with mock_nested: 327 self.assertInWithManagerInvariants(m) 328 self.assertInWithManagerInvariants(n) 329 self.assertInWithManagerInvariants(o) 330 self.assertInWithManagerInvariants(mock_nested) 331 self.assertAfterWithManagerInvariantsNoError(m) 332 self.assertAfterWithManagerInvariantsNoError(n) 333 self.assertAfterWithManagerInvariantsNoError(o) 334 self.assertAfterWithManagerInvariantsNoError(mock_nested) 335 336 def testMultipleArgBound(self): 337 mock_nested = MockNested(mock_contextmanager_generator(), 338 mock_contextmanager_generator(), mock_contextmanager_generator()) 339 with mock_nested as (m, n, o): 340 self.assertInWithGeneratorInvariants(m) 341 self.assertInWithGeneratorInvariants(n) 342 self.assertInWithGeneratorInvariants(o) 343 self.assertInWithManagerInvariants(mock_nested) 344 self.assertAfterWithGeneratorInvariantsNoError(m) 345 self.assertAfterWithGeneratorInvariantsNoError(n) 346 self.assertAfterWithGeneratorInvariantsNoError(o) 347 self.assertAfterWithManagerInvariantsNoError(mock_nested) 348 349 350class ExceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin): 351 def testSingleResource(self): 352 cm = mock_contextmanager_generator() 353 def shouldThrow(): 354 with cm as self.resource: 355 self.assertInWithManagerInvariants(cm) 356 self.assertInWithGeneratorInvariants(self.resource) 357 self.raiseTestException() 358 self.assertRaises(RuntimeError, shouldThrow) 359 self.assertAfterWithManagerInvariantsWithError(cm) 360 self.assertAfterWithGeneratorInvariantsWithError(self.resource) 361 362 def testExceptionNormalized(self): 363 cm = mock_contextmanager_generator() 364 def shouldThrow(): 365 with cm as self.resource: 366 # Note this relies on the fact that 1 // 0 produces an exception 367 # that is not normalized immediately. 368 1 // 0 369 self.assertRaises(ZeroDivisionError, shouldThrow) 370 self.assertAfterWithManagerInvariantsWithError(cm, ZeroDivisionError) 371 372 def testNestedSingleStatements(self): 373 mock_a = mock_contextmanager_generator() 374 mock_b = mock_contextmanager_generator() 375 def shouldThrow(): 376 with mock_a as self.foo: 377 with mock_b as self.bar: 378 self.assertInWithManagerInvariants(mock_a) 379 self.assertInWithManagerInvariants(mock_b) 380 self.assertInWithGeneratorInvariants(self.foo) 381 self.assertInWithGeneratorInvariants(self.bar) 382 self.raiseTestException() 383 self.assertRaises(RuntimeError, shouldThrow) 384 self.assertAfterWithManagerInvariantsWithError(mock_a) 385 self.assertAfterWithManagerInvariantsWithError(mock_b) 386 self.assertAfterWithGeneratorInvariantsWithError(self.foo) 387 self.assertAfterWithGeneratorInvariantsWithError(self.bar) 388 389 def testMultipleResourcesInSingleStatement(self): 390 cm_a = mock_contextmanager_generator() 391 cm_b = mock_contextmanager_generator() 392 mock_nested = MockNested(cm_a, cm_b) 393 def shouldThrow(): 394 with mock_nested as (self.resource_a, self.resource_b): 395 self.assertInWithManagerInvariants(cm_a) 396 self.assertInWithManagerInvariants(cm_b) 397 self.assertInWithManagerInvariants(mock_nested) 398 self.assertInWithGeneratorInvariants(self.resource_a) 399 self.assertInWithGeneratorInvariants(self.resource_b) 400 self.raiseTestException() 401 self.assertRaises(RuntimeError, shouldThrow) 402 self.assertAfterWithManagerInvariantsWithError(cm_a) 403 self.assertAfterWithManagerInvariantsWithError(cm_b) 404 self.assertAfterWithManagerInvariantsWithError(mock_nested) 405 self.assertAfterWithGeneratorInvariantsWithError(self.resource_a) 406 self.assertAfterWithGeneratorInvariantsWithError(self.resource_b) 407 408 def testNestedExceptionBeforeInnerStatement(self): 409 mock_a = mock_contextmanager_generator() 410 mock_b = mock_contextmanager_generator() 411 self.bar = None 412 def shouldThrow(): 413 with mock_a as self.foo: 414 self.assertInWithManagerInvariants(mock_a) 415 self.assertInWithGeneratorInvariants(self.foo) 416 self.raiseTestException() 417 with mock_b as self.bar: 418 pass 419 self.assertRaises(RuntimeError, shouldThrow) 420 self.assertAfterWithManagerInvariantsWithError(mock_a) 421 self.assertAfterWithGeneratorInvariantsWithError(self.foo) 422 423 # The inner statement stuff should never have been touched 424 self.assertEqual(self.bar, None) 425 self.assertFalse(mock_b.enter_called) 426 self.assertFalse(mock_b.exit_called) 427 self.assertEqual(mock_b.exit_args, None) 428 429 def testNestedExceptionAfterInnerStatement(self): 430 mock_a = mock_contextmanager_generator() 431 mock_b = mock_contextmanager_generator() 432 def shouldThrow(): 433 with mock_a as self.foo: 434 with mock_b as self.bar: 435 self.assertInWithManagerInvariants(mock_a) 436 self.assertInWithManagerInvariants(mock_b) 437 self.assertInWithGeneratorInvariants(self.foo) 438 self.assertInWithGeneratorInvariants(self.bar) 439 self.raiseTestException() 440 self.assertRaises(RuntimeError, shouldThrow) 441 self.assertAfterWithManagerInvariantsWithError(mock_a) 442 self.assertAfterWithManagerInvariantsNoError(mock_b) 443 self.assertAfterWithGeneratorInvariantsWithError(self.foo) 444 self.assertAfterWithGeneratorInvariantsNoError(self.bar) 445 446 def testRaisedStopIteration1(self): 447 # From bug 1462485 448 @contextmanager 449 def cm(): 450 yield 451 452 def shouldThrow(): 453 with cm(): 454 raise StopIteration("from with") 455 456 self.assertRaises(StopIteration, shouldThrow) 457 458 def testRaisedStopIteration2(self): 459 # From bug 1462485 460 class cm(object): 461 def __enter__(self): 462 pass 463 def __exit__(self, type, value, traceback): 464 pass 465 466 def shouldThrow(): 467 with cm(): 468 raise StopIteration("from with") 469 470 self.assertRaises(StopIteration, shouldThrow) 471 472 def testRaisedStopIteration3(self): 473 # Another variant where the exception hasn't been instantiated 474 # From bug 1705170 475 @contextmanager 476 def cm(): 477 yield 478 479 def shouldThrow(): 480 with cm(): 481 raise iter([]).next() 482 483 self.assertRaises(StopIteration, shouldThrow) 484 485 def testRaisedGeneratorExit1(self): 486 # From bug 1462485 487 @contextmanager 488 def cm(): 489 yield 490 491 def shouldThrow(): 492 with cm(): 493 raise GeneratorExit("from with") 494 495 self.assertRaises(GeneratorExit, shouldThrow) 496 497 def testRaisedGeneratorExit2(self): 498 # From bug 1462485 499 class cm (object): 500 def __enter__(self): 501 pass 502 def __exit__(self, type, value, traceback): 503 pass 504 505 def shouldThrow(): 506 with cm(): 507 raise GeneratorExit("from with") 508 509 self.assertRaises(GeneratorExit, shouldThrow) 510 511 def testErrorsInBool(self): 512 # issue4589: __exit__ return code may raise an exception 513 # when looking at its truth value. 514 515 class cm(object): 516 def __init__(self, bool_conversion): 517 class Bool: 518 def __nonzero__(self): 519 return bool_conversion() 520 self.exit_result = Bool() 521 def __enter__(self): 522 return 3 523 def __exit__(self, a, b, c): 524 return self.exit_result 525 526 def trueAsBool(): 527 with cm(lambda: True): 528 self.fail("Should NOT see this") 529 trueAsBool() 530 531 def falseAsBool(): 532 with cm(lambda: False): 533 self.fail("Should raise") 534 self.assertRaises(AssertionError, falseAsBool) 535 536 def failAsBool(): 537 with cm(lambda: 1 // 0): 538 self.fail("Should NOT see this") 539 self.assertRaises(ZeroDivisionError, failAsBool) 540 541 542class NonLocalFlowControlTestCase(unittest.TestCase): 543 544 def testWithBreak(self): 545 counter = 0 546 while True: 547 counter += 1 548 with mock_contextmanager_generator(): 549 counter += 10 550 break 551 counter += 100 # Not reached 552 self.assertEqual(counter, 11) 553 554 def testWithContinue(self): 555 counter = 0 556 while True: 557 counter += 1 558 if counter > 2: 559 break 560 with mock_contextmanager_generator(): 561 counter += 10 562 continue 563 counter += 100 # Not reached 564 self.assertEqual(counter, 12) 565 566 def testWithReturn(self): 567 def foo(): 568 counter = 0 569 while True: 570 counter += 1 571 with mock_contextmanager_generator(): 572 counter += 10 573 return counter 574 counter += 100 # Not reached 575 self.assertEqual(foo(), 11) 576 577 def testWithYield(self): 578 def gen(): 579 with mock_contextmanager_generator(): 580 yield 12 581 yield 13 582 x = list(gen()) 583 self.assertEqual(x, [12, 13]) 584 585 def testWithRaise(self): 586 counter = 0 587 try: 588 counter += 1 589 with mock_contextmanager_generator(): 590 counter += 10 591 raise RuntimeError 592 counter += 100 # Not reached 593 except RuntimeError: 594 self.assertEqual(counter, 11) 595 else: 596 self.fail("Didn't raise RuntimeError") 597 598 599class AssignmentTargetTestCase(unittest.TestCase): 600 601 def testSingleComplexTarget(self): 602 targets = {1: [0, 1, 2]} 603 with mock_contextmanager_generator() as targets[1][0]: 604 self.assertEqual(targets.keys(), [1]) 605 self.assertEqual(targets[1][0].__class__, MockResource) 606 with mock_contextmanager_generator() as targets.values()[0][1]: 607 self.assertEqual(targets.keys(), [1]) 608 self.assertEqual(targets[1][1].__class__, MockResource) 609 with mock_contextmanager_generator() as targets[2]: 610 keys = targets.keys() 611 keys.sort() 612 self.assertEqual(keys, [1, 2]) 613 class C: pass 614 blah = C() 615 with mock_contextmanager_generator() as blah.foo: 616 self.assertEqual(hasattr(blah, "foo"), True) 617 618 def testMultipleComplexTargets(self): 619 class C: 620 def __enter__(self): return 1, 2, 3 621 def __exit__(self, t, v, tb): pass 622 targets = {1: [0, 1, 2]} 623 with C() as (targets[1][0], targets[1][1], targets[1][2]): 624 self.assertEqual(targets, {1: [1, 2, 3]}) 625 with C() as (targets.values()[0][2], targets.values()[0][1], targets.values()[0][0]): 626 self.assertEqual(targets, {1: [3, 2, 1]}) 627 with C() as (targets[1], targets[2], targets[3]): 628 self.assertEqual(targets, {1: 1, 2: 2, 3: 3}) 629 class B: pass 630 blah = B() 631 with C() as (blah.one, blah.two, blah.three): 632 self.assertEqual(blah.one, 1) 633 self.assertEqual(blah.two, 2) 634 self.assertEqual(blah.three, 3) 635 636 637class ExitSwallowsExceptionTestCase(unittest.TestCase): 638 639 def testExitTrueSwallowsException(self): 640 class AfricanSwallow: 641 def __enter__(self): pass 642 def __exit__(self, t, v, tb): return True 643 try: 644 with AfricanSwallow(): 645 1 // 0 646 except ZeroDivisionError: 647 self.fail("ZeroDivisionError should have been swallowed") 648 649 def testExitFalseDoesntSwallowException(self): 650 class EuropeanSwallow: 651 def __enter__(self): pass 652 def __exit__(self, t, v, tb): return False 653 try: 654 with EuropeanSwallow(): 655 1 // 0 656 except ZeroDivisionError: 657 pass 658 else: 659 self.fail("ZeroDivisionError should have been raised") 660 661 662class NestedWith(unittest.TestCase): 663 664 class Dummy(object): 665 def __init__(self, value=None, gobble=False): 666 if value is None: 667 value = self 668 self.value = value 669 self.gobble = gobble 670 self.enter_called = False 671 self.exit_called = False 672 673 def __enter__(self): 674 self.enter_called = True 675 return self.value 676 677 def __exit__(self, *exc_info): 678 self.exit_called = True 679 self.exc_info = exc_info 680 if self.gobble: 681 return True 682 683 class InitRaises(object): 684 def __init__(self): raise RuntimeError() 685 686 class EnterRaises(object): 687 def __enter__(self): raise RuntimeError() 688 def __exit__(self, *exc_info): pass 689 690 class ExitRaises(object): 691 def __enter__(self): pass 692 def __exit__(self, *exc_info): raise RuntimeError() 693 694 def testNoExceptions(self): 695 with self.Dummy() as a, self.Dummy() as b: 696 self.assertTrue(a.enter_called) 697 self.assertTrue(b.enter_called) 698 self.assertTrue(a.exit_called) 699 self.assertTrue(b.exit_called) 700 701 def testExceptionInExprList(self): 702 try: 703 with self.Dummy() as a, self.InitRaises(): 704 pass 705 except: 706 pass 707 self.assertTrue(a.enter_called) 708 self.assertTrue(a.exit_called) 709 710 def testExceptionInEnter(self): 711 try: 712 with self.Dummy() as a, self.EnterRaises(): 713 self.fail('body of bad with executed') 714 except RuntimeError: 715 pass 716 else: 717 self.fail('RuntimeError not reraised') 718 self.assertTrue(a.enter_called) 719 self.assertTrue(a.exit_called) 720 721 def testExceptionInExit(self): 722 body_executed = False 723 with self.Dummy(gobble=True) as a, self.ExitRaises(): 724 body_executed = True 725 self.assertTrue(a.enter_called) 726 self.assertTrue(a.exit_called) 727 self.assertTrue(body_executed) 728 self.assertNotEqual(a.exc_info[0], None) 729 730 def testEnterReturnsTuple(self): 731 with self.Dummy(value=(1,2)) as (a1, a2), \ 732 self.Dummy(value=(10, 20)) as (b1, b2): 733 self.assertEqual(1, a1) 734 self.assertEqual(2, a2) 735 self.assertEqual(10, b1) 736 self.assertEqual(20, b2) 737 738def test_main(): 739 run_unittest(FailureTestCase, NonexceptionalTestCase, 740 NestedNonexceptionalTestCase, ExceptionalTestCase, 741 NonLocalFlowControlTestCase, 742 AssignmentTargetTestCase, 743 ExitSwallowsExceptionTestCase, 744 NestedWith) 745 746 747if __name__ == '__main__': 748 test_main() 749