bpo-38140: Document offsets in PyMemberDef (GH-16354)

bpo-38140: Document offsets in PyMemberDef

Co-Authored-By: Ammar Askar <ammar_askar@hotmail.com>
diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst
index af79777..b0a1938 100644
--- a/Doc/c-api/structures.rst
+++ b/Doc/c-api/structures.rst
@@ -346,6 +346,19 @@
    Only :c:macro:`T_OBJECT` and :c:macro:`T_OBJECT_EX`
    members can be deleted.  (They are set to *NULL*).
 
+   .. _pymemberdef-offsets:
+
+   Heap allocated types (created using :c:func:`PyType_FromSpec` or similar),
+   ``PyMemberDef`` may contain defintitions for the special members
+   ``__dictoffset__`` and ``__weaklistoffset__``, corresponding to
+   :c:member:`~PyTypeObject.tp_dictoffset` and
+   :c:member:`~PyTypeObject.tp_weaklistoffset` in type objects.
+   These must be defined with ``T_PYSSIZET`` and ``READONLY``, for example::
+
+      static PyMemberDef spam_type_members[] = {
+          {"__dictoffset__", T_PYSSIZET, offsetof(Spam_object, dict), READONLY},
+          {NULL}  /* Sentinel */
+      };
 
 .. c:type:: PyGetSetDef
 
diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst
index ad3e022..36309dd 100644
--- a/Doc/c-api/type.rst
+++ b/Doc/c-api/type.rst
@@ -188,7 +188,10 @@
       * :c:member:`~PyTypeObject.tp_subclasses`
       * :c:member:`~PyTypeObject.tp_weaklist`
       * :c:member:`~PyTypeObject.tp_vectorcall`
-      * :c:member:`~PyTypeObject.tp_print`
+      * :c:member:`~PyTypeObject.tp_weaklistoffset`
+        (see :ref:`PyMemberDef <pymemberdef-offsets>`)
+      * :c:member:`~PyTypeObject.tp_dictoffset`
+        (see :ref:`PyMemberDef <pymemberdef-offsets>`)
       * :c:member:`~PyBufferProcs.bf_getbuffer`
       * :c:member:`~PyBufferProcs.bf_releasebuffer`