Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Doc/data/stable_abi.dat

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

85 changes: 46 additions & 39 deletions Include/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,56 +265,41 @@ _Py_IsOwnedByCurrentThread(PyObject *ob)
}
#endif

// 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
static inline PyTypeObject* _Py_TYPE(PyObject *ob)
{
return ob->ob_type;
}
#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;
PyAPI_DATA(PyTypeObject) PyBool_Type;

/* Definitions for the stable ABI */
PyAPI_FUNC(PyTypeObject*) Py_TYPE(PyObject *ob);
PyAPI_FUNC(Py_ssize_t) Py_SIZE(PyObject *ob);
PyAPI_FUNC(int) Py_IS_TYPE(PyObject *ob, PyTypeObject *type);
PyAPI_FUNC(void) Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size);

#ifndef _Py_OPAQUE_PYOBJECT

static inline
PyTypeObject* _Py_TYPE_impl(PyObject *ob)
{
return ob->ob_type;
}

// bpo-39573: The Py_SET_SIZE() function must be used to set an object size.
static inline Py_ssize_t Py_SIZE(PyObject *ob) {
static inline Py_ssize_t
_Py_SIZE_impl(PyObject *ob)
{
assert(Py_TYPE(ob) != &PyLong_Type);
assert(Py_TYPE(ob) != &PyBool_Type);
return _PyVarObject_CAST(ob)->ob_size;
}
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
# define Py_SIZE(ob) Py_SIZE(_PyObject_CAST(ob))
#endif
#endif // !defined(_Py_OPAQUE_PYOBJECT)

static inline int Py_IS_TYPE(PyObject *ob, PyTypeObject *type) {
static inline int
_Py_IS_TYPE_impl(PyObject *ob, PyTypeObject *type)
{
return Py_TYPE(ob) == type;
}
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
# define Py_IS_TYPE(ob, type) Py_IS_TYPE(_PyObject_CAST(ob), (type))
#endif


#ifndef _Py_OPAQUE_PYOBJECT
static inline void Py_SET_TYPE(PyObject *ob, PyTypeObject *type) {
ob->ob_type = type;
}
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
# define Py_SET_TYPE(ob, type) Py_SET_TYPE(_PyObject_CAST(ob), type)
#endif

static inline void Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) {
static inline void
_Py_SET_SIZE_impl(PyVarObject *ob, Py_ssize_t size)
{
assert(Py_TYPE(_PyObject_CAST(ob)) != &PyLong_Type);
assert(Py_TYPE(_PyObject_CAST(ob)) != &PyBool_Type);
#ifdef Py_GIL_DISABLED
Expand All @@ -323,9 +308,31 @@ static inline void Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) {
ob->ob_size = size;
#endif
}
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
# define Py_SET_SIZE(ob, size) Py_SET_SIZE(_PyVarObject_CAST(ob), (size))

static inline void
Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
{
ob->ob_type = type;
}

#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < _Py_PACK_VERSION(3, 11)
// Non-limited API & limited API 3.11 & below: the user can omit casts
# define Py_TYPE(ob) _Py_TYPE_impl(_PyObject_CAST(ob))
# define Py_SIZE(ob) _Py_SIZE_impl(_PyObject_CAST(ob))
# define Py_IS_TYPE(ob, type) _Py_IS_TYPE_impl(_PyObject_CAST(ob), (type))
# define Py_SET_SIZE(ob, size) _Py_SET_SIZE_impl(_PyVarObject_CAST(ob), (size))
# define Py_SET_TYPE(ob, type) Py_SET_TYPE(_PyObject_CAST(ob), type)
#elif Py_LIMITED_API+0 < _Py_PACK_VERSION(3, 15)
# if Py_LIMITED_API+0 < _Py_PACK_VERSION(3, 14)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean >=?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, but I can expand the comments :)

// Py_TYPE() is a function call on Limited API 3.14 and newer
# define Py_TYPE(ob) _Py_TYPE_impl(ob)
# endif
// These are function calls on Limited API 3.15 and newer:
# define Py_SIZE(ob) _Py_SIZE_impl(ob)
# define Py_IS_TYPE(ob, type) _Py_IS_TYPE_impl((ob), (type))
# define Py_SET_SIZE(ob, size) _Py_SET_SIZE_impl((ob), (size))
#endif

#endif // !defined(_Py_OPAQUE_PYOBJECT)


Expand Down
3 changes: 3 additions & 0 deletions Lib/test/test_stable_abi_ctypes.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions Misc/stable_abi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2519,8 +2519,10 @@
added = '3.13'

[function.Py_TYPE]
# Before 3.14, this was a macro that accessed the PyObject member
added = '3.14'
[function.Py_REFCNT]
# Before 3.14, this was a macro that accessed the PyObject member
added = '3.14'
[function.PyIter_NextItem]
added = '3.14'
Expand Down Expand Up @@ -2606,3 +2608,12 @@
added = '3.15'
[const.PyABIInfo_FREETHREADING_AGNOSTIC]
added = '3.15'
[function.Py_SIZE]
# Before 3.15, this was a macro that accessed the PyObject member
added = '3.15'
[function.Py_IS_TYPE]
# Before 3.15, this was a macro that accessed the PyObject member
added = '3.15'
[function.Py_SET_SIZE]
# Before 3.15, this was a macro that accessed the PyObject member
added = '3.15'
31 changes: 13 additions & 18 deletions Objects/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -3361,24 +3361,6 @@ Py_GetConstantBorrowed(unsigned int constant_id)
return Py_GetConstant(constant_id);
}


// Py_TYPE() implementation for the stable ABI
#undef Py_TYPE
PyTypeObject*
Py_TYPE(PyObject *ob)
{
return _Py_TYPE(ob);
}


// Py_REFCNT() implementation for the stable ABI
#undef Py_REFCNT
Py_ssize_t
Py_REFCNT(PyObject *ob)
{
return _Py_REFCNT(ob);
}

int
PyUnstable_IsImmortal(PyObject *op)
{
Expand All @@ -3405,3 +3387,16 @@ _PyObject_VisitType(PyObject *op, visitproc visit, void *arg)
Py_VISIT(tp);
return 0;
}

// Implementations for the stable ABI
// Keep these at the end.
#undef Py_TYPE
#undef Py_REFCNT
#undef Py_SIZE
#undef Py_IS_TYPE
#undef Py_SET_SIZE
PyTypeObject* Py_TYPE(PyObject *ob) { return _Py_TYPE_impl(ob); }
Py_ssize_t Py_REFCNT(PyObject *ob) { return _Py_REFCNT(ob); }
Py_ssize_t Py_SIZE(PyObject *o) { return _Py_SIZE_impl(o); }
int Py_IS_TYPE(PyObject *o, PyTypeObject *t) { return _Py_IS_TYPE_impl(o, t); }
void Py_SET_SIZE(PyVarObject *o, Py_ssize_t s) { _Py_SET_SIZE_impl(o, s); }
3 changes: 3 additions & 0 deletions PC/python3dll.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading