[C++-sig] Re: Pyste feature: class member deletion order solution

David Abrahams dave at boost-consulting.com
Mon Nov 10 01:19:02 CET 2003

"Niall Douglas" <s_sourceforge at nedprod.com> writes:

> Just encountered an interesting problem in my now fully working 
> python test program - python does not delete class instance data 
> members in the reverse order of which they were created. For example:
> class MainWindow(FXMainWindow):
>     def __init__(self, app, title):
>         FXMainWindow.__init__(self, app, title)
>         self._vframe=FXVerticalFrame(self, LAYOUT_FILL)
>         self._text=FXText(self._vframe, None, 0, LAYOUT_FILL)
>         self._text.setEditable(False)
>         self._text.setText("Hello World!")
>         self._okb=FXButton(self._vframe, "&Close", None, app, 
>         self.resize(320, 256)
> The problem is when python is deleting everything it goes to delete 
> MainWindow - according to the python spec, if an instance data member 
> starts with "_" then it gets "del" called upon it before all else 
> (section 3.3.1 reference manual). Unfortunately, in the case above it 
> deletes self._vframe before self._text.
> This is a problem because under C++ _text is a child of _vframe and 
> deleting _vframe causes auto-delete of _text - and so when python 
> comes to delete _text, the memory is vacant and nasty fatal exit 
> happens.
> I was thinking that the obvious solution is for representations of 
> C++ objects to be able to hold a boost::python::handle<> of their 
> parent, thus ensuring that the parent stays alive as long as its 
> children. 

Won't help.  You'll have a reference cycle.  that have __del__()
methods and are part of a reference cycle cause the entire reference
cycle to be uncollectable, which will prevent the C++ object from
being destroyed.

> For that, pyste would merely need to add a handle<> to the 
> class wrapper with something like:
> struct FX_FXText_Wrapper: FX::FXText
> {
>     handle<> parentHandle;
>     PyObject* self;
>     FX_FXText_Wrapper(PyObject* self_, FX::FXComposite* p0):
>         FX::FXText(p0), parentHandle(object(p0 ? *p0 : 0).ptr()), 
> self(self_)
>     { }
> The only thing is, I've not determined if object() matches the 
> FXComposite pointer to what it really is, a FXVerticalFrame.
> Thus Q: Does boost::python::object(type &) search a list of pointers 
> to all known instantiated things and thus correctly increment the 
> reference of the right thing? Or does it depend on type, which being 
> that of a base class of FXVerticalFrame means it might get confused?
> Bruno, how easy is this to implement in pyste?

Do not try to solve this problem in Boost.Python or in Pyste.  It's a Python
issue, pure and simple.  

Dave Abrahams
Boost Consulting

More information about the Cplusplus-sig mailing list