currently executing.
+.. cfunction:: int PyFrame_GetLineNumber(PyFrameObject *frame)
+
+ Return the line number that *frame* is currently executing.
+
+
.. cfunction:: int PyEval_GetRestricted()
If there is a current frame and it is executing in restricted mode, return true,
PyAPI_FUNC(PyCodeObject *)
PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno);
+/* Return the line number associated with the specified bytecode index
+ in this code object. If you just need the line number of a frame,
+ use PyFrame_GetLineNumber() instead. */
PyAPI_FUNC(int) PyCode_Addr2Line(PyCodeObject *, int);
/* for internal use only */
PyThreadState *f_tstate;
int f_lasti; /* Last instruction if called */
- /* As of 2.3 f_lineno is only valid when tracing is active (i.e. when
- f_trace is set) -- at other times use PyCode_Addr2Line instead. */
+ /* Call PyFrame_GetLineNumber() instead of reading this field
+ directly. As of 2.3 f_lineno is only valid when tracing is
+ active (i.e. when f_trace is set). At other times we use
+ PyCode_Addr2Line to calculate the line from the current
+ bytecode index. */
int f_lineno; /* Current line number */
int f_iblock; /* index in f_blockstack */
PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */
PyAPI_FUNC(int) PyFrame_ClearFreeList(void);
+/* Return the line of code the frame is currently executing. */
+PyAPI_FUNC(int) PyFrame_GetLineNumber(PyFrameObject *);
+
#ifdef __cplusplus
}
#endif
C-API
-----
+- Issue #5954: Add a PyFrame_GetLineNumber() function to replace most uses of
+ PyCode_Addr2Line().
+
- Issue #5959: Add a PyCode_NewEmpty() function to create a new empty code
object at a specified file, function, and line number.
return f->f_locals;
}
-static PyObject *
-frame_getlineno(PyFrameObject *f, void *closure)
+int
+PyFrame_GetLineNumber(PyFrameObject *f)
{
- int lineno;
-
if (f->f_trace)
- lineno = f->f_lineno;
+ return f->f_lineno;
else
- lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
+ return PyCode_Addr2Line(f->f_code, f->f_lasti);
+}
- return PyInt_FromLong(lineno);
+static PyObject *
+frame_getlineno(PyFrameObject *f, void *closure)
+{
+ return PyInt_FromLong(PyFrame_GetLineNumber(f));
}
/* Setter for f_lineno - you can set f_lineno from within a trace function in
static int
frame_settrace(PyFrameObject *f, PyObject* v, void *closure)
{
- /* We rely on f_lineno being accurate when f_trace is set. */
+ PyObject* old_value;
- PyObject* old_value = f->f_trace;
+ /* We rely on f_lineno being accurate when f_trace is set. */
+ f->f_lineno = PyFrame_GetLineNumber(f);
+ old_value = f->f_trace;
Py_XINCREF(v);
f->f_trace = v;
-
- if (v != NULL)
- f->f_lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
-
Py_XDECREF(old_value);
return 0;
}
else {
globals = f->f_globals;
- *lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
+ *lineno = PyFrame_GetLineNumber(f);
}
*module = NULL;
default:
fprintf(stderr,
"XXX lineno: %d, opcode: %d\n",
- PyCode_Addr2Line(f->f_code, f->f_lasti),
+ PyFrame_GetLineNumber(f),
opcode);
PyErr_SetString(PyExc_SystemError, "unknown opcode");
why = WHY_EXCEPTION;
Py_XINCREF(frame);
tb->tb_frame = frame;
tb->tb_lasti = frame->f_lasti;
- tb->tb_lineno = PyCode_Addr2Line(frame->f_code,
- frame->f_lasti);
+ tb->tb_lineno = PyFrame_GetLineNumber(frame);
PyObject_GC_Track(tb);
}
return tb;