Skip to content

Commit 26329e4

Browse files
GH-93249: relax overly strict assertion on bounds->ar_start (GH-93961) (GH-94032)
(cherry picked from commit 1603a10) Co-authored-by: Irit Katriel <[email protected]> Co-authored-by: Irit Katriel <[email protected]>
1 parent e6ad599 commit 26329e4

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

Lib/test/test_traceback.py

+27-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from io import StringIO
55
import linecache
66
import sys
7+
import types
78
import inspect
89
import unittest
910
import re
@@ -1129,7 +1130,7 @@ def test_print_exception_bad_type_python(self):
11291130
class BaseExceptionReportingTests:
11301131

11311132
def get_exception(self, exception_or_callable):
1132-
if isinstance(exception_or_callable, Exception):
1133+
if isinstance(exception_or_callable, BaseException):
11331134
return exception_or_callable
11341135
try:
11351136
exception_or_callable()
@@ -1851,6 +1852,31 @@ def exc():
18511852
report = self.get_report(exc)
18521853
self.assertEqual(report, expected)
18531854

1855+
def test_KeyboardInterrupt_at_first_line_of_frame(self):
1856+
# see GH-93249
1857+
def f():
1858+
return sys._getframe()
1859+
1860+
tb_next = None
1861+
frame = f()
1862+
lasti = 0
1863+
lineno = f.__code__.co_firstlineno
1864+
tb = types.TracebackType(tb_next, frame, lasti, lineno)
1865+
1866+
exc = KeyboardInterrupt()
1867+
exc.__traceback__ = tb
1868+
1869+
expected = (f'Traceback (most recent call last):\n'
1870+
f' File "{__file__}", line {lineno}, in f\n'
1871+
f' def f():\n'
1872+
f'\n'
1873+
f'KeyboardInterrupt\n')
1874+
1875+
report = self.get_report(exc)
1876+
# remove trailing writespace:
1877+
report = '\n'.join([l.rstrip() for l in report.split('\n')])
1878+
self.assertEqual(report, expected)
1879+
18541880

18551881
class PyExcReportingTests(BaseExceptionReportingTests, unittest.TestCase):
18561882
#

Objects/codeobject.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,11 @@ next_code_delta(PyCodeAddressRange *bounds)
768768
static int
769769
previous_code_delta(PyCodeAddressRange *bounds)
770770
{
771+
if (bounds->ar_start == 0) {
772+
// If we looking at the first entry, the
773+
// "previous" entry has an implicit length of 1.
774+
return 1;
775+
}
771776
const uint8_t *ptr = bounds->opaque.lo_next-1;
772777
while (((*ptr) & 128) == 0) {
773778
ptr--;
@@ -811,7 +816,7 @@ static void
811816
retreat(PyCodeAddressRange *bounds)
812817
{
813818
ASSERT_VALID_BOUNDS(bounds);
814-
assert(bounds->ar_start > 0);
819+
assert(bounds->ar_start >= 0);
815820
do {
816821
bounds->opaque.lo_next--;
817822
} while (((*bounds->opaque.lo_next) & 128) == 0);

0 commit comments

Comments
 (0)