[PyKDE] Re: PyKDE issues

Phil Thompson phil at river-bank.demon.co.uk
Sun Oct 3 12:00:43 BST 1999

Arun Sharma wrote:
> Phil,
> First of all, thanks for the great work on PyQT/KDE. Either I've gotten
> faster hardware or you've fixed all performance problems, that's making
> me much happier.
> However, I found that there are some problems with reference counting.
> Specifically, if I do,
> # These may be syntactically incorrect, but convey the point
> w1 = QWidget()
> w2 = QWidget()
> w1.setChild(w2)
> self.w = w1
> self still has a reference to w1, so won't be garbage collected. However,
> w2 will be, as soon as I exit the function. This is wrong because w1 has
> a reference to w2.
> A specific example of the above scenerio is in KTreeListItem::appendChild.
> I don't see a Py_INCREF on the child there.
> Just wanted to make sure that you're aware of the problem and are planning
> to fix this in the next version :-)
> Thanks once again!
>         -Arun

By default SIP assumes that if an object was created in Python then it
will be destroyed from Python. There are some cases where this isn't
valid. QTab.addTab() takes a pointer to another QTab and will eventually
call the destructor of that QTab. SIP has to know this so that the
destructor isn't also called from Python - usually resulting in a core
dump. SIP is told by the "Transfer" flag in the specification of
QTab.addTab() to transfer responsibility for calling the destructor from
Python to C++.

To take your made up example, if w1 was going to call the destructor of
w2 later on because of the setChild() call, then the specification would
include the "Transfer" flag and everything would be Ok. The Python
object w2 would disappear - but the underlying C++ object would still be
there. If w1 was not going to call the w2 destructor then you must keep
w2 alive in Python (e.g. self.w2 = QWidget()) - otherwise it is a bug in
your program. This is one of the few cases where you might have to do
something slightly different in Python than you would in C++.

Applying this to the specific example of KTreeListItem, by calling
appendChild() does KTreeListItem take responsibility for calling the
destructor of the child? Looking at the KDE 1.1.2 implementation, the
destructor does nothing. This looks completely broken to me - it should
destroy its children before destroying itself. As it stands there is a
memory leak.

I could add "Transfer" flags (its not just appendChild()) but it's
difficult to pick the right places when the underlying widget is wrong.

Is this causing you a real problem - or did you just happen to notice?


More information about the PyQt mailing list