diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat index 811b1bd84d24174..34fa3b97c584ea4 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -859,6 +859,7 @@ function,Py_NewInterpreter,3.2,, function,Py_NewRef,3.10,, function,Py_ReprEnter,3.2,, function,Py_ReprLeave,3.2,, +function,Py_SET_REFCNT,3.13,, function,Py_SetRecursionLimit,3.2,, type,Py_UCS4,3.2,, macro,Py_UNBLOCK_THREADS,3.2,, diff --git a/Include/object.h b/Include/object.h index 85abd30b5ad7d6a..fc5331a76420581 100644 --- a/Include/object.h +++ b/Include/object.h @@ -332,7 +332,8 @@ static inline Py_ssize_t Py_SIZE(PyObject *ob) { # define Py_SIZE(ob) Py_SIZE(_PyObject_CAST(ob)) #endif -static inline Py_ALWAYS_INLINE int _Py_IsImmortal(PyObject *op) +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030d0000 +inline Py_ALWAYS_INLINE int _Py_IsImmortal(PyObject *op) { #if defined(Py_GIL_DISABLED) return (op->ob_ref_local == _Py_IMMORTAL_REFCNT_LOCAL); @@ -343,6 +344,8 @@ static inline Py_ALWAYS_INLINE int _Py_IsImmortal(PyObject *op) #endif } #define _Py_IsImmortal(op) _Py_IsImmortal(_PyObject_CAST(op)) +#endif // !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030d0000 + static inline int Py_IS_TYPE(PyObject *ob, PyTypeObject *type) { return Py_TYPE(ob) == type; @@ -352,15 +355,12 @@ 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) { +// Stable ABI implements Py_SET_REFCNT() as an opaque function call in the +// limited C API version 3.13 and newer. #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); +PyAPI_DATA(void) Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt); #else +inline void Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) { // 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 @@ -394,11 +394,11 @@ static inline void Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) { ob->ob_ref_shared = _Py_REF_SHARED(refcnt, _Py_REF_MERGED); } #endif // Py_GIL_DISABLED -#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)) #endif +#endif // !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030d0000 static inline void Py_SET_TYPE(PyObject *ob, PyTypeObject *type) { diff --git a/Lib/test/test_stable_abi_ctypes.py b/Lib/test/test_stable_abi_ctypes.py index 4976ac3642bbe46..1236e345d2bc0d5 100644 --- a/Lib/test/test_stable_abi_ctypes.py +++ b/Lib/test/test_stable_abi_ctypes.py @@ -870,6 +870,7 @@ def test_windows_feature_macros(self): "Py_NewRef", "Py_ReprEnter", "Py_ReprLeave", + "Py_SET_REFCNT", "Py_SetPath", "Py_SetProgramName", "Py_SetPythonHome", @@ -906,7 +907,6 @@ def test_windows_feature_macros(self): "_Py_IncRef", "_Py_NoneStruct", "_Py_NotImplementedStruct", - "_Py_SetRefcnt", "_Py_SwappedOp", "_Py_TrueStruct", "_Py_VaBuildValue_SizeT", diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml index 22b25dd0ec141fd..ba589f6e28ab481 100644 --- a/Misc/stable_abi.toml +++ b/Misc/stable_abi.toml @@ -2478,6 +2478,5 @@ added = '3.13' [function.PySys_AuditTuple] added = '3.13' -[function._Py_SetRefcnt] +[function.Py_SET_REFCNT] added = '3.13' - abi_only = true diff --git a/Objects/object.c b/Objects/object.c index d145674cb3ba34d..0aeb02b191e9211 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2938,3 +2938,11 @@ _Py_SetRefcnt(PyObject *ob, Py_ssize_t refcnt) { Py_SET_REFCNT(ob, refcnt); } + +// Export _Py_IsImmortal() as a regular function +#undef _Py_IsImmortal +extern inline PyAPI_FUNC(int) _Py_IsImmortal(PyObject *op); + +// Export Py_SET_REFCNT() as a regular function in stable ABI +#undef Py_SET_REFCNT +extern inline PyAPI_FUNC(void) Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt); diff --git a/PC/python3dll.c b/PC/python3dll.c index 07aa84c91f9fc7f..1e44b1cd0b75e10 100755 --- a/PC/python3dll.c +++ b/PC/python3dll.c @@ -19,7 +19,6 @@ 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) @@ -81,6 +80,7 @@ EXPORT_FUNC(Py_NewInterpreter) EXPORT_FUNC(Py_NewRef) EXPORT_FUNC(Py_ReprEnter) EXPORT_FUNC(Py_ReprLeave) +EXPORT_FUNC(Py_SET_REFCNT) EXPORT_FUNC(Py_SetPath) EXPORT_FUNC(Py_SetProgramName) EXPORT_FUNC(Py_SetPythonHome)