Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-91768: C API no longer use "const PyObject*" type #91769

Merged
merged 2 commits into from
Apr 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
19 changes: 12 additions & 7 deletions Doc/c-api/structures.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,38 +62,38 @@ 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.

.. 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.

.. 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.

.. 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*.

Expand All @@ -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)
Expand All @@ -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.

Expand All @@ -137,14 +141,15 @@ 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*.

Use the :c:func:`Py_SET_SIZE` function to set an object size.

.. 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)
Expand Down
4 changes: 2 additions & 2 deletions Include/internal/pycore_strhex.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 9 additions & 13 deletions Include/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -114,39 +113,36 @@ 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.
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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
10 changes: 6 additions & 4 deletions Python/pystrhex.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <stdlib.h> // 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);
Expand Down Expand Up @@ -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);
}