Skip to content

Commit bebf735

Browse files
committed
Issue #20287: Argument Clinic's output is now configurable, allowing
delaying its output or even redirecting it to a separate file.
1 parent 601d366 commit bebf735

8 files changed

Lines changed: 1015 additions & 243 deletions

File tree

Doc/howto/clinic.rst

Lines changed: 319 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,58 @@ Argument Clinic How-To
2323
version of Argument Clinic that ships with CPython 3.5 *could*
2424
be totally incompatible and break all your code.
2525

26+
============================
27+
The Goals Of Argument Clinic
28+
============================
29+
30+
Argument Clinic's primary goal
31+
is to take over responsibility for all argument parsing code
32+
inside CPython. This means that, when you convert a function
33+
to work with Argument Clinic, that function should no longer
34+
do any of its own argument parsing--the code generated by
35+
Argument Clinic should be a "black box" to you, where CPython
36+
calls in at the top, and your code gets called at the bottom,
37+
with ``PyObject *args`` (and maybe ``PyObject *kwargs``)
38+
magically converted into the C variables and types you need.
39+
40+
In order for Argument Clinic to accomplish its primary goal,
41+
it must be easy to use. Currently, working with CPython's
42+
argument parsing library is a chore, requiring maintaining
43+
redundant information in a surprising number of places.
44+
When you use Argument Clinic, you don't have to repeat yourself.
45+
46+
Obviously, no one would want to use Argument Clinic unless
47+
it's solving a their problem without creating problems of
48+
its own.
49+
So Argument Clinic should generate correct code, and its
50+
code should preferably be slower, and definitely should
51+
not introduce a major speed regression. (Eventually Argument
52+
Clinic should enable a major speedup--we should be able
53+
to rewrite its code generator so it produces tailor-made
54+
parsing code, rather than using the general-purpose functions
55+
from the CPython code base, which would make for the fastest
56+
argument parsing possible.)
57+
58+
Additionally, Argument Clinic must be flexible enough to
59+
work with any approach to argument parsing. Python has
60+
some functions with some very strange parsing behaviors;
61+
Argument Clinic's goal is to support all of them.
62+
63+
Finally, the original motivation for Argument Clinic was
64+
to provide introspection "signatures" for CPython builtins.
65+
It used to be, the introspection query functions would throw
66+
an exception if you passed in a builtin. With Argument
67+
Clinic, that's a thing of the past!
68+
69+
One idea you should keep in mind, as you work with
70+
Argument Clinic: the more information you give it, the
71+
better job it'll be able to do.
72+
Argument Clinic is admittedly relatively simple right
73+
now. But as it evolves it will get more sophisticated,
74+
and it should be able to do many interesting and smart
75+
things with all the information you give it.
76+
77+
2678
========================
2779
Basic Concepts And Usage
2880
========================
@@ -84,7 +136,15 @@ Converting Your First Function
84136
==============================
85137

86138
The best way to get a sense of how Argument Clinic works is to
87-
convert a function to work with it. Let's dive in!
139+
convert a function to work with it. Here, then, are the bare
140+
minimum steps you'd need to follow to convert a function to
141+
work with Argument Clinic. Note that for code you plan to
142+
check in to CPython, you really should take the conversion farther,
143+
using some of the advanced concepts you'll see later on in
144+
the document (like "return converters" and "self converters").
145+
But we'll keep it simple for this walkthrough so you can learn.
146+
147+
Let's dive in!
88148

89149
0. Make sure you're working with a freshly updated checkout
90150
of the CPython trunk.
@@ -1282,6 +1342,264 @@ available, the macro turns into nothing. Perfect!
12821342
(This is the preferred approach for optional functions; in the future,
12831343
Argument Clinic may generate the entire ``PyMethodDef`` structure.)
12841344

1345+
1346+
Changing and redirecting Clinic's output
1347+
----------------------------------------
1348+
1349+
It can be inconvenient to have Clinic's output interspersed with
1350+
your conventional hand-edited C code. Luckily, Clinic is configurable:
1351+
you can buffer up its output for printing later (or earlier!), or write
1352+
its output to a separate file. You can also add a prefix or suffix to
1353+
every line of Clinic's generated output.
1354+
1355+
While changing Clinic's output in this manner can be a boon to readability,
1356+
it may result in Clinic code using types before they are defined, or
1357+
your code attempting to use Clinic-generated code befire it is defined.
1358+
These problems can be easily solved by rearranging the declarations in your file,
1359+
or moving where Clinic's generated code goes. (This is why the default behavior
1360+
of Clinic is to output everything into the current block; while many people
1361+
consider this hampers readability, it will never require rearranging your
1362+
code to fix definition-before-use problems.)
1363+
1364+
Let's start with defining some terminology:
1365+
1366+
*field*
1367+
A field, in this context, is a subsection of Clinic's output.
1368+
For example, the ``#define`` for the ``PyMethodDef`` structure
1369+
is a field, called ``methoddef_define``. Clinic has seven
1370+
different fields it can output per function definition::
1371+
1372+
docstring_prototype
1373+
docstring_definition
1374+
methoddef_define
1375+
impl_prototype
1376+
parser_prototype
1377+
parser_definition
1378+
impl_definition
1379+
1380+
All the names are of the form ``"<a>_<b>"``,
1381+
where ``"<a>"`` is the semantic object represented (the parsing function,
1382+
the impl function, the docstring, or the methoddef structure) and ``"<b>"``
1383+
represents what kind of statement the field is. Field names that end in
1384+
``"_prototype"``
1385+
represent forward declarations of that thing, without the actual body/data
1386+
of the thing; field names that end in ``"_definition"`` represent the actual
1387+
definition of the thing, with the body/data of the thing. (``"methoddef"``
1388+
is special, it's the only one that ends with ``"_define"``, representing that
1389+
it's a preprocessor #define.)
1390+
1391+
*destination*
1392+
A destination is a place Clinic can write output to. There are
1393+
five built-in destinations:
1394+
1395+
``block``
1396+
The default destination: printed in the output section of
1397+
the current Clinic block.
1398+
1399+
``buffer``
1400+
A text buffer where you can save text for later. Text sent
1401+
here is appended to the end of any exsiting text. It's an
1402+
error to have any text left in the buffer when Clinic finishes
1403+
processing a file.
1404+
1405+
``file``
1406+
A separate "clinic file" that will be created automatically by Clinic.
1407+
The filename chosen for the file is ``{basename}.clinic{extension}``,
1408+
where ``basename`` and ``extension`` were assigned the output
1409+
from ``os.path.splitext()`` run on the current file. (Example:
1410+
the ``file`` destination for ``_pickle.c`` would be written to
1411+
``_pickle.clinic.c``.)
1412+
1413+
**Important: When using a** ``file`` **destination, you**
1414+
*must check in* **the generated file!**
1415+
1416+
``two-pass``
1417+
A buffer like ``buffer``. However, a two-pass buffer can only
1418+
be written once, and it prints out all text sent to it during
1419+
all of processing, even from Clinic blocks *after* the
1420+
1421+
``suppress``
1422+
The text is suppressed--thrown away.
1423+
1424+
1425+
Clinic defines five new directives that let you reconfigure its output.
1426+
1427+
The first new directive is ``dump``::
1428+
1429+
dump <destination>
1430+
1431+
This dumps the current contents of the named destination into the output of
1432+
the current block, and empties it. This only works with ``buffer`` and
1433+
``two-pass`` destinations.
1434+
1435+
The second new directive is ``output``. The most basic form of ``output``
1436+
is like this::
1437+
1438+
output <field> <destination>
1439+
1440+
This tells Clinic to output *field* to *destination*. ``output`` also
1441+
supports a special meta-destination, called ``everything``, which tells
1442+
Clinic to output *all* fields to that *destination*.
1443+
1444+
``output`` has a number of other functions::
1445+
1446+
output push
1447+
output pop
1448+
output preset <preset>
1449+
1450+
1451+
``output push`` and ``output pop`` allow you to push and pop
1452+
configurations on an internal configuration stack, so that you
1453+
can temporarily modify the output configuration, then easily restore
1454+
the previous configuration. Simply push before your change to save
1455+
the current configuration, then pop when you wish to restore the
1456+
previous configuration.
1457+
1458+
``output preset`` sets Clinic's output to one of several built-in
1459+
preset configurations, as follows:
1460+
1461+
``original``
1462+
Clinic's starting configuration.
1463+
1464+
Suppress the ``parser_prototype``
1465+
and ``docstring_prototype``, write everything else to ``block``.
1466+
1467+
``file``
1468+
Designed to write everything to the "clinic file" that it can.
1469+
You then ``#include`` this file near the top of your file.
1470+
You may need to rearrange your file to make this work, though
1471+
usually this just means creating forward declarations for various
1472+
``typedef`` and ``PyTypeObject`` definitions.
1473+
1474+
Suppress the ``parser_prototype``
1475+
and ``docstring_prototype``, write the ``impl_definition`` to
1476+
``block``, and write everything else to ``file``.
1477+
1478+
``buffer``
1479+
Save up all most of the output from Clinic, to be written into
1480+
your file near the end. For Python files implementing modules
1481+
or builtin types, it's recommended that you dump the buffer
1482+
just above the static structures for your module or
1483+
builtin type; these are normally very near the end. Using
1484+
``buffer`` may require even more editing than ``file``, if
1485+
your file has static ``PyMethodDef`` arrays defined in the
1486+
middle of the file.
1487+
1488+
Suppress the ``parser_prototype``, ``impl_prototype``,
1489+
and ``docstring_prototype``, write the ``impl_definition`` to
1490+
``block``, and write everything else to ``file``.
1491+
1492+
``two-pass``
1493+
Similar to the ``buffer`` preset, but writes forward declarations to
1494+
the ``two-pass`` buffer, and definitions to the ``buffer``.
1495+
This is similar to the ``buffer`` preset, but may require
1496+
less editing than ``buffer``. Dump the ``two-pass`` buffer
1497+
near the top of your file, and dump the ``buffer`` near
1498+
the end just like you would when using the ``buffer`` preset.
1499+
1500+
Suppresses the ``impl_prototype``, write the ``impl_definition``
1501+
to ``block``, write ``docstring_prototype``, ``methoddef_define``,
1502+
and ``parser_prototype`` to ``two-pass``, write everything else
1503+
to ``buffer``.
1504+
1505+
``partial-buffer``
1506+
Similar to the ``buffer`` preset, but writes more things to ``block``,
1507+
only writing the really big chunks of generated code to ``buffer``.
1508+
This avoids the definition-before-use problem of ``buffer`` completely,
1509+
at the small cost of having slightly more stuff in the block's output.
1510+
Dump the ``buffer`` near the end, just like you would when using
1511+
the ``buffer`` preset.
1512+
1513+
Suppresses the ``impl_prototype``, write the ``docstring_definition``
1514+
and ``parser_defintion`` to ``buffer``, write everything else to ``block``.
1515+
1516+
The third new directive is ``destination``::
1517+
1518+
destination <name> <command> [...]
1519+
1520+
This performs an operation on the destination named ``name``.
1521+
1522+
There are two defined subcommands: ``new`` and ``clear``.
1523+
1524+
The ``new`` subcommand works like this::
1525+
1526+
destination <name> new <type>
1527+
1528+
This creates a new destination with name ``<name>`` and type ``<type>``.
1529+
1530+
There are five destination types::
1531+
1532+
``suppress``
1533+
Throws the text away.
1534+
1535+
``block``
1536+
Writes the text to the current block. This is what Clinic
1537+
originally did.
1538+
1539+
``buffer``
1540+
A simple text buffer, like the "buffer" builtin destination above.
1541+
1542+
``file``
1543+
A text file. The file destination takes an extra argument,
1544+
a template to use for building the filename, like so:
1545+
1546+
destination <name> new <type> <file_template>
1547+
1548+
The template can use three strings internally that will be replaced
1549+
by bits of the filename:
1550+
1551+
{filename}
1552+
The full filename.
1553+
{basename}
1554+
Everything up to but not including the last '.'.
1555+
{extension}
1556+
The last '.' and everything after it.
1557+
1558+
If there are no periods in the filename, {basename} and {filename}
1559+
are the same, and {extension} is empty. "{basename}{extension}"
1560+
is always exactly the same as "{filename}"."
1561+
1562+
``two-pass``
1563+
A two-pass buffer, like the "two-pass" builtin destination above.
1564+
1565+
1566+
The ``clear`` subcommand works like this::
1567+
1568+
destination <name> clear
1569+
1570+
It removes all the accumulated text up to this point in the destination.
1571+
(I don't know what you'd need this for, but I thought maybe it'd be
1572+
useful while someone's experimenting.)
1573+
1574+
The fourth new directive is ``set``::
1575+
1576+
set line_prefix "string"
1577+
set line_suffix "string"
1578+
1579+
``set`` lets you set two internal variables in Clinic.
1580+
``line_prefix`` is a string that will be prepended to every line of Clinic's output;
1581+
``line_suffix`` is a string that will be appended to every line of Clinic's output.
1582+
1583+
Both of these suport two format strings:
1584+
1585+
``{block comment start}``
1586+
Turns into the string ``/*``, the start-comment text sequence for C files.
1587+
1588+
``{block comment end}``
1589+
Turns into the string ``*/``, the end-comment text sequence for C files.
1590+
1591+
The final new directive is one you shouldn't need to use directly,
1592+
called ``preserve``::
1593+
1594+
preserve
1595+
1596+
This tells Clinic that the current contents of the output should be kept, unmodifed.
1597+
This is used internally by Clinic when dumping output into ``file`` files; wrapping
1598+
it in a Clinic block lets Clinic use its existing checksum functionality to ensure
1599+
the file was not modified by hand before it gets overwritten.
1600+
1601+
1602+
Using Argument Clinic in Python files
12851603
-------------------------------------
12861604

12871605
It's actually possible to use Argument Clinic to preprocess Python files.

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ Tests
8888
Tools/Demos
8989
-----------
9090

91+
- Issue #20287: Argument Clinic's output is now configurable, allowing
92+
delaying its output or even redirecting it to a separate file.
93+
9194
- Issue #20226: Argument Clinic now permits simple expressions
9295
(e.g. "sys.maxsize - 1") as default values for parameters.
9396

0 commit comments

Comments
 (0)