Skip to content

Commit

Permalink
Get the correct computed tb lineno
Browse files Browse the repository at this point in the history
Fix for python/cpython#109181 introduced
lazily computed lineno for traceback object in 3.11.7 and 3.12.1.
Tested in a number of Python versions, the change seems to be safe.
  • Loading branch information
jmao-denver committed Aug 8, 2024
1 parent e080ab9 commit b56b946
Showing 1 changed file with 11 additions and 4 deletions.
15 changes: 11 additions & 4 deletions src/main/c/jni/org_jpy_PyLib.c
Original file line number Diff line number Diff line change
Expand Up @@ -2667,7 +2667,7 @@ void PyLib_RedirectStdOut(void)


static const int PYLIB_RECURSIVE_CUTOFF = 3;
#define PyLib_TraceBack_LIMIT 1024
#define PyLib_TraceBack_LIMIT 1024

static PyObject *format_displayline(PyObject *filename, int lineno, PyObject *name)
{
Expand Down Expand Up @@ -2730,6 +2730,13 @@ static int append_to_java_message(PyObject * pyObjUtf8, char **buf, int *bufLen
return 0;
}

static int get_traceback_lineno(PyTracebackObject *tb) {
PyObject* po_lineno = PyObject_GetAttrString((PyObject*)tb, "tb_lineno");
int lineno = (int)PyLong_AsLong(po_lineno);
JPy_DECREF(po_lineno);
return lineno;
}

static int format_python_traceback(PyTracebackObject *tb, char **buf, int *bufLen)
{
int err = 0;
Expand All @@ -2754,7 +2761,7 @@ static int format_python_traceback(PyTracebackObject *tb, char **buf, int *bufLe
PyCodeObject* co = PyFrame_GetCode(tb->tb_frame);
if (last_file == NULL ||
co->co_filename != last_file ||
last_line == -1 || tb->tb_lineno != last_line ||
last_line == -1 || get_traceback_lineno(tb) != last_line ||
last_name == NULL || co->co_name != last_name) {
if (cnt > PYLIB_RECURSIVE_CUTOFF) {
pyObjUtf8 = format_line_repeated(cnt);
Expand All @@ -2765,15 +2772,15 @@ static int format_python_traceback(PyTracebackObject *tb, char **buf, int *bufLe
}
}
last_file = co->co_filename;
last_line = tb->tb_lineno;
last_line = get_traceback_lineno(tb);
last_name = co->co_name;
cnt = 0;
}
cnt++;
if (err == 0 && cnt <= PYLIB_RECURSIVE_CUTOFF) {
pyObjUtf8 = format_displayline(
co->co_filename,
tb->tb_lineno,
get_traceback_lineno(tb),
co->co_name);
err = append_to_java_message(pyObjUtf8, buf, bufLen);
if (err != 0) {
Expand Down

0 comments on commit b56b946

Please sign in to comment.