1# Python test set -- part 5, built-in exceptions 2 3import os 4import sys 5import unittest 6import pickle 7import weakref 8import errno 9 10from test.support import (TESTFN, captured_stderr, check_impl_detail, 11 check_warnings, cpython_only, gc_collect, run_unittest, 12 no_tracing, unlink, import_module) 13 14class NaiveException(Exception): 15 def __init__(self, x): 16 self.x = x 17 18class SlottedNaiveException(Exception): 19 __slots__ = ('x',) 20 def __init__(self, x): 21 self.x = x 22 23class BrokenStrException(Exception): 24 def __str__(self): 25 raise Exception("str() is broken") 26 27# XXX This is not really enough, each *operation* should be tested! 28 29class ExceptionTests(unittest.TestCase): 30 31 def raise_catch(self, exc, excname): 32 try: 33 raise exc("spam") 34 except exc as err: 35 buf1 = str(err) 36 try: 37 raise exc("spam") 38 except exc as err: 39 buf2 = str(err) 40 self.assertEqual(buf1, buf2) 41 self.assertEqual(exc.__name__, excname) 42 43 def testRaising(self): 44 self.raise_catch(AttributeError, "AttributeError") 45 self.assertRaises(AttributeError, getattr, sys, "undefined_attribute") 46 47 self.raise_catch(EOFError, "EOFError") 48 fp = open(TESTFN, 'w') 49 fp.close() 50 fp = open(TESTFN, 'r') 51 savestdin = sys.stdin 52 try: 53 try: 54 import marshal 55 marshal.loads(b'') 56 except EOFError: 57 pass 58 finally: 59 sys.stdin = savestdin 60 fp.close() 61 unlink(TESTFN) 62 63 self.raise_catch(OSError, "OSError") 64 self.assertRaises(OSError, open, 'this file does not exist', 'r') 65 66 self.raise_catch(ImportError, "ImportError") 67 self.assertRaises(ImportError, __import__, "undefined_module") 68 69 self.raise_catch(IndexError, "IndexError") 70 x = [] 71 self.assertRaises(IndexError, x.__getitem__, 10) 72 73 self.raise_catch(KeyError, "KeyError") 74 x = {} 75 self.assertRaises(KeyError, x.__getitem__, 'key') 76 77 self.raise_catch(KeyboardInterrupt, "KeyboardInterrupt") 78 79 self.raise_catch(MemoryError, "MemoryError") 80 81 self.raise_catch(NameError, "NameError") 82 try: x = undefined_variable 83 except NameError: pass 84 85 self.raise_catch(OverflowError, "OverflowError") 86 x = 1 87 for dummy in range(128): 88 x += x # this simply shouldn't blow up 89 90 self.raise_catch(RuntimeError, "RuntimeError") 91 self.raise_catch(RecursionError, "RecursionError") 92 93 self.raise_catch(SyntaxError, "SyntaxError") 94 try: exec('/\n') 95 except SyntaxError: pass 96 97 self.raise_catch(IndentationError, "IndentationError") 98 99 self.raise_catch(TabError, "TabError") 100 try: compile("try:\n\t1/0\n \t1/0\nfinally:\n pass\n", 101 '<string>', 'exec') 102 except TabError: pass 103 else: self.fail("TabError not raised") 104 105 self.raise_catch(SystemError, "SystemError") 106 107 self.raise_catch(SystemExit, "SystemExit") 108 self.assertRaises(SystemExit, sys.exit, 0) 109 110 self.raise_catch(TypeError, "TypeError") 111 try: [] + () 112 except TypeError: pass 113 114 self.raise_catch(ValueError, "ValueError") 115 self.assertRaises(ValueError, chr, 17<<16) 116 117 self.raise_catch(ZeroDivisionError, "ZeroDivisionError") 118 try: x = 1/0 119 except ZeroDivisionError: pass 120 121 self.raise_catch(Exception, "Exception") 122 try: x = 1/0 123 except Exception as e: pass 124 125 self.raise_catch(StopAsyncIteration, "StopAsyncIteration") 126 127 def testSyntaxErrorMessage(self): 128 # make sure the right exception message is raised for each of 129 # these code fragments 130 131 def ckmsg(src, msg): 132 try: 133 compile(src, '<fragment>', 'exec') 134 except SyntaxError as e: 135 if e.msg != msg: 136 self.fail("expected %s, got %s" % (msg, e.msg)) 137 else: 138 self.fail("failed to get expected SyntaxError") 139 140 s = '''while 1: 141 try: 142 pass 143 finally: 144 continue''' 145 146 if not sys.platform.startswith('java'): 147 ckmsg(s, "'continue' not supported inside 'finally' clause") 148 149 s = '''if 1: 150 try: 151 continue 152 except: 153 pass''' 154 155 ckmsg(s, "'continue' not properly in loop") 156 ckmsg("continue\n", "'continue' not properly in loop") 157 158 def testSyntaxErrorOffset(self): 159 def check(src, lineno, offset): 160 with self.assertRaises(SyntaxError) as cm: 161 compile(src, '<fragment>', 'exec') 162 self.assertEqual(cm.exception.lineno, lineno) 163 self.assertEqual(cm.exception.offset, offset) 164 165 check('def fact(x):\n\treturn x!\n', 2, 10) 166 check('1 +\n', 1, 4) 167 check('def spam():\n print(1)\n print(2)', 3, 10) 168 check('Python = "Python" +', 1, 20) 169 check('Python = "\u1e54\xfd\u0163\u0125\xf2\xf1" +', 1, 20) 170 171 @cpython_only 172 def testSettingException(self): 173 # test that setting an exception at the C level works even if the 174 # exception object can't be constructed. 175 176 class BadException(Exception): 177 def __init__(self_): 178 raise RuntimeError("can't instantiate BadException") 179 180 class InvalidException: 181 pass 182 183 def test_capi1(): 184 import _testcapi 185 try: 186 _testcapi.raise_exception(BadException, 1) 187 except TypeError as err: 188 exc, err, tb = sys.exc_info() 189 co = tb.tb_frame.f_code 190 self.assertEqual(co.co_name, "test_capi1") 191 self.assertTrue(co.co_filename.endswith('test_exceptions.py')) 192 else: 193 self.fail("Expected exception") 194 195 def test_capi2(): 196 import _testcapi 197 try: 198 _testcapi.raise_exception(BadException, 0) 199 except RuntimeError as err: 200 exc, err, tb = sys.exc_info() 201 co = tb.tb_frame.f_code 202 self.assertEqual(co.co_name, "__init__") 203 self.assertTrue(co.co_filename.endswith('test_exceptions.py')) 204 co2 = tb.tb_frame.f_back.f_code 205 self.assertEqual(co2.co_name, "test_capi2") 206 else: 207 self.fail("Expected exception") 208 209 def test_capi3(): 210 import _testcapi 211 self.assertRaises(SystemError, _testcapi.raise_exception, 212 InvalidException, 1) 213 214 if not sys.platform.startswith('java'): 215 test_capi1() 216 test_capi2() 217 test_capi3() 218 219 def test_WindowsError(self): 220 try: 221 WindowsError 222 except NameError: 223 pass 224 else: 225 self.assertIs(WindowsError, OSError) 226 self.assertEqual(str(OSError(1001)), "1001") 227 self.assertEqual(str(OSError(1001, "message")), 228 "[Errno 1001] message") 229 # POSIX errno (9 aka EBADF) is untranslated 230 w = OSError(9, 'foo', 'bar') 231 self.assertEqual(w.errno, 9) 232 self.assertEqual(w.winerror, None) 233 self.assertEqual(str(w), "[Errno 9] foo: 'bar'") 234 # ERROR_PATH_NOT_FOUND (win error 3) becomes ENOENT (2) 235 w = OSError(0, 'foo', 'bar', 3) 236 self.assertEqual(w.errno, 2) 237 self.assertEqual(w.winerror, 3) 238 self.assertEqual(w.strerror, 'foo') 239 self.assertEqual(w.filename, 'bar') 240 self.assertEqual(w.filename2, None) 241 self.assertEqual(str(w), "[WinError 3] foo: 'bar'") 242 # Unknown win error becomes EINVAL (22) 243 w = OSError(0, 'foo', None, 1001) 244 self.assertEqual(w.errno, 22) 245 self.assertEqual(w.winerror, 1001) 246 self.assertEqual(w.strerror, 'foo') 247 self.assertEqual(w.filename, None) 248 self.assertEqual(w.filename2, None) 249 self.assertEqual(str(w), "[WinError 1001] foo") 250 # Non-numeric "errno" 251 w = OSError('bar', 'foo') 252 self.assertEqual(w.errno, 'bar') 253 self.assertEqual(w.winerror, None) 254 self.assertEqual(w.strerror, 'foo') 255 self.assertEqual(w.filename, None) 256 self.assertEqual(w.filename2, None) 257 258 @unittest.skipUnless(sys.platform == 'win32', 259 'test specific to Windows') 260 def test_windows_message(self): 261 """Should fill in unknown error code in Windows error message""" 262 ctypes = import_module('ctypes') 263 # this error code has no message, Python formats it as hexadecimal 264 code = 3765269347 265 with self.assertRaisesRegex(OSError, 'Windows Error 0x%x' % code): 266 ctypes.pythonapi.PyErr_SetFromWindowsErr(code) 267 268 def testAttributes(self): 269 # test that exception attributes are happy 270 271 exceptionList = [ 272 (BaseException, (), {'args' : ()}), 273 (BaseException, (1, ), {'args' : (1,)}), 274 (BaseException, ('foo',), 275 {'args' : ('foo',)}), 276 (BaseException, ('foo', 1), 277 {'args' : ('foo', 1)}), 278 (SystemExit, ('foo',), 279 {'args' : ('foo',), 'code' : 'foo'}), 280 (OSError, ('foo',), 281 {'args' : ('foo',), 'filename' : None, 'filename2' : None, 282 'errno' : None, 'strerror' : None}), 283 (OSError, ('foo', 'bar'), 284 {'args' : ('foo', 'bar'), 285 'filename' : None, 'filename2' : None, 286 'errno' : 'foo', 'strerror' : 'bar'}), 287 (OSError, ('foo', 'bar', 'baz'), 288 {'args' : ('foo', 'bar'), 289 'filename' : 'baz', 'filename2' : None, 290 'errno' : 'foo', 'strerror' : 'bar'}), 291 (OSError, ('foo', 'bar', 'baz', None, 'quux'), 292 {'args' : ('foo', 'bar'), 'filename' : 'baz', 'filename2': 'quux'}), 293 (OSError, ('errnoStr', 'strErrorStr', 'filenameStr'), 294 {'args' : ('errnoStr', 'strErrorStr'), 295 'strerror' : 'strErrorStr', 'errno' : 'errnoStr', 296 'filename' : 'filenameStr'}), 297 (OSError, (1, 'strErrorStr', 'filenameStr'), 298 {'args' : (1, 'strErrorStr'), 'errno' : 1, 299 'strerror' : 'strErrorStr', 300 'filename' : 'filenameStr', 'filename2' : None}), 301 (SyntaxError, (), {'msg' : None, 'text' : None, 302 'filename' : None, 'lineno' : None, 'offset' : None, 303 'print_file_and_line' : None}), 304 (SyntaxError, ('msgStr',), 305 {'args' : ('msgStr',), 'text' : None, 306 'print_file_and_line' : None, 'msg' : 'msgStr', 307 'filename' : None, 'lineno' : None, 'offset' : None}), 308 (SyntaxError, ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr', 309 'textStr')), 310 {'offset' : 'offsetStr', 'text' : 'textStr', 311 'args' : ('msgStr', ('filenameStr', 'linenoStr', 312 'offsetStr', 'textStr')), 313 'print_file_and_line' : None, 'msg' : 'msgStr', 314 'filename' : 'filenameStr', 'lineno' : 'linenoStr'}), 315 (SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr', 316 'textStr', 'print_file_and_lineStr'), 317 {'text' : None, 318 'args' : ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr', 319 'textStr', 'print_file_and_lineStr'), 320 'print_file_and_line' : None, 'msg' : 'msgStr', 321 'filename' : None, 'lineno' : None, 'offset' : None}), 322 (UnicodeError, (), {'args' : (),}), 323 (UnicodeEncodeError, ('ascii', 'a', 0, 1, 324 'ordinal not in range'), 325 {'args' : ('ascii', 'a', 0, 1, 326 'ordinal not in range'), 327 'encoding' : 'ascii', 'object' : 'a', 328 'start' : 0, 'reason' : 'ordinal not in range'}), 329 (UnicodeDecodeError, ('ascii', bytearray(b'\xff'), 0, 1, 330 'ordinal not in range'), 331 {'args' : ('ascii', bytearray(b'\xff'), 0, 1, 332 'ordinal not in range'), 333 'encoding' : 'ascii', 'object' : b'\xff', 334 'start' : 0, 'reason' : 'ordinal not in range'}), 335 (UnicodeDecodeError, ('ascii', b'\xff', 0, 1, 336 'ordinal not in range'), 337 {'args' : ('ascii', b'\xff', 0, 1, 338 'ordinal not in range'), 339 'encoding' : 'ascii', 'object' : b'\xff', 340 'start' : 0, 'reason' : 'ordinal not in range'}), 341 (UnicodeTranslateError, ("\u3042", 0, 1, "ouch"), 342 {'args' : ('\u3042', 0, 1, 'ouch'), 343 'object' : '\u3042', 'reason' : 'ouch', 344 'start' : 0, 'end' : 1}), 345 (NaiveException, ('foo',), 346 {'args': ('foo',), 'x': 'foo'}), 347 (SlottedNaiveException, ('foo',), 348 {'args': ('foo',), 'x': 'foo'}), 349 ] 350 try: 351 # More tests are in test_WindowsError 352 exceptionList.append( 353 (WindowsError, (1, 'strErrorStr', 'filenameStr'), 354 {'args' : (1, 'strErrorStr'), 355 'strerror' : 'strErrorStr', 'winerror' : None, 356 'errno' : 1, 357 'filename' : 'filenameStr', 'filename2' : None}) 358 ) 359 except NameError: 360 pass 361 362 for exc, args, expected in exceptionList: 363 try: 364 e = exc(*args) 365 except: 366 print("\nexc=%r, args=%r" % (exc, args), file=sys.stderr) 367 raise 368 else: 369 # Verify module name 370 if not type(e).__name__.endswith('NaiveException'): 371 self.assertEqual(type(e).__module__, 'builtins') 372 # Verify no ref leaks in Exc_str() 373 s = str(e) 374 for checkArgName in expected: 375 value = getattr(e, checkArgName) 376 self.assertEqual(repr(value), 377 repr(expected[checkArgName]), 378 '%r.%s == %r, expected %r' % ( 379 e, checkArgName, 380 value, expected[checkArgName])) 381 382 # test for pickling support 383 for p in [pickle]: 384 for protocol in range(p.HIGHEST_PROTOCOL + 1): 385 s = p.dumps(e, protocol) 386 new = p.loads(s) 387 for checkArgName in expected: 388 got = repr(getattr(new, checkArgName)) 389 want = repr(expected[checkArgName]) 390 self.assertEqual(got, want, 391 'pickled "%r", attribute "%s' % 392 (e, checkArgName)) 393 394 def testWithTraceback(self): 395 try: 396 raise IndexError(4) 397 except: 398 tb = sys.exc_info()[2] 399 400 e = BaseException().with_traceback(tb) 401 self.assertIsInstance(e, BaseException) 402 self.assertEqual(e.__traceback__, tb) 403 404 e = IndexError(5).with_traceback(tb) 405 self.assertIsInstance(e, IndexError) 406 self.assertEqual(e.__traceback__, tb) 407 408 class MyException(Exception): 409 pass 410 411 e = MyException().with_traceback(tb) 412 self.assertIsInstance(e, MyException) 413 self.assertEqual(e.__traceback__, tb) 414 415 def testInvalidTraceback(self): 416 try: 417 Exception().__traceback__ = 5 418 except TypeError as e: 419 self.assertIn("__traceback__ must be a traceback", str(e)) 420 else: 421 self.fail("No exception raised") 422 423 def testInvalidAttrs(self): 424 self.assertRaises(TypeError, setattr, Exception(), '__cause__', 1) 425 self.assertRaises(TypeError, delattr, Exception(), '__cause__') 426 self.assertRaises(TypeError, setattr, Exception(), '__context__', 1) 427 self.assertRaises(TypeError, delattr, Exception(), '__context__') 428 429 def testNoneClearsTracebackAttr(self): 430 try: 431 raise IndexError(4) 432 except: 433 tb = sys.exc_info()[2] 434 435 e = Exception() 436 e.__traceback__ = tb 437 e.__traceback__ = None 438 self.assertEqual(e.__traceback__, None) 439 440 def testChainingAttrs(self): 441 e = Exception() 442 self.assertIsNone(e.__context__) 443 self.assertIsNone(e.__cause__) 444 445 e = TypeError() 446 self.assertIsNone(e.__context__) 447 self.assertIsNone(e.__cause__) 448 449 class MyException(OSError): 450 pass 451 452 e = MyException() 453 self.assertIsNone(e.__context__) 454 self.assertIsNone(e.__cause__) 455 456 def testChainingDescriptors(self): 457 try: 458 raise Exception() 459 except Exception as exc: 460 e = exc 461 462 self.assertIsNone(e.__context__) 463 self.assertIsNone(e.__cause__) 464 self.assertFalse(e.__suppress_context__) 465 466 e.__context__ = NameError() 467 e.__cause__ = None 468 self.assertIsInstance(e.__context__, NameError) 469 self.assertIsNone(e.__cause__) 470 self.assertTrue(e.__suppress_context__) 471 e.__suppress_context__ = False 472 self.assertFalse(e.__suppress_context__) 473 474 def testKeywordArgs(self): 475 # test that builtin exception don't take keyword args, 476 # but user-defined subclasses can if they want 477 self.assertRaises(TypeError, BaseException, a=1) 478 479 class DerivedException(BaseException): 480 def __init__(self, fancy_arg): 481 BaseException.__init__(self) 482 self.fancy_arg = fancy_arg 483 484 x = DerivedException(fancy_arg=42) 485 self.assertEqual(x.fancy_arg, 42) 486 487 @no_tracing 488 def testInfiniteRecursion(self): 489 def f(): 490 return f() 491 self.assertRaises(RecursionError, f) 492 493 def g(): 494 try: 495 return g() 496 except ValueError: 497 return -1 498 self.assertRaises(RecursionError, g) 499 500 def test_str(self): 501 # Make sure both instances and classes have a str representation. 502 self.assertTrue(str(Exception)) 503 self.assertTrue(str(Exception('a'))) 504 self.assertTrue(str(Exception('a', 'b'))) 505 506 def testExceptionCleanupNames(self): 507 # Make sure the local variable bound to the exception instance by 508 # an "except" statement is only visible inside the except block. 509 try: 510 raise Exception() 511 except Exception as e: 512 self.assertTrue(e) 513 del e 514 self.assertNotIn('e', locals()) 515 516 def testExceptionCleanupState(self): 517 # Make sure exception state is cleaned up as soon as the except 518 # block is left. See #2507 519 520 class MyException(Exception): 521 def __init__(self, obj): 522 self.obj = obj 523 class MyObj: 524 pass 525 526 def inner_raising_func(): 527 # Create some references in exception value and traceback 528 local_ref = obj 529 raise MyException(obj) 530 531 # Qualified "except" with "as" 532 obj = MyObj() 533 wr = weakref.ref(obj) 534 try: 535 inner_raising_func() 536 except MyException as e: 537 pass 538 obj = None 539 obj = wr() 540 self.assertTrue(obj is None, "%s" % obj) 541 542 # Qualified "except" without "as" 543 obj = MyObj() 544 wr = weakref.ref(obj) 545 try: 546 inner_raising_func() 547 except MyException: 548 pass 549 obj = None 550 obj = wr() 551 self.assertTrue(obj is None, "%s" % obj) 552 553 # Bare "except" 554 obj = MyObj() 555 wr = weakref.ref(obj) 556 try: 557 inner_raising_func() 558 except: 559 pass 560 obj = None 561 obj = wr() 562 self.assertTrue(obj is None, "%s" % obj) 563 564 # "except" with premature block leave 565 obj = MyObj() 566 wr = weakref.ref(obj) 567 for i in [0]: 568 try: 569 inner_raising_func() 570 except: 571 break 572 obj = None 573 obj = wr() 574 self.assertTrue(obj is None, "%s" % obj) 575 576 # "except" block raising another exception 577 obj = MyObj() 578 wr = weakref.ref(obj) 579 try: 580 try: 581 inner_raising_func() 582 except: 583 raise KeyError 584 except KeyError as e: 585 # We want to test that the except block above got rid of 586 # the exception raised in inner_raising_func(), but it 587 # also ends up in the __context__ of the KeyError, so we 588 # must clear the latter manually for our test to succeed. 589 e.__context__ = None 590 obj = None 591 obj = wr() 592 # guarantee no ref cycles on CPython (don't gc_collect) 593 if check_impl_detail(cpython=False): 594 gc_collect() 595 self.assertTrue(obj is None, "%s" % obj) 596 597 # Some complicated construct 598 obj = MyObj() 599 wr = weakref.ref(obj) 600 try: 601 inner_raising_func() 602 except MyException: 603 try: 604 try: 605 raise 606 finally: 607 raise 608 except MyException: 609 pass 610 obj = None 611 if check_impl_detail(cpython=False): 612 gc_collect() 613 obj = wr() 614 self.assertTrue(obj is None, "%s" % obj) 615 616 # Inside an exception-silencing "with" block 617 class Context: 618 def __enter__(self): 619 return self 620 def __exit__ (self, exc_type, exc_value, exc_tb): 621 return True 622 obj = MyObj() 623 wr = weakref.ref(obj) 624 with Context(): 625 inner_raising_func() 626 obj = None 627 if check_impl_detail(cpython=False): 628 gc_collect() 629 obj = wr() 630 self.assertTrue(obj is None, "%s" % obj) 631 632 def test_exception_target_in_nested_scope(self): 633 # issue 4617: This used to raise a SyntaxError 634 # "can not delete variable 'e' referenced in nested scope" 635 def print_error(): 636 e 637 try: 638 something 639 except Exception as e: 640 print_error() 641 # implicit "del e" here 642 643 def test_generator_leaking(self): 644 # Test that generator exception state doesn't leak into the calling 645 # frame 646 def yield_raise(): 647 try: 648 raise KeyError("caught") 649 except KeyError: 650 yield sys.exc_info()[0] 651 yield sys.exc_info()[0] 652 yield sys.exc_info()[0] 653 g = yield_raise() 654 self.assertEqual(next(g), KeyError) 655 self.assertEqual(sys.exc_info()[0], None) 656 self.assertEqual(next(g), KeyError) 657 self.assertEqual(sys.exc_info()[0], None) 658 self.assertEqual(next(g), None) 659 660 # Same test, but inside an exception handler 661 try: 662 raise TypeError("foo") 663 except TypeError: 664 g = yield_raise() 665 self.assertEqual(next(g), KeyError) 666 self.assertEqual(sys.exc_info()[0], TypeError) 667 self.assertEqual(next(g), KeyError) 668 self.assertEqual(sys.exc_info()[0], TypeError) 669 self.assertEqual(next(g), TypeError) 670 del g 671 self.assertEqual(sys.exc_info()[0], TypeError) 672 673 def test_generator_leaking2(self): 674 # See issue 12475. 675 def g(): 676 yield 677 try: 678 raise RuntimeError 679 except RuntimeError: 680 it = g() 681 next(it) 682 try: 683 next(it) 684 except StopIteration: 685 pass 686 self.assertEqual(sys.exc_info(), (None, None, None)) 687 688 def test_generator_leaking3(self): 689 # See issue #23353. When gen.throw() is called, the caller's 690 # exception state should be save and restored. 691 def g(): 692 try: 693 yield 694 except ZeroDivisionError: 695 yield sys.exc_info()[1] 696 it = g() 697 next(it) 698 try: 699 1/0 700 except ZeroDivisionError as e: 701 self.assertIs(sys.exc_info()[1], e) 702 gen_exc = it.throw(e) 703 self.assertIs(sys.exc_info()[1], e) 704 self.assertIs(gen_exc, e) 705 self.assertEqual(sys.exc_info(), (None, None, None)) 706 707 def test_generator_leaking4(self): 708 # See issue #23353. When an exception is raised by a generator, 709 # the caller's exception state should still be restored. 710 def g(): 711 try: 712 1/0 713 except ZeroDivisionError: 714 yield sys.exc_info()[0] 715 raise 716 it = g() 717 try: 718 raise TypeError 719 except TypeError: 720 # The caller's exception state (TypeError) is temporarily 721 # saved in the generator. 722 tp = next(it) 723 self.assertIs(tp, ZeroDivisionError) 724 try: 725 next(it) 726 # We can't check it immediately, but while next() returns 727 # with an exception, it shouldn't have restored the old 728 # exception state (TypeError). 729 except ZeroDivisionError as e: 730 self.assertIs(sys.exc_info()[1], e) 731 # We used to find TypeError here. 732 self.assertEqual(sys.exc_info(), (None, None, None)) 733 734 def test_generator_doesnt_retain_old_exc(self): 735 def g(): 736 self.assertIsInstance(sys.exc_info()[1], RuntimeError) 737 yield 738 self.assertEqual(sys.exc_info(), (None, None, None)) 739 it = g() 740 try: 741 raise RuntimeError 742 except RuntimeError: 743 next(it) 744 self.assertRaises(StopIteration, next, it) 745 746 def test_generator_finalizing_and_exc_info(self): 747 # See #7173 748 def simple_gen(): 749 yield 1 750 def run_gen(): 751 gen = simple_gen() 752 try: 753 raise RuntimeError 754 except RuntimeError: 755 return next(gen) 756 run_gen() 757 gc_collect() 758 self.assertEqual(sys.exc_info(), (None, None, None)) 759 760 def _check_generator_cleanup_exc_state(self, testfunc): 761 # Issue #12791: exception state is cleaned up as soon as a generator 762 # is closed (reference cycles are broken). 763 class MyException(Exception): 764 def __init__(self, obj): 765 self.obj = obj 766 class MyObj: 767 pass 768 769 def raising_gen(): 770 try: 771 raise MyException(obj) 772 except MyException: 773 yield 774 775 obj = MyObj() 776 wr = weakref.ref(obj) 777 g = raising_gen() 778 next(g) 779 testfunc(g) 780 g = obj = None 781 obj = wr() 782 self.assertIs(obj, None) 783 784 def test_generator_throw_cleanup_exc_state(self): 785 def do_throw(g): 786 try: 787 g.throw(RuntimeError()) 788 except RuntimeError: 789 pass 790 self._check_generator_cleanup_exc_state(do_throw) 791 792 def test_generator_close_cleanup_exc_state(self): 793 def do_close(g): 794 g.close() 795 self._check_generator_cleanup_exc_state(do_close) 796 797 def test_generator_del_cleanup_exc_state(self): 798 def do_del(g): 799 g = None 800 self._check_generator_cleanup_exc_state(do_del) 801 802 def test_generator_next_cleanup_exc_state(self): 803 def do_next(g): 804 try: 805 next(g) 806 except StopIteration: 807 pass 808 else: 809 self.fail("should have raised StopIteration") 810 self._check_generator_cleanup_exc_state(do_next) 811 812 def test_generator_send_cleanup_exc_state(self): 813 def do_send(g): 814 try: 815 g.send(None) 816 except StopIteration: 817 pass 818 else: 819 self.fail("should have raised StopIteration") 820 self._check_generator_cleanup_exc_state(do_send) 821 822 def test_3114(self): 823 # Bug #3114: in its destructor, MyObject retrieves a pointer to 824 # obsolete and/or deallocated objects. 825 class MyObject: 826 def __del__(self): 827 nonlocal e 828 e = sys.exc_info() 829 e = () 830 try: 831 raise Exception(MyObject()) 832 except: 833 pass 834 self.assertEqual(e, (None, None, None)) 835 836 def test_unicode_change_attributes(self): 837 # See issue 7309. This was a crasher. 838 839 u = UnicodeEncodeError('baz', 'xxxxx', 1, 5, 'foo') 840 self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: foo") 841 u.end = 2 842 self.assertEqual(str(u), "'baz' codec can't encode character '\\x78' in position 1: foo") 843 u.end = 5 844 u.reason = 0x345345345345345345 845 self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: 965230951443685724997") 846 u.encoding = 4000 847 self.assertEqual(str(u), "'4000' codec can't encode characters in position 1-4: 965230951443685724997") 848 u.start = 1000 849 self.assertEqual(str(u), "'4000' codec can't encode characters in position 1000-4: 965230951443685724997") 850 851 u = UnicodeDecodeError('baz', b'xxxxx', 1, 5, 'foo') 852 self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: foo") 853 u.end = 2 854 self.assertEqual(str(u), "'baz' codec can't decode byte 0x78 in position 1: foo") 855 u.end = 5 856 u.reason = 0x345345345345345345 857 self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: 965230951443685724997") 858 u.encoding = 4000 859 self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1-4: 965230951443685724997") 860 u.start = 1000 861 self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1000-4: 965230951443685724997") 862 863 u = UnicodeTranslateError('xxxx', 1, 5, 'foo') 864 self.assertEqual(str(u), "can't translate characters in position 1-4: foo") 865 u.end = 2 866 self.assertEqual(str(u), "can't translate character '\\x78' in position 1: foo") 867 u.end = 5 868 u.reason = 0x345345345345345345 869 self.assertEqual(str(u), "can't translate characters in position 1-4: 965230951443685724997") 870 u.start = 1000 871 self.assertEqual(str(u), "can't translate characters in position 1000-4: 965230951443685724997") 872 873 def test_unicode_errors_no_object(self): 874 # See issue #21134. 875 klasses = UnicodeEncodeError, UnicodeDecodeError, UnicodeTranslateError 876 for klass in klasses: 877 self.assertEqual(str(klass.__new__(klass)), "") 878 879 @no_tracing 880 def test_badisinstance(self): 881 # Bug #2542: if issubclass(e, MyException) raises an exception, 882 # it should be ignored 883 class Meta(type): 884 def __subclasscheck__(cls, subclass): 885 raise ValueError() 886 class MyException(Exception, metaclass=Meta): 887 pass 888 889 with captured_stderr() as stderr: 890 try: 891 raise KeyError() 892 except MyException as e: 893 self.fail("exception should not be a MyException") 894 except KeyError: 895 pass 896 except: 897 self.fail("Should have raised KeyError") 898 else: 899 self.fail("Should have raised KeyError") 900 901 def g(): 902 try: 903 return g() 904 except RecursionError: 905 return sys.exc_info() 906 e, v, tb = g() 907 self.assertTrue(isinstance(v, RecursionError), type(v)) 908 self.assertIn("maximum recursion depth exceeded", str(v)) 909 910 911 @cpython_only 912 def test_MemoryError(self): 913 # PyErr_NoMemory always raises the same exception instance. 914 # Check that the traceback is not doubled. 915 import traceback 916 from _testcapi import raise_memoryerror 917 def raiseMemError(): 918 try: 919 raise_memoryerror() 920 except MemoryError as e: 921 tb = e.__traceback__ 922 else: 923 self.fail("Should have raises a MemoryError") 924 return traceback.format_tb(tb) 925 926 tb1 = raiseMemError() 927 tb2 = raiseMemError() 928 self.assertEqual(tb1, tb2) 929 930 @cpython_only 931 def test_exception_with_doc(self): 932 import _testcapi 933 doc2 = "This is a test docstring." 934 doc4 = "This is another test docstring." 935 936 self.assertRaises(SystemError, _testcapi.make_exception_with_doc, 937 "error1") 938 939 # test basic usage of PyErr_NewException 940 error1 = _testcapi.make_exception_with_doc("_testcapi.error1") 941 self.assertIs(type(error1), type) 942 self.assertTrue(issubclass(error1, Exception)) 943 self.assertIsNone(error1.__doc__) 944 945 # test with given docstring 946 error2 = _testcapi.make_exception_with_doc("_testcapi.error2", doc2) 947 self.assertEqual(error2.__doc__, doc2) 948 949 # test with explicit base (without docstring) 950 error3 = _testcapi.make_exception_with_doc("_testcapi.error3", 951 base=error2) 952 self.assertTrue(issubclass(error3, error2)) 953 954 # test with explicit base tuple 955 class C(object): 956 pass 957 error4 = _testcapi.make_exception_with_doc("_testcapi.error4", doc4, 958 (error3, C)) 959 self.assertTrue(issubclass(error4, error3)) 960 self.assertTrue(issubclass(error4, C)) 961 self.assertEqual(error4.__doc__, doc4) 962 963 # test with explicit dictionary 964 error5 = _testcapi.make_exception_with_doc("_testcapi.error5", "", 965 error4, {'a': 1}) 966 self.assertTrue(issubclass(error5, error4)) 967 self.assertEqual(error5.a, 1) 968 self.assertEqual(error5.__doc__, "") 969 970 @cpython_only 971 def test_memory_error_cleanup(self): 972 # Issue #5437: preallocated MemoryError instances should not keep 973 # traceback objects alive. 974 from _testcapi import raise_memoryerror 975 class C: 976 pass 977 wr = None 978 def inner(): 979 nonlocal wr 980 c = C() 981 wr = weakref.ref(c) 982 raise_memoryerror() 983 # We cannot use assertRaises since it manually deletes the traceback 984 try: 985 inner() 986 except MemoryError as e: 987 self.assertNotEqual(wr(), None) 988 else: 989 self.fail("MemoryError not raised") 990 self.assertEqual(wr(), None) 991 992 @no_tracing 993 def test_recursion_error_cleanup(self): 994 # Same test as above, but with "recursion exceeded" errors 995 class C: 996 pass 997 wr = None 998 def inner(): 999 nonlocal wr 1000 c = C() 1001 wr = weakref.ref(c) 1002 inner() 1003 # We cannot use assertRaises since it manually deletes the traceback 1004 try: 1005 inner() 1006 except RecursionError as e: 1007 self.assertNotEqual(wr(), None) 1008 else: 1009 self.fail("RecursionError not raised") 1010 self.assertEqual(wr(), None) 1011 1012 def test_errno_ENOTDIR(self): 1013 # Issue #12802: "not a directory" errors are ENOTDIR even on Windows 1014 with self.assertRaises(OSError) as cm: 1015 os.listdir(__file__) 1016 self.assertEqual(cm.exception.errno, errno.ENOTDIR, cm.exception) 1017 1018 def test_unraisable(self): 1019 # Issue #22836: PyErr_WriteUnraisable() should give sensible reports 1020 class BrokenDel: 1021 def __del__(self): 1022 exc = ValueError("del is broken") 1023 # The following line is included in the traceback report: 1024 raise exc 1025 1026 class BrokenRepr(BrokenDel): 1027 def __repr__(self): 1028 raise AttributeError("repr() is broken") 1029 1030 class BrokenExceptionDel: 1031 def __del__(self): 1032 exc = BrokenStrException() 1033 # The following line is included in the traceback report: 1034 raise exc 1035 1036 for test_class in (BrokenDel, BrokenRepr, BrokenExceptionDel): 1037 with self.subTest(test_class): 1038 obj = test_class() 1039 with captured_stderr() as stderr: 1040 del obj 1041 report = stderr.getvalue() 1042 self.assertIn("Exception ignored", report) 1043 if test_class is BrokenRepr: 1044 self.assertIn("<object repr() failed>", report) 1045 else: 1046 self.assertIn(test_class.__del__.__qualname__, report) 1047 self.assertIn("test_exceptions.py", report) 1048 self.assertIn("raise exc", report) 1049 if test_class is BrokenExceptionDel: 1050 self.assertIn("BrokenStrException", report) 1051 self.assertIn("<exception str() failed>", report) 1052 else: 1053 self.assertIn("ValueError", report) 1054 self.assertIn("del is broken", report) 1055 self.assertTrue(report.endswith("\n")) 1056 1057 def test_unhandled(self): 1058 # Check for sensible reporting of unhandled exceptions 1059 for exc_type in (ValueError, BrokenStrException): 1060 with self.subTest(exc_type): 1061 try: 1062 exc = exc_type("test message") 1063 # The following line is included in the traceback report: 1064 raise exc 1065 except exc_type: 1066 with captured_stderr() as stderr: 1067 sys.__excepthook__(*sys.exc_info()) 1068 report = stderr.getvalue() 1069 self.assertIn("test_exceptions.py", report) 1070 self.assertIn("raise exc", report) 1071 self.assertIn(exc_type.__name__, report) 1072 if exc_type is BrokenStrException: 1073 self.assertIn("<exception str() failed>", report) 1074 else: 1075 self.assertIn("test message", report) 1076 self.assertTrue(report.endswith("\n")) 1077 1078 1079class ImportErrorTests(unittest.TestCase): 1080 1081 def test_attributes(self): 1082 # Setting 'name' and 'path' should not be a problem. 1083 exc = ImportError('test') 1084 self.assertIsNone(exc.name) 1085 self.assertIsNone(exc.path) 1086 1087 exc = ImportError('test', name='somemodule') 1088 self.assertEqual(exc.name, 'somemodule') 1089 self.assertIsNone(exc.path) 1090 1091 exc = ImportError('test', path='somepath') 1092 self.assertEqual(exc.path, 'somepath') 1093 self.assertIsNone(exc.name) 1094 1095 exc = ImportError('test', path='somepath', name='somename') 1096 self.assertEqual(exc.name, 'somename') 1097 self.assertEqual(exc.path, 'somepath') 1098 1099 msg = "'invalid' is an invalid keyword argument for this function" 1100 with self.assertRaisesRegex(TypeError, msg): 1101 ImportError('test', invalid='keyword') 1102 1103 with self.assertRaisesRegex(TypeError, msg): 1104 ImportError('test', name='name', invalid='keyword') 1105 1106 with self.assertRaisesRegex(TypeError, msg): 1107 ImportError('test', path='path', invalid='keyword') 1108 1109 with self.assertRaisesRegex(TypeError, msg): 1110 ImportError(invalid='keyword') 1111 1112 with self.assertRaisesRegex(TypeError, msg): 1113 ImportError('test', invalid='keyword', another=True) 1114 1115 def test_non_str_argument(self): 1116 # Issue #15778 1117 with check_warnings(('', BytesWarning), quiet=True): 1118 arg = b'abc' 1119 exc = ImportError(arg) 1120 self.assertEqual(str(arg), str(exc)) 1121 1122 1123if __name__ == '__main__': 1124 unittest.main() 1125