summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErlend Egeberg Aasland <erlend.aasland@innova.no>2021-01-20 11:19:57 (GMT)
committerGitHub <noreply@github.com>2021-01-20 11:19:57 (GMT)
commite982fe496bf756afd2ead8e56eb24b28a93c627a (patch)
tree487f4e8ad86bce3fd26c81e21cd128332c1d66d8
parent61d26394f97306ab4890f1522f26ee6d17461e2b (diff)
downloadcpython-e982fe496bf756afd2ead8e56eb24b28a93c627a.zip
cpython-e982fe496bf756afd2ead8e56eb24b28a93c627a.tar.gz
cpython-e982fe496bf756afd2ead8e56eb24b28a93c627a.tar.bz2
bpo-42048: Clinic Howto: Document AC's defining_class converter (GH-23978)
-rw-r--r--Doc/howto/clinic.rst62
1 files changed, 62 insertions, 0 deletions
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 @@ type for ``self``, it's best to create your own converter, subclassing
[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
--------------------------