[PyQt] Garbage collection, signals to partial functions

Martin Teichmann martin.teichmann at mbi-berlin.de
Tue Nov 17 17:13:39 GMT 2009


Hi again, list,

as per Phil, I changed the code to be executed
in an event loop. The problem persists.

Greetings

Martin

new code follows:
-------------------- snip -------------------------------------
import gc
from PyQt4 import QtCore
from weakref import ref
from functools import partial
import sys

class A(QtCore.QObject):
    def init(self):
        try:
            self.test()
        finally:
            QtCore.QCoreApplication.exit(0)

    def test(self):
        b = A()
        a = A(self)

        # connect a signal to a partial function
        f = b.f
        p = partial(f, 3)
        a.connect(a, QtCore.SIGNAL("a"), p)
        wf = ref(f)
        wp = ref(p)
        self.wp = wp
        f = None
        p = None

        # kill all references
        wa = ref(a)
        wb = ref(b)
        a = None
        b = None

        # but they're still here!
        # (following line prints four objects, but should print four Nones)
        print wa(), wb(), wp(), wf()

        # OK, let's garbage collect
        gc.collect()

        # still everything there (again, not a single None)
        print wa(), wb(), wp(), wf()

        # that's the bug: still one reference, but no referrer
        # (the line prints 1 [], getrefcount always gives 1 to high)
        if wp() is not None:
            print sys.getrefcount(wp()) - 1, gc.get_referrers(wp())

        # assert that everything is gone
        assert wa() is None
        assert wb() is None
        assert wp() is None
        assert wf() is None

    def f(self, x):
        print x

app = QtCore.QCoreApplication(sys.argv)
c = A()
QtCore.QTimer.singleShot(0, c.init)
app.exec_()

gc.collect()
if c.wp() is not None:
    print sys.getrefcount(c.wp()) - 1, gc.get_referrers(c.wp())
assert c.wp() is None


More information about the PyQt mailing list