Skip to content

Commit 498cf19

Browse files
authored
fix: Get the correct computed tb lineno (#158)
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.
1 parent e080ab9 commit 498cf19

File tree

2 files changed

+13
-5
lines changed

2 files changed

+13
-5
lines changed

.github/workflows/check.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
distribution: 'temurin'
2626
java-version: ${{ matrix.java }}
2727

28-
- run: pip install setuptools
28+
- run: pip install "setuptools < 72"
2929

3030
- name: Run Test
3131
run: python setup.py test

src/main/c/jni/org_jpy_PyLib.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2667,7 +2667,7 @@ void PyLib_RedirectStdOut(void)
26672667

26682668

26692669
static const int PYLIB_RECURSIVE_CUTOFF = 3;
2670-
#define PyLib_TraceBack_LIMIT 1024
2670+
#define PyLib_TraceBack_LIMIT 1024
26712671

26722672
static PyObject *format_displayline(PyObject *filename, int lineno, PyObject *name)
26732673
{
@@ -2730,6 +2730,13 @@ static int append_to_java_message(PyObject * pyObjUtf8, char **buf, int *bufLen
27302730
return 0;
27312731
}
27322732

2733+
static int get_traceback_lineno(PyTracebackObject *tb) {
2734+
PyObject* po_lineno = PyObject_GetAttrString((PyObject*)tb, "tb_lineno");
2735+
int lineno = (int)PyLong_AsLong(po_lineno);
2736+
JPy_DECREF(po_lineno);
2737+
return lineno;
2738+
}
2739+
27332740
static int format_python_traceback(PyTracebackObject *tb, char **buf, int *bufLen)
27342741
{
27352742
int err = 0;
@@ -2752,9 +2759,10 @@ static int format_python_traceback(PyTracebackObject *tb, char **buf, int *bufLe
27522759
}
27532760
while (tb != NULL && err == 0) {
27542761
PyCodeObject* co = PyFrame_GetCode(tb->tb_frame);
2762+
int tb_lineno = get_traceback_lineno(tb);
27552763
if (last_file == NULL ||
27562764
co->co_filename != last_file ||
2757-
last_line == -1 || tb->tb_lineno != last_line ||
2765+
last_line == -1 || tb_lineno != last_line ||
27582766
last_name == NULL || co->co_name != last_name) {
27592767
if (cnt > PYLIB_RECURSIVE_CUTOFF) {
27602768
pyObjUtf8 = format_line_repeated(cnt);
@@ -2765,15 +2773,15 @@ static int format_python_traceback(PyTracebackObject *tb, char **buf, int *bufLe
27652773
}
27662774
}
27672775
last_file = co->co_filename;
2768-
last_line = tb->tb_lineno;
2776+
last_line = tb_lineno;
27692777
last_name = co->co_name;
27702778
cnt = 0;
27712779
}
27722780
cnt++;
27732781
if (err == 0 && cnt <= PYLIB_RECURSIVE_CUTOFF) {
27742782
pyObjUtf8 = format_displayline(
27752783
co->co_filename,
2776-
tb->tb_lineno,
2784+
tb_lineno,
27772785
co->co_name);
27782786
err = append_to_java_message(pyObjUtf8, buf, bufLen);
27792787
if (err != 0) {

0 commit comments

Comments
 (0)