28 PyGILState_STATE state = PyGILState_Ensure();
31#if PY_VERSION_HEX >= 0x030c0000
32 PyObject *pyvalue = PyErr_GetRaisedException();
34 PyObject* traceback = pyvalue ? PyException_GetTraceback(pyvalue) :
nullptr;
36 PyObject* pytype =
nullptr, *pyvalue =
nullptr, *pytrace =
nullptr;
37 PyErr_Fetch(&pytype, &pyvalue, &pytrace);
39 Py_XINCREF(traceback);
42 if (pytype && pyvalue) {
43 const char* tname = PyExceptionClass_Name(pytype);
45 char* dot = strrchr((
char*)tname,
'.');
46 if (dot) tname = dot+1;
51 PyObject* msg = PyObject_Str(pyvalue);
62 while (traceback && traceback != Py_None) {
63 PyObject* frame = PyObject_GetAttrString(traceback,
"tb_frame");
64 PyObject* code = PyObject_GetAttrString(frame,
"f_code");
67 PyObject* filename = PyObject_GetAttrString(code,
"co_filename");
70 PyObject* filenameStr = PyObject_Str(filename);
72 Py_DECREF(filenameStr);
75 PyObject*
name = PyObject_GetAttrString(code,
"co_name");
81 PyObject* lineno = PyObject_GetAttrString(traceback,
"tb_lineno");
82 locLine = PyLong_AsLong(lineno);
85 if (locFile ==
"<string>") {
86 PyObject* nextTraceback = PyObject_GetAttrString(traceback,
"tb_next");
88 traceback = nextTraceback;
95 Py_XDECREF(traceback);
97#if PY_VERSION_HEX >= 0x030c0000
98 PyErr_SetRaisedException(pyvalue);
100 PyErr_Restore(pytype, pyvalue, pytrace);
104 fMsg =
"python exception";
106 if (!locFile.empty()) {
109 locFile = locFile.substr(locFile.find_last_of(
"/\\") + 1);
111 fMsg +=
" (at " + locFile +
":" + std::to_string(locLine);
113 if (locName !=
"<module>")
114 fMsg +=
" in " + locName;
120 PyGILState_Release(state);