]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-111506: Implement Py_SET_REFCNT() as opaque function in limited C API (#111508)
authorVictor Stinner <vstinner@python.org>
Fri, 3 Nov 2023 17:18:57 +0000 (18:18 +0100)
committerGitHub <noreply@github.com>
Fri, 3 Nov 2023 17:18:57 +0000 (18:18 +0100)
In the limited C API version 3.13, Py_SET_REFCNT() function is now
implemented as an opaque function call.

Add _Py_SetRefcnt() to the stable ABI.

Include/object.h
Lib/test/test_stable_abi_ctypes.py
Misc/NEWS.d/next/C API/2023-10-30-18-13-01.gh-issue-111506.EUdO22.rst [new file with mode: 0644]
Misc/stable_abi.toml
Objects/object.c
PC/python3dll.c

index 1c7d7f407fe23ea12650740fcbb52e021f6fbc7c..bdc07d9e8d7f837b17b51ab10f1eb079a481e543 100644 (file)
@@ -327,7 +327,15 @@ static inline int Py_IS_TYPE(PyObject *ob, PyTypeObject *type) {
 #endif
 
 
+// Py_SET_REFCNT() implementation for stable ABI
+PyAPI_FUNC(void) _Py_SetRefcnt(PyObject *ob, Py_ssize_t refcnt);
+
 static inline void Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) {
+#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030d0000
+    // Stable ABI implements Py_SET_REFCNT() as a function call
+    // on limited C API version 3.13 and newer.
+    _Py_SetRefcnt(ob, refcnt);
+#else
     // This immortal check is for code that is unaware of immortal objects.
     // The runtime tracks these objects and we should avoid as much
     // as possible having extensions inadvertently change the refcnt
@@ -335,7 +343,7 @@ static inline void Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) {
     if (_Py_IsImmortal(ob)) {
         return;
     }
-#if !defined(Py_NOGIL)
+#ifndef Py_NOGIL
     ob->ob_refcnt = refcnt;
 #else
     if (_Py_IsOwnedByCurrentThread(ob)) {
@@ -352,7 +360,8 @@ static inline void Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) {
         ob->ob_ref_local = 0;
         ob->ob_ref_shared = _Py_REF_SHARED(refcnt, _Py_REF_MERGED);
     }
-#endif
+#endif  // Py_NOGIL
+#endif  // Py_LIMITED_API+0 < 0x030d0000
 }
 #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
 #  define Py_SET_REFCNT(ob, refcnt) Py_SET_REFCNT(_PyObject_CAST(ob), (refcnt))
index 88bc0fd4025a171365a8a661a6b3cea82bebe116..85a63c44b494316e04bd65a7112944f4cc3d6b62 100644 (file)
@@ -907,6 +907,7 @@ SYMBOL_NAMES = (
     "_Py_IncRef",
     "_Py_NoneStruct",
     "_Py_NotImplementedStruct",
+    "_Py_SetRefcnt",
     "_Py_SwappedOp",
     "_Py_TrueStruct",
     "_Py_VaBuildValue_SizeT",
diff --git a/Misc/NEWS.d/next/C API/2023-10-30-18-13-01.gh-issue-111506.EUdO22.rst b/Misc/NEWS.d/next/C API/2023-10-30-18-13-01.gh-issue-111506.EUdO22.rst
new file mode 100644 (file)
index 0000000..f4d71fd
--- /dev/null
@@ -0,0 +1,2 @@
+In the limited C API version 3.13, :c:func:`Py_SET_REFCNT` function is now
+implemented as an opaque function call. Patch by Victor Stinner.
index 0601de20fe0f46b9f189d1a09e5623180dd5daa1..b55bb599d71dcc1080597c38493e233d55891130 100644 (file)
     added = '3.13'
 [function.PyUnicode_AsUTF8]
     added = '3.13'
+[function._Py_SetRefcnt]
+    added = '3.13'
+    abi_only = true
index 35c7e7bf33b13508e697fbe2ea97391fd32642f0..1cc3f9146467094b07c1df5726426a72f0bada64 100644 (file)
@@ -2931,3 +2931,11 @@ int Py_IsFalse(PyObject *x)
 {
     return Py_Is(x, Py_False);
 }
+
+
+// Py_SET_REFCNT() implementation for stable ABI
+void
+_Py_SetRefcnt(PyObject *ob, Py_ssize_t refcnt)
+{
+    Py_SET_REFCNT(ob, refcnt);
+}
index 7f5d97ae4dc83f9c52e964ef5114c20cc71db890..fa6bf1f0282b0a1cf0547d2f19fab7b53fefc95f 100755 (executable)
@@ -19,6 +19,7 @@ EXPORT_FUNC(_Py_Dealloc)
 EXPORT_FUNC(_Py_DecRef)
 EXPORT_FUNC(_Py_IncRef)
 EXPORT_FUNC(_Py_NegativeRefcount)
+EXPORT_FUNC(_Py_SetRefcnt)
 EXPORT_FUNC(_Py_VaBuildValue_SizeT)
 EXPORT_FUNC(_PyArg_Parse_SizeT)
 EXPORT_FUNC(_PyArg_ParseTuple_SizeT)