From 18ea973c21ee4a6adc26be41027881043fa498eb Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 28 Jan 2022 00:39:52 +0100 Subject: [PATCH] bpo-40170: Remove PyHeapType_GET_MEMBERS() macro (GH-30942) Remove the PyHeapType_GET_MEMBERS() macro. It was exposed in the public C API by mistake, it must only be used by Python internally. Use the PyTypeObject.tp_members member instead. Rename PyHeapType_GET_MEMBERS() to _PyHeapType_GET_MEMBERS() and move it to the internal C API. --- Doc/whatsnew/3.11.rst | 5 +++++ Include/cpython/object.h | 4 ---- Include/internal/pycore_object.h | 4 ++++ .../C API/2022-01-27-02-51-22.bpo-40170.uPolek.rst | 4 ++++ Objects/typeobject.c | 12 ++++++------ 5 files changed, 19 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2022-01-27-02-51-22.bpo-40170.uPolek.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index adf38b6b014..daa0a2af061 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -929,3 +929,8 @@ Removed worked since the :c:type:`PyWeakReference` structure is opaque in the limited C API. (Contributed by Victor Stinner in :issue:`35134`.) + +* Remove the ``PyHeapType_GET_MEMBERS()`` macro. It was exposed in the + public C API by mistake, it must only be used by Python internally. + Use the ``PyTypeObject.tp_members`` member instead. + (Contributed by Victor Stinner in :issue:`40170`.) diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 0c3957aff4b..7b9f3acbc43 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -293,10 +293,6 @@ typedef struct _heaptypeobject { /* here are optional user slots, followed by the members. */ } PyHeapTypeObject; -/* access macro to the members which are floating "behind" the object */ -#define PyHeapType_GET_MEMBERS(etype) \ - ((PyMemberDef *)(((char *)etype) + Py_TYPE(etype)->tp_basicsize)) - PyAPI_FUNC(const char *) _PyType_Name(PyTypeObject *); PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *); PyAPI_FUNC(PyObject *) _PyType_LookupId(PyTypeObject *, _Py_Identifier *); diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 5fe4ddb2efb..e2da2537c11 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -232,6 +232,10 @@ extern void _PyObject_FreeInstanceAttributes(PyObject *self); extern int _PyObject_IsInstanceDictEmpty(PyObject *); extern PyObject* _PyType_GetSubclasses(PyTypeObject *); +// Access macro to the members which are floating "behind" the object +#define _PyHeapType_GET_MEMBERS(etype) \ + ((PyMemberDef *)(((char *)etype) + Py_TYPE(etype)->tp_basicsize)) + #ifdef __cplusplus } #endif diff --git a/Misc/NEWS.d/next/C API/2022-01-27-02-51-22.bpo-40170.uPolek.rst b/Misc/NEWS.d/next/C API/2022-01-27-02-51-22.bpo-40170.uPolek.rst new file mode 100644 index 00000000000..6b185f0284e --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-01-27-02-51-22.bpo-40170.uPolek.rst @@ -0,0 +1,4 @@ +Remove the ``PyHeapType_GET_MEMBERS()`` macro. It was exposed in the public C +API by mistake, it must only be used by Python internally. Use the +``PyTypeObject.tp_members`` member instead. Patch by Victor Stinner. + diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 39e8b466ce8..621ad9745d8 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1209,7 +1209,7 @@ traverse_slots(PyTypeObject *type, PyObject *self, visitproc visit, void *arg) PyMemberDef *mp; n = Py_SIZE(type); - mp = PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); + mp = _PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); for (i = 0; i < n; i++, mp++) { if (mp->type == T_OBJECT_EX) { char *addr = (char *)self + mp->offset; @@ -1281,7 +1281,7 @@ clear_slots(PyTypeObject *type, PyObject *self) PyMemberDef *mp; n = Py_SIZE(type); - mp = PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); + mp = _PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); for (i = 0; i < n; i++, mp++) { if (mp->type == T_OBJECT_EX && !(mp->flags & READONLY)) { char *addr = (char *)self + mp->offset; @@ -2977,7 +2977,7 @@ type_new_descriptors(const type_new_ctx *ctx, PyTypeObject *type) PyHeapTypeObject *et = (PyHeapTypeObject *)type; Py_ssize_t slotoffset = ctx->base->tp_basicsize; if (et->ht_slots != NULL) { - PyMemberDef *mp = PyHeapType_GET_MEMBERS(et); + PyMemberDef *mp = _PyHeapType_GET_MEMBERS(et); Py_ssize_t nslot = PyTuple_GET_SIZE(et->ht_slots); for (Py_ssize_t i = 0; i < nslot; i++, mp++) { mp->name = PyUnicode_AsUTF8( @@ -3014,7 +3014,7 @@ type_new_descriptors(const type_new_ctx *ctx, PyTypeObject *type) type->tp_basicsize = slotoffset; type->tp_itemsize = ctx->base->tp_itemsize; - type->tp_members = PyHeapType_GET_MEMBERS(et); + type->tp_members = _PyHeapType_GET_MEMBERS(et); return 0; } @@ -3570,8 +3570,8 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) else if (slot->slot == Py_tp_members) { /* Move the slots to the heap type itself */ size_t len = Py_TYPE(type)->tp_itemsize * nmembers; - memcpy(PyHeapType_GET_MEMBERS(res), slot->pfunc, len); - type->tp_members = PyHeapType_GET_MEMBERS(res); + memcpy(_PyHeapType_GET_MEMBERS(res), slot->pfunc, len); + type->tp_members = _PyHeapType_GET_MEMBERS(res); } else { /* Copy other slots directly */