Skip to content

Commit

Permalink
python support: fixed some problems with handling of unicode strings
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@10038 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
wonder committed Jan 29, 2009
1 parent 28bfeb5 commit 376bccc
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 25 deletions.
97 changes: 72 additions & 25 deletions src/python/qgspythonutilsimpl.cpp
Expand Up @@ -169,7 +169,10 @@ void QgsPythonUtilsImpl::uninstallConsoleHooks()

bool QgsPythonUtilsImpl::runStringUnsafe( const QString& command )
{
PyRun_String( command.toLocal8Bit().data(), Py_single_input, mMainDict, mMainDict );
// TODO: convert special characters from unicode strings u"..." to \uXXXX
// so that they're not mangled to utf-8
// (non-unicode strings can be mangled)
PyRun_String( command.toUtf8().data(), Py_single_input, mMainDict, mMainDict );
return ( PyErr_Occurred() == 0 );
}

Expand Down Expand Up @@ -294,20 +297,15 @@ QString QgsPythonUtilsImpl::getTypeAsString( PyObject* obj )
else
{
QgsDebugMsg( "got object" );
PyObject* s = PyObject_Str( obj );
QString str;
if ( s && PyString_Check( s ) )
str = QString( PyString_AsString( s ) );
Py_XDECREF( s );
return str;
return PyObjectToQString( obj );
}
}

bool QgsPythonUtilsImpl::getError( QString& errorClassName, QString& errorText )
{
if ( !PyErr_Occurred() )
return false;

PyObject* obj_str;
PyObject* err_type;
PyObject* err_value;
Expand All @@ -322,9 +320,7 @@ bool QgsPythonUtilsImpl::getError( QString& errorClassName, QString& errorText )
// get exception's text
if ( err_value != NULL && err_value != Py_None )
{
obj_str = PyObject_Str( err_value ); // new reference
errorText = PyString_AS_STRING( obj_str );
Py_XDECREF( obj_str );
errorText = PyObjectToQString( err_value );
}
else
errorText.clear();
Expand All @@ -342,24 +338,77 @@ QString QgsPythonUtilsImpl::getResult()
return getVariableFromMain( "__result" );
}

QString QgsPythonUtilsImpl::PyObjectToQString( PyObject* obj )
{
QString result;

// is it None?
if ( obj == Py_None )
{
return QString();
}

// 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 );
return result;
}

// check whether the object is a classical (8-bit) string
if ( PyString_Check( obj ) )
{
return QString::fromUtf8( PyString_AS_STRING( 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 )
{
// get utf-8 representation of unicode string (new reference)
PyObject* obj_utf8 = PyUnicode_AsUTF8String(obj_uni);
// convert from utf-8 to QString
if ( obj_utf8 )
result = QString::fromUtf8(PyString_AsString( obj_utf8 ));
else
result = "(qgis error)";
Py_XDECREF( obj_utf8 );
Py_XDECREF( obj_uni );
return result;
}

// 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 ) );
Py_XDECREF( obj_str );
return result;
}

// some problem with conversion to unicode string
QgsDebugMsg("unable to convert PyObject to a QString!");
return "(qgis error)";
}

QString QgsPythonUtilsImpl::getVariableFromMain( QString name )
{
PyObject* obj;
PyObject* obj_str;

QString output;

// get the result
obj = PyDict_GetItemString( mMainDict, name.toUtf8() ); // obj is borrowed reference

if ( obj != NULL && obj != Py_None )
{
obj_str = PyObject_Str( obj ); // obj_str is new reference
if ( obj_str != NULL && obj_str != Py_None )
{
output = PyString_AsString( obj_str );
}
Py_XDECREF( obj_str );
output = PyObjectToQString( obj );
}

// erase result
Expand All @@ -370,15 +419,13 @@ QString QgsPythonUtilsImpl::getVariableFromMain( QString name )

bool QgsPythonUtilsImpl::evalString( const QString& command, QString& result )
{
PyObject* res = PyRun_String( command.toLocal8Bit().data(), Py_eval_input, mMainDict, mMainDict );
PyObject* res = PyRun_String( command.toUtf8().data(), Py_eval_input, mMainDict, mMainDict );

if ( res != NULL && PyString_Check( res ) )
if ( res != NULL )
{
result = PyString_AsString( res );
Py_XDECREF( res );
result = PyObjectToQString( res );
return true;
}
Py_XDECREF( res );
return false;
}

Expand Down Expand Up @@ -426,7 +473,7 @@ QString QgsPythonUtilsImpl::getPluginMetadata( QString pluginName, QString funct

// temporary disable error hook - UI will handle this gracefully
uninstallErrorHook();
PyObject* obj = PyRun_String( command.toLocal8Bit().data(), Py_eval_input, mMainDict, mMainDict );
PyObject* obj = PyRun_String( command.toUtf8().data(), Py_eval_input, mMainDict, mMainDict );

if ( PyErr_Occurred() )
{
Expand Down
3 changes: 3 additions & 0 deletions src/python/qgspythonutilsimpl.h
Expand Up @@ -116,6 +116,9 @@ class QgsPythonUtilsImpl : public QgsPythonUtils

QString getTraceback();

//! convert python object to QString. If the object isn't unicode/str, it will be converted
QString PyObjectToQString( PyObject* obj );

//! reference to module __main__
PyObject* mMainModule;

Expand Down

0 comments on commit 376bccc

Please sign in to comment.