[PyQt] Proposal for QPyNullVariant

Phil Thompson phil at riverbankcomputing.com
Tue Jan 4 13:08:11 GMT 2011


The problem...

v2 of the QVariant API (the default for Python v3) eliminates QVariant as
a Python type.  Python objects are converted to and from C++ QVariants
automatically as and when required.  An invalid C++ QVariant is converted
to and from None.  The problem is that there is currently no way to
represent a null C++ QVariant as a Python object.  This is particularly an
issue when using the Qt SQL classes.

The proposed solution...

A new Python type, QPyNullVariant, will be implemented (as a mapped type)
which will automatically be converted to and from a null C++ QVariant.

Its __init__ method will take a single argument that is either a Python
type object or a string describing a C++ type.

It will have type(), typeName() and userType() methods that will delegate
to the QVariant's method of the same name.

It will have a isNull() method that always returns True.

When converting a C++ QVariant to a Python object a null QVariant will be
converted to a QPyNullVariant unless the type of the data in the QVariant
has an isNull() method.  The exception to this rule is a null QString
which, even though it has an isNull() method, will be converted to a
QPyNullVariant. (The reason for the exception is because - for very good
reasons - PyQt converts a null QString to an empty unicode/str
object.)

This conversion rule means that existing code that populates models will
continue to work.  For example, when a null QDate is added to a model, it
will still be read as a null QDate.  It also means that the object
retrieved from an SQL model should always have an isNull() method that
returns the correct value.

The rule introduces an incompatibility for models that may be populated
from C++, typically SQL data.  For example a null value in an int column
of an SQL table will now be returned as a QPyNullVariant rather than an
integer with the value 0.  This compatibility is considered acceptable,
because the current implementation is arguably broken anyway, and will be
addressed by a "potential incompatibilities" section in the documentation.
(The alternative would be to introduce v3 of the QVariant API.)

Comments welcome...

Phil



More information about the PyQt mailing list