@@ -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