https://github.com/python/cpython/commit/72e7eddce6c7137cef06b6eba15641597919e3d4
commit: 72e7eddce6c7137cef06b6eba15641597919e3d4
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2026-06-11T12:55:13+02:00
summary:
gh-123619: Fix PyUnstable_Object_EnableDeferredRefcount() (#151260)
Return 0 if the object is not tracked by the GC.
files:
A Misc/NEWS.d/next/C_API/2026-06-10-16-43-37.gh-issue-123619.dV82r6.rst
M Lib/test/test_capi/test_object.py
M Objects/object.c
diff --git a/Lib/test/test_capi/test_object.py
b/Lib/test/test_capi/test_object.py
index e5c50902a0118d4..433afac875aa7bf 100644
--- a/Lib/test/test_capi/test_object.py
+++ b/Lib/test/test_capi/test_object.py
@@ -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:
diff --git
a/Misc/NEWS.d/next/C_API/2026-06-10-16-43-37.gh-issue-123619.dV82r6.rst
b/Misc/NEWS.d/next/C_API/2026-06-10-16-43-37.gh-issue-123619.dV82r6.rst
new file mode 100644
index 000000000000000..4d4c94563330c06
--- /dev/null
+++ b/Misc/NEWS.d/next/C_API/2026-06-10-16-43-37.gh-issue-123619.dV82r6.rst
@@ -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.
diff --git a/Objects/object.c b/Objects/object.c
index e0e26bb50d36537..bd23c2e23881949 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -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)
{
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]