Reputation: 21514
I run a Python script from a C++ program using PyRun_SimpleFile
. I defined a custom module (using PyImport_AppendInittab
, as done here), so it can be imported in my Python script and some C++ code gets executed by the Python script when functions from this module are used, this is done through a callback PyObject* MyFunction(PyObject *self, PyObject *args)
being invoked by Python interpreter.
I want to know the current script file name and line number within the callback function being invoked.
I could not find any way to retrieve this. Is this possible?
Note: This question is definitely not a duplicate of How to get the caller's method name in the called method?. I'm trying to retrieve file name and line number from C++ code executing and later executed by a Python script.
Upvotes: 2
Views: 352
Reputation: 5783
You will need PyTraceBack_Here
.
You can take a look at a traceback object's implementation here
Here is an example printig the traceback created by PyTraceBack_Here
#include <Python.h>
PyObject * mymodule_meth_test(PyObject * self) {
PyTraceBack_Here(PyEval_GetFrame());
PyObject * exc;
PyObject * val;
PyObject * tb;
PyErr_Fetch(&exc, &val, &tb);
PyTraceBack_Print(tb, PySys_GetObject("stderr"));
Py_RETURN_NONE;
}
PyMethodDef module_methods[] = {
{"test", (PyCFunction)mymodule_meth_test, METH_NOARGS, NULL},
{},
};
PyModuleDef module_def = {PyModuleDef_HEAD_INIT, "mymodule", NULL, -1, module_methods};
extern "C" PyObject * PyInit_mymodule() {
PyObject * module = PyModule_Create(&module_def);
return module;
}
From the tb
object you should be able to extract the filename and line number.
It is an ordinary PyObject you can pass it to a python script or inspect it.
Here is how to extract the values without taking care of the refcounts:
int line = PyLong_AsLong(PyObject_GetAttrString(PyObject_GetAttrString(tb, "tb_frame"), "f_lineno"));
const char * filename = PyUnicode_AsUTF8(PyObject_GetAttrString(PyObject_GetAttrString(PyObject_GetAttrString(tb, "tb_frame"), "f_code"), "co_filename"));
Upvotes: 1