PageRenderTime 280ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/Lib/test/test_with.py

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