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