Skip to content

Commit a1e2ebf

Browse files
committed
pythongh-120600: Make Py_TYPE() opaque in limited C API 3.14
In the limited C API 3.14 and newer, Py_TYPE() and Py_SET_TYPE() are now implemented as opaque function calls to hide implementation details. Add _Py_TYPE() and _Py_SET_TYPE() private functions.
1 parent 4f59f86 commit a1e2ebf

File tree

7 files changed

+47
-2
lines changed

7 files changed

+47
-2
lines changed

Doc/whatsnew/3.14.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,12 @@ New Features
286286
Porting to Python 3.14
287287
----------------------
288288

289+
* In the limited C API 3.14 and newer, :c:func:`Py_TYPE` and
290+
:c:func:`Py_SET_TYPE` are now implemented as opaque function calls to hide
291+
implementation details.
292+
(Contributed by Victor Stinner in :gh:`120600`.)
293+
294+
289295
Deprecated
290296
----------
291297

Include/object.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,15 @@ _Py_IsOwnedByCurrentThread(PyObject *ob)
244244
}
245245
#endif
246246

247+
PyAPI_FUNC(PyTypeObject*) _Py_TYPE(PyObject *ob);
248+
247249
// bpo-39573: The Py_SET_TYPE() function must be used to set an object type.
248250
static inline PyTypeObject* Py_TYPE(PyObject *ob) {
249-
#ifdef Py_GIL_DISABLED
251+
#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030e0000
252+
// Stable ABI implements Py_TYPE() as a function call
253+
// on limited C API version 3.14 and newer.
254+
return _Py_TYPE(ob);
255+
#elif defined(Py_GIL_DISABLED)
250256
return (PyTypeObject *)_Py_atomic_load_ptr_relaxed(&ob->ob_type);
251257
#else
252258
return ob->ob_type;
@@ -277,8 +283,14 @@ static inline int Py_IS_TYPE(PyObject *ob, PyTypeObject *type) {
277283
#endif
278284

279285

286+
PyAPI_FUNC(void) _Py_SET_TYPE(PyObject *ob, PyTypeObject *type);
287+
280288
static inline void Py_SET_TYPE(PyObject *ob, PyTypeObject *type) {
281-
#ifdef Py_GIL_DISABLED
289+
#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030e0000
290+
// Stable ABI implements Py_SET_TYPE() as a function call
291+
// on limited C API version 3.14 and newer.
292+
return _Py_SET_TYPE(ob, type);
293+
#elif defined(Py_GIL_DISABLED)
282294
_Py_atomic_store_ptr(&ob->ob_type, type);
283295
#else
284296
ob->ob_type = type;

Lib/test/test_stable_abi_ctypes.py

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
In the limited C API 3.14 and newer, :c:func:`Py_TYPE` and
2+
:c:func:`Py_SET_TYPE` are now implemented as opaque function calls to hide
3+
implementation details. Patch by Victor Stinner.

Misc/stable_abi.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2507,3 +2507,9 @@
25072507
added = '3.13'
25082508
[function.PyEval_GetFrameLocals]
25092509
added = '3.13'
2510+
[function._Py_TYPE]
2511+
added = '3.14'
2512+
abi_only = true
2513+
[function._Py_SET_TYPE]
2514+
added = '3.14'
2515+
abi_only = true

Objects/object.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3001,3 +3001,17 @@ Py_GetConstantBorrowed(unsigned int constant_id)
30013001
// All constants are immortal
30023002
return Py_GetConstant(constant_id);
30033003
}
3004+
3005+
3006+
// Py_TYPE() implementation for the stable ABI
3007+
PyTypeObject* _Py_TYPE(PyObject *ob)
3008+
{
3009+
return Py_TYPE(ob);
3010+
}
3011+
3012+
3013+
// Py_SET_TYPE() implementation for the stable ABI
3014+
void _Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
3015+
{
3016+
Py_SET_TYPE(ob, type);
3017+
}

PC/python3dll.c

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)