test_raise.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. # Copyright 2007 Google, Inc. All Rights Reserved.
  2. # Licensed to PSF under a Contributor Agreement.
  3. """Tests for the raise statement."""
  4. from test import support
  5. import sys
  6. import types
  7. import unittest
  8. def get_tb():
  9. try:
  10. raise OSError()
  11. except OSError as e:
  12. return e.__traceback__
  13. class Context:
  14. def __enter__(self):
  15. return self
  16. def __exit__(self, exc_type, exc_value, exc_tb):
  17. return True
  18. class TestRaise(unittest.TestCase):
  19. def test_invalid_reraise(self):
  20. try:
  21. raise
  22. except RuntimeError as e:
  23. self.assertIn("No active exception", str(e))
  24. else:
  25. self.fail("No exception raised")
  26. def test_reraise(self):
  27. try:
  28. try:
  29. raise IndexError()
  30. except IndexError as e:
  31. exc1 = e
  32. raise
  33. except IndexError as exc2:
  34. self.assertIs(exc1, exc2)
  35. else:
  36. self.fail("No exception raised")
  37. def test_except_reraise(self):
  38. def reraise():
  39. try:
  40. raise TypeError("foo")
  41. except:
  42. try:
  43. raise KeyError("caught")
  44. except KeyError:
  45. pass
  46. raise
  47. self.assertRaises(TypeError, reraise)
  48. def test_finally_reraise(self):
  49. def reraise():
  50. try:
  51. raise TypeError("foo")
  52. except:
  53. try:
  54. raise KeyError("caught")
  55. finally:
  56. raise
  57. self.assertRaises(KeyError, reraise)
  58. def test_nested_reraise(self):
  59. def nested_reraise():
  60. raise
  61. def reraise():
  62. try:
  63. raise TypeError("foo")
  64. except:
  65. nested_reraise()
  66. self.assertRaises(TypeError, reraise)
  67. def test_raise_from_None(self):
  68. try:
  69. try:
  70. raise TypeError("foo")
  71. except:
  72. raise ValueError() from None
  73. except ValueError as e:
  74. self.assertIsInstance(e.__context__, TypeError)
  75. self.assertIsNone(e.__cause__)
  76. def test_with_reraise1(self):
  77. def reraise():
  78. try:
  79. raise TypeError("foo")
  80. except:
  81. with Context():
  82. pass
  83. raise
  84. self.assertRaises(TypeError, reraise)
  85. def test_with_reraise2(self):
  86. def reraise():
  87. try:
  88. raise TypeError("foo")
  89. except:
  90. with Context():
  91. raise KeyError("caught")
  92. raise
  93. self.assertRaises(TypeError, reraise)
  94. def test_yield_reraise(self):
  95. def reraise():
  96. try:
  97. raise TypeError("foo")
  98. except:
  99. yield 1
  100. raise
  101. g = reraise()
  102. next(g)
  103. self.assertRaises(TypeError, lambda: next(g))
  104. self.assertRaises(StopIteration, lambda: next(g))
  105. def test_erroneous_exception(self):
  106. class MyException(Exception):
  107. def __init__(self):
  108. raise RuntimeError()
  109. try:
  110. raise MyException
  111. except RuntimeError:
  112. pass
  113. else:
  114. self.fail("No exception raised")
  115. def test_new_returns_invalid_instance(self):
  116. # See issue #11627.
  117. class MyException(Exception):
  118. def __new__(cls, *args):
  119. return object()
  120. with self.assertRaises(TypeError):
  121. raise MyException
  122. def test_assert_with_tuple_arg(self):
  123. try:
  124. assert False, (3,)
  125. except AssertionError as e:
  126. self.assertEqual(str(e), "(3,)")
  127. class TestCause(unittest.TestCase):
  128. def testCauseSyntax(self):
  129. try:
  130. try:
  131. try:
  132. raise TypeError
  133. except Exception:
  134. raise ValueError from None
  135. except ValueError as exc:
  136. self.assertIsNone(exc.__cause__)
  137. self.assertTrue(exc.__suppress_context__)
  138. exc.__suppress_context__ = False
  139. raise exc
  140. except ValueError as exc:
  141. e = exc
  142. self.assertIsNone(e.__cause__)
  143. self.assertFalse(e.__suppress_context__)
  144. self.assertIsInstance(e.__context__, TypeError)
  145. def test_invalid_cause(self):
  146. try:
  147. raise IndexError from 5
  148. except TypeError as e:
  149. self.assertIn("exception cause", str(e))
  150. else:
  151. self.fail("No exception raised")
  152. def test_class_cause(self):
  153. try:
  154. raise IndexError from KeyError
  155. except IndexError as e:
  156. self.assertIsInstance(e.__cause__, KeyError)
  157. else:
  158. self.fail("No exception raised")
  159. def test_instance_cause(self):
  160. cause = KeyError()
  161. try:
  162. raise IndexError from cause
  163. except IndexError as e:
  164. self.assertIs(e.__cause__, cause)
  165. else:
  166. self.fail("No exception raised")
  167. def test_erroneous_cause(self):
  168. class MyException(Exception):
  169. def __init__(self):
  170. raise RuntimeError()
  171. try:
  172. raise IndexError from MyException
  173. except RuntimeError:
  174. pass
  175. else:
  176. self.fail("No exception raised")
  177. class TestTraceback(unittest.TestCase):
  178. def test_sets_traceback(self):
  179. try:
  180. raise IndexError()
  181. except IndexError as e:
  182. self.assertIsInstance(e.__traceback__, types.TracebackType)
  183. else:
  184. self.fail("No exception raised")
  185. def test_accepts_traceback(self):
  186. tb = get_tb()
  187. try:
  188. raise IndexError().with_traceback(tb)
  189. except IndexError as e:
  190. self.assertNotEqual(e.__traceback__, tb)
  191. self.assertEqual(e.__traceback__.tb_next, tb)
  192. else:
  193. self.fail("No exception raised")
  194. class TestTracebackType(unittest.TestCase):
  195. def raiser(self):
  196. raise ValueError
  197. def test_attrs(self):
  198. try:
  199. self.raiser()
  200. except Exception as exc:
  201. tb = exc.__traceback__
  202. self.assertIsInstance(tb.tb_next, types.TracebackType)
  203. self.assertIs(tb.tb_frame, sys._getframe())
  204. self.assertIsInstance(tb.tb_lasti, int)
  205. self.assertIsInstance(tb.tb_lineno, int)
  206. self.assertIs(tb.tb_next.tb_next, None)
  207. # Invalid assignments
  208. with self.assertRaises(TypeError):
  209. del tb.tb_next
  210. with self.assertRaises(TypeError):
  211. tb.tb_next = "asdf"
  212. # Loops
  213. with self.assertRaises(ValueError):
  214. tb.tb_next = tb
  215. with self.assertRaises(ValueError):
  216. tb.tb_next.tb_next = tb
  217. # Valid assignments
  218. tb.tb_next = None
  219. self.assertIs(tb.tb_next, None)
  220. new_tb = get_tb()
  221. tb.tb_next = new_tb
  222. self.assertIs(tb.tb_next, new_tb)
  223. def test_constructor(self):
  224. other_tb = get_tb()
  225. frame = sys._getframe()
  226. tb = types.TracebackType(other_tb, frame, 1, 2)
  227. self.assertEqual(tb.tb_next, other_tb)
  228. self.assertEqual(tb.tb_frame, frame)
  229. self.assertEqual(tb.tb_lasti, 1)
  230. self.assertEqual(tb.tb_lineno, 2)
  231. tb = types.TracebackType(None, frame, 1, 2)
  232. self.assertEqual(tb.tb_next, None)
  233. with self.assertRaises(TypeError):
  234. types.TracebackType("no", frame, 1, 2)
  235. with self.assertRaises(TypeError):
  236. types.TracebackType(other_tb, "no", 1, 2)
  237. with self.assertRaises(TypeError):
  238. types.TracebackType(other_tb, frame, "no", 2)
  239. with self.assertRaises(TypeError):
  240. types.TracebackType(other_tb, frame, 1, "nuh-uh")
  241. class TestContext(unittest.TestCase):
  242. def test_instance_context_instance_raise(self):
  243. context = IndexError()
  244. try:
  245. try:
  246. raise context
  247. except:
  248. raise OSError()
  249. except OSError as e:
  250. self.assertIs(e.__context__, context)
  251. else:
  252. self.fail("No exception raised")
  253. def test_class_context_instance_raise(self):
  254. context = IndexError
  255. try:
  256. try:
  257. raise context
  258. except:
  259. raise OSError()
  260. except OSError as e:
  261. self.assertIsNot(e.__context__, context)
  262. self.assertIsInstance(e.__context__, context)
  263. else:
  264. self.fail("No exception raised")
  265. def test_class_context_class_raise(self):
  266. context = IndexError
  267. try:
  268. try:
  269. raise context
  270. except:
  271. raise OSError
  272. except OSError as e:
  273. self.assertIsNot(e.__context__, context)
  274. self.assertIsInstance(e.__context__, context)
  275. else:
  276. self.fail("No exception raised")
  277. def test_c_exception_context(self):
  278. try:
  279. try:
  280. 1/0
  281. except:
  282. raise OSError
  283. except OSError as e:
  284. self.assertIsInstance(e.__context__, ZeroDivisionError)
  285. else:
  286. self.fail("No exception raised")
  287. def test_c_exception_raise(self):
  288. try:
  289. try:
  290. 1/0
  291. except:
  292. xyzzy
  293. except NameError as e:
  294. self.assertIsInstance(e.__context__, ZeroDivisionError)
  295. else:
  296. self.fail("No exception raised")
  297. def test_noraise_finally(self):
  298. try:
  299. try:
  300. pass
  301. finally:
  302. raise OSError
  303. except OSError as e:
  304. self.assertIsNone(e.__context__)
  305. else:
  306. self.fail("No exception raised")
  307. def test_raise_finally(self):
  308. try:
  309. try:
  310. 1/0
  311. finally:
  312. raise OSError
  313. except OSError as e:
  314. self.assertIsInstance(e.__context__, ZeroDivisionError)
  315. else:
  316. self.fail("No exception raised")
  317. def test_context_manager(self):
  318. class ContextManager:
  319. def __enter__(self):
  320. pass
  321. def __exit__(self, t, v, tb):
  322. xyzzy
  323. try:
  324. with ContextManager():
  325. 1/0
  326. except NameError as e:
  327. self.assertIsInstance(e.__context__, ZeroDivisionError)
  328. else:
  329. self.fail("No exception raised")
  330. def test_cycle_broken(self):
  331. # Self-cycles (when re-raising a caught exception) are broken
  332. try:
  333. try:
  334. 1/0
  335. except ZeroDivisionError as e:
  336. raise e
  337. except ZeroDivisionError as e:
  338. self.assertIsNone(e.__context__)
  339. def test_reraise_cycle_broken(self):
  340. # Non-trivial context cycles (through re-raising a previous exception)
  341. # are broken too.
  342. try:
  343. try:
  344. xyzzy
  345. except NameError as a:
  346. try:
  347. 1/0
  348. except ZeroDivisionError:
  349. raise a
  350. except NameError as e:
  351. self.assertIsNone(e.__context__.__context__)
  352. def test_not_last(self):
  353. # Context is not necessarily the last exception
  354. context = Exception("context")
  355. try:
  356. raise context
  357. except Exception:
  358. try:
  359. raise Exception("caught")
  360. except Exception:
  361. pass
  362. try:
  363. raise Exception("new")
  364. except Exception as exc:
  365. raised = exc
  366. self.assertIs(raised.__context__, context)
  367. def test_3118(self):
  368. # deleting the generator caused the __context__ to be cleared
  369. def gen():
  370. try:
  371. yield 1
  372. finally:
  373. pass
  374. def f():
  375. g = gen()
  376. next(g)
  377. try:
  378. try:
  379. raise ValueError
  380. except:
  381. del g
  382. raise KeyError
  383. except Exception as e:
  384. self.assertIsInstance(e.__context__, ValueError)
  385. f()
  386. def test_3611(self):
  387. import gc
  388. # A re-raised exception in a __del__ caused the __context__
  389. # to be cleared
  390. class C:
  391. def __del__(self):
  392. try:
  393. 1/0
  394. except:
  395. raise
  396. def f():
  397. x = C()
  398. try:
  399. try:
  400. f.x
  401. except AttributeError:
  402. # make x.__del__ trigger
  403. del x
  404. gc.collect() # For PyPy or other GCs.
  405. raise TypeError
  406. except Exception as e:
  407. self.assertNotEqual(e.__context__, None)
  408. self.assertIsInstance(e.__context__, AttributeError)
  409. with support.catch_unraisable_exception() as cm:
  410. f()
  411. self.assertEqual(ZeroDivisionError, cm.unraisable.exc_type)
  412. class TestRemovedFunctionality(unittest.TestCase):
  413. def test_tuples(self):
  414. try:
  415. raise (IndexError, KeyError) # This should be a tuple!
  416. except TypeError:
  417. pass
  418. else:
  419. self.fail("No exception raised")
  420. def test_strings(self):
  421. try:
  422. raise "foo"
  423. except TypeError:
  424. pass
  425. else:
  426. self.fail("No exception raised")
  427. if __name__ == "__main__":
  428. unittest.main()