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

A hash to distinguish unique inputs and outputs.

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.

--make

Walk --srcdir to run over all relevant files.

--srcdir SRCDIR

The directory tree to walk in --make mode.

--exclude EXCLUDE

A file to exclude in --make mode. This option can be given multiple times.

--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. Or None if there is no default.

c_default

default as it should appear in C code, as a string. Or None 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 into PyArg_ParseTuple().