Skip to content

Commit 9d344fa

Browse files
authored
gh-124127: Make Py_REFCNT() opaque in limited C API 3.14 (#124128)
1 parent b82f076 commit 9d344fa

File tree

8 files changed

+44
-17
lines changed

8 files changed

+44
-17
lines changed

Doc/data/stable_abi.dat

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

Doc/whatsnew/3.14.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -650,9 +650,10 @@ New Features
650650
Porting to Python 3.14
651651
----------------------
652652

653-
* In the limited C API 3.14 and newer, :c:func:`Py_TYPE` is now implemented as
654-
an opaque function call to hide implementation details.
655-
(Contributed by Victor Stinner in :gh:`120600`.)
653+
* In the limited C API 3.14 and newer, :c:func:`Py_TYPE` and
654+
:c:func:`Py_REFCNT` are now implemented as an opaque function call to hide
655+
implementation details.
656+
(Contributed by Victor Stinner in :gh:`120600` and :gh:`124127`.)
656657

657658

658659
Deprecated

Include/refcount.h

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -77,21 +77,29 @@ check by comparing the reference count field to the immortality reference count.
7777
#endif // Py_GIL_DISABLED
7878

7979

80-
static inline Py_ssize_t Py_REFCNT(PyObject *ob) {
81-
#if !defined(Py_GIL_DISABLED)
82-
return ob->ob_refcnt;
80+
// Py_REFCNT() implementation for the stable ABI
81+
PyAPI_FUNC(Py_ssize_t) Py_REFCNT(PyObject *ob);
82+
83+
#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030e0000
84+
// Stable ABI implements Py_REFCNT() as a function call
85+
// on limited C API version 3.14 and newer.
8386
#else
84-
uint32_t local = _Py_atomic_load_uint32_relaxed(&ob->ob_ref_local);
85-
if (local == _Py_IMMORTAL_REFCNT_LOCAL) {
86-
return _Py_IMMORTAL_REFCNT;
87+
static inline Py_ssize_t _Py_REFCNT(PyObject *ob) {
88+
#if !defined(Py_GIL_DISABLED)
89+
return ob->ob_refcnt;
90+
#else
91+
uint32_t local = _Py_atomic_load_uint32_relaxed(&ob->ob_ref_local);
92+
if (local == _Py_IMMORTAL_REFCNT_LOCAL) {
93+
return _Py_IMMORTAL_REFCNT;
94+
}
95+
Py_ssize_t shared = _Py_atomic_load_ssize_relaxed(&ob->ob_ref_shared);
96+
return _Py_STATIC_CAST(Py_ssize_t, local) +
97+
Py_ARITHMETIC_RIGHT_SHIFT(Py_ssize_t, shared, _Py_REF_SHARED_SHIFT);
98+
#endif
8799
}
88-
Py_ssize_t shared = _Py_atomic_load_ssize_relaxed(&ob->ob_ref_shared);
89-
return _Py_STATIC_CAST(Py_ssize_t, local) +
90-
Py_ARITHMETIC_RIGHT_SHIFT(Py_ssize_t, shared, _Py_REF_SHARED_SHIFT);
91-
#endif
92-
}
93-
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
94-
# define Py_REFCNT(ob) Py_REFCNT(_PyObject_CAST(ob))
100+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
101+
# define Py_REFCNT(ob) _Py_REFCNT(_PyObject_CAST(ob))
102+
#endif
95103
#endif
96104

97105

Lib/test/test_stable_abi_ctypes.py

Lines changed: 1 addition & 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_REFCNT` is now implemented
2+
as an opaque function call to hide implementation details. Patch by Victor
3+
Stinner.

Misc/stable_abi.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2508,6 +2508,8 @@
25082508

25092509
[function.Py_TYPE]
25102510
added = '3.14'
2511+
[function.Py_REFCNT]
2512+
added = '3.14'
25112513
[function.PyIter_NextItem]
25122514
added = '3.14'
25132515
[function.PyLong_FromInt32]

Objects/object.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3039,7 +3039,17 @@ Py_GetConstantBorrowed(unsigned int constant_id)
30393039

30403040
// Py_TYPE() implementation for the stable ABI
30413041
#undef Py_TYPE
3042-
PyTypeObject* Py_TYPE(PyObject *ob)
3042+
PyTypeObject*
3043+
Py_TYPE(PyObject *ob)
30433044
{
30443045
return _Py_TYPE(ob);
30453046
}
3047+
3048+
3049+
// Py_REFCNT() implementation for the stable ABI
3050+
#undef Py_REFCNT
3051+
Py_ssize_t
3052+
Py_REFCNT(PyObject *ob)
3053+
{
3054+
return _Py_REFCNT(ob);
3055+
}

PC/python3dll.c

Lines changed: 1 addition & 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)