Fix for SF 742911. We now clear the weakrefs *before* calling __del__

or emptying __dict__, just as we do for classic classes.
This commit is contained in:
Guido van Rossum 2003-05-29 14:29:23 +00:00
parent aabe0b3e34
commit 1987c6693b
1 changed files with 12 additions and 11 deletions

View File

@ -638,13 +638,6 @@ subtype_dealloc(PyObject *self)
--_PyTrash_delete_nesting; --_PyTrash_delete_nesting;
_PyObject_GC_TRACK(self); /* We'll untrack for real later */ _PyObject_GC_TRACK(self); /* We'll untrack for real later */
/* Maybe call finalizer; exit early if resurrected */
if (type->tp_del) {
type->tp_del(self);
if (self->ob_refcnt > 0)
goto endlabel;
}
/* Find the nearest base with a different tp_dealloc /* Find the nearest base with a different tp_dealloc
and clear slots while we're at it */ and clear slots while we're at it */
base = type; base = type;
@ -655,6 +648,18 @@ subtype_dealloc(PyObject *self)
assert(base); assert(base);
} }
/* If we added a weaklist, we clear it. Do this *before* calling
the finalizer (__del__) or clearing the instance dict. */
if (type->tp_weaklistoffset && !base->tp_weaklistoffset)
PyObject_ClearWeakRefs(self);
/* Maybe call finalizer; exit early if resurrected */
if (type->tp_del) {
type->tp_del(self);
if (self->ob_refcnt > 0)
goto endlabel;
}
/* If we added a dict, DECREF it */ /* If we added a dict, DECREF it */
if (type->tp_dictoffset && !base->tp_dictoffset) { if (type->tp_dictoffset && !base->tp_dictoffset) {
PyObject **dictptr = _PyObject_GetDictPtr(self); PyObject **dictptr = _PyObject_GetDictPtr(self);
@ -667,10 +672,6 @@ subtype_dealloc(PyObject *self)
} }
} }
/* If we added weaklist, we clear it */
if (type->tp_weaklistoffset && !base->tp_weaklistoffset)
PyObject_ClearWeakRefs(self);
/* Finalize GC if the base doesn't do GC and we do */ /* Finalize GC if the base doesn't do GC and we do */
if (!PyType_IS_GC(base)) if (!PyType_IS_GC(base))
_PyObject_GC_UNTRACK(self); _PyObject_GC_UNTRACK(self);