mirror of https://github.com/python/cpython
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.
This commit is contained in:
parent
bae415ad02
commit
92022d8416
|
@ -343,6 +343,15 @@ Build Changes
|
||||||
:file:`!configure`.
|
:file:`!configure`.
|
||||||
(Contributed by Christian Heimes in :gh:`89886`.)
|
(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
|
C API Changes
|
||||||
=============
|
=============
|
||||||
|
|
|
@ -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.)
|
you can count such references to the type object.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef Py_REF_DEBUG
|
#if defined(Py_REF_DEBUG) && !defined(Py_LIMITED_API)
|
||||||
# if defined(Py_LIMITED_API) && Py_LIMITED_API+0 < 0x030A0000
|
PyAPI_FUNC(void) _Py_NegativeRefcount(const char *filename, int lineno,
|
||||||
extern Py_ssize_t _Py_RefTotal;
|
PyObject *op);
|
||||||
# define _Py_INC_REFTOTAL() _Py_RefTotal++
|
|
||||||
# define _Py_DEC_REFTOTAL() _Py_RefTotal--
|
|
||||||
# elif !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030C0000
|
|
||||||
PyAPI_FUNC(void) _Py_IncRefTotal_DO_NOT_USE_THIS(void);
|
PyAPI_FUNC(void) _Py_IncRefTotal_DO_NOT_USE_THIS(void);
|
||||||
PyAPI_FUNC(void) _Py_DecRefTotal_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_INC_REFTOTAL() _Py_IncRefTotal_DO_NOT_USE_THIS()
|
||||||
# define _Py_DEC_REFTOTAL() _Py_DecRefTotal_DO_NOT_USE_THIS()
|
# define _Py_DEC_REFTOTAL() _Py_DecRefTotal_DO_NOT_USE_THIS()
|
||||||
# endif
|
#endif // Py_REF_DEBUG && !Py_LIMITED_API
|
||||||
PyAPI_FUNC(void) _Py_NegativeRefcount(const char *filename, int lineno,
|
|
||||||
PyObject *op);
|
|
||||||
#endif /* Py_REF_DEBUG */
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) _Py_Dealloc(PyObject *);
|
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)
|
static inline Py_ALWAYS_INLINE void Py_INCREF(PyObject *op)
|
||||||
{
|
{
|
||||||
#if defined(Py_REF_DEBUG) && defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030A0000
|
#if defined(Py_REF_DEBUG) && defined(Py_LIMITED_API)
|
||||||
// Stable ABI for Python 3.10 built in debug mode.
|
// Stable ABI for Python built in debug mode
|
||||||
_Py_IncRef(op);
|
_Py_IncRef(op);
|
||||||
#else
|
#else
|
||||||
// Non-limited C API and limited C API for Python 3.9 and older access
|
// 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))
|
# define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(Py_REF_DEBUG) && defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030A0000
|
#if defined(Py_REF_DEBUG) && defined(Py_LIMITED_API)
|
||||||
// Stable ABI for limited C API version 3.10 of Python debug build
|
// Stable ABI for Python built in debug mode
|
||||||
static inline void Py_DECREF(PyObject *op) {
|
static inline void Py_DECREF(PyObject *op) {
|
||||||
_Py_DecRef(op);
|
_Py_DecRef(op);
|
||||||
}
|
}
|
||||||
|
|
|
@ -917,8 +917,6 @@ if feature_macros['PY_HAVE_THREAD_NATIVE_ID']:
|
||||||
)
|
)
|
||||||
if feature_macros['Py_REF_DEBUG']:
|
if feature_macros['Py_REF_DEBUG']:
|
||||||
SYMBOL_NAMES += (
|
SYMBOL_NAMES += (
|
||||||
'_Py_DecRefTotal_DO_NOT_USE_THIS',
|
|
||||||
'_Py_IncRefTotal_DO_NOT_USE_THIS',
|
|
||||||
'_Py_NegativeRefcount',
|
'_Py_NegativeRefcount',
|
||||||
'_Py_RefTotal',
|
'_Py_RefTotal',
|
||||||
)
|
)
|
||||||
|
|
|
@ -2428,12 +2428,3 @@
|
||||||
added = '3.12'
|
added = '3.12'
|
||||||
[const.Py_TPFLAGS_ITEMS_AT_END]
|
[const.Py_TPFLAGS_ITEMS_AT_END]
|
||||||
added = '3.12'
|
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
|
|
||||||
|
|
|
@ -17,9 +17,7 @@ EXPORT_FUNC(_Py_BuildValue_SizeT)
|
||||||
EXPORT_FUNC(_Py_CheckRecursiveCall)
|
EXPORT_FUNC(_Py_CheckRecursiveCall)
|
||||||
EXPORT_FUNC(_Py_Dealloc)
|
EXPORT_FUNC(_Py_Dealloc)
|
||||||
EXPORT_FUNC(_Py_DecRef)
|
EXPORT_FUNC(_Py_DecRef)
|
||||||
EXPORT_FUNC(_Py_DecRefTotal_DO_NOT_USE_THIS)
|
|
||||||
EXPORT_FUNC(_Py_IncRef)
|
EXPORT_FUNC(_Py_IncRef)
|
||||||
EXPORT_FUNC(_Py_IncRefTotal_DO_NOT_USE_THIS)
|
|
||||||
EXPORT_FUNC(_Py_NegativeRefcount)
|
EXPORT_FUNC(_Py_NegativeRefcount)
|
||||||
EXPORT_FUNC(_Py_VaBuildValue_SizeT)
|
EXPORT_FUNC(_Py_VaBuildValue_SizeT)
|
||||||
EXPORT_FUNC(_PyArg_Parse_SizeT)
|
EXPORT_FUNC(_PyArg_Parse_SizeT)
|
||||||
|
|
Loading…
Reference in New Issue