diff --git a/wxPython/CHANGES.txt b/wxPython/CHANGES.txt index 707b28b44f..ea105db1e8 100644 --- a/wxPython/CHANGES.txt +++ b/wxPython/CHANGES.txt @@ -24,8 +24,8 @@ people can do imports without "import *" and can use names like wx.Frame instead of wx.wxFrame. This is phase 1 of a full transition to the new namespace. -Updated Scintilla to 1.51. I also changed it to use wxListCtrl -instead of wxLIstBox for the AutoComplete window, added the ability to +Updated Scintilla to 1.52. I also changed it to use wxListCtrl +instead of wxListBox for the AutoComplete window, added the ability to use custom bitmaps in the margin and in the AutoComplete windows, and worked out how to do proper clipping of child windows on wxGTK. @@ -49,6 +49,8 @@ passed back and forth on wxPython-users a while back. Added masked edit controls (wxPython.lib.maskededit) by Jeff Childers and Will Sadkin. Updated wxTimeCtrl to use MaskedEdit. +When the __class__ of a dead object is replaced with _wxPyDeadObject +the __del__ of the original class is now called first. diff --git a/wxPython/src/helpers.cpp b/wxPython/src/helpers.cpp index 8425ec2682..13186d98fe 100644 --- a/wxPython/src/helpers.cpp +++ b/wxPython/src/helpers.cpp @@ -591,21 +591,37 @@ void wxPyOORClientData_dtor(wxPyOORClientData* self) { Py_INCREF(deadObjectClass); } - // TODO: If wxPyDOingCleanup, should we skip the code below? - // Clear the instance's dictionary, put the name of the old class into the - // instance, and then reset the class to be the dead class. - if (self->m_obj->ob_refcnt > 1) { // but only if there is more than one reference + // Only if there is more than one reference to the object + if ( !wxPyDoingCleanup && self->m_obj->ob_refcnt > 1 ) { wxASSERT_MSG(PyInstance_Check(self->m_obj), wxT("m_obj not an instance!?!?!")); + + // Call __del__, if there is one. + PyObject* func = PyObject_GetAttrString(self->m_obj, "__del__"); + if (func) { + PyObject* rv = PyObject_CallMethod(self->m_obj, "__del__", NULL); + Py_XDECREF(rv); + Py_DECREF(func); + } + if (PyErr_Occurred()) + PyErr_Clear(); // just ignore it for now + + // Clear the instance's dictionary PyInstanceObject* inst = (PyInstanceObject*)self->m_obj; PyDict_Clear(inst->in_dict); + + // put the name of the old class into the instance, and then reset the + // class to be the dead class. PyDict_SetItemString(inst->in_dict, "_name", inst->in_class->cl_name); inst->in_class = (PyClassObject*)deadObjectClass; Py_INCREF(deadObjectClass); } + + // m_obj is DECREF's in the base class dtor... wxPyEndBlockThreads(); } + //--------------------------------------------------------------------------- // Stuff used by OOR to find the right wxPython class type to return and to // build it.