mirror of
https://github.com/python/cpython.git
synced 2025-11-01 18:51:43 +00:00
Issue #20214: Fixed a number of small issues and documentation errors in
Argument Clinic (see issue for details).
This commit is contained in:
parent
583baa8fef
commit
4a55fc5a9d
4 changed files with 223 additions and 50 deletions
|
|
@ -109,6 +109,13 @@ convert a function to work with it. Let's dive in!
|
|||
support all of these scenarios. But these are advanced
|
||||
topics--let's do something simpler for your first function.
|
||||
|
||||
Also, if the function has multiple calls to :c:func:`PyArg_ParseTuple`
|
||||
or :c:func:`PyArg_ParseTupleAndKeywords` where it supports different
|
||||
types for the same argument, or if the function uses something besides
|
||||
PyArg_Parse functions to parse its arguments, it probably
|
||||
isn't suitable for conversion to Argument Clinic. Argument Clinic
|
||||
doesn't support generic functions or polymorphic parameters.
|
||||
|
||||
3. Add the following boilerplate above the function, creating our block::
|
||||
|
||||
/*[clinic input]
|
||||
|
|
@ -170,6 +177,11 @@ convert a function to work with it. Let's dive in!
|
|||
Write a pickled representation of obj to the open file.
|
||||
[clinic start generated code]*/
|
||||
|
||||
The name of the class and module should be the same as the one
|
||||
seen by Python. Check the name defined in the :c:type:`PyModuleDef`
|
||||
or :c:type:`PyTypeObject` as appropriate.
|
||||
|
||||
|
||||
|
||||
8. Declare each of the parameters to the function. Each parameter
|
||||
should get its own line. All the parameter lines should be
|
||||
|
|
@ -455,6 +467,28 @@ convert a function to work with it. Let's dive in!
|
|||
Advanced Topics
|
||||
===============
|
||||
|
||||
Now that you've had some experience working with Argument Clinic, it's time
|
||||
for some advanced topics.
|
||||
|
||||
|
||||
Symbolic default values
|
||||
-----------------------
|
||||
|
||||
The default value you provide for a parameter can't be any arbitrary
|
||||
expression. Currently the following are explicitly supported:
|
||||
|
||||
* Numeric constants (integer and float)
|
||||
* String constants
|
||||
* ``True``, ``False``, and ``None``
|
||||
* Simple symbolic constants like ``sys.maxsize``, which must
|
||||
start with the name of the module
|
||||
|
||||
In case you're curious, this is implemented in ``from_builtin()``
|
||||
in ``Lib/inspect.py``.
|
||||
|
||||
(In the future, this may need to get even more elaborate,
|
||||
to allow full expressions like ``CONSTANT - 1``.)
|
||||
|
||||
|
||||
Renaming the C functions generated by Argument Clinic
|
||||
-----------------------------------------------------
|
||||
|
|
@ -479,6 +513,29 @@ 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
|
||||
--------------------------------------------
|
||||
|
||||
To convert a function parsing its arguments with :c:func:`PyArg_UnpackTuple`,
|
||||
simply write out all the arguments, specifying each as an ``object``. You
|
||||
may specify the ``type`` argument to cast the type as appropriate. All
|
||||
arguments should be marked positional-only (add a ``/`` on a line by itself
|
||||
after the last argument).
|
||||
|
||||
Currently the generated code will use :c:func:`PyArg_ParseTuple`, but this
|
||||
will change soon.
|
||||
|
||||
Optional Groups
|
||||
---------------
|
||||
|
||||
|
|
@ -570,8 +627,8 @@ To save time, and to minimize how much you need to learn
|
|||
to achieve your first port to Argument Clinic, the walkthrough above tells
|
||||
you to use "legacy converters". "Legacy converters" are a convenience,
|
||||
designed explicitly to make porting existing code to Argument Clinic
|
||||
easier. And to be clear, their use is entirely acceptable when porting
|
||||
code for Python 3.4.
|
||||
easier. And to be clear, their use is acceptable when porting code for
|
||||
Python 3.4.
|
||||
|
||||
However, in the long term we probably want all our blocks to
|
||||
use Argument Clinic's real syntax for converters. Why? A couple
|
||||
|
|
@ -585,8 +642,8 @@ reasons:
|
|||
restricted to what :c:func:`PyArg_ParseTuple` supports; this flexibility
|
||||
won't be available to parameters using legacy converters.
|
||||
|
||||
Therefore, if you don't mind a little extra effort, you should consider
|
||||
using normal converters instead of legacy converters.
|
||||
Therefore, if you don't mind a little extra effort, please use the normal
|
||||
converters instead of legacy converters.
|
||||
|
||||
In a nutshell, the syntax for Argument Clinic (non-legacy) converters
|
||||
looks like a Python function call. However, if there are no explicit
|
||||
|
|
@ -597,12 +654,19 @@ the same converters.
|
|||
All arguments to Argument Clinic converters are keyword-only.
|
||||
All Argument Clinic converters accept the following arguments:
|
||||
|
||||
``doc_default``
|
||||
If the parameter takes a default value, normally this value is also
|
||||
provided in the ``inspect.Signature`` metadata, and displayed in the
|
||||
docstring. ``doc_default`` lets you override the value used in these
|
||||
two places: pass in a string representing the Python value you wish
|
||||
to use in these two contexts.
|
||||
``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
|
||||
|
|
@ -612,6 +676,9 @@ All Argument Clinic converters accept the following arguments:
|
|||
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
|
||||
|
|
@ -634,10 +701,11 @@ on the right is the text you'd replace it with.
|
|||
``'et'`` ``str(encoding='name_of_encoding', types='bytes bytearray str')``
|
||||
``'f'`` ``float``
|
||||
``'h'`` ``short``
|
||||
``'H'`` ``unsigned_short``
|
||||
``'H'`` ``unsigned_short(bitwise=True)``
|
||||
``'i'`` ``int``
|
||||
``'I'`` ``unsigned_int``
|
||||
``'K'`` ``unsigned_PY_LONG_LONG``
|
||||
``'I'`` ``unsigned_int(bitwise=True)``
|
||||
``'k'`` ``unsigned_long(bitwise=True)``
|
||||
``'K'`` ``unsigned_PY_LONG_LONG(bitwise=True)``
|
||||
``'L'`` ``PY_LONG_LONG``
|
||||
``'n'`` ``Py_ssize_t``
|
||||
``'O!'`` ``object(subclass_of='&PySomething_Type')``
|
||||
|
|
@ -681,6 +749,14 @@ available. For each converter it'll show you all the parameters
|
|||
it accepts, along with the default value for each parameter.
|
||||
Just run ``Tools/clinic/clinic.py --converters`` to see the full list.
|
||||
|
||||
Py_buffer
|
||||
---------
|
||||
|
||||
When using the ``Py_buffer`` converter
|
||||
(or the ``'s*'``, ``'w*'``, ``'*y'``, or ``'z*'`` legacy converters)
|
||||
note that the code Argument Clinic generates for you will automatically
|
||||
call :c:func:`PyBuffer_Release` on the buffer for you.
|
||||
|
||||
|
||||
Advanced converters
|
||||
-------------------
|
||||
|
|
@ -745,15 +821,26 @@ encode the value you return like normal.
|
|||
|
||||
Currently Argument Clinic supports only a few return converters::
|
||||
|
||||
bool
|
||||
int
|
||||
unsigned int
|
||||
long
|
||||
unsigned int
|
||||
size_t
|
||||
Py_ssize_t
|
||||
float
|
||||
double
|
||||
DecodeFSDefault
|
||||
|
||||
None of these take parameters. For the first three, return -1 to indicate
|
||||
error. For ``DecodeFSDefault``, the return type is ``char *``; return a NULL
|
||||
pointer to indicate an error.
|
||||
|
||||
(There's also an experimental ``NoneType`` converter, which lets you
|
||||
return ``Py_None`` on success or ``NULL`` on failure, without having
|
||||
to increment the reference count on ``Py_None``. I'm not sure it adds
|
||||
enough clarity to be worth using.)
|
||||
|
||||
To see all the return converters Argument Clinic supports, along with
|
||||
their parameters (if any),
|
||||
just run ``Tools/clinic/clinic.py --converters`` for the full list.
|
||||
|
|
@ -873,13 +960,6 @@ to specify in your subclass. Here's the current list:
|
|||
The Python default value for this parameter, as a Python value.
|
||||
Or the magic value ``unspecified`` if there is no default.
|
||||
|
||||
``doc_default``
|
||||
``default`` as it should appear in the documentation,
|
||||
as a string.
|
||||
Or ``None`` if there is no default.
|
||||
This string, when run through ``eval()``, should produce
|
||||
a Python value.
|
||||
|
||||
``py_default``
|
||||
``default`` as it should appear in Python code,
|
||||
as a string.
|
||||
|
|
@ -951,6 +1031,26 @@ write your own return converter, please read ``Tools/clinic/clinic.py``,
|
|||
specifically the implementation of ``CReturnConverter`` and
|
||||
all its subclasses.
|
||||
|
||||
METH_O and METH_NOARGS
|
||||
----------------------------------------------
|
||||
|
||||
To convert a function using ``METH_O``, make sure the function's
|
||||
single argument is using the ``object`` converter, and mark the
|
||||
arguments as positional-only::
|
||||
|
||||
/*[clinic input]
|
||||
meth_o_sample
|
||||
|
||||
argument: object
|
||||
/
|
||||
[clinic start generated code]*/
|
||||
|
||||
|
||||
To convert a function using ``METH_NOARGS``, just don't specify
|
||||
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
|
||||
-------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue