|
|
@ -30,7 +30,7 @@ Argument Clinic's primary goal
|
|
|
|
is to take over responsibility for all argument parsing code
|
|
|
|
is to take over responsibility for all argument parsing code
|
|
|
|
inside CPython. This means that, when you convert a function
|
|
|
|
inside CPython. This means that, when you convert a function
|
|
|
|
to work with Argument Clinic, that function should no longer
|
|
|
|
to work with Argument Clinic, that function should no longer
|
|
|
|
do any of its own argument parsing--the code generated by
|
|
|
|
do any of its own argument parsing—the code generated by
|
|
|
|
Argument Clinic should be a "black box" to you, where CPython
|
|
|
|
Argument Clinic should be a "black box" to you, where CPython
|
|
|
|
calls in at the top, and your code gets called at the bottom,
|
|
|
|
calls in at the top, and your code gets called at the bottom,
|
|
|
|
with ``PyObject *args`` (and maybe ``PyObject *kwargs``)
|
|
|
|
with ``PyObject *args`` (and maybe ``PyObject *kwargs``)
|
|
|
@ -43,12 +43,12 @@ redundant information in a surprising number of places.
|
|
|
|
When you use Argument Clinic, you don't have to repeat yourself.
|
|
|
|
When you use Argument Clinic, you don't have to repeat yourself.
|
|
|
|
|
|
|
|
|
|
|
|
Obviously, no one would want to use Argument Clinic unless
|
|
|
|
Obviously, no one would want to use Argument Clinic unless
|
|
|
|
it's solving their problem--and without creating new problems of
|
|
|
|
it's solving their problem—and without creating new problems of
|
|
|
|
its own.
|
|
|
|
its own.
|
|
|
|
So it's paramount that Argument Clinic generate correct code.
|
|
|
|
So it's paramount that Argument Clinic generate correct code.
|
|
|
|
It'd be nice if the code was faster, too, but at the very least
|
|
|
|
It'd be nice if the code was faster, too, but at the very least
|
|
|
|
it should not introduce a major speed regression. (Eventually Argument
|
|
|
|
it should not introduce a major speed regression. (Eventually Argument
|
|
|
|
Clinic *should* make a major speedup possible--we could
|
|
|
|
Clinic *should* make a major speedup possible—we could
|
|
|
|
rewrite its code generator to produce tailor-made argument
|
|
|
|
rewrite its code generator to produce tailor-made argument
|
|
|
|
parsing code, rather than calling the general-purpose CPython
|
|
|
|
parsing code, rather than calling the general-purpose CPython
|
|
|
|
argument parsing library. That would make for the fastest
|
|
|
|
argument parsing library. That would make for the fastest
|
|
|
@ -113,7 +113,7 @@ line. However, if the input hasn't changed, the output won't change either.
|
|
|
|
|
|
|
|
|
|
|
|
You should never modify the output portion of an Argument Clinic block. Instead,
|
|
|
|
You should never modify the output portion of an Argument Clinic block. Instead,
|
|
|
|
change the input until it produces the output you want. (That's the purpose of the
|
|
|
|
change the input until it produces the output you want. (That's the purpose of the
|
|
|
|
checksum--to detect if someone changed the output, as these edits would be lost
|
|
|
|
checksum—to detect if someone changed the output, as these edits would be lost
|
|
|
|
the next time Argument Clinic writes out fresh output.)
|
|
|
|
the next time Argument Clinic writes out fresh output.)
|
|
|
|
|
|
|
|
|
|
|
|
For the sake of clarity, here's the terminology we'll use with Argument Clinic:
|
|
|
|
For the sake of clarity, here's the terminology we'll use with Argument Clinic:
|
|
|
@ -166,7 +166,7 @@ Let's dive in!
|
|
|
|
or if it has multiple calls to :c:func:`PyArg_ParseTuple`,
|
|
|
|
or if it has multiple calls to :c:func:`PyArg_ParseTuple`,
|
|
|
|
you should choose a different function. Argument Clinic *does*
|
|
|
|
you should choose a different function. Argument Clinic *does*
|
|
|
|
support all of these scenarios. But these are advanced
|
|
|
|
support all of these scenarios. But these are advanced
|
|
|
|
topics--let's do something simpler for your first function.
|
|
|
|
topics—let's do something simpler for your first function.
|
|
|
|
|
|
|
|
|
|
|
|
Also, if the function has multiple calls to :c:func:`PyArg_ParseTuple`
|
|
|
|
Also, if the function has multiple calls to :c:func:`PyArg_ParseTuple`
|
|
|
|
or :c:func:`PyArg_ParseTupleAndKeywords` where it supports different
|
|
|
|
or :c:func:`PyArg_ParseTupleAndKeywords` where it supports different
|
|
|
@ -188,7 +188,7 @@ Let's dive in!
|
|
|
|
|
|
|
|
|
|
|
|
If the old docstring had a first line that looked like a function
|
|
|
|
If the old docstring had a first line that looked like a function
|
|
|
|
signature, throw that line away. (The docstring doesn't need it
|
|
|
|
signature, throw that line away. (The docstring doesn't need it
|
|
|
|
anymore--when you use ``help()`` on your builtin in the future,
|
|
|
|
anymore—when you use ``help()`` on your builtin in the future,
|
|
|
|
the first line will be built automatically based on the function's
|
|
|
|
the first line will be built automatically based on the function's
|
|
|
|
signature.)
|
|
|
|
signature.)
|
|
|
|
|
|
|
|
|
|
|
@ -209,7 +209,7 @@ Let's dive in!
|
|
|
|
6. Above the docstring, enter the name of the function, followed
|
|
|
|
6. Above the docstring, enter the name of the function, followed
|
|
|
|
by a blank line. This should be the Python name of the function,
|
|
|
|
by a blank line. This should be the Python name of the function,
|
|
|
|
and should be the full dotted path
|
|
|
|
and should be the full dotted path
|
|
|
|
to the function--it should start with the name of the module,
|
|
|
|
to the function—it should start with the name of the module,
|
|
|
|
include any sub-modules, and if the function is a method on
|
|
|
|
include any sub-modules, and if the function is a method on
|
|
|
|
a class it should include the class name too.
|
|
|
|
a class it should include the class name too.
|
|
|
|
|
|
|
|
|
|
|
@ -275,7 +275,7 @@ Let's dive in!
|
|
|
|
What's a "converter"? It establishes both the type
|
|
|
|
What's a "converter"? It establishes both the type
|
|
|
|
of the variable used in C, and the method to convert the Python
|
|
|
|
of the variable used in C, and the method to convert the Python
|
|
|
|
value into a C value at runtime.
|
|
|
|
value into a C value at runtime.
|
|
|
|
For now you're going to use what's called a "legacy converter"--a
|
|
|
|
For now you're going to use what's called a "legacy converter"—a
|
|
|
|
convenience syntax intended to make porting old code into Argument
|
|
|
|
convenience syntax intended to make porting old code into Argument
|
|
|
|
Clinic easier.
|
|
|
|
Clinic easier.
|
|
|
|
|
|
|
|
|
|
|
@ -425,7 +425,7 @@ Let's dive in!
|
|
|
|
(Argument Clinic always generates its format strings
|
|
|
|
(Argument Clinic always generates its format strings
|
|
|
|
with a ``:`` followed by the name of the function. If the
|
|
|
|
with a ``:`` followed by the name of the function. If the
|
|
|
|
existing code's format string ends with ``;``, to provide
|
|
|
|
existing code's format string ends with ``;``, to provide
|
|
|
|
usage help, this change is harmless--don't worry about it.)
|
|
|
|
usage help, this change is harmless—don't worry about it.)
|
|
|
|
|
|
|
|
|
|
|
|
Third, for parameters whose format units require two arguments
|
|
|
|
Third, for parameters whose format units require two arguments
|
|
|
|
(like a length variable, or an encoding string, or a pointer
|
|
|
|
(like a length variable, or an encoding string, or a pointer
|
|
|
@ -638,7 +638,7 @@ an optional argument on the *left* side of its required argument!
|
|
|
|
Another example is ``curses.window.addch()``, which has a group of two
|
|
|
|
Another example is ``curses.window.addch()``, which has a group of two
|
|
|
|
arguments that must always be specified together. (The arguments are
|
|
|
|
arguments that must always be specified together. (The arguments are
|
|
|
|
called ``x`` and ``y``; if you call the function passing in ``x``,
|
|
|
|
called ``x`` and ``y``; if you call the function passing in ``x``,
|
|
|
|
you must also pass in ``y``--and if you don't pass in ``x`` you may not
|
|
|
|
you must also pass in ``y``—and if you don't pass in ``x`` you may not
|
|
|
|
pass in ``y`` either.)
|
|
|
|
pass in ``y`` either.)
|
|
|
|
|
|
|
|
|
|
|
|
In any case, the goal of Argument Clinic is to support argument parsing
|
|
|
|
In any case, the goal of Argument Clinic is to support argument parsing
|
|
|
@ -889,7 +889,7 @@ Advanced converters
|
|
|
|
Remember those format units you skipped for your first
|
|
|
|
Remember those format units you skipped for your first
|
|
|
|
time because they were advanced? Here's how to handle those too.
|
|
|
|
time because they were advanced? Here's how to handle those too.
|
|
|
|
|
|
|
|
|
|
|
|
The trick is, all those format units take arguments--either
|
|
|
|
The trick is, all those format units take arguments—either
|
|
|
|
conversion functions, or types, or strings specifying an encoding.
|
|
|
|
conversion functions, or types, or strings specifying an encoding.
|
|
|
|
(But "legacy converters" don't support arguments. That's why we
|
|
|
|
(But "legacy converters" don't support arguments. That's why we
|
|
|
|
skipped them for your first function.) The argument you specified
|
|
|
|
skipped them for your first function.) The argument you specified
|
|
|
@ -1003,7 +1003,7 @@ Using a return converter
|
|
|
|
By default the impl function Argument Clinic generates for you returns ``PyObject *``.
|
|
|
|
By default the impl function Argument Clinic generates for you returns ``PyObject *``.
|
|
|
|
But your C function often computes some C type, then converts it into the ``PyObject *``
|
|
|
|
But your C function often computes some C type, then converts it into the ``PyObject *``
|
|
|
|
at the last moment. Argument Clinic handles converting your inputs from Python types
|
|
|
|
at the last moment. Argument Clinic handles converting your inputs from Python types
|
|
|
|
into native C types--why not have it convert your return value from a native C type
|
|
|
|
into native C types—why not have it convert your return value from a native C type
|
|
|
|
into a Python type too?
|
|
|
|
into a Python type too?
|
|
|
|
|
|
|
|
|
|
|
|
That's what a "return converter" does. It changes your impl function to return
|
|
|
|
That's what a "return converter" does. It changes your impl function to return
|
|
|
@ -1185,7 +1185,7 @@ Writing a custom converter
|
|
|
|
As we hinted at in the previous section... you can write your own converters!
|
|
|
|
As we hinted at in the previous section... you can write your own converters!
|
|
|
|
A converter is simply a Python class that inherits from ``CConverter``.
|
|
|
|
A converter is simply a Python class that inherits from ``CConverter``.
|
|
|
|
The main purpose of a custom converter is if you have a parameter using
|
|
|
|
The main purpose of a custom converter is if you have a parameter using
|
|
|
|
the ``O&`` format unit--parsing this parameter means calling
|
|
|
|
the ``O&`` format unit—parsing this parameter means calling
|
|
|
|
a :c:func:`PyArg_ParseTuple` "converter function".
|
|
|
|
a :c:func:`PyArg_ParseTuple` "converter function".
|
|
|
|
|
|
|
|
|
|
|
|
Your converter class should be named ``*something*_converter``.
|
|
|
|
Your converter class should be named ``*something*_converter``.
|
|
|
@ -1227,7 +1227,7 @@ to specify in your subclass. Here's the current list:
|
|
|
|
The default value used to initialize the C variable when
|
|
|
|
The default value used to initialize the C variable when
|
|
|
|
there is no default, but not specifying a default may
|
|
|
|
there is no default, but not specifying a default may
|
|
|
|
result in an "uninitialized variable" warning. This can
|
|
|
|
result in an "uninitialized variable" warning. This can
|
|
|
|
easily happen when using option groups--although
|
|
|
|
easily happen when using option groups—although
|
|
|
|
properly-written code will never actually use this value,
|
|
|
|
properly-written code will never actually use this value,
|
|
|
|
the variable does get passed in to the impl, and the
|
|
|
|
the variable does get passed in to the impl, and the
|
|
|
|
C compiler will complain about the "use" of the
|
|
|
|
C compiler will complain about the "use" of the
|
|
|
@ -1403,7 +1403,7 @@ Let's start with defining some terminology:
|
|
|
|
all of processing, even from Clinic blocks *after* the
|
|
|
|
all of processing, even from Clinic blocks *after* the
|
|
|
|
|
|
|
|
|
|
|
|
``suppress``
|
|
|
|
``suppress``
|
|
|
|
The text is suppressed--thrown away.
|
|
|
|
The text is suppressed—thrown away.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Clinic defines five new directives that let you reconfigure its output.
|
|
|
|
Clinic defines five new directives that let you reconfigure its output.
|
|
|
|