Skip to content

Commit

Permalink
bpo-39573: Py_TYPE becomes a static inline function (GH-26493)
Browse files Browse the repository at this point in the history
Convert the Py_TYPE() and Py_SIZE() macros to static inline
functions. The Py_SET_TYPE() and Py_SET_SIZE() functions must now be
used to set an object type and size.
  • Loading branch information
vstinner committed Jun 3, 2021
1 parent d88b47b commit f3fa63e
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 9 deletions.
13 changes: 10 additions & 3 deletions Doc/c-api/structures.rst
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,10 @@ the definition of all other Python objects.
Return a :term:`borrowed reference`.
The :c:func:`Py_SET_TYPE` function must be used to set an object type.
Use the :c:func:`Py_SET_TYPE` function to set an object type.
.. versionchanged:: 3.11
:c:func:`Py_TYPE()` is changed to an inline static function.
.. c:function:: int Py_IS_TYPE(PyObject *o, PyTypeObject *type)
Expand All @@ -121,9 +124,10 @@ the definition of all other Python objects.
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.10
:c:func:`Py_REFCNT()` is changed to the inline static function.
Use :c:func:`Py_SET_REFCNT()` to set an object reference count.
.. c:function:: void Py_SET_REFCNT(PyObject *o, Py_ssize_t refcnt)
Expand All @@ -137,7 +141,10 @@ the definition of all other Python objects.
Get the size of the Python object *o*.
The :c:func:`Py_SET_SIZE` function must be used to set an object size.
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.
.. c:function:: void Py_SET_SIZE(PyVarObject *o, Py_ssize_t size)
Expand Down
28 changes: 28 additions & 0 deletions Doc/whatsnew/3.11.rst
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,34 @@ Porting to Python 3.11
(:c:member:`PyTypeObject.tp_traverse`).
(Contributed by Victor Stinner in :issue:`44263`.)

* Since :c:func:`Py_TYPE()` is changed to a inline static function,
``Py_TYPE(obj) = new_type`` must be replaced with
``Py_SET_TYPE(obj, new_type)``: see the :c:func:`Py_SET_TYPE()` function
(available since Python 3.9). For backward compatibility, this macro can be
used::

#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE)
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)
#endif

(Contributed by Victor Stinner in :issue:`39573`.)

* Since :c:func:`Py_SIZE()` is changed to a inline static function,
``Py_SIZE(obj) = new_size`` must be replaced with
``Py_SET_SIZE(obj, new_size)``: see the :c:func:`Py_SET_SIZE()` function
(available since Python 3.9). For backward compatibility, this macro can be
used::

#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE)
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*)(ob), size)
#endif

(Contributed by Victor Stinner in :issue:`39573`.)

Deprecated
----------

Expand Down
10 changes: 8 additions & 2 deletions Include/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,16 @@ static inline Py_ssize_t _Py_REFCNT(const PyObject *ob) {


// bpo-39573: The Py_SET_TYPE() function must be used to set an object type.
#define Py_TYPE(ob) (_PyObject_CAST(ob)->ob_type)
static inline PyTypeObject* _Py_TYPE(const PyObject *ob) {
return ob->ob_type;
}
#define Py_TYPE(ob) _Py_TYPE(_PyObject_CAST_CONST(ob))

// bpo-39573: The Py_SET_SIZE() function must be used to set an object size.
#define Py_SIZE(ob) (_PyVarObject_CAST(ob)->ob_size)
static inline Py_ssize_t _Py_SIZE(const PyVarObject *ob) {
return ob->ob_size;
}
#define Py_SIZE(ob) _Py_SIZE(_PyVarObject_CAST_CONST(ob))


static inline int _Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Convert the :c:func:`Py_TYPE` and :c:func:`Py_SIZE` macros to static inline
functions. The :c:func:`Py_SET_TYPE` and :c:func:`Py_SET_SIZE` functions
must now be used to set an object type and size. Patch by Victor Stinner.
7 changes: 3 additions & 4 deletions Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -5423,10 +5423,9 @@ test_set_type_size(PyObject *self, PyObject *Py_UNUSED(ignored))
assert(Py_TYPE(obj) == &PyList_Type);
assert(Py_SIZE(obj) == 0);

// bpo-39573: Check that Py_TYPE() and Py_SIZE() can be used
// as l-values to set an object type and size.
Py_TYPE(obj) = &PyList_Type;
Py_SIZE(obj) = 0;
// bpo-39573: Test Py_SET_TYPE() and Py_SET_SIZE() functions.
Py_SET_TYPE(obj, &PyList_Type);
Py_SET_SIZE(obj, 0);

Py_DECREF(obj);
Py_RETURN_NONE;
Expand Down

0 comments on commit f3fa63e

Please sign in to comment.