[Python-checkins] [3.12] gh-102304: Fix Py_INCREF() stable ABI in debug mode (#104763) (#105352)

vstinner webhook-mailer at python.org
Tue Jun 6 10:22:11 EDT 2023


https://github.com/python/cpython/commit/2bbb557b0f077f8c8b571148e0368472bbbbf5ea
commit: 2bbb557b0f077f8c8b571148e0368472bbbbf5ea
branch: 3.12
author: Victor Stinner <vstinner at python.org>
committer: vstinner <vstinner at python.org>
date: 2023-06-06T16:22:04+02:00
summary:

[3.12] gh-102304: Fix Py_INCREF() stable ABI in debug mode (#104763) (#105352)

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)

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

diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst
index 287549fe30ec..4a755975b788 100644
--- a/Doc/whatsnew/3.12.rst
+++ b/Doc/whatsnew/3.12.rst
@@ -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
 =============
diff --git a/Include/object.h b/Include/object.h
index c2fee85a2c38..dc5b087db2f4 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -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);
 }
diff --git a/Lib/test/test_stable_abi_ctypes.py b/Lib/test/test_stable_abi_ctypes.py
index 689836754883..8cad71c7c345 100644
--- a/Lib/test/test_stable_abi_ctypes.py
+++ b/Lib/test/test_stable_abi_ctypes.py
@@ -917,8 +917,6 @@ def test_windows_feature_macros(self):
     )
 if feature_macros['Py_REF_DEBUG']:
     SYMBOL_NAMES += (
-        '_Py_DecRefTotal_DO_NOT_USE_THIS',
-        '_Py_IncRefTotal_DO_NOT_USE_THIS',
         '_Py_NegativeRefcount',
         '_Py_RefTotal',
     )
diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml
index 1db98483f09f..48299e9b35ff 100644
--- a/Misc/stable_abi.toml
+++ b/Misc/stable_abi.toml
@@ -2406,12 +2406,3 @@
     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
diff --git a/PC/python3dll.c b/PC/python3dll.c
index 5665d5530e23..505feef4b986 100755
--- a/PC/python3dll.c
+++ b/PC/python3dll.c
@@ -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)



More information about the Python-checkins mailing list