blob: 8ae92105d10ddc24bafa1d25801a612ee3918d40 [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 Coghlanab7bf212012-02-26 17:49:52 +10006from test import support, script_helper
7import re
Collin Winter828f04a2007-08-31 00:04:24 +00008import sys
9import types
10import unittest
11
12
Nick Coghlanab7bf212012-02-26 17:49:52 +100013try:
14 from resource import setrlimit, RLIMIT_CORE, error as resource_error
15except ImportError:
16 prepare_subprocess = None
17else:
18 def prepare_subprocess():
19 # don't create core file
20 try:
21 setrlimit(RLIMIT_CORE, (0, 0))
22 except (ValueError, resource_error):
23 pass
24
25
26
Collin Winter828f04a2007-08-31 00:04:24 +000027def get_tb():
28 try:
29 raise OSError()
30 except:
31 return sys.exc_info()[2]
32
33
Benjamin Petersoneec3d712008-06-11 15:59:43 +000034class Context:
35 def __enter__(self):
36 return self
37 def __exit__(self, exc_type, exc_value, exc_tb):
38 return True
39
40
Collin Winter828f04a2007-08-31 00:04:24 +000041class TestRaise(unittest.TestCase):
42 def test_invalid_reraise(self):
43 try:
44 raise
45 except RuntimeError as e:
Benjamin Peterson577473f2010-01-19 00:09:57 +000046 self.assertIn("No active exception", str(e))
Collin Winter828f04a2007-08-31 00:04:24 +000047 else:
48 self.fail("No exception raised")
49
50 def test_reraise(self):
51 try:
52 try:
53 raise IndexError()
54 except IndexError as e:
55 exc1 = e
56 raise
57 except IndexError as exc2:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000058 self.assertTrue(exc1 is exc2)
Collin Winter828f04a2007-08-31 00:04:24 +000059 else:
60 self.fail("No exception raised")
61
Benjamin Petersoneec3d712008-06-11 15:59:43 +000062 def test_except_reraise(self):
63 def reraise():
64 try:
65 raise TypeError("foo")
66 except:
67 try:
68 raise KeyError("caught")
69 except KeyError:
70 pass
71 raise
72 self.assertRaises(TypeError, reraise)
73
74 def test_finally_reraise(self):
75 def reraise():
76 try:
77 raise TypeError("foo")
78 except:
79 try:
80 raise KeyError("caught")
81 finally:
82 raise
83 self.assertRaises(KeyError, reraise)
84
85 def test_nested_reraise(self):
86 def nested_reraise():
87 raise
88 def reraise():
89 try:
90 raise TypeError("foo")
91 except:
92 nested_reraise()
93 self.assertRaises(TypeError, reraise)
94
Nick Coghlanab7bf212012-02-26 17:49:52 +100095 def test_raise_from_None(self):
96 try:
97 try:
98 raise TypeError("foo")
99 except:
100 raise ValueError() from None
101 except ValueError as e:
102 self.assertTrue(isinstance(e.__context__, TypeError))
103 self.assertIsNone(e.__cause__)
104
Benjamin Petersoneec3d712008-06-11 15:59:43 +0000105 def test_with_reraise1(self):
106 def reraise():
107 try:
108 raise TypeError("foo")
109 except:
110 with Context():
111 pass
112 raise
113 self.assertRaises(TypeError, reraise)
114
115 def test_with_reraise2(self):
116 def reraise():
117 try:
118 raise TypeError("foo")
119 except:
120 with Context():
121 raise KeyError("caught")
122 raise
123 self.assertRaises(TypeError, reraise)
124
125 def test_yield_reraise(self):
126 def reraise():
127 try:
128 raise TypeError("foo")
129 except:
130 yield 1
131 raise
132 g = reraise()
133 next(g)
134 self.assertRaises(TypeError, lambda: next(g))
135 self.assertRaises(StopIteration, lambda: next(g))
136
Collin Winter1966f1c2007-09-01 20:26:44 +0000137 def test_erroneous_exception(self):
138 class MyException(Exception):
139 def __init__(self):
140 raise RuntimeError()
141
142 try:
143 raise MyException
144 except RuntimeError:
145 pass
146 else:
147 self.fail("No exception raised")
148
Benjamin Peterson5afa03a2011-07-15 14:09:26 -0500149 def test_new_returns_invalid_instance(self):
150 # See issue #11627.
151 class MyException(Exception):
152 def __new__(cls, *args):
153 return object()
154
155 with self.assertRaises(TypeError):
156 raise MyException
157
Benjamin Peterson2f8dfcd2011-10-27 08:20:01 -0400158 def test_assert_with_tuple_arg(self):
159 try:
160 assert False, (3,)
161 except AssertionError as e:
162 self.assertEqual(str(e), "(3,)")
163
164
Collin Winter828f04a2007-08-31 00:04:24 +0000165
166class TestCause(unittest.TestCase):
Nick Coghlanab7bf212012-02-26 17:49:52 +1000167
168 def testCauseSyntax(self):
169 try:
170 try:
171 try:
172 raise TypeError
173 except Exception:
174 raise ValueError from None
175 except ValueError as exc:
176 self.assertIsNone(exc.__cause__)
177 raise exc from Ellipsis
178 except ValueError as exc:
179 e = exc
180
181 self.assertIs(e.__cause__, Ellipsis)
182 self.assertIsInstance(e.__context__, TypeError)
183
Collin Winter828f04a2007-08-31 00:04:24 +0000184 def test_invalid_cause(self):
185 try:
186 raise IndexError from 5
187 except TypeError as e:
Benjamin Peterson577473f2010-01-19 00:09:57 +0000188 self.assertIn("exception cause", str(e))
Collin Winter828f04a2007-08-31 00:04:24 +0000189 else:
190 self.fail("No exception raised")
191
192 def test_class_cause(self):
193 try:
194 raise IndexError from KeyError
195 except IndexError as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000196 self.assertIsInstance(e.__cause__, KeyError)
Collin Winter828f04a2007-08-31 00:04:24 +0000197 else:
198 self.fail("No exception raised")
199
200 def test_instance_cause(self):
201 cause = KeyError()
202 try:
203 raise IndexError from cause
204 except IndexError as e:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000205 self.assertTrue(e.__cause__ is cause)
Collin Winter828f04a2007-08-31 00:04:24 +0000206 else:
207 self.fail("No exception raised")
208
Collin Winter1966f1c2007-09-01 20:26:44 +0000209 def test_erroneous_cause(self):
210 class MyException(Exception):
211 def __init__(self):
212 raise RuntimeError()
213
214 try:
215 raise IndexError from MyException
216 except RuntimeError:
217 pass
218 else:
219 self.fail("No exception raised")
220
Collin Winter828f04a2007-08-31 00:04:24 +0000221
222class TestTraceback(unittest.TestCase):
Nick Coghlanab7bf212012-02-26 17:49:52 +1000223
224 def get_output(self, code, filename=None):
225 """
226 Run the specified code in Python (in a new child process) and read the
227 output from the standard error or from a file (if filename is set).
228 Return the output lines as a list.
229 """
230 options = {}
231 if prepare_subprocess:
232 options['preexec_fn'] = prepare_subprocess
233 process = script_helper.spawn_python('-c', code, **options)
234 stdout, stderr = process.communicate()
235 exitcode = process.wait()
236 output = support.strip_python_stderr(stdout)
237 output = output.decode('ascii', 'backslashreplace')
238 if filename:
239 self.assertEqual(output, '')
240 with open(filename, "rb") as fp:
241 output = fp.read()
242 output = output.decode('ascii', 'backslashreplace')
243 output = re.sub('Current thread 0x[0-9a-f]+',
244 'Current thread XXX',
245 output)
246 return output.splitlines(), exitcode
247
248 def test_traceback_verbiage(self):
249 code = """
250try:
251 raise ValueError
252except:
253 raise NameError from None
254"""
255 text, exitcode = self.get_output(code)
256 self.assertEqual(len(text), 3)
257 self.assertTrue(text[0].startswith('Traceback'))
258 self.assertTrue(text[1].startswith(' File '))
259 self.assertTrue(text[2].startswith('NameError'))
260
Collin Winter828f04a2007-08-31 00:04:24 +0000261 def test_sets_traceback(self):
262 try:
263 raise IndexError()
264 except IndexError as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000265 self.assertIsInstance(e.__traceback__, types.TracebackType)
Collin Winter828f04a2007-08-31 00:04:24 +0000266 else:
267 self.fail("No exception raised")
268
269 def test_accepts_traceback(self):
270 tb = get_tb()
271 try:
272 raise IndexError().with_traceback(tb)
273 except IndexError as e:
274 self.assertNotEqual(e.__traceback__, tb)
275 self.assertEqual(e.__traceback__.tb_next, tb)
276 else:
277 self.fail("No exception raised")
278
279
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000280class TestContext(unittest.TestCase):
281 def test_instance_context_instance_raise(self):
282 context = IndexError()
283 try:
284 try:
285 raise context
286 except:
287 raise OSError()
288 except OSError as e:
289 self.assertEqual(e.__context__, context)
290 else:
291 self.fail("No exception raised")
292
293 def test_class_context_instance_raise(self):
294 context = IndexError
295 try:
296 try:
297 raise context
298 except:
299 raise OSError()
300 except OSError as e:
301 self.assertNotEqual(e.__context__, context)
Ezio Melottie9615932010-01-24 19:26:24 +0000302 self.assertIsInstance(e.__context__, context)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000303 else:
304 self.fail("No exception raised")
305
306 def test_class_context_class_raise(self):
307 context = IndexError
308 try:
309 try:
310 raise context
311 except:
312 raise OSError
313 except OSError as e:
314 self.assertNotEqual(e.__context__, context)
Ezio Melottie9615932010-01-24 19:26:24 +0000315 self.assertIsInstance(e.__context__, context)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000316 else:
317 self.fail("No exception raised")
318
319 def test_c_exception_context(self):
320 try:
321 try:
322 1/0
323 except:
324 raise OSError
325 except OSError as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000326 self.assertIsInstance(e.__context__, ZeroDivisionError)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000327 else:
328 self.fail("No exception raised")
329
330 def test_c_exception_raise(self):
331 try:
332 try:
333 1/0
334 except:
335 xyzzy
336 except NameError as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000337 self.assertIsInstance(e.__context__, ZeroDivisionError)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000338 else:
339 self.fail("No exception raised")
340
341 def test_noraise_finally(self):
342 try:
343 try:
344 pass
345 finally:
346 raise OSError
347 except OSError as e:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000348 self.assertTrue(e.__context__ is None)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000349 else:
350 self.fail("No exception raised")
351
352 def test_raise_finally(self):
353 try:
354 try:
355 1/0
356 finally:
357 raise OSError
358 except OSError as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000359 self.assertIsInstance(e.__context__, ZeroDivisionError)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000360 else:
361 self.fail("No exception raised")
362
363 def test_context_manager(self):
364 class ContextManager:
365 def __enter__(self):
366 pass
367 def __exit__(self, t, v, tb):
368 xyzzy
369 try:
370 with ContextManager():
371 1/0
372 except NameError as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000373 self.assertIsInstance(e.__context__, ZeroDivisionError)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000374 else:
375 self.fail("No exception raised")
Collin Winter828f04a2007-08-31 00:04:24 +0000376
Benjamin Petersone6528212008-07-15 15:32:09 +0000377 def test_cycle_broken(self):
378 # Self-cycles (when re-raising a caught exception) are broken
379 try:
380 try:
381 1/0
382 except ZeroDivisionError as e:
383 raise e
384 except ZeroDivisionError as e:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000385 self.assertTrue(e.__context__ is None, e.__context__)
Benjamin Petersone6528212008-07-15 15:32:09 +0000386
387 def test_reraise_cycle_broken(self):
388 # Non-trivial context cycles (through re-raising a previous exception)
389 # are broken too.
390 try:
391 try:
392 xyzzy
393 except NameError as a:
394 try:
395 1/0
396 except ZeroDivisionError:
397 raise a
398 except NameError as e:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000399 self.assertTrue(e.__context__.__context__ is None)
Benjamin Petersone6528212008-07-15 15:32:09 +0000400
Benjamin Peterson9b676022008-08-21 17:00:40 +0000401 def test_3118(self):
402 # deleting the generator caused the __context__ to be cleared
403 def gen():
404 try:
405 yield 1
406 finally:
407 pass
408
409 def f():
410 g = gen()
411 next(g)
412 try:
413 try:
414 raise ValueError
415 except:
416 del g
417 raise KeyError
418 except Exception as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000419 self.assertIsInstance(e.__context__, ValueError)
Benjamin Peterson9b676022008-08-21 17:00:40 +0000420
421 f()
422
Amaury Forgeot d'Arcdb26f7c2008-08-29 07:13:32 +0000423 def test_3611(self):
424 # A re-raised exception in a __del__ caused the __context__
425 # to be cleared
426 class C:
427 def __del__(self):
428 try:
429 1/0
430 except:
431 raise
432
433 def f():
434 x = C()
435 try:
436 try:
437 x.x
438 except AttributeError:
439 del x
440 raise TypeError
441 except Exception as e:
442 self.assertNotEqual(e.__context__, None)
Ezio Melottie9615932010-01-24 19:26:24 +0000443 self.assertIsInstance(e.__context__, AttributeError)
Amaury Forgeot d'Arcdb26f7c2008-08-29 07:13:32 +0000444
445 with support.captured_output("stderr"):
446 f()
Collin Winter828f04a2007-08-31 00:04:24 +0000447
448class TestRemovedFunctionality(unittest.TestCase):
449 def test_tuples(self):
450 try:
451 raise (IndexError, KeyError) # This should be a tuple!
452 except TypeError:
453 pass
454 else:
455 self.fail("No exception raised")
456
457 def test_strings(self):
458 try:
459 raise "foo"
460 except TypeError:
461 pass
462 else:
463 self.fail("No exception raised")
464
465
466def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000467 support.run_unittest(__name__)
Collin Winter828f04a2007-08-31 00:04:24 +0000468
Collin Winter828f04a2007-08-31 00:04:24 +0000469if __name__ == "__main__":
470 unittest.main()