[3.15] gh-123619: Fix PyUnstable_Object_EnableDeferredRefcount() (GH-151260) (#151326)

gh-123619: Fix PyUnstable_Object_EnableDeferredRefcount() (GH-151260)

Return 0 if the object is not tracked by the GC.
(cherry picked from commit 72e7eddce6)

Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
Miss Islington (bot) 2026-06-11 13:21:26 +02:00 committed by GitHub
parent 491768da4c
commit dc5ebe3da4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 16 additions and 0 deletions

View file

@ -178,11 +178,17 @@ class EnableDeferredRefcountingTest(unittest.TestCase):
@support.requires_resource("cpu")
def test_enable_deferred_refcount(self):
from threading import Thread
import gc
self.assertEqual(_testcapi.pyobject_enable_deferred_refcount("not tracked"), 0)
foo = []
self.assertEqual(_testcapi.pyobject_enable_deferred_refcount(foo), int(support.Py_GIL_DISABLED))
# The object must be tracked by the GC
not_gc_tracked = tuple([1, 2])
self.assertFalse(gc.is_tracked(not_gc_tracked))
self.assertEqual(_testcapi.pyobject_enable_deferred_refcount(not_gc_tracked), 0)
# Make sure reference counting works on foo now
self.assertEqual(foo, [])
if support.Py_GIL_DISABLED:

View file

@ -0,0 +1,3 @@
:c:func:`PyUnstable_Object_EnableDeferredRefcount` now returns ``0`` if the
object is not tracked by the garbage collector: if :func:`gc.is_tracked` is
false. Patch by Victor Stinner.

View file

@ -2821,6 +2821,13 @@ PyUnstable_Object_EnableDeferredRefcount(PyObject *op)
return 0;
}
if (!PyObject_GC_IsTracked(op)) {
// When deferred refcount is enabled, the object will only be
// deallocated by the tracing garbage collector. So it must be tracked
// by the garbage collector.
return 0;
}
uint8_t bits = _Py_atomic_load_uint8(&op->ob_gc_bits);
if ((bits & _PyGC_BITS_DEFERRED) != 0)
{