[QGIS Commit] r10038 - trunk/qgis/src/python

svn_qgis at osgeo.org svn_qgis at osgeo.org
Wed Jan 28 19:31:27 EST 2009


Author: wonder
Date: 2009-01-28 19:31:27 -0500 (Wed, 28 Jan 2009)
New Revision: 10038

Modified:
   trunk/qgis/src/python/qgspythonutilsimpl.cpp
   trunk/qgis/src/python/qgspythonutilsimpl.h
Log:
python support: fixed some problems with handling of unicode strings


Modified: trunk/qgis/src/python/qgspythonutilsimpl.cpp
===================================================================
--- trunk/qgis/src/python/qgspythonutilsimpl.cpp	2009-01-28 19:39:28 UTC (rev 10037)
+++ trunk/qgis/src/python/qgspythonutilsimpl.cpp	2009-01-29 00:31:27 UTC (rev 10038)
@@ -169,7 +169,10 @@
 
 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 );
 }
 
@@ -294,12 +297,7 @@
   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 );
   }
 }
 
@@ -307,7 +305,7 @@
 {
   if ( !PyErr_Occurred() )
     return false;
-
+  
   PyObject* obj_str;
   PyObject* err_type;
   PyObject* err_value;
@@ -322,9 +320,7 @@
   // 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();
@@ -342,11 +338,69 @@
   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
@@ -354,12 +408,7 @@
 
   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
@@ -370,15 +419,13 @@
 
 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;
 }
 
@@ -426,7 +473,7 @@
 
   // 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() )
   {

Modified: trunk/qgis/src/python/qgspythonutilsimpl.h
===================================================================
--- trunk/qgis/src/python/qgspythonutilsimpl.h	2009-01-28 19:39:28 UTC (rev 10037)
+++ trunk/qgis/src/python/qgspythonutilsimpl.h	2009-01-29 00:31:27 UTC (rev 10038)
@@ -116,6 +116,9 @@
 
     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;
 



More information about the QGIS-commit mailing list