From eaa85cb22fa2d9e7cd31c2eac29a56cd3a8f2f65 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 21 Apr 2022 22:07:19 +0200 Subject: [PATCH] gh-91768: C API no longer use "const PyObject*" type (#91769) Py_REFCNT(), Py_TYPE(), Py_SIZE() and Py_IS_TYPE() functions argument type is now "PyObject*", rather than "const PyObject*". * Replace also "const PyObject*" with "PyObject*" in functions: * _Py_strhex_impl() * _Py_strhex_with_sep() * _Py_strhex_bytes_with_sep() * Remove _PyObject_CAST_CONST() and _PyVarObject_CAST_CONST() macros. * Py_IS_TYPE() can now use Py_TYPE() in its implementation. --- Doc/c-api/structures.rst | 19 ++++++++++------ Include/internal/pycore_strhex.h | 4 ++-- Include/object.h | 22 ++++++++----------- ...2-04-21-01-48-22.gh-issue-91768.x_aKzv.rst | 3 +++ Python/pystrhex.c | 10 +++++---- 5 files changed, 32 insertions(+), 26 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2022-04-21-01-48-22.gh-issue-91768.x_aKzv.rst diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index aa74f6cce1a..ff5ecf24072 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -62,14 +62,14 @@ the definition of all other Python objects. See documentation of :c:type:`PyVarObject` above. -.. c:function:: int Py_Is(const PyObject *x, const PyObject *y) +.. c:function:: int Py_Is(PyObject *x, PyObject *y) Test if the *x* object is the *y* object, the same as ``x is y`` in Python. .. versionadded:: 3.10 -.. c:function:: int Py_IsNone(const PyObject *x) +.. c:function:: int Py_IsNone(PyObject *x) Test if an object is the ``None`` singleton, the same as ``x is None`` in Python. @@ -77,7 +77,7 @@ the definition of all other Python objects. .. versionadded:: 3.10 -.. c:function:: int Py_IsTrue(const PyObject *x) +.. c:function:: int Py_IsTrue(PyObject *x) Test if an object is the ``True`` singleton, the same as ``x is True`` in Python. @@ -85,7 +85,7 @@ the definition of all other Python objects. .. versionadded:: 3.10 -.. c:function:: int Py_IsFalse(const PyObject *x) +.. c:function:: int Py_IsFalse(PyObject *x) Test if an object is the ``False`` singleton, the same as ``x is False`` in Python. @@ -93,7 +93,7 @@ the definition of all other Python objects. .. versionadded:: 3.10 -.. c:function:: PyTypeObject* Py_TYPE(const PyObject *o) +.. c:function:: PyTypeObject* Py_TYPE(PyObject *o) Get the type of the Python object *o*. @@ -103,6 +103,7 @@ the definition of all other Python objects. .. versionchanged:: 3.11 :c:func:`Py_TYPE()` is changed to an inline static function. + The parameter type is no longer :c:type:`const PyObject*`. .. c:function:: int Py_IS_TYPE(PyObject *o, PyTypeObject *type) @@ -120,12 +121,15 @@ the definition of all other Python objects. .. versionadded:: 3.9 -.. c:function:: Py_ssize_t Py_REFCNT(const PyObject *o) +.. c:function:: Py_ssize_t Py_REFCNT(PyObject *o) Get the reference count of the Python object *o*. Use the :c:func:`Py_SET_REFCNT()` function to set an object reference count. + .. versionchanged:: 3.11 + The parameter type is no longer :c:type:`const PyObject*`. + .. versionchanged:: 3.10 :c:func:`Py_REFCNT()` is changed to the inline static function. @@ -137,7 +141,7 @@ the definition of all other Python objects. .. versionadded:: 3.9 -.. c:function:: Py_ssize_t Py_SIZE(const PyVarObject *o) +.. c:function:: Py_ssize_t Py_SIZE(PyVarObject *o) Get the size of the Python object *o*. @@ -145,6 +149,7 @@ the definition of all other Python objects. .. versionchanged:: 3.11 :c:func:`Py_SIZE()` is changed to an inline static function. + The parameter type is no longer :c:type:`const PyVarObject*`. .. c:function:: void Py_SET_SIZE(PyVarObject *o, Py_ssize_t size) diff --git a/Include/internal/pycore_strhex.h b/Include/internal/pycore_strhex.h index 1633671da0f..f427b4d695b 100644 --- a/Include/internal/pycore_strhex.h +++ b/Include/internal/pycore_strhex.h @@ -22,12 +22,12 @@ PyAPI_FUNC(PyObject*) _Py_strhex_bytes( PyAPI_FUNC(PyObject*) _Py_strhex_with_sep( const char* argbuf, const Py_ssize_t arglen, - const PyObject* sep, + PyObject* sep, const int bytes_per_group); PyAPI_FUNC(PyObject*) _Py_strhex_bytes_with_sep( const char* argbuf, const Py_ssize_t arglen, - const PyObject* sep, + PyObject* sep, const int bytes_per_group); #ifdef __cplusplus diff --git a/Include/object.h b/Include/object.h index 0b4b55ea1de..8a45ddbf605 100644 --- a/Include/object.h +++ b/Include/object.h @@ -105,7 +105,6 @@ struct _object { /* Cast argument to PyObject* type. */ #define _PyObject_CAST(op) ((PyObject*)(op)) -#define _PyObject_CAST_CONST(op) ((const PyObject*)(op)) typedef struct { PyObject ob_base; @@ -114,7 +113,6 @@ typedef struct { /* Cast argument to PyVarObject* type. */ #define _PyVarObject_CAST(op) ((PyVarObject*)(op)) -#define _PyVarObject_CAST_CONST(op) ((const PyVarObject*)(op)) // Test if the 'x' object is the 'y' object, the same as "x is y" in Python. @@ -122,31 +120,29 @@ PyAPI_FUNC(int) Py_Is(PyObject *x, PyObject *y); #define Py_Is(x, y) ((x) == (y)) -static inline Py_ssize_t Py_REFCNT(const PyObject *ob) { +static inline Py_ssize_t Py_REFCNT(PyObject *ob) { return ob->ob_refcnt; } -#define Py_REFCNT(ob) Py_REFCNT(_PyObject_CAST_CONST(ob)) +#define Py_REFCNT(ob) Py_REFCNT(_PyObject_CAST(ob)) // bpo-39573: The Py_SET_TYPE() function must be used to set an object type. -static inline PyTypeObject* Py_TYPE(const PyObject *ob) { +static inline PyTypeObject* Py_TYPE(PyObject *ob) { return ob->ob_type; } -#define Py_TYPE(ob) Py_TYPE(_PyObject_CAST_CONST(ob)) +#define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob)) // bpo-39573: The Py_SET_SIZE() function must be used to set an object size. -static inline Py_ssize_t Py_SIZE(const PyVarObject *ob) { +static inline Py_ssize_t Py_SIZE(PyVarObject *ob) { return ob->ob_size; } -#define Py_SIZE(ob) Py_SIZE(_PyVarObject_CAST_CONST(ob)) +#define Py_SIZE(ob) Py_SIZE(_PyVarObject_CAST(ob)) -static inline int Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) { - // bpo-44378: Don't use Py_TYPE() since Py_TYPE() requires a non-const - // object. - return ob->ob_type == type; +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_CONST(ob), type) +#define Py_IS_TYPE(ob, type) Py_IS_TYPE(_PyObject_CAST(ob), type) static inline void Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) { diff --git a/Misc/NEWS.d/next/C API/2022-04-21-01-48-22.gh-issue-91768.x_aKzv.rst b/Misc/NEWS.d/next/C API/2022-04-21-01-48-22.gh-issue-91768.x_aKzv.rst new file mode 100644 index 00000000000..43423069321 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-04-21-01-48-22.gh-issue-91768.x_aKzv.rst @@ -0,0 +1,3 @@ +:c:func:`Py_REFCNT`, :c:func:`Py_TYPE`, :c:func:`Py_SIZE` and +:c:func:`Py_IS_TYPE` functions argument type is now ``PyObject*``, rather +than ``const PyObject*``. Patch by Victor Stinner. diff --git a/Python/pystrhex.c b/Python/pystrhex.c index 880af44ea0e..e4f06d76639 100644 --- a/Python/pystrhex.c +++ b/Python/pystrhex.c @@ -5,7 +5,7 @@ #include // abs() static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen, - const PyObject* sep, int bytes_per_sep_group, + PyObject* sep, int bytes_per_sep_group, const int return_bytes) { assert(arglen >= 0); @@ -152,21 +152,23 @@ PyObject * _Py_strhex(const char* argbuf, const Py_ssize_t arglen) /* Same as above but returns a bytes() instead of str() to avoid the * need to decode the str() when bytes are needed. */ -PyObject * _Py_strhex_bytes(const char* argbuf, const Py_ssize_t arglen) +PyObject* _Py_strhex_bytes(const char* argbuf, const Py_ssize_t arglen) { return _Py_strhex_impl(argbuf, arglen, NULL, 0, 1); } /* These variants include support for a separator between every N bytes: */ -PyObject * _Py_strhex_with_sep(const char* argbuf, const Py_ssize_t arglen, const PyObject* sep, const int bytes_per_group) +PyObject* _Py_strhex_with_sep(const char* argbuf, const Py_ssize_t arglen, + PyObject* sep, const int bytes_per_group) { return _Py_strhex_impl(argbuf, arglen, sep, bytes_per_group, 0); } /* Same as above but returns a bytes() instead of str() to avoid the * need to decode the str() when bytes are needed. */ -PyObject * _Py_strhex_bytes_with_sep(const char* argbuf, const Py_ssize_t arglen, const PyObject* sep, const int bytes_per_group) +PyObject* _Py_strhex_bytes_with_sep(const char* argbuf, const Py_ssize_t arglen, + PyObject* sep, const int bytes_per_group) { return _Py_strhex_impl(argbuf, arglen, sep, bytes_per_group, 1); }