From 38aefc585f60a77d66f4fbe5a37594a488b53474 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 6 Apr 2020 14:07:02 +0200 Subject: [PATCH] bpo-40170: PyObject_GET_WEAKREFS_LISTPTR() becomes a function (GH-19377) Convert the PyObject_GET_WEAKREFS_LISTPTR() macro to a function to hide implementation details: the macro accessed directly to the PyTypeObject.tp_weaklistoffset member. Add _PyObject_GET_WEAKREFS_LISTPTR() static inline function to the internal C API. --- Include/cpython/objimpl.h | 3 +-- Include/internal/pycore_object.h | 7 +++++++ .../next/C API/2020-04-05-00-10-45.bpo-40170.6nFYbY.rst | 3 +++ Modules/_weakref.c | 3 ++- Modules/gcmodule.c | 2 +- Objects/object.c | 8 ++++++++ Objects/typeobject.c | 2 +- Objects/weakrefobject.c | 3 ++- 8 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2020-04-05-00-10-45.bpo-40170.6nFYbY.rst diff --git a/Include/cpython/objimpl.h b/Include/cpython/objimpl.h index 8e3c964cf44..2f802e92a6c 100644 --- a/Include/cpython/objimpl.h +++ b/Include/cpython/objimpl.h @@ -138,8 +138,7 @@ PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size); /* Test if a type supports weak references */ #define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0) -#define PyObject_GET_WEAKREFS_LISTPTR(o) \ - ((PyObject **) (((char *) (o)) + Py_TYPE(o)->tp_weaklistoffset)) +PyAPI_FUNC(PyObject **) PyObject_GET_WEAKREFS_LISTPTR(PyObject *op); #ifdef __cplusplus } diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 10a5746997e..002b70007b6 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -87,6 +87,13 @@ extern void _Py_PrintReferences(FILE *); extern void _Py_PrintReferenceAddresses(FILE *); #endif +static inline PyObject ** +_PyObject_GET_WEAKREFS_LISTPTR(PyObject *op) +{ + Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset; + return (PyObject **)((char *)op + offset); +} + #ifdef __cplusplus } #endif diff --git a/Misc/NEWS.d/next/C API/2020-04-05-00-10-45.bpo-40170.6nFYbY.rst b/Misc/NEWS.d/next/C API/2020-04-05-00-10-45.bpo-40170.6nFYbY.rst new file mode 100644 index 00000000000..3c4e33b9da1 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-04-05-00-10-45.bpo-40170.6nFYbY.rst @@ -0,0 +1,3 @@ +Convert the :c:func:`PyObject_GET_WEAKREFS_LISTPTR` macro to a function to hide +implementation details: the macro accessed directly to the +:c:member:`PyTypeObject.tp_weaklistoffset` member. diff --git a/Modules/_weakref.c b/Modules/_weakref.c index cd7c4c159ac..e33cba2a3dd 100644 --- a/Modules/_weakref.c +++ b/Modules/_weakref.c @@ -1,8 +1,9 @@ #include "Python.h" +#include "pycore_object.h" // _PyObject_GET_WEAKREFS_LISTPTR #define GET_WEAKREFS_LISTPTR(o) \ - ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o)) + ((PyWeakReference **) _PyObject_GET_WEAKREFS_LISTPTR(o)) /*[clinic input] module _weakref diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index cf164c17d7b..1bc41fb83d8 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -788,7 +788,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) /* It supports weakrefs. Does it have any? */ wrlist = (PyWeakReference **) - PyObject_GET_WEAKREFS_LISTPTR(op); + _PyObject_GET_WEAKREFS_LISTPTR(op); /* `op` may have some weakrefs. March over the list, clear * all the weakrefs, and move the weakrefs with callbacks diff --git a/Objects/object.c b/Objects/object.c index e6d0da1c775..05241e8a740 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2206,6 +2206,14 @@ _Py_Dealloc(PyObject *op) (*dealloc)(op); } + +PyObject ** +PyObject_GET_WEAKREFS_LISTPTR(PyObject *op) +{ + return _PyObject_GET_WEAKREFS_LISTPTR(op); +} + + #ifdef __cplusplus } #endif diff --git a/Objects/typeobject.c b/Objects/typeobject.c index bed50d1e7f2..bdd16af9290 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1271,7 +1271,7 @@ subtype_dealloc(PyObject *self) if (type->tp_weaklistoffset && !base->tp_weaklistoffset) { /* Modeled after GET_WEAKREFS_LISTPTR() */ PyWeakReference **list = (PyWeakReference **) \ - PyObject_GET_WEAKREFS_LISTPTR(self); + _PyObject_GET_WEAKREFS_LISTPTR(self); while (*list) _PyWeakref_ClearRef(*list); } diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index 7a5d9fb88af..1e6697b729c 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -1,9 +1,10 @@ #include "Python.h" +#include "pycore_object.h" // _PyObject_GET_WEAKREFS_LISTPTR #include "structmember.h" #define GET_WEAKREFS_LISTPTR(o) \ - ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o)) + ((PyWeakReference **) _PyObject_GET_WEAKREFS_LISTPTR(o)) Py_ssize_t