Skip to content

Commit 376bccc

Browse files
author
wonder
committedJan 29, 2009
python support: fixed some problems with handling of unicode strings
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@10038 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 28bfeb5 commit 376bccc

File tree

2 files changed

+75
-25
lines changed

2 files changed

+75
-25
lines changed
 

‎src/python/qgspythonutilsimpl.cpp

Lines changed: 72 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,10 @@ void QgsPythonUtilsImpl::uninstallConsoleHooks()
169169

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

@@ -294,20 +297,15 @@ QString QgsPythonUtilsImpl::getTypeAsString( PyObject* obj )
294297
else
295298
{
296299
QgsDebugMsg( "got object" );
297-
PyObject* s = PyObject_Str( obj );
298-
QString str;
299-
if ( s && PyString_Check( s ) )
300-
str = QString( PyString_AsString( s ) );
301-
Py_XDECREF( s );
302-
return str;
300+
return PyObjectToQString( obj );
303301
}
304302
}
305303

306304
bool QgsPythonUtilsImpl::getError( QString& errorClassName, QString& errorText )
307305
{
308306
if ( !PyErr_Occurred() )
309307
return false;
310-
308+
311309
PyObject* obj_str;
312310
PyObject* err_type;
313311
PyObject* err_value;
@@ -322,9 +320,7 @@ bool QgsPythonUtilsImpl::getError( QString& errorClassName, QString& errorText )
322320
// get exception's text
323321
if ( err_value != NULL && err_value != Py_None )
324322
{
325-
obj_str = PyObject_Str( err_value ); // new reference
326-
errorText = PyString_AS_STRING( obj_str );
327-
Py_XDECREF( obj_str );
323+
errorText = PyObjectToQString( err_value );
328324
}
329325
else
330326
errorText.clear();
@@ -342,24 +338,77 @@ QString QgsPythonUtilsImpl::getResult()
342338
return getVariableFromMain( "__result" );
343339
}
344340

341+
QString QgsPythonUtilsImpl::PyObjectToQString( PyObject* obj )
342+
{
343+
QString result;
344+
345+
// is it None?
346+
if ( obj == Py_None )
347+
{
348+
return QString();
349+
}
350+
351+
// check whether the object is already a unicode string
352+
if ( PyUnicode_Check( obj ) )
353+
{
354+
PyObject* utf8 = PyUnicode_AsUTF8String( obj );
355+
if ( utf8 )
356+
result = QString::fromUtf8( PyString_AS_STRING( utf8 ) );
357+
else
358+
result = "(qgis error)";
359+
Py_XDECREF( utf8 );
360+
return result;
361+
}
362+
363+
// check whether the object is a classical (8-bit) string
364+
if ( PyString_Check( obj ) )
365+
{
366+
return QString::fromUtf8( PyString_AS_STRING( obj ) );
367+
}
368+
369+
// it's some other type of object:
370+
// convert object to unicode string (equivalent to calling unicode(obj) )
371+
372+
PyObject* obj_uni = PyObject_Unicode( obj ); // obj_uni is new reference
373+
if ( obj_uni )
374+
{
375+
// get utf-8 representation of unicode string (new reference)
376+
PyObject* obj_utf8 = PyUnicode_AsUTF8String(obj_uni);
377+
// convert from utf-8 to QString
378+
if ( obj_utf8 )
379+
result = QString::fromUtf8(PyString_AsString( obj_utf8 ));
380+
else
381+
result = "(qgis error)";
382+
Py_XDECREF( obj_utf8 );
383+
Py_XDECREF( obj_uni );
384+
return result;
385+
}
386+
387+
// if conversion to unicode failed, try to convert it to classic string, i.e. str(obj)
388+
PyObject* obj_str = PyObject_Str( obj ); // new reference
389+
if ( obj_str )
390+
{
391+
result = QString::fromUtf8( PyString_AS_STRING( obj_str ) );
392+
Py_XDECREF( obj_str );
393+
return result;
394+
}
395+
396+
// some problem with conversion to unicode string
397+
QgsDebugMsg("unable to convert PyObject to a QString!");
398+
return "(qgis error)";
399+
}
400+
345401
QString QgsPythonUtilsImpl::getVariableFromMain( QString name )
346402
{
347403
PyObject* obj;
348-
PyObject* obj_str;
349-
350404
QString output;
351405

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

355409
if ( obj != NULL && obj != Py_None )
356410
{
357-
obj_str = PyObject_Str( obj ); // obj_str is new reference
358-
if ( obj_str != NULL && obj_str != Py_None )
359-
{
360-
output = PyString_AsString( obj_str );
361-
}
362-
Py_XDECREF( obj_str );
411+
output = PyObjectToQString( obj );
363412
}
364413

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

371420
bool QgsPythonUtilsImpl::evalString( const QString& command, QString& result )
372421
{
373-
PyObject* res = PyRun_String( command.toLocal8Bit().data(), Py_eval_input, mMainDict, mMainDict );
422+
PyObject* res = PyRun_String( command.toUtf8().data(), Py_eval_input, mMainDict, mMainDict );
374423

375-
if ( res != NULL && PyString_Check( res ) )
424+
if ( res != NULL )
376425
{
377-
result = PyString_AsString( res );
378-
Py_XDECREF( res );
426+
result = PyObjectToQString( res );
379427
return true;
380428
}
381-
Py_XDECREF( res );
382429
return false;
383430
}
384431

@@ -426,7 +473,7 @@ QString QgsPythonUtilsImpl::getPluginMetadata( QString pluginName, QString funct
426473

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

431478
if ( PyErr_Occurred() )
432479
{

‎src/python/qgspythonutilsimpl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ class QgsPythonUtilsImpl : public QgsPythonUtils
116116

117117
QString getTraceback();
118118

119+
//! convert python object to QString. If the object isn't unicode/str, it will be converted
120+
QString PyObjectToQString( PyObject* obj );
121+
119122
//! reference to module __main__
120123
PyObject* mMainModule;
121124

0 commit comments

Comments
 (0)