[PyQt] Garbage collection, signals to partial functions

Martin Teichmann martin.teichmann at mbi-berlin.de
Tue Nov 17 16:31:29 GMT 2009

Hi List,

already recently, I reported a problem with
partial functions as slots not being correctly
garbage collected. As Phil noted, this was
fixed in recent snapshots. But since my
code still wouldn't run properly, I investigated
a bit more and wrote the following new test case,
where still the objects are not garbage collected,
although they should be.

This time I tested with latest snapshot
(4.6.2-snapshot-20091115 and 4.9.2-snapshot-20091115)



Here we go:

--------------------- snip --------------------------
import gc
from PyQt4 import QtCore
from weakref import ref
from functools import partial
import sys

class A(QtCore.QObject):
    def f(self, x):
        print x

# make 2 objects of A
b = A()
a = A(b)
# last line is the important difference to
# previously reported problems. b is now parent of a.

# 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)
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

# 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

More information about the PyQt mailing list