2023-12-07 10:38:10 +01:00
|
|
|
%Module(name=qgis._core,
|
|
|
|
keyword_arguments="All")
|
|
|
|
|
|
|
|
${DEFAULTDOCSTRINGSIGNATURE}
|
|
|
|
|
|
|
|
%ModuleCode
|
|
|
|
|
|
|
|
#include "qgsexception.h"
|
|
|
|
#include "qgslogger.h"
|
|
|
|
|
|
|
|
QString 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 );
|
|
|
|
|
|
|
|
const char *iomod = "io";
|
|
|
|
|
|
|
|
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 ( !PyUnicode_Check( obResult ) )
|
|
|
|
TRACEBACK_FETCH_ERROR( "getvalue() did not return a string" );
|
|
|
|
|
|
|
|
result = QString::fromUtf8( PyUnicode_AsUTF8( 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
%End
|
|
|
|
|
|
|
|
%Import QtXml/QtXmlmod.sip
|
|
|
|
%Import QtNetwork/QtNetworkmod.sip
|
|
|
|
%Import QtSql/QtSqlmod.sip
|
|
|
|
|
|
|
|
%Import QtPrintSupport/QtPrintSupportmod.sip
|
|
|
|
%Import QtWidgets/QtWidgetsmod.sip
|
|
|
|
%Import QtPositioning/QtPositioningmod.sip
|
2024-02-06 07:53:11 +01:00
|
|
|
%Import QtSerialPort/QtSerialPortmod.sip
|
2023-12-07 10:38:10 +01:00
|
|
|
|
|
|
|
%Feature HAVE_GUI
|
|
|
|
%Feature HAVE_QTSERIALPORT
|
2024-01-21 10:10:20 +07:00
|
|
|
%Feature HAVE_QTPRINTER
|
2023-12-07 10:38:10 +01:00
|
|
|
%Feature ANDROID
|
|
|
|
%Feature VECTOR_MAPPED_TYPE
|
2023-12-15 12:17:30 +10:00
|
|
|
%Feature HAVE_WEBENGINE_SIP
|
2023-12-07 10:38:10 +01:00
|
|
|
%Feature PYQT6
|
|
|
|
|
|
|
|
%Include conversions.sip
|
|
|
|
%Include qgsexception.sip
|
|
|
|
%Include typedefs.sip
|
|
|
|
%Include std.sip
|
|
|
|
|
|
|
|
|
|
|
|
%Include core_auto.sip
|
|
|
|
|
|
|
|
%VirtualErrorHandler processing_exception_handler
|
|
|
|
// if an explicit QgsProcessingException was raised, we don't retrieve
|
|
|
|
// and append the trace. It's too noisy for these "expected" type errors.
|
|
|
|
// For all other exceptions, it's likely a coding error in the algorithm,
|
|
|
|
// so we DO retrieve the full traceback for debugging.
|
|
|
|
PyGILState_STATE gstate;
|
|
|
|
gstate = PyGILState_Ensure();
|
|
|
|
PyTypeObject* err = reinterpret_cast< PyTypeObject* >( PyErr_Occurred() );
|
|
|
|
const bool isProcessingException = err && QString( err->tp_name ) == QStringLiteral( "QgsProcessingException" );
|
|
|
|
|
|
|
|
QString what;
|
|
|
|
if ( isProcessingException )
|
|
|
|
{
|
|
|
|
PyObject *type, *value, *traceback;
|
|
|
|
PyErr_Fetch( &type, &value, &traceback );
|
|
|
|
// check whether the object is already a unicode string
|
|
|
|
if ( PyUnicode_Check( value) )
|
|
|
|
{
|
|
|
|
what = QString::fromUtf8( PyUnicode_AsUTF8( value ) );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PyObject* str = PyObject_Str( value );
|
|
|
|
what = QString::fromUtf8( PyUnicode_AsUTF8( str ) );
|
|
|
|
Py_XDECREF( str );
|
|
|
|
}
|
|
|
|
PyGILState_Release( gstate );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PyGILState_Release( gstate );
|
|
|
|
QString trace = getTraceback();
|
|
|
|
QgsLogger::critical( trace );
|
|
|
|
what = trace;
|
|
|
|
}
|
|
|
|
SIP_RELEASE_GIL( sipGILState );
|
|
|
|
throw QgsProcessingException( what );
|
|
|
|
%End
|