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.
diff --git a/Include/cpython/objimpl.h b/Include/cpython/objimpl.h
index 8e3c964..2f802e9 100644
--- a/Include/cpython/objimpl.h
+++ b/Include/cpython/objimpl.h
@@ -138,8 +138,7 @@
 /* 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 10a5746..002b700 100644
--- a/Include/internal/pycore_object.h
+++ b/Include/internal/pycore_object.h
@@ -87,6 +87,13 @@
 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 0000000..3c4e33b
--- /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 cd7c4c1..e33cba2 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 cf164c1..1bc41fb 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -788,7 +788,7 @@
 
         /* 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 e6d0da1..05241e8 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -2206,6 +2206,14 @@
     (*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 bed50d1..bdd16af 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -1271,7 +1271,7 @@
         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 7a5d9fb..1e6697b 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