From 16f8e22e7c681d8e8184048ed1bf927d33e11758 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 18 Jun 2024 16:28:48 +0200 Subject: [PATCH] gh-120600: Make Py_TYPE() opaque in limited C API 3.14 (#120601) In the limited C API 3.14 and newer, Py_TYPE() is now implemented as an opaque function call to hide implementation details. --- Doc/data/stable_abi.dat | 1 + Doc/whatsnew/3.14.rst | 5 ++++ Include/object.h | 28 +++++++++++++------ Lib/test/test_stable_abi_ctypes.py | 1 + ...-06-16-22-58-47.gh-issue-120600.TJdf0w.rst | 2 ++ Misc/stable_abi.toml | 3 ++ Objects/object.c | 8 ++++++ PC/python3dll.c | 1 + 8 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2024-06-16-22-58-47.gh-issue-120600.TJdf0w.rst diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat index 76a035f194d..c18c813104c 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -877,6 +877,7 @@ function,Py_ReprLeave,3.2,, function,Py_SetProgramName,3.2,, function,Py_SetPythonHome,3.2,, function,Py_SetRecursionLimit,3.2,, +function,Py_TYPE,3.14,, type,Py_UCS4,3.2,, macro,Py_UNBLOCK_THREADS,3.2,, var,Py_UTF8Mode,3.8,, diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 55541ff14d8..804d39ab646 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -301,6 +301,11 @@ New Features Porting to Python 3.14 ---------------------- +* In the limited C API 3.14 and newer, :c:func:`Py_TYPE` is now implemented as + an opaque function call to hide implementation details. + (Contributed by Victor Stinner in :gh:`120600`.) + + Deprecated ---------- diff --git a/Include/object.h b/Include/object.h index 48f97502ad1..795d4fb2584 100644 --- a/Include/object.h +++ b/Include/object.h @@ -244,16 +244,26 @@ _Py_IsOwnedByCurrentThread(PyObject *ob) } #endif -// bpo-39573: The Py_SET_TYPE() function must be used to set an object type. -static inline PyTypeObject* Py_TYPE(PyObject *ob) { -#ifdef Py_GIL_DISABLED - return (PyTypeObject *)_Py_atomic_load_ptr_relaxed(&ob->ob_type); +// Py_TYPE() implementation for the stable ABI +PyAPI_FUNC(PyTypeObject*) Py_TYPE(PyObject *ob); + +#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030e0000 + // Stable ABI implements Py_TYPE() as a function call + // on limited C API version 3.14 and newer. #else - return ob->ob_type; -#endif -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob)) + static inline PyTypeObject* _Py_TYPE(PyObject *ob) + { + #if defined(Py_GIL_DISABLED) + return (PyTypeObject *)_Py_atomic_load_ptr_relaxed(&ob->ob_type); + #else + return ob->ob_type; + #endif + } + #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 + # define Py_TYPE(ob) _Py_TYPE(_PyObject_CAST(ob)) + #else + # define Py_TYPE(ob) _Py_TYPE(ob) + #endif #endif PyAPI_DATA(PyTypeObject) PyLong_Type; diff --git a/Lib/test/test_stable_abi_ctypes.py b/Lib/test/test_stable_abi_ctypes.py index c06c285c501..47dff5c28f6 100644 --- a/Lib/test/test_stable_abi_ctypes.py +++ b/Lib/test/test_stable_abi_ctypes.py @@ -896,6 +896,7 @@ SYMBOL_NAMES = ( "Py_SetProgramName", "Py_SetPythonHome", "Py_SetRecursionLimit", + "Py_TYPE", "Py_UTF8Mode", "Py_VaBuildValue", "Py_Version", diff --git a/Misc/NEWS.d/next/C API/2024-06-16-22-58-47.gh-issue-120600.TJdf0w.rst b/Misc/NEWS.d/next/C API/2024-06-16-22-58-47.gh-issue-120600.TJdf0w.rst new file mode 100644 index 00000000000..12ffd9b348d --- /dev/null +++ b/Misc/NEWS.d/next/C API/2024-06-16-22-58-47.gh-issue-120600.TJdf0w.rst @@ -0,0 +1,2 @@ +In the limited C API 3.14 and newer, :c:func:`Py_TYPE` is now implemented as an +opaque function call to hide implementation details. Patch by Victor Stinner. diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml index 77473662aaa..305978f9f0c 100644 --- a/Misc/stable_abi.toml +++ b/Misc/stable_abi.toml @@ -2507,3 +2507,6 @@ added = '3.13' [function.PyEval_GetFrameLocals] added = '3.13' + +[function.Py_TYPE] + added = '3.14' diff --git a/Objects/object.c b/Objects/object.c index b7730475ac3..16f940f46f1 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -3001,3 +3001,11 @@ Py_GetConstantBorrowed(unsigned int constant_id) // All constants are immortal return Py_GetConstant(constant_id); } + + +// Py_TYPE() implementation for the stable ABI +#undef Py_TYPE +PyTypeObject* Py_TYPE(PyObject *ob) +{ + return _Py_TYPE(ob); +} diff --git a/PC/python3dll.c b/PC/python3dll.c index 86c88843089..0bcf1cc507e 100755 --- a/PC/python3dll.c +++ b/PC/python3dll.c @@ -87,6 +87,7 @@ EXPORT_FUNC(Py_SetPath) EXPORT_FUNC(Py_SetProgramName) EXPORT_FUNC(Py_SetPythonHome) EXPORT_FUNC(Py_SetRecursionLimit) +EXPORT_FUNC(Py_TYPE) EXPORT_FUNC(Py_VaBuildValue) EXPORT_FUNC(Py_XNewRef) EXPORT_FUNC(PyAIter_Check)