diff --git a/Include/cpython/objimpl.h b/Include/cpython/objimpl.h index 8e3c964cf44e76..2f802e92a6cdf8 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 10a5746997ec72..002b70007b639c 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 00000000000000..3c4e33b9da1347 --- /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 cd7c4c159ac1b6..e33cba2a3dd81f 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 cf164c17d7bf17..1bc41fb83d8a60 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 e6d0da1c775c26..05241e8a740d14 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 bed50d1e7f2d3c..bdd16af929079f 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 7a5d9fb88af14d..1e6697b729c9c0 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