bpo-39573: Convert Py_TYPE() and Py_SIZE() back to macros (GH-23366)
This change partically reverts commitad3252bad9
and the commitfe2978b3b9
. 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;".
This commit is contained in:
parent
2156d964a1
commit
0e2ac21dd4
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;``.
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue