diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index ed5ddf95069e35..e8ff4b5a28f55f 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -4,6 +4,7 @@ from io import StringIO import linecache import sys +import types import inspect import unittest import re @@ -1129,7 +1130,7 @@ def test_print_exception_bad_type_python(self): class BaseExceptionReportingTests: def get_exception(self, exception_or_callable): - if isinstance(exception_or_callable, Exception): + if isinstance(exception_or_callable, BaseException): return exception_or_callable try: exception_or_callable() @@ -1851,6 +1852,31 @@ def exc(): report = self.get_report(exc) self.assertEqual(report, expected) + def test_KeyboardInterrupt_at_first_line_of_frame(self): + # see GH-93249 + def f(): + return sys._getframe() + + tb_next = None + frame = f() + lasti = 0 + lineno = f.__code__.co_firstlineno + tb = types.TracebackType(tb_next, frame, lasti, lineno) + + exc = KeyboardInterrupt() + exc.__traceback__ = tb + + expected = (f'Traceback (most recent call last):\n' + f' File "{__file__}", line {lineno}, in f\n' + f' def f():\n' + f'\n' + f'KeyboardInterrupt\n') + + report = self.get_report(exc) + # remove trailing writespace: + report = '\n'.join([l.rstrip() for l in report.split('\n')]) + self.assertEqual(report, expected) + class PyExcReportingTests(BaseExceptionReportingTests, unittest.TestCase): # diff --git a/Objects/codeobject.c b/Objects/codeobject.c index c2b29be1fe8693..dd3f555e024e0e 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -768,6 +768,11 @@ next_code_delta(PyCodeAddressRange *bounds) static int previous_code_delta(PyCodeAddressRange *bounds) { + if (bounds->ar_start == 0) { + // If we looking at the first entry, the + // "previous" entry has an implicit length of 1. + return 1; + } const uint8_t *ptr = bounds->opaque.lo_next-1; while (((*ptr) & 128) == 0) { ptr--; @@ -811,7 +816,7 @@ static void retreat(PyCodeAddressRange *bounds) { ASSERT_VALID_BOUNDS(bounds); - assert(bounds->ar_start > 0); + assert(bounds->ar_start >= 0); do { bounds->opaque.lo_next--; } while (((*bounds->opaque.lo_next) & 128) == 0);
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: