QString QgsPythonUtilsImpl::getTraceback() { #define TRACEBACK_FETCH_ERROR(what) {errMsg = what; goto done;} // acquire global interpreter lock to ensure we are in a consistent state PyGILState_STATE gstate; gstate = PyGILState_Ensure(); QString errMsg; QString result; PyObject *modStringIO = nullptr; PyObject *modTB = nullptr; PyObject *obStringIO = nullptr; PyObject *obResult = nullptr; PyObject *type, *value, *traceback; PyErr_Fetch( &type, &value, &traceback ); PyErr_NormalizeException( &type, &value, &traceback ); #if (PY_VERSION_HEX < 0x03000000) const char* iomod = "cStringIO"; #else const char* iomod = "io"; #endif modStringIO = PyImport_ImportModule( iomod ); if ( !modStringIO ) TRACEBACK_FETCH_ERROR( QString( "can't import %1" ).arg( iomod ) ); obStringIO = PyObject_CallMethod( modStringIO, ( char* ) "StringIO", nullptr ); /* Construct a cStringIO object */ if ( !obStringIO ) TRACEBACK_FETCH_ERROR( "cStringIO.StringIO() failed" ); modTB = PyImport_ImportModule( "traceback" ); if ( !modTB ) TRACEBACK_FETCH_ERROR( "can't import traceback" ); obResult = PyObject_CallMethod( modTB, ( char* ) "print_exception", ( char* ) "OOOOO", type, value ? value : Py_None, traceback ? traceback : Py_None, Py_None, obStringIO ); if ( !obResult ) TRACEBACK_FETCH_ERROR( "traceback.print_exception() failed" ); Py_DECREF( obResult ); obResult = PyObject_CallMethod( obStringIO, ( char* ) "getvalue", nullptr ); if ( !obResult ) TRACEBACK_FETCH_ERROR( "getvalue() failed." ); /* And it should be a string all ready to go - duplicate it. */ if ( ! #if (PY_VERSION_HEX < 0x03000000) PyString_Check( obResult ) #else PyUnicode_Check( obResult ) #endif ) TRACEBACK_FETCH_ERROR( "getvalue() did not return a string" ); result = PYOBJ2QSTRING( obResult ); done: // All finished - first see if we encountered an error if ( result.isEmpty() && !errMsg.isEmpty() ) { result = errMsg; } Py_XDECREF( modStringIO ); Py_XDECREF( modTB ); Py_XDECREF( obStringIO ); Py_XDECREF( obResult ); Py_XDECREF( value ); Py_XDECREF( traceback ); Py_XDECREF( type ); // we are done calling python API, release global interpreter lock PyGILState_Release( gstate ); return result; }
std::string PyTracebackToString(void) { std::string errMsg; /* holds a local error message */ std::string result; /* a valid, allocated result. */ PyObject *modStringIO = NULL; PyObject *modTB = NULL; PyObject *obStringIO = NULL; PyObject *obResult = NULL; PyObject *type, *value, *traceback; PyErr_Fetch(&type, &value, &traceback); PyErr_NormalizeException(&type, &value, &traceback); # if PY_VERSION_HEX >= 0x03000000 modStringIO = PyImport_ImportModule("io"); #else modStringIO = PyImport_ImportModule("cStringIO"); #endif if (modStringIO==NULL) TRACEBACK_FETCH_ERROR("cant import cStringIO\n"); obStringIO = PyObject_CallMethod(modStringIO, "StringIO", NULL); /* Construct a cStringIO object */ if (obStringIO==NULL) TRACEBACK_FETCH_ERROR("cStringIO.StringIO() failed\n"); modTB = PyImport_ImportModule("traceback"); if (modTB==NULL) TRACEBACK_FETCH_ERROR("cant import traceback\n"); obResult = PyObject_CallMethod(modTB, "print_exception", "OOOOO", type, value ? value : Py_None, traceback ? traceback : Py_None, Py_None, obStringIO); if (obResult==NULL) TRACEBACK_FETCH_ERROR("traceback.print_exception() failed\n"); Py_DECREF(obResult); obResult = PyObject_CallMethod(obStringIO, "getvalue", NULL); if (obResult==NULL) TRACEBACK_FETCH_ERROR("getvalue() failed.\n"); /* And it should be a string all ready to go - duplicate it. */ if (!pyStrCheck(obResult)) TRACEBACK_FETCH_ERROR("getvalue() did not return a string\n"); result = extractStringFromPyStr(obResult); done: /* All finished - first see if we encountered an error */ if (result.empty() && errMsg.size()) { result = errMsg; } Py_XDECREF(modStringIO); Py_XDECREF(modTB); Py_XDECREF(obStringIO); Py_XDECREF(obResult); Py_XDECREF(value); Py_XDECREF(traceback); Py_XDECREF(type); return result; }
QString QgsPythonUtilsImpl::getTraceback() { #define TRACEBACK_FETCH_ERROR(what) {errMsg = what; goto done;} // acquire global interpreter lock to ensure we are in a consistent state PyGILState_STATE gstate; gstate = PyGILState_Ensure(); QString errMsg; QString result; PyObject *modStringIO = NULL; PyObject *modTB = NULL; PyObject *obStringIO = NULL; PyObject *obResult = NULL; PyObject *type, *value, *traceback; PyErr_Fetch( &type, &value, &traceback ); PyErr_NormalizeException( &type, &value, &traceback ); modStringIO = PyImport_ImportModule( "cStringIO" ); if ( modStringIO == NULL ) TRACEBACK_FETCH_ERROR( "can't import cStringIO" ); obStringIO = PyObject_CallMethod( modStringIO, ( char* ) "StringIO", NULL ); /* Construct a cStringIO object */ if ( obStringIO == NULL ) TRACEBACK_FETCH_ERROR( "cStringIO.StringIO() failed" ); modTB = PyImport_ImportModule( "traceback" ); if ( modTB == NULL ) TRACEBACK_FETCH_ERROR( "can't import traceback" ); obResult = PyObject_CallMethod( modTB, ( char* ) "print_exception", ( char* ) "OOOOO", type, value ? value : Py_None, traceback ? traceback : Py_None, Py_None, obStringIO ); if ( obResult == NULL ) TRACEBACK_FETCH_ERROR( "traceback.print_exception() failed" ); Py_DECREF( obResult ); obResult = PyObject_CallMethod( obStringIO, ( char* ) "getvalue", NULL ); if ( obResult == NULL ) TRACEBACK_FETCH_ERROR( "getvalue() failed." ); /* And it should be a string all ready to go - duplicate it. */ if ( !PyUnicode_Check( obResult ) ) TRACEBACK_FETCH_ERROR( "getvalue() did not return a string" ); #if PYTHON2 result = PyString_AsString( obResult ); #else result = QString::fromUtf8( PyUnicode_AsUTF8( obResult ) ); #endif done: // All finished - first see if we encountered an error if ( result.isEmpty() && !errMsg.isEmpty() ) { result = errMsg; } Py_XDECREF( modStringIO ); Py_XDECREF( modTB ); Py_XDECREF( obStringIO ); Py_XDECREF( obResult ); Py_XDECREF( value ); Py_XDECREF( traceback ); Py_XDECREF( type ); // we are done calling python API, release global interpreter lock PyGILState_Release( gstate ); return result; }
char *PyTraceback_AsString(PyObject *exc_tb) { const char *errMsg = NULL; /* holds a local error message */ char *result = NULL; /* a valid, allocated result. */ PyObject *modStringIO = NULL; PyObject *modTB = NULL; PyObject *obFuncStringIO = NULL; PyObject *obStringIO = NULL; PyObject *obFuncTB = NULL; PyObject *argsTB = NULL; PyObject *obResult = NULL; #if PY_MAJOR_VERSION <= 2 /* Import the modules we need - cStringIO and traceback */ modStringIO = PyImport_ImportModule("cStringIO"); if (modStringIO==NULL) TRACEBACK_FETCH_ERROR("cant import cStringIO\n"); modTB = PyImport_ImportModule("traceback"); if (modTB==NULL) TRACEBACK_FETCH_ERROR("cant import traceback\n"); /* Construct a cStringIO object */ obFuncStringIO = PyObject_GetAttrString(modStringIO, "StringIO"); if (obFuncStringIO==NULL) TRACEBACK_FETCH_ERROR("cant find cStringIO.StringIO\n"); obStringIO = PyObject_CallObject(obFuncStringIO, NULL); if (obStringIO==NULL) TRACEBACK_FETCH_ERROR("cStringIO.StringIO() failed\n"); #else /* Import the modules we need - io and traceback */ modStringIO = PyImport_ImportModule("io"); if (modStringIO==NULL) TRACEBACK_FETCH_ERROR("cant import io\n"); modTB = PyImport_ImportModule("traceback"); if (modTB==NULL) TRACEBACK_FETCH_ERROR("cant import traceback\n"); /* Construct a StringIO object */ obFuncStringIO = PyObject_GetAttrString(modStringIO, "StringIO"); if (obFuncStringIO==NULL) TRACEBACK_FETCH_ERROR("cant find io.StringIO\n"); obStringIO = PyObject_CallObject(obFuncStringIO, NULL); if (obStringIO==NULL) TRACEBACK_FETCH_ERROR("io.StringIO() failed\n"); #endif /* Get the traceback.print_exception function, and call it. */ obFuncTB = PyObject_GetAttrString(modTB, "print_tb"); if (obFuncTB==NULL) TRACEBACK_FETCH_ERROR("cant find traceback.print_tb\n"); argsTB = Py_BuildValue("OOO", exc_tb ? exc_tb : Py_None, Py_None, obStringIO); if (argsTB==NULL) TRACEBACK_FETCH_ERROR("cant make print_tb arguments\n"); obResult = PyObject_CallObject(obFuncTB, argsTB); if (obResult==NULL) TRACEBACK_FETCH_ERROR("traceback.print_tb() failed\n"); /* Now call the getvalue() method in the StringIO instance */ Py_DECREF(obFuncStringIO); obFuncStringIO = PyObject_GetAttrString(obStringIO, "getvalue"); if (obFuncStringIO==NULL) TRACEBACK_FETCH_ERROR("cant find getvalue function\n"); Py_DECREF(obResult); obResult = PyObject_CallObject(obFuncStringIO, NULL); if (obResult==NULL) TRACEBACK_FETCH_ERROR("getvalue() failed.\n"); /* And it should be a string all ready to go - duplicate it. */ #if PY_MAJOR_VERSION <= 2 if (!PyString_Check(obResult)) #else if (!PyUnicode_Check(obResult)) #endif TRACEBACK_FETCH_ERROR("getvalue() did not return a string\n"); { // a temp scope so I can use temp locals. #if PY_MAJOR_VERSION <= 2 char *tempResult = PyString_AsString(obResult); #else char *tempResult = PyUnicode_AsUTF8(obResult); #endif result = (char *)PyMem_Malloc(strlen(tempResult)+1); if (result==NULL) TRACEBACK_FETCH_ERROR("memory error duplicating the traceback string\n"); strcpy(result, tempResult); } // end of temp scope. done: /* All finished - first see if we encountered an error */ if (result==NULL && errMsg != NULL) { result = (char *)PyMem_Malloc(strlen(errMsg)+1); if (result != NULL) /* if it does, not much we can do! */ strcpy(result, errMsg); } Py_XDECREF(modStringIO); Py_XDECREF(modTB); Py_XDECREF(obFuncStringIO); Py_XDECREF(obStringIO); Py_XDECREF(obFuncTB); Py_XDECREF(argsTB); Py_XDECREF(obResult); return result; }
QString QgsPythonUtilsImpl::getTraceback() { #define TRACEBACK_FETCH_ERROR(what) {errMsg = what; goto done;} QString errMsg; QString result; PyObject *modStringIO = NULL; PyObject *modTB = NULL; PyObject *obStringIO = NULL; PyObject *obResult = NULL; PyObject *type, *value, *traceback; PyErr_Fetch( &type, &value, &traceback ); PyErr_NormalizeException( &type, &value, &traceback ); modStringIO = PyImport_ImportModule( "cStringIO" ); if ( modStringIO == NULL ) TRACEBACK_FETCH_ERROR( "can't import cStringIO" ); obStringIO = PyObject_CallMethod( modStringIO, ( char* ) "StringIO", NULL ); /* Construct a cStringIO object */ if ( obStringIO == NULL ) TRACEBACK_FETCH_ERROR( "cStringIO.StringIO() failed" ); modTB = PyImport_ImportModule( "traceback" ); if ( modTB == NULL ) TRACEBACK_FETCH_ERROR( "can't import traceback" ); obResult = PyObject_CallMethod( modTB, ( char* ) "print_exception", ( char* ) "OOOOO", type, value ? value : Py_None, traceback ? traceback : Py_None, Py_None, obStringIO ); if ( obResult == NULL ) TRACEBACK_FETCH_ERROR( "traceback.print_exception() failed" ); Py_DECREF( obResult ); obResult = PyObject_CallMethod( obStringIO, ( char* ) "getvalue", NULL ); if ( obResult == NULL ) TRACEBACK_FETCH_ERROR( "getvalue() failed." ); /* And it should be a string all ready to go - duplicate it. */ if ( !PyString_Check( obResult ) ) TRACEBACK_FETCH_ERROR( "getvalue() did not return a string" ); result = PyString_AsString( obResult ); done: // All finished - first see if we encountered an error if ( result.isEmpty() && !errMsg.isEmpty() ) { result = errMsg; } Py_XDECREF( modStringIO ); Py_XDECREF( modTB ); Py_XDECREF( obStringIO ); Py_XDECREF( obResult ); Py_XDECREF( value ); Py_XDECREF( traceback ); Py_XDECREF( type ); return result; }