Skip to content

Commit 1bb08c2

Browse files
committed
Make Py_{SIZE,IS_TYPE,SET_SIZE} regular functions in stable ABI
Group them together with Py_TYPE & Py_SET_TYPE to cut down on repetitive preprocessor macros. Format repetitive definitions in object.c more concisely. Py_SET_TYPE is still left out of the Limited API.
1 parent a269e69 commit 1bb08c2

File tree

6 files changed

+79
-57
lines changed

6 files changed

+79
-57
lines changed

Doc/data/stable_abi.dat

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

Include/object.h

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -265,56 +265,41 @@ _Py_IsOwnedByCurrentThread(PyObject *ob)
265265
}
266266
#endif
267267

268-
// Py_TYPE() implementation for the stable ABI
269-
PyAPI_FUNC(PyTypeObject*) Py_TYPE(PyObject *ob);
270-
271-
#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030e0000
272-
// Stable ABI implements Py_TYPE() as a function call
273-
// on limited C API version 3.14 and newer.
274-
#else
275-
static inline PyTypeObject* _Py_TYPE(PyObject *ob)
276-
{
277-
return ob->ob_type;
278-
}
279-
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
280-
# define Py_TYPE(ob) _Py_TYPE(_PyObject_CAST(ob))
281-
#else
282-
# define Py_TYPE(ob) _Py_TYPE(ob)
283-
#endif
284-
#endif
285-
286268
PyAPI_DATA(PyTypeObject) PyLong_Type;
287269
PyAPI_DATA(PyTypeObject) PyBool_Type;
288270

271+
/* Definitions for the stable ABI */
272+
PyAPI_FUNC(PyTypeObject*) Py_TYPE(PyObject *ob);
273+
PyAPI_FUNC(Py_ssize_t) Py_SIZE(PyObject *ob);
274+
PyAPI_FUNC(int) Py_IS_TYPE(PyObject *ob, PyTypeObject *type);
275+
PyAPI_FUNC(void) Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size);
276+
289277
#ifndef _Py_OPAQUE_PYOBJECT
278+
279+
static inline
280+
PyTypeObject* _Py_TYPE_impl(PyObject *ob)
281+
{
282+
return ob->ob_type;
283+
}
284+
290285
// bpo-39573: The Py_SET_SIZE() function must be used to set an object size.
291-
static inline Py_ssize_t Py_SIZE(PyObject *ob) {
286+
static inline Py_ssize_t
287+
_Py_SIZE_impl(PyObject *ob)
288+
{
292289
assert(Py_TYPE(ob) != &PyLong_Type);
293290
assert(Py_TYPE(ob) != &PyBool_Type);
294291
return _PyVarObject_CAST(ob)->ob_size;
295292
}
296-
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
297-
# define Py_SIZE(ob) Py_SIZE(_PyObject_CAST(ob))
298-
#endif
299-
#endif // !defined(_Py_OPAQUE_PYOBJECT)
300293

301-
static inline int Py_IS_TYPE(PyObject *ob, PyTypeObject *type) {
294+
static inline int
295+
_Py_IS_TYPE_impl(PyObject *ob, PyTypeObject *type)
296+
{
302297
return Py_TYPE(ob) == type;
303298
}
304-
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
305-
# define Py_IS_TYPE(ob, type) Py_IS_TYPE(_PyObject_CAST(ob), (type))
306-
#endif
307-
308-
309-
#ifndef _Py_OPAQUE_PYOBJECT
310-
static inline void Py_SET_TYPE(PyObject *ob, PyTypeObject *type) {
311-
ob->ob_type = type;
312-
}
313-
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
314-
# define Py_SET_TYPE(ob, type) Py_SET_TYPE(_PyObject_CAST(ob), type)
315-
#endif
316299

317-
static inline void Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) {
300+
static inline void
301+
_Py_SET_SIZE_impl(PyVarObject *ob, Py_ssize_t size)
302+
{
318303
assert(Py_TYPE(_PyObject_CAST(ob)) != &PyLong_Type);
319304
assert(Py_TYPE(_PyObject_CAST(ob)) != &PyBool_Type);
320305
#ifdef Py_GIL_DISABLED
@@ -323,9 +308,31 @@ static inline void Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) {
323308
ob->ob_size = size;
324309
#endif
325310
}
326-
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
327-
# define Py_SET_SIZE(ob, size) Py_SET_SIZE(_PyVarObject_CAST(ob), (size))
311+
312+
static inline void
313+
Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
314+
{
315+
ob->ob_type = type;
316+
}
317+
318+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < _Py_PACK_VERSION(3, 11)
319+
// Non-limited API & limited API 3.11 & below: the user can omit casts
320+
# define Py_TYPE(ob) _Py_TYPE_impl(_PyObject_CAST(ob))
321+
# define Py_SIZE(ob) _Py_SIZE_impl(_PyObject_CAST(ob))
322+
# define Py_IS_TYPE(ob, type) _Py_IS_TYPE_impl(_PyObject_CAST(ob), (type))
323+
# define Py_SET_SIZE(ob, size) _Py_SET_SIZE_impl(_PyVarObject_CAST(ob), (size))
324+
# define Py_SET_TYPE(ob, type) Py_SET_TYPE(_PyObject_CAST(ob), type)
325+
#elif Py_LIMITED_API+0 < _Py_PACK_VERSION(3, 15)
326+
# if Py_LIMITED_API+0 < _Py_PACK_VERSION(3, 14)
327+
// Py_TYPE() is a function call on Limited API 3.14 and newer
328+
# define Py_TYPE(ob) _Py_TYPE_impl(ob)
329+
# endif
330+
// These are function calls on Limited API 3.15 and newer:
331+
# define Py_SIZE(ob) _Py_SIZE_impl(ob)
332+
# define Py_IS_TYPE(ob, type) _Py_IS_TYPE_impl((ob), (type))
333+
# define Py_SET_SIZE(ob, size) _Py_SET_SIZE_impl((ob), (size))
328334
#endif
335+
329336
#endif // !defined(_Py_OPAQUE_PYOBJECT)
330337

331338

Lib/test/test_stable_abi_ctypes.py

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

Misc/stable_abi.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2519,8 +2519,10 @@
25192519
added = '3.13'
25202520

25212521
[function.Py_TYPE]
2522+
# Before 3.14, this was a macro that accessed the PyObject member
25222523
added = '3.14'
25232524
[function.Py_REFCNT]
2525+
# Before 3.14, this was a macro that accessed the PyObject member
25242526
added = '3.14'
25252527
[function.PyIter_NextItem]
25262528
added = '3.14'
@@ -2606,3 +2608,12 @@
26062608
added = '3.15'
26072609
[const.PyABIInfo_FREETHREADING_AGNOSTIC]
26082610
added = '3.15'
2611+
[function.Py_SIZE]
2612+
# Before 3.15, this was a macro that accessed the PyObject member
2613+
added = '3.15'
2614+
[function.Py_IS_TYPE]
2615+
# Before 3.15, this was a macro that accessed the PyObject member
2616+
added = '3.15'
2617+
[function.Py_SET_SIZE]
2618+
# Before 3.15, this was a macro that accessed the PyObject member
2619+
added = '3.15'

Objects/object.c

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3361,24 +3361,6 @@ Py_GetConstantBorrowed(unsigned int constant_id)
33613361
return Py_GetConstant(constant_id);
33623362
}
33633363

3364-
3365-
// Py_TYPE() implementation for the stable ABI
3366-
#undef Py_TYPE
3367-
PyTypeObject*
3368-
Py_TYPE(PyObject *ob)
3369-
{
3370-
return _Py_TYPE(ob);
3371-
}
3372-
3373-
3374-
// Py_REFCNT() implementation for the stable ABI
3375-
#undef Py_REFCNT
3376-
Py_ssize_t
3377-
Py_REFCNT(PyObject *ob)
3378-
{
3379-
return _Py_REFCNT(ob);
3380-
}
3381-
33823364
int
33833365
PyUnstable_IsImmortal(PyObject *op)
33843366
{
@@ -3405,3 +3387,16 @@ _PyObject_VisitType(PyObject *op, visitproc visit, void *arg)
34053387
Py_VISIT(tp);
34063388
return 0;
34073389
}
3390+
3391+
// Implementations for the stable ABI
3392+
// Keep these at the end.
3393+
#undef Py_TYPE
3394+
#undef Py_REFCNT
3395+
#undef Py_SIZE
3396+
#undef Py_IS_TYPE
3397+
#undef Py_SET_SIZE
3398+
PyTypeObject* Py_TYPE(PyObject *ob) { return _Py_TYPE_impl(ob); }
3399+
Py_ssize_t Py_REFCNT(PyObject *ob) { return _Py_REFCNT(ob); }
3400+
Py_ssize_t Py_SIZE(PyObject *o) { return _Py_SIZE_impl(o); }
3401+
int Py_IS_TYPE(PyObject *o, PyTypeObject *t) { return _Py_IS_TYPE_impl(o, t); }
3402+
void Py_SET_SIZE(PyVarObject *o, Py_ssize_t s) { _Py_SET_SIZE_impl(o, s); }

PC/python3dll.c

Lines changed: 3 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)