Skip to content

Commit

Permalink
[py3] Some python3 compatibility fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn committed Nov 16, 2015
1 parent dea8c9f commit 26ce3cc
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 34 deletions.
2 changes: 1 addition & 1 deletion src/core/auth/qgsauthmanager.h
Expand Up @@ -165,7 +165,7 @@ class CORE_EXPORT QgsAuthManager : public QObject
void setScheduledAuthDbEraseRequestEmitted( bool emitted ) { mScheduledDbEraseRequestEmitted = emitted; }

/** Simple text tag describing authentication system for message logs */
const QString authManTag() const { return smAuthManTag; }
QString authManTag() const { return smAuthManTag; }

/** Instantiate and register existing C++ core authentication methods from plugins */
bool registerCoreAuthMethods();
Expand Down
79 changes: 48 additions & 31 deletions src/python/qgspythonutilsimpl.cpp
Expand Up @@ -33,6 +33,12 @@
#include <QStringList>
#include <QDir>

#ifdef PYTHON2
#define PYOBJ2QSTRING(obj) PyString_AsString( obj )
#else
#define PYOBJ2QSTRING(obj) QString::fromUtf8( PyUnicode_AsUTF8( obj ) )
#endif

PyThreadState* _mainState;

QgsPythonUtilsImpl::QgsPythonUtilsImpl()
Expand Down Expand Up @@ -119,13 +125,21 @@ bool QgsPythonUtilsImpl::checkSystemImports()
return false;
}
}

#ifdef PYTHON2
// import Qt bindings
if ( !runString( "from PyQt4 import QtCore, QtGui",
QObject::tr( "Couldn't load PyQt4." ) + '\n' + QObject::tr( "Python support will be disabled." ) ) )
QObject::tr( "Couldn't load PyQt." ) + '\n' + QObject::tr( "Python support will be disabled." ) ) )
{
return false;
}
#else
// import Qt bindings
if ( !runString( "from PyQt5 import QtCore, QtGui",
QObject::tr( "Couldn't load PyQt." ) + '\n' + QObject::tr( "Python support will be disabled." ) ) )
{
return false;
}
#endif

// import QGIS bindings
QString error_msg = QObject::tr( "Couldn't load PyQGIS." ) + '\n' + QObject::tr( "Python support will be disabled." );
Expand Down Expand Up @@ -349,9 +363,15 @@ QString QgsPythonUtilsImpl::getTraceback()
PyErr_Fetch( &type, &value, &traceback );
PyErr_NormalizeException( &type, &value, &traceback );

modStringIO = PyImport_ImportModule( "cStringIO" );
#ifdef PYTHON2
const char* iomod = "cStringIO";
#else
const char* iomod = "io";
#endif

modStringIO = PyImport_ImportModule( iomod );
if ( modStringIO == NULL )
TRACEBACK_FETCH_ERROR( "can't import cStringIO" );
TRACEBACK_FETCH_ERROR( QString( "can't import %1" ).arg( iomod ) );

obStringIO = PyObject_CallMethod( modStringIO, ( char* ) "StringIO", NULL );

Expand Down Expand Up @@ -382,12 +402,7 @@ QString QgsPythonUtilsImpl::getTraceback()
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

result = PYOBJ2QSTRING( obResult );

done:

Expand All @@ -413,23 +428,27 @@ QString QgsPythonUtilsImpl::getTraceback()

QString QgsPythonUtilsImpl::getTypeAsString( PyObject* obj )
{
if ( obj == NULL )
return NULL;
if ( !obj )
return 0;

#ifdef PYTHON2
if ( PyClass_Check( obj ) )
{
QgsDebugMsg( "got class" );
return QString( PyString_AsString((( PyClassObject* )obj )->cl_name ) );
}
else if ( PyType_Check( obj ) )
{
QgsDebugMsg( "got type" );
return QString((( PyTypeObject* )obj )->tp_name );
}
else
{
QgsDebugMsg( "got object" );
return PyObjectToQString( obj );
}
#endif
if ( PyType_Check( obj ) )
{
QgsDebugMsg( "got type" );
return QString((( PyTypeObject* )obj )->tp_name );
}
else
{
QgsDebugMsg( "got object" );
return PyObjectToQString( obj );
}
}

bool QgsPythonUtilsImpl::getError( QString& errorClassName, QString& errorText )
Expand Down Expand Up @@ -487,15 +506,11 @@ QString QgsPythonUtilsImpl::PyObjectToQString( PyObject* obj )
// check whether the object is already a unicode string
if ( PyUnicode_Check( obj ) )
{
PyObject* utf8 = PyUnicode_AsUTF8String( obj );
if ( utf8 )
result = QString::fromUtf8( PyString_AS_STRING( utf8 ) );
else
result = "(qgis error)";
Py_XDECREF( utf8 );
result = PYOBJ2QSTRING( obj );
return result;
}

#if PYTHON2
// check whether the object is a classical (8-bit) string
if ( PyString_Check( obj ) )
{
Expand All @@ -504,7 +519,6 @@ QString QgsPythonUtilsImpl::PyObjectToQString( PyObject* obj )

// it's some other type of object:
// convert object to unicode string (equivalent to calling unicode(obj) )

PyObject* obj_uni = PyObject_Unicode( obj ); // obj_uni is new reference
if ( obj_uni )
{
Expand All @@ -515,15 +529,18 @@ QString QgsPythonUtilsImpl::PyObjectToQString( PyObject* obj )
result = QString::fromUtf8( PyString_AsString( obj_utf8 ) );
else
result = "(qgis error)";

Py_XDECREF( obj_utf8 );
Py_XDECREF( obj_uni );
return result;
}
#endif

// if conversion to unicode failed, try to convert it to classic string, i.e. str(obj)
PyObject* obj_str = PyObject_Str( obj ); // new reference
if ( obj_str )
{
result = QString::fromUtf8( PyString_AS_STRING( obj_str ) );
result = PYOBJ2QSTRING( obj_str );
Py_XDECREF( obj_str );
return result;
}
Expand Down Expand Up @@ -572,11 +589,11 @@ QString QgsPythonUtilsImpl::homePythonPath()
QString settingsDir = QgsApplication::qgisSettingsDirPath();
if ( QDir::cleanPath( settingsDir ) == QDir::homePath() + QString( "/.qgis%1" ).arg( QGis::QGIS_VERSION_INT / 10000 ) )
{
return QString( "\"%1/.qgis%2/python\".decode('utf-8')" ).arg( QDir::homePath() ).arg( QGis::QGIS_VERSION_INT / 10000 );
return QString( "b\"%1/.qgis%2/python\".decode('utf-8')" ).arg( QDir::homePath() ).arg( QGis::QGIS_VERSION_INT / 10000 );
}
else
{
return '"' + settingsDir.replace( '\\', "\\\\" ) + "python\".decode('utf-8')";
return "b\"" + settingsDir.replace( '\\', "\\\\" ) + "python\".decode('utf-8')";
}
}

Expand Down
4 changes: 2 additions & 2 deletions tests/src/core/testqgspainteffect.cpp
Expand Up @@ -254,13 +254,13 @@ void TestQgsPaintEffect::stackSaveRestore()

//check if stack effect node was written
QDomNodeList evalNodeList = effectParentElem.childNodes();
QCOMPARE( evalNodeList.length(), ( unsigned int )1 );
QCOMPARE( evalNodeList.count(), 1 );
QDomElement effectElem = evalNodeList.at( 0 ).toElement();
QCOMPARE( effectElem.attribute( "type" ), stack->type() );

//should be two effect child nodes
QDomNodeList childNodeList = effectElem.elementsByTagName( "effect" );
QCOMPARE( childNodeList.length(), ( unsigned int )2 );
QCOMPARE( childNodeList.count(), 2 );
QCOMPARE( childNodeList.at( 0 ).toElement().attribute( "type" ), blur->type() );
QCOMPARE( childNodeList.at( 1 ).toElement().attribute( "type" ), shadow->type() );

Expand Down

0 comments on commit 26ce3cc

Please sign in to comment.