@@ -109,6 +109,20 @@ tb_next_get(PyTracebackObject *self, void *Py_UNUSED(_))
109109 return Py_NewRef (ret );
110110}
111111
112+ static PyObject *
113+ tb_lineno_get (PyTracebackObject * self , void * Py_UNUSED (_ ))
114+ {
115+ int lineno = self -> tb_lineno ;
116+ if (lineno == -1 ) {
117+ lineno = PyCode_Addr2Line (
118+ _PyFrame_GetCode (self -> tb_frame -> f_frame ), self -> tb_lasti );
119+ if (lineno < 0 ) {
120+ Py_RETURN_NONE ;
121+ }
122+ }
123+ return PyLong_FromLong (lineno );
124+ }
125+
112126static int
113127tb_next_set (PyTracebackObject * self , PyObject * new_next , void * Py_UNUSED (_ ))
114128{
@@ -152,12 +166,12 @@ static PyMethodDef tb_methods[] = {
152166static PyMemberDef tb_memberlist [] = {
153167 {"tb_frame" , _Py_T_OBJECT , OFF (tb_frame ), Py_READONLY |Py_AUDIT_READ },
154168 {"tb_lasti" , Py_T_INT , OFF (tb_lasti ), Py_READONLY },
155- {"tb_lineno" , Py_T_INT , OFF (tb_lineno ), Py_READONLY },
156169 {NULL } /* Sentinel */
157170};
158171
159172static PyGetSetDef tb_getsetters [] = {
160173 {"tb_next" , (getter )tb_next_get , (setter )tb_next_set , NULL , NULL },
174+ {"tb_lineno" , (getter )tb_lineno_get , NULL , NULL , NULL },
161175 {NULL } /* Sentinel */
162176};
163177
@@ -236,8 +250,7 @@ _PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame)
236250 assert (tb_next == NULL || PyTraceBack_Check (tb_next ));
237251 assert (frame != NULL );
238252 int addr = _PyInterpreterFrame_LASTI (frame -> f_frame ) * sizeof (_Py_CODEUNIT );
239- return tb_create_raw ((PyTracebackObject * )tb_next , frame , addr ,
240- PyFrame_GetLineNumber (frame ));
253+ return tb_create_raw ((PyTracebackObject * )tb_next , frame , addr , -1 );
241254}
242255
243256
@@ -681,23 +694,27 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
681694 }
682695 while (tb != NULL ) {
683696 code = PyFrame_GetCode (tb -> tb_frame );
697+ int tb_lineno = tb -> tb_lineno ;
698+ if (tb_lineno == -1 ) {
699+ tb_lineno = PyCode_Addr2Line (_PyFrame_GetCode (tb -> tb_frame -> f_frame ), tb -> tb_lasti );
700+ }
684701 if (last_file == NULL ||
685702 code -> co_filename != last_file ||
686- last_line == -1 || tb -> tb_lineno != last_line ||
703+ last_line == -1 || tb_lineno != last_line ||
687704 last_name == NULL || code -> co_name != last_name ) {
688705 if (cnt > TB_RECURSIVE_CUTOFF ) {
689706 if (tb_print_line_repeated (f , cnt ) < 0 ) {
690707 goto error ;
691708 }
692709 }
693710 last_file = code -> co_filename ;
694- last_line = tb -> tb_lineno ;
711+ last_line = tb_lineno ;
695712 last_name = code -> co_name ;
696713 cnt = 0 ;
697714 }
698715 cnt ++ ;
699716 if (cnt <= TB_RECURSIVE_CUTOFF ) {
700- if (tb_displayline (tb , f , code -> co_filename , tb -> tb_lineno ,
717+ if (tb_displayline (tb , f , code -> co_filename , tb_lineno ,
701718 tb -> tb_frame , code -> co_name ) < 0 ) {
702719 goto error ;
703720 }
0 commit comments