diff options
author | Erlend Egeberg Aasland <erlend.aasland@innova.no> | 2021-01-20 11:19:57 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-20 11:19:57 (GMT) |
commit | e982fe496bf756afd2ead8e56eb24b28a93c627a (patch) | |
tree | 487f4e8ad86bce3fd26c81e21cd128332c1d66d8 | |
parent | 61d26394f97306ab4890f1522f26ee6d17461e2b (diff) | |
download | cpython-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.rst | 62 |
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 -------------------------- |