mirror of
https://github.com/python/cpython.git
synced 2025-07-23 03:05:38 +00:00
gh-89653: PEP 670: Functions don't cast pointers (#91697)
In the limited C API version 3.11 and newer, the following functions no longer cast their object pointer argument with _PyObject_CAST() or _PyObject_CAST_CONST(): * Py_REFCNT(), Py_TYPE(), Py_SIZE() * Py_SET_REFCNT(), Py_SET_TYPE(), Py_SET_SIZE() * Py_IS_TYPE() * Py_INCREF(), Py_DECREF() * Py_XINCREF(), Py_XDECREF() * Py_NewRef(), Py_XNewRef() * PyObject_TypeCheck() * PyType_Check() * PyType_CheckExact() Split Py_DECREF() implementation in 3 versions to make the code more readable. Update the xxlimited.c extension, which uses the limited C API version 3.11, to pass PyObject* to these functions.
This commit is contained in:
parent
1cd8c29dac
commit
61381d7da1
3 changed files with 119 additions and 56 deletions
101
Include/object.h
101
Include/object.h
|
@ -123,44 +123,58 @@ PyAPI_FUNC(int) Py_Is(PyObject *x, PyObject *y);
|
|||
static inline Py_ssize_t Py_REFCNT(PyObject *ob) {
|
||||
return ob->ob_refcnt;
|
||||
}
|
||||
#define Py_REFCNT(ob) Py_REFCNT(_PyObject_CAST(ob))
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
||||
# define Py_REFCNT(ob) Py_REFCNT(_PyObject_CAST(ob))
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-39573: The Py_SET_TYPE() function must be used to set an object type.
|
||||
static inline PyTypeObject* Py_TYPE(PyObject *ob) {
|
||||
return ob->ob_type;
|
||||
}
|
||||
#define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
||||
# define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
|
||||
#endif
|
||||
|
||||
// bpo-39573: The Py_SET_SIZE() function must be used to set an object size.
|
||||
static inline Py_ssize_t Py_SIZE(PyVarObject *ob) {
|
||||
return ob->ob_size;
|
||||
}
|
||||
#define Py_SIZE(ob) Py_SIZE(_PyVarObject_CAST(ob))
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
||||
# define Py_SIZE(ob) Py_SIZE(_PyVarObject_CAST(ob))
|
||||
#endif
|
||||
|
||||
|
||||
static inline int Py_IS_TYPE(PyObject *ob, PyTypeObject *type) {
|
||||
return Py_TYPE(ob) == type;
|
||||
}
|
||||
#define Py_IS_TYPE(ob, type) Py_IS_TYPE(_PyObject_CAST(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 Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) {
|
||||
ob->ob_refcnt = refcnt;
|
||||
}
|
||||
#define Py_SET_REFCNT(ob, refcnt) Py_SET_REFCNT(_PyObject_CAST(ob), refcnt)
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
||||
# define Py_SET_REFCNT(ob, refcnt) Py_SET_REFCNT(_PyObject_CAST(ob), refcnt)
|
||||
#endif
|
||||
|
||||
|
||||
static inline void Py_SET_TYPE(PyObject *ob, PyTypeObject *type) {
|
||||
ob->ob_type = type;
|
||||
}
|
||||
#define Py_SET_TYPE(ob, type) Py_SET_TYPE(_PyObject_CAST(ob), 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) {
|
||||
ob->ob_size = size;
|
||||
}
|
||||
#define Py_SET_SIZE(ob, size) Py_SET_SIZE(_PyVarObject_CAST(ob), size)
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
||||
# define Py_SET_SIZE(ob, size) Py_SET_SIZE(_PyVarObject_CAST(ob), size)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -247,7 +261,9 @@ PyAPI_FUNC(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *);
|
|||
static inline int PyObject_TypeCheck(PyObject *ob, PyTypeObject *type) {
|
||||
return Py_IS_TYPE(ob, type) || PyType_IsSubtype(Py_TYPE(ob), type);
|
||||
}
|
||||
#define PyObject_TypeCheck(ob, type) PyObject_TypeCheck(_PyObject_CAST(ob), type)
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
||||
# define PyObject_TypeCheck(ob, type) PyObject_TypeCheck(_PyObject_CAST(ob), type)
|
||||
#endif
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyType_Type; /* built-in 'type' */
|
||||
PyAPI_DATA(PyTypeObject) PyBaseObject_Type; /* built-in 'object' */
|
||||
|
@ -485,39 +501,43 @@ static inline void Py_INCREF(PyObject *op)
|
|||
op->ob_refcnt++;
|
||||
#endif
|
||||
}
|
||||
#define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
||||
# define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
|
||||
#endif
|
||||
|
||||
|
||||
static inline void Py_DECREF(
|
||||
#if defined(Py_REF_DEBUG) && !(defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030A0000)
|
||||
const char *filename, int lineno,
|
||||
#endif
|
||||
PyObject *op)
|
||||
{
|
||||
#if defined(Py_REF_DEBUG) && defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030A0000
|
||||
// Stable ABI for Python 3.10 built in debug mode.
|
||||
// Stable ABI for limited C API version 3.10 of Python debug build
|
||||
static inline void Py_DECREF(PyObject *op) {
|
||||
_Py_DecRef(op);
|
||||
#else
|
||||
// Non-limited C API and limited C API for Python 3.9 and older access
|
||||
// directly PyObject.ob_refcnt.
|
||||
#ifdef Py_REF_DEBUG
|
||||
}
|
||||
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
|
||||
|
||||
#elif defined(Py_REF_DEBUG)
|
||||
static inline void Py_DECREF(const char *filename, int lineno, PyObject *op)
|
||||
{
|
||||
_Py_RefTotal--;
|
||||
#endif
|
||||
if (--op->ob_refcnt != 0) {
|
||||
#ifdef Py_REF_DEBUG
|
||||
if (op->ob_refcnt < 0) {
|
||||
_Py_NegativeRefcount(filename, lineno, op);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
_Py_Dealloc(op);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if defined(Py_REF_DEBUG) && !(defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030A0000)
|
||||
# define Py_DECREF(op) Py_DECREF(__FILE__, __LINE__, _PyObject_CAST(op))
|
||||
#define Py_DECREF(op) Py_DECREF(__FILE__, __LINE__, _PyObject_CAST(op))
|
||||
|
||||
#else
|
||||
# define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
|
||||
static inline void Py_DECREF(PyObject *op)
|
||||
{
|
||||
// Non-limited C API and limited C API for Python 3.9 and older access
|
||||
// directly PyObject.ob_refcnt.
|
||||
if (--op->ob_refcnt == 0) {
|
||||
_Py_Dealloc(op);
|
||||
}
|
||||
}
|
||||
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -571,8 +591,9 @@ static inline void Py_XINCREF(PyObject *op)
|
|||
Py_INCREF(op);
|
||||
}
|
||||
}
|
||||
|
||||
#define Py_XINCREF(op) Py_XINCREF(_PyObject_CAST(op))
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
||||
# define Py_XINCREF(op) Py_XINCREF(_PyObject_CAST(op))
|
||||
#endif
|
||||
|
||||
static inline void Py_XDECREF(PyObject *op)
|
||||
{
|
||||
|
@ -580,8 +601,9 @@ static inline void Py_XDECREF(PyObject *op)
|
|||
Py_DECREF(op);
|
||||
}
|
||||
}
|
||||
|
||||
#define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
||||
# define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
|
||||
#endif
|
||||
|
||||
// Create a new strong reference to an object:
|
||||
// increment the reference count of the object and return the object.
|
||||
|
@ -605,8 +627,13 @@ static inline PyObject* _Py_XNewRef(PyObject *obj)
|
|||
// Py_NewRef() and Py_XNewRef() are exported as functions for the stable ABI.
|
||||
// Names overridden with macros by static inline functions for best
|
||||
// performances.
|
||||
#define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
|
||||
#define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj))
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
||||
# define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
|
||||
# define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj))
|
||||
#else
|
||||
# define Py_NewRef(obj) _Py_NewRef(obj)
|
||||
# define Py_XNewRef(obj) _Py_XNewRef(obj)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -749,14 +776,18 @@ PyType_HasFeature(PyTypeObject *type, unsigned long feature)
|
|||
static inline int PyType_Check(PyObject *op) {
|
||||
return PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS);
|
||||
}
|
||||
#define PyType_Check(op) PyType_Check(_PyObject_CAST(op))
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
||||
# define PyType_Check(op) PyType_Check(_PyObject_CAST(op))
|
||||
#endif
|
||||
|
||||
#define _PyType_CAST(op) (assert(PyType_Check(op)), (PyTypeObject*)(op))
|
||||
|
||||
static inline int PyType_CheckExact(PyObject *op) {
|
||||
return Py_IS_TYPE(op, &PyType_Type);
|
||||
}
|
||||
#define PyType_CheckExact(op) PyType_CheckExact(_PyObject_CAST(op))
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
||||
# define PyType_CheckExact(op) PyType_CheckExact(_PyObject_CAST(op))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue