[PyQt] Conversion to wrong SubClass

Matthias Kuhn matthias at opengis.ch
Fri Jan 18 11:22:43 GMT 2019


Hi

In QGIS we are facing an issue, where in some cases a wrong subclass
mapping is used in the python bindings.

The code looks like this:

 * There is a parent class QgsAbstractGeometry

 * There are various child classes, among them QgsPoint and QgsMultiPolygon


After heavy operation it can happen, that the python bindings indicate,
that an object is of type QgsPoint, whereas the underlying object is
actually a QgsMultiPolygon (verified that when an overwritten method is
called on the object, the one from QgsMultiPolygon is executed).

It looks like objects which are created subsequently have exactly the
same memory address (see below) and I suspect sip caches type
information with memory addresses somewhere (based on "When SIP needs to
wrap a C++ class instance it first checks to make sure it hasn’t already
done so. " /
http://pyqt.sourceforge.net/Docs/sip4/directives.html?highlight=subclass#directive-%ConvertToSubClassCode)

Does sip invalidate this cache information somehow (when the python
wrapper is garbage collected or something else)? Is it possible to
proactively trigger cache invalidation from a destructor? Are there
other ideas what could go wrong and how to deal with that?


** Insights from debugging:

Unconditional debug print statements have been added to

 * QgsAbstractGeometry::QgsAbstractGeometry() (Constructor)
 * QgsAbstractGeometry::~QgsAbstractGeometry() (Destructor)
 * %SipConvertToSubClassCode

grepping the log for the memory address of an affected geometry reveals,
that the constructor is called twice with the object on the same
address, but the SipConvertToSubClassCode is only called once

----------

Constructor: 0x8b1cbd0
SipConvertToSubClassCode - Type QgsPoint: 0x8b1cbd0
Destructor: 0x8b1cbd0
Constructor: 0x8b1cbd0
Destructor: 0x8b1cbd0

---------

Any hints would be much appreciated

Best regards

Matthias



More information about the PyQt mailing list