blob: c1ef154a9a9f0330a2fc7d30ad8dce380e98aa38 [file] [log] [blame]
Collin Winter828f04a2007-08-31 00:04:24 +00001# Copyright 2007 Google, Inc. All Rights Reserved.
2# Licensed to PSF under a Contributor Agreement.
3
4"""Tests for the raise statement."""
5
Nick Coghlan1d5ccdb2012-05-21 23:03:30 +10006from test import support
Collin Winter828f04a2007-08-31 00:04:24 +00007import sys
8import types
9import unittest
10
11
12def get_tb():
13 try:
14 raise OSError()
15 except:
16 return sys.exc_info()[2]
17
18
Benjamin Petersoneec3d712008-06-11 15:59:43 +000019class Context:
20 def __enter__(self):
21 return self
22 def __exit__(self, exc_type, exc_value, exc_tb):
23 return True
24
25
Collin Winter828f04a2007-08-31 00:04:24 +000026class TestRaise(unittest.TestCase):
27 def test_invalid_reraise(self):
28 try:
29 raise
30 except RuntimeError as e:
Benjamin Peterson577473f2010-01-19 00:09:57 +000031 self.assertIn("No active exception", str(e))
Collin Winter828f04a2007-08-31 00:04:24 +000032 else:
33 self.fail("No exception raised")
34
35 def test_reraise(self):
36 try:
37 try:
38 raise IndexError()
39 except IndexError as e:
40 exc1 = e
41 raise
42 except IndexError as exc2:
Serhiy Storchakaf15c4d32017-03-30 18:05:08 +030043 self.assertIs(exc1, exc2)
Collin Winter828f04a2007-08-31 00:04:24 +000044 else:
45 self.fail("No exception raised")
46
Benjamin Petersoneec3d712008-06-11 15:59:43 +000047 def test_except_reraise(self):
48 def reraise():
49 try:
50 raise TypeError("foo")
51 except:
52 try:
53 raise KeyError("caught")
54 except KeyError:
55 pass
56 raise
57 self.assertRaises(TypeError, reraise)
58
59 def test_finally_reraise(self):
60 def reraise():
61 try:
62 raise TypeError("foo")
63 except:
64 try:
65 raise KeyError("caught")
66 finally:
67 raise
68 self.assertRaises(KeyError, reraise)
69
70 def test_nested_reraise(self):
71 def nested_reraise():
72 raise
73 def reraise():
74 try:
75 raise TypeError("foo")
76 except:
77 nested_reraise()
78 self.assertRaises(TypeError, reraise)
79
Nick Coghlanab7bf212012-02-26 17:49:52 +100080 def test_raise_from_None(self):
81 try:
82 try:
83 raise TypeError("foo")
84 except:
85 raise ValueError() from None
86 except ValueError as e:
Serhiy Storchakaf15c4d32017-03-30 18:05:08 +030087 self.assertIsInstance(e.__context__, TypeError)
Nick Coghlanab7bf212012-02-26 17:49:52 +100088 self.assertIsNone(e.__cause__)
89
Benjamin Petersoneec3d712008-06-11 15:59:43 +000090 def test_with_reraise1(self):
91 def reraise():
92 try:
93 raise TypeError("foo")
94 except:
95 with Context():
96 pass
97 raise
98 self.assertRaises(TypeError, reraise)
99
100 def test_with_reraise2(self):
101 def reraise():
102 try:
103 raise TypeError("foo")
104 except:
105 with Context():
106 raise KeyError("caught")
107 raise
108 self.assertRaises(TypeError, reraise)
109
110 def test_yield_reraise(self):
111 def reraise():
112 try:
113 raise TypeError("foo")
114 except:
115 yield 1
116 raise
117 g = reraise()
118 next(g)
119 self.assertRaises(TypeError, lambda: next(g))
120 self.assertRaises(StopIteration, lambda: next(g))
121
Collin Winter1966f1c2007-09-01 20:26:44 +0000122 def test_erroneous_exception(self):
123 class MyException(Exception):
124 def __init__(self):
125 raise RuntimeError()
126
127 try:
128 raise MyException
129 except RuntimeError:
130 pass
131 else:
132 self.fail("No exception raised")
133
Benjamin Peterson5afa03a2011-07-15 14:09:26 -0500134 def test_new_returns_invalid_instance(self):
135 # See issue #11627.
136 class MyException(Exception):
137 def __new__(cls, *args):
138 return object()
139
140 with self.assertRaises(TypeError):
141 raise MyException
142
Benjamin Peterson2f8dfcd2011-10-27 08:20:01 -0400143 def test_assert_with_tuple_arg(self):
144 try:
145 assert False, (3,)
146 except AssertionError as e:
147 self.assertEqual(str(e), "(3,)")
148
149
Collin Winter828f04a2007-08-31 00:04:24 +0000150
151class TestCause(unittest.TestCase):
Nick Coghlanab7bf212012-02-26 17:49:52 +1000152
153 def testCauseSyntax(self):
154 try:
155 try:
156 try:
157 raise TypeError
158 except Exception:
159 raise ValueError from None
160 except ValueError as exc:
161 self.assertIsNone(exc.__cause__)
Benjamin Petersond5a1c442012-05-14 22:09:31 -0700162 self.assertTrue(exc.__suppress_context__)
163 exc.__suppress_context__ = False
164 raise exc
Nick Coghlanab7bf212012-02-26 17:49:52 +1000165 except ValueError as exc:
166 e = exc
167
Benjamin Petersond5a1c442012-05-14 22:09:31 -0700168 self.assertIsNone(e.__cause__)
169 self.assertFalse(e.__suppress_context__)
Nick Coghlanab7bf212012-02-26 17:49:52 +1000170 self.assertIsInstance(e.__context__, TypeError)
171
Collin Winter828f04a2007-08-31 00:04:24 +0000172 def test_invalid_cause(self):
173 try:
174 raise IndexError from 5
175 except TypeError as e:
Benjamin Peterson577473f2010-01-19 00:09:57 +0000176 self.assertIn("exception cause", str(e))
Collin Winter828f04a2007-08-31 00:04:24 +0000177 else:
178 self.fail("No exception raised")
179
180 def test_class_cause(self):
181 try:
182 raise IndexError from KeyError
183 except IndexError as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000184 self.assertIsInstance(e.__cause__, KeyError)
Collin Winter828f04a2007-08-31 00:04:24 +0000185 else:
186 self.fail("No exception raised")
187
188 def test_instance_cause(self):
189 cause = KeyError()
190 try:
191 raise IndexError from cause
192 except IndexError as e:
Serhiy Storchakaf15c4d32017-03-30 18:05:08 +0300193 self.assertIs(e.__cause__, cause)
Collin Winter828f04a2007-08-31 00:04:24 +0000194 else:
195 self.fail("No exception raised")
196
Collin Winter1966f1c2007-09-01 20:26:44 +0000197 def test_erroneous_cause(self):
198 class MyException(Exception):
199 def __init__(self):
200 raise RuntimeError()
201
202 try:
203 raise IndexError from MyException
204 except RuntimeError:
205 pass
206 else:
207 self.fail("No exception raised")
208
Collin Winter828f04a2007-08-31 00:04:24 +0000209
210class TestTraceback(unittest.TestCase):
Nick Coghlanab7bf212012-02-26 17:49:52 +1000211
Collin Winter828f04a2007-08-31 00:04:24 +0000212 def test_sets_traceback(self):
213 try:
214 raise IndexError()
215 except IndexError as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000216 self.assertIsInstance(e.__traceback__, types.TracebackType)
Collin Winter828f04a2007-08-31 00:04:24 +0000217 else:
218 self.fail("No exception raised")
219
220 def test_accepts_traceback(self):
221 tb = get_tb()
222 try:
223 raise IndexError().with_traceback(tb)
224 except IndexError as e:
225 self.assertNotEqual(e.__traceback__, tb)
226 self.assertEqual(e.__traceback__.tb_next, tb)
227 else:
228 self.fail("No exception raised")
229
230
Nathaniel J. Smithe46a8af2018-01-07 05:30:18 -0800231class TestTracebackType(unittest.TestCase):
232
233 def raiser(self):
234 raise ValueError
235
236 def test_attrs(self):
237 try:
238 self.raiser()
239 except Exception as exc:
240 tb = exc.__traceback__
241
242 self.assertIsInstance(tb.tb_next, types.TracebackType)
243 self.assertIs(tb.tb_frame, sys._getframe())
244 self.assertIsInstance(tb.tb_lasti, int)
245 self.assertIsInstance(tb.tb_lineno, int)
246
247 self.assertIs(tb.tb_next.tb_next, None)
248
249 # Invalid assignments
250 with self.assertRaises(TypeError):
251 del tb.tb_next
252
253 with self.assertRaises(TypeError):
254 tb.tb_next = "asdf"
255
256 # Loops
257 with self.assertRaises(ValueError):
258 tb.tb_next = tb
259
260 with self.assertRaises(ValueError):
261 tb.tb_next.tb_next = tb
262
263 # Valid assignments
264 tb.tb_next = None
265 self.assertIs(tb.tb_next, None)
266
267 new_tb = get_tb()
268 tb.tb_next = new_tb
269 self.assertIs(tb.tb_next, new_tb)
270
271 def test_constructor(self):
272 other_tb = get_tb()
273 frame = sys._getframe()
274
275 tb = types.TracebackType(other_tb, frame, 1, 2)
276 self.assertEqual(tb.tb_next, other_tb)
277 self.assertEqual(tb.tb_frame, frame)
278 self.assertEqual(tb.tb_lasti, 1)
279 self.assertEqual(tb.tb_lineno, 2)
280
281 tb = types.TracebackType(None, frame, 1, 2)
282 self.assertEqual(tb.tb_next, None)
283
284 with self.assertRaises(TypeError):
285 types.TracebackType("no", frame, 1, 2)
286
287 with self.assertRaises(TypeError):
288 types.TracebackType(other_tb, "no", 1, 2)
289
290 with self.assertRaises(TypeError):
291 types.TracebackType(other_tb, frame, "no", 2)
292
293 with self.assertRaises(TypeError):
294 types.TracebackType(other_tb, frame, 1, "nuh-uh")
295
296
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000297class TestContext(unittest.TestCase):
298 def test_instance_context_instance_raise(self):
299 context = IndexError()
300 try:
301 try:
302 raise context
303 except:
304 raise OSError()
305 except OSError as e:
306 self.assertEqual(e.__context__, context)
307 else:
308 self.fail("No exception raised")
309
310 def test_class_context_instance_raise(self):
311 context = IndexError
312 try:
313 try:
314 raise context
315 except:
316 raise OSError()
317 except OSError as e:
318 self.assertNotEqual(e.__context__, context)
Ezio Melottie9615932010-01-24 19:26:24 +0000319 self.assertIsInstance(e.__context__, context)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000320 else:
321 self.fail("No exception raised")
322
323 def test_class_context_class_raise(self):
324 context = IndexError
325 try:
326 try:
327 raise context
328 except:
329 raise OSError
330 except OSError as e:
331 self.assertNotEqual(e.__context__, context)
Ezio Melottie9615932010-01-24 19:26:24 +0000332 self.assertIsInstance(e.__context__, context)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000333 else:
334 self.fail("No exception raised")
335
336 def test_c_exception_context(self):
337 try:
338 try:
339 1/0
340 except:
341 raise OSError
342 except OSError as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000343 self.assertIsInstance(e.__context__, ZeroDivisionError)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000344 else:
345 self.fail("No exception raised")
346
347 def test_c_exception_raise(self):
348 try:
349 try:
350 1/0
351 except:
352 xyzzy
353 except NameError as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000354 self.assertIsInstance(e.__context__, ZeroDivisionError)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000355 else:
356 self.fail("No exception raised")
357
358 def test_noraise_finally(self):
359 try:
360 try:
361 pass
362 finally:
363 raise OSError
364 except OSError as e:
Serhiy Storchakaf15c4d32017-03-30 18:05:08 +0300365 self.assertIsNone(e.__context__)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000366 else:
367 self.fail("No exception raised")
368
369 def test_raise_finally(self):
370 try:
371 try:
372 1/0
373 finally:
374 raise OSError
375 except OSError as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000376 self.assertIsInstance(e.__context__, ZeroDivisionError)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000377 else:
378 self.fail("No exception raised")
379
380 def test_context_manager(self):
381 class ContextManager:
382 def __enter__(self):
383 pass
384 def __exit__(self, t, v, tb):
385 xyzzy
386 try:
387 with ContextManager():
388 1/0
389 except NameError as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000390 self.assertIsInstance(e.__context__, ZeroDivisionError)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000391 else:
392 self.fail("No exception raised")
Collin Winter828f04a2007-08-31 00:04:24 +0000393
Benjamin Petersone6528212008-07-15 15:32:09 +0000394 def test_cycle_broken(self):
395 # Self-cycles (when re-raising a caught exception) are broken
396 try:
397 try:
398 1/0
399 except ZeroDivisionError as e:
400 raise e
401 except ZeroDivisionError as e:
Serhiy Storchakaf15c4d32017-03-30 18:05:08 +0300402 self.assertIsNone(e.__context__)
Benjamin Petersone6528212008-07-15 15:32:09 +0000403
404 def test_reraise_cycle_broken(self):
405 # Non-trivial context cycles (through re-raising a previous exception)
406 # are broken too.
407 try:
408 try:
409 xyzzy
410 except NameError as a:
411 try:
412 1/0
413 except ZeroDivisionError:
414 raise a
415 except NameError as e:
Serhiy Storchakaf15c4d32017-03-30 18:05:08 +0300416 self.assertIsNone(e.__context__.__context__)
Benjamin Petersone6528212008-07-15 15:32:09 +0000417
Benjamin Peterson9b676022008-08-21 17:00:40 +0000418 def test_3118(self):
419 # deleting the generator caused the __context__ to be cleared
420 def gen():
421 try:
422 yield 1
423 finally:
424 pass
425
426 def f():
427 g = gen()
428 next(g)
429 try:
430 try:
431 raise ValueError
432 except:
433 del g
434 raise KeyError
435 except Exception as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000436 self.assertIsInstance(e.__context__, ValueError)
Benjamin Peterson9b676022008-08-21 17:00:40 +0000437
438 f()
439
Amaury Forgeot d'Arcdb26f7c2008-08-29 07:13:32 +0000440 def test_3611(self):
441 # A re-raised exception in a __del__ caused the __context__
442 # to be cleared
443 class C:
444 def __del__(self):
445 try:
446 1/0
447 except:
448 raise
449
450 def f():
451 x = C()
452 try:
453 try:
454 x.x
455 except AttributeError:
456 del x
457 raise TypeError
458 except Exception as e:
459 self.assertNotEqual(e.__context__, None)
Ezio Melottie9615932010-01-24 19:26:24 +0000460 self.assertIsInstance(e.__context__, AttributeError)
Amaury Forgeot d'Arcdb26f7c2008-08-29 07:13:32 +0000461
462 with support.captured_output("stderr"):
463 f()
Collin Winter828f04a2007-08-31 00:04:24 +0000464
465class TestRemovedFunctionality(unittest.TestCase):
466 def test_tuples(self):
467 try:
468 raise (IndexError, KeyError) # This should be a tuple!
469 except TypeError:
470 pass
471 else:
472 self.fail("No exception raised")
473
474 def test_strings(self):
475 try:
476 raise "foo"
477 except TypeError:
478 pass
479 else:
480 self.fail("No exception raised")
481
482
Collin Winter828f04a2007-08-31 00:04:24 +0000483if __name__ == "__main__":
484 unittest.main()