[Python-checkins] bpo-39573: Convert Py_TYPE() and Py_SIZE() back to macros (GH-23366)

vstinner webhook-mailer at python.org
Wed Nov 18 12:48:16 EST 2020


https://github.com/python/cpython/commit/0e2ac21dd4960574e89561243763eabba685296a
commit: 0e2ac21dd4960574e89561243763eabba685296a
branch: master
author: Victor Stinner <vstinner at python.org>
committer: vstinner <vstinner at python.org>
date: 2020-11-18T18:48:06+01:00
summary:

bpo-39573: Convert Py_TYPE() and Py_SIZE() back to macros (GH-23366)

This change partically reverts
commit ad3252bad905d41635bcbb4b76db30d570cf0087
and the commit fe2978b3b940fe2478335e3a2ca5ad22338cdf9c.

Many third party C extension modules rely on the ability of using
Py_TYPE() to set an object type: "Py_TYPE(obj) = type;" or to set an
object type using: "Py_SIZE(obj) = size;".

files:
A Misc/NEWS.d/next/C API/2020-11-18-15-21-59.bpo-39573.VB3G2y.rst
M Doc/c-api/structures.rst
M Doc/whatsnew/3.10.rst
M Include/object.h
M Modules/_testcapimodule.c

diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst
index 37602ed5b4dc7..37072d30d5715 100644
--- a/Doc/c-api/structures.rst
+++ b/Doc/c-api/structures.rst
@@ -68,9 +68,7 @@ the definition of all other Python objects.
 
    Return a :term:`borrowed reference`.
 
-   .. versionchanged:: 3.10
-      :c:func:`Py_TYPE()` is changed to the inline static function.
-      Use :c:func:`Py_SET_TYPE()` to set an object type.
+   The :c:func:`Py_SET_TYPE` function must be used to set an object type.
 
 
 .. c:function:: int Py_IS_TYPE(PyObject *o, PyTypeObject *type)
@@ -108,9 +106,7 @@ the definition of all other Python objects.
 
    Get the size of the Python object *o*.
 
-   .. versionchanged:: 3.10
-      :c:func:`Py_SIZE()` is changed to the inline static function.
-      Use :c:func:`Py_SET_SIZE()` to set an object size.
+   The :c:func:`Py_SET_SIZE` function must be used to set an object size.
 
 
 .. c:function:: void Py_SET_SIZE(PyVarObject *o, Py_ssize_t size)
diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst
index 41252b8e0ab01..cfb0383180f99 100644
--- a/Doc/whatsnew/3.10.rst
+++ b/Doc/whatsnew/3.10.rst
@@ -489,17 +489,6 @@ Porting to Python 3.10
   <arg-parsing>` and the :pep:`353`.
   (Contributed by Victor Stinner in :issue:`40943`.)
 
-* Since :c:func:`Py_TYPE()` is changed to the inline static function,
-  ``Py_TYPE(obj) = new_type`` must be replaced with ``Py_SET_TYPE(obj, new_type)``:
-  see :c:func:`Py_SET_TYPE()` (available since Python 3.9). For backward
-  compatibility, this macro can be used::
-
-      #if PY_VERSION_HEX < 0x030900A4
-      #  define Py_SET_TYPE(obj, type) ((Py_TYPE(obj) = (type)), (void)0)
-      #endif
-
-  (Contributed by Dong-hee Na in :issue:`39573`.)
-
 * Since :c:func:`Py_REFCNT()` is changed to the inline static function,
   ``Py_REFCNT(obj) = new_refcnt`` must be replaced with ``Py_SET_REFCNT(obj, new_refcnt)``:
   see :c:func:`Py_SET_REFCNT()` (available since Python 3.9). For backward
diff --git a/Include/object.h b/Include/object.h
index dd1b217686717..f68423a09c4e4 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -128,16 +128,11 @@ static inline Py_ssize_t _Py_REFCNT(const PyObject *ob) {
 #define Py_REFCNT(ob) _Py_REFCNT(_PyObject_CAST_CONST(ob))
 
 
-static inline Py_ssize_t _Py_SIZE(const PyVarObject *ob) {
-    return ob->ob_size;
-}
-#define Py_SIZE(ob) _Py_SIZE(_PyVarObject_CAST_CONST(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 int _Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) {
diff --git a/Misc/NEWS.d/next/C API/2020-11-18-15-21-59.bpo-39573.VB3G2y.rst b/Misc/NEWS.d/next/C API/2020-11-18-15-21-59.bpo-39573.VB3G2y.rst
new file mode 100644
index 0000000000000..b4fade6e202ed
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2020-11-18-15-21-59.bpo-39573.VB3G2y.rst	
@@ -0,0 +1,4 @@
+Convert :c:func:`Py_TYPE` and :c:func:`Py_SIZE` back to macros to allow
+using them as an l-value. Many third party C extension modules rely on the
+ability of using Py_TYPE() and Py_SIZE() to set an object type and size:
+``Py_TYPE(obj) = type;`` and ``Py_SIZE(obj) = size;``.
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 7b6da1e4c9055..a1d4c929b0205 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -5612,6 +5612,30 @@ pynumber_tobase(PyObject *module, PyObject *args)
 
 static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *);
 
+
+static PyObject*
+test_set_type_size(PyObject* self, PyObject* ignored)
+{
+    PyObject *obj = PyList_New(0);
+    if (obj == NULL) {
+        return NULL;
+    }
+
+    // Ensure that following tests don't modify the object,
+    // to ensure that Py_DECREF() will not crash.
+    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;
+
+    Py_DECREF(obj);
+    Py_RETURN_NONE;
+}
+
+
 static PyMethodDef TestMethods[] = {
     {"raise_exception",         raise_exception,                 METH_VARARGS},
     {"raise_memoryerror",       raise_memoryerror,               METH_NOARGS},
@@ -5883,6 +5907,7 @@ static PyMethodDef TestMethods[] = {
     {"meth_fastcall_keywords", (PyCFunction)(void(*)(void))meth_fastcall_keywords, METH_FASTCALL|METH_KEYWORDS},
     {"pynumber_tobase", pynumber_tobase, METH_VARARGS},
     {"without_gc", without_gc, METH_O},
+    {"test_set_type_size", test_set_type_size, METH_NOARGS},
     {NULL, NULL} /* sentinel */
 };
 



More information about the Python-checkins mailing list