Re: [PyQt] Again, problems with garbage collection
Hi List, Hi Phil, I just upgraded to PyQt4 4.7.2 (with Python 2.6.4 on Windows XP) and the following little script crashes with unterlying C/C++ object has been deleted I guess that's a bug. Why? It works as I would expect. Oops. I didn't realize that that's a excpected behaviour. I was under the impression that Qt shouldn't own objects and delete them, so that this runtime error was always indicator of a bug (or an indicator that someone forgot to call the parent's __init__, maybe the error message should actually read underlying C/C++ object has been deleted or not yet created, anyhow, that's not the current problem) Unfortunately, this leads to the somewhat annoying behaviour that signals are still sent to C++-dead but python-alive objects. That's especially annoying when the python object ought to be dead already, just had not been collected yet, as illustrated in the following example. Note how gc.collect makes a difference, a situation that better should not happen as garbage collection happens at random intervals... Greetings Martin And here the example: -- snip - from PyQt4.QtCore import QObject, SIGNAL, QCoreApplication import gc # following two lines not important from sys import argv app = QCoreApplication(argv) class A(QObject): def __init__(self, p=None): QObject.__init__(self, p) def g(self): self.emit(SIGNAL(sig)) def k(self): self.emit(SIGNAL(kill)) def f(self): try: print self.children() # only to test if C++ object is still alive except RuntimeError: print hey, caught runtime error! def kill(self): self.setParent(None) a = A() b = A(a) c = A(b) b.connect(a, SIGNAL(sig), c.f) b.connect(a, SIGNAL(kill), b.kill) a.g() # deliver signal to c, all fine c.v = c # create cycle to prevent immediate collection b = None c = None a.k() # now c ceases existence in the C++ world print here a.g() # signal is still delivered print now collect gc.collect() a.g() # signal no more delivered, python object has died snip - ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Again, problems with garbage collection
Hi List, I just upgraded to PyQt4 4.7.2 (with Python 2.6.4 on Windows XP) and the following little script crashes with unterlying C/C++ object has been deleted I guess that's a bug. --- snip -- from PyQt4.QtCore import QObject, SIGNAL, QCoreApplication # following two lines not important from sys import argv app = QCoreApplication(argv) class A(QObject): def __init__(self, p=None): QObject.__init__(self, p) def g(self): self.emit(SIGNAL(sig)) def f(self): print hello def kill(self): self.setParent(None) b = A() a = A(b) b.connect(a, SIGNAL(sig), b.f) a.g() b.kill() b = None a.g() --- snip - greetings Martin ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Again, problems with garbage collection
On Thu, 18 Mar 2010 15:48:25 +0100, Martin Teichmann lkb.teichm...@gmail.com wrote: Hi List, I just upgraded to PyQt4 4.7.2 (with Python 2.6.4 on Windows XP) and the following little script crashes with unterlying C/C++ object has been deleted I guess that's a bug. Why? It works as I would expect. --- snip -- from PyQt4.QtCore import QObject, SIGNAL, QCoreApplication # following two lines not important from sys import argv app = QCoreApplication(argv) class A(QObject): def __init__(self, p=None): QObject.__init__(self, p) def g(self): self.emit(SIGNAL(sig)) def f(self): print hello def kill(self): self.setParent(None) b = A() a = A(b) So a's parent is b. b.connect(a, SIGNAL(sig), b.f) a.g() b.kill() This has no effect as b doesn't have a parent. b = None This garbage collects the original b. As it didn't have a parent it also destroys the C++ instance. Because b's C++ instance owns a's it also destroys a's C++ instance. Because a is still bound to it, the Python object isn't garbage collected. a.g() self.emit needs a's C++ instance which has been destroyed - so it raises the exception. --- snip - Phil ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt