]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-39573: Py_TYPE becomes a static inline function (GH-26493)
authorVictor Stinner <vstinner@python.org>
Thu, 3 Jun 2021 16:42:59 +0000 (18:42 +0200)
committerGitHub <noreply@github.com>
Thu, 3 Jun 2021 16:42:59 +0000 (18:42 +0200)
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.

Doc/c-api/structures.rst
Doc/whatsnew/3.11.rst
Include/object.h
Misc/NEWS.d/next/C API/2021-06-03-00-59-48.bpo-39573.-elHTJ.rst [new file with mode: 0644]
Modules/_testcapimodule.c

index 20d5485d5544c2241b24aece5fbb298aae688268..1a6e14eae59239aee01da9aac44c2cbf52fe924c 100644 (file)
@@ -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)
@@ -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)
@@ -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)
index 1b3b8240a521f2feb85564bf1cc48931e754b4f0..1ea8cbaf9a82a33fcf03df49a6b78be9e0fcde75 100644 (file)
@@ -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
 ----------
 
index 4c069998574b4a39f432b108e1741329cc677e73..a3b5d0d29d3e7b8515c8b89c7bee937782aa3e1f 100644 (file)
@@ -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) {
diff --git a/Misc/NEWS.d/next/C API/2021-06-03-00-59-48.bpo-39573.-elHTJ.rst b/Misc/NEWS.d/next/C API/2021-06-03-00-59-48.bpo-39573.-elHTJ.rst
new file mode 100644 (file)
index 0000000..d9641ed
--- /dev/null
@@ -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.
index ab47949d89e6351027b4faa8c0330c80b44d01df..9b106a566373722eb65d7507a3a41a63048ac217 100644 (file)
@@ -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;