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

gh-64658: Expand Argument Clinic return converter docs #104175

Merged
merged 7 commits into from
May 5, 2023
Merged
Changes from 5 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
41 changes: 28 additions & 13 deletions Doc/howto/clinic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1033,19 +1033,36 @@ you're not permitted to use:
Using a return converter
------------------------

By default the impl function Argument Clinic generates for you returns ``PyObject *``.
But your C function often computes some C type, then converts it into the ``PyObject *``
By default the impl function Argument Clinic generates for you returns
erlend-aasland marked this conversation as resolved.
Show resolved Hide resolved
:c:type:`PyObject * <PyObject>`.
But your C function often computes some C type, then converts it into the
:c:type:`!PyObject *`
erlend-aasland marked this conversation as resolved.
Show resolved Hide resolved
at the last moment. Argument Clinic handles converting your inputs from Python types
into native C types—why not have it convert your return value from a native C type
into a Python type too?

That's what a "return converter" does. It changes your impl function to return
some C type, then adds code to the generated (non-impl) function to handle converting
that value into the appropriate ``PyObject *``.
that value into the appropriate :c:type:`!PyObject *`.

The syntax for return converters is similar to that of parameter converters.
You specify the return converter like it was a return annotation on the
function itself. Return converters behave much the same as parameter converters;
function itself, using ``->`` notation.

For example:

.. code-block:: c

/*[clinic input]
add -> int

a: int
b: int
/

[clinic start generated code]*/

Return converters behave much the same as parameter converters;
they take arguments, the arguments are all keyword-only, and if you're not changing
any of the default arguments you can omit the parentheses.

Expand All @@ -1066,19 +1083,17 @@ Currently Argument Clinic supports only a few return converters:
.. code-block:: none

bool
double
float
int
unsigned int
long
unsigned int
size_t
Py_ssize_t
float
double
DecodeFSDefault
erlend-aasland marked this conversation as resolved.
Show resolved Hide resolved
size_t
unsigned int
unsigned long

None of these take parameters. For the first three, return -1 to indicate
error. For ``DecodeFSDefault``, the return type is ``const char *``; return a ``NULL``
pointer to indicate an error.
None of these take parameters.
For all of these, return ``-1`` to indicate error.

To see all the return converters Argument Clinic supports, along with
their parameters (if any),
Expand Down