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

This commit is contained in:
Erlend Egeberg Aasland 2021-01-20 12:19:57 +01:00 committed by GitHub
parent 61d26394f9
commit e982fe496b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 62 additions and 0 deletions

View File

@ -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
--------------------------