@@ -169,7 +169,10 @@ void QgsPythonUtilsImpl::uninstallConsoleHooks()
169
169
170
170
bool QgsPythonUtilsImpl::runStringUnsafe ( const QString& command )
171
171
{
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 );
173
176
return ( PyErr_Occurred () == 0 );
174
177
}
175
178
@@ -294,20 +297,15 @@ QString QgsPythonUtilsImpl::getTypeAsString( PyObject* obj )
294
297
else
295
298
{
296
299
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 );
303
301
}
304
302
}
305
303
306
304
bool QgsPythonUtilsImpl::getError ( QString& errorClassName, QString& errorText )
307
305
{
308
306
if ( !PyErr_Occurred () )
309
307
return false ;
310
-
308
+
311
309
PyObject* obj_str;
312
310
PyObject* err_type;
313
311
PyObject* err_value;
@@ -322,9 +320,7 @@ bool QgsPythonUtilsImpl::getError( QString& errorClassName, QString& errorText )
322
320
// get exception's text
323
321
if ( err_value != NULL && err_value != Py_None )
324
322
{
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 );
328
324
}
329
325
else
330
326
errorText.clear ();
@@ -342,24 +338,77 @@ QString QgsPythonUtilsImpl::getResult()
342
338
return getVariableFromMain ( " __result" );
343
339
}
344
340
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
+
345
401
QString QgsPythonUtilsImpl::getVariableFromMain ( QString name )
346
402
{
347
403
PyObject* obj;
348
- PyObject* obj_str;
349
-
350
404
QString output;
351
405
352
406
// get the result
353
407
obj = PyDict_GetItemString ( mMainDict , name.toUtf8 () ); // obj is borrowed reference
354
408
355
409
if ( obj != NULL && obj != Py_None )
356
410
{
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 );
363
412
}
364
413
365
414
// erase result
@@ -370,15 +419,13 @@ QString QgsPythonUtilsImpl::getVariableFromMain( QString name )
370
419
371
420
bool QgsPythonUtilsImpl::evalString ( const QString& command, QString& result )
372
421
{
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 );
374
423
375
- if ( res != NULL && PyString_Check ( res ) )
424
+ if ( res != NULL )
376
425
{
377
- result = PyString_AsString ( res );
378
- Py_XDECREF ( res );
426
+ result = PyObjectToQString ( res );
379
427
return true ;
380
428
}
381
- Py_XDECREF ( res );
382
429
return false ;
383
430
}
384
431
@@ -426,7 +473,7 @@ QString QgsPythonUtilsImpl::getPluginMetadata( QString pluginName, QString funct
426
473
427
474
// temporary disable error hook - UI will handle this gracefully
428
475
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 );
430
477
431
478
if ( PyErr_Occurred () )
432
479
{
0 commit comments