[QGIS-Developer] Is it just me, or is sip totally broken?

Nyall Dawson nyall.dawson at gmail.com
Wed Jan 2 23:19:29 PST 2019

Hi list,

I'm at my wits end here, fighting with a sip issue I can't solve. And
honestly, I'm starting to think maybe there's something completely
broken in sip. (Or at least, in the version 4.19.7 provided by my

Here's what I'm currently hitting:

The validity check registry added this week has a method "addCheck",
which transfers ownership of the check to c++:

void addCheck( QgsAbstractValidityCheck *check SIP_TRANSFER );

But if I make a Python subclass of QgsAbstractValidityCheck, and add
it to the registry, it's immediately garbage collected by Python!

My test code looks like this:

class LayoutMapCrsCheck(QgsAbstractValidityCheck):

    def __del__(self):

    def id(self):
        return 'map_crs_check'

    def checkType(self):
        return QgsAbstractValidityCheck.TypeLayoutCheck

    def prepareCheck(self,context, feedback):
        return True

    def runCheck(self,context, feedback):
        return []

def add_check():


So I create a Python subclass of the interface, and then add it to the
registry. And boom - it's immediately deleted.

If I make a global copy of the check, and then add to the registry,
everything works -- the check isn't garbage collected.

check_instance = LayoutMapCrsCheck()

But this leads me to believe that sip is broken somewhere, and is
ignoring the /Transfer/ annotation.

Indeed - I've also seen this in other classes. Specifically
QgsTaskManager.addTask() -- Python tasks must be stored globally in
order to avoid them being immediately deleted too.

Can anyone else reproduce using my above code? Does anyone have any
ideas what's happening here?


More information about the QGIS-Developer mailing list