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