mirror of
https://github.com/python/cpython.git
synced 2025-12-07 13:50:06 +00:00
gh-139165: Make Py_SIZE, Py_IS_TYPE,Py_ SET_SIZE regular functions in stable ABI (GH-139166)
* 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.
This commit is contained in:
parent
e6174ee981
commit
226011ba12
7 changed files with 92 additions and 61 deletions
3
Doc/data/stable_abi.dat
generated
3
Doc/data/stable_abi.dat
generated
|
|
@ -915,6 +915,7 @@ func,Py_GetPlatform,3.2,,
|
||||||
func,Py_GetRecursionLimit,3.2,,
|
func,Py_GetRecursionLimit,3.2,,
|
||||||
func,Py_GetVersion,3.2,,
|
func,Py_GetVersion,3.2,,
|
||||||
data,Py_HasFileSystemDefaultEncoding,3.2,,
|
data,Py_HasFileSystemDefaultEncoding,3.2,,
|
||||||
|
func,Py_IS_TYPE,3.15,,
|
||||||
func,Py_IncRef,3.2,,
|
func,Py_IncRef,3.2,,
|
||||||
func,Py_Initialize,3.2,,
|
func,Py_Initialize,3.2,,
|
||||||
func,Py_InitializeEx,3.2,,
|
func,Py_InitializeEx,3.2,,
|
||||||
|
|
@ -936,6 +937,8 @@ func,Py_REFCNT,3.14,,
|
||||||
macro,Py_RELATIVE_OFFSET,3.12,,
|
macro,Py_RELATIVE_OFFSET,3.12,,
|
||||||
func,Py_ReprEnter,3.2,,
|
func,Py_ReprEnter,3.2,,
|
||||||
func,Py_ReprLeave,3.2,,
|
func,Py_ReprLeave,3.2,,
|
||||||
|
func,Py_SET_SIZE,3.15,,
|
||||||
|
func,Py_SIZE,3.15,,
|
||||||
func,Py_SetProgramName,3.2,,
|
func,Py_SetProgramName,3.2,,
|
||||||
func,Py_SetPythonHome,3.2,,
|
func,Py_SetPythonHome,3.2,,
|
||||||
func,Py_SetRecursionLimit,3.2,,
|
func,Py_SetRecursionLimit,3.2,,
|
||||||
|
|
|
||||||
100
Include/object.h
100
Include/object.h
|
|
@ -140,12 +140,12 @@ struct _object {
|
||||||
# endif
|
# endif
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
Py_ssize_t ob_refcnt;
|
Py_ssize_t ob_refcnt; // part of stable ABI; do not change
|
||||||
#endif
|
#endif
|
||||||
_Py_ALIGNED_DEF(_PyObject_MIN_ALIGNMENT, char) _aligner;
|
_Py_ALIGNED_DEF(_PyObject_MIN_ALIGNMENT, char) _aligner;
|
||||||
};
|
};
|
||||||
|
|
||||||
PyTypeObject *ob_type;
|
PyTypeObject *ob_type; // part of stable ABI; do not change
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
// Objects that are not owned by any thread use a thread id (tid) of zero.
|
// Objects that are not owned by any thread use a thread id (tid) of zero.
|
||||||
|
|
@ -173,7 +173,7 @@ struct _object {
|
||||||
#ifndef _Py_OPAQUE_PYOBJECT
|
#ifndef _Py_OPAQUE_PYOBJECT
|
||||||
struct PyVarObject {
|
struct PyVarObject {
|
||||||
PyObject ob_base;
|
PyObject ob_base;
|
||||||
Py_ssize_t ob_size; /* Number of items in variable part */
|
Py_ssize_t ob_size; // Number of items in variable part. Part of stable ABI
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
typedef struct PyVarObject PyVarObject;
|
typedef struct PyVarObject PyVarObject;
|
||||||
|
|
@ -265,56 +265,72 @@ _Py_IsOwnedByCurrentThread(PyObject *ob)
|
||||||
}
|
}
|
||||||
#endif
|
#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) PyLong_Type;
|
||||||
PyAPI_DATA(PyTypeObject) PyBool_Type;
|
PyAPI_DATA(PyTypeObject) PyBool_Type;
|
||||||
|
|
||||||
|
/* Definitions for the stable ABI */
|
||||||
|
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= _Py_PACK_VERSION(3, 14)
|
||||||
|
PyAPI_FUNC(PyTypeObject*) Py_TYPE(PyObject *ob);
|
||||||
|
#endif
|
||||||
|
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= _Py_PACK_VERSION(3, 15)
|
||||||
|
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);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef _Py_OPAQUE_PYOBJECT
|
#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 < _Py_PACK_VERSION(3, 11)
|
||||||
|
// Non-limited API & limited API 3.11 & below: use static inline functions and
|
||||||
|
// use _PyObject_CAST so that users don't need their own 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)
|
||||||
|
// Limited API 3.11-3.14: use static inline functions, without casts
|
||||||
|
# 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))
|
||||||
|
# if Py_LIMITED_API+0 < _Py_PACK_VERSION(3, 14)
|
||||||
|
// Py_TYPE() is static inline only on Limited API 3.13 and below
|
||||||
|
# define Py_TYPE(ob) _Py_TYPE_impl(ob)
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
// Limited API 3.15+: use function calls
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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.
|
// 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) != &PyLong_Type);
|
||||||
assert(Py_TYPE(ob) != &PyBool_Type);
|
assert(Py_TYPE(ob) != &PyBool_Type);
|
||||||
return _PyVarObject_CAST(ob)->ob_size;
|
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;
|
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
|
|
||||||
|
|
||||||
|
static inline void
|
||||||
#ifndef _Py_OPAQUE_PYOBJECT
|
_Py_SET_SIZE_impl(PyVarObject *ob, Py_ssize_t size)
|
||||||
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) {
|
|
||||||
assert(Py_TYPE(_PyObject_CAST(ob)) != &PyLong_Type);
|
assert(Py_TYPE(_PyObject_CAST(ob)) != &PyLong_Type);
|
||||||
assert(Py_TYPE(_PyObject_CAST(ob)) != &PyBool_Type);
|
assert(Py_TYPE(_PyObject_CAST(ob)) != &PyBool_Type);
|
||||||
#ifdef Py_GIL_DISABLED
|
#ifdef Py_GIL_DISABLED
|
||||||
|
|
@ -323,9 +339,7 @@ static inline void Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) {
|
||||||
ob->ob_size = size;
|
ob->ob_size = size;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
|
||||||
# define Py_SET_SIZE(ob, size) Py_SET_SIZE(_PyVarObject_CAST(ob), (size))
|
|
||||||
#endif
|
|
||||||
#endif // !defined(_Py_OPAQUE_PYOBJECT)
|
#endif // !defined(_Py_OPAQUE_PYOBJECT)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
3
Lib/test/test_stable_abi_ctypes.py
generated
3
Lib/test/test_stable_abi_ctypes.py
generated
|
|
@ -901,6 +901,7 @@ SYMBOL_NAMES = (
|
||||||
"Py_GetRecursionLimit",
|
"Py_GetRecursionLimit",
|
||||||
"Py_GetVersion",
|
"Py_GetVersion",
|
||||||
"Py_HasFileSystemDefaultEncoding",
|
"Py_HasFileSystemDefaultEncoding",
|
||||||
|
"Py_IS_TYPE",
|
||||||
"Py_IncRef",
|
"Py_IncRef",
|
||||||
"Py_Initialize",
|
"Py_Initialize",
|
||||||
"Py_InitializeEx",
|
"Py_InitializeEx",
|
||||||
|
|
@ -920,6 +921,8 @@ SYMBOL_NAMES = (
|
||||||
"Py_REFCNT",
|
"Py_REFCNT",
|
||||||
"Py_ReprEnter",
|
"Py_ReprEnter",
|
||||||
"Py_ReprLeave",
|
"Py_ReprLeave",
|
||||||
|
"Py_SET_SIZE",
|
||||||
|
"Py_SIZE",
|
||||||
"Py_SetPath",
|
"Py_SetPath",
|
||||||
"Py_SetProgramName",
|
"Py_SetProgramName",
|
||||||
"Py_SetPythonHome",
|
"Py_SetPythonHome",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
Expose the functions :c:func:`Py_SIZE`, :c:func:`Py_IS_TYPE` and
|
||||||
|
:c:func:`Py_SET_SIZE` in the Stable ABI.
|
||||||
|
|
@ -2524,8 +2524,10 @@
|
||||||
added = '3.13'
|
added = '3.13'
|
||||||
|
|
||||||
[function.Py_TYPE]
|
[function.Py_TYPE]
|
||||||
|
# Before 3.14, this was a macro that accessed the PyObject member
|
||||||
added = '3.14'
|
added = '3.14'
|
||||||
[function.Py_REFCNT]
|
[function.Py_REFCNT]
|
||||||
|
# Before 3.14, this was a macro that accessed the PyObject member
|
||||||
added = '3.14'
|
added = '3.14'
|
||||||
[function.PyIter_NextItem]
|
[function.PyIter_NextItem]
|
||||||
added = '3.14'
|
added = '3.14'
|
||||||
|
|
@ -2641,3 +2643,12 @@
|
||||||
added = '3.15'
|
added = '3.15'
|
||||||
[function.PyDict_SetDefaultRef]
|
[function.PyDict_SetDefaultRef]
|
||||||
added = '3.15'
|
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'
|
||||||
|
|
|
||||||
|
|
@ -3361,24 +3361,6 @@ Py_GetConstantBorrowed(unsigned int constant_id)
|
||||||
return Py_GetConstant(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
|
int
|
||||||
PyUnstable_IsImmortal(PyObject *op)
|
PyUnstable_IsImmortal(PyObject *op)
|
||||||
{
|
{
|
||||||
|
|
@ -3405,3 +3387,16 @@ _PyObject_VisitType(PyObject *op, visitproc visit, void *arg)
|
||||||
Py_VISIT(tp);
|
Py_VISIT(tp);
|
||||||
return 0;
|
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
PC/python3dll.c
generated
3
PC/python3dll.c
generated
|
|
@ -71,6 +71,7 @@ EXPORT_FUNC(Py_IncRef)
|
||||||
EXPORT_FUNC(Py_Initialize)
|
EXPORT_FUNC(Py_Initialize)
|
||||||
EXPORT_FUNC(Py_InitializeEx)
|
EXPORT_FUNC(Py_InitializeEx)
|
||||||
EXPORT_FUNC(Py_Is)
|
EXPORT_FUNC(Py_Is)
|
||||||
|
EXPORT_FUNC(Py_IS_TYPE)
|
||||||
EXPORT_FUNC(Py_IsFalse)
|
EXPORT_FUNC(Py_IsFalse)
|
||||||
EXPORT_FUNC(Py_IsFinalizing)
|
EXPORT_FUNC(Py_IsFinalizing)
|
||||||
EXPORT_FUNC(Py_IsInitialized)
|
EXPORT_FUNC(Py_IsInitialized)
|
||||||
|
|
@ -86,10 +87,12 @@ EXPORT_FUNC(Py_PACK_VERSION)
|
||||||
EXPORT_FUNC(Py_REFCNT)
|
EXPORT_FUNC(Py_REFCNT)
|
||||||
EXPORT_FUNC(Py_ReprEnter)
|
EXPORT_FUNC(Py_ReprEnter)
|
||||||
EXPORT_FUNC(Py_ReprLeave)
|
EXPORT_FUNC(Py_ReprLeave)
|
||||||
|
EXPORT_FUNC(Py_SET_SIZE)
|
||||||
EXPORT_FUNC(Py_SetPath)
|
EXPORT_FUNC(Py_SetPath)
|
||||||
EXPORT_FUNC(Py_SetProgramName)
|
EXPORT_FUNC(Py_SetProgramName)
|
||||||
EXPORT_FUNC(Py_SetPythonHome)
|
EXPORT_FUNC(Py_SetPythonHome)
|
||||||
EXPORT_FUNC(Py_SetRecursionLimit)
|
EXPORT_FUNC(Py_SetRecursionLimit)
|
||||||
|
EXPORT_FUNC(Py_SIZE)
|
||||||
EXPORT_FUNC(Py_TYPE)
|
EXPORT_FUNC(Py_TYPE)
|
||||||
EXPORT_FUNC(Py_VaBuildValue)
|
EXPORT_FUNC(Py_VaBuildValue)
|
||||||
EXPORT_FUNC(Py_XNewRef)
|
EXPORT_FUNC(Py_XNewRef)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue