bpo-42048: Clinic Howto: Document AC's defining_class converter (GH-23978)

diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst
index 5004182..3a3653a 100644
--- a/Doc/howto/clinic.rst
+++ b/Doc/howto/clinic.rst
@@ -1206,6 +1206,68 @@
     [clinic start generated code]*/
 
 
+Using a "defining class" converter
+----------------------------------
+
+Argument Clinic facilitates gaining access to the defining class of a method.
+This is useful for :ref:`heap type <heap-types>` methods that need to fetch
+module level state.  Use :c:func:`PyType_FromModuleAndSpec` to associate a new
+heap type with a module.  You can now use :c:func:`PyType_GetModuleState` on
+the defining class to fetch the module state, for example from a module method.
+
+Example from ``Modules/zlibmodule.c``.  First, ``defining_class`` is added to
+the clinic input::
+
+    /*[clinic input]
+    zlib.Compress.compress
+
+      cls: defining_class
+      data: Py_buffer
+        Binary data to be compressed.
+      /
+
+
+After running the Argument Clinic tool, the following function signature is
+generated::
+
+    /*[clinic start generated code]*/
+    static PyObject *
+    zlib_Compress_compress_impl(compobject *self, PyTypeObject *cls,
+                                Py_buffer *data)
+    /*[clinic end generated code: output=6731b3f0ff357ca6 input=04d00f65ab01d260]*/
+
+
+The following code can now use ``PyType_GetModuleState(cls)`` to fetch the
+module state::
+
+    zlibstate *state = PyType_GetModuleState(cls);
+
+
+Each method may only have one argument using this converter, and it must appear
+after ``self``, or, if ``self`` is not used, as the first argument.  The argument
+will be of type ``PyTypeObject *``.  The argument will not appear in the
+``__text_signature__``.
+
+The ``defining_class`` converter is not compatible with ``__init__`` and ``__new__``
+methods, which cannot use the ``METH_METHOD`` convention.
+
+It is not possible to use ``defining_class`` with slot methods.  In order to
+fetch the module state from such methods, use ``_PyType_GetModuleByDef`` to
+look up the module and then :c:func:`PyModule_GetState` to fetch the module
+state.  Example from the ``setattro`` slot method in
+``Modules/_threadmodule.c``::
+
+    static int
+    local_setattro(localobject *self, PyObject *name, PyObject *v)
+    {
+        PyObject *module = _PyType_GetModuleByDef(Py_TYPE(self), &thread_module);
+        thread_module_state *state = get_thread_state(module);
+        ...
+    }
+
+
+See also :pep:`573`.
+
 
 Writing a custom converter
 --------------------------