Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-42048: Document AC's defining_class converter #23978

Merged
merged 9 commits into from
Jan 20, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions Doc/howto/clinic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
--------------------------
Expand Down