Skip to content

Docs: Argument Clinic: Improve 'How to write a custom converter' #107328

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

Merged
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
50 changes: 26 additions & 24 deletions Doc/howto/clinic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1343,35 +1343,37 @@ state. Example from the ``setattro`` slot method in
See also :pep:`573`.


.. _clinic-howto-custom-converter:

How to write a custom converter
-------------------------------

As we hinted at in the previous section... you can write your own converters!
A converter is simply a Python class that inherits from :py:class:`!CConverter`.
The main purpose of a custom converter is if you have a parameter using
the ``O&`` format unit—parsing this parameter means calling
A converter is a Python class that inherits from :py:class:`!CConverter`.
The main purpose of a custom converter, is for parameters parsed with
the ``O&`` format unit --- parsing such a parameter means calling
a :c:func:`PyArg_ParseTuple` "converter function".

Your converter class should be named ``*something*_converter``.
If the name follows this convention, then your converter class
will be automatically registered with Argument Clinic; its name
will be the name of your class with the ``_converter`` suffix
stripped off. (This is accomplished with a metaclass.)

You shouldn't subclass :py:meth:`!CConverter.__init__`. Instead, you should
write a :py:meth:`!converter_init` function. :py:meth:`!converter_init`
always accepts a *self* parameter; after that, all additional
parameters *must* be keyword-only. Any arguments passed in to
the converter in Argument Clinic will be passed along to your
:py:meth:`!converter_init`.
Your converter class should be named :samp:`{ConverterName}_converter`.
By following this convention, your converter class will be automatically
registered with Argument Clinic, with its *converter name* being the name of
your converter class with the ``_converter`` suffix stripped off.

There are some additional members of :py:class:`!CConverter` you may wish
to specify in your subclass. Here's the current list:
Instead of subclassing :py:meth:`!CConverter.__init__`,
write a :py:meth:`!converter_init` method.
Apart for the *self* parameter, all additional :py:meth:`!converter_init`
parameters **must** be keyword-only.
Any arguments passed to the converter in Argument Clinic
will be passed along to your :py:meth:`!converter_init` method.
See :py:class:`!CConverter` for a list of members you may wish to specify in
your subclass.

.. module:: clinic

.. class:: CConverter

The base class for all converters.
See :ref:`clinic-howto-custom-converter` for how to subclass this class.

.. attribute:: type

The C type to use for this variable.
Expand Down Expand Up @@ -1436,16 +1438,16 @@ Here's the simplest example of a custom converter, from :source:`Modules/zlibmod
[python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=35521e4e733823c7]*/

This block adds a converter to Argument Clinic named ``ssize_t``. Parameters
declared as ``ssize_t`` will be declared as type :c:type:`Py_ssize_t`, and will
be parsed by the ``'O&'`` format unit, which will call the
``ssize_t_converter`` converter function. ``ssize_t`` variables
automatically support default values.
This block adds a converter named ``ssize_t`` to Argument Clinic.
Parameters declared as ``ssize_t`` will be declared with type :c:type:`Py_ssize_t`,
and will be parsed by the ``'O&'`` format unit,
which will call the :c:func:`!ssize_t_converter` converter C function.
``ssize_t`` variables automatically support default values.

More sophisticated custom converters can insert custom C code to
handle initialization and cleanup.
You can see more examples of custom converters in the CPython
source tree; grep the C files for the string :py:class:`!CConverter`.
source tree; grep the C files for the string ``CConverter``.


How to write a custom return converter
Expand Down