1# Python test set -- part 5, built-in exceptions 2 3import copy 4import os 5import sys 6import unittest 7import pickle 8import weakref 9import errno 10from codecs import BOM_UTF8 11from itertools import product 12from textwrap import dedent 13 14from test.support import (captured_stderr, check_impl_detail, 15 cpython_only, gc_collect, 16 no_tracing, script_helper, 17 SuppressCrashReport, 18 force_not_colorized) 19from test.support.import_helper import import_module 20from test.support.os_helper import TESTFN, unlink 21from test.support.warnings_helper import check_warnings 22from test import support 23 24try: 25 import _testcapi 26 from _testcapi import INT_MAX 27except ImportError: 28 _testcapi = None 29 INT_MAX = 2**31 - 1 30 31 32class NaiveException(Exception): 33 def __init__(self, x): 34 self.x = x 35 36class SlottedNaiveException(Exception): 37 __slots__ = ('x',) 38 def __init__(self, x): 39 self.x = x 40 41class BrokenStrException(Exception): 42 def __str__(self): 43 raise Exception("str() is broken") 44 45# XXX This is not really enough, each *operation* should be tested! 46 47 48class ExceptionTests(unittest.TestCase): 49 50 def raise_catch(self, exc, excname): 51 with self.subTest(exc=exc, excname=excname): 52 try: 53 raise exc("spam") 54 except exc as err: 55 buf1 = str(err) 56 try: 57 raise exc("spam") 58 except exc as err: 59 buf2 = str(err) 60 self.assertEqual(buf1, buf2) 61 self.assertEqual(exc.__name__, excname) 62 63 def testRaising(self): 64 self.raise_catch(AttributeError, "AttributeError") 65 self.assertRaises(AttributeError, getattr, sys, "undefined_attribute") 66 67 self.raise_catch(EOFError, "EOFError") 68 fp = open(TESTFN, 'w', encoding="utf-8") 69 fp.close() 70 fp = open(TESTFN, 'r', encoding="utf-8") 71 savestdin = sys.stdin 72 try: 73 try: 74 import marshal 75 marshal.loads(b'') 76 except EOFError: 77 pass 78 finally: 79 sys.stdin = savestdin 80 fp.close() 81 unlink(TESTFN) 82 83 self.raise_catch(OSError, "OSError") 84 self.assertRaises(OSError, open, 'this file does not exist', 'r') 85 86 self.raise_catch(ImportError, "ImportError") 87 self.assertRaises(ImportError, __import__, "undefined_module") 88 89 self.raise_catch(IndexError, "IndexError") 90 x = [] 91 self.assertRaises(IndexError, x.__getitem__, 10) 92 93 self.raise_catch(KeyError, "KeyError") 94 x = {} 95 self.assertRaises(KeyError, x.__getitem__, 'key') 96 97 self.raise_catch(KeyboardInterrupt, "KeyboardInterrupt") 98 99 self.raise_catch(MemoryError, "MemoryError") 100 101 self.raise_catch(NameError, "NameError") 102 try: x = undefined_variable 103 except NameError: pass 104 105 self.raise_catch(OverflowError, "OverflowError") 106 x = 1 107 for dummy in range(128): 108 x += x # this simply shouldn't blow up 109 110 self.raise_catch(RuntimeError, "RuntimeError") 111 self.raise_catch(RecursionError, "RecursionError") 112 113 self.raise_catch(SyntaxError, "SyntaxError") 114 try: exec('/\n') 115 except SyntaxError: pass 116 117 self.raise_catch(IndentationError, "IndentationError") 118 119 self.raise_catch(TabError, "TabError") 120 try: compile("try:\n\t1/0\n \t1/0\nfinally:\n pass\n", 121 '<string>', 'exec') 122 except TabError: pass 123 else: self.fail("TabError not raised") 124 125 self.raise_catch(SystemError, "SystemError") 126 127 self.raise_catch(SystemExit, "SystemExit") 128 self.assertRaises(SystemExit, sys.exit, 0) 129 130 self.raise_catch(TypeError, "TypeError") 131 try: [] + () 132 except TypeError: pass 133 134 self.raise_catch(ValueError, "ValueError") 135 self.assertRaises(ValueError, chr, 17<<16) 136 137 self.raise_catch(ZeroDivisionError, "ZeroDivisionError") 138 try: x = 1/0 139 except ZeroDivisionError: pass 140 141 self.raise_catch(Exception, "Exception") 142 try: x = 1/0 143 except Exception as e: pass 144 145 self.raise_catch(StopAsyncIteration, "StopAsyncIteration") 146 147 def testSyntaxErrorMessage(self): 148 # make sure the right exception message is raised for each of 149 # these code fragments 150 151 def ckmsg(src, msg): 152 with self.subTest(src=src, msg=msg): 153 try: 154 compile(src, '<fragment>', 'exec') 155 except SyntaxError as e: 156 if e.msg != msg: 157 self.fail("expected %s, got %s" % (msg, e.msg)) 158 else: 159 self.fail("failed to get expected SyntaxError") 160 161 s = '''if 1: 162 try: 163 continue 164 except: 165 pass''' 166 167 ckmsg(s, "'continue' not properly in loop") 168 ckmsg("continue\n", "'continue' not properly in loop") 169 ckmsg("f'{6 0}'", "invalid syntax. Perhaps you forgot a comma?") 170 171 def testSyntaxErrorMissingParens(self): 172 def ckmsg(src, msg, exception=SyntaxError): 173 try: 174 compile(src, '<fragment>', 'exec') 175 except exception as e: 176 if e.msg != msg: 177 self.fail("expected %s, got %s" % (msg, e.msg)) 178 else: 179 self.fail("failed to get expected SyntaxError") 180 181 s = '''print "old style"''' 182 ckmsg(s, "Missing parentheses in call to 'print'. Did you mean print(...)?") 183 184 s = '''print "old style",''' 185 ckmsg(s, "Missing parentheses in call to 'print'. Did you mean print(...)?") 186 187 s = 'print f(a+b,c)' 188 ckmsg(s, "Missing parentheses in call to 'print'. Did you mean print(...)?") 189 190 s = '''exec "old style"''' 191 ckmsg(s, "Missing parentheses in call to 'exec'. Did you mean exec(...)?") 192 193 s = 'exec f(a+b,c)' 194 ckmsg(s, "Missing parentheses in call to 'exec'. Did you mean exec(...)?") 195 196 # Check that we don't incorrectly identify '(...)' as an expression to the right 197 # of 'print' 198 199 s = 'print (a+b,c) $ 42' 200 ckmsg(s, "invalid syntax") 201 202 s = 'exec (a+b,c) $ 42' 203 ckmsg(s, "invalid syntax") 204 205 # should not apply to subclasses, see issue #31161 206 s = '''if True:\nprint "No indent"''' 207 ckmsg(s, "expected an indented block after 'if' statement on line 1", IndentationError) 208 209 s = '''if True:\n print()\n\texec "mixed tabs and spaces"''' 210 ckmsg(s, "inconsistent use of tabs and spaces in indentation", TabError) 211 212 def check(self, src, lineno, offset, end_lineno=None, end_offset=None, encoding='utf-8'): 213 with self.subTest(source=src, lineno=lineno, offset=offset): 214 with self.assertRaises(SyntaxError) as cm: 215 compile(src, '<fragment>', 'exec') 216 self.assertEqual(cm.exception.lineno, lineno) 217 self.assertEqual(cm.exception.offset, offset) 218 if end_lineno is not None: 219 self.assertEqual(cm.exception.end_lineno, end_lineno) 220 if end_offset is not None: 221 self.assertEqual(cm.exception.end_offset, end_offset) 222 223 if cm.exception.text is not None: 224 if not isinstance(src, str): 225 src = src.decode(encoding, 'replace') 226 line = src.split('\n')[lineno-1] 227 self.assertIn(line, cm.exception.text) 228 229 def test_error_offset_continuation_characters(self): 230 check = self.check 231 check('"\\\n"(1 for c in I,\\\n\\', 2, 2) 232 233 def testSyntaxErrorOffset(self): 234 check = self.check 235 check('def fact(x):\n\treturn x!\n', 2, 10) 236 check('1 +\n', 1, 4) 237 check('def spam():\n print(1)\n print(2)', 3, 10) 238 check('Python = "Python" +', 1, 20) 239 check('Python = "\u1e54\xfd\u0163\u0125\xf2\xf1" +', 1, 20) 240 check(b'# -*- coding: cp1251 -*-\nPython = "\xcf\xb3\xf2\xee\xed" +', 241 2, 19, encoding='cp1251') 242 check(b'Python = "\xcf\xb3\xf2\xee\xed" +', 1, 10) 243 check('x = "a', 1, 5) 244 check('lambda x: x = 2', 1, 1) 245 check('f{a + b + c}', 1, 2) 246 check('[file for str(file) in []\n]', 1, 11) 247 check('a = « hello » « world »', 1, 5) 248 check('[\nfile\nfor str(file)\nin\n[]\n]', 3, 5) 249 check('[file for\n str(file) in []]', 2, 2) 250 check("ages = {'Alice'=22, 'Bob'=23}", 1, 9) 251 check('match ...:\n case {**rest, "key": value}:\n ...', 2, 19) 252 check("[a b c d e f]", 1, 2) 253 check("for x yfff:", 1, 7) 254 check("f(a for a in b, c)", 1, 3, 1, 15) 255 check("f(a for a in b if a, c)", 1, 3, 1, 20) 256 check("f(a, b for b in c)", 1, 6, 1, 18) 257 check("f(a, b for b in c, d)", 1, 6, 1, 18) 258 259 # Errors thrown by compile.c 260 check('class foo:return 1', 1, 11) 261 check('def f():\n continue', 2, 3) 262 check('def f():\n break', 2, 3) 263 check('try:\n pass\nexcept:\n pass\nexcept ValueError:\n pass', 3, 1) 264 check('try:\n pass\nexcept*:\n pass', 3, 8) 265 check('try:\n pass\nexcept*:\n pass\nexcept* ValueError:\n pass', 3, 8) 266 267 # Errors thrown by the tokenizer 268 check('(0x+1)', 1, 3) 269 check('x = 0xI', 1, 6) 270 check('0010 + 2', 1, 1) 271 check('x = 32e-+4', 1, 8) 272 check('x = 0o9', 1, 7) 273 check('\u03b1 = 0xI', 1, 6) 274 check(b'\xce\xb1 = 0xI', 1, 6) 275 check(b'# -*- coding: iso8859-7 -*-\n\xe1 = 0xI', 2, 6, 276 encoding='iso8859-7') 277 check(b"""if 1: 278 def foo(): 279 ''' 280 281 def bar(): 282 pass 283 284 def baz(): 285 '''quux''' 286 """, 9, 24) 287 check("pass\npass\npass\n(1+)\npass\npass\npass", 4, 4) 288 check("(1+)", 1, 4) 289 check("[interesting\nfoo()\n", 1, 1) 290 check(b"\xef\xbb\xbf#coding: utf8\nprint('\xe6\x88\x91')\n", 0, -1) 291 check("""f''' 292 { 293 (123_a) 294 }'''""", 3, 17) 295 check("""f''' 296 { 297 f\"\"\" 298 { 299 (123_a) 300 } 301 \"\"\" 302 }'''""", 5, 17) 303 check('''f""" 304 305 306 { 307 6 308 0="""''', 5, 13) 309 check('b"fooжжж"'.encode(), 1, 1, 1, 10) 310 311 # Errors thrown by symtable.c 312 check('x = [(yield i) for i in range(3)]', 1, 7) 313 check('def f():\n from _ import *', 2, 17) 314 check('def f(x, x):\n pass', 1, 10) 315 check('{i for i in range(5) if (j := 0) for j in range(5)}', 1, 38) 316 check('def f(x):\n nonlocal x', 2, 3) 317 check('def f(x):\n x = 1\n global x', 3, 3) 318 check('nonlocal x', 1, 1) 319 check('def f():\n global x\n nonlocal x', 2, 3) 320 321 # Errors thrown by future.c 322 check('from __future__ import doesnt_exist', 1, 24) 323 check('from __future__ import braces', 1, 24) 324 check('x=1\nfrom __future__ import division', 2, 1) 325 check('foo(1=2)', 1, 5) 326 check('def f():\n x, y: int', 2, 3) 327 check('[*x for x in xs]', 1, 2) 328 check('foo(x for x in range(10), 100)', 1, 5) 329 check('for 1 in []: pass', 1, 5) 330 check('(yield i) = 2', 1, 2) 331 check('def f(*):\n pass', 1, 7) 332 333 @unittest.skipIf(INT_MAX >= sys.maxsize, "Downcasting to int is safe for col_offset") 334 @support.requires_resource('cpu') 335 @support.bigmemtest(INT_MAX, memuse=2, dry_run=False) 336 def testMemoryErrorBigSource(self, size): 337 src = b"if True:\n%*s" % (size, b"pass") 338 with self.assertRaisesRegex(OverflowError, "Parser column offset overflow"): 339 compile(src, '<fragment>', 'exec') 340 341 @cpython_only 342 def testSettingException(self): 343 # test that setting an exception at the C level works even if the 344 # exception object can't be constructed. 345 346 class BadException(Exception): 347 def __init__(self_): 348 raise RuntimeError("can't instantiate BadException") 349 350 class InvalidException: 351 pass 352 353 @unittest.skipIf(_testcapi is None, "requires _testcapi") 354 def test_capi1(): 355 try: 356 _testcapi.raise_exception(BadException, 1) 357 except TypeError as err: 358 co = err.__traceback__.tb_frame.f_code 359 self.assertEqual(co.co_name, "test_capi1") 360 self.assertTrue(co.co_filename.endswith('test_exceptions.py')) 361 else: 362 self.fail("Expected exception") 363 364 @unittest.skipIf(_testcapi is None, "requires _testcapi") 365 def test_capi2(): 366 try: 367 _testcapi.raise_exception(BadException, 0) 368 except RuntimeError as err: 369 tb = err.__traceback__.tb_next 370 co = tb.tb_frame.f_code 371 self.assertEqual(co.co_name, "__init__") 372 self.assertTrue(co.co_filename.endswith('test_exceptions.py')) 373 co2 = tb.tb_frame.f_back.f_code 374 self.assertEqual(co2.co_name, "test_capi2") 375 else: 376 self.fail("Expected exception") 377 378 @unittest.skipIf(_testcapi is None, "requires _testcapi") 379 def test_capi3(): 380 self.assertRaises(SystemError, _testcapi.raise_exception, 381 InvalidException, 1) 382 383 test_capi1() 384 test_capi2() 385 test_capi3() 386 387 def test_WindowsError(self): 388 try: 389 WindowsError 390 except NameError: 391 pass 392 else: 393 self.assertIs(WindowsError, OSError) 394 self.assertEqual(str(OSError(1001)), "1001") 395 self.assertEqual(str(OSError(1001, "message")), 396 "[Errno 1001] message") 397 # POSIX errno (9 aka EBADF) is untranslated 398 w = OSError(9, 'foo', 'bar') 399 self.assertEqual(w.errno, 9) 400 self.assertEqual(w.winerror, None) 401 self.assertEqual(str(w), "[Errno 9] foo: 'bar'") 402 # ERROR_PATH_NOT_FOUND (win error 3) becomes ENOENT (2) 403 w = OSError(0, 'foo', 'bar', 3) 404 self.assertEqual(w.errno, 2) 405 self.assertEqual(w.winerror, 3) 406 self.assertEqual(w.strerror, 'foo') 407 self.assertEqual(w.filename, 'bar') 408 self.assertEqual(w.filename2, None) 409 self.assertEqual(str(w), "[WinError 3] foo: 'bar'") 410 # Unknown win error becomes EINVAL (22) 411 w = OSError(0, 'foo', None, 1001) 412 self.assertEqual(w.errno, 22) 413 self.assertEqual(w.winerror, 1001) 414 self.assertEqual(w.strerror, 'foo') 415 self.assertEqual(w.filename, None) 416 self.assertEqual(w.filename2, None) 417 self.assertEqual(str(w), "[WinError 1001] foo") 418 # Non-numeric "errno" 419 w = OSError('bar', 'foo') 420 self.assertEqual(w.errno, 'bar') 421 self.assertEqual(w.winerror, None) 422 self.assertEqual(w.strerror, 'foo') 423 self.assertEqual(w.filename, None) 424 self.assertEqual(w.filename2, None) 425 426 @unittest.skipUnless(sys.platform == 'win32', 427 'test specific to Windows') 428 def test_windows_message(self): 429 """Should fill in unknown error code in Windows error message""" 430 ctypes = import_module('ctypes') 431 # this error code has no message, Python formats it as hexadecimal 432 code = 3765269347 433 with self.assertRaisesRegex(OSError, 'Windows Error 0x%x' % code): 434 ctypes.pythonapi.PyErr_SetFromWindowsErr(code) 435 436 def testAttributes(self): 437 # test that exception attributes are happy 438 439 exceptionList = [ 440 (BaseException, (), {}, {'args' : ()}), 441 (BaseException, (1, ), {}, {'args' : (1,)}), 442 (BaseException, ('foo',), {}, 443 {'args' : ('foo',)}), 444 (BaseException, ('foo', 1), {}, 445 {'args' : ('foo', 1)}), 446 (SystemExit, ('foo',), {}, 447 {'args' : ('foo',), 'code' : 'foo'}), 448 (OSError, ('foo',), {}, 449 {'args' : ('foo',), 'filename' : None, 'filename2' : None, 450 'errno' : None, 'strerror' : None}), 451 (OSError, ('foo', 'bar'), {}, 452 {'args' : ('foo', 'bar'), 453 'filename' : None, 'filename2' : None, 454 'errno' : 'foo', 'strerror' : 'bar'}), 455 (OSError, ('foo', 'bar', 'baz'), {}, 456 {'args' : ('foo', 'bar'), 457 'filename' : 'baz', 'filename2' : None, 458 'errno' : 'foo', 'strerror' : 'bar'}), 459 (OSError, ('foo', 'bar', 'baz', None, 'quux'), {}, 460 {'args' : ('foo', 'bar'), 'filename' : 'baz', 'filename2': 'quux'}), 461 (OSError, ('errnoStr', 'strErrorStr', 'filenameStr'), {}, 462 {'args' : ('errnoStr', 'strErrorStr'), 463 'strerror' : 'strErrorStr', 'errno' : 'errnoStr', 464 'filename' : 'filenameStr'}), 465 (OSError, (1, 'strErrorStr', 'filenameStr'), {}, 466 {'args' : (1, 'strErrorStr'), 'errno' : 1, 467 'strerror' : 'strErrorStr', 468 'filename' : 'filenameStr', 'filename2' : None}), 469 (SyntaxError, (), {}, {'msg' : None, 'text' : None, 470 'filename' : None, 'lineno' : None, 'offset' : None, 471 'end_offset': None, 'print_file_and_line' : None}), 472 (SyntaxError, ('msgStr',), {}, 473 {'args' : ('msgStr',), 'text' : None, 474 'print_file_and_line' : None, 'msg' : 'msgStr', 475 'filename' : None, 'lineno' : None, 'offset' : None, 476 'end_offset': None}), 477 (SyntaxError, ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr', 478 'textStr', 'endLinenoStr', 'endOffsetStr')), {}, 479 {'offset' : 'offsetStr', 'text' : 'textStr', 480 'args' : ('msgStr', ('filenameStr', 'linenoStr', 481 'offsetStr', 'textStr', 482 'endLinenoStr', 'endOffsetStr')), 483 'print_file_and_line' : None, 'msg' : 'msgStr', 484 'filename' : 'filenameStr', 'lineno' : 'linenoStr', 485 'end_lineno': 'endLinenoStr', 'end_offset': 'endOffsetStr'}), 486 (SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr', 487 'textStr', 'endLinenoStr', 'endOffsetStr', 488 'print_file_and_lineStr'), {}, 489 {'text' : None, 490 'args' : ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr', 491 'textStr', 'endLinenoStr', 'endOffsetStr', 492 'print_file_and_lineStr'), 493 'print_file_and_line' : None, 'msg' : 'msgStr', 494 'filename' : None, 'lineno' : None, 'offset' : None, 495 'end_lineno': None, 'end_offset': None}), 496 (UnicodeError, (), {}, {'args' : (),}), 497 (UnicodeEncodeError, ('ascii', 'a', 0, 1, 498 'ordinal not in range'), {}, 499 {'args' : ('ascii', 'a', 0, 1, 500 'ordinal not in range'), 501 'encoding' : 'ascii', 'object' : 'a', 502 'start' : 0, 'reason' : 'ordinal not in range'}), 503 (UnicodeDecodeError, ('ascii', bytearray(b'\xff'), 0, 1, 504 'ordinal not in range'), {}, 505 {'args' : ('ascii', bytearray(b'\xff'), 0, 1, 506 'ordinal not in range'), 507 'encoding' : 'ascii', 'object' : b'\xff', 508 'start' : 0, 'reason' : 'ordinal not in range'}), 509 (UnicodeDecodeError, ('ascii', b'\xff', 0, 1, 510 'ordinal not in range'), {}, 511 {'args' : ('ascii', b'\xff', 0, 1, 512 'ordinal not in range'), 513 'encoding' : 'ascii', 'object' : b'\xff', 514 'start' : 0, 'reason' : 'ordinal not in range'}), 515 (UnicodeTranslateError, ("\u3042", 0, 1, "ouch"), {}, 516 {'args' : ('\u3042', 0, 1, 'ouch'), 517 'object' : '\u3042', 'reason' : 'ouch', 518 'start' : 0, 'end' : 1}), 519 (NaiveException, ('foo',), {}, 520 {'args': ('foo',), 'x': 'foo'}), 521 (SlottedNaiveException, ('foo',), {}, 522 {'args': ('foo',), 'x': 'foo'}), 523 (AttributeError, ('foo',), dict(name='name', obj='obj'), 524 dict(args=('foo',), name='name', obj='obj')), 525 ] 526 try: 527 # More tests are in test_WindowsError 528 exceptionList.append( 529 (WindowsError, (1, 'strErrorStr', 'filenameStr'), {}, 530 {'args' : (1, 'strErrorStr'), 531 'strerror' : 'strErrorStr', 'winerror' : None, 532 'errno' : 1, 533 'filename' : 'filenameStr', 'filename2' : None}) 534 ) 535 except NameError: 536 pass 537 538 for exc, args, kwargs, expected in exceptionList: 539 try: 540 e = exc(*args, **kwargs) 541 except: 542 print(f"\nexc={exc!r}, args={args!r}", file=sys.stderr) 543 # raise 544 else: 545 # Verify module name 546 if not type(e).__name__.endswith('NaiveException'): 547 self.assertEqual(type(e).__module__, 'builtins') 548 # Verify no ref leaks in Exc_str() 549 s = str(e) 550 for checkArgName in expected: 551 value = getattr(e, checkArgName) 552 self.assertEqual(repr(value), 553 repr(expected[checkArgName]), 554 '%r.%s == %r, expected %r' % ( 555 e, checkArgName, 556 value, expected[checkArgName])) 557 558 # test for pickling support 559 for p in [pickle]: 560 for protocol in range(p.HIGHEST_PROTOCOL + 1): 561 s = p.dumps(e, protocol) 562 new = p.loads(s) 563 for checkArgName in expected: 564 got = repr(getattr(new, checkArgName)) 565 if exc == AttributeError and checkArgName == 'obj': 566 # See GH-103352, we're not pickling 567 # obj at this point. So verify it's None. 568 want = repr(None) 569 else: 570 want = repr(expected[checkArgName]) 571 self.assertEqual(got, want, 572 'pickled "%r", attribute "%s' % 573 (e, checkArgName)) 574 575 def test_setstate(self): 576 e = Exception(42) 577 e.blah = 53 578 self.assertEqual(e.args, (42,)) 579 self.assertEqual(e.blah, 53) 580 self.assertRaises(AttributeError, getattr, e, 'a') 581 self.assertRaises(AttributeError, getattr, e, 'b') 582 e.__setstate__({'a': 1 , 'b': 2}) 583 self.assertEqual(e.args, (42,)) 584 self.assertEqual(e.blah, 53) 585 self.assertEqual(e.a, 1) 586 self.assertEqual(e.b, 2) 587 e.__setstate__({'a': 11, 'args': (1,2,3), 'blah': 35}) 588 self.assertEqual(e.args, (1,2,3)) 589 self.assertEqual(e.blah, 35) 590 self.assertEqual(e.a, 11) 591 self.assertEqual(e.b, 2) 592 593 def test_invalid_setstate(self): 594 e = Exception(42) 595 with self.assertRaisesRegex(TypeError, "state is not a dictionary"): 596 e.__setstate__(42) 597 598 def test_notes(self): 599 for e in [BaseException(1), Exception(2), ValueError(3)]: 600 with self.subTest(e=e): 601 self.assertFalse(hasattr(e, '__notes__')) 602 e.add_note("My Note") 603 self.assertEqual(e.__notes__, ["My Note"]) 604 605 with self.assertRaises(TypeError): 606 e.add_note(42) 607 self.assertEqual(e.__notes__, ["My Note"]) 608 609 e.add_note("Your Note") 610 self.assertEqual(e.__notes__, ["My Note", "Your Note"]) 611 612 del e.__notes__ 613 self.assertFalse(hasattr(e, '__notes__')) 614 615 e.add_note("Our Note") 616 self.assertEqual(e.__notes__, ["Our Note"]) 617 618 e.__notes__ = 42 619 self.assertEqual(e.__notes__, 42) 620 621 with self.assertRaises(TypeError): 622 e.add_note("will not work") 623 self.assertEqual(e.__notes__, 42) 624 625 def testWithTraceback(self): 626 try: 627 raise IndexError(4) 628 except Exception as e: 629 tb = e.__traceback__ 630 631 e = BaseException().with_traceback(tb) 632 self.assertIsInstance(e, BaseException) 633 self.assertEqual(e.__traceback__, tb) 634 635 e = IndexError(5).with_traceback(tb) 636 self.assertIsInstance(e, IndexError) 637 self.assertEqual(e.__traceback__, tb) 638 639 class MyException(Exception): 640 pass 641 642 e = MyException().with_traceback(tb) 643 self.assertIsInstance(e, MyException) 644 self.assertEqual(e.__traceback__, tb) 645 646 def testInvalidTraceback(self): 647 try: 648 Exception().__traceback__ = 5 649 except TypeError as e: 650 self.assertIn("__traceback__ must be a traceback", str(e)) 651 else: 652 self.fail("No exception raised") 653 654 def test_invalid_setattr(self): 655 TE = TypeError 656 exc = Exception() 657 msg = "'int' object is not iterable" 658 self.assertRaisesRegex(TE, msg, setattr, exc, 'args', 1) 659 msg = "__traceback__ must be a traceback or None" 660 self.assertRaisesRegex(TE, msg, setattr, exc, '__traceback__', 1) 661 msg = "exception cause must be None or derive from BaseException" 662 self.assertRaisesRegex(TE, msg, setattr, exc, '__cause__', 1) 663 msg = "exception context must be None or derive from BaseException" 664 self.assertRaisesRegex(TE, msg, setattr, exc, '__context__', 1) 665 666 def test_invalid_delattr(self): 667 TE = TypeError 668 try: 669 raise IndexError(4) 670 except Exception as e: 671 exc = e 672 673 msg = "may not be deleted" 674 self.assertRaisesRegex(TE, msg, delattr, exc, 'args') 675 self.assertRaisesRegex(TE, msg, delattr, exc, '__traceback__') 676 self.assertRaisesRegex(TE, msg, delattr, exc, '__cause__') 677 self.assertRaisesRegex(TE, msg, delattr, exc, '__context__') 678 679 def testNoneClearsTracebackAttr(self): 680 try: 681 raise IndexError(4) 682 except Exception as e: 683 tb = e.__traceback__ 684 685 e = Exception() 686 e.__traceback__ = tb 687 e.__traceback__ = None 688 self.assertEqual(e.__traceback__, None) 689 690 def testChainingAttrs(self): 691 e = Exception() 692 self.assertIsNone(e.__context__) 693 self.assertIsNone(e.__cause__) 694 695 e = TypeError() 696 self.assertIsNone(e.__context__) 697 self.assertIsNone(e.__cause__) 698 699 class MyException(OSError): 700 pass 701 702 e = MyException() 703 self.assertIsNone(e.__context__) 704 self.assertIsNone(e.__cause__) 705 706 def testChainingDescriptors(self): 707 try: 708 raise Exception() 709 except Exception as exc: 710 e = exc 711 712 self.assertIsNone(e.__context__) 713 self.assertIsNone(e.__cause__) 714 self.assertFalse(e.__suppress_context__) 715 716 e.__context__ = NameError() 717 e.__cause__ = None 718 self.assertIsInstance(e.__context__, NameError) 719 self.assertIsNone(e.__cause__) 720 self.assertTrue(e.__suppress_context__) 721 e.__suppress_context__ = False 722 self.assertFalse(e.__suppress_context__) 723 724 def testKeywordArgs(self): 725 # test that builtin exception don't take keyword args, 726 # but user-defined subclasses can if they want 727 self.assertRaises(TypeError, BaseException, a=1) 728 729 class DerivedException(BaseException): 730 def __init__(self, fancy_arg): 731 BaseException.__init__(self) 732 self.fancy_arg = fancy_arg 733 734 x = DerivedException(fancy_arg=42) 735 self.assertEqual(x.fancy_arg, 42) 736 737 @no_tracing 738 def testInfiniteRecursion(self): 739 def f(): 740 return f() 741 self.assertRaises(RecursionError, f) 742 743 def g(): 744 try: 745 return g() 746 except ValueError: 747 return -1 748 self.assertRaises(RecursionError, g) 749 750 def test_str(self): 751 # Make sure both instances and classes have a str representation. 752 self.assertTrue(str(Exception)) 753 self.assertTrue(str(Exception('a'))) 754 self.assertTrue(str(Exception('a', 'b'))) 755 756 def test_exception_cleanup_names(self): 757 # Make sure the local variable bound to the exception instance by 758 # an "except" statement is only visible inside the except block. 759 try: 760 raise Exception() 761 except Exception as e: 762 self.assertIsInstance(e, Exception) 763 self.assertNotIn('e', locals()) 764 with self.assertRaises(UnboundLocalError): 765 e 766 767 def test_exception_cleanup_names2(self): 768 # Make sure the cleanup doesn't break if the variable is explicitly deleted. 769 try: 770 raise Exception() 771 except Exception as e: 772 self.assertIsInstance(e, Exception) 773 del e 774 self.assertNotIn('e', locals()) 775 with self.assertRaises(UnboundLocalError): 776 e 777 778 def testExceptionCleanupState(self): 779 # Make sure exception state is cleaned up as soon as the except 780 # block is left. See #2507 781 782 class MyException(Exception): 783 def __init__(self, obj): 784 self.obj = obj 785 class MyObj: 786 pass 787 788 def inner_raising_func(): 789 # Create some references in exception value and traceback 790 local_ref = obj 791 raise MyException(obj) 792 793 # Qualified "except" with "as" 794 obj = MyObj() 795 wr = weakref.ref(obj) 796 try: 797 inner_raising_func() 798 except MyException as e: 799 pass 800 obj = None 801 gc_collect() # For PyPy or other GCs. 802 obj = wr() 803 self.assertIsNone(obj) 804 805 # Qualified "except" without "as" 806 obj = MyObj() 807 wr = weakref.ref(obj) 808 try: 809 inner_raising_func() 810 except MyException: 811 pass 812 obj = None 813 gc_collect() # For PyPy or other GCs. 814 obj = wr() 815 self.assertIsNone(obj) 816 817 # Bare "except" 818 obj = MyObj() 819 wr = weakref.ref(obj) 820 try: 821 inner_raising_func() 822 except: 823 pass 824 obj = None 825 gc_collect() # For PyPy or other GCs. 826 obj = wr() 827 self.assertIsNone(obj) 828 829 # "except" with premature block leave 830 obj = MyObj() 831 wr = weakref.ref(obj) 832 for i in [0]: 833 try: 834 inner_raising_func() 835 except: 836 break 837 obj = None 838 gc_collect() # For PyPy or other GCs. 839 obj = wr() 840 self.assertIsNone(obj) 841 842 # "except" block raising another exception 843 obj = MyObj() 844 wr = weakref.ref(obj) 845 try: 846 try: 847 inner_raising_func() 848 except: 849 raise KeyError 850 except KeyError as e: 851 # We want to test that the except block above got rid of 852 # the exception raised in inner_raising_func(), but it 853 # also ends up in the __context__ of the KeyError, so we 854 # must clear the latter manually for our test to succeed. 855 e.__context__ = None 856 obj = None 857 gc_collect() # For PyPy or other GCs. 858 obj = wr() 859 # guarantee no ref cycles on CPython (don't gc_collect) 860 if check_impl_detail(cpython=False): 861 gc_collect() 862 self.assertIsNone(obj) 863 864 # Some complicated construct 865 obj = MyObj() 866 wr = weakref.ref(obj) 867 try: 868 inner_raising_func() 869 except MyException: 870 try: 871 try: 872 raise 873 finally: 874 raise 875 except MyException: 876 pass 877 obj = None 878 if check_impl_detail(cpython=False): 879 gc_collect() 880 obj = wr() 881 self.assertIsNone(obj) 882 883 # Inside an exception-silencing "with" block 884 class Context: 885 def __enter__(self): 886 return self 887 def __exit__ (self, exc_type, exc_value, exc_tb): 888 return True 889 obj = MyObj() 890 wr = weakref.ref(obj) 891 with Context(): 892 inner_raising_func() 893 obj = None 894 if check_impl_detail(cpython=False): 895 gc_collect() 896 obj = wr() 897 self.assertIsNone(obj) 898 899 def test_exception_target_in_nested_scope(self): 900 # issue 4617: This used to raise a SyntaxError 901 # "can not delete variable 'e' referenced in nested scope" 902 def print_error(): 903 e 904 try: 905 something 906 except Exception as e: 907 print_error() 908 # implicit "del e" here 909 910 def test_generator_leaking(self): 911 # Test that generator exception state doesn't leak into the calling 912 # frame 913 def yield_raise(): 914 try: 915 raise KeyError("caught") 916 except KeyError: 917 yield sys.exception() 918 yield sys.exception() 919 yield sys.exception() 920 g = yield_raise() 921 self.assertIsInstance(next(g), KeyError) 922 self.assertIsNone(sys.exception()) 923 self.assertIsInstance(next(g), KeyError) 924 self.assertIsNone(sys.exception()) 925 self.assertIsNone(next(g)) 926 927 # Same test, but inside an exception handler 928 try: 929 raise TypeError("foo") 930 except TypeError: 931 g = yield_raise() 932 self.assertIsInstance(next(g), KeyError) 933 self.assertIsInstance(sys.exception(), TypeError) 934 self.assertIsInstance(next(g), KeyError) 935 self.assertIsInstance(sys.exception(), TypeError) 936 self.assertIsInstance(next(g), TypeError) 937 del g 938 self.assertIsInstance(sys.exception(), TypeError) 939 940 def test_generator_leaking2(self): 941 # See issue 12475. 942 def g(): 943 yield 944 try: 945 raise RuntimeError 946 except RuntimeError: 947 it = g() 948 next(it) 949 try: 950 next(it) 951 except StopIteration: 952 pass 953 self.assertIsNone(sys.exception()) 954 955 def test_generator_leaking3(self): 956 # See issue #23353. When gen.throw() is called, the caller's 957 # exception state should be save and restored. 958 def g(): 959 try: 960 yield 961 except ZeroDivisionError: 962 yield sys.exception() 963 it = g() 964 next(it) 965 try: 966 1/0 967 except ZeroDivisionError as e: 968 self.assertIs(sys.exception(), e) 969 gen_exc = it.throw(e) 970 self.assertIs(sys.exception(), e) 971 self.assertIs(gen_exc, e) 972 self.assertIsNone(sys.exception()) 973 974 def test_generator_leaking4(self): 975 # See issue #23353. When an exception is raised by a generator, 976 # the caller's exception state should still be restored. 977 def g(): 978 try: 979 1/0 980 except ZeroDivisionError: 981 yield sys.exception() 982 raise 983 it = g() 984 try: 985 raise TypeError 986 except TypeError: 987 # The caller's exception state (TypeError) is temporarily 988 # saved in the generator. 989 tp = type(next(it)) 990 self.assertIs(tp, ZeroDivisionError) 991 try: 992 next(it) 993 # We can't check it immediately, but while next() returns 994 # with an exception, it shouldn't have restored the old 995 # exception state (TypeError). 996 except ZeroDivisionError as e: 997 self.assertIs(sys.exception(), e) 998 # We used to find TypeError here. 999 self.assertIsNone(sys.exception()) 1000 1001 def test_generator_doesnt_retain_old_exc(self): 1002 def g(): 1003 self.assertIsInstance(sys.exception(), RuntimeError) 1004 yield 1005 self.assertIsNone(sys.exception()) 1006 it = g() 1007 try: 1008 raise RuntimeError 1009 except RuntimeError: 1010 next(it) 1011 self.assertRaises(StopIteration, next, it) 1012 1013 def test_generator_finalizing_and_sys_exception(self): 1014 # See #7173 1015 def simple_gen(): 1016 yield 1 1017 def run_gen(): 1018 gen = simple_gen() 1019 try: 1020 raise RuntimeError 1021 except RuntimeError: 1022 return next(gen) 1023 run_gen() 1024 gc_collect() 1025 self.assertIsNone(sys.exception()) 1026 1027 def _check_generator_cleanup_exc_state(self, testfunc): 1028 # Issue #12791: exception state is cleaned up as soon as a generator 1029 # is closed (reference cycles are broken). 1030 class MyException(Exception): 1031 def __init__(self, obj): 1032 self.obj = obj 1033 class MyObj: 1034 pass 1035 1036 def raising_gen(): 1037 try: 1038 raise MyException(obj) 1039 except MyException: 1040 yield 1041 1042 obj = MyObj() 1043 wr = weakref.ref(obj) 1044 g = raising_gen() 1045 next(g) 1046 testfunc(g) 1047 g = obj = None 1048 gc_collect() # For PyPy or other GCs. 1049 obj = wr() 1050 self.assertIsNone(obj) 1051 1052 def test_generator_throw_cleanup_exc_state(self): 1053 def do_throw(g): 1054 try: 1055 g.throw(RuntimeError()) 1056 except RuntimeError: 1057 pass 1058 self._check_generator_cleanup_exc_state(do_throw) 1059 1060 def test_generator_close_cleanup_exc_state(self): 1061 def do_close(g): 1062 g.close() 1063 self._check_generator_cleanup_exc_state(do_close) 1064 1065 def test_generator_del_cleanup_exc_state(self): 1066 def do_del(g): 1067 g = None 1068 self._check_generator_cleanup_exc_state(do_del) 1069 1070 def test_generator_next_cleanup_exc_state(self): 1071 def do_next(g): 1072 try: 1073 next(g) 1074 except StopIteration: 1075 pass 1076 else: 1077 self.fail("should have raised StopIteration") 1078 self._check_generator_cleanup_exc_state(do_next) 1079 1080 def test_generator_send_cleanup_exc_state(self): 1081 def do_send(g): 1082 try: 1083 g.send(None) 1084 except StopIteration: 1085 pass 1086 else: 1087 self.fail("should have raised StopIteration") 1088 self._check_generator_cleanup_exc_state(do_send) 1089 1090 def test_3114(self): 1091 # Bug #3114: in its destructor, MyObject retrieves a pointer to 1092 # obsolete and/or deallocated objects. 1093 class MyObject: 1094 def __del__(self): 1095 nonlocal e 1096 e = sys.exception() 1097 e = () 1098 try: 1099 raise Exception(MyObject()) 1100 except: 1101 pass 1102 gc_collect() # For PyPy or other GCs. 1103 self.assertIsNone(e) 1104 1105 def test_raise_does_not_create_context_chain_cycle(self): 1106 class A(Exception): 1107 pass 1108 class B(Exception): 1109 pass 1110 class C(Exception): 1111 pass 1112 1113 # Create a context chain: 1114 # C -> B -> A 1115 # Then raise A in context of C. 1116 try: 1117 try: 1118 raise A 1119 except A as a_: 1120 a = a_ 1121 try: 1122 raise B 1123 except B as b_: 1124 b = b_ 1125 try: 1126 raise C 1127 except C as c_: 1128 c = c_ 1129 self.assertIsInstance(a, A) 1130 self.assertIsInstance(b, B) 1131 self.assertIsInstance(c, C) 1132 self.assertIsNone(a.__context__) 1133 self.assertIs(b.__context__, a) 1134 self.assertIs(c.__context__, b) 1135 raise a 1136 except A as e: 1137 exc = e 1138 1139 # Expect A -> C -> B, without cycle 1140 self.assertIs(exc, a) 1141 self.assertIs(a.__context__, c) 1142 self.assertIs(c.__context__, b) 1143 self.assertIsNone(b.__context__) 1144 1145 def test_no_hang_on_context_chain_cycle1(self): 1146 # See issue 25782. Cycle in context chain. 1147 1148 def cycle(): 1149 try: 1150 raise ValueError(1) 1151 except ValueError as ex: 1152 ex.__context__ = ex 1153 raise TypeError(2) 1154 1155 try: 1156 cycle() 1157 except Exception as e: 1158 exc = e 1159 1160 self.assertIsInstance(exc, TypeError) 1161 self.assertIsInstance(exc.__context__, ValueError) 1162 self.assertIs(exc.__context__.__context__, exc.__context__) 1163 1164 def test_no_hang_on_context_chain_cycle2(self): 1165 # See issue 25782. Cycle at head of context chain. 1166 1167 class A(Exception): 1168 pass 1169 class B(Exception): 1170 pass 1171 class C(Exception): 1172 pass 1173 1174 # Context cycle: 1175 # +-----------+ 1176 # V | 1177 # C --> B --> A 1178 with self.assertRaises(C) as cm: 1179 try: 1180 raise A() 1181 except A as _a: 1182 a = _a 1183 try: 1184 raise B() 1185 except B as _b: 1186 b = _b 1187 try: 1188 raise C() 1189 except C as _c: 1190 c = _c 1191 a.__context__ = c 1192 raise c 1193 1194 self.assertIs(cm.exception, c) 1195 # Verify the expected context chain cycle 1196 self.assertIs(c.__context__, b) 1197 self.assertIs(b.__context__, a) 1198 self.assertIs(a.__context__, c) 1199 1200 def test_no_hang_on_context_chain_cycle3(self): 1201 # See issue 25782. Longer context chain with cycle. 1202 1203 class A(Exception): 1204 pass 1205 class B(Exception): 1206 pass 1207 class C(Exception): 1208 pass 1209 class D(Exception): 1210 pass 1211 class E(Exception): 1212 pass 1213 1214 # Context cycle: 1215 # +-----------+ 1216 # V | 1217 # E --> D --> C --> B --> A 1218 with self.assertRaises(E) as cm: 1219 try: 1220 raise A() 1221 except A as _a: 1222 a = _a 1223 try: 1224 raise B() 1225 except B as _b: 1226 b = _b 1227 try: 1228 raise C() 1229 except C as _c: 1230 c = _c 1231 a.__context__ = c 1232 try: 1233 raise D() 1234 except D as _d: 1235 d = _d 1236 e = E() 1237 raise e 1238 1239 self.assertIs(cm.exception, e) 1240 # Verify the expected context chain cycle 1241 self.assertIs(e.__context__, d) 1242 self.assertIs(d.__context__, c) 1243 self.assertIs(c.__context__, b) 1244 self.assertIs(b.__context__, a) 1245 self.assertIs(a.__context__, c) 1246 1247 def test_context_of_exception_in_try_and_finally(self): 1248 try: 1249 try: 1250 te = TypeError(1) 1251 raise te 1252 finally: 1253 ve = ValueError(2) 1254 raise ve 1255 except Exception as e: 1256 exc = e 1257 1258 self.assertIs(exc, ve) 1259 self.assertIs(exc.__context__, te) 1260 1261 def test_context_of_exception_in_except_and_finally(self): 1262 try: 1263 try: 1264 te = TypeError(1) 1265 raise te 1266 except: 1267 ve = ValueError(2) 1268 raise ve 1269 finally: 1270 oe = OSError(3) 1271 raise oe 1272 except Exception as e: 1273 exc = e 1274 1275 self.assertIs(exc, oe) 1276 self.assertIs(exc.__context__, ve) 1277 self.assertIs(exc.__context__.__context__, te) 1278 1279 def test_context_of_exception_in_else_and_finally(self): 1280 try: 1281 try: 1282 pass 1283 except: 1284 pass 1285 else: 1286 ve = ValueError(1) 1287 raise ve 1288 finally: 1289 oe = OSError(2) 1290 raise oe 1291 except Exception as e: 1292 exc = e 1293 1294 self.assertIs(exc, oe) 1295 self.assertIs(exc.__context__, ve) 1296 1297 def test_unicode_change_attributes(self): 1298 # See issue 7309. This was a crasher. 1299 1300 u = UnicodeEncodeError('baz', 'xxxxx', 1, 5, 'foo') 1301 self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: foo") 1302 u.end = 2 1303 self.assertEqual(str(u), "'baz' codec can't encode character '\\x78' in position 1: foo") 1304 u.end = 5 1305 u.reason = 0x345345345345345345 1306 self.assertEqual(str(u), "'baz' codec can't encode characters in position 1-4: 965230951443685724997") 1307 u.encoding = 4000 1308 self.assertEqual(str(u), "'4000' codec can't encode characters in position 1-4: 965230951443685724997") 1309 u.start = 1000 1310 self.assertEqual(str(u), "'4000' codec can't encode characters in position 1000-4: 965230951443685724997") 1311 1312 u = UnicodeDecodeError('baz', b'xxxxx', 1, 5, 'foo') 1313 self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: foo") 1314 u.end = 2 1315 self.assertEqual(str(u), "'baz' codec can't decode byte 0x78 in position 1: foo") 1316 u.end = 5 1317 u.reason = 0x345345345345345345 1318 self.assertEqual(str(u), "'baz' codec can't decode bytes in position 1-4: 965230951443685724997") 1319 u.encoding = 4000 1320 self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1-4: 965230951443685724997") 1321 u.start = 1000 1322 self.assertEqual(str(u), "'4000' codec can't decode bytes in position 1000-4: 965230951443685724997") 1323 1324 u = UnicodeTranslateError('xxxx', 1, 5, 'foo') 1325 self.assertEqual(str(u), "can't translate characters in position 1-4: foo") 1326 u.end = 2 1327 self.assertEqual(str(u), "can't translate character '\\x78' in position 1: foo") 1328 u.end = 5 1329 u.reason = 0x345345345345345345 1330 self.assertEqual(str(u), "can't translate characters in position 1-4: 965230951443685724997") 1331 u.start = 1000 1332 self.assertEqual(str(u), "can't translate characters in position 1000-4: 965230951443685724997") 1333 1334 def test_unicode_errors_no_object(self): 1335 # See issue #21134. 1336 klasses = UnicodeEncodeError, UnicodeDecodeError, UnicodeTranslateError 1337 for klass in klasses: 1338 self.assertEqual(str(klass.__new__(klass)), "") 1339 1340 def test_unicode_error_str_does_not_crash(self): 1341 # Test that str(UnicodeError(...)) does not crash. 1342 # See https://github.com/python/cpython/issues/123378. 1343 1344 for start, end, objlen in product( 1345 range(-5, 5), 1346 range(-5, 5), 1347 range(7), 1348 ): 1349 obj = 'a' * objlen 1350 with self.subTest('encode', objlen=objlen, start=start, end=end): 1351 exc = UnicodeEncodeError('utf-8', obj, start, end, '') 1352 self.assertIsInstance(str(exc), str) 1353 1354 with self.subTest('translate', objlen=objlen, start=start, end=end): 1355 exc = UnicodeTranslateError(obj, start, end, '') 1356 self.assertIsInstance(str(exc), str) 1357 1358 encoded = obj.encode() 1359 with self.subTest('decode', objlen=objlen, start=start, end=end): 1360 exc = UnicodeDecodeError('utf-8', encoded, start, end, '') 1361 self.assertIsInstance(str(exc), str) 1362 1363 @no_tracing 1364 def test_badisinstance(self): 1365 # Bug #2542: if issubclass(e, MyException) raises an exception, 1366 # it should be ignored 1367 class Meta(type): 1368 def __subclasscheck__(cls, subclass): 1369 raise ValueError() 1370 class MyException(Exception, metaclass=Meta): 1371 pass 1372 1373 with captured_stderr() as stderr: 1374 try: 1375 raise KeyError() 1376 except MyException as e: 1377 self.fail("exception should not be a MyException") 1378 except KeyError: 1379 pass 1380 except: 1381 self.fail("Should have raised KeyError") 1382 else: 1383 self.fail("Should have raised KeyError") 1384 1385 def g(): 1386 try: 1387 return g() 1388 except RecursionError as e: 1389 return e 1390 exc = g() 1391 self.assertIsInstance(exc, RecursionError, type(exc)) 1392 self.assertIn("maximum recursion depth exceeded", str(exc)) 1393 1394 1395 @cpython_only 1396 @support.requires_resource('cpu') 1397 def test_trashcan_recursion(self): 1398 # See bpo-33930 1399 1400 def foo(): 1401 o = object() 1402 for x in range(1_000_000): 1403 # Create a big chain of method objects that will trigger 1404 # a deep chain of calls when they need to be destructed. 1405 o = o.__dir__ 1406 1407 foo() 1408 support.gc_collect() 1409 1410 @cpython_only 1411 def test_recursion_normalizing_exception(self): 1412 import_module("_testinternalcapi") 1413 # Issue #22898. 1414 # Test that a RecursionError is raised when tstate->recursion_depth is 1415 # equal to recursion_limit in PyErr_NormalizeException() and check 1416 # that a ResourceWarning is printed. 1417 # Prior to #22898, the recursivity of PyErr_NormalizeException() was 1418 # controlled by tstate->recursion_depth and a PyExc_RecursionErrorInst 1419 # singleton was being used in that case, that held traceback data and 1420 # locals indefinitely and would cause a segfault in _PyExc_Fini() upon 1421 # finalization of these locals. 1422 code = """if 1: 1423 import sys 1424 from _testinternalcapi import get_recursion_depth 1425 from test import support 1426 1427 class MyException(Exception): pass 1428 1429 def setrecursionlimit(depth): 1430 while 1: 1431 try: 1432 sys.setrecursionlimit(depth) 1433 return depth 1434 except RecursionError: 1435 # sys.setrecursionlimit() raises a RecursionError if 1436 # the new recursion limit is too low (issue #25274). 1437 depth += 1 1438 1439 def recurse(cnt): 1440 cnt -= 1 1441 if cnt: 1442 recurse(cnt) 1443 else: 1444 generator.throw(MyException) 1445 1446 def gen(): 1447 f = open(%a, mode='rb', buffering=0) 1448 yield 1449 1450 generator = gen() 1451 next(generator) 1452 recursionlimit = sys.getrecursionlimit() 1453 try: 1454 recurse(support.exceeds_recursion_limit()) 1455 finally: 1456 sys.setrecursionlimit(recursionlimit) 1457 print('Done.') 1458 """ % __file__ 1459 rc, out, err = script_helper.assert_python_failure("-Wd", "-c", code) 1460 # Check that the program does not fail with SIGABRT. 1461 self.assertEqual(rc, 1) 1462 self.assertIn(b'RecursionError', err) 1463 self.assertIn(b'ResourceWarning', err) 1464 self.assertIn(b'Done.', out) 1465 1466 @cpython_only 1467 @unittest.skipIf(_testcapi is None, "requires _testcapi") 1468 def test_recursion_normalizing_infinite_exception(self): 1469 # Issue #30697. Test that a RecursionError is raised when 1470 # maximum recursion depth has been exceeded when creating 1471 # an exception 1472 code = """if 1: 1473 import _testcapi 1474 try: 1475 raise _testcapi.RecursingInfinitelyError 1476 finally: 1477 print('Done.') 1478 """ 1479 rc, out, err = script_helper.assert_python_failure("-c", code) 1480 self.assertEqual(rc, 1) 1481 expected = b'RecursionError: maximum recursion depth exceeded' 1482 self.assertTrue(expected in err, msg=f"{expected!r} not found in {err[:3_000]!r}... (truncated)") 1483 self.assertIn(b'Done.', out) 1484 1485 1486 def test_recursion_in_except_handler(self): 1487 1488 def set_relative_recursion_limit(n): 1489 depth = 1 1490 while True: 1491 try: 1492 sys.setrecursionlimit(depth) 1493 except RecursionError: 1494 depth += 1 1495 else: 1496 break 1497 sys.setrecursionlimit(depth+n) 1498 1499 def recurse_in_except(): 1500 try: 1501 1/0 1502 except: 1503 recurse_in_except() 1504 1505 def recurse_after_except(): 1506 try: 1507 1/0 1508 except: 1509 pass 1510 recurse_after_except() 1511 1512 def recurse_in_body_and_except(): 1513 try: 1514 recurse_in_body_and_except() 1515 except: 1516 recurse_in_body_and_except() 1517 1518 recursionlimit = sys.getrecursionlimit() 1519 try: 1520 set_relative_recursion_limit(10) 1521 for func in (recurse_in_except, recurse_after_except, recurse_in_body_and_except): 1522 with self.subTest(func=func): 1523 try: 1524 func() 1525 except RecursionError: 1526 pass 1527 else: 1528 self.fail("Should have raised a RecursionError") 1529 finally: 1530 sys.setrecursionlimit(recursionlimit) 1531 1532 1533 @cpython_only 1534 # Python built with Py_TRACE_REFS fail with a fatal error in 1535 # _PyRefchain_Trace() on memory allocation error. 1536 @unittest.skipIf(support.Py_TRACE_REFS, 'cannot test Py_TRACE_REFS build') 1537 @unittest.skipIf(_testcapi is None, "requires _testcapi") 1538 def test_recursion_normalizing_with_no_memory(self): 1539 # Issue #30697. Test that in the abort that occurs when there is no 1540 # memory left and the size of the Python frames stack is greater than 1541 # the size of the list of preallocated MemoryError instances, the 1542 # Fatal Python error message mentions MemoryError. 1543 code = """if 1: 1544 import _testcapi 1545 class C(): pass 1546 def recurse(cnt): 1547 cnt -= 1 1548 if cnt: 1549 recurse(cnt) 1550 else: 1551 _testcapi.set_nomemory(0) 1552 C() 1553 recurse(16) 1554 """ 1555 with SuppressCrashReport(): 1556 rc, out, err = script_helper.assert_python_failure("-c", code) 1557 self.assertIn(b'MemoryError', err) 1558 1559 @cpython_only 1560 @unittest.skipIf(_testcapi is None, "requires _testcapi") 1561 def test_MemoryError(self): 1562 # PyErr_NoMemory always raises the same exception instance. 1563 # Check that the traceback is not doubled. 1564 import traceback 1565 from _testcapi import raise_memoryerror 1566 def raiseMemError(): 1567 try: 1568 raise_memoryerror() 1569 except MemoryError as e: 1570 tb = e.__traceback__ 1571 else: 1572 self.fail("Should have raised a MemoryError") 1573 return traceback.format_tb(tb) 1574 1575 tb1 = raiseMemError() 1576 tb2 = raiseMemError() 1577 self.assertEqual(tb1, tb2) 1578 1579 @cpython_only 1580 @unittest.skipIf(_testcapi is None, "requires _testcapi") 1581 def test_exception_with_doc(self): 1582 doc2 = "This is a test docstring." 1583 doc4 = "This is another test docstring." 1584 1585 self.assertRaises(SystemError, _testcapi.make_exception_with_doc, 1586 "error1") 1587 1588 # test basic usage of PyErr_NewException 1589 error1 = _testcapi.make_exception_with_doc("_testcapi.error1") 1590 self.assertIs(type(error1), type) 1591 self.assertTrue(issubclass(error1, Exception)) 1592 self.assertIsNone(error1.__doc__) 1593 1594 # test with given docstring 1595 error2 = _testcapi.make_exception_with_doc("_testcapi.error2", doc2) 1596 self.assertEqual(error2.__doc__, doc2) 1597 1598 # test with explicit base (without docstring) 1599 error3 = _testcapi.make_exception_with_doc("_testcapi.error3", 1600 base=error2) 1601 self.assertTrue(issubclass(error3, error2)) 1602 1603 # test with explicit base tuple 1604 class C(object): 1605 pass 1606 error4 = _testcapi.make_exception_with_doc("_testcapi.error4", doc4, 1607 (error3, C)) 1608 self.assertTrue(issubclass(error4, error3)) 1609 self.assertTrue(issubclass(error4, C)) 1610 self.assertEqual(error4.__doc__, doc4) 1611 1612 # test with explicit dictionary 1613 error5 = _testcapi.make_exception_with_doc("_testcapi.error5", "", 1614 error4, {'a': 1}) 1615 self.assertTrue(issubclass(error5, error4)) 1616 self.assertEqual(error5.a, 1) 1617 self.assertEqual(error5.__doc__, "") 1618 1619 @cpython_only 1620 @unittest.skipIf(_testcapi is None, "requires _testcapi") 1621 def test_memory_error_cleanup(self): 1622 # Issue #5437: preallocated MemoryError instances should not keep 1623 # traceback objects alive. 1624 from _testcapi import raise_memoryerror 1625 class C: 1626 pass 1627 wr = None 1628 def inner(): 1629 nonlocal wr 1630 c = C() 1631 wr = weakref.ref(c) 1632 raise_memoryerror() 1633 # We cannot use assertRaises since it manually deletes the traceback 1634 try: 1635 inner() 1636 except MemoryError as e: 1637 self.assertNotEqual(wr(), None) 1638 else: 1639 self.fail("MemoryError not raised") 1640 gc_collect() # For PyPy or other GCs. 1641 self.assertEqual(wr(), None) 1642 1643 @no_tracing 1644 def test_recursion_error_cleanup(self): 1645 # Same test as above, but with "recursion exceeded" errors 1646 class C: 1647 pass 1648 wr = None 1649 def inner(): 1650 nonlocal wr 1651 c = C() 1652 wr = weakref.ref(c) 1653 inner() 1654 # We cannot use assertRaises since it manually deletes the traceback 1655 try: 1656 inner() 1657 except RecursionError as e: 1658 self.assertNotEqual(wr(), None) 1659 else: 1660 self.fail("RecursionError not raised") 1661 gc_collect() # For PyPy or other GCs. 1662 self.assertEqual(wr(), None) 1663 1664 def test_errno_ENOTDIR(self): 1665 # Issue #12802: "not a directory" errors are ENOTDIR even on Windows 1666 with self.assertRaises(OSError) as cm: 1667 os.listdir(__file__) 1668 self.assertEqual(cm.exception.errno, errno.ENOTDIR, cm.exception) 1669 1670 def test_unraisable(self): 1671 # Issue #22836: PyErr_WriteUnraisable() should give sensible reports 1672 class BrokenDel: 1673 def __del__(self): 1674 exc = ValueError("del is broken") 1675 # The following line is included in the traceback report: 1676 raise exc 1677 1678 obj = BrokenDel() 1679 with support.catch_unraisable_exception() as cm: 1680 del obj 1681 1682 gc_collect() # For PyPy or other GCs. 1683 self.assertEqual(cm.unraisable.object, BrokenDel.__del__) 1684 self.assertIsNotNone(cm.unraisable.exc_traceback) 1685 1686 def test_unhandled(self): 1687 # Check for sensible reporting of unhandled exceptions 1688 for exc_type in (ValueError, BrokenStrException): 1689 with self.subTest(exc_type): 1690 try: 1691 exc = exc_type("test message") 1692 # The following line is included in the traceback report: 1693 raise exc 1694 except exc_type: 1695 with captured_stderr() as stderr: 1696 sys.__excepthook__(*sys.exc_info()) 1697 report = stderr.getvalue() 1698 self.assertIn("test_exceptions.py", report) 1699 self.assertIn("raise exc", report) 1700 self.assertIn(exc_type.__name__, report) 1701 if exc_type is BrokenStrException: 1702 self.assertIn("<exception str() failed>", report) 1703 else: 1704 self.assertIn("test message", report) 1705 self.assertTrue(report.endswith("\n")) 1706 1707 @cpython_only 1708 # Python built with Py_TRACE_REFS fail with a fatal error in 1709 # _PyRefchain_Trace() on memory allocation error. 1710 @unittest.skipIf(support.Py_TRACE_REFS, 'cannot test Py_TRACE_REFS build') 1711 @unittest.skipIf(_testcapi is None, "requires _testcapi") 1712 def test_memory_error_in_PyErr_PrintEx(self): 1713 code = """if 1: 1714 import _testcapi 1715 class C(): pass 1716 _testcapi.set_nomemory(0, %d) 1717 C() 1718 """ 1719 1720 # Issue #30817: Abort in PyErr_PrintEx() when no memory. 1721 # Span a large range of tests as the CPython code always evolves with 1722 # changes that add or remove memory allocations. 1723 for i in range(1, 20): 1724 rc, out, err = script_helper.assert_python_failure("-c", code % i) 1725 self.assertIn(rc, (1, 120)) 1726 self.assertIn(b'MemoryError', err) 1727 1728 def test_yield_in_nested_try_excepts(self): 1729 #Issue #25612 1730 class MainError(Exception): 1731 pass 1732 1733 class SubError(Exception): 1734 pass 1735 1736 def main(): 1737 try: 1738 raise MainError() 1739 except MainError: 1740 try: 1741 yield 1742 except SubError: 1743 pass 1744 raise 1745 1746 coro = main() 1747 coro.send(None) 1748 with self.assertRaises(MainError): 1749 coro.throw(SubError()) 1750 1751 def test_generator_doesnt_retain_old_exc2(self): 1752 #Issue 28884#msg282532 1753 def g(): 1754 try: 1755 raise ValueError 1756 except ValueError: 1757 yield 1 1758 self.assertIsNone(sys.exception()) 1759 yield 2 1760 1761 gen = g() 1762 1763 try: 1764 raise IndexError 1765 except IndexError: 1766 self.assertEqual(next(gen), 1) 1767 self.assertEqual(next(gen), 2) 1768 1769 def test_raise_in_generator(self): 1770 #Issue 25612#msg304117 1771 def g(): 1772 yield 1 1773 raise 1774 yield 2 1775 1776 with self.assertRaises(ZeroDivisionError): 1777 i = g() 1778 try: 1779 1/0 1780 except: 1781 next(i) 1782 next(i) 1783 1784 @unittest.skipUnless(__debug__, "Won't work if __debug__ is False") 1785 def test_assert_shadowing(self): 1786 # Shadowing AssertionError would cause the assert statement to 1787 # misbehave. 1788 global AssertionError 1789 AssertionError = TypeError 1790 try: 1791 assert False, 'hello' 1792 except BaseException as e: 1793 del AssertionError 1794 self.assertIsInstance(e, AssertionError) 1795 self.assertEqual(str(e), 'hello') 1796 else: 1797 del AssertionError 1798 self.fail('Expected exception') 1799 1800 def test_memory_error_subclasses(self): 1801 # bpo-41654: MemoryError instances use a freelist of objects that are 1802 # linked using the 'dict' attribute when they are inactive/dead. 1803 # Subclasses of MemoryError should not participate in the freelist 1804 # schema. This test creates a MemoryError object and keeps it alive 1805 # (therefore advancing the freelist) and then it creates and destroys a 1806 # subclass object. Finally, it checks that creating a new MemoryError 1807 # succeeds, proving that the freelist is not corrupted. 1808 1809 class TestException(MemoryError): 1810 pass 1811 1812 try: 1813 raise MemoryError 1814 except MemoryError as exc: 1815 inst = exc 1816 1817 try: 1818 raise TestException 1819 except Exception: 1820 pass 1821 1822 for _ in range(10): 1823 try: 1824 raise MemoryError 1825 except MemoryError as exc: 1826 pass 1827 1828 gc_collect() 1829 1830 @unittest.skipIf(_testcapi is None, "requires _testcapi") 1831 def test_memory_error_in_subinterp(self): 1832 # gh-109894: subinterpreters shouldn't count on last resort memory error 1833 # when MemoryError is raised through PyErr_NoMemory() call, 1834 # and should preallocate memory errors as does the main interpreter. 1835 # interp.static_objects.last_resort_memory_error.args 1836 # should be initialized to empty tuple to avoid crash on attempt to print it. 1837 code = f"""if 1: 1838 import _testcapi 1839 _testcapi.run_in_subinterp(\"[0]*{sys.maxsize}\") 1840 exit(0) 1841 """ 1842 rc, _, err = script_helper.assert_python_ok("-c", code) 1843 self.assertIn(b'MemoryError', err) 1844 1845 1846class NameErrorTests(unittest.TestCase): 1847 def test_name_error_has_name(self): 1848 try: 1849 bluch 1850 except NameError as exc: 1851 self.assertEqual("bluch", exc.name) 1852 1853 def test_issue45826(self): 1854 # regression test for bpo-45826 1855 def f(): 1856 with self.assertRaisesRegex(NameError, 'aaa'): 1857 aab 1858 1859 try: 1860 f() 1861 except self.failureException: 1862 with support.captured_stderr() as err: 1863 sys.__excepthook__(*sys.exc_info()) 1864 else: 1865 self.fail("assertRaisesRegex should have failed.") 1866 1867 self.assertIn("aab", err.getvalue()) 1868 1869 def test_issue45826_focused(self): 1870 def f(): 1871 try: 1872 nonsense 1873 except BaseException as E: 1874 E.with_traceback(None) 1875 raise ZeroDivisionError() 1876 1877 try: 1878 f() 1879 except ZeroDivisionError: 1880 with support.captured_stderr() as err: 1881 sys.__excepthook__(*sys.exc_info()) 1882 1883 self.assertIn("nonsense", err.getvalue()) 1884 self.assertIn("ZeroDivisionError", err.getvalue()) 1885 1886 def test_gh_111654(self): 1887 def f(): 1888 class TestClass: 1889 TestClass 1890 1891 self.assertRaises(NameError, f) 1892 1893 # Note: name suggestion tests live in `test_traceback`. 1894 1895 1896class AttributeErrorTests(unittest.TestCase): 1897 def test_attributes(self): 1898 # Setting 'attr' should not be a problem. 1899 exc = AttributeError('Ouch!') 1900 self.assertIsNone(exc.name) 1901 self.assertIsNone(exc.obj) 1902 1903 sentinel = object() 1904 exc = AttributeError('Ouch', name='carry', obj=sentinel) 1905 self.assertEqual(exc.name, 'carry') 1906 self.assertIs(exc.obj, sentinel) 1907 1908 def test_getattr_has_name_and_obj(self): 1909 class A: 1910 blech = None 1911 1912 obj = A() 1913 try: 1914 obj.bluch 1915 except AttributeError as exc: 1916 self.assertEqual("bluch", exc.name) 1917 self.assertEqual(obj, exc.obj) 1918 try: 1919 object.__getattribute__(obj, "bluch") 1920 except AttributeError as exc: 1921 self.assertEqual("bluch", exc.name) 1922 self.assertEqual(obj, exc.obj) 1923 1924 def test_getattr_has_name_and_obj_for_method(self): 1925 class A: 1926 def blech(self): 1927 return 1928 1929 obj = A() 1930 try: 1931 obj.bluch() 1932 except AttributeError as exc: 1933 self.assertEqual("bluch", exc.name) 1934 self.assertEqual(obj, exc.obj) 1935 1936 # Note: name suggestion tests live in `test_traceback`. 1937 1938 1939class ImportErrorTests(unittest.TestCase): 1940 1941 def test_attributes(self): 1942 # Setting 'name' and 'path' should not be a problem. 1943 exc = ImportError('test') 1944 self.assertIsNone(exc.name) 1945 self.assertIsNone(exc.path) 1946 1947 exc = ImportError('test', name='somemodule') 1948 self.assertEqual(exc.name, 'somemodule') 1949 self.assertIsNone(exc.path) 1950 1951 exc = ImportError('test', path='somepath') 1952 self.assertEqual(exc.path, 'somepath') 1953 self.assertIsNone(exc.name) 1954 1955 exc = ImportError('test', path='somepath', name='somename') 1956 self.assertEqual(exc.name, 'somename') 1957 self.assertEqual(exc.path, 'somepath') 1958 1959 msg = r"ImportError\(\) got an unexpected keyword argument 'invalid'" 1960 with self.assertRaisesRegex(TypeError, msg): 1961 ImportError('test', invalid='keyword') 1962 1963 with self.assertRaisesRegex(TypeError, msg): 1964 ImportError('test', name='name', invalid='keyword') 1965 1966 with self.assertRaisesRegex(TypeError, msg): 1967 ImportError('test', path='path', invalid='keyword') 1968 1969 with self.assertRaisesRegex(TypeError, msg): 1970 ImportError(invalid='keyword') 1971 1972 with self.assertRaisesRegex(TypeError, msg): 1973 ImportError('test', invalid='keyword', another=True) 1974 1975 def test_reset_attributes(self): 1976 exc = ImportError('test', name='name', path='path') 1977 self.assertEqual(exc.args, ('test',)) 1978 self.assertEqual(exc.msg, 'test') 1979 self.assertEqual(exc.name, 'name') 1980 self.assertEqual(exc.path, 'path') 1981 1982 # Reset not specified attributes 1983 exc.__init__() 1984 self.assertEqual(exc.args, ()) 1985 self.assertEqual(exc.msg, None) 1986 self.assertEqual(exc.name, None) 1987 self.assertEqual(exc.path, None) 1988 1989 def test_non_str_argument(self): 1990 # Issue #15778 1991 with check_warnings(('', BytesWarning), quiet=True): 1992 arg = b'abc' 1993 exc = ImportError(arg) 1994 self.assertEqual(str(arg), str(exc)) 1995 1996 def test_copy_pickle(self): 1997 for kwargs in (dict(), 1998 dict(name='somename'), 1999 dict(path='somepath'), 2000 dict(name='somename', path='somepath')): 2001 orig = ImportError('test', **kwargs) 2002 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 2003 exc = pickle.loads(pickle.dumps(orig, proto)) 2004 self.assertEqual(exc.args, ('test',)) 2005 self.assertEqual(exc.msg, 'test') 2006 self.assertEqual(exc.name, orig.name) 2007 self.assertEqual(exc.path, orig.path) 2008 for c in copy.copy, copy.deepcopy: 2009 exc = c(orig) 2010 self.assertEqual(exc.args, ('test',)) 2011 self.assertEqual(exc.msg, 'test') 2012 self.assertEqual(exc.name, orig.name) 2013 self.assertEqual(exc.path, orig.path) 2014 2015 2016def run_script(source): 2017 if isinstance(source, str): 2018 with open(TESTFN, 'w', encoding='utf-8') as testfile: 2019 testfile.write(dedent(source)) 2020 else: 2021 with open(TESTFN, 'wb') as testfile: 2022 testfile.write(source) 2023 _rc, _out, err = script_helper.assert_python_failure('-Wd', '-X', 'utf8', TESTFN) 2024 return err.decode('utf-8').splitlines() 2025 2026class AssertionErrorTests(unittest.TestCase): 2027 def tearDown(self): 2028 unlink(TESTFN) 2029 2030 @force_not_colorized 2031 def test_assertion_error_location(self): 2032 cases = [ 2033 ('assert None', 2034 [ 2035 ' assert None', 2036 ' ^^^^', 2037 'AssertionError', 2038 ], 2039 ), 2040 ('assert 0', 2041 [ 2042 ' assert 0', 2043 ' ^', 2044 'AssertionError', 2045 ], 2046 ), 2047 ('assert 1 > 2', 2048 [ 2049 ' assert 1 > 2', 2050 ' ^^^^^', 2051 'AssertionError', 2052 ], 2053 ), 2054 ('assert 1 > 2 and 3 > 2', 2055 [ 2056 ' assert 1 > 2 and 3 > 2', 2057 ' ^^^^^^^^^^^^^^^', 2058 'AssertionError', 2059 ], 2060 ), 2061 ('assert 1 > 2, "messäge"', 2062 [ 2063 ' assert 1 > 2, "messäge"', 2064 ' ^^^^^', 2065 'AssertionError: messäge', 2066 ], 2067 ), 2068 ('assert 1 > 2, "messäge"'.encode(), 2069 [ 2070 ' assert 1 > 2, "messäge"', 2071 ' ^^^^^', 2072 'AssertionError: messäge', 2073 ], 2074 ), 2075 ('# coding: latin1\nassert 1 > 2, "messäge"'.encode('latin1'), 2076 [ 2077 ' assert 1 > 2, "messäge"', 2078 ' ^^^^^', 2079 'AssertionError: messäge', 2080 ], 2081 ), 2082 (BOM_UTF8 + 'assert 1 > 2, "messäge"'.encode(), 2083 [ 2084 ' assert 1 > 2, "messäge"', 2085 ' ^^^^^', 2086 'AssertionError: messäge', 2087 ], 2088 ), 2089 2090 # Multiline: 2091 (""" 2092 assert ( 2093 1 > 2) 2094 """, 2095 [ 2096 ' 1 > 2)', 2097 ' ^^^^^', 2098 'AssertionError', 2099 ], 2100 ), 2101 (""" 2102 assert ( 2103 1 > 2), "Message" 2104 """, 2105 [ 2106 ' 1 > 2), "Message"', 2107 ' ^^^^^', 2108 'AssertionError: Message', 2109 ], 2110 ), 2111 (""" 2112 assert ( 2113 1 > 2), \\ 2114 "Message" 2115 """, 2116 [ 2117 ' 1 > 2), \\', 2118 ' ^^^^^', 2119 'AssertionError: Message', 2120 ], 2121 ), 2122 ] 2123 for source, expected in cases: 2124 with self.subTest(source=source): 2125 result = run_script(source) 2126 self.assertEqual(result[-3:], expected) 2127 2128 @force_not_colorized 2129 def test_multiline_not_highlighted(self): 2130 cases = [ 2131 (""" 2132 assert ( 2133 1 > 2 2134 ) 2135 """, 2136 [ 2137 ' 1 > 2', 2138 'AssertionError', 2139 ], 2140 ), 2141 (""" 2142 assert ( 2143 1 < 2 and 2144 3 > 4 2145 ) 2146 """, 2147 [ 2148 ' 1 < 2 and', 2149 ' 3 > 4', 2150 'AssertionError', 2151 ], 2152 ), 2153 ] 2154 for source, expected in cases: 2155 with self.subTest(source=source): 2156 result = run_script(source) 2157 self.assertEqual(result[-len(expected):], expected) 2158 2159 2160class SyntaxErrorTests(unittest.TestCase): 2161 maxDiff = None 2162 2163 @force_not_colorized 2164 def test_range_of_offsets(self): 2165 cases = [ 2166 # Basic range from 2->7 2167 (("bad.py", 1, 2, "abcdefg", 1, 7), 2168 dedent( 2169 """ 2170 File "bad.py", line 1 2171 abcdefg 2172 ^^^^^ 2173 SyntaxError: bad bad 2174 """)), 2175 # end_offset = start_offset + 1 2176 (("bad.py", 1, 2, "abcdefg", 1, 3), 2177 dedent( 2178 """ 2179 File "bad.py", line 1 2180 abcdefg 2181 ^ 2182 SyntaxError: bad bad 2183 """)), 2184 # Negative end offset 2185 (("bad.py", 1, 2, "abcdefg", 1, -2), 2186 dedent( 2187 """ 2188 File "bad.py", line 1 2189 abcdefg 2190 ^ 2191 SyntaxError: bad bad 2192 """)), 2193 # end offset before starting offset 2194 (("bad.py", 1, 4, "abcdefg", 1, 2), 2195 dedent( 2196 """ 2197 File "bad.py", line 1 2198 abcdefg 2199 ^ 2200 SyntaxError: bad bad 2201 """)), 2202 # Both offsets negative 2203 (("bad.py", 1, -4, "abcdefg", 1, -2), 2204 dedent( 2205 """ 2206 File "bad.py", line 1 2207 abcdefg 2208 SyntaxError: bad bad 2209 """)), 2210 # Both offsets negative and the end more negative 2211 (("bad.py", 1, -4, "abcdefg", 1, -5), 2212 dedent( 2213 """ 2214 File "bad.py", line 1 2215 abcdefg 2216 SyntaxError: bad bad 2217 """)), 2218 # Both offsets 0 2219 (("bad.py", 1, 0, "abcdefg", 1, 0), 2220 dedent( 2221 """ 2222 File "bad.py", line 1 2223 abcdefg 2224 SyntaxError: bad bad 2225 """)), 2226 # Start offset 0 and end offset not 0 2227 (("bad.py", 1, 0, "abcdefg", 1, 5), 2228 dedent( 2229 """ 2230 File "bad.py", line 1 2231 abcdefg 2232 SyntaxError: bad bad 2233 """)), 2234 # End offset pass the source length 2235 (("bad.py", 1, 2, "abcdefg", 1, 100), 2236 dedent( 2237 """ 2238 File "bad.py", line 1 2239 abcdefg 2240 ^^^^^^ 2241 SyntaxError: bad bad 2242 """)), 2243 ] 2244 for args, expected in cases: 2245 with self.subTest(args=args): 2246 try: 2247 raise SyntaxError("bad bad", args) 2248 except SyntaxError as exc: 2249 with support.captured_stderr() as err: 2250 sys.__excepthook__(*sys.exc_info()) 2251 self.assertIn(expected, err.getvalue()) 2252 the_exception = exc 2253 2254 def test_encodings(self): 2255 self.addCleanup(unlink, TESTFN) 2256 source = ( 2257 '# -*- coding: cp437 -*-\n' 2258 '"┬ó┬ó┬ó┬ó┬ó┬ó" + f(4, x for x in range(1))\n' 2259 ) 2260 err = run_script(source.encode('cp437')) 2261 self.assertEqual(err[-3], ' "┬ó┬ó┬ó┬ó┬ó┬ó" + f(4, x for x in range(1))') 2262 self.assertEqual(err[-2], ' ^^^^^^^^^^^^^^^^^^^') 2263 2264 # Check backwards tokenizer errors 2265 source = '# -*- coding: ascii -*-\n\n(\n' 2266 err = run_script(source) 2267 self.assertEqual(err[-3], ' (') 2268 self.assertEqual(err[-2], ' ^') 2269 2270 def test_non_utf8(self): 2271 # Check non utf-8 characters 2272 self.addCleanup(unlink, TESTFN) 2273 err = run_script(b"\x89") 2274 self.assertIn("SyntaxError: Non-UTF-8 code starting with '\\x89' in file", err[-1]) 2275 2276 def test_string_source(self): 2277 def try_compile(source): 2278 with self.assertRaises(SyntaxError) as cm: 2279 compile(source, '<string>', 'exec') 2280 return cm.exception 2281 2282 exc = try_compile('return "ä"') 2283 self.assertEqual(str(exc), "'return' outside function (<string>, line 1)") 2284 self.assertIsNone(exc.text) 2285 self.assertEqual(exc.offset, 1) 2286 self.assertEqual(exc.end_offset, 12) 2287 2288 exc = try_compile('return "ä"'.encode()) 2289 self.assertEqual(str(exc), "'return' outside function (<string>, line 1)") 2290 self.assertIsNone(exc.text) 2291 self.assertEqual(exc.offset, 1) 2292 self.assertEqual(exc.end_offset, 12) 2293 2294 exc = try_compile(BOM_UTF8 + 'return "ä"'.encode()) 2295 self.assertEqual(str(exc), "'return' outside function (<string>, line 1)") 2296 self.assertIsNone(exc.text) 2297 self.assertEqual(exc.offset, 1) 2298 self.assertEqual(exc.end_offset, 12) 2299 2300 exc = try_compile('# coding: latin1\nreturn "ä"'.encode('latin1')) 2301 self.assertEqual(str(exc), "'return' outside function (<string>, line 2)") 2302 self.assertIsNone(exc.text) 2303 self.assertEqual(exc.offset, 1) 2304 self.assertEqual(exc.end_offset, 12) 2305 2306 exc = try_compile('return "ä" #' + 'ä'*1000) 2307 self.assertEqual(str(exc), "'return' outside function (<string>, line 1)") 2308 self.assertIsNone(exc.text) 2309 self.assertEqual(exc.offset, 1) 2310 self.assertEqual(exc.end_offset, 12) 2311 2312 exc = try_compile('return "ä" # ' + 'ä'*1000) 2313 self.assertEqual(str(exc), "'return' outside function (<string>, line 1)") 2314 self.assertIsNone(exc.text) 2315 self.assertEqual(exc.offset, 1) 2316 self.assertEqual(exc.end_offset, 12) 2317 2318 def test_file_source(self): 2319 self.addCleanup(unlink, TESTFN) 2320 err = run_script('return "ä"') 2321 self.assertEqual(err[-3:], [ 2322 ' return "ä"', 2323 ' ^^^^^^^^^^', 2324 "SyntaxError: 'return' outside function"]) 2325 2326 err = run_script('return "ä"'.encode()) 2327 self.assertEqual(err[-3:], [ 2328 ' return "ä"', 2329 ' ^^^^^^^^^^', 2330 "SyntaxError: 'return' outside function"]) 2331 2332 err = run_script(BOM_UTF8 + 'return "ä"'.encode()) 2333 self.assertEqual(err[-3:], [ 2334 ' return "ä"', 2335 ' ^^^^^^^^^^', 2336 "SyntaxError: 'return' outside function"]) 2337 2338 err = run_script('# coding: latin1\nreturn "ä"'.encode('latin1')) 2339 self.assertEqual(err[-3:], [ 2340 ' return "ä"', 2341 ' ^^^^^^^^^^', 2342 "SyntaxError: 'return' outside function"]) 2343 2344 err = run_script('return "ä" #' + 'ä'*1000) 2345 self.assertEqual(err[-2:], [ 2346 ' ^^^^^^^^^^^', 2347 "SyntaxError: 'return' outside function"]) 2348 self.assertEqual(err[-3][:100], ' return "ä" #' + 'ä'*84) 2349 2350 err = run_script('return "ä" # ' + 'ä'*1000) 2351 self.assertEqual(err[-2:], [ 2352 ' ^^^^^^^^^^^', 2353 "SyntaxError: 'return' outside function"]) 2354 self.assertEqual(err[-3][:100], ' return "ä" # ' + 'ä'*83) 2355 2356 def test_attributes_new_constructor(self): 2357 args = ("bad.py", 1, 2, "abcdefg", 1, 100) 2358 the_exception = SyntaxError("bad bad", args) 2359 filename, lineno, offset, error, end_lineno, end_offset = args 2360 self.assertEqual(filename, the_exception.filename) 2361 self.assertEqual(lineno, the_exception.lineno) 2362 self.assertEqual(end_lineno, the_exception.end_lineno) 2363 self.assertEqual(offset, the_exception.offset) 2364 self.assertEqual(end_offset, the_exception.end_offset) 2365 self.assertEqual(error, the_exception.text) 2366 self.assertEqual("bad bad", the_exception.msg) 2367 2368 def test_attributes_old_constructor(self): 2369 args = ("bad.py", 1, 2, "abcdefg") 2370 the_exception = SyntaxError("bad bad", args) 2371 filename, lineno, offset, error = args 2372 self.assertEqual(filename, the_exception.filename) 2373 self.assertEqual(lineno, the_exception.lineno) 2374 self.assertEqual(None, the_exception.end_lineno) 2375 self.assertEqual(offset, the_exception.offset) 2376 self.assertEqual(None, the_exception.end_offset) 2377 self.assertEqual(error, the_exception.text) 2378 self.assertEqual("bad bad", the_exception.msg) 2379 2380 def test_incorrect_constructor(self): 2381 args = ("bad.py", 1, 2) 2382 self.assertRaises(TypeError, SyntaxError, "bad bad", args) 2383 2384 args = ("bad.py", 1, 2, 4, 5, 6, 7) 2385 self.assertRaises(TypeError, SyntaxError, "bad bad", args) 2386 2387 args = ("bad.py", 1, 2, "abcdefg", 1) 2388 self.assertRaises(TypeError, SyntaxError, "bad bad", args) 2389 2390 2391class TestInvalidExceptionMatcher(unittest.TestCase): 2392 def test_except_star_invalid_exception_type(self): 2393 with self.assertRaises(TypeError): 2394 try: 2395 raise ValueError 2396 except 42: 2397 pass 2398 2399 with self.assertRaises(TypeError): 2400 try: 2401 raise ValueError 2402 except (ValueError, 42): 2403 pass 2404 2405 2406class PEP626Tests(unittest.TestCase): 2407 2408 def lineno_after_raise(self, f, *expected): 2409 try: 2410 f() 2411 except Exception as ex: 2412 t = ex.__traceback__ 2413 else: 2414 self.fail("No exception raised") 2415 lines = [] 2416 t = t.tb_next # Skip this function 2417 while t: 2418 frame = t.tb_frame 2419 lines.append( 2420 None if frame.f_lineno is None else 2421 frame.f_lineno-frame.f_code.co_firstlineno 2422 ) 2423 t = t.tb_next 2424 self.assertEqual(tuple(lines), expected) 2425 2426 def test_lineno_after_raise_simple(self): 2427 def simple(): 2428 1/0 2429 pass 2430 self.lineno_after_raise(simple, 1) 2431 2432 def test_lineno_after_raise_in_except(self): 2433 def in_except(): 2434 try: 2435 1/0 2436 except: 2437 1/0 2438 pass 2439 self.lineno_after_raise(in_except, 4) 2440 2441 def test_lineno_after_other_except(self): 2442 def other_except(): 2443 try: 2444 1/0 2445 except TypeError as ex: 2446 pass 2447 self.lineno_after_raise(other_except, 3) 2448 2449 def test_lineno_in_named_except(self): 2450 def in_named_except(): 2451 try: 2452 1/0 2453 except Exception as ex: 2454 1/0 2455 pass 2456 self.lineno_after_raise(in_named_except, 4) 2457 2458 def test_lineno_in_try(self): 2459 def in_try(): 2460 try: 2461 1/0 2462 finally: 2463 pass 2464 self.lineno_after_raise(in_try, 4) 2465 2466 def test_lineno_in_finally_normal(self): 2467 def in_finally_normal(): 2468 try: 2469 pass 2470 finally: 2471 1/0 2472 pass 2473 self.lineno_after_raise(in_finally_normal, 4) 2474 2475 def test_lineno_in_finally_except(self): 2476 def in_finally_except(): 2477 try: 2478 1/0 2479 finally: 2480 1/0 2481 pass 2482 self.lineno_after_raise(in_finally_except, 4) 2483 2484 def test_lineno_after_with(self): 2485 class Noop: 2486 def __enter__(self): 2487 return self 2488 def __exit__(self, *args): 2489 pass 2490 def after_with(): 2491 with Noop(): 2492 1/0 2493 pass 2494 self.lineno_after_raise(after_with, 2) 2495 2496 def test_missing_lineno_shows_as_none(self): 2497 def f(): 2498 1/0 2499 self.lineno_after_raise(f, 1) 2500 f.__code__ = f.__code__.replace(co_linetable=b'\xf8\xf8\xf8\xf9\xf8\xf8\xf8') 2501 self.lineno_after_raise(f, None) 2502 2503 def test_lineno_after_raise_in_with_exit(self): 2504 class ExitFails: 2505 def __enter__(self): 2506 return self 2507 def __exit__(self, *args): 2508 raise ValueError 2509 2510 def after_with(): 2511 with ExitFails(): 2512 1/0 2513 self.lineno_after_raise(after_with, 1, 1) 2514 2515if __name__ == '__main__': 2516 unittest.main() 2517