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

J Barchan jnbarchan at gmail.com
Wed May 9 15:36:18 BST 2018


On 9 May 2018 at 14:53, Ricardo Araoz <ricaraoz at gmail.com> wrote:

> On 09/05/18 05:57, Phil Thompson wrote:
>>>> 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
>>>  From your Python data() you call the C++ data(). This returns a
>> QVariant to PyQt. With auto-conversion enabled this is converted to a
>> Python value before being passed back to your Python data(). This loses the
>> null information. Your Python data() then returns this value. The C++ code
>> that invoked it requires a QVariant so (with auto-conversion enabled) PyQt
>> first converts it back to a QVariant.
>> The only way to keep the null information is to disable auto-conversion.
>> This means that the object that your Python data() got back from calling
>> the C++ data() is the QVariant (with intact null information). You then
>> return this and it then makes its way back to the invoking C++.
>> Phil
>> _______________________________________________
>> PyQt mailing list    PyQt at riverbankcomputing.com
>> https://www.riverbankcomputing.com/mailman/listinfo/pyqt
> Sorry to chime in but I also don't completely get it.
> AFAIK the call to super() should return a reference to the parent class,
> that is pyqt's QSqlQueryModel, not the C++ class. And in case there is a
> reason for that (which I'm sure there is), is there a way to call the pyqt
> parent class' data() method and not the c++ method?
> Isn't there a way to call the pyqt method so that IT may call the c++
> method and all would be nice? (I don't know, would "super(QSqlQueryModel,
> self).data()" do the trick?)
> In case there isn't, would there be a way to call the conversion method
> pyqt's data() class uses and feed it the c++ data() results so that they
> are properly converted in the same way it's done originally?
> Because I understand Jonathan's concern that he wants a way to replicate
> what would be going on if he hadn't subclassed the method.
> Ricardo
> _______________________________________________
> PyQt mailing list    PyQt at riverbankcomputing.com
> https://www.riverbankcomputing.com/mailman/listinfo/pyqt

​Thanks for your moral support, Ricardo!  We shall see what Phil has to
say, as only he can answer this.

For my own part, ​having finally understood what was necessary, with great
regret I am abandoning my whole PyQt sub-classing of this method and just
having to manage without.  The outcome was that the *caller* code has to be
changed to either execute .value() on every result (iff I do the
sub-classing, which has to suppress the auto-conversion, and returns a
QVariant), or not to do .value() (iff, say, I decide to get rid of my
override at some point, and it returns native type).  The two are
incompatible, and technically it is not possible to write calling code
which works regardless of whether there is sub-classing going on.  I can
see it's not PyQt/Phil's "fault", but that is very strange behaviour to
accept in overriding a method, it would be expected to behave identically.
I do not wish to carry that burden in my code, and/or have to change
hundreds of callers in existing code.

I'll keep an eye out in case Phil has something to say about your
suggestions, as you guys understand much better than I.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20180509/8f2c850c/attachment.html>

More information about the PyQt mailing list