I have embedded python interpreter in my application. I use it to run python scripts using PyRun_String()
API. I can fetch error information using PyErr_F
The attributes are set on the the PySyntaxErrorObject struct, but be aware that the struct is not exposed if you are adhering to Python's stable ABI. Otherwise you should be able to use a PyObject_GetAttr* function to get at the attributes.
I resolved it in following way. I used PyErr_NormalizeException() after PyErr_Fetch() and code is working fine now.
int main(int argc, char** argv)
{
Py_Initialize();
// Get a reference to the main module.
PyObject* main_module =
PyImport_AddModule("__main__");
// Get the main module's dictionary
// and make a copy of it.
PyObject* main_dict =
PyModule_GetDict(main_module);
const char *script_source = "def main():\n\tprint('Hello'\n\nmain()";
PyObject *res = PyRun_String(script_source,Py_file_input,main_dict,main_dict);
if(res == NULL)
{
PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL;
PyErr_Fetch(&ptype,&pvalue,&ptraceback);
PyErr_NormalizeException(&ptype,&pvalue,&ptraceback);
char *msg;
char *file;
int line;
int offset;
char *text;
int res = PyArg_ParseTuple(pvalue,"s(siis)",&msg,&file,&line,&offset,&text);
PyObject* file_name = PyObject_GetAttrString(pvalue,"filename");
PyObject* file_name_str = PyObject_Str(file_name);
PyObject* file_name_unicode = PyUnicode_AsEncodedString(file_name_str,"utf-8", "Error");
char *actual_file_name = PyBytes_AsString(file_name_unicode);
PyObject* line_no = PyObject_GetAttrString(pvalue,"lineno");
PyObject* line_no_str = PyObject_Str(line_no);
PyObject* line_no_unicode = PyUnicode_AsEncodedString(line_no_str,"utf-8", "Error");
char *actual_line_no = PyBytes_AsString(line_no_unicode);
printf("done");
}
}