From 22fcb01b9e966853e2440d4d8661b4bdff80fe85 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 6 Dec 2023 11:36:54 +0100 Subject: [PATCH] gh-111506: Rename _Py_SetRefcnt() to Py_SET_REFCNT() --- Doc/data/stable_abi.dat | 1 + Include/object.h | 20 +++++----- Include/pyport.h | 4 ++ Lib/test/test_stable_abi_ctypes.py | 2 +- Makefile.pre.in | 1 + Misc/stable_abi.toml | 3 +- Objects/object.c | 52 ------------------------- Objects/object_abi.c | 61 ++++++++++++++++++++++++++++++ PC/python3dll.c | 2 +- PCbuild/pythoncore.vcxproj | 1 + PCbuild/pythoncore.vcxproj.filters | 3 ++ 11 files changed, 85 insertions(+), 65 deletions(-) create mode 100644 Objects/object_abi.c 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..cb16e3736239df5 100644 --- a/Include/object.h +++ b/Include/object.h @@ -352,15 +352,17 @@ 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); +// Stable ABI implements Py_SET_REFCNT() as a function call +// on limited C API version 3.13 and newer. +PyAPI_FUNC(void) Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt); #else + +#ifdef _Py_STABLE_ABI_IMPL +# define Py_SET_REFCNT _Py_SET_REFCNT +#endif + +static 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 +396,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 +#if (!defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000) && !defined(_Py_STABLE_ABI_IMPL) # define Py_SET_REFCNT(ob, refcnt) Py_SET_REFCNT(_PyObject_CAST(ob), (refcnt)) #endif +#endif static inline void Py_SET_TYPE(PyObject *ob, PyTypeObject *type) { diff --git a/Include/pyport.h b/Include/pyport.h index 328471085f959da..661af523850a045 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -180,6 +180,10 @@ typedef Py_ssize_t Py_ssize_clean_t; # define Py_LOCAL_INLINE(type) static inline type #endif +#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 < 0x030d0000 && defined(Py_GIL_DISABLED) +# error "Free threading build doesn't support limited C API 3.12 and older" +#endif + #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 # define Py_MEMCPY memcpy #endif 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/Makefile.pre.in b/Makefile.pre.in index b5edb4e6748fb09..3a58539507c1ceb 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -508,6 +508,7 @@ OBJECT_OBJS= \ Objects/moduleobject.o \ Objects/namespaceobject.o \ Objects/object.o \ + Objects/object_abi.o \ Objects/obmalloc.o \ Objects/picklebufobject.o \ Objects/rangeobject.o \ 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..b9e97dcbdeba312 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2886,55 +2886,3 @@ PyObject_GET_WEAKREFS_LISTPTR(PyObject *op) { return _PyObject_GET_WEAKREFS_LISTPTR(op); } - - -#undef Py_NewRef -#undef Py_XNewRef - -// Export Py_NewRef() and Py_XNewRef() as regular functions for the stable ABI. -PyObject* -Py_NewRef(PyObject *obj) -{ - return _Py_NewRef(obj); -} - -PyObject* -Py_XNewRef(PyObject *obj) -{ - return _Py_XNewRef(obj); -} - -#undef Py_Is -#undef Py_IsNone -#undef Py_IsTrue -#undef Py_IsFalse - -// Export Py_Is(), Py_IsNone(), Py_IsTrue(), Py_IsFalse() as regular functions -// for the stable ABI. -int Py_Is(PyObject *x, PyObject *y) -{ - return (x == y); -} - -int Py_IsNone(PyObject *x) -{ - return Py_Is(x, Py_None); -} - -int Py_IsTrue(PyObject *x) -{ - return Py_Is(x, Py_True); -} - -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); -} diff --git a/Objects/object_abi.c b/Objects/object_abi.c new file mode 100644 index 000000000000000..294c60a4fa385a6 --- /dev/null +++ b/Objects/object_abi.c @@ -0,0 +1,61 @@ +// Stable ABI implementation for PyObject functions. + + +// Rename static inline functions with macros +#define _Py_STABLE_ABI_IMPL + +#include "Python.h" + + +#undef Py_NewRef +#undef Py_XNewRef + +// Export Py_NewRef() and Py_XNewRef() as regular functions for the stable ABI. +PyObject* +Py_NewRef(PyObject *obj) +{ + return _Py_NewRef(obj); +} + +PyObject* +Py_XNewRef(PyObject *obj) +{ + return _Py_XNewRef(obj); +} + + +#undef Py_Is +#undef Py_IsNone +#undef Py_IsTrue +#undef Py_IsFalse + +// Export Py_Is(), Py_IsNone(), Py_IsTrue(), Py_IsFalse() as regular functions +// for the stable ABI. +int Py_Is(PyObject *x, PyObject *y) +{ + return (x == y); +} + +int Py_IsNone(PyObject *x) +{ + return Py_Is(x, Py_None); +} + +int Py_IsTrue(PyObject *x) +{ + return Py_Is(x, Py_True); +} + +int Py_IsFalse(PyObject *x) +{ + return Py_Is(x, Py_False); +} + + +#undef Py_SET_REFCNT + +void +Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) +{ + _Py_SET_REFCNT(ob, 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) diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index be1b98dba02fc5c..13536fb4e07fec4 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -503,6 +503,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 4f0da8f35998b76..b7d0b7b4536e7ae 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -1142,6 +1142,9 @@ Objects + + Objects + Objects