Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1987c66

Browse files
committed
Fix for SF 742911. We now clear the weakrefs *before* calling __del__
or emptying __dict__, just as we do for classic classes.
1 parent aabe0b3 commit 1987c66

1 file changed

Lines changed: 12 additions & 11 deletions

File tree

Objects/typeobject.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -638,13 +638,6 @@ subtype_dealloc(PyObject *self)
638638
--_PyTrash_delete_nesting;
639639
_PyObject_GC_TRACK(self); /* We'll untrack for real later */
640640

641-
/* Maybe call finalizer; exit early if resurrected */
642-
if (type->tp_del) {
643-
type->tp_del(self);
644-
if (self->ob_refcnt > 0)
645-
goto endlabel;
646-
}
647-
648641
/* Find the nearest base with a different tp_dealloc
649642
and clear slots while we're at it */
650643
base = type;
@@ -655,6 +648,18 @@ subtype_dealloc(PyObject *self)
655648
assert(base);
656649
}
657650

651+
/* If we added a weaklist, we clear it. Do this *before* calling
652+
the finalizer (__del__) or clearing the instance dict. */
653+
if (type->tp_weaklistoffset && !base->tp_weaklistoffset)
654+
PyObject_ClearWeakRefs(self);
655+
656+
/* Maybe call finalizer; exit early if resurrected */
657+
if (type->tp_del) {
658+
type->tp_del(self);
659+
if (self->ob_refcnt > 0)
660+
goto endlabel;
661+
}
662+
658663
/* If we added a dict, DECREF it */
659664
if (type->tp_dictoffset && !base->tp_dictoffset) {
660665
PyObject **dictptr = _PyObject_GetDictPtr(self);
@@ -667,10 +672,6 @@ subtype_dealloc(PyObject *self)
667672
}
668673
}
669674

670-
/* If we added weaklist, we clear it */
671-
if (type->tp_weaklistoffset && !base->tp_weaklistoffset)
672-
PyObject_ClearWeakRefs(self);
673-
674675
/* Finalize GC if the base doesn't do GC and we do */
675676
if (!PyType_IS_GC(base))
676677
_PyObject_GC_UNTRACK(self);

0 commit comments

Comments
 (0)