]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-124127: Make Py_REFCNT() opaque in limited C API 3.14 (#124128)
authorVictor Stinner <vstinner@python.org>
Tue, 24 Sep 2024 06:42:58 +0000 (08:42 +0200)
committerGitHub <noreply@github.com>
Tue, 24 Sep 2024 06:42:58 +0000 (08:42 +0200)
Doc/data/stable_abi.dat
Doc/whatsnew/3.14.rst
Include/refcount.h
Lib/test/test_stable_abi_ctypes.py
Misc/NEWS.d/next/C_API/2024-09-16-16-21-39.gh-issue-124127.LB8DBU.rst [new file with mode: 0644]
Misc/stable_abi.toml
Objects/object.c
PC/python3dll.c

index 7c4b56d1dd652f42b9ecb36502230cb4cababebb..19dc71a345b47415b798007cc794d262bc607fab 100644 (file)
@@ -881,6 +881,7 @@ func,Py_Main,3.2,,
 func,Py_MakePendingCalls,3.2,,
 func,Py_NewInterpreter,3.2,,
 func,Py_NewRef,3.10,,
+func,Py_REFCNT,3.14,,
 func,Py_ReprEnter,3.2,,
 func,Py_ReprLeave,3.2,,
 func,Py_SetProgramName,3.2,,
index 04f1a195bca561960e7260b8bfdb6b2382db586e..5acb9bfe18b2d076b5b8d398c6067e99db5accbb 100644 (file)
@@ -650,9 +650,10 @@ New Features
 Porting to Python 3.14
 ----------------------
 
-* In the limited C API 3.14 and newer, :c:func:`Py_TYPE` is now implemented as
-  an opaque function call to hide implementation details.
-  (Contributed by Victor Stinner in :gh:`120600`.)
+* In the limited C API 3.14 and newer, :c:func:`Py_TYPE` and
+  :c:func:`Py_REFCNT` are now implemented as an opaque function call to hide
+  implementation details.
+  (Contributed by Victor Stinner in :gh:`120600` and :gh:`124127`.)
 
 
 Deprecated
index 1d736b194dcc776f6a9f7644ead8d5b6a4bfda26..9a4e15065ecab8c8cfdc60b29a7e64434c5b448e 100644 (file)
@@ -77,21 +77,29 @@ check by comparing the reference count field to the immortality reference count.
 #endif  // Py_GIL_DISABLED
 
 
-static inline Py_ssize_t Py_REFCNT(PyObject *ob) {
-#if !defined(Py_GIL_DISABLED)
-    return ob->ob_refcnt;
+// Py_REFCNT() implementation for the stable ABI
+PyAPI_FUNC(Py_ssize_t) Py_REFCNT(PyObject *ob);
+
+#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030e0000
+    // Stable ABI implements Py_REFCNT() as a function call
+    // on limited C API version 3.14 and newer.
 #else
-    uint32_t local = _Py_atomic_load_uint32_relaxed(&ob->ob_ref_local);
-    if (local == _Py_IMMORTAL_REFCNT_LOCAL) {
-        return _Py_IMMORTAL_REFCNT;
+    static inline Py_ssize_t _Py_REFCNT(PyObject *ob) {
+    #if !defined(Py_GIL_DISABLED)
+        return ob->ob_refcnt;
+    #else
+        uint32_t local = _Py_atomic_load_uint32_relaxed(&ob->ob_ref_local);
+        if (local == _Py_IMMORTAL_REFCNT_LOCAL) {
+            return _Py_IMMORTAL_REFCNT;
+        }
+        Py_ssize_t shared = _Py_atomic_load_ssize_relaxed(&ob->ob_ref_shared);
+        return _Py_STATIC_CAST(Py_ssize_t, local) +
+               Py_ARITHMETIC_RIGHT_SHIFT(Py_ssize_t, shared, _Py_REF_SHARED_SHIFT);
+    #endif
     }
-    Py_ssize_t shared = _Py_atomic_load_ssize_relaxed(&ob->ob_ref_shared);
-    return _Py_STATIC_CAST(Py_ssize_t, local) +
-           Py_ARITHMETIC_RIGHT_SHIFT(Py_ssize_t, shared, _Py_REF_SHARED_SHIFT);
-#endif
-}
-#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
-#  define Py_REFCNT(ob) Py_REFCNT(_PyObject_CAST(ob))
+    #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
+    #  define Py_REFCNT(ob) _Py_REFCNT(_PyObject_CAST(ob))
+    #endif
 #endif
 
 
index 4e509e30bee1227ba022269813d1cfe4b875e75c..d16ad7ef5d4328333e22d80360f432001766df26 100644 (file)
@@ -899,6 +899,7 @@ SYMBOL_NAMES = (
     "Py_MakePendingCalls",
     "Py_NewInterpreter",
     "Py_NewRef",
+    "Py_REFCNT",
     "Py_ReprEnter",
     "Py_ReprLeave",
     "Py_SetPath",
diff --git a/Misc/NEWS.d/next/C_API/2024-09-16-16-21-39.gh-issue-124127.LB8DBU.rst b/Misc/NEWS.d/next/C_API/2024-09-16-16-21-39.gh-issue-124127.LB8DBU.rst
new file mode 100644 (file)
index 0000000..883f173
--- /dev/null
@@ -0,0 +1,3 @@
+In the limited C API 3.14 and newer, :c:func:`Py_REFCNT` is now implemented
+as an opaque function call to hide implementation details. Patch by Victor
+Stinner.
index d8a9d1f3335583c3cf892b1e1777b85bfa5b6366..fe0a5e44f8fb155f08091402cc149016540c5e3c 100644 (file)
 
 [function.Py_TYPE]
     added = '3.14'
+[function.Py_REFCNT]
+    added = '3.14'
 [function.PyIter_NextItem]
     added = '3.14'
 [function.PyLong_FromInt32]
index bc63b8120a516037e6aaef3e603ffb7b8e0cfdf8..8a819dd336e4213c850f107e25f97a1cc820e8af 100644 (file)
@@ -3039,7 +3039,17 @@ Py_GetConstantBorrowed(unsigned int constant_id)
 
 // Py_TYPE() implementation for the stable ABI
 #undef Py_TYPE
-PyTypeObject* Py_TYPE(PyObject *ob)
+PyTypeObject*
+Py_TYPE(PyObject *ob)
 {
     return _Py_TYPE(ob);
 }
+
+
+// Py_REFCNT() implementation for the stable ABI
+#undef Py_REFCNT
+Py_ssize_t
+Py_REFCNT(PyObject *ob)
+{
+    return _Py_REFCNT(ob);
+}
index 7bd04cb483b547b253c57feab1700b25155d172b..6b8208ab90bd9504931d891e4f28fb074e59f850 100755 (executable)
@@ -81,6 +81,7 @@ EXPORT_FUNC(Py_Main)
 EXPORT_FUNC(Py_MakePendingCalls)
 EXPORT_FUNC(Py_NewInterpreter)
 EXPORT_FUNC(Py_NewRef)
+EXPORT_FUNC(Py_REFCNT)
 EXPORT_FUNC(Py_ReprEnter)
 EXPORT_FUNC(Py_ReprLeave)
 EXPORT_FUNC(Py_SetPath)