Skip to content

Commit a4aa213

Browse files
authored
[3.11] gh-109181: Speed up Traceback object creation by lazily compute the line number (GH-111548) (#111550)
. (cherry picked from commit abb1542)
1 parent 19a266c commit a4aa213

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Speed up :obj:`Traceback` object creation by lazily compute the line number.
2+
Patch by Pablo Galindo

Python/traceback.c

+29-6
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,26 @@ tb_next_get(PyTracebackObject *self, void *Py_UNUSED(_))
111111
return ret;
112112
}
113113

114+
static int
115+
tb_get_lineno(PyTracebackObject* tb) {
116+
PyFrameObject* frame = tb->tb_frame;
117+
assert(frame != NULL);
118+
return PyCode_Addr2Line(PyFrame_GetCode(frame), tb->tb_lasti);
119+
}
120+
121+
static PyObject *
122+
tb_lineno_get(PyTracebackObject *self, void *Py_UNUSED(_))
123+
{
124+
int lineno = self->tb_lineno;
125+
if (lineno == -1) {
126+
lineno = tb_get_lineno(self);
127+
if (lineno < 0) {
128+
Py_RETURN_NONE;
129+
}
130+
}
131+
return PyLong_FromLong(lineno);
132+
}
133+
114134
static int
115135
tb_next_set(PyTracebackObject *self, PyObject *new_next, void *Py_UNUSED(_))
116136
{
@@ -157,12 +177,12 @@ static PyMethodDef tb_methods[] = {
157177
static PyMemberDef tb_memberlist[] = {
158178
{"tb_frame", T_OBJECT, OFF(tb_frame), READONLY|PY_AUDIT_READ},
159179
{"tb_lasti", T_INT, OFF(tb_lasti), READONLY},
160-
{"tb_lineno", T_INT, OFF(tb_lineno), READONLY},
161180
{NULL} /* Sentinel */
162181
};
163182

164183
static PyGetSetDef tb_getsetters[] = {
165184
{"tb_next", (getter)tb_next_get, (setter)tb_next_set, NULL, NULL},
185+
{"tb_lineno", (getter)tb_lineno_get, NULL, NULL, NULL},
166186
{NULL} /* Sentinel */
167187
};
168188

@@ -241,8 +261,7 @@ _PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame)
241261
assert(tb_next == NULL || PyTraceBack_Check(tb_next));
242262
assert(frame != NULL);
243263
int addr = _PyInterpreterFrame_LASTI(frame->f_frame) * sizeof(_Py_CODEUNIT);
244-
return tb_create_raw((PyTracebackObject *)tb_next, frame, addr,
245-
PyFrame_GetLineNumber(frame));
264+
return tb_create_raw((PyTracebackObject *)tb_next, frame, addr, -1);
246265
}
247266

248267

@@ -990,23 +1009,27 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit,
9901009
}
9911010
while (tb != NULL) {
9921011
code = PyFrame_GetCode(tb->tb_frame);
1012+
int tb_lineno = tb->tb_lineno;
1013+
if (tb_lineno == -1) {
1014+
tb_lineno = tb_get_lineno(tb);
1015+
}
9931016
if (last_file == NULL ||
9941017
code->co_filename != last_file ||
995-
last_line == -1 || tb->tb_lineno != last_line ||
1018+
last_line == -1 || tb_lineno != last_line ||
9961019
last_name == NULL || code->co_name != last_name) {
9971020
if (cnt > TB_RECURSIVE_CUTOFF) {
9981021
if (tb_print_line_repeated(f, cnt) < 0) {
9991022
goto error;
10001023
}
10011024
}
10021025
last_file = code->co_filename;
1003-
last_line = tb->tb_lineno;
1026+
last_line = tb_lineno;
10041027
last_name = code->co_name;
10051028
cnt = 0;
10061029
}
10071030
cnt++;
10081031
if (cnt <= TB_RECURSIVE_CUTOFF) {
1009-
if (tb_displayline(tb, f, code->co_filename, tb->tb_lineno,
1032+
if (tb_displayline(tb, f, code->co_filename, tb_lineno,
10101033
tb->tb_frame, code->co_name, indent, margin) < 0) {
10111034
goto error;
10121035
}

0 commit comments

Comments
 (0)