File tree Expand file tree Collapse file tree
Misc/NEWS.d/next/Core_and_Builtins Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -742,6 +742,8 @@ _PyObject_ResurrectEnd(PyObject *op)
742742 if (_Py_IsOwnedByCurrentThread (op ) && local == 1 && shared == 0 ) {
743743 // Fast-path: object has a single refcount and is owned by this thread
744744 _Py_atomic_store_uint32_relaxed (& op -> ob_ref_local , 0 );
745+ _Py_atomic_store_uintptr_relaxed (& op -> ob_tid , _Py_UNOWNED_TID );
746+ _Py_atomic_store_ssize_relaxed (& op -> ob_ref_shared , _Py_REF_MERGED );
745747# ifdef Py_TRACE_REFS
746748 _Py_ForgetReference (op );
747749# endif
Original file line number Diff line number Diff line change 11import gc
2+ import io
23import sys
34import doctest
45import unittest
@@ -1012,6 +1013,29 @@ def cb(wparent):
10121013 del root
10131014 gc .collect ()
10141015
1016+ def test_ref_to_object_dying_after_finalizer (self ):
1017+ cleared = []
1018+ class Attr :
1019+ def __del__ (self ):
1020+ cleared .append (self .wr () is None )
1021+
1022+ class SetWithDel (set ):
1023+ __slots__ = ('a' ,)
1024+ def __del__ (self ):
1025+ pass
1026+
1027+ class Raw (io .RawIOBase ):
1028+ __slots__ = ('a' ,)
1029+
1030+ for cls in (SetWithDel , Raw ):
1031+ with self .subTest (cls = cls .__name__ ):
1032+ cleared .clear ()
1033+ o = cls ()
1034+ o .a = Attr ()
1035+ o .a .wr = weakref .ref (o )
1036+ del o
1037+ self .assertEqual (cleared , [True ])
1038+
10151039 def test_callback_attribute (self ):
10161040 x = Object (1 )
10171041 callback = lambda ref : None
Original file line number Diff line number Diff line change 1+ Fix a crash in the :term: `free-threaded build ` where a weak reference could
2+ revive an object whose finalizer had already run during deallocation, causing
3+ it to be deallocated twice.
You can’t perform that action at this time.
0 commit comments