mirror of
https://github.com/python/cpython.git
synced 2025-09-27 18:59:43 +00:00
[3.12] gh-109181: Speed up Traceback object creation by lazily compute the line number (GH-111548) (#111551)
.
(cherry picked from commit abb15420c1
)
This commit is contained in:
parent
b1da63468e
commit
4f619e83fe
2 changed files with 31 additions and 6 deletions
|
@ -0,0 +1,2 @@
|
||||||
|
Speed up :obj:`Traceback` object creation by lazily compute the line number.
|
||||||
|
Patch by Pablo Galindo
|
|
@ -107,6 +107,26 @@ tb_next_get(PyTracebackObject *self, void *Py_UNUSED(_))
|
||||||
return Py_NewRef(ret);
|
return Py_NewRef(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
tb_get_lineno(PyTracebackObject* tb) {
|
||||||
|
PyFrameObject* frame = tb->tb_frame;
|
||||||
|
assert(frame != NULL);
|
||||||
|
return PyCode_Addr2Line(PyFrame_GetCode(frame), tb->tb_lasti);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
tb_lineno_get(PyTracebackObject *self, void *Py_UNUSED(_))
|
||||||
|
{
|
||||||
|
int lineno = self->tb_lineno;
|
||||||
|
if (lineno == -1) {
|
||||||
|
lineno = tb_get_lineno(self);
|
||||||
|
if (lineno < 0) {
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PyLong_FromLong(lineno);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
tb_next_set(PyTracebackObject *self, PyObject *new_next, void *Py_UNUSED(_))
|
tb_next_set(PyTracebackObject *self, PyObject *new_next, void *Py_UNUSED(_))
|
||||||
{
|
{
|
||||||
|
@ -150,12 +170,12 @@ static PyMethodDef tb_methods[] = {
|
||||||
static PyMemberDef tb_memberlist[] = {
|
static PyMemberDef tb_memberlist[] = {
|
||||||
{"tb_frame", T_OBJECT, OFF(tb_frame), READONLY|PY_AUDIT_READ},
|
{"tb_frame", T_OBJECT, OFF(tb_frame), READONLY|PY_AUDIT_READ},
|
||||||
{"tb_lasti", T_INT, OFF(tb_lasti), READONLY},
|
{"tb_lasti", T_INT, OFF(tb_lasti), READONLY},
|
||||||
{"tb_lineno", T_INT, OFF(tb_lineno), READONLY},
|
|
||||||
{NULL} /* Sentinel */
|
{NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyGetSetDef tb_getsetters[] = {
|
static PyGetSetDef tb_getsetters[] = {
|
||||||
{"tb_next", (getter)tb_next_get, (setter)tb_next_set, NULL, NULL},
|
{"tb_next", (getter)tb_next_get, (setter)tb_next_set, NULL, NULL},
|
||||||
|
{"tb_lineno", (getter)tb_lineno_get, NULL, NULL, NULL},
|
||||||
{NULL} /* Sentinel */
|
{NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -234,8 +254,7 @@ _PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame)
|
||||||
assert(tb_next == NULL || PyTraceBack_Check(tb_next));
|
assert(tb_next == NULL || PyTraceBack_Check(tb_next));
|
||||||
assert(frame != NULL);
|
assert(frame != NULL);
|
||||||
int addr = _PyInterpreterFrame_LASTI(frame->f_frame) * sizeof(_Py_CODEUNIT);
|
int addr = _PyInterpreterFrame_LASTI(frame->f_frame) * sizeof(_Py_CODEUNIT);
|
||||||
return tb_create_raw((PyTracebackObject *)tb_next, frame, addr,
|
return tb_create_raw((PyTracebackObject *)tb_next, frame, addr, -1);
|
||||||
PyFrame_GetLineNumber(frame));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -983,9 +1002,13 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit,
|
||||||
}
|
}
|
||||||
while (tb != NULL) {
|
while (tb != NULL) {
|
||||||
code = PyFrame_GetCode(tb->tb_frame);
|
code = PyFrame_GetCode(tb->tb_frame);
|
||||||
|
int tb_lineno = tb->tb_lineno;
|
||||||
|
if (tb_lineno == -1) {
|
||||||
|
tb_lineno = tb_get_lineno(tb);
|
||||||
|
}
|
||||||
if (last_file == NULL ||
|
if (last_file == NULL ||
|
||||||
code->co_filename != last_file ||
|
code->co_filename != last_file ||
|
||||||
last_line == -1 || tb->tb_lineno != last_line ||
|
last_line == -1 || tb_lineno != last_line ||
|
||||||
last_name == NULL || code->co_name != last_name) {
|
last_name == NULL || code->co_name != last_name) {
|
||||||
if (cnt > TB_RECURSIVE_CUTOFF) {
|
if (cnt > TB_RECURSIVE_CUTOFF) {
|
||||||
if (tb_print_line_repeated(f, cnt) < 0) {
|
if (tb_print_line_repeated(f, cnt) < 0) {
|
||||||
|
@ -993,13 +1016,13 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
last_file = code->co_filename;
|
last_file = code->co_filename;
|
||||||
last_line = tb->tb_lineno;
|
last_line = tb_lineno;
|
||||||
last_name = code->co_name;
|
last_name = code->co_name;
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
}
|
}
|
||||||
cnt++;
|
cnt++;
|
||||||
if (cnt <= TB_RECURSIVE_CUTOFF) {
|
if (cnt <= TB_RECURSIVE_CUTOFF) {
|
||||||
if (tb_displayline(tb, f, code->co_filename, tb->tb_lineno,
|
if (tb_displayline(tb, f, code->co_filename, tb_lineno,
|
||||||
tb->tb_frame, code->co_name, indent, margin) < 0) {
|
tb->tb_frame, code->co_name, indent, margin) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue