1# Python test set -- part 5, built-in exceptions 2 3import copy 4import gc 5import os 6import sys 7import unittest 8import pickle 9import weakref 10import errno 11from textwrap import dedent 12 13from test.support import (captured_stderr, check_impl_detail, 14 cpython_only, gc_collect, 15 no_tracing, script_helper, 16 SuppressCrashReport) 17from test.support.import_helper import import_module 18from test.support.os_helper import TESTFN, unlink 19from test.support.warnings_helper import check_warnings 20from test import support 21 22 23class NaiveException(Exception): 24 def __init__(self, x): 25 self.x = x 26 27class SlottedNaiveException(Exception): 28 __slots__ = ('x',) 29 def __init__(self, x): 30 self.x = x 31 32class BrokenStrException(Exception): 33 def __str__(self): 34 raise Exception("str() is broken") 35 36# XXX This is not really enough, each *operation* should be tested! 37 38class ExceptionTests(unittest.TestCase): 39 40 def raise_catch(self, exc, excname): 41 with self.subTest(exc=exc, excname=excname): 42 try: 43 raise exc("spam") 44 except exc as err: 45 buf1 = str(err) 46 try: 47 raise exc("spam") 48 except exc as err: 49 buf2 = str(err) 50 self.assertEqual(buf1, buf2) 51 self.assertEqual(exc.__name__, excname) 52 53 def testRaising(self): 54 self.raise_catch(AttributeError, "AttributeError") 55 self.assertRaises(AttributeError, getattr, sys, "undefined_attribute") 56 57 self.raise_catch(EOFError, "EOFError") 58 fp = open(TESTFN, 'w', encoding="utf-8") 59 fp.close() 60 fp = open(TESTFN, 'r', encoding="utf-8") 61 savestdin = sys.stdin 62 try: 63 try: 64 import marshal 65 marshal.loads(b'') 66 except EOFError: 67 pass 68 finally: 69 sys.stdin = savestdin 70 fp.close() 71 unlink(TESTFN) 72 73 self.raise_catch(OSError, "OSError") 74 self.assertRaises(OSError, open, 'this file does not exist', 'r') 75 76 self.raise_catch(ImportError, "ImportError") 77 self.assertRaises(ImportError, __import__, "undefined_module") 78 79 self.raise_catch(IndexError, "IndexError") 80 x = [] 81 self.assertRaises(IndexError, x.__getitem__, 10) 82 83 self.raise_catch(KeyError, "KeyError") 84 x = {} 85 self.assertRaises(KeyError, x.__getitem__, 'key') 86 87 self.raise_catch(KeyboardInterrupt, "KeyboardInterrupt") 88 89 self.raise_catch(MemoryError, "MemoryError") 90 91 self.raise_catch(NameError, "NameError") 92 try: x = undefined_variable 93 except NameError: pass 94 95 self.raise_catch(OverflowError, "OverflowError") 96 x = 1 97 for dummy in range(128): 98 x += x # this simply shouldn't blow up 99 100 self.raise_catch(RuntimeError, "RuntimeError") 101 self.raise_catch(RecursionError, "RecursionError") 102 103 self.raise_catch(SyntaxError, "SyntaxError") 104 try: exec('/\n') 105 except SyntaxError: pass 106 107 self.raise_catch(IndentationError, "IndentationError") 108 109 self.raise_catch(TabError, "TabError") 110 try: compile("try:\n\t1/0\n \t1/0\nfinally:\n pass\n", 111 '<string>', 'exec') 112 except TabError: pass 113 else: self.fail("TabError not raised") 114 115 self.raise_catch(SystemError, "SystemError") 116 117 self.raise_catch(SystemExit, "SystemExit") 118 self.assertRaises(SystemExit, sys.exit, 0) 119 120 self.raise_catch(TypeError, "TypeError") 121 try: [] + () 122 except TypeError: pass 123 124 self.raise_catch(ValueError, "ValueError") 125 self.assertRaises(ValueError, chr, 17<<16) 126 127 self.raise_catch(ZeroDivisionError, "ZeroDivisionError") 128 try: x = 1/0 129 except ZeroDivisionError: pass 130 131 self.raise_catch(Exception, "Exception") 132 try: x = 1/0 133 except Exception as e: pass 134 135 self.raise_catch(StopAsyncIteration, "StopAsyncIteration") 136 137 def testSyntaxErrorMessage(self): 138 # make sure the right exception message is raised for each of 139 # these code fragments 140 141 def ckmsg(src, msg): 142 with self.subTest(src=src, msg=msg): 143 try: 144 compile(src, '<fragment>', 'exec') 145 except SyntaxError as e: 146 if e.msg != msg: 147 self.fail("expected %s, got %s" % (msg, e.msg)) 148 else: 149 self.fail("failed to get expected SyntaxError") 150 151 s = '''if 1: 152 try: 153 continue 154 except: 155 pass''' 156 157 ckmsg(s, "'continue' not properly in loop") 158 ckmsg("continue\n", "'continue' not properly in loop") 159 160 def testSyntaxErrorMissingParens(self): 161 def ckmsg(src, msg, exception=SyntaxError): 162 try: 163 compile(src, '<fragment>', 'exec') 164 except exception as e: 165 if e.msg != msg: 166 self.fail("expected %s, got %s" % (msg, e.msg)) 167 else: 168 self.fail("failed to get expected SyntaxError") 169 170 s = '''print "old style"''' 171 ckmsg(s, "Missing parentheses in call to 'print'. Did you mean print(...)?") 172 173 s = '''print "old style",''' 174 ckmsg(s, "Missing parentheses in call to 'print'. Did you mean print(...)?") 175 176 s = 'print f(a+b,c)' 177 ckmsg(s, "Missing parentheses in call to 'print'. Did you mean print(...)?") 178 179 s = '''exec "old style"''' 180 ckmsg(s, "Missing parentheses in call to 'exec'. Did you mean exec(...)?") 181 182 s = 'exec f(a+b,c)' 183 ckmsg(s, "Missing parentheses in call to 'exec'. Did you mean exec(...)?") 184 185 # Check that we don't incorrectly identify '(...)' as an expression to the right 186 # of 'print' 187 188 s = 'print (a+b,c) $ 42' 189 ckmsg(s, "invalid syntax") 190 191 s = 'exec (a+b,c) $ 42' 192 ckmsg(s, "invalid syntax") 193 194 # should not apply to subclasses, see issue #31161 195 s = '''if True:\nprint "No indent"''' 196 ckmsg(s, "expected an indented block after 'if' statement on line 1", IndentationError) 197 198 s = '''if True:\n print()\n\texec "mixed tabs and spaces"''' 199 ckmsg(s, "inconsistent use of tabs and spaces in indentation", TabError) 200 201 def check(self, src, lineno, offset, end_lineno=None, end_offset=None, encoding='utf-8'): 202 with self.subTest(source=src, lineno=lineno, offset=offset): 203 with self.assertRaises(SyntaxError) as cm: 204 compile(src, '<fragment>', 'exec') 205 self.assertEqual(cm.exception.lineno, lineno) 206 self.assertEqual(cm.exception.offset, offset) 207 if end_lineno is not None: 208 self.assertEqual(cm.exception.end_lineno, end_lineno) 209 if end_offset is not None: 210 self.assertEqual(cm.exception.end_offset, end_offset) 211 212 if cm.exception.text is not None: 213 if not isinstance(src, str): 214 src = src.decode(encoding, 'replace') 215 line = src.split('\n')[lineno-1] 216 self.assertIn(line, cm.exception.text) 217 218 def test_error_offset_continuation_characters(self): 219 check = self.check 220 check('"\\\n"(1 for c in I,\\\n\\', 2, 2) 221 222 def testSyntaxErrorOffset(self): 223 check = self.check 224 check('def fact(x):\n\treturn x!\n', 2, 10) 225 check('1 +\n', 1, 4) 226 check('def spam():\n print(1)\n print(2)', 3, 10) 227 check('Python = "Python" +', 1, 20) 228 check('Python = "\u1e54\xfd\u0163\u0125\xf2\xf1" +', 1, 20) 229 check(b'# -*- coding: cp1251 -*-\nPython = "\xcf\xb3\xf2\xee\xed" +', 230 2, 19, encoding='cp1251') 231 check(b'Python = "\xcf\xb3\xf2\xee\xed" +', 1, 18) 232 check('x = "a', 1, 5) 233 check('lambda x: x = 2', 1, 1) 234 check('f{a + b + c}', 1, 2) 235 check('[file for str(file) in []\n]', 1, 11) 236 check('a = « hello » « world »', 1, 5) 237 check('[\nfile\nfor str(file)\nin\n[]\n]', 3, 5) 238 check('[file for\n str(file) in []]', 2, 2) 239 check("ages = {'Alice'=22, 'Bob'=23}", 1, 9) 240 check('match ...:\n case {**rest, "key": value}:\n ...', 2, 19) 241 check("[a b c d e f]", 1, 2) 242 check("for x yfff:", 1, 7) 243 check("f(a for a in b, c)", 1, 3, 1, 15) 244 check("f(a for a in b if a, c)", 1, 3, 1, 20) 245 check("f(a, b for b in c)", 1, 6, 1, 18) 246 check("f(a, b for b in c, d)", 1, 6, 1, 18) 247 248 # Errors thrown by compile.c 249 check('class foo:return 1', 1, 11) 250 check('def f():\n continue', 2, 3) 251 check('def f():\n break', 2, 3) 252 check('try:\n pass\nexcept:\n pass\nexcept ValueError:\n pass', 3, 1) 253 check('try:\n pass\nexcept*:\n pass', 3, 8) 254 check('try:\n pass\nexcept*:\n pass\nexcept* ValueError:\n pass', 3, 8) 255 256 # Errors thrown by tokenizer.c 257 check('(0x+1)', 1, 3) 258 check('x = 0xI', 1, 6) 259 check('0010 + 2', 1, 1) 260 check('x = 32e-+4', 1, 8) 261 check('x = 0o9', 1, 7) 262 check('\u03b1 = 0xI', 1, 6) 263 check(b'\xce\xb1 = 0xI', 1, 6) 264 check(b'# -*- coding: iso8859-7 -*-\n\xe1 = 0xI', 2, 6, 265 encoding='iso8859-7') 266 check(b"""if 1: 267 def foo(): 268 ''' 269 270 def bar(): 271 pass 272 273 def baz(): 274 '''quux''' 275 """, 9, 24) 276 check("pass\npass\npass\n(1+)\npass\npass\npass", 4, 4) 277 check("(1+)", 1, 4) 278 check("[interesting\nfoo()\n", 1, 1) 279 check(b"\xef\xbb\xbf#coding: utf8\nprint('\xe6\x88\x91')\n", 0, -1) 280 check("""f''' 281 { 282 (123_a) 283 }'''""", 3, 17) 284 check("""f''' 285 { 286 f\"\"\" 287 { 288 (123_a) 289 } 290 \"\"\" 291 }'''""", 5, 17) 292 check('''f""" 293 294 295 { 296 6 297 0="""''', 5, 13) 298 299 # Errors thrown by symtable.c 300 check('x = [(yield i) for i in range(3)]', 1, 7) 301 check('def f():\n from _ import *', 2, 17) 302 check('def f(x, x):\n pass', 1, 10) 303 check('{i for i in range(5) if (j := 0) for j in range(5)}', 1, 38) 304 check('def f(x):\n nonlocal x', 2, 3) 305 check('def f(x):\n x = 1\n global x', 3, 3) 306 check('nonlocal x', 1, 1) 307 check('def f():\n global x\n nonlocal x', 2, 3) 308 309 # Errors thrown by future.c 310 check('from __future__ import doesnt_exist', 1, 1) 311 check('from __future__ import braces', 1, 1) 312 check('x=1\nfrom __future__ import division', 2, 1) 313 check('foo(1=2)', 1, 5) 314 check('def f():\n x, y: int', 2, 3) 315 check('[*x for x in xs]', 1, 2) 316 check('foo(x for x in range(10), 100)', 1, 5) 317 check('for 1 in []: pass', 1, 5) 318 check('(yield i) = 2', 1, 2) 319 check('def f(*):\n pass', 1, 7) 320 321 @cpython_only 322 def testSettingException(self): 323 # test that setting an exception at the C level works even if the 324 # exception object can't be constructed. 325 326 class BadException(Exception): 327 def __init__(self_): 328 raise RuntimeError("can't instantiate BadException") 329 330 class InvalidException: 331 pass 332 333 def test_capi1(): 334 import _testcapi 335 try: 336 _testcapi.raise_exception(BadException, 1) 337 except TypeError as err: 338 exc, err, tb = sys.exc_info() 339 co = tb.tb_frame.f_code 340 self.assertEqual(co.co_name, "test_capi1") 341 self.assertTrue(co.co_filename.endswith('test_exceptions.py')) 342 else: 343 self.fail("Expected exception") 344 345 def test_capi2(): 346 import _testcapi 347 try: 348 _testcapi.raise_exception(BadException, 0) 349 except RuntimeError as err: 350 exc, err, tb = sys.exc_info() 351 co = tb.tb_frame.f_code 352 self.assertEqual(co.co_name, "__init__") 353 self.assertTrue(co.co_filename.endswith('test_exceptions.py')) 354 co2 = tb.tb_frame.f_back.f_code 355 self.assertEqual(co2.co_name, "test_capi2") 356 else: 357 self.fail("Expected exception") 358 359 def test_capi3(): 360 import _testcapi 361 self.assertRaises(SystemError, _testcapi.raise_exception, 362 InvalidException, 1) 363 364 if not sys.platform.startswith('java'): 365 test_capi1() 366 test_capi2() 367 test_capi3() 368 369 def test_WindowsError(self): 370 try: 371 WindowsError 372 except NameError: 373 pass 374 else: 375 self.assertIs(WindowsError, OSError) 376 self.assertEqual(str(OSError(1001)), "1001") 377 self.assertEqual(str(OSError(1001, "message")), 378 "[Errno 1001] message") 379 # POSIX errno (9 aka EBADF) is untranslated 380 w = OSError(9, 'foo', 'bar') 381 self.assertEqual(w.errno, 9) 382 self.assertEqual(w.winerror, None) 383 self.assertEqual(str(w), "[Errno 9] foo: 'bar'") 384 # ERROR_PATH_NOT_FOUND (win error 3) becomes ENOENT (2) 385 w = OSError(0, 'foo', 'bar', 3) 386 self.assertEqual(w.errno, 2) 387 self.assertEqual(w.winerror, 3) 388 self.assertEqual(w.strerror, 'foo') 389 self.assertEqual(w.filename, 'bar') 390 self.assertEqual(w.filename2, None) 391 self.assertEqual(str(w), "[WinError 3] foo: 'bar'") 392 # Unknown win error becomes EINVAL (22) 393 w = OSError(0, 'foo', None, 1001) 394 self.assertEqual(w.errno, 22) 395 self.assertEqual(w.winerror, 1001) 396 self.assertEqual(w.strerror, 'foo') 397 self.assertEqual(w.filename, None) 398 self.assertEqual(w.filename2, None) 399 self.assertEqual(str(w), "[WinError 1001] foo") 400 # Non-numeric "errno" 401 w = OSError('bar', 'foo') 402 self.assertEqual(w.errno, 'bar') 403 self.assertEqual(w.winerror, None) 404 self.assertEqual(w.strerror, 'foo') 405 self.assertEqual(w.filename, None) 406 self.assertEqual(w.filename2, None) 407 408 @unittest.skipUnless(sys.platform == 'win32', 409 'test specific to Windows') 410 def test_windows_message(self): 411 """Should fill in unknown error code in Windows error message""" 412 ctypes = import_module('ctypes') 413 # this error code has no message, Python formats it as hexadecimal 414 code = 3765269347 415 with self.assertRaisesRegex(OSError, 'Windows Error 0x%x' % code): 416 ctypes.pythonapi.PyErr_SetFromWindowsErr(code) 417 418 def testAttributes(self): 419 # test that exception attributes are happy 420 421 exceptionList = [ 422 (BaseException, (), {'args' : ()}), 423 (BaseException, (1, ), {'args' : (1,)}), 424 (BaseException, ('foo',), 425 {'args' : ('foo',)}), 426 (BaseException, ('foo', 1), 427 {'args' : ('foo', 1)}), 428 (SystemExit, ('foo',), 429 {'args' : ('foo',), 'code' : 'foo'}), 430 (OSError, ('foo',), 431 {'args' : ('foo',), 'filename' : None, 'filename2' : None, 432 'errno' : None, 'strerror' : None}), 433 (OSError, ('foo', 'bar'), 434 {'args' : ('foo', 'bar'), 435 'filename' : None, 'filename2' : None, 436 'errno' : 'foo', 'strerror' : 'bar'}), 437 (OSError, ('foo', 'bar', 'baz'), 438 {'args' : ('foo', 'bar'), 439 'filename' : 'baz', 'filename2' : None, 440 'errno' : 'foo', 'strerror' : 'bar'}), 441 (OSError, ('foo', 'bar', 'baz', None, 'quux'), 442 {'args' : ('foo', 'bar'), 'filename' : 'baz', 'filename2': 'quux'}), 443 (OSError, ('errnoStr', 'strErrorStr', 'filenameStr'), 444 {'args' : ('errnoStr', 'strErrorStr'), 445 'strerror' : 'strErrorStr', 'errno' : 'errnoStr', 446 'filename' : 'filenameStr'}), 447 (OSError, (1, 'strErrorStr', 'filenameStr'), 448 {'args' : (1, 'strErrorStr'), 'errno' : 1, 449 'strerror' : 'strErrorStr', 450 'filename' : 'filenameStr', 'filename2' : None}), 451 (SyntaxError, (), {'msg' : None, 'text' : None, 452 'filename' : None, 'lineno' : None, 'offset' : None, 453 'end_offset': None, 'print_file_and_line' : None}), 454 (SyntaxError, ('msgStr',), 455 {'args' : ('msgStr',), 'text' : None, 456 'print_file_and_line' : None, 'msg' : 'msgStr', 457 'filename' : None, 'lineno' : None, 'offset' : None, 458 'end_offset': None}), 459 (SyntaxError, ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr', 460 'textStr', 'endLinenoStr', 'endOffsetStr')), 461 {'offset' : 'offsetStr', 'text' : 'textStr', 462 'args' : ('msgStr', ('filenameStr', 'linenoStr', 463 'offsetStr', 'textStr', 464 'endLinenoStr', 'endOffsetStr')), 465 'print_file_and_line' : None, 'msg' : 'msgStr', 466 'filename' : 'filenameStr', 'lineno' : 'linenoStr', 467 'end_lineno': 'endLinenoStr', 'end_offset': 'endOffsetStr'}), 468 (SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr', 469 'textStr', 'endLinenoStr', 'endOffsetStr', 470 'print_file_and_lineStr'), 471 {'text' : None, 472 'args' : ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr', 473 'textStr', 'endLinenoStr', 'endOffsetStr', 474 'print_file_and_lineStr'), 475 'print_file_and_line' : None, 'msg' : 'msgStr', 476 'filename' : None, 'lineno' : None, 'offset' : None, 477 'end_lineno': None, 'end_offset': None}), 478 (UnicodeError, (), {'args' : (),}), 479 (UnicodeEncodeError, ('ascii', 'a', 0, 1, 480 'ordinal not in range'), 481 {'args' : ('ascii', 'a', 0, 1, 482 'ordinal not in range'), 483 'encoding' : 'ascii', 'object' : 'a', 484 'start' : 0, 'reason' : 'ordinal not in range'}), 485 (UnicodeDecodeError, ('ascii', bytearray(b'\xff'), 0, 1, 486 'ordinal not in range'), 487 {'args' : ('ascii', bytearray(b'\xff'), 0, 1, 488 'ordinal not in range'), 489 'encoding' : 'ascii', 'object' : b'\xff', 490 'start' : 0, 'reason' : 'ordinal not in range'}), 491 (UnicodeDecodeError, ('ascii', b'\xff', 0, 1, 492 'ordinal not in range'), 493 {'args' : ('ascii', b'\xff', 0, 1, 494 'ordinal not in range'), 495 'encoding' : 'ascii', 'object' : b'\xff', 496 'start' : 0, 'reason' : 'ordinal not in range'}), 497 (UnicodeTranslateError, ("\u3042", 0, 1, "ouch"), 498 {'args' : ('\u3042', 0, 1, 'ouch'), 499 'object' : '\u3042', 'reason' : 'ouch', 500 'start' : 0, 'end' : 1}), 501 (NaiveException, ('foo',), 502 {'args': ('foo',), 'x': 'foo'}), 503 (SlottedNaiveException, ('foo',), 504 {'args': ('foo',), 'x': 'foo'}), 505 ] 506 try: 507 # More tests are in test_WindowsError 508 exceptionList.append( 509 (WindowsError, (1, 'strErrorStr', 'filenameStr'), 510 {'args' : (1, 'strErrorStr'), 511 'strerror' : 'strErrorStr', 'winerror' : None, 512 'errno' : 1, 513 'filename' : 'filenameStr', 'filename2' : None}) 514 ) 515 except NameError: 516 pass 517 518 for exc, args, expected in exceptionList: 519 try: 520 e = exc(*args) 521 except: 522 print("\nexc=%r, args=%r" % (exc, args), file=sys.stderr) 523 # raise 524 else: 525 # Verify module name 526 if not type(e).__name__.endswith('NaiveException'): 527 self.assertEqual(type(e).__module__, 'builtins') 528 # Verify no ref leaks in Exc_str() 529 s = str(e) 530 for checkArgName in expected: 531 value = getattr(e, checkArgName) 532 self.assertEqual(repr(value), 533 repr(expected[checkArgName]), 534 '%r.%s == %r, expected %r' % ( 535 e, checkArgName, 536 value, expected[checkArgName])) 537 538 # test for pickling support 539 for p in [pickle]: 540 for protocol in range(p.HIGHEST_PROTOCOL + 1): 541 s = p.dumps(e, protocol) 542 new = p.loads(s) 543 for checkArgName in expected: 544 got = repr(getattr(new, checkArgName)) 545 want = repr(expected[checkArgName]) 546 self.assertEqual(got, want, 547 'pickled "%r", attribute "%s' % 548 (e, checkArgName)) 549 550 def test_notes(self): 551 for e in [BaseException(1), Exception(2), ValueError(3)]: 552 with self.subTest(e=e): 553 self.assertFalse(hasattr(e, '__notes__')) 554 e.add_note("My Note") 555 self.assertEqual(e.__notes__, ["My Note"]) 556 557 with self.assertRaises(TypeError): 558 e.add_note(42) 559 self.assertEqual(e.__notes__, ["My Note"]) 560 561 e.add_note("Your Note") 562 self.assertEqual(e.__notes__, ["My Note", "Your Note"]) 563 564 del e.__notes__ 565 self.assertFalse(hasattr(e, '__notes__')) 566 567 e.add_note("Our Note") 568 self.assertEqual(e.__notes__, ["Our Note"]) 569 570 e.__notes__ = 42 571 self.assertEqual(e.__notes__, 42) 572 573 with self.assertRaises(TypeError): 574 e.add_note("will not work") 575 self.assertEqual(e.__notes__, 42) 576 577 def testWithTraceback(self): 578 try: 579 raise IndexError(4) 580 except: 581 tb = sys.exc_info()[2] 582 583 e = BaseException().with_traceback(tb) 584 self.assertIsInstance(e, BaseException) 585 self.assertEqual(e.__traceback__, tb) 586 587 e = IndexError(5).with_traceback(tb) 588 self.assertIsInstance(e, IndexError) 589 self.assertEqual(e.__traceback__, tb) 590 591 class MyException(Exception): 592 pass 593 594 e = MyException().with_traceback(tb) 595 self.assertIsInstance(e, MyException) 596 self.assertEqual(e.__traceback__, tb) 597 598 def testInvalidTraceback(self): 599 try: 600 Exception().__traceback__ = 5 601 except TypeError as e: 602 self.assertIn("__traceback__ must be a traceback", str(e)) 603 else: 604 self.fail("No exception raised") 605 606 def testInvalidAttrs(self): 607 self.assertRaises(TypeError, setattr, Exception(), '__cause__', 1) 608 self.assertRaises(TypeError, delattr, Exception(), '__cause__') 609 self.assertRaises(TypeError, setattr, Exception(), '__context__', 1) 610 self.assertRaises(TypeError, delattr, Exception(), '__context__') 611 612 def testNoneClearsTracebackAttr(self): 613 try: 614 raise IndexError(4) 615 except: 616 tb = sys.exc_info()[2] 617 618 e = Exception() 619 e.__traceback__ = tb 620 e.__traceback__ = None 621 self.assertEqual(e.__traceback__, None) 622 623 def testChainingAttrs(self): 624 e = Exception() 625 self.assertIsNone(e.__context__) 626 self.assertIsNone(e.__cause__) 627 628 e = TypeError() 629 self.assertIsNone(e.__context__) 630 self.assertIsNone(e.__cause__) 631 632 class MyException(OSError): 633 pass 634 635 e = MyException() 636 self.assertIsNone(e.__context__) 637 self.assertIsNone(e.__cause__) 638 639 def testChainingDescriptors(self): 640 try: 641 raise Exception() 642 except Exception as exc: 643 e = exc 644 645 self.assertIsNone(e.__context__) 646 self.assertIsNone(e.__cause__) 647 self.assertFalse(e.__suppress_context__) 648 649 e.__context__ = NameError() 650 e.__cause__ = None 651 self.assertIsInstance(e.__context__, NameError) 652 self.assertIsNone(e.__cause__) 653 self.assertTrue(e.__suppress_context__) 654 e.__suppress_context__ = False 655 self.assertFalse(e.__suppress_context__) 656 657 def testKeywordArgs(self): 658 # test that builtin exception don't take keyword args, 659 # but user-defined subclasses can if they want 660 self.assertRaises(TypeError, BaseException, a=1) 661 662 class DerivedException(BaseException): 663 def __init__(self, fancy_arg): 664 BaseException.__init__(self) 665 self.fancy_arg = fancy_arg 666 667 x = DerivedException(fancy_arg=42) 668 self.assertEqual(x.fancy_arg, 42) 669 670 @no_tracing 671 def testInfiniteRecursion(self): 672 def f(): 673 return f() 674 self.assertRaises(RecursionError, f) 675 676 def g(): 677 try: 678 return g() 679 except ValueError: 680 return -1 681 self.assertRaises(RecursionError, g) 682 683 def test_str(self): 684 # Make sure both instances and classes have a str representation. 685 self.assertTrue(str(Exception)) 686 self.assertTrue(str(Exception('a'))) 687 self.assertTrue(str(Exception('a', 'b'))) 688 689 def test_exception_cleanup_names(self): 690 # Make sure the local variable bound to the exception instance by 691 # an "except" statement is only visible inside the except block. 692 try: 693 raise Exception() 694 except Exception as e: 695 self.assertIsInstance(e, Exception) 696 self.assertNotIn('e', locals()) 697 with self.assertRaises(UnboundLocalError): 698 e 699 700 def test_exception_cleanup_names2(self): 701 # Make sure the cleanup doesn't break if the variable is explicitly deleted. 702 try: 703 raise Exception() 704 except Exception as e: 705 self.assertIsInstance(e, Exception) 706 del e 707 self.assertNotIn('e', locals()) 708 with self.assertRaises(UnboundLocalError): 709 e 710 711 def testExceptionCleanupState(self): 712 # Make sure exception state is cleaned up as soon as the except 713 # block is left. See #2507 714 715 class MyException(Exception): 716 def __init__(self, obj): 717 self.obj = obj 718 class MyObj: 719 pass 720 721 def inner_raising_func(): 722 # Create some references in exception value and traceback 723 local_ref = obj 724 raise MyException(obj) 725 726 # Qualified "except" with "as" 727 obj = MyObj() 728 wr = weakref.ref(obj) 729 try: 730 inner_raising_func() 731 except MyException as e: 732 pass 733 obj = None 734 gc_collect() # For PyPy or other GCs. 735 obj = wr() 736 self.assertIsNone(obj) 737 738 # Qualified "except" without "as" 739 obj = MyObj() 740 wr = weakref.ref(obj) 741 try: 742 inner_raising_func() 743 except MyException: 744 pass 745 obj = None 746 gc_collect() # For PyPy or other GCs. 747 obj = wr() 748 self.assertIsNone(obj) 749 750 # Bare "except" 751 obj = MyObj() 752 wr = weakref.ref(obj) 753 try: 754 inner_raising_func() 755 except: 756 pass 757 obj = None 758 gc_collect() # For PyPy or other GCs. 759 obj = wr() 760 self.assertIsNone(obj) 761 762 # "except" with premature block leave 763 obj = MyObj() 764 wr = weakref.ref(obj) 765 for i in [0]: 766 try: 767 inner_raising_func() 768 except: 769 break 770 obj = None 771 gc_collect() # For PyPy or other GCs. 772 obj = wr() 773 self.assertIsNone(obj) 774 775 # "except" block raising another exception 776 obj = MyObj() 777 wr = weakref.ref(obj) 778 try: 779 try: 780 inner_raising_func() 781 except: 782 raise KeyError 783 except KeyError as e: 784 # We want to test that the except block above got rid of 785 # the exception raised in inner_raising_func(), but it 786 # also ends up in the __context__ of the KeyError, so we 787 # must clear the latter manually for our test to succeed. 788 e.__context__ = None 789 obj = None 790 gc_collect() # For PyPy or other GCs. 791 obj = wr() 792 # guarantee no ref cycles on CPython (don't gc_collect) 793 if check_impl_detail(cpython=False): 794 gc_collect() 795 self.assertIsNone(obj) 796 797 # Some complicated construct 798 obj = MyObj() 799 wr = weakref.ref(obj) 800 try: 801 inner_raising_func() 802 except MyException: 803 try: 804 try: 805 raise 806 finally: 807 raise 808 except MyException: 809 pass 810 obj = None 811 if check_impl_detail(cpython=False): 812 gc_collect() 813 obj = wr() 814 self.assertIsNone(obj) 815 816 # Inside an exception-silencing "with" block 817 class Context: 818 def __enter__(self): 819 return self 820 def __exit__ (self, exc_type, exc_value, exc_tb): 821 return True 822 obj = MyObj() 823 wr = weakref.ref(obj) 824 with Context(): 825 inner_raising_func() 826 obj = None 827 if check_impl_detail(cpython=False): 828 gc_collect() 829 obj = wr() 830 self.assertIsNone(obj) 831 832 def test_exception_target_in_nested_scope(self): 833 # issue 4617: This used to raise a SyntaxError 834 # "can not delete variable 'e' referenced in nested scope" 835 def print_error(): 836 e 837 try: 838 something 839 except Exception as e: 840 print_error() 841 # implicit "del e" here 842 843 def test_generator_leaking(self): 844 # Test that generator exception state doesn't leak into the calling 845 # frame 846 def yield_raise(): 847 try: 848 raise KeyError("caught") 849 except KeyError: 850 yield sys.exc_info()[0] 851 yield sys.exc_info()[0] 852 yield sys.exc_info()[0] 853 g = yield_raise() 854 self.assertEqual(next(g), KeyError) 855 self.assertEqual(sys.exc_info()[0], None) 856 self.assertEqual(next(g), KeyError) 857 self.assertEqual(sys.exc_info()[0], None) 858 self.assertEqual(next(g), None) 859 860 # Same test, but inside an exception handler 861 try: 862 raise TypeError("foo") 863 except TypeError: 864 g = yield_raise() 865 self.assertEqual(next(g), KeyError) 866 self.assertEqual(sys.exc_info()[0], TypeError) 867 self.assertEqual(next(g), KeyError) 868 self.assertEqual(sys.exc_info()[0], TypeError) 869 self.assertEqual(next(g), TypeError) 870 del g 871 self.assertEqual(sys.exc_info()[0], TypeError) 872 873 def test_generator_leaking2(self): 874 # See issue 12475. 875 def g(): 876 yield 877 try: 878 raise RuntimeError 879 except RuntimeError: 880 it = g() 881 next(it) 882 try: 883 next(it) 884 except StopIteration: 885 pass 886 self.assertEqual(sys.exc_info(), (None, None, None)) 887 888 def test_generator_leaking3(self): 889 # See issue #23353. When gen.throw() is called, the caller's 890 # exception state should be save and restored. 891 def g(): 892 try: 893 yield 894 except ZeroDivisionError: 895 yield sys.exc_info()[1] 896 it = g() 897 next(it) 898 try: 899 1/0 900 except ZeroDivisionError as e: 901 self.assertIs(sys.exc_info()[1], e) 902 gen_exc = it.throw(e) 903 self.assertIs(sys.exc_info()[1], e) 904 self.assertIs(gen_exc, e) 905 self.assertEqual(sys.exc_info(), (None, None, None)) 906 907 def test_generator_leaking4(self): 908 # See issue #23353. When an exception is raised by a generator, 909 # the caller's exception state should still be restored. 910 def g(): 911 try: 912 1/0 913 except ZeroDivisionError: 914 yield sys.exc_info()[0] 915 raise 916 it = g() 917 try: 918 raise TypeError 919 except TypeError: 920 # The caller's exception state (TypeError) is temporarily 921 # saved in the generator. 922 tp = next(it) 923 self.assertIs(tp, ZeroDivisionError) 924 try: 925 next(it) 926 # We can't check it immediately, but while next() returns 927 # with an exception, it shouldn't have restored the old 928 # exception state (TypeError). 929 except ZeroDivisionError as e: 930 self.assertIs(sys.exc_info()[1], e) 931 # We used to find TypeError here. 932 self.assertEqual(sys.exc_info(), (None, None, None)) 933 934 def test_generator_doesnt_retain_old_exc(self): 935 def g(): 936 self.assertIsInstance(sys.exc_info()[1], RuntimeError) 937 yield 938 self.assertEqual(sys.exc_info(), (None, None, None)) 939 it = g() 940 try: 941 raise RuntimeError 942 except RuntimeError: 943 next(it) 944 self.assertRaises(StopIteration, next, it) 945 946 def test_generator_finalizing_and_exc_info(self): 947 # See #7173 948 def simple_gen(): 949 yield 1 950 def run_gen(): 951 gen = simple_gen() 952 try: 953 raise RuntimeError 954 except RuntimeError: 955 return next(gen) 956 run_gen() 957 gc_collect() 958 self.assertEqual(sys.exc_info(), (None, None, None)) 959 960 def _check_generator_cleanup_exc_state(self, testfunc): 961 # Issue #12791: exception state is cleaned up as soon as a generator 962 # is closed (reference cycles are broken). 963 class MyException(Exception): 964 def __init__(self, obj): 965 self.obj = obj 966 class MyObj: 967 pass 968 969 def raising_gen(): 970 try: 971 raise MyException(obj) 972 except MyException: 973 yield 974 975 obj = MyObj() 976 wr = weakref.ref(obj) 977 g = raising_gen() 978 next(g) 979 testfunc(g) 980 g = obj = None 981 gc_collect() # For PyPy or other GCs. 982 obj = wr() 983 self.assertIsNone(obj) 984 985 def test_generator_throw_cleanup_exc_state(self): 986 def do_throw(g): 987 try: 988 g.throw(RuntimeError()) 989 except RuntimeError: 990 pass 991 self._check_generator_cleanup_exc_state(do_throw) 992 993 def test_generator_close_cleanup_exc_state(self): 994 def do_close(g): 995 g.close() 996 self._check_generator_cleanup_exc_state(do_close) 997 998 def test_generator_del_cleanup_exc_state(self): 999 def do_del(g): 1000 g = None 1001 self._check_generator_cleanup_exc_state(do_del) 1002 1003 def test_generator_next_cleanup_exc_state(self): 1004 def do_next(g): 1005 try: 1006 next(g) 1007 except StopIteration: 1008 pass 1009 else: 1010 self.fail("should have raised StopIteration") 1011 self._check_generator_cleanup_exc_state(do_next) 1012 1013 def test_generator_send_cleanup_exc_state(self): 1014 def do_send(g): 1015 try: 1016 g.send(None) 1017 except StopIteration: 1018 pass 1019 else: 1020 self.fail("should have raised StopIteration") 1021 self._check_generator_cleanup_exc_state(do_send) 1022 1023 def test_3114(self): 1024 # Bug #3114: in its destructor, MyObject retrieves a pointer to 1025 # obsolete and/or deallocated objects. 1026 class MyObject: 1027 def __del__(self): 1028 nonlocal e 1029 e = sys.exc_info() 1030 e = () 1031 try: 1032 raise Exception(MyObject()) 1033 except: 1034 pass 1035 gc_collect() # For PyPy or other GCs. 1036 self.assertEqual(e, (None, None, None)) 1037 1038 def test_raise_does_not_create_context_chain_cycle(self): 1039 class A(Exception): 1040 pass 1041 class B(Exception): 1042 pass 1043 class C(Exception): 1044 pass 1045 1046 # Create a context chain: 1047 # C -> B -> A 1048 # Then raise A in context of C. 1049 try: 1050 try: 1051 raise A 1052 except A as a_: 1053 a = a_ 1054 try: 1055 raise B 1056 except B as b_: 1057 b = b_ 1058 try: 1059 raise C 1060 except C as c_: 1061 c = c_ 1062 self.assertIsInstance(a, A) 1063 self.assertIsInstance(b, B) 1064 self.assertIsInstance(c, C) 1065 self.assertIsNone(a.__context__) 1066 self.assertIs(b.__context__, a) 1067 self.assertIs(c.__context__, b) 1068 raise a 1069 except A as e: 1070 exc = e 1071 1072 # Expect A -> C -> B, without cycle 1073 self.assertIs(exc, a) 1074 self.assertIs(a.__context__, c) 1075 self.assertIs(c.__context__, b) 1076 self.assertIsNone(b.__context__) 1077 1078 def test_no_hang_on_context_chain_cycle1(self): 1079 # See issue 25782. Cycle in context chain. 1080 1081 def cycle(): 1082 try: 1083 raise ValueError(1) 1084 except ValueError as ex: 1085 ex.__context__ = ex 1086 raise TypeError(2) 1087 1088 try: 1089 cycle() 1090 except Exception as e: 1091 exc = e 1092 1093 self.assertIsInstance(exc, TypeError) 1094 self.assertIsInstance(exc.__context__, ValueError) 1095 self.assertIs(exc.__context__.__context__, exc.__context__) 1096 1097 @unittest.skip("See issue 44895") 1098 def test_no_hang_on_context_chain_cycle2(self): 1099 # See issue 25782. Cycle at head of context chain. 1100 1101 class A(Exception): 1102 pass 1103 class B(Exception): 1104 pass 1105 class C(Exception): 1106 pass 1107 1108 # Context cycle: 1109 # +-----------+ 1110 # V | 1111 # C --> B --> A 1112 with self.assertRaises(C) as cm: 1113 try: 1114 raise A() 1115 except A as _a: 1116 a = _a 1117 try: 1118 raise B() 1119 except B as _b: 1120 b = _b 1121 try: 1122 raise C() 1123 except C as _c: 1124 c = _c 1125 a.__context__ = c 1126 raise c 1127 1128 self.assertIs(cm.exception, c) 1129 # Verify the expected context chain cycle 1130 self.assertIs(c.__context__, b) 1131 self.assertIs(b.__context__, a) 1132 self.assertIs(a.__context__, c) 1133 1134 def test_no_hang_on_context_chain_cycle3(self): 1135 # See issue 25782. Longer context chain with cycle. 1136 1137 class A(Exception): 1138 pass 1139 class B(Exception): 1140 pass 1141 class C(Exception): 1142 pass 1143 class D(Exception): 1144 pass 1145 class E(Exception): 1146 pass 1147 1148 # Context cycle: 1149 # +-----------+ 1150 # V | 1151 # E --> D --> C --> B --> A 1152 with self.assertRaises(E) as cm: 1153 try: 1154 raise A() 1155 except A as _a: 1156 a = _a 1157 try: 1158 raise B() 1159 except B as _b: 1160 b = _b 1161 try: 1162 raise C() 1163 except C as _c: 1164 c = _c 1165 a.__context__ = c 1166 try: 1167 raise D() 1168 except D as _d: 1169 d = _d 1170 e = E() 1171 raise e 1172 1173 self.assertIs(cm.exception, e) 1174 # Verify the expected context chain cycle 1175 self.assertIs(e.__context__, d) 1176 self.assertIs(d.__context__, c) 1177 self.assertIs(c.__context__, b) 1178 self.assertIs(b.__context__, a) 1179 self.assertIs(a.__context__, c) 1180 1181 def test_context_of_exception_in_try_and_finally(self): 1182 try: 1183 try: 1184 te = TypeError(1) 1185 raise te 1186 finally: 1187 ve = ValueError(2) 1188 raise ve 1189 except Exception as e: 1190 exc = e 1191 1192 self.assertIs(exc, ve) 1193 self.assertIs(exc.__context__, te) 1194 1195 def test_context_of_exception_in_except_and_finally(self): 1196 try: 1197 try: 1198 te = TypeError(1) 1199 raise te 1200 except: 1201 ve = ValueError(2) 1202 raise ve 1203 finally: 1204 oe = OSError(3) 1205 raise oe 1206 except Exception as e: 1207 exc = e 1208 1209 self.assertIs(exc, oe) 1210 self.assertIs(exc.__context__, ve) 1211 self.assertIs(exc.__context__.__context__, te) 1212 1213 def test_context_of_exception_in_else_and_finally(self): 1214 try: 1215 try: 1216 pass 1217 except: 1218 pass 1219 else: 1220 ve = ValueError(1) 1221 raise ve 1222 finally: 1223 oe = OSError(2) 1224 raise oe 1225 except Exception as e: 1226 exc = e 1227 1228 self.assertIs(exc, oe) 1229 self.assertIs(exc.__context__, ve) 1230 1231 def test_unicode_change_attributes(self): 1232 # See issue 7309. This was a crasher. 1233 1234 u = UnicodeEncodeError('baz', 'xxxxx', 1, 5, 'foo') 1235 self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: foo") 1236 u.end = 2 1237 self.assertEqual(str(u), "'baz' codec can't encode character '\\x78' in position 1: foo") 1238 u.end = 5 1239 u.reason = 0x345345345345345345 1240 self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: 965230951443685724997") 1241 u.encoding = 4000 1242 self.assertEqual(str(u), "'4000' codec can't encode characters in position 1-4: 965230951443685724997") 1243 u.start = 1000 1244 self.assertEqual(str(u), "'4000' codec can't encode characters in position 1000-4: 965230951443685724997") 1245 1246 u = UnicodeDecodeError('baz', b'xxxxx', 1, 5, 'foo') 1247 self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: foo") 1248 u.end = 2 1249 self.assertEqual(str(u), "'baz' codec can't decode byte 0x78 in position 1: foo") 1250 u.end = 5 1251 u.reason = 0x345345345345345345 1252 self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: 965230951443685724997") 1253 u.encoding = 4000 1254 self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1-4: 965230951443685724997") 1255 u.start = 1000 1256 self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1000-4: 965230951443685724997") 1257 1258 u = UnicodeTranslateError('xxxx', 1, 5, 'foo') 1259 self.assertEqual(str(u), "can't translate characters in position 1-4: foo") 1260 u.end = 2 1261 self.assertEqual(str(u), "can't translate character '\\x78' in position 1: foo") 1262 u.end = 5 1263 u.reason = 0x345345345345345345 1264 self.assertEqual(str(u), "can't translate characters in position 1-4: 965230951443685724997") 1265 u.start = 1000 1266 self.assertEqual(str(u), "can't translate characters in position 1000-4: 965230951443685724997") 1267 1268 def test_unicode_errors_no_object(self): 1269 # See issue #21134. 1270 klasses = UnicodeEncodeError, UnicodeDecodeError, UnicodeTranslateError 1271 for klass in klasses: 1272 self.assertEqual(str(klass.__new__(klass)), "") 1273 1274 @no_tracing 1275 def test_badisinstance(self): 1276 # Bug #2542: if issubclass(e, MyException) raises an exception, 1277 # it should be ignored 1278 class Meta(type): 1279 def __subclasscheck__(cls, subclass): 1280 raise ValueError() 1281 class MyException(Exception, metaclass=Meta): 1282 pass 1283 1284 with captured_stderr() as stderr: 1285 try: 1286 raise KeyError() 1287 except MyException as e: 1288 self.fail("exception should not be a MyException") 1289 except KeyError: 1290 pass 1291 except: 1292 self.fail("Should have raised KeyError") 1293 else: 1294 self.fail("Should have raised KeyError") 1295 1296 def g(): 1297 try: 1298 return g() 1299 except RecursionError: 1300 return sys.exc_info() 1301 e, v, tb = g() 1302 self.assertIsInstance(v, RecursionError, type(v)) 1303 self.assertIn("maximum recursion depth exceeded", str(v)) 1304 1305 1306 @cpython_only 1307 def test_trashcan_recursion(self): 1308 # See bpo-33930 1309 1310 def foo(): 1311 o = object() 1312 for x in range(1_000_000): 1313 # Create a big chain of method objects that will trigger 1314 # a deep chain of calls when they need to be destructed. 1315 o = o.__dir__ 1316 1317 foo() 1318 support.gc_collect() 1319 1320 @cpython_only 1321 def test_recursion_normalizing_exception(self): 1322 # Issue #22898. 1323 # Test that a RecursionError is raised when tstate->recursion_depth is 1324 # equal to recursion_limit in PyErr_NormalizeException() and check 1325 # that a ResourceWarning is printed. 1326 # Prior to #22898, the recursivity of PyErr_NormalizeException() was 1327 # controlled by tstate->recursion_depth and a PyExc_RecursionErrorInst 1328 # singleton was being used in that case, that held traceback data and 1329 # locals indefinitely and would cause a segfault in _PyExc_Fini() upon 1330 # finalization of these locals. 1331 code = """if 1: 1332 import sys 1333 from _testinternalcapi import get_recursion_depth 1334 1335 class MyException(Exception): pass 1336 1337 def setrecursionlimit(depth): 1338 while 1: 1339 try: 1340 sys.setrecursionlimit(depth) 1341 return depth 1342 except RecursionError: 1343 # sys.setrecursionlimit() raises a RecursionError if 1344 # the new recursion limit is too low (issue #25274). 1345 depth += 1 1346 1347 def recurse(cnt): 1348 cnt -= 1 1349 if cnt: 1350 recurse(cnt) 1351 else: 1352 generator.throw(MyException) 1353 1354 def gen(): 1355 f = open(%a, mode='rb', buffering=0) 1356 yield 1357 1358 generator = gen() 1359 next(generator) 1360 recursionlimit = sys.getrecursionlimit() 1361 depth = get_recursion_depth() 1362 try: 1363 # Upon the last recursive invocation of recurse(), 1364 # tstate->recursion_depth is equal to (recursion_limit - 1) 1365 # and is equal to recursion_limit when _gen_throw() calls 1366 # PyErr_NormalizeException(). 1367 recurse(setrecursionlimit(depth + 2) - depth) 1368 finally: 1369 sys.setrecursionlimit(recursionlimit) 1370 print('Done.') 1371 """ % __file__ 1372 rc, out, err = script_helper.assert_python_failure("-Wd", "-c", code) 1373 # Check that the program does not fail with SIGABRT. 1374 self.assertEqual(rc, 1) 1375 self.assertIn(b'RecursionError', err) 1376 self.assertIn(b'ResourceWarning', err) 1377 self.assertIn(b'Done.', out) 1378 1379 @cpython_only 1380 def test_recursion_normalizing_infinite_exception(self): 1381 # Issue #30697. Test that a RecursionError is raised when 1382 # PyErr_NormalizeException() maximum recursion depth has been 1383 # exceeded. 1384 code = """if 1: 1385 import _testcapi 1386 try: 1387 raise _testcapi.RecursingInfinitelyError 1388 finally: 1389 print('Done.') 1390 """ 1391 rc, out, err = script_helper.assert_python_failure("-c", code) 1392 self.assertEqual(rc, 1) 1393 self.assertIn(b'RecursionError: maximum recursion depth exceeded ' 1394 b'while normalizing an exception', err) 1395 self.assertIn(b'Done.', out) 1396 1397 1398 def test_recursion_in_except_handler(self): 1399 1400 def set_relative_recursion_limit(n): 1401 depth = 1 1402 while True: 1403 try: 1404 sys.setrecursionlimit(depth) 1405 except RecursionError: 1406 depth += 1 1407 else: 1408 break 1409 sys.setrecursionlimit(depth+n) 1410 1411 def recurse_in_except(): 1412 try: 1413 1/0 1414 except: 1415 recurse_in_except() 1416 1417 def recurse_after_except(): 1418 try: 1419 1/0 1420 except: 1421 pass 1422 recurse_after_except() 1423 1424 def recurse_in_body_and_except(): 1425 try: 1426 recurse_in_body_and_except() 1427 except: 1428 recurse_in_body_and_except() 1429 1430 recursionlimit = sys.getrecursionlimit() 1431 try: 1432 set_relative_recursion_limit(10) 1433 for func in (recurse_in_except, recurse_after_except, recurse_in_body_and_except): 1434 with self.subTest(func=func): 1435 try: 1436 func() 1437 except RecursionError: 1438 pass 1439 else: 1440 self.fail("Should have raised a RecursionError") 1441 finally: 1442 sys.setrecursionlimit(recursionlimit) 1443 1444 1445 @cpython_only 1446 def test_recursion_normalizing_with_no_memory(self): 1447 # Issue #30697. Test that in the abort that occurs when there is no 1448 # memory left and the size of the Python frames stack is greater than 1449 # the size of the list of preallocated MemoryError instances, the 1450 # Fatal Python error message mentions MemoryError. 1451 code = """if 1: 1452 import _testcapi 1453 class C(): pass 1454 def recurse(cnt): 1455 cnt -= 1 1456 if cnt: 1457 recurse(cnt) 1458 else: 1459 _testcapi.set_nomemory(0) 1460 C() 1461 recurse(16) 1462 """ 1463 with SuppressCrashReport(): 1464 rc, out, err = script_helper.assert_python_failure("-c", code) 1465 self.assertIn(b'MemoryError', err) 1466 1467 @cpython_only 1468 def test_MemoryError(self): 1469 # PyErr_NoMemory always raises the same exception instance. 1470 # Check that the traceback is not doubled. 1471 import traceback 1472 from _testcapi import raise_memoryerror 1473 def raiseMemError(): 1474 try: 1475 raise_memoryerror() 1476 except MemoryError as e: 1477 tb = e.__traceback__ 1478 else: 1479 self.fail("Should have raised a MemoryError") 1480 return traceback.format_tb(tb) 1481 1482 tb1 = raiseMemError() 1483 tb2 = raiseMemError() 1484 self.assertEqual(tb1, tb2) 1485 1486 @cpython_only 1487 def test_exception_with_doc(self): 1488 import _testcapi 1489 doc2 = "This is a test docstring." 1490 doc4 = "This is another test docstring." 1491 1492 self.assertRaises(SystemError, _testcapi.make_exception_with_doc, 1493 "error1") 1494 1495 # test basic usage of PyErr_NewException 1496 error1 = _testcapi.make_exception_with_doc("_testcapi.error1") 1497 self.assertIs(type(error1), type) 1498 self.assertTrue(issubclass(error1, Exception)) 1499 self.assertIsNone(error1.__doc__) 1500 1501 # test with given docstring 1502 error2 = _testcapi.make_exception_with_doc("_testcapi.error2", doc2) 1503 self.assertEqual(error2.__doc__, doc2) 1504 1505 # test with explicit base (without docstring) 1506 error3 = _testcapi.make_exception_with_doc("_testcapi.error3", 1507 base=error2) 1508 self.assertTrue(issubclass(error3, error2)) 1509 1510 # test with explicit base tuple 1511 class C(object): 1512 pass 1513 error4 = _testcapi.make_exception_with_doc("_testcapi.error4", doc4, 1514 (error3, C)) 1515 self.assertTrue(issubclass(error4, error3)) 1516 self.assertTrue(issubclass(error4, C)) 1517 self.assertEqual(error4.__doc__, doc4) 1518 1519 # test with explicit dictionary 1520 error5 = _testcapi.make_exception_with_doc("_testcapi.error5", "", 1521 error4, {'a': 1}) 1522 self.assertTrue(issubclass(error5, error4)) 1523 self.assertEqual(error5.a, 1) 1524 self.assertEqual(error5.__doc__, "") 1525 1526 @cpython_only 1527 def test_memory_error_cleanup(self): 1528 # Issue #5437: preallocated MemoryError instances should not keep 1529 # traceback objects alive. 1530 from _testcapi import raise_memoryerror 1531 class C: 1532 pass 1533 wr = None 1534 def inner(): 1535 nonlocal wr 1536 c = C() 1537 wr = weakref.ref(c) 1538 raise_memoryerror() 1539 # We cannot use assertRaises since it manually deletes the traceback 1540 try: 1541 inner() 1542 except MemoryError as e: 1543 self.assertNotEqual(wr(), None) 1544 else: 1545 self.fail("MemoryError not raised") 1546 gc_collect() # For PyPy or other GCs. 1547 self.assertEqual(wr(), None) 1548 1549 @no_tracing 1550 def test_recursion_error_cleanup(self): 1551 # Same test as above, but with "recursion exceeded" errors 1552 class C: 1553 pass 1554 wr = None 1555 def inner(): 1556 nonlocal wr 1557 c = C() 1558 wr = weakref.ref(c) 1559 inner() 1560 # We cannot use assertRaises since it manually deletes the traceback 1561 try: 1562 inner() 1563 except RecursionError as e: 1564 self.assertNotEqual(wr(), None) 1565 else: 1566 self.fail("RecursionError not raised") 1567 gc_collect() # For PyPy or other GCs. 1568 self.assertEqual(wr(), None) 1569 1570 def test_errno_ENOTDIR(self): 1571 # Issue #12802: "not a directory" errors are ENOTDIR even on Windows 1572 with self.assertRaises(OSError) as cm: 1573 os.listdir(__file__) 1574 self.assertEqual(cm.exception.errno, errno.ENOTDIR, cm.exception) 1575 1576 def test_unraisable(self): 1577 # Issue #22836: PyErr_WriteUnraisable() should give sensible reports 1578 class BrokenDel: 1579 def __del__(self): 1580 exc = ValueError("del is broken") 1581 # The following line is included in the traceback report: 1582 raise exc 1583 1584 obj = BrokenDel() 1585 with support.catch_unraisable_exception() as cm: 1586 del obj 1587 1588 gc_collect() # For PyPy or other GCs. 1589 self.assertEqual(cm.unraisable.object, BrokenDel.__del__) 1590 self.assertIsNotNone(cm.unraisable.exc_traceback) 1591 1592 def test_unhandled(self): 1593 # Check for sensible reporting of unhandled exceptions 1594 for exc_type in (ValueError, BrokenStrException): 1595 with self.subTest(exc_type): 1596 try: 1597 exc = exc_type("test message") 1598 # The following line is included in the traceback report: 1599 raise exc 1600 except exc_type: 1601 with captured_stderr() as stderr: 1602 sys.__excepthook__(*sys.exc_info()) 1603 report = stderr.getvalue() 1604 self.assertIn("test_exceptions.py", report) 1605 self.assertIn("raise exc", report) 1606 self.assertIn(exc_type.__name__, report) 1607 if exc_type is BrokenStrException: 1608 self.assertIn("<exception str() failed>", report) 1609 else: 1610 self.assertIn("test message", report) 1611 self.assertTrue(report.endswith("\n")) 1612 1613 @cpython_only 1614 def test_memory_error_in_PyErr_PrintEx(self): 1615 code = """if 1: 1616 import _testcapi 1617 class C(): pass 1618 _testcapi.set_nomemory(0, %d) 1619 C() 1620 """ 1621 1622 # Issue #30817: Abort in PyErr_PrintEx() when no memory. 1623 # Span a large range of tests as the CPython code always evolves with 1624 # changes that add or remove memory allocations. 1625 for i in range(1, 20): 1626 rc, out, err = script_helper.assert_python_failure("-c", code % i) 1627 self.assertIn(rc, (1, 120)) 1628 self.assertIn(b'MemoryError', err) 1629 1630 def test_yield_in_nested_try_excepts(self): 1631 #Issue #25612 1632 class MainError(Exception): 1633 pass 1634 1635 class SubError(Exception): 1636 pass 1637 1638 def main(): 1639 try: 1640 raise MainError() 1641 except MainError: 1642 try: 1643 yield 1644 except SubError: 1645 pass 1646 raise 1647 1648 coro = main() 1649 coro.send(None) 1650 with self.assertRaises(MainError): 1651 coro.throw(SubError()) 1652 1653 def test_generator_doesnt_retain_old_exc2(self): 1654 #Issue 28884#msg282532 1655 def g(): 1656 try: 1657 raise ValueError 1658 except ValueError: 1659 yield 1 1660 self.assertEqual(sys.exc_info(), (None, None, None)) 1661 yield 2 1662 1663 gen = g() 1664 1665 try: 1666 raise IndexError 1667 except IndexError: 1668 self.assertEqual(next(gen), 1) 1669 self.assertEqual(next(gen), 2) 1670 1671 def test_raise_in_generator(self): 1672 #Issue 25612#msg304117 1673 def g(): 1674 yield 1 1675 raise 1676 yield 2 1677 1678 with self.assertRaises(ZeroDivisionError): 1679 i = g() 1680 try: 1681 1/0 1682 except: 1683 next(i) 1684 next(i) 1685 1686 @unittest.skipUnless(__debug__, "Won't work if __debug__ is False") 1687 def test_assert_shadowing(self): 1688 # Shadowing AssertionError would cause the assert statement to 1689 # misbehave. 1690 global AssertionError 1691 AssertionError = TypeError 1692 try: 1693 assert False, 'hello' 1694 except BaseException as e: 1695 del AssertionError 1696 self.assertIsInstance(e, AssertionError) 1697 self.assertEqual(str(e), 'hello') 1698 else: 1699 del AssertionError 1700 self.fail('Expected exception') 1701 1702 def test_memory_error_subclasses(self): 1703 # bpo-41654: MemoryError instances use a freelist of objects that are 1704 # linked using the 'dict' attribute when they are inactive/dead. 1705 # Subclasses of MemoryError should not participate in the freelist 1706 # schema. This test creates a MemoryError object and keeps it alive 1707 # (therefore advancing the freelist) and then it creates and destroys a 1708 # subclass object. Finally, it checks that creating a new MemoryError 1709 # succeeds, proving that the freelist is not corrupted. 1710 1711 class TestException(MemoryError): 1712 pass 1713 1714 try: 1715 raise MemoryError 1716 except MemoryError as exc: 1717 inst = exc 1718 1719 try: 1720 raise TestException 1721 except Exception: 1722 pass 1723 1724 for _ in range(10): 1725 try: 1726 raise MemoryError 1727 except MemoryError as exc: 1728 pass 1729 1730 gc_collect() 1731 1732global_for_suggestions = None 1733 1734class NameErrorTests(unittest.TestCase): 1735 def test_name_error_has_name(self): 1736 try: 1737 bluch 1738 except NameError as exc: 1739 self.assertEqual("bluch", exc.name) 1740 1741 def test_name_error_suggestions(self): 1742 def Substitution(): 1743 noise = more_noise = a = bc = None 1744 blech = None 1745 print(bluch) 1746 1747 def Elimination(): 1748 noise = more_noise = a = bc = None 1749 blch = None 1750 print(bluch) 1751 1752 def Addition(): 1753 noise = more_noise = a = bc = None 1754 bluchin = None 1755 print(bluch) 1756 1757 def SubstitutionOverElimination(): 1758 blach = None 1759 bluc = None 1760 print(bluch) 1761 1762 def SubstitutionOverAddition(): 1763 blach = None 1764 bluchi = None 1765 print(bluch) 1766 1767 def EliminationOverAddition(): 1768 blucha = None 1769 bluc = None 1770 print(bluch) 1771 1772 for func, suggestion in [(Substitution, "'blech'?"), 1773 (Elimination, "'blch'?"), 1774 (Addition, "'bluchin'?"), 1775 (EliminationOverAddition, "'blucha'?"), 1776 (SubstitutionOverElimination, "'blach'?"), 1777 (SubstitutionOverAddition, "'blach'?")]: 1778 err = None 1779 try: 1780 func() 1781 except NameError as exc: 1782 with support.captured_stderr() as err: 1783 sys.__excepthook__(*sys.exc_info()) 1784 self.assertIn(suggestion, err.getvalue()) 1785 1786 def test_name_error_suggestions_from_globals(self): 1787 def func(): 1788 print(global_for_suggestio) 1789 try: 1790 func() 1791 except NameError as exc: 1792 with support.captured_stderr() as err: 1793 sys.__excepthook__(*sys.exc_info()) 1794 self.assertIn("'global_for_suggestions'?", err.getvalue()) 1795 1796 def test_name_error_suggestions_from_builtins(self): 1797 def func(): 1798 print(ZeroDivisionErrrrr) 1799 try: 1800 func() 1801 except NameError as exc: 1802 with support.captured_stderr() as err: 1803 sys.__excepthook__(*sys.exc_info()) 1804 self.assertIn("'ZeroDivisionError'?", err.getvalue()) 1805 1806 def test_name_error_suggestions_do_not_trigger_for_long_names(self): 1807 def f(): 1808 somethingverywronghehehehehehe = None 1809 print(somethingverywronghe) 1810 1811 try: 1812 f() 1813 except NameError as exc: 1814 with support.captured_stderr() as err: 1815 sys.__excepthook__(*sys.exc_info()) 1816 1817 self.assertNotIn("somethingverywronghehe", err.getvalue()) 1818 1819 def test_name_error_bad_suggestions_do_not_trigger_for_small_names(self): 1820 vvv = mom = w = id = pytho = None 1821 1822 with self.subTest(name="b"): 1823 try: 1824 b 1825 except NameError as exc: 1826 with support.captured_stderr() as err: 1827 sys.__excepthook__(*sys.exc_info()) 1828 self.assertNotIn("you mean", err.getvalue()) 1829 self.assertNotIn("vvv", err.getvalue()) 1830 self.assertNotIn("mom", err.getvalue()) 1831 self.assertNotIn("'id'", err.getvalue()) 1832 self.assertNotIn("'w'", err.getvalue()) 1833 self.assertNotIn("'pytho'", err.getvalue()) 1834 1835 with self.subTest(name="v"): 1836 try: 1837 v 1838 except NameError as exc: 1839 with support.captured_stderr() as err: 1840 sys.__excepthook__(*sys.exc_info()) 1841 self.assertNotIn("you mean", err.getvalue()) 1842 self.assertNotIn("vvv", err.getvalue()) 1843 self.assertNotIn("mom", err.getvalue()) 1844 self.assertNotIn("'id'", err.getvalue()) 1845 self.assertNotIn("'w'", err.getvalue()) 1846 self.assertNotIn("'pytho'", err.getvalue()) 1847 1848 with self.subTest(name="m"): 1849 try: 1850 m 1851 except NameError as exc: 1852 with support.captured_stderr() as err: 1853 sys.__excepthook__(*sys.exc_info()) 1854 self.assertNotIn("you mean", err.getvalue()) 1855 self.assertNotIn("vvv", err.getvalue()) 1856 self.assertNotIn("mom", err.getvalue()) 1857 self.assertNotIn("'id'", err.getvalue()) 1858 self.assertNotIn("'w'", err.getvalue()) 1859 self.assertNotIn("'pytho'", err.getvalue()) 1860 1861 with self.subTest(name="py"): 1862 try: 1863 py 1864 except NameError as exc: 1865 with support.captured_stderr() as err: 1866 sys.__excepthook__(*sys.exc_info()) 1867 self.assertNotIn("you mean", err.getvalue()) 1868 self.assertNotIn("vvv", err.getvalue()) 1869 self.assertNotIn("mom", err.getvalue()) 1870 self.assertNotIn("'id'", err.getvalue()) 1871 self.assertNotIn("'w'", err.getvalue()) 1872 self.assertNotIn("'pytho'", err.getvalue()) 1873 1874 def test_name_error_suggestions_do_not_trigger_for_too_many_locals(self): 1875 def f(): 1876 # Mutating locals() is unreliable, so we need to do it by hand 1877 a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 = a10 = \ 1878 a11 = a12 = a13 = a14 = a15 = a16 = a17 = a18 = a19 = a20 = \ 1879 a21 = a22 = a23 = a24 = a25 = a26 = a27 = a28 = a29 = a30 = \ 1880 a31 = a32 = a33 = a34 = a35 = a36 = a37 = a38 = a39 = a40 = \ 1881 a41 = a42 = a43 = a44 = a45 = a46 = a47 = a48 = a49 = a50 = \ 1882 a51 = a52 = a53 = a54 = a55 = a56 = a57 = a58 = a59 = a60 = \ 1883 a61 = a62 = a63 = a64 = a65 = a66 = a67 = a68 = a69 = a70 = \ 1884 a71 = a72 = a73 = a74 = a75 = a76 = a77 = a78 = a79 = a80 = \ 1885 a81 = a82 = a83 = a84 = a85 = a86 = a87 = a88 = a89 = a90 = \ 1886 a91 = a92 = a93 = a94 = a95 = a96 = a97 = a98 = a99 = a100 = \ 1887 a101 = a102 = a103 = a104 = a105 = a106 = a107 = a108 = a109 = a110 = \ 1888 a111 = a112 = a113 = a114 = a115 = a116 = a117 = a118 = a119 = a120 = \ 1889 a121 = a122 = a123 = a124 = a125 = a126 = a127 = a128 = a129 = a130 = \ 1890 a131 = a132 = a133 = a134 = a135 = a136 = a137 = a138 = a139 = a140 = \ 1891 a141 = a142 = a143 = a144 = a145 = a146 = a147 = a148 = a149 = a150 = \ 1892 a151 = a152 = a153 = a154 = a155 = a156 = a157 = a158 = a159 = a160 = \ 1893 a161 = a162 = a163 = a164 = a165 = a166 = a167 = a168 = a169 = a170 = \ 1894 a171 = a172 = a173 = a174 = a175 = a176 = a177 = a178 = a179 = a180 = \ 1895 a181 = a182 = a183 = a184 = a185 = a186 = a187 = a188 = a189 = a190 = \ 1896 a191 = a192 = a193 = a194 = a195 = a196 = a197 = a198 = a199 = a200 = \ 1897 a201 = a202 = a203 = a204 = a205 = a206 = a207 = a208 = a209 = a210 = \ 1898 a211 = a212 = a213 = a214 = a215 = a216 = a217 = a218 = a219 = a220 = \ 1899 a221 = a222 = a223 = a224 = a225 = a226 = a227 = a228 = a229 = a230 = \ 1900 a231 = a232 = a233 = a234 = a235 = a236 = a237 = a238 = a239 = a240 = \ 1901 a241 = a242 = a243 = a244 = a245 = a246 = a247 = a248 = a249 = a250 = \ 1902 a251 = a252 = a253 = a254 = a255 = a256 = a257 = a258 = a259 = a260 = \ 1903 a261 = a262 = a263 = a264 = a265 = a266 = a267 = a268 = a269 = a270 = \ 1904 a271 = a272 = a273 = a274 = a275 = a276 = a277 = a278 = a279 = a280 = \ 1905 a281 = a282 = a283 = a284 = a285 = a286 = a287 = a288 = a289 = a290 = \ 1906 a291 = a292 = a293 = a294 = a295 = a296 = a297 = a298 = a299 = a300 = \ 1907 a301 = a302 = a303 = a304 = a305 = a306 = a307 = a308 = a309 = a310 = \ 1908 a311 = a312 = a313 = a314 = a315 = a316 = a317 = a318 = a319 = a320 = \ 1909 a321 = a322 = a323 = a324 = a325 = a326 = a327 = a328 = a329 = a330 = \ 1910 a331 = a332 = a333 = a334 = a335 = a336 = a337 = a338 = a339 = a340 = \ 1911 a341 = a342 = a343 = a344 = a345 = a346 = a347 = a348 = a349 = a350 = \ 1912 a351 = a352 = a353 = a354 = a355 = a356 = a357 = a358 = a359 = a360 = \ 1913 a361 = a362 = a363 = a364 = a365 = a366 = a367 = a368 = a369 = a370 = \ 1914 a371 = a372 = a373 = a374 = a375 = a376 = a377 = a378 = a379 = a380 = \ 1915 a381 = a382 = a383 = a384 = a385 = a386 = a387 = a388 = a389 = a390 = \ 1916 a391 = a392 = a393 = a394 = a395 = a396 = a397 = a398 = a399 = a400 = \ 1917 a401 = a402 = a403 = a404 = a405 = a406 = a407 = a408 = a409 = a410 = \ 1918 a411 = a412 = a413 = a414 = a415 = a416 = a417 = a418 = a419 = a420 = \ 1919 a421 = a422 = a423 = a424 = a425 = a426 = a427 = a428 = a429 = a430 = \ 1920 a431 = a432 = a433 = a434 = a435 = a436 = a437 = a438 = a439 = a440 = \ 1921 a441 = a442 = a443 = a444 = a445 = a446 = a447 = a448 = a449 = a450 = \ 1922 a451 = a452 = a453 = a454 = a455 = a456 = a457 = a458 = a459 = a460 = \ 1923 a461 = a462 = a463 = a464 = a465 = a466 = a467 = a468 = a469 = a470 = \ 1924 a471 = a472 = a473 = a474 = a475 = a476 = a477 = a478 = a479 = a480 = \ 1925 a481 = a482 = a483 = a484 = a485 = a486 = a487 = a488 = a489 = a490 = \ 1926 a491 = a492 = a493 = a494 = a495 = a496 = a497 = a498 = a499 = a500 = \ 1927 a501 = a502 = a503 = a504 = a505 = a506 = a507 = a508 = a509 = a510 = \ 1928 a511 = a512 = a513 = a514 = a515 = a516 = a517 = a518 = a519 = a520 = \ 1929 a521 = a522 = a523 = a524 = a525 = a526 = a527 = a528 = a529 = a530 = \ 1930 a531 = a532 = a533 = a534 = a535 = a536 = a537 = a538 = a539 = a540 = \ 1931 a541 = a542 = a543 = a544 = a545 = a546 = a547 = a548 = a549 = a550 = \ 1932 a551 = a552 = a553 = a554 = a555 = a556 = a557 = a558 = a559 = a560 = \ 1933 a561 = a562 = a563 = a564 = a565 = a566 = a567 = a568 = a569 = a570 = \ 1934 a571 = a572 = a573 = a574 = a575 = a576 = a577 = a578 = a579 = a580 = \ 1935 a581 = a582 = a583 = a584 = a585 = a586 = a587 = a588 = a589 = a590 = \ 1936 a591 = a592 = a593 = a594 = a595 = a596 = a597 = a598 = a599 = a600 = \ 1937 a601 = a602 = a603 = a604 = a605 = a606 = a607 = a608 = a609 = a610 = \ 1938 a611 = a612 = a613 = a614 = a615 = a616 = a617 = a618 = a619 = a620 = \ 1939 a621 = a622 = a623 = a624 = a625 = a626 = a627 = a628 = a629 = a630 = \ 1940 a631 = a632 = a633 = a634 = a635 = a636 = a637 = a638 = a639 = a640 = \ 1941 a641 = a642 = a643 = a644 = a645 = a646 = a647 = a648 = a649 = a650 = \ 1942 a651 = a652 = a653 = a654 = a655 = a656 = a657 = a658 = a659 = a660 = \ 1943 a661 = a662 = a663 = a664 = a665 = a666 = a667 = a668 = a669 = a670 = \ 1944 a671 = a672 = a673 = a674 = a675 = a676 = a677 = a678 = a679 = a680 = \ 1945 a681 = a682 = a683 = a684 = a685 = a686 = a687 = a688 = a689 = a690 = \ 1946 a691 = a692 = a693 = a694 = a695 = a696 = a697 = a698 = a699 = a700 = \ 1947 a701 = a702 = a703 = a704 = a705 = a706 = a707 = a708 = a709 = a710 = \ 1948 a711 = a712 = a713 = a714 = a715 = a716 = a717 = a718 = a719 = a720 = \ 1949 a721 = a722 = a723 = a724 = a725 = a726 = a727 = a728 = a729 = a730 = \ 1950 a731 = a732 = a733 = a734 = a735 = a736 = a737 = a738 = a739 = a740 = \ 1951 a741 = a742 = a743 = a744 = a745 = a746 = a747 = a748 = a749 = a750 = \ 1952 a751 = a752 = a753 = a754 = a755 = a756 = a757 = a758 = a759 = a760 = \ 1953 a761 = a762 = a763 = a764 = a765 = a766 = a767 = a768 = a769 = a770 = \ 1954 a771 = a772 = a773 = a774 = a775 = a776 = a777 = a778 = a779 = a780 = \ 1955 a781 = a782 = a783 = a784 = a785 = a786 = a787 = a788 = a789 = a790 = \ 1956 a791 = a792 = a793 = a794 = a795 = a796 = a797 = a798 = a799 = a800 \ 1957 = None 1958 print(a0) 1959 1960 try: 1961 f() 1962 except NameError as exc: 1963 with support.captured_stderr() as err: 1964 sys.__excepthook__(*sys.exc_info()) 1965 1966 self.assertNotRegex(err.getvalue(), r"NameError.*a1") 1967 1968 def test_name_error_with_custom_exceptions(self): 1969 def f(): 1970 blech = None 1971 raise NameError() 1972 1973 try: 1974 f() 1975 except NameError as exc: 1976 with support.captured_stderr() as err: 1977 sys.__excepthook__(*sys.exc_info()) 1978 1979 self.assertNotIn("blech", err.getvalue()) 1980 1981 def f(): 1982 blech = None 1983 raise NameError 1984 1985 try: 1986 f() 1987 except NameError as exc: 1988 with support.captured_stderr() as err: 1989 sys.__excepthook__(*sys.exc_info()) 1990 1991 self.assertNotIn("blech", err.getvalue()) 1992 1993 def test_unbound_local_error_doesn_not_match(self): 1994 def foo(): 1995 something = 3 1996 print(somethong) 1997 somethong = 3 1998 1999 try: 2000 foo() 2001 except UnboundLocalError as exc: 2002 with support.captured_stderr() as err: 2003 sys.__excepthook__(*sys.exc_info()) 2004 2005 self.assertNotIn("something", err.getvalue()) 2006 2007 def test_issue45826(self): 2008 # regression test for bpo-45826 2009 def f(): 2010 with self.assertRaisesRegex(NameError, 'aaa'): 2011 aab 2012 2013 try: 2014 f() 2015 except self.failureException: 2016 with support.captured_stderr() as err: 2017 sys.__excepthook__(*sys.exc_info()) 2018 2019 self.assertIn("aab", err.getvalue()) 2020 2021 def test_issue45826_focused(self): 2022 def f(): 2023 try: 2024 nonsense 2025 except BaseException as E: 2026 E.with_traceback(None) 2027 raise ZeroDivisionError() 2028 2029 try: 2030 f() 2031 except ZeroDivisionError: 2032 with support.captured_stderr() as err: 2033 sys.__excepthook__(*sys.exc_info()) 2034 2035 self.assertIn("nonsense", err.getvalue()) 2036 self.assertIn("ZeroDivisionError", err.getvalue()) 2037 2038 2039class AttributeErrorTests(unittest.TestCase): 2040 def test_attributes(self): 2041 # Setting 'attr' should not be a problem. 2042 exc = AttributeError('Ouch!') 2043 self.assertIsNone(exc.name) 2044 self.assertIsNone(exc.obj) 2045 2046 sentinel = object() 2047 exc = AttributeError('Ouch', name='carry', obj=sentinel) 2048 self.assertEqual(exc.name, 'carry') 2049 self.assertIs(exc.obj, sentinel) 2050 2051 def test_getattr_has_name_and_obj(self): 2052 class A: 2053 blech = None 2054 2055 obj = A() 2056 try: 2057 obj.bluch 2058 except AttributeError as exc: 2059 self.assertEqual("bluch", exc.name) 2060 self.assertEqual(obj, exc.obj) 2061 try: 2062 object.__getattribute__(obj, "bluch") 2063 except AttributeError as exc: 2064 self.assertEqual("bluch", exc.name) 2065 self.assertEqual(obj, exc.obj) 2066 2067 def test_getattr_has_name_and_obj_for_method(self): 2068 class A: 2069 def blech(self): 2070 return 2071 2072 obj = A() 2073 try: 2074 obj.bluch() 2075 except AttributeError as exc: 2076 self.assertEqual("bluch", exc.name) 2077 self.assertEqual(obj, exc.obj) 2078 2079 def test_getattr_suggestions(self): 2080 class Substitution: 2081 noise = more_noise = a = bc = None 2082 blech = None 2083 2084 class Elimination: 2085 noise = more_noise = a = bc = None 2086 blch = None 2087 2088 class Addition: 2089 noise = more_noise = a = bc = None 2090 bluchin = None 2091 2092 class SubstitutionOverElimination: 2093 blach = None 2094 bluc = None 2095 2096 class SubstitutionOverAddition: 2097 blach = None 2098 bluchi = None 2099 2100 class EliminationOverAddition: 2101 blucha = None 2102 bluc = None 2103 2104 for cls, suggestion in [(Substitution, "'blech'?"), 2105 (Elimination, "'blch'?"), 2106 (Addition, "'bluchin'?"), 2107 (EliminationOverAddition, "'bluc'?"), 2108 (SubstitutionOverElimination, "'blach'?"), 2109 (SubstitutionOverAddition, "'blach'?")]: 2110 try: 2111 cls().bluch 2112 except AttributeError as exc: 2113 with support.captured_stderr() as err: 2114 sys.__excepthook__(*sys.exc_info()) 2115 2116 self.assertIn(suggestion, err.getvalue()) 2117 2118 def test_getattr_suggestions_do_not_trigger_for_long_attributes(self): 2119 class A: 2120 blech = None 2121 2122 try: 2123 A().somethingverywrong 2124 except AttributeError as exc: 2125 with support.captured_stderr() as err: 2126 sys.__excepthook__(*sys.exc_info()) 2127 2128 self.assertNotIn("blech", err.getvalue()) 2129 2130 def test_getattr_error_bad_suggestions_do_not_trigger_for_small_names(self): 2131 class MyClass: 2132 vvv = mom = w = id = pytho = None 2133 2134 with self.subTest(name="b"): 2135 try: 2136 MyClass.b 2137 except AttributeError as exc: 2138 with support.captured_stderr() as err: 2139 sys.__excepthook__(*sys.exc_info()) 2140 self.assertNotIn("you mean", err.getvalue()) 2141 self.assertNotIn("vvv", err.getvalue()) 2142 self.assertNotIn("mom", err.getvalue()) 2143 self.assertNotIn("'id'", err.getvalue()) 2144 self.assertNotIn("'w'", err.getvalue()) 2145 self.assertNotIn("'pytho'", err.getvalue()) 2146 2147 with self.subTest(name="v"): 2148 try: 2149 MyClass.v 2150 except AttributeError as exc: 2151 with support.captured_stderr() as err: 2152 sys.__excepthook__(*sys.exc_info()) 2153 self.assertNotIn("you mean", err.getvalue()) 2154 self.assertNotIn("vvv", err.getvalue()) 2155 self.assertNotIn("mom", err.getvalue()) 2156 self.assertNotIn("'id'", err.getvalue()) 2157 self.assertNotIn("'w'", err.getvalue()) 2158 self.assertNotIn("'pytho'", err.getvalue()) 2159 2160 with self.subTest(name="m"): 2161 try: 2162 MyClass.m 2163 except AttributeError as exc: 2164 with support.captured_stderr() as err: 2165 sys.__excepthook__(*sys.exc_info()) 2166 self.assertNotIn("you mean", err.getvalue()) 2167 self.assertNotIn("vvv", err.getvalue()) 2168 self.assertNotIn("mom", err.getvalue()) 2169 self.assertNotIn("'id'", err.getvalue()) 2170 self.assertNotIn("'w'", err.getvalue()) 2171 self.assertNotIn("'pytho'", err.getvalue()) 2172 2173 with self.subTest(name="py"): 2174 try: 2175 MyClass.py 2176 except AttributeError as exc: 2177 with support.captured_stderr() as err: 2178 sys.__excepthook__(*sys.exc_info()) 2179 self.assertNotIn("you mean", err.getvalue()) 2180 self.assertNotIn("vvv", err.getvalue()) 2181 self.assertNotIn("mom", err.getvalue()) 2182 self.assertNotIn("'id'", err.getvalue()) 2183 self.assertNotIn("'w'", err.getvalue()) 2184 self.assertNotIn("'pytho'", err.getvalue()) 2185 2186 2187 def test_getattr_suggestions_do_not_trigger_for_big_dicts(self): 2188 class A: 2189 blech = None 2190 # A class with a very big __dict__ will not be consider 2191 # for suggestions. 2192 for index in range(2000): 2193 setattr(A, f"index_{index}", None) 2194 2195 try: 2196 A().bluch 2197 except AttributeError as exc: 2198 with support.captured_stderr() as err: 2199 sys.__excepthook__(*sys.exc_info()) 2200 2201 self.assertNotIn("blech", err.getvalue()) 2202 2203 def test_getattr_suggestions_no_args(self): 2204 class A: 2205 blech = None 2206 def __getattr__(self, attr): 2207 raise AttributeError() 2208 2209 try: 2210 A().bluch 2211 except AttributeError as exc: 2212 with support.captured_stderr() as err: 2213 sys.__excepthook__(*sys.exc_info()) 2214 2215 self.assertIn("blech", err.getvalue()) 2216 2217 class A: 2218 blech = None 2219 def __getattr__(self, attr): 2220 raise AttributeError 2221 2222 try: 2223 A().bluch 2224 except AttributeError as exc: 2225 with support.captured_stderr() as err: 2226 sys.__excepthook__(*sys.exc_info()) 2227 2228 self.assertIn("blech", err.getvalue()) 2229 2230 def test_getattr_suggestions_invalid_args(self): 2231 class NonStringifyClass: 2232 __str__ = None 2233 __repr__ = None 2234 2235 class A: 2236 blech = None 2237 def __getattr__(self, attr): 2238 raise AttributeError(NonStringifyClass()) 2239 2240 class B: 2241 blech = None 2242 def __getattr__(self, attr): 2243 raise AttributeError("Error", 23) 2244 2245 class C: 2246 blech = None 2247 def __getattr__(self, attr): 2248 raise AttributeError(23) 2249 2250 for cls in [A, B, C]: 2251 try: 2252 cls().bluch 2253 except AttributeError as exc: 2254 with support.captured_stderr() as err: 2255 sys.__excepthook__(*sys.exc_info()) 2256 2257 self.assertIn("blech", err.getvalue()) 2258 2259 def test_getattr_suggestions_for_same_name(self): 2260 class A: 2261 def __dir__(self): 2262 return ['blech'] 2263 try: 2264 A().blech 2265 except AttributeError as exc: 2266 with support.captured_stderr() as err: 2267 sys.__excepthook__(*sys.exc_info()) 2268 2269 self.assertNotIn("Did you mean", err.getvalue()) 2270 2271 def test_attribute_error_with_failing_dict(self): 2272 class T: 2273 bluch = 1 2274 def __dir__(self): 2275 raise AttributeError("oh no!") 2276 2277 try: 2278 T().blich 2279 except AttributeError as exc: 2280 with support.captured_stderr() as err: 2281 sys.__excepthook__(*sys.exc_info()) 2282 2283 self.assertNotIn("blech", err.getvalue()) 2284 self.assertNotIn("oh no!", err.getvalue()) 2285 2286 def test_attribute_error_with_bad_name(self): 2287 try: 2288 raise AttributeError(name=12, obj=23) 2289 except AttributeError as exc: 2290 with support.captured_stderr() as err: 2291 sys.__excepthook__(*sys.exc_info()) 2292 2293 self.assertNotIn("?", err.getvalue()) 2294 2295 def test_attribute_error_inside_nested_getattr(self): 2296 class A: 2297 bluch = 1 2298 2299 class B: 2300 def __getattribute__(self, attr): 2301 a = A() 2302 return a.blich 2303 2304 try: 2305 B().something 2306 except AttributeError as exc: 2307 with support.captured_stderr() as err: 2308 sys.__excepthook__(*sys.exc_info()) 2309 2310 self.assertIn("Did you mean", err.getvalue()) 2311 self.assertIn("bluch", err.getvalue()) 2312 2313 2314class ImportErrorTests(unittest.TestCase): 2315 2316 def test_attributes(self): 2317 # Setting 'name' and 'path' should not be a problem. 2318 exc = ImportError('test') 2319 self.assertIsNone(exc.name) 2320 self.assertIsNone(exc.path) 2321 2322 exc = ImportError('test', name='somemodule') 2323 self.assertEqual(exc.name, 'somemodule') 2324 self.assertIsNone(exc.path) 2325 2326 exc = ImportError('test', path='somepath') 2327 self.assertEqual(exc.path, 'somepath') 2328 self.assertIsNone(exc.name) 2329 2330 exc = ImportError('test', path='somepath', name='somename') 2331 self.assertEqual(exc.name, 'somename') 2332 self.assertEqual(exc.path, 'somepath') 2333 2334 msg = "'invalid' is an invalid keyword argument for ImportError" 2335 with self.assertRaisesRegex(TypeError, msg): 2336 ImportError('test', invalid='keyword') 2337 2338 with self.assertRaisesRegex(TypeError, msg): 2339 ImportError('test', name='name', invalid='keyword') 2340 2341 with self.assertRaisesRegex(TypeError, msg): 2342 ImportError('test', path='path', invalid='keyword') 2343 2344 with self.assertRaisesRegex(TypeError, msg): 2345 ImportError(invalid='keyword') 2346 2347 with self.assertRaisesRegex(TypeError, msg): 2348 ImportError('test', invalid='keyword', another=True) 2349 2350 def test_reset_attributes(self): 2351 exc = ImportError('test', name='name', path='path') 2352 self.assertEqual(exc.args, ('test',)) 2353 self.assertEqual(exc.msg, 'test') 2354 self.assertEqual(exc.name, 'name') 2355 self.assertEqual(exc.path, 'path') 2356 2357 # Reset not specified attributes 2358 exc.__init__() 2359 self.assertEqual(exc.args, ()) 2360 self.assertEqual(exc.msg, None) 2361 self.assertEqual(exc.name, None) 2362 self.assertEqual(exc.path, None) 2363 2364 def test_non_str_argument(self): 2365 # Issue #15778 2366 with check_warnings(('', BytesWarning), quiet=True): 2367 arg = b'abc' 2368 exc = ImportError(arg) 2369 self.assertEqual(str(arg), str(exc)) 2370 2371 def test_copy_pickle(self): 2372 for kwargs in (dict(), 2373 dict(name='somename'), 2374 dict(path='somepath'), 2375 dict(name='somename', path='somepath')): 2376 orig = ImportError('test', **kwargs) 2377 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 2378 exc = pickle.loads(pickle.dumps(orig, proto)) 2379 self.assertEqual(exc.args, ('test',)) 2380 self.assertEqual(exc.msg, 'test') 2381 self.assertEqual(exc.name, orig.name) 2382 self.assertEqual(exc.path, orig.path) 2383 for c in copy.copy, copy.deepcopy: 2384 exc = c(orig) 2385 self.assertEqual(exc.args, ('test',)) 2386 self.assertEqual(exc.msg, 'test') 2387 self.assertEqual(exc.name, orig.name) 2388 self.assertEqual(exc.path, orig.path) 2389 2390class SyntaxErrorTests(unittest.TestCase): 2391 def test_range_of_offsets(self): 2392 cases = [ 2393 # Basic range from 2->7 2394 (("bad.py", 1, 2, "abcdefg", 1, 7), 2395 dedent( 2396 """ 2397 File "bad.py", line 1 2398 abcdefg 2399 ^^^^^ 2400 SyntaxError: bad bad 2401 """)), 2402 # end_offset = start_offset + 1 2403 (("bad.py", 1, 2, "abcdefg", 1, 3), 2404 dedent( 2405 """ 2406 File "bad.py", line 1 2407 abcdefg 2408 ^ 2409 SyntaxError: bad bad 2410 """)), 2411 # Negative end offset 2412 (("bad.py", 1, 2, "abcdefg", 1, -2), 2413 dedent( 2414 """ 2415 File "bad.py", line 1 2416 abcdefg 2417 ^ 2418 SyntaxError: bad bad 2419 """)), 2420 # end offset before starting offset 2421 (("bad.py", 1, 4, "abcdefg", 1, 2), 2422 dedent( 2423 """ 2424 File "bad.py", line 1 2425 abcdefg 2426 ^ 2427 SyntaxError: bad bad 2428 """)), 2429 # Both offsets negative 2430 (("bad.py", 1, -4, "abcdefg", 1, -2), 2431 dedent( 2432 """ 2433 File "bad.py", line 1 2434 abcdefg 2435 SyntaxError: bad bad 2436 """)), 2437 # Both offsets negative and the end more negative 2438 (("bad.py", 1, -4, "abcdefg", 1, -5), 2439 dedent( 2440 """ 2441 File "bad.py", line 1 2442 abcdefg 2443 SyntaxError: bad bad 2444 """)), 2445 # Both offsets 0 2446 (("bad.py", 1, 0, "abcdefg", 1, 0), 2447 dedent( 2448 """ 2449 File "bad.py", line 1 2450 abcdefg 2451 SyntaxError: bad bad 2452 """)), 2453 # Start offset 0 and end offset not 0 2454 (("bad.py", 1, 0, "abcdefg", 1, 5), 2455 dedent( 2456 """ 2457 File "bad.py", line 1 2458 abcdefg 2459 SyntaxError: bad bad 2460 """)), 2461 # End offset pass the source length 2462 (("bad.py", 1, 2, "abcdefg", 1, 100), 2463 dedent( 2464 """ 2465 File "bad.py", line 1 2466 abcdefg 2467 ^^^^^^ 2468 SyntaxError: bad bad 2469 """)), 2470 ] 2471 for args, expected in cases: 2472 with self.subTest(args=args): 2473 try: 2474 raise SyntaxError("bad bad", args) 2475 except SyntaxError as exc: 2476 with support.captured_stderr() as err: 2477 sys.__excepthook__(*sys.exc_info()) 2478 self.assertIn(expected, err.getvalue()) 2479 the_exception = exc 2480 2481 def test_encodings(self): 2482 source = ( 2483 '# -*- coding: cp437 -*-\n' 2484 '"┬ó┬ó┬ó┬ó┬ó┬ó" + f(4, x for x in range(1))\n' 2485 ) 2486 try: 2487 with open(TESTFN, 'w', encoding='cp437') as testfile: 2488 testfile.write(source) 2489 rc, out, err = script_helper.assert_python_failure('-Wd', '-X', 'utf8', TESTFN) 2490 err = err.decode('utf-8').splitlines() 2491 2492 self.assertEqual(err[-3], ' "┬ó┬ó┬ó┬ó┬ó┬ó" + f(4, x for x in range(1))') 2493 self.assertEqual(err[-2], ' ^^^^^^^^^^^^^^^^^^^') 2494 finally: 2495 unlink(TESTFN) 2496 2497 # Check backwards tokenizer errors 2498 source = '# -*- coding: ascii -*-\n\n(\n' 2499 try: 2500 with open(TESTFN, 'w', encoding='ascii') as testfile: 2501 testfile.write(source) 2502 rc, out, err = script_helper.assert_python_failure('-Wd', '-X', 'utf8', TESTFN) 2503 err = err.decode('utf-8').splitlines() 2504 2505 self.assertEqual(err[-3], ' (') 2506 self.assertEqual(err[-2], ' ^') 2507 finally: 2508 unlink(TESTFN) 2509 2510 def test_non_utf8(self): 2511 # Check non utf-8 characters 2512 try: 2513 with open(TESTFN, 'bw') as testfile: 2514 testfile.write(b"\x89") 2515 rc, out, err = script_helper.assert_python_failure('-Wd', '-X', 'utf8', TESTFN) 2516 err = err.decode('utf-8').splitlines() 2517 2518 self.assertIn("SyntaxError: Non-UTF-8 code starting with '\\x89' in file", err[-1]) 2519 finally: 2520 unlink(TESTFN) 2521 2522 def test_attributes_new_constructor(self): 2523 args = ("bad.py", 1, 2, "abcdefg", 1, 100) 2524 the_exception = SyntaxError("bad bad", args) 2525 filename, lineno, offset, error, end_lineno, end_offset = args 2526 self.assertEqual(filename, the_exception.filename) 2527 self.assertEqual(lineno, the_exception.lineno) 2528 self.assertEqual(end_lineno, the_exception.end_lineno) 2529 self.assertEqual(offset, the_exception.offset) 2530 self.assertEqual(end_offset, the_exception.end_offset) 2531 self.assertEqual(error, the_exception.text) 2532 self.assertEqual("bad bad", the_exception.msg) 2533 2534 def test_attributes_old_constructor(self): 2535 args = ("bad.py", 1, 2, "abcdefg") 2536 the_exception = SyntaxError("bad bad", args) 2537 filename, lineno, offset, error = args 2538 self.assertEqual(filename, the_exception.filename) 2539 self.assertEqual(lineno, the_exception.lineno) 2540 self.assertEqual(None, the_exception.end_lineno) 2541 self.assertEqual(offset, the_exception.offset) 2542 self.assertEqual(None, the_exception.end_offset) 2543 self.assertEqual(error, the_exception.text) 2544 self.assertEqual("bad bad", the_exception.msg) 2545 2546 def test_incorrect_constructor(self): 2547 args = ("bad.py", 1, 2) 2548 self.assertRaises(TypeError, SyntaxError, "bad bad", args) 2549 2550 args = ("bad.py", 1, 2, 4, 5, 6, 7) 2551 self.assertRaises(TypeError, SyntaxError, "bad bad", args) 2552 2553 args = ("bad.py", 1, 2, "abcdefg", 1) 2554 self.assertRaises(TypeError, SyntaxError, "bad bad", args) 2555 2556 2557class TestInvalidExceptionMatcher(unittest.TestCase): 2558 def test_except_star_invalid_exception_type(self): 2559 with self.assertRaises(TypeError): 2560 try: 2561 raise ValueError 2562 except 42: 2563 pass 2564 2565 with self.assertRaises(TypeError): 2566 try: 2567 raise ValueError 2568 except (ValueError, 42): 2569 pass 2570 2571 2572class PEP626Tests(unittest.TestCase): 2573 2574 def lineno_after_raise(self, f, *expected): 2575 try: 2576 f() 2577 except Exception as ex: 2578 t = ex.__traceback__ 2579 else: 2580 self.fail("No exception raised") 2581 lines = [] 2582 t = t.tb_next # Skip this function 2583 while t: 2584 frame = t.tb_frame 2585 lines.append( 2586 None if frame.f_lineno is None else 2587 frame.f_lineno-frame.f_code.co_firstlineno 2588 ) 2589 t = t.tb_next 2590 self.assertEqual(tuple(lines), expected) 2591 2592 def test_lineno_after_raise_simple(self): 2593 def simple(): 2594 1/0 2595 pass 2596 self.lineno_after_raise(simple, 1) 2597 2598 def test_lineno_after_raise_in_except(self): 2599 def in_except(): 2600 try: 2601 1/0 2602 except: 2603 1/0 2604 pass 2605 self.lineno_after_raise(in_except, 4) 2606 2607 def test_lineno_after_other_except(self): 2608 def other_except(): 2609 try: 2610 1/0 2611 except TypeError as ex: 2612 pass 2613 self.lineno_after_raise(other_except, 3) 2614 2615 def test_lineno_in_named_except(self): 2616 def in_named_except(): 2617 try: 2618 1/0 2619 except Exception as ex: 2620 1/0 2621 pass 2622 self.lineno_after_raise(in_named_except, 4) 2623 2624 def test_lineno_in_try(self): 2625 def in_try(): 2626 try: 2627 1/0 2628 finally: 2629 pass 2630 self.lineno_after_raise(in_try, 4) 2631 2632 def test_lineno_in_finally_normal(self): 2633 def in_finally_normal(): 2634 try: 2635 pass 2636 finally: 2637 1/0 2638 pass 2639 self.lineno_after_raise(in_finally_normal, 4) 2640 2641 def test_lineno_in_finally_except(self): 2642 def in_finally_except(): 2643 try: 2644 1/0 2645 finally: 2646 1/0 2647 pass 2648 self.lineno_after_raise(in_finally_except, 4) 2649 2650 def test_lineno_after_with(self): 2651 class Noop: 2652 def __enter__(self): 2653 return self 2654 def __exit__(self, *args): 2655 pass 2656 def after_with(): 2657 with Noop(): 2658 1/0 2659 pass 2660 self.lineno_after_raise(after_with, 2) 2661 2662 def test_missing_lineno_shows_as_none(self): 2663 def f(): 2664 1/0 2665 self.lineno_after_raise(f, 1) 2666 f.__code__ = f.__code__.replace(co_linetable=b'\xf8\xf8\xf8\xf9\xf8\xf8\xf8') 2667 self.lineno_after_raise(f, None) 2668 2669 def test_lineno_after_raise_in_with_exit(self): 2670 class ExitFails: 2671 def __enter__(self): 2672 return self 2673 def __exit__(self, *args): 2674 raise ValueError 2675 2676 def after_with(): 2677 with ExitFails(): 2678 1/0 2679 self.lineno_after_raise(after_with, 1, 1) 2680 2681if __name__ == '__main__': 2682 unittest.main() 2683