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