gh-89653: PEP 670: Macros always cast arguments in cpython/ (#93766)

Header files in the Include/cpython/ are only included if
the Py_LIMITED_API macro is not defined.
This commit is contained in:
Victor Stinner 2022-06-13 20:09:40 +02:00 committed by GitHub
parent c2007573dd
commit df22eec421
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 28 additions and 92 deletions

View file

@ -25,14 +25,10 @@ static inline char* PyByteArray_AS_STRING(PyObject *op)
} }
return _PyByteArray_empty_string; return _PyByteArray_empty_string;
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyByteArray_AS_STRING(self) PyByteArray_AS_STRING(_PyObject_CAST(self))
# define PyByteArray_AS_STRING(self) PyByteArray_AS_STRING(_PyObject_CAST(self))
#endif
static inline Py_ssize_t PyByteArray_GET_SIZE(PyObject *op) { static inline Py_ssize_t PyByteArray_GET_SIZE(PyObject *op) {
PyByteArrayObject *self = _PyByteArray_CAST(op); PyByteArrayObject *self = _PyByteArray_CAST(op);
return Py_SIZE(self); return Py_SIZE(self);
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyByteArray_GET_SIZE(self) PyByteArray_GET_SIZE(_PyObject_CAST(self))
# define PyByteArray_GET_SIZE(self) PyByteArray_GET_SIZE(_PyObject_CAST(self))
#endif

View file

@ -36,17 +36,13 @@ static inline char* PyBytes_AS_STRING(PyObject *op)
{ {
return _PyBytes_CAST(op)->ob_sval; return _PyBytes_CAST(op)->ob_sval;
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
# define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
#endif
static inline Py_ssize_t PyBytes_GET_SIZE(PyObject *op) { static inline Py_ssize_t PyBytes_GET_SIZE(PyObject *op) {
PyBytesObject *self = _PyBytes_CAST(op); PyBytesObject *self = _PyBytes_CAST(op);
return Py_SIZE(self); return Py_SIZE(self);
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyBytes_GET_SIZE(self) PyBytes_GET_SIZE(_PyObject_CAST(self))
# define PyBytes_GET_SIZE(self) PyBytes_GET_SIZE(_PyObject_CAST(self))
#endif
/* _PyBytes_Join(sep, x) is like sep.join(x). sep must be PyBytesObject*, /* _PyBytes_Join(sep, x) is like sep.join(x). sep must be PyBytesObject*,
x must be an iterable object. */ x must be an iterable object. */

View file

@ -27,9 +27,7 @@ static inline PyObject* PyCell_GET(PyObject *op) {
cell = _Py_CAST(PyCellObject*, op); cell = _Py_CAST(PyCellObject*, op);
return cell->ob_ref; return cell->ob_ref;
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030c0000 #define PyCell_GET(op) PyCell_GET(_PyObject_CAST(op))
# define PyCell_GET(op) PyCell_GET(_PyObject_CAST(op))
#endif
static inline void PyCell_SET(PyObject *op, PyObject *value) { static inline void PyCell_SET(PyObject *op, PyObject *value) {
PyCellObject *cell; PyCellObject *cell;
@ -37,9 +35,7 @@ static inline void PyCell_SET(PyObject *op, PyObject *value) {
cell = _Py_CAST(PyCellObject*, op); cell = _Py_CAST(PyCellObject*, op);
cell->ob_ref = value; cell->ob_ref = value;
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030c0000 #define PyCell_SET(op, value) PyCell_SET(_PyObject_CAST(op), (value))
# define PyCell_SET(op, value) PyCell_SET(_PyObject_CAST(op), (value))
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -52,9 +52,7 @@ static inline Py_ssize_t PyDict_GET_SIZE(PyObject *op) {
mp = _Py_CAST(PyDictObject*, op); mp = _Py_CAST(PyDictObject*, op);
return mp->ma_used; return mp->ma_used;
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030c0000 #define PyDict_GET_SIZE(op) PyDict_GET_SIZE(_PyObject_CAST(op))
# define PyDict_GET_SIZE(op) PyDict_GET_SIZE(_PyObject_CAST(op))
#endif
PyAPI_FUNC(int) _PyDict_Contains_KnownHash(PyObject *, PyObject *, Py_hash_t); PyAPI_FUNC(int) _PyDict_Contains_KnownHash(PyObject *, PyObject *, Py_hash_t);
PyAPI_FUNC(int) _PyDict_ContainsId(PyObject *, _Py_Identifier *); PyAPI_FUNC(int) _PyDict_ContainsId(PyObject *, _Py_Identifier *);

View file

@ -34,9 +34,7 @@ static inline Py_ssize_t PyList_GET_SIZE(PyObject *op) {
PyListObject *list = _PyList_CAST(op); PyListObject *list = _PyList_CAST(op);
return Py_SIZE(list); return Py_SIZE(list);
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyList_GET_SIZE(op) PyList_GET_SIZE(_PyObject_CAST(op))
# define PyList_GET_SIZE(op) PyList_GET_SIZE(_PyObject_CAST(op))
#endif
#define PyList_GET_ITEM(op, index) (_PyList_CAST(op)->ob_item[index]) #define PyList_GET_ITEM(op, index) (_PyList_CAST(op)->ob_item[index])
@ -45,7 +43,5 @@ PyList_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value) {
PyListObject *list = _PyList_CAST(op); PyListObject *list = _PyList_CAST(op);
list->ob_item[index] = value; list->ob_item[index] = value;
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
#define PyList_SET_ITEM(op, index, value) \ #define PyList_SET_ITEM(op, index, value) \
PyList_SET_ITEM(_PyObject_CAST(op), index, _PyObject_CAST(value)) PyList_SET_ITEM(_PyObject_CAST(op), index, _PyObject_CAST(value))
#endif

View file

@ -40,9 +40,7 @@ PyAPI_DATA(PyTypeObject) PyCMethod_Type;
static inline PyCFunction PyCFunction_GET_FUNCTION(PyObject *func) { static inline PyCFunction PyCFunction_GET_FUNCTION(PyObject *func) {
return _PyCFunctionObject_CAST(func)->m_ml->ml_meth; return _PyCFunctionObject_CAST(func)->m_ml->ml_meth;
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(_PyObject_CAST(func))
# define PyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(_PyObject_CAST(func))
#endif
static inline PyObject* PyCFunction_GET_SELF(PyObject *func_obj) { static inline PyObject* PyCFunction_GET_SELF(PyObject *func_obj) {
PyCFunctionObject *func = _PyCFunctionObject_CAST(func_obj); PyCFunctionObject *func = _PyCFunctionObject_CAST(func_obj);
@ -51,16 +49,12 @@ static inline PyObject* PyCFunction_GET_SELF(PyObject *func_obj) {
} }
return func->m_self; return func->m_self;
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyCFunction_GET_SELF(func) PyCFunction_GET_SELF(_PyObject_CAST(func))
# define PyCFunction_GET_SELF(func) PyCFunction_GET_SELF(_PyObject_CAST(func))
#endif
static inline int PyCFunction_GET_FLAGS(PyObject *func) { static inline int PyCFunction_GET_FLAGS(PyObject *func) {
return _PyCFunctionObject_CAST(func)->m_ml->ml_flags; return _PyCFunctionObject_CAST(func)->m_ml->ml_flags;
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyCFunction_GET_FLAGS(func) PyCFunction_GET_FLAGS(_PyObject_CAST(func))
# define PyCFunction_GET_FLAGS(func) PyCFunction_GET_FLAGS(_PyObject_CAST(func))
#endif
static inline PyTypeObject* PyCFunction_GET_CLASS(PyObject *func_obj) { static inline PyTypeObject* PyCFunction_GET_CLASS(PyObject *func_obj) {
PyCFunctionObject *func = _PyCFunctionObject_CAST(func_obj); PyCFunctionObject *func = _PyCFunctionObject_CAST(func_obj);
@ -69,6 +63,4 @@ static inline PyTypeObject* PyCFunction_GET_CLASS(PyObject *func_obj) {
} }
return _Py_NULL; return _Py_NULL;
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyCFunction_GET_CLASS(func) PyCFunction_GET_CLASS(_PyObject_CAST(func))
# define PyCFunction_GET_CLASS(func) PyCFunction_GET_CLASS(_PyObject_CAST(func))
#endif

View file

@ -23,9 +23,7 @@ static inline Py_ssize_t PyTuple_GET_SIZE(PyObject *op) {
PyTupleObject *tuple = _PyTuple_CAST(op); PyTupleObject *tuple = _PyTuple_CAST(op);
return Py_SIZE(tuple); return Py_SIZE(tuple);
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyTuple_GET_SIZE(op) PyTuple_GET_SIZE(_PyObject_CAST(op))
# define PyTuple_GET_SIZE(op) PyTuple_GET_SIZE(_PyObject_CAST(op))
#endif
#define PyTuple_GET_ITEM(op, index) (_PyTuple_CAST(op)->ob_item[index]) #define PyTuple_GET_ITEM(op, index) (_PyTuple_CAST(op)->ob_item[index])
@ -35,9 +33,7 @@ PyTuple_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value) {
PyTupleObject *tuple = _PyTuple_CAST(op); PyTupleObject *tuple = _PyTuple_CAST(op);
tuple->ob_item[index] = value; tuple->ob_item[index] = value;
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
#define PyTuple_SET_ITEM(op, index, value) \ #define PyTuple_SET_ITEM(op, index, value) \
PyTuple_SET_ITEM(_PyObject_CAST(op), index, _PyObject_CAST(value)) PyTuple_SET_ITEM(_PyObject_CAST(op), index, _PyObject_CAST(value))
#endif
PyAPI_FUNC(void) _PyTuple_DebugMallocStats(FILE *out); PyAPI_FUNC(void) _PyTuple_DebugMallocStats(FILE *out);

View file

@ -188,17 +188,13 @@ PyAPI_FUNC(int) _PyUnicode_CheckConsistency(
static inline unsigned int PyUnicode_CHECK_INTERNED(PyObject *op) { static inline unsigned int PyUnicode_CHECK_INTERNED(PyObject *op) {
return _PyASCIIObject_CAST(op)->state.interned; return _PyASCIIObject_CAST(op)->state.interned;
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyUnicode_CHECK_INTERNED(op) PyUnicode_CHECK_INTERNED(_PyObject_CAST(op))
# define PyUnicode_CHECK_INTERNED(op) PyUnicode_CHECK_INTERNED(_PyObject_CAST(op))
#endif
/* For backward compatibility */ /* For backward compatibility */
static inline unsigned int PyUnicode_IS_READY(PyObject* Py_UNUSED(op)) { static inline unsigned int PyUnicode_IS_READY(PyObject* Py_UNUSED(op)) {
return 1; return 1;
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyUnicode_IS_READY(op) PyUnicode_IS_READY(_PyObject_CAST(op))
# define PyUnicode_IS_READY(op) PyUnicode_IS_READY(_PyObject_CAST(op))
#endif
/* Return true if the string contains only ASCII characters, or 0 if not. The /* Return true if the string contains only ASCII characters, or 0 if not. The
string may be compact (PyUnicode_IS_COMPACT_ASCII) or not, but must be string may be compact (PyUnicode_IS_COMPACT_ASCII) or not, but must be
@ -206,27 +202,21 @@ static inline unsigned int PyUnicode_IS_READY(PyObject* Py_UNUSED(op)) {
static inline unsigned int PyUnicode_IS_ASCII(PyObject *op) { static inline unsigned int PyUnicode_IS_ASCII(PyObject *op) {
return _PyASCIIObject_CAST(op)->state.ascii; return _PyASCIIObject_CAST(op)->state.ascii;
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyUnicode_IS_ASCII(op) PyUnicode_IS_ASCII(_PyObject_CAST(op))
# define PyUnicode_IS_ASCII(op) PyUnicode_IS_ASCII(_PyObject_CAST(op))
#endif
/* Return true if the string is compact or 0 if not. /* Return true if the string is compact or 0 if not.
No type checks or Ready calls are performed. */ No type checks or Ready calls are performed. */
static inline unsigned int PyUnicode_IS_COMPACT(PyObject *op) { static inline unsigned int PyUnicode_IS_COMPACT(PyObject *op) {
return _PyASCIIObject_CAST(op)->state.compact; return _PyASCIIObject_CAST(op)->state.compact;
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyUnicode_IS_COMPACT(op) PyUnicode_IS_COMPACT(_PyObject_CAST(op))
# define PyUnicode_IS_COMPACT(op) PyUnicode_IS_COMPACT(_PyObject_CAST(op))
#endif
/* Return true if the string is a compact ASCII string (use PyASCIIObject /* Return true if the string is a compact ASCII string (use PyASCIIObject
structure), or 0 if not. No type checks or Ready calls are performed. */ structure), or 0 if not. No type checks or Ready calls are performed. */
static inline int PyUnicode_IS_COMPACT_ASCII(PyObject *op) { static inline int PyUnicode_IS_COMPACT_ASCII(PyObject *op) {
return (_PyASCIIObject_CAST(op)->state.ascii && PyUnicode_IS_COMPACT(op)); return (_PyASCIIObject_CAST(op)->state.ascii && PyUnicode_IS_COMPACT(op));
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyUnicode_IS_COMPACT_ASCII(op) PyUnicode_IS_COMPACT_ASCII(_PyObject_CAST(op))
# define PyUnicode_IS_COMPACT_ASCII(op) PyUnicode_IS_COMPACT_ASCII(_PyObject_CAST(op))
#endif
enum PyUnicode_Kind { enum PyUnicode_Kind {
/* Return values of the PyUnicode_KIND() function: */ /* Return values of the PyUnicode_KIND() function: */
@ -236,22 +226,14 @@ enum PyUnicode_Kind {
}; };
// PyUnicode_KIND(): Return one of the PyUnicode_*_KIND values defined above. // PyUnicode_KIND(): Return one of the PyUnicode_*_KIND values defined above.
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030c0000 //
// gh-89653: Converting this macro to a static inline function would introduce // gh-89653: Converting this macro to a static inline function would introduce
// new compiler warnings on "kind < PyUnicode_KIND(str)" (compare signed and // new compiler warnings on "kind < PyUnicode_KIND(str)" (compare signed and
// unsigned numbers) where kind type is an int or on // unsigned numbers) where kind type is an int or on
// "unsigned int kind = PyUnicode_KIND(str)" (cast signed to unsigned). // "unsigned int kind = PyUnicode_KIND(str)" (cast signed to unsigned).
// Only declare the function as static inline function in the limited C API // Only declare the function as static inline function in the limited C API
// version 3.12 which is stricter. // version 3.12 which is stricter.
#define PyUnicode_KIND(op) \ #define PyUnicode_KIND(op) (_PyASCIIObject_CAST(op)->state.kind)
(_PyASCIIObject_CAST(op)->state.kind)
#else
// Limited C API 3.12 and newer
static inline int PyUnicode_KIND(PyObject *op) {
assert(PyUnicode_IS_READY(op));
return _PyASCIIObject_CAST(op)->state.kind;
}
#endif
/* Return a void pointer to the raw unicode buffer. */ /* Return a void pointer to the raw unicode buffer. */
static inline void* _PyUnicode_COMPACT_DATA(PyObject *op) { static inline void* _PyUnicode_COMPACT_DATA(PyObject *op) {
@ -275,9 +257,7 @@ static inline void* PyUnicode_DATA(PyObject *op) {
} }
return _PyUnicode_NONCOMPACT_DATA(op); return _PyUnicode_NONCOMPACT_DATA(op);
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyUnicode_DATA(op) PyUnicode_DATA(_PyObject_CAST(op))
# define PyUnicode_DATA(op) PyUnicode_DATA(_PyObject_CAST(op))
#endif
/* Return pointers to the canonical representation cast to unsigned char, /* Return pointers to the canonical representation cast to unsigned char,
Py_UCS2, or Py_UCS4 for direct character access. Py_UCS2, or Py_UCS4 for direct character access.
@ -292,9 +272,7 @@ static inline void* PyUnicode_DATA(PyObject *op) {
static inline Py_ssize_t PyUnicode_GET_LENGTH(PyObject *op) { static inline Py_ssize_t PyUnicode_GET_LENGTH(PyObject *op) {
return _PyASCIIObject_CAST(op)->length; return _PyASCIIObject_CAST(op)->length;
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyUnicode_GET_LENGTH(op) PyUnicode_GET_LENGTH(_PyObject_CAST(op))
# define PyUnicode_GET_LENGTH(op) PyUnicode_GET_LENGTH(_PyObject_CAST(op))
#endif
/* Write into the canonical representation, this function does not do any sanity /* Write into the canonical representation, this function does not do any sanity
checks and is intended for usage in loops. The caller should cache the checks and is intended for usage in loops. The caller should cache the
@ -319,11 +297,9 @@ static inline void PyUnicode_WRITE(int kind, void *data,
_Py_STATIC_CAST(Py_UCS4*, data)[index] = value; _Py_STATIC_CAST(Py_UCS4*, data)[index] = value;
} }
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
#define PyUnicode_WRITE(kind, data, index, value) \ #define PyUnicode_WRITE(kind, data, index, value) \
PyUnicode_WRITE(_Py_STATIC_CAST(int, kind), _Py_CAST(void*, data), \ PyUnicode_WRITE(_Py_STATIC_CAST(int, kind), _Py_CAST(void*, data), \
(index), _Py_STATIC_CAST(Py_UCS4, value)) (index), _Py_STATIC_CAST(Py_UCS4, value))
#endif
/* Read a code point from the string's canonical representation. No checks /* Read a code point from the string's canonical representation. No checks
or ready calls are performed. */ or ready calls are performed. */
@ -340,12 +316,10 @@ static inline Py_UCS4 PyUnicode_READ(int kind,
assert(kind == PyUnicode_4BYTE_KIND); assert(kind == PyUnicode_4BYTE_KIND);
return _Py_STATIC_CAST(const Py_UCS4*, data)[index]; return _Py_STATIC_CAST(const Py_UCS4*, data)[index];
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
#define PyUnicode_READ(kind, data, index) \ #define PyUnicode_READ(kind, data, index) \
PyUnicode_READ(_Py_STATIC_CAST(int, kind), \ PyUnicode_READ(_Py_STATIC_CAST(int, kind), \
_Py_STATIC_CAST(const void*, data), \ _Py_STATIC_CAST(const void*, data), \
(index)) (index))
#endif
/* PyUnicode_READ_CHAR() is less efficient than PyUnicode_READ() because it /* PyUnicode_READ_CHAR() is less efficient than PyUnicode_READ() because it
calls PyUnicode_KIND() and might call it twice. For single reads, use calls PyUnicode_KIND() and might call it twice. For single reads, use
@ -369,10 +343,8 @@ static inline Py_UCS4 PyUnicode_READ_CHAR(PyObject *unicode, Py_ssize_t index)
assert(kind == PyUnicode_4BYTE_KIND); assert(kind == PyUnicode_4BYTE_KIND);
return PyUnicode_4BYTE_DATA(unicode)[index]; return PyUnicode_4BYTE_DATA(unicode)[index];
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyUnicode_READ_CHAR(unicode, index) \
# define PyUnicode_READ_CHAR(unicode, index) \
PyUnicode_READ_CHAR(_PyObject_CAST(unicode), (index)) PyUnicode_READ_CHAR(_PyObject_CAST(unicode), (index))
#endif
/* Return a maximum character value which is suitable for creating another /* Return a maximum character value which is suitable for creating another
string based on op. This is always an approximation but more efficient string based on op. This is always an approximation but more efficient
@ -395,10 +367,8 @@ static inline Py_UCS4 PyUnicode_MAX_CHAR_VALUE(PyObject *op)
assert(kind == PyUnicode_4BYTE_KIND); assert(kind == PyUnicode_4BYTE_KIND);
return 0x10ffffU; return 0x10ffffU;
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyUnicode_MAX_CHAR_VALUE(op) \
# define PyUnicode_MAX_CHAR_VALUE(op) \
PyUnicode_MAX_CHAR_VALUE(_PyObject_CAST(op)) PyUnicode_MAX_CHAR_VALUE(_PyObject_CAST(op))
#endif
/* === Public API ========================================================= */ /* === Public API ========================================================= */
@ -417,9 +387,7 @@ static inline int PyUnicode_READY(PyObject* Py_UNUSED(op))
{ {
return 0; return 0;
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyUnicode_READY(op) PyUnicode_READY(_PyObject_CAST(op))
# define PyUnicode_READY(op) PyUnicode_READY(_PyObject_CAST(op))
#endif
/* Get a copy of a Unicode string. */ /* Get a copy of a Unicode string. */
PyAPI_FUNC(PyObject*) _PyUnicode_Copy( PyAPI_FUNC(PyObject*) _PyUnicode_Copy(

View file

@ -53,6 +53,4 @@ static inline PyObject* PyWeakref_GET_OBJECT(PyObject *ref_obj) {
} }
return Py_None; return Py_None;
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyWeakref_GET_OBJECT(ref) PyWeakref_GET_OBJECT(_PyObject_CAST(ref))
# define PyWeakref_GET_OBJECT(ref) PyWeakref_GET_OBJECT(_PyObject_CAST(ref))
#endif