[PyQt] A possible bug in PyQt when loading Boolean values via QSettings
Phil Thompson
phil at riverbankcomputing.com
Sat Jan 8 12:02:49 GMT 2011
On Mon, 27 Dec 2010 20:17:10 +0000, Baz Walter <bazwal at ftml.net> wrote:
> On 27/12/10 10:04, Phil Thompson wrote:
>> A typical backend will save values as a string without any metadata
>> describing the original type. In QVariant v1 the conversion back is
done
>> by
>> QVariant::toBool() which only checks for "true" and "false", so that is
>> the
>> behaviour to be replicated in QVariant v2.
>>
>> If this is a problem then I could add an optional keyword argument to
>> QSettings.value() that takes a Python type argument and will
>> automatically
>> return a value of that type or raise an exception...
>>
>> b = settings.value(key, type=bool)
>>
>> ...or any other suggestions?
>
> i expanded my previous test to include a few other types:
>
> from PyQt4.QtCore import QSettings, QPoint
>
> settings = QSettings('foo', 'foo')
> settings.clear()
> settings.beginGroup('section')
> settings.setValue('bool', False)
> print('bool = %s' % repr(settings.value('bool')))
> settings.setValue('int', 42)
> print('int = %s' % repr(settings.value('int')))
> settings.setValue('point', QPoint(10, 20))
> print('point = %s' % repr(settings.value('point')))
> settings.setValue('list', [1, 2, 3])
> print('list = %s' % repr(settings.value('list')))
> settings.endGroup()
>
> # re-sync with storage
> settings = QSettings('foo', 'foo')
> settings.beginGroup('section')
> print('bool = %s' % repr(settings.value('bool')))
> print('int = %s' % repr(settings.value('int')))
> print('point = %s' % repr(settings.value('point')))
> print('list = %s' % repr(settings.value('list')))
> settings.endGroup()
>
> output for linux, using python 3.1.3, qt 4.7.1, sip 4.11.2, pyqt 4.8.1:
>
> $ python3 settings.py
> bool = False
> int = 42
> point = PyQt4.QtCore.QPoint(10, 20)
> list = [1, 2, 3]
> bool = 'false'
> int = '42'
> point = PyQt4.QtCore.QPoint(10, 20)
> list = ['1', '2', '3']
>
> output for win xp, using python 3.1.3, qt 4.7.1, sip 4.12, pyqt 4.8.2:
>
>>c:\python31\python.exe settings.py
> bool = 'false'
> int = 42
> point = PyQt4.QtCore.QPoint(10, 20)
> list = ['1', '2', '3']
> bool = 'false'
> int = 42
> point = PyQt4.QtCore.QPoint(10, 20)
> list = ['1', '2', '3']
>
> so it looks like portability *has* been compromised. there are
> differences between linux and windows both before and after a re-sync.
>
> also, i think xavion may be right to suggest there is at least one other
> bug here. on linux, there is inconsistency between some values before
> and after a re-sync that is not present on windows.
>
> (of course, it goes without saying that the easy way to avoid all these
> complications is to use the QVariant v1 api).
QSettings.value() now takes an optional "type" argument which is either a
Python type object or a string specifying a C++ type. The value returned
will be of that type, or an exception will be raised.
If the value is a container then the type is applied to the contents of
the container.
Phil
More information about the PyQt
mailing list