[PyQt] PyQt 5.7, QSqlQueryModel.data() sub-classed override bug?

J Barchan jnbarchan at gmail.com
Tue May 8 20:22:12 BST 2018


​

On 8 May 2018 at 18:14, Phil Thompson <phil at riverbankcomputing.com> wrote:

> On 8 May 2018, at 9:04 am, J Barchan <jnbarchan at gmail.com> wrote:
> >
> > ​Now I'm finding that, with the fix discussed, while my overridden
> function definition correctly handles database NULLs, it "goes wrong" (as
> in, different behaviour from before) in certain other cases, returning a
> QVariant where it did not do so before (it returned the converted, native
> Python type).​
> >
> > 1. So long as I do not override QSqlQueryModel.data() at all, there is
> absolutely no problem --- both database NULL and auto-conversion of
> non-NULL to Python native type work fine, and are distinct.  This is the
> situation I need.
> >
> > 2. I need to override QSqlQueryModel.data() for my own purposes.  If I
> write just:
> > def data(self, index: QtCore.QModelIndex, role=QtCore.Qt.DisplayRole) ->
> typing.Any:
> >     value = super().data(index, role)
> >     return value
> > Some data conversion happens, such that I no longer get NULL back where
> the value is NULL --- instead it is converted to '' if string or 0 if int.
> This was my original problem and is not acceptable.
> >
> > 3. Following our discussion, I change that to:
> > def data(self, index: QtCore.QModelIndex, role=QtCore.Qt.DisplayRole) ->
> typing.Any:
> >     was_enabled = sip.enableautoconversion(QtCore.QVariant, False)
> >     value = super().data(index, role)
> >     sip.enableautoconversion(QtCore.QVariant, was_enabled)
> >     return value
> > Now I correctly get whatever for database NULL, which works.  However,
> some other path of code, on some quite different non-NULL value, gets back
> a QVariant where it used to get a string.  I don't know what that path of
> code is, but I don't think I should care.
> >
> > So, what I need is: code which allows me to override
> ​​
> QSqlQueryModel.data() but returns the original data() value unchanged,
> just like it used when I did not put any override in (case #1).  It must do
> whatever to correctly deal with NULL & non-NULL, just like the
> non-overridden QSqlQueryModel.data() does.
> >
> > (In PyQt 5.7) What exact code can I put into the override to achieve
> just that, please?  Surely that can be done, no?
>
> You can't have it both ways. Either you let PyQt automatically convert
> to/from QVariant (and you lose the detection of nulls) or you do it
> yourself (converting to Python using the value() method).
>
> By the way, I've just noticed a bug in the docs which says (incorrectly)
> that null QVariants are converted to None and vice versa.
>
> Phil


​Hi Phil,

Thanks for your reply.

I think one of us *must* be getting something wrong here.  I wonder if
you're still expecting me to understand something which is obvious to you
but not to me.

You can't have it both ways. Either you let PyQt automatically convert
> to/from QVariant (and you lose the detection of nulls) or you do it
> yourself (converting to Python using the value() method).


I'm not asking to have anything both ways.​  I'm just asking how to write
code so that the overridden method behaves *absolutely identically* to the
base method it's overriding.  Surely that must be possible?

I remind you: when I have no override for ​QSqlQueryModel.data() *everything
behaves perfectly*.  I am saying: there is no problem, NULLs are handled as
such and non-NULLs are correctly converted to their Python equivalent.  I
do not know how NULLs work (what they are returned as), but everything just
works.

As soon as I write an override which just returns the base method, it goes
wrong on NULL.  If I put it the sip.autoconversion(False), it works on NULL
but now returns a QVariant where it used to return a Python native type, I
think.

All I want to know is: how can I write an override of  ​
QSqlQueryModel.data() in Python/PyQt like:

def data(self, index: QtCore.QModelIndex, role=QtCore.Qt.DisplayRole) ->
typing.Any:
     value = super().data(index, role)
     return value

such that it returns *just exactly the same as* QSqlQueryModel.data() would
have done, please, please, please?

-- 
Kindest,
Jonathan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20180508/db818e7e/attachment.html>


More information about the PyQt mailing list