[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