[PyQt] Re: SIP bug with object lifetime

Phil Thompson phil at riverbankcomputing.co.uk
Mon May 14 08:33:11 BST 2007


On Monday 14 May 2007 12:16 am, Giovanni Bajo wrote:
> On 13/05/2007 12.41, Phil Thompson wrote:
> >> Hi Phil,
> >>
> >> I've got another bug with object lifetimes:
> >>
> >> =========================================
> >> from qt import *
> >> import weakref
> >>
> >> app = QApplication([])
> >>
> >> ql = QListView(None)
> >> viewport = ql.viewport()
> >>
> >> o = QObject(viewport)
> >> o.xxx = viewport  # bug-trigger!
> >>
> >> destroyed = []
> >> def cb(wr):
> >>      destroyed.append(1)
> >> wr = weakref.ref(o, cb)
> >>
> >> del o
> >> del viewport
> >> assert not destroyed, "object destroyed too early #1!"
> >>
> >> import gc
> >> gc.collect()
> >> assert not destroyed, "object destroyed too early #2!"
> >>
> >> del ql
> >> import gc
> >> gc.collect()
> >> assert destroyed, "object never destroyed!"
> >> =========================================
> >> Traceback (most recent call last):
> >>    File "pyqtbug19.py", line 25, in ?
> >>      assert not destroyed, "object destroyed too early #2!"
> >> AssertionError: object destroyed too early #2!
> >>
> >>
> >> This happens with latest PyQt and SIP official releases (3.17.1 and
> >> 4.6). The line that seems to trigger the bug is the one marked with a
> >> comment.
> >
> > This behaves as I would expect - ie. it's a missing feature rather than a
> > bug.
> >
> > Although ql is the parent of viewport, Python doesn't know that and there
> > is no hidden extra reference to viewport to keep it alive when collect()
> > is run.
>
> But the problem here is that "o" is collected. o is a QObject whose
> lifetime should be transferred to C++ (given that it has a non-NULL parent,
> right?).

But that parent is owned by Python. When viewpoint (Python) goes, viewpoint 
(C++) goes, which takes o (C++), which takes o (Python).

> And why is this behaviour triggered *only* when I add the "xxx" attribute
> to o? If I don't do that, everything looks right.

That confuses me a little bit too. It may be a case of timing - objects are 
not guaranteed to be garbage collected immediately their reference count 
reaches 0.

Phil


More information about the PyQt mailing list