Argument Clinic¶
- author:
Larry Hastings
Source code: Tools/clinic/clinic.py.
Argument Clinic is a preprocessor for CPython C files. It was introduced in Python 3.4 with PEP 436, in order to provide introspection signatures, and to generate performant and tailor-made boilerplate code for argument parsing in CPython builtins, module level functions, and class methods. This document is divided in four major sections:
Background talks about the basic concepts and goals of Argument Clinic.
Reference describes the command-line interface and Argument Clinic terminology.
Tutorial guides you through all the steps required to adapt an existing C function to Argument Clinic.
How-to guides details how to handle specific tasks.
Note
Argument Clinic is considered internal-only for CPython. Its use is not supported for files outside CPython, and no guarantees are made regarding backwards compatibility for future versions. In other words: if you maintain an external C extension for CPython, you’re welcome to experiment with Argument Clinic in your own code. But the version of Argument Clinic that ships with the next version of CPython could be totally incompatible and break all your code.
Background¶
Basic concepts¶
When Argument Clinic is run on a file, either via the Command-line interface
or via make clinic
, it will scan over the input files looking for
start lines:
/*[clinic input]
When it finds one, it reads everything up to the end line:
[clinic start generated code]*/
Everything in between these two lines is Argument Clinic input. When Argument Clinic parses input, it generates output. The output is rewritten into the C file immediately after the input, followed by a checksum line. All of these lines, including the start line and checksum line, are collectively called an Argument Clinic block:
/*[clinic input]
... clinic input goes here ...
[clinic start generated code]*/
... clinic output goes here ...
/*[clinic end generated code: ...]*/
If you run Argument Clinic on the same file a second time, Argument Clinic will discard the old output and write out the new output with a fresh checksum line. If the input hasn’t changed, the output won’t change either.
Note
You should never modify the output of an Argument Clinic block, as any change will be lost in future Argument Clinic runs; Argument Clinic will detect an output checksum mismatch and regenerate the correct output. If you are not happy with the generated output, you should instead change the input until it produces the output you want.
Reference¶
Terminology¶
- start line¶
The line
/*[clinic input]
. This line marks the beginning of Argument Clinic input. Note that the start line opens a C block comment.- end line¶
The line
[clinic start generated code]*/
. The end line marks the end of Argument Clinic input, but at the same time marks the start of Argument Clinic output, thus the text “clinic start start generated code” Note that the end line closes the C block comment opened by the start line.- checksum¶
- checksum line¶
A line that looks like
/*[clinic end generated code: ...]*/
. The three dots will be replaced by a checksum generated from the input, and a checksum generated from the output. The checksum line marks the end of Argument Clinic generated code, and is used by Argument Clinic to determine if it needs to regenerate output.- input¶
The text between the start line and the end line. Note that the start and end lines open and close a C block comment; the input is thus a part of that same C block comment.
- output¶
The text between the end line and the checksum line.
- block¶
All text from the start line to the checksum line inclusively.
Command-line interface¶
The Argument Clinic CLI is typically used to process a single source file, like this:
$ python3 ./Tools/clinic/clinic.py foo.c
The CLI supports the following options:
- -h, --help¶
Print CLI usage.
- -f, --force¶
Force output regeneration.
- -o, --output OUTPUT¶
Redirect file output to OUTPUT
- -v, --verbose¶
Enable verbose mode.
- --converters¶
Print a list of all supported converters and return converters.
- --limited¶
Use the Limited API to parse arguments in the generated C code. See How to use the Limited C API.
- FILE ...¶
The list of files to process.
Classes for extending Argument Clinic¶
- class clinic.CConverter¶
The base class for all converters. See How to write a custom converter for how to subclass this class.
- type¶
The C type to use for this variable.
type
should be a Python string specifying the type, for example,'int'
. If this is a pointer type, the type string should end with' *'
.
- default¶
The Python default value for this parameter, as a Python value. Or the magic value
unspecified
if there is no default.
- py_default¶
default
as it should appear in Python code, as a string. OrNone
if there is no default.
- c_default¶
default
as it should appear in C code, as a string. OrNone
if there is no default.
- c_ignored_default¶
The default value used to initialize the C variable when there is no default, but not specifying a default may result in an “uninitialized variable” warning. This can easily happen when using option groups—although properly written code will never actually use this value, the variable does get passed in to the impl, and the C compiler will complain about the “use” of the uninitialized value. This value should always be a non-empty string.
- converter¶
The name of the C converter function, as a string.
- impl_by_reference¶
A boolean value. If true, Argument Clinic will add a
&
in front of the name of the variable when passing it into the impl function.
- parse_by_reference¶
A boolean value. If true, Argument Clinic will add a
&
in front of the name of the variable when passing it intoPyArg_ParseTuple()
.