[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