blob: b169867e1f1b95aa20392c0f7244418245358a8d [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__)
Benjamin Petersond5a1c442012-05-14 22:09:31 -0700177 self.assertTrue(exc.__suppress_context__)
178 exc.__suppress_context__ = False
179 raise exc
Nick Coghlanab7bf212012-02-26 17:49:52 +1000180 except ValueError as exc:
181 e = exc
182
Benjamin Petersond5a1c442012-05-14 22:09:31 -0700183 self.assertIsNone(e.__cause__)
184 self.assertFalse(e.__suppress_context__)
Nick Coghlanab7bf212012-02-26 17:49:52 +1000185 self.assertIsInstance(e.__context__, TypeError)
186
Collin Winter828f04a2007-08-31 00:04:24 +0000187 def test_invalid_cause(self):
188 try:
189 raise IndexError from 5
190 except TypeError as e:
Benjamin Peterson577473f2010-01-19 00:09:57 +0000191 self.assertIn("exception cause", str(e))
Collin Winter828f04a2007-08-31 00:04:24 +0000192 else:
193 self.fail("No exception raised")
194
195 def test_class_cause(self):
196 try:
197 raise IndexError from KeyError
198 except IndexError as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000199 self.assertIsInstance(e.__cause__, KeyError)
Collin Winter828f04a2007-08-31 00:04:24 +0000200 else:
201 self.fail("No exception raised")
202
203 def test_instance_cause(self):
204 cause = KeyError()
205 try:
206 raise IndexError from cause
207 except IndexError as e:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000208 self.assertTrue(e.__cause__ is cause)
Collin Winter828f04a2007-08-31 00:04:24 +0000209 else:
210 self.fail("No exception raised")
211
Collin Winter1966f1c2007-09-01 20:26:44 +0000212 def test_erroneous_cause(self):
213 class MyException(Exception):
214 def __init__(self):
215 raise RuntimeError()
216
217 try:
218 raise IndexError from MyException
219 except RuntimeError:
220 pass
221 else:
222 self.fail("No exception raised")
223
Collin Winter828f04a2007-08-31 00:04:24 +0000224
225class TestTraceback(unittest.TestCase):
Nick Coghlanab7bf212012-02-26 17:49:52 +1000226
227 def get_output(self, code, filename=None):
228 """
229 Run the specified code in Python (in a new child process) and read the
230 output from the standard error or from a file (if filename is set).
231 Return the output lines as a list.
232 """
233 options = {}
234 if prepare_subprocess:
235 options['preexec_fn'] = prepare_subprocess
236 process = script_helper.spawn_python('-c', code, **options)
237 stdout, stderr = process.communicate()
238 exitcode = process.wait()
239 output = support.strip_python_stderr(stdout)
240 output = output.decode('ascii', 'backslashreplace')
241 if filename:
242 self.assertEqual(output, '')
243 with open(filename, "rb") as fp:
244 output = fp.read()
245 output = output.decode('ascii', 'backslashreplace')
246 output = re.sub('Current thread 0x[0-9a-f]+',
247 'Current thread XXX',
248 output)
249 return output.splitlines(), exitcode
250
251 def test_traceback_verbiage(self):
252 code = """
253try:
254 raise ValueError
255except:
256 raise NameError from None
257"""
258 text, exitcode = self.get_output(code)
259 self.assertEqual(len(text), 3)
260 self.assertTrue(text[0].startswith('Traceback'))
261 self.assertTrue(text[1].startswith(' File '))
262 self.assertTrue(text[2].startswith('NameError'))
263
Collin Winter828f04a2007-08-31 00:04:24 +0000264 def test_sets_traceback(self):
265 try:
266 raise IndexError()
267 except IndexError as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000268 self.assertIsInstance(e.__traceback__, types.TracebackType)
Collin Winter828f04a2007-08-31 00:04:24 +0000269 else:
270 self.fail("No exception raised")
271
272 def test_accepts_traceback(self):
273 tb = get_tb()
274 try:
275 raise IndexError().with_traceback(tb)
276 except IndexError as e:
277 self.assertNotEqual(e.__traceback__, tb)
278 self.assertEqual(e.__traceback__.tb_next, tb)
279 else:
280 self.fail("No exception raised")
281
282
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000283class TestContext(unittest.TestCase):
284 def test_instance_context_instance_raise(self):
285 context = IndexError()
286 try:
287 try:
288 raise context
289 except:
290 raise OSError()
291 except OSError as e:
292 self.assertEqual(e.__context__, context)
293 else:
294 self.fail("No exception raised")
295
296 def test_class_context_instance_raise(self):
297 context = IndexError
298 try:
299 try:
300 raise context
301 except:
302 raise OSError()
303 except OSError as e:
304 self.assertNotEqual(e.__context__, context)
Ezio Melottie9615932010-01-24 19:26:24 +0000305 self.assertIsInstance(e.__context__, context)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000306 else:
307 self.fail("No exception raised")
308
309 def test_class_context_class_raise(self):
310 context = IndexError
311 try:
312 try:
313 raise context
314 except:
315 raise OSError
316 except OSError as e:
317 self.assertNotEqual(e.__context__, context)
Ezio Melottie9615932010-01-24 19:26:24 +0000318 self.assertIsInstance(e.__context__, context)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000319 else:
320 self.fail("No exception raised")
321
322 def test_c_exception_context(self):
323 try:
324 try:
325 1/0
326 except:
327 raise OSError
328 except OSError as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000329 self.assertIsInstance(e.__context__, ZeroDivisionError)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000330 else:
331 self.fail("No exception raised")
332
333 def test_c_exception_raise(self):
334 try:
335 try:
336 1/0
337 except:
338 xyzzy
339 except NameError as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000340 self.assertIsInstance(e.__context__, ZeroDivisionError)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000341 else:
342 self.fail("No exception raised")
343
344 def test_noraise_finally(self):
345 try:
346 try:
347 pass
348 finally:
349 raise OSError
350 except OSError as e:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000351 self.assertTrue(e.__context__ is None)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000352 else:
353 self.fail("No exception raised")
354
355 def test_raise_finally(self):
356 try:
357 try:
358 1/0
359 finally:
360 raise OSError
361 except OSError as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000362 self.assertIsInstance(e.__context__, ZeroDivisionError)
Guido van Rossumb4fb6e42008-06-14 20:20:24 +0000363 else:
364 self.fail("No exception raised")
365
366 def test_context_manager(self):
367 class ContextManager:
368 def __enter__(self):
369 pass
370 def __exit__(self, t, v, tb):
371 xyzzy
372 try:
373 with ContextManager():
374 1/0
375 except NameError 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")
Collin Winter828f04a2007-08-31 00:04:24 +0000379
Benjamin Petersone6528212008-07-15 15:32:09 +0000380 def test_cycle_broken(self):
381 # Self-cycles (when re-raising a caught exception) are broken
382 try:
383 try:
384 1/0
385 except ZeroDivisionError as e:
386 raise e
387 except ZeroDivisionError as e:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000388 self.assertTrue(e.__context__ is None, e.__context__)
Benjamin Petersone6528212008-07-15 15:32:09 +0000389
390 def test_reraise_cycle_broken(self):
391 # Non-trivial context cycles (through re-raising a previous exception)
392 # are broken too.
393 try:
394 try:
395 xyzzy
396 except NameError as a:
397 try:
398 1/0
399 except ZeroDivisionError:
400 raise a
401 except NameError as e:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000402 self.assertTrue(e.__context__.__context__ is None)
Benjamin Petersone6528212008-07-15 15:32:09 +0000403
Benjamin Peterson9b676022008-08-21 17:00:40 +0000404 def test_3118(self):
405 # deleting the generator caused the __context__ to be cleared
406 def gen():
407 try:
408 yield 1
409 finally:
410 pass
411
412 def f():
413 g = gen()
414 next(g)
415 try:
416 try:
417 raise ValueError
418 except:
419 del g
420 raise KeyError
421 except Exception as e:
Ezio Melottie9615932010-01-24 19:26:24 +0000422 self.assertIsInstance(e.__context__, ValueError)
Benjamin Peterson9b676022008-08-21 17:00:40 +0000423
424 f()
425
Amaury Forgeot d'Arcdb26f7c2008-08-29 07:13:32 +0000426 def test_3611(self):
427 # A re-raised exception in a __del__ caused the __context__
428 # to be cleared
429 class C:
430 def __del__(self):
431 try:
432 1/0
433 except:
434 raise
435
436 def f():
437 x = C()
438 try:
439 try:
440 x.x
441 except AttributeError:
442 del x
443 raise TypeError
444 except Exception as e:
445 self.assertNotEqual(e.__context__, None)
Ezio Melottie9615932010-01-24 19:26:24 +0000446 self.assertIsInstance(e.__context__, AttributeError)
Amaury Forgeot d'Arcdb26f7c2008-08-29 07:13:32 +0000447
448 with support.captured_output("stderr"):
449 f()
Collin Winter828f04a2007-08-31 00:04:24 +0000450
451class TestRemovedFunctionality(unittest.TestCase):
452 def test_tuples(self):
453 try:
454 raise (IndexError, KeyError) # This should be a tuple!
455 except TypeError:
456 pass
457 else:
458 self.fail("No exception raised")
459
460 def test_strings(self):
461 try:
462 raise "foo"
463 except TypeError:
464 pass
465 else:
466 self.fail("No exception raised")
467
468
469def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000470 support.run_unittest(__name__)
Collin Winter828f04a2007-08-31 00:04:24 +0000471
Collin Winter828f04a2007-08-31 00:04:24 +0000472if __name__ == "__main__":
473 unittest.main()