]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-102304: Fix Py_INCREF() stable ABI in debug mode (#104763) (#105352)
authorVictor Stinner <vstinner@python.org>
Tue, 6 Jun 2023 14:22:04 +0000 (16:22 +0200)
committerGitHub <noreply@github.com>
Tue, 6 Jun 2023 14:22:04 +0000 (16:22 +0200)
gh-102304: Fix Py_INCREF() stable ABI in debug mode (#104763)

When Python is built in debug mode (if the Py_REF_DEBUG macro is
defined), the Py_INCREF() and Py_DECREF() function are now always
implemented as opaque functions to avoid leaking implementation
details like the "_Py_RefTotal" variable or the
_Py_DecRefTotal_DO_NOT_USE_THIS() function.

* Remove _Py_IncRefTotal_DO_NOT_USE_THIS() and
  _Py_DecRefTotal_DO_NOT_USE_THIS() from the stable ABI.
* Remove _Py_NegativeRefcount() from limited C API.

(cherry picked from commit 92022d8416d9e175800b65c4d71d4e4fb47adcb0)

Doc/whatsnew/3.12.rst
Include/object.h
Lib/test/test_stable_abi_ctypes.py
Misc/stable_abi.toml
PC/python3dll.c

index 287549fe30ec1abfd874cec27639fb917fd65b8b..4a755975b788b68e0475d268cfd386c3441c5ee4 100644 (file)
@@ -1535,6 +1535,15 @@ Build Changes
   :file:`!configure`.
   (Contributed by Christian Heimes in :gh:`89886`.)
 
+* C extensions built with the :ref:`limited C API <limited-c-api>`
+  on :ref:`Python build in debug mode <debug-build>` no longer support Python
+  3.9 and older. In this configuration, :c:func:`Py_INCREF` and
+  :c:func:`Py_DECREF` are now always implemented as opaque function calls,
+  but the called functions were added to Python 3.10. Build C extensions
+  with a release build of Python or with Python 3.12 and older, to keep support
+  for Python 3.9 and older.
+  (Contributed by Victor Stinner in :gh:`102304`.)
+
 
 C API Changes
 =============
index c2fee85a2c38f6a48809fdb25f7b0fa08d22eda1..dc5b087db2f467bc443709dc7456d07e894da62a 100644 (file)
@@ -585,20 +585,14 @@ decision that's up to the implementer of each new type so if you want,
 you can count such references to the type object.)
 */
 
-#ifdef Py_REF_DEBUG
-#  if defined(Py_LIMITED_API) && Py_LIMITED_API+0 < 0x030A0000
-extern Py_ssize_t _Py_RefTotal;
-#    define _Py_INC_REFTOTAL() _Py_RefTotal++
-#    define _Py_DEC_REFTOTAL() _Py_RefTotal--
-#  elif !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030C0000
+#if defined(Py_REF_DEBUG) && !defined(Py_LIMITED_API)
+PyAPI_FUNC(void) _Py_NegativeRefcount(const char *filename, int lineno,
+                                      PyObject *op);
 PyAPI_FUNC(void) _Py_IncRefTotal_DO_NOT_USE_THIS(void);
 PyAPI_FUNC(void) _Py_DecRefTotal_DO_NOT_USE_THIS(void);
 #    define _Py_INC_REFTOTAL() _Py_IncRefTotal_DO_NOT_USE_THIS()
 #    define _Py_DEC_REFTOTAL() _Py_DecRefTotal_DO_NOT_USE_THIS()
-#  endif
-PyAPI_FUNC(void) _Py_NegativeRefcount(const char *filename, int lineno,
-                                      PyObject *op);
-#endif /* Py_REF_DEBUG */
+#endif  // Py_REF_DEBUG && !Py_LIMITED_API
 
 PyAPI_FUNC(void) _Py_Dealloc(PyObject *);
 
@@ -616,8 +610,8 @@ PyAPI_FUNC(void) _Py_DecRef(PyObject *);
 
 static inline Py_ALWAYS_INLINE void Py_INCREF(PyObject *op)
 {
-#if defined(Py_REF_DEBUG) && defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030A0000
-    // Stable ABI for Python 3.10 built in debug mode.
+#if defined(Py_REF_DEBUG) && defined(Py_LIMITED_API)
+    // Stable ABI for Python built in debug mode
     _Py_IncRef(op);
 #else
     // Non-limited C API and limited C API for Python 3.9 and older access
@@ -647,8 +641,8 @@ static inline Py_ALWAYS_INLINE void Py_INCREF(PyObject *op)
 #  define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
 #endif
 
-#if defined(Py_REF_DEBUG) && defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030A0000
-// Stable ABI for limited C API version 3.10 of Python debug build
+#if defined(Py_REF_DEBUG) && defined(Py_LIMITED_API)
+// Stable ABI for Python built in debug mode
 static inline void Py_DECREF(PyObject *op) {
     _Py_DecRef(op);
 }
index 689836754883894027635fc8056b4c538a86c5c2..8cad71c7c34545cb0c43545103d251e872e0da1d 100644 (file)
@@ -917,8 +917,6 @@ if feature_macros['PY_HAVE_THREAD_NATIVE_ID']:
     )
 if feature_macros['Py_REF_DEBUG']:
     SYMBOL_NAMES += (
-        '_Py_DecRefTotal_DO_NOT_USE_THIS',
-        '_Py_IncRefTotal_DO_NOT_USE_THIS',
         '_Py_NegativeRefcount',
         '_Py_RefTotal',
     )
index 1db98483f09f770a69cfd163b811ceaee843dd21..48299e9b35ff973b6fcc50ab1ba31f96976c46b1 100644 (file)
     added = '3.12'
 [const.Py_TPFLAGS_ITEMS_AT_END]
     added = '3.12'
-
-[function._Py_IncRefTotal_DO_NOT_USE_THIS]
-    added = '3.12'
-    ifdef = 'Py_REF_DEBUG'
-    abi_only = true
-[function._Py_DecRefTotal_DO_NOT_USE_THIS]
-    added = '3.12'
-    ifdef = 'Py_REF_DEBUG'
-    abi_only = true
index 5665d5530e2360cdf33e54b33fe0f80bd01c5c8b..505feef4b986c41669d26022d674d337416eea8e 100755 (executable)
@@ -17,9 +17,7 @@ EXPORT_FUNC(_Py_BuildValue_SizeT)
 EXPORT_FUNC(_Py_CheckRecursiveCall)
 EXPORT_FUNC(_Py_Dealloc)
 EXPORT_FUNC(_Py_DecRef)
-EXPORT_FUNC(_Py_DecRefTotal_DO_NOT_USE_THIS)
 EXPORT_FUNC(_Py_IncRef)
-EXPORT_FUNC(_Py_IncRefTotal_DO_NOT_USE_THIS)
 EXPORT_FUNC(_Py_NegativeRefcount)
 EXPORT_FUNC(_Py_VaBuildValue_SizeT)
 EXPORT_FUNC(_PyArg_Parse_SizeT)