[PyKDE] QString to Python string conversion trouble

Andreas Gerstlauer gerstl at ics.uci.edu
Thu Oct 25 02:22:20 BST 2001


phil at river-bank.demon.co.uk said:
> >> It's not acceptable to get an exception when applying str() to a QString 
> > Why not? Even in Python itself it is handled like that: 
> Because unicode() is the only way PyQt has of allowing the programmer to 
> convert from QString to a Python Unicode object. 

Yep, I agree, unicode() shouldn't deliver an exception. However, str() may, 
IMHO.

> My original implementation 
> meant that characters >128 raised an exception because it went via a string 
> object and the default ascii encoding - but see my later comments.
> 
The problem is that both unicode() and str() go through the __str__ method.
If __str__ returns a string object the results in both cases will always
depend on the chosen encoding - including possible exceptions. Even then,
using the default encoding is the most sensible approach IMHO - if the user
is dealing with unicode he/she has to set the default encoding such that it
handles everything correctly and doesn't raise exceptions. See also my other
mail about that and about why returning a unicode seems to be the only proper 
way to handle both unicode() and str().

> If the __str__ implementation in QString was changed to just return the Python 
> Unicode object without converting it again to a string object - would that 
> work? Can you test this - I can't get near a system again until Friday.
> 
Ok, I expaned a bit on my "Test" class example. See the enclosed script plus
output generated by it. Seems to work fine.

I tried to apply that to PyQt and I would love to have a patch but I couldn't
figure out how to do that. Changing the code in qstring.sip to return a unicode
is simple. But that code ends up as the tp_str slot function for the QString
type object. The QString shadow class (in qt.py) has the following code:
   def __str__(self):
      return str(self.sipThis)
So any str() or unicode() on an QString *instance* will go through that
additional str() call in the __str__ method - exception right there!
I can't figure out how to make that __str__ method call the tp_str slot and 
return the unicode result directly... Any ideas?

phil at river-bank.demon.co.uk said:
> Errm - a guess based on ignorance. You have to remember that Unicode
> is  related to "foreign" languages and that I am English - so I am
> genetically  incapable of understanding this properly ;) 
>
Oh well, that whole unicode stuff is not for me either. Foreign languages
for me is English and I guess that's not foreign enough ;-)
But you are the expert on sip, PyQt and Python API so I hope you can 
figure out how to pass the unicode all the way through...

Andreas

-------------- next part --------------
Test with no unicode chars:
unicode(): <type 'unicode'>
Test
Test
str(): <type 'string'>
Test
Test
Test with unicode chars:
unicode(): <type 'unicode'>
Test\u0400Test
str():
Traceback (most recent call last):
  File "test.py", line 22, in ?
    print "str():", type(str(t1))
UnicodeError: ASCII encoding error: ordinal not in range(128)
-------------- next part --------------
#!/usr/bin/env python

class QString:
    def __init__(self, string):
        self.string = string
        
    def __str__(self):
        # returns a unicode object!
        return unicode(self.string)
    
    
print "Test with no unicode chars:"    
t1 = QString(u"Test\nTest")
print "unicode():", type(unicode(t1))
print unicode(t1)
print "str():", type(str(t1))
print str(t1)

print "Test with unicode chars:"
t1 = QString(u"Test\u0400Test")
print "unicode():", type(unicode(t1))
print unicode(t1).encode('Unicode Escape')
print "str():", type(str(t1))
print str(t1)


More information about the PyQt mailing list