]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-123619: Fix PyUnstable_Object_EnableDeferredRefcount() (GH-151260) (#151327)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Thu, 11 Jun 2026 11:20:21 +0000 (13:20 +0200)
committerGitHub <noreply@github.com>
Thu, 11 Jun 2026 11:20:21 +0000 (11:20 +0000)
gh-123619: Fix PyUnstable_Object_EnableDeferredRefcount() (GH-151260)

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

Co-authored-by: Victor Stinner <vstinner@python.org>
Lib/test/test_capi/test_object.py
Misc/NEWS.d/next/C_API/2026-06-10-16-43-37.gh-issue-123619.dV82r6.rst [new file with mode: 0644]
Objects/object.c

index 807b62c19863e70f3cf399799103199c6fb5e27f..0b188fc90597744f67879432d1489fdaedf387ca 100644 (file)
@@ -144,11 +144,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 (file)
index 0000000..4d4c945
--- /dev/null
@@ -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.
index fa7351bb5173fff03e93b0021d8e72bdd6b3e406..3a104bcd932cd4f332f4a96f0767360f888d0039 100644 (file)
@@ -2728,6 +2728,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)
     {