Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
376caf0
Issue #19659: Added documentation for Argument Clinic.
larryhastings Jan 4, 2014
5ca5d3a
Argument Clinic: fixed test suite, improved howto.
larryhastings Jan 5, 2014
9e47d75
Issue #20141: Improved Argument Clinic's support for the PyArg_Parse …
larryhastings Jan 7, 2014
01ae6c7
Issue #19273: The marker comments Argument Clinic uses have been changed
larryhastings Jan 7, 2014
1f988b1
Closes #20200: Argument Clinic custom converter example should be in a
zware Jan 10, 2014
5c53fd9
Issue #20214: Fixed a number of small issues and documentation errors in
larryhastings Jan 12, 2014
8d13753
Minor doc fix in Clinic howto.
larryhastings Jan 12, 2014
ef8fde7
Issue #20268: Argument Clinic now supports cloning the parameters
larryhastings Jan 15, 2014
ecea194
Issue #20226: Major improvements to Argument Clinic.
larryhastings Jan 16, 2014
71ff306
Issue #20287: Argument Clinic's output is now configurable, allowing
larryhastings Jan 18, 2014
8224acf
Doc improvements for Clinic howto "Goals" section.
larryhastings Jan 18, 2014
3619f5f
Issue #20294: Argument Clinic now supports argument parsing for __new…
larryhastings Jan 19, 2014
745625b
Doc fixes for Argument Clinic.
larryhastings Jan 22, 2014
4259315
GitHub-Issue-Link: https://github.com/python/cpython/issues/64547
ezio-melotti Jan 25, 2014
86a65e4
Documentation fixes, including fixing "suspicious" problems.
larryhastings Jan 26, 2014
416ba5f
including correctly generating code for Clinic blocks inside C
larryhastings Feb 1, 2014
6341d75
Fix Issue #21528 - Fix documentation typos
dstufft May 20, 2014
e3c5656
Issue #24000: Improved Argument Clinic's mapping of converters to legacy
larryhastings May 8, 2015
2914da8
Argument Clinic: added missing bit of info in howto
taleinat May 16, 2015
1b9d562
Issue #24232: Fix typos. Patch by Ville Skyttä.
berkerpeksag May 18, 2015
be8c565
Issue #24232: Fix typos. Patch by Ville Skyttä.
berkerpeksag May 18, 2015
f3fcaa4
Back porting changeset db302b88fdb6 to 3.4 branch, which fixed multip…
orsenthil Jun 15, 2015
62bda94
null merge with 3.4
orsenthil Jun 15, 2015
05046f9
null merge 3.4 to 3.5 (9a0c5ffe7420 merged 3.4 to default, bypassing …
ned-deily Jun 15, 2015
70bfe58
null merge 3.5 to default (9a0c5ffe7420 merged 3.4 to default, bypass…
ned-deily Jun 15, 2015
0ca4094
Issue #25626: Change zlib to accept Py_ssize_t and cap to UINT_MAX
vadmium Nov 20, 2015
c7b612a
Issue #25626: Merge zlib fix from 3.5
vadmium Nov 21, 2015
cfb1132
Issue #27130: Fix handling of buffers exceeding UINT_MAX in “zlib” mo…
vadmium Jul 23, 2016
4d20304
Issue #27626: Spelling fixes in docs, comments and internal names
vadmium Jul 28, 2016
3c7af20
Issue #26462: Doc: reduce literal_block warnings, fix syntax highligh…
vadmium Jul 26, 2016
2138267
Issue #27745: Fix some typos in Argument Clinic howto, by Lele Gaifax
vadmium Aug 12, 2016
83f8383
clinic: PY_LONG_LONG -> long long
benjaminp Sep 8, 2016
0147885
Issue 28753: Argument Clinic howto docfix, courtesy Julien Palard.
larryhastings Nov 20, 2016
2ff77e2
Change double hyphens (en dashes) to em (longer) dashes
vadmium Nov 21, 2016
a0b8e05
Merge doc fixups from 3.5
vadmium Nov 21, 2016
e066b36
Merge doc fixups from 3.6
vadmium Nov 21, 2016
d29e1f8
Change an en-dash to an em-dash.
serhiy-storchaka Nov 21, 2016
36e7d29
Issue 28753: Argument Clinic howto docfix, courtesy Julien Palard.
vadmium Dec 10, 2016
85fea54
Issue #28755: Improve syntax highlighting in Arg Clinic howto
vadmium Dec 10, 2016
8764b20
Issues #28755, #28753: Merge Arg Clinic howto from 3.5
vadmium Dec 10, 2016
4ad9136
Issue #28755: Merge Arg Clinic howto from 3.6
vadmium Dec 10, 2016
9a35ab4
bpo-29918: Add missed "const" modifiers in C API documentation. (#846)
serhiy-storchaka Mar 30, 2017
3fae62e
bpo-29596: Improve clinic howto documentation (GH-1710)
gfyoung Jun 6, 2017
3f5fc8f
Improve highlighting of some code blocks. (python/cpython#6401)
serhiy-storchaka Apr 8, 2018
40bb2c7
Docs: be less specific about python versions (python/cpython#6985)
grimreaper May 20, 2018
357a8f2
bpo-20260: Implement non-bitwise unsigned int converters for Argument…
serhiy-storchaka Jul 26, 2018
f9b4857
bpo-35042: Use the :pep: role where a PEP is specified (python/cpytho…
matrixise Oct 26, 2018
8c3d865
Doc: Replace the deprecated highlightlang directive by highlight. (py…
matrixise May 17, 2019
50f60a4
bpo-38600: NULL -> ``NULL``. (python/cpython#17001)
serhiy-storchaka Oct 30, 2019
403488f
bpo-42048: Clinic Howto: Document AC's defining_class converter (pyth…
Jan 20, 2021
4cd6fc6
bpo-45320: Remove long-deprecated inspect methods (python/cpython#28618)
hugovk Oct 20, 2021
9d1a7ad
bpo-46613: Add PyType_GetModuleByDef to the public API (python/cpytho…
encukou Feb 11, 2022
03d39ac
python/cpython#92536: PEP 623: Remove wstr and legacy APIs from Unico…
methane May 12, 2022
7980ac5
Document Py_ssize_t. (python/cpython#92512)
JulienPalard May 13, 2022
d2514e5
Docs: remove redundant "adverb-adjective" hyphens from compound modif…
nedbat Jul 5, 2022
d6ff211
python/cpython#95007: Remove the NoneType return converter from Argum…
noamcohen97 Aug 1, 2022
5f6ac54
python/cpython#97956: Mention `generate_global_objects.py` in `AC How…
sobolevn Oct 7, 2022
1196c45
docs: Change links to label refs (python/cpython#98454)
slateny Oct 26, 2022
9243c7a
python/cpython#98763: Prefer "python" over "python3" for command line…
felixxm Jan 11, 2023
59eef01
python/cpython#64658: Expand Argument Clinic return converter docs (p…
erlend-aasland May 5, 2023
d8a7663
python/cpython#104389: Add 'unused' keyword to Argument Clinic C conv…
erlend-aasland May 12, 2023
b247a69
Docs: Normalize Argument Clinic How-To section capitalization (python…
erlend-aasland Jul 15, 2023
9ca360c
Docs: Normalise Argument Clinic advanced topics headings (python/cpyt…
erlend-aasland Jul 18, 2023
4c56015
Docs: Argument Clinic: Group guides about default values (python/cpyt…
erlend-aasland Jul 18, 2023
60a674b
Docs: Argument Clinic: Add Background and Tutorial top-level sections…
erlend-aasland Jul 21, 2023
f73589c
Docs: Remove duplicate word in Argument Clinic howto heading (python/…
hakancelikdev Jul 24, 2023
4eda298
Docs: Add missing markup to Argument Clinic docs (python/cpython#106876)
erlend-aasland Jul 24, 2023
f4d2138
Docs: Remove the numbered steps from the Argument Clinic tutorial (py…
erlend-aasland Jul 26, 2023
8405f89
Docs: Argument Clinic: Restructure "Basic concepts and usage" (python…
erlend-aasland Jul 26, 2023
64b07f5
python/cpython#107507: Replace 'The goals of Argument Clinic' with a …
erlend-aasland Jul 31, 2023
1c3fb9b
Docs: Argument Clinic: Improve 'How to write a custom converter' (pyt…
erlend-aasland Aug 5, 2023
ce3b69d
Docs: Argument Clinic: Move the CConverter class to the reference (py…
erlend-aasland Aug 7, 2023
eec5f46
python/cpython#95065: Add Argument Clinic support for deprecating pos…
erlend-aasland Aug 7, 2023
6a0051f
python/cpython#86457: Add docs for Argument Clinic @text_signature di…
erlend-aasland Aug 8, 2023
8dd6936
python/cpython#104683: Add --exclude option to Argument Clinic CLI (p…
erlend-aasland Aug 8, 2023
067ee64
Docs: clean up Argument Clinic howto's (python/cpython#107797)
erlend-aasland Aug 9, 2023
f62db14
Add clinic.rst with history
erlend-aasland Aug 9, 2023
b091bbd
Add clinic.rst to Development Tools
erlend-aasland Aug 9, 2023
7e4977f
Adapt clinic.rst
erlend-aasland Aug 9, 2023
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
Prev Previous commit
Next Next commit
Issue #20226: Major improvements to Argument Clinic.
* You may now specify an expression as the default value for a
  parameter!  Example: "sys.maxsize - 1".  This support is
  intentionally quite limited; you may only use values that
  can be represented as static C values.
* Removed "doc_default", simplified support for "c_default"
  and "py_default".  (I'm not sure we still even need
  "py_default", but I'm leaving it in for now in case a
  use presents itself.)
* Parameter lines support a trailing '\\' as a line
  continuation character, allowing you to break up long lines.
* The argument parsing code generated when supporting optional
  groups now uses PyTuple_GET_SIZE instead of PyTuple_GetSize,
  leading to a 850% speedup in parsing.  (Just kidding, this
  is an unmeasurable difference.)
* A bugfix for the recent regression where the generated
  prototype from pydoc for builtins would be littered with
  unreadable "=<object ...>"" default values for parameters
  that had no default value.
* Converted some asserts into proper failure messages.
* Many doc improvements and fixes.

GitHub-Issue-Link: python/cpython#64425
  • Loading branch information
larryhastings committed Jan 16, 2014
commit ecea194e10ce1274f16d7fb161ecfa51899beed7
269 changes: 227 additions & 42 deletions Doc/howto/clinic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ convert a function to work with it. Let's dive in!
margin, with no line wider than 80 characters.
(Argument Clinic will preserve indents inside the docstring.)

If the old docstring had a first line that looked like a function
signature, throw that line away. (The docstring doesn't need it
anymore--when you use ``help()`` on your builtin in the future,
the first line will be built automatically based on the function's
signature.)

Sample::

/*[clinic input]
Expand Down Expand Up @@ -196,6 +202,10 @@ convert a function to work with it. Let's dive in!

name_of_parameter: converter = default_value

Argument Clinic's support for "default values" is quite sophisticated;
please see :ref:`the section below on default values <default_values>`
for more information.

Add a blank line below the parameters.

What's a "converter"? It establishes both the type
Expand Down Expand Up @@ -513,16 +523,6 @@ The base function would now be named ``pickler_dumper()``,
and the impl function would now be named ``pickler_dumper_impl()``.


The NULL default value
----------------------

For string and object parameters, you can set them to ``None`` to indicate
that there is no default. However, that means the C variable will be
initialized to ``Py_None``. For convenience's sakes, there's a special
value called ``NULL`` for just this case: from Python's perspective it
behaves like a default value of ``None``, but the C variable is initialized
with ``NULL``.


Converting functions using PyArg_UnpackTuple
--------------------------------------------
Expand Down Expand Up @@ -654,35 +654,70 @@ the same converters.
All arguments to Argument Clinic converters are keyword-only.
All Argument Clinic converters accept the following arguments:

``py_default``
The default value for this parameter when defined in Python.
Specifically, the value that will be used in the ``inspect.Signature``
string.
If a default value is specified for the parameter, defaults to
``repr(default)``, else defaults to ``None``.
Specified as a string.

``c_default``
The default value for this parameter when defined in C.
Specifically, this will be the initializer for the variable declared
in the "parse function".
Specified as a string.

``required``
If a parameter takes a default value, Argument Clinic infers that the
parameter is optional. However, you may want a parameter to take a
default value in C, but not behave in Python as if the parameter is
optional. Passing in ``required=True`` to a converter tells Argument
Clinic that this parameter is not optional, even if it has a default
value.

(The need for ``required`` may be obviated by ``c_default``, which is
newer but arguably a better solution.)

``annotation``
The annotation value for this parameter. Not currently supported,
because PEP 8 mandates that the Python library may not use
annotations.
``c_default``
The default value for this parameter when defined in C.
Specifically, this will be the initializer for the variable declared
in the "parse function". See :ref:`the section on default values <default_values>`
for how to use this.
Specified as a string.

``annotation``
The annotation value for this parameter. Not currently supported,
because PEP 8 mandates that the Python library may not use
annotations.

In addition, some converters accept additional arguments. Here is a list
of these arguments, along with their meanings:

``bitwise``
Only supported for unsigned integers. The native integer value of this
Python argument will be written to the parameter without any range checking,
even for negative values.

``converter``
Only supported by the ``object`` converter. Specifies the name of a
:ref:`C "converter function" <o_ampersand>`
to use to convert this object to a native type.

``encoding``
Only supported for strings. Specifies the encoding to use when converting
this string from a Python str (Unicode) value into a C ``char *`` value.

``length``
Only supported for strings. If true, requests that the length of the
string be passed in to the impl function, just after the string parameter,
in a parameter named ``<parameter_name>_length``.

``nullable``
Only supported for strings. If true, this parameter may also be set to
``None``, in which case the C parameter will be set to ``NULL``.

``subclass_of``
Only supported for the ``object`` converter. Requires that the Python
value be a subclass of a Python type, as expressed in C.

``types``
Only supported for the ``object`` (and ``self``) converter. Specifies
the C type that will be used to declare the variable. Default value is
``"PyObject *"``.

``types``
A string containing a list of Python types (and possibly pseudo-types);
this restricts the allowable Python argument to values of these types.
(This is not a general-purpose facility; as a rule it only supports
specific lists of types as shown in the legacy converter table.)

``zeroes``
Only supported for strings. If true, embedded NUL bytes (``'\\0'``) are
permitted inside the value.

Please note, not every possible combination of arguments will work.
Often these arguments are implemented internally by specific ``PyArg_ParseTuple``
*format units*, with specific behavior. For example, currently you cannot
call ``str`` and pass in ``zeroes=True`` without also specifying an ``encoding``;
although it's perfectly reasonable to think this would work, these semantics don't
map to any existing format unit. So Argument Clinic doesn't support it. (Or, at
least, not yet.)

Below is a table showing the mapping of legacy converters into real
Argument Clinic converters. On the left is the legacy converter,
Expand Down Expand Up @@ -720,9 +755,9 @@ on the right is the text you'd replace it with.
``'u'`` ``Py_UNICODE``
``'U'`` ``unicode``
``'w*'`` ``Py_buffer(types='bytearray rwbuffer')``
``'y#'`` ``str(type='bytes', length=True)``
``'y#'`` ``str(types='bytes', length=True)``
``'Y'`` ``PyByteArrayObject``
``'y'`` ``str(type='bytes')``
``'y'`` ``str(types='bytes')``
``'y*'`` ``Py_buffer``
``'Z#'`` ``Py_UNICODE(nullable=True, length=True)``
``'z#'`` ``str(nullable=True, length=True)``
Expand Down Expand Up @@ -789,6 +824,90 @@ This restriction doesn't seem unreasonable; CPython itself always passes in stat
hard-coded encoding strings for parameters whose format units start with ``e``.


.. _default_values:

Parameter default values
------------------------

Default values for parameters can be any of a number of values.
At their simplest, they can be string, int, or float literals::

foo: str = "abc"
bar: int = 123
bat: float = 45.6

They can also use any of Python's built-in constants::

yep: bool = True
nope: bool = False
nada: object = None

There's also special support for a default value of ``NULL``, and
for simple expressions, documented in the following sections.


The ``NULL`` default value
--------------------------

For string and object parameters, you can set them to ``None`` to indicate
that there's no default. However, that means the C variable will be
initialized to ``Py_None``. For convenience's sakes, there's a special
value called ``NULL`` for just this reason: from Python's perspective it
behaves like a default value of ``None``, but the C variable is initialized
with ``NULL``.

Expressions specified as default values
---------------------------------------

The default value for a parameter can be more than just a literal value.
It can be an entire expression, using math operators and looking up attributes
on objects. However, this support isn't exactly simple, because of some
non-obvious semantics.

Consider the following example::

foo: Py_ssize_t = sys.maxsize - 1

``sys.maxsize`` can have different values on different platforms. Therefore
Argument Clinic can't simply evaluate that expression locally and hard-code it
in C. So it stores the default in such a way that it will get evaluated at
runtime, when the user asks for the function's signature.

What namespace is available when the expression is evaluated? It's evaluated
in the context of the module the builtin came from. So, if your module has an
attribute called "``max_widgets``", you may simply use it::

foo: Py_ssize_t = max_widgets

If the symbol isn't found in the current module, it fails over to looking in
``sys.modules``. That's how it can find ``sys.maxsize`` for example. (Since you
don't know in advance what modules the user will load into their interpreter,
it's best to restrict yourself to modules that are preloaded by Python itself.)

Evaluating default values only at runtime means Argument Clinic can't compute
the correct equivalent C default value. So you need to tell it explicitly.
When you use an expression, you must also specify the equivalent expression
in C, using the ``c_default`` parameter to the converter::

foo: Py_ssize_t(c_default="PY_SSIZE_T_MAX - 1") = sys.maxsize - 1

Another complication: Argument Clinic can't know in advance whether or not the
expression you supply is valid. It parses it to make sure it looks legal, but
it can't *actually* know. You must be very careful when using expressions to
specify values that are guaranteed to be valid at runtime!

Finally, because expressions must be representable as static C values, there
are many restrictions on legal expressions. Here's a list of Python features
you're not permitted to use:

* Function calls.
* Inline if statements (``3 if foo else 5``).
* Automatic sequence unpacking (``*[1, 2, 3]``).
* List/set/dict comprehensions and generator expressions.
* Tuple/list/set/dict literals.



Using a return converter
------------------------

Expand Down Expand Up @@ -1096,7 +1215,73 @@ any arguments.
You can still use a self converter, a return converter, and specify
a ``type`` argument to the object converter for ``METH_O``.

Using Argument Clinic in Python files
The #ifdef trick
----------------------------------------------

If you're converting a function that isn't available on all platforms,
there's a trick you can use to make life a little easier. The existing
code probably looks like this::

#ifdef HAVE_FUNCTIONNAME
static module_functionname(...)
{
...
}
#endif /* HAVE_FUNCTIONNAME */

And then in the ``PyMethodDef`` structure at the bottom you'll have::

#ifdef HAVE_FUNCTIONNAME
{'functionname', ... },
#endif /* HAVE_FUNCTIONNAME */

In this scenario, you should change the code to look like the following::

#ifdef HAVE_FUNCTIONNAME
/*[clinic input]
module.functionname
...
[clinic start generated code]*/
static module_functionname(...)
{
...
}
#endif /* HAVE_FUNCTIONNAME */

Run Argument Clinic on the code in this state, then refresh the file in
your editor. Now you'll have the generated code, including the #define
for the ``PyMethodDef``, like so::

#ifdef HAVE_FUNCTIONNAME
/*[clinic input]
...
[clinic start generated code]*/
...
#define MODULE_FUNCTIONNAME \
{'functionname', ... },
...
/*[clinic end generated code: checksum=...]*/
static module_functionname(...)
{
...
}
#endif /* HAVE_FUNCTIONNAME */

Change the #endif at the bottom as follows::

#else
#define MODULE_FUNCTIONNAME
#endif /* HAVE_FUNCTIONNAME */

Now you can remove the #ifdefs around the ``PyMethodDef`` structure
at the end, and replace those three lines with ``MODULE_FUNCTIONNAME``.
If the function is available, the macro turns into the ``PyMethodDef``
static value, including the trailing comma; if the function isn't
available, the macro turns into nothing. Perfect!

(This is the preferred approach for optional functions; in the future,
Argument Clinic may generate the entire ``PyMethodDef`` structure.)

-------------------------------------

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