Issue #20287: Argument Clinic's output is now configurable, allowing
delaying its output or even redirecting it to a separate file.
This commit is contained in:
parent
601d366844
commit
bebf73511a
|
@ -23,6 +23,58 @@ Argument Clinic How-To
|
|||
version of Argument Clinic that ships with CPython 3.5 *could*
|
||||
be totally incompatible and break all your code.
|
||||
|
||||
============================
|
||||
The Goals Of Argument Clinic
|
||||
============================
|
||||
|
||||
Argument Clinic's primary goal
|
||||
is to take over responsibility for all argument parsing code
|
||||
inside CPython. This means that, when you convert a function
|
||||
to work with Argument Clinic, that function should no longer
|
||||
do any of its own argument parsing--the code generated by
|
||||
Argument Clinic should be a "black box" to you, where CPython
|
||||
calls in at the top, and your code gets called at the bottom,
|
||||
with ``PyObject *args`` (and maybe ``PyObject *kwargs``)
|
||||
magically converted into the C variables and types you need.
|
||||
|
||||
In order for Argument Clinic to accomplish its primary goal,
|
||||
it must be easy to use. Currently, working with CPython's
|
||||
argument parsing library is a chore, requiring maintaining
|
||||
redundant information in a surprising number of places.
|
||||
When you use Argument Clinic, you don't have to repeat yourself.
|
||||
|
||||
Obviously, no one would want to use Argument Clinic unless
|
||||
it's solving a their problem without creating problems of
|
||||
its own.
|
||||
So Argument Clinic should generate correct code, and its
|
||||
code should preferably be slower, and definitely should
|
||||
not introduce a major speed regression. (Eventually Argument
|
||||
Clinic should enable a major speedup--we should be able
|
||||
to rewrite its code generator so it produces tailor-made
|
||||
parsing code, rather than using the general-purpose functions
|
||||
from the CPython code base, which would make for the fastest
|
||||
argument parsing possible.)
|
||||
|
||||
Additionally, Argument Clinic must be flexible enough to
|
||||
work with any approach to argument parsing. Python has
|
||||
some functions with some very strange parsing behaviors;
|
||||
Argument Clinic's goal is to support all of them.
|
||||
|
||||
Finally, the original motivation for Argument Clinic was
|
||||
to provide introspection "signatures" for CPython builtins.
|
||||
It used to be, the introspection query functions would throw
|
||||
an exception if you passed in a builtin. With Argument
|
||||
Clinic, that's a thing of the past!
|
||||
|
||||
One idea you should keep in mind, as you work with
|
||||
Argument Clinic: the more information you give it, the
|
||||
better job it'll be able to do.
|
||||
Argument Clinic is admittedly relatively simple right
|
||||
now. But as it evolves it will get more sophisticated,
|
||||
and it should be able to do many interesting and smart
|
||||
things with all the information you give it.
|
||||
|
||||
|
||||
========================
|
||||
Basic Concepts And Usage
|
||||
========================
|
||||
|
@ -84,7 +136,15 @@ Converting Your First Function
|
|||
==============================
|
||||
|
||||
The best way to get a sense of how Argument Clinic works is to
|
||||
convert a function to work with it. Let's dive in!
|
||||
convert a function to work with it. Here, then, are the bare
|
||||
minimum steps you'd need to follow to convert a function to
|
||||
work with Argument Clinic. Note that for code you plan to
|
||||
check in to CPython, you really should take the conversion farther,
|
||||
using some of the advanced concepts you'll see later on in
|
||||
the document (like "return converters" and "self converters").
|
||||
But we'll keep it simple for this walkthrough so you can learn.
|
||||
|
||||
Let's dive in!
|
||||
|
||||
0. Make sure you're working with a freshly updated checkout
|
||||
of the CPython trunk.
|
||||
|
@ -1282,6 +1342,264 @@ 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.)
|
||||
|
||||
|
||||
Changing and redirecting Clinic's output
|
||||
----------------------------------------
|
||||
|
||||
It can be inconvenient to have Clinic's output interspersed with
|
||||
your conventional hand-edited C code. Luckily, Clinic is configurable:
|
||||
you can buffer up its output for printing later (or earlier!), or write
|
||||
its output to a separate file. You can also add a prefix or suffix to
|
||||
every line of Clinic's generated output.
|
||||
|
||||
While changing Clinic's output in this manner can be a boon to readability,
|
||||
it may result in Clinic code using types before they are defined, or
|
||||
your code attempting to use Clinic-generated code befire it is defined.
|
||||
These problems can be easily solved by rearranging the declarations in your file,
|
||||
or moving where Clinic's generated code goes. (This is why the default behavior
|
||||
of Clinic is to output everything into the current block; while many people
|
||||
consider this hampers readability, it will never require rearranging your
|
||||
code to fix definition-before-use problems.)
|
||||
|
||||
Let's start with defining some terminology:
|
||||
|
||||
*field*
|
||||
A field, in this context, is a subsection of Clinic's output.
|
||||
For example, the ``#define`` for the ``PyMethodDef`` structure
|
||||
is a field, called ``methoddef_define``. Clinic has seven
|
||||
different fields it can output per function definition::
|
||||
|
||||
docstring_prototype
|
||||
docstring_definition
|
||||
methoddef_define
|
||||
impl_prototype
|
||||
parser_prototype
|
||||
parser_definition
|
||||
impl_definition
|
||||
|
||||
All the names are of the form ``"<a>_<b>"``,
|
||||
where ``"<a>"`` is the semantic object represented (the parsing function,
|
||||
the impl function, the docstring, or the methoddef structure) and ``"<b>"``
|
||||
represents what kind of statement the field is. Field names that end in
|
||||
``"_prototype"``
|
||||
represent forward declarations of that thing, without the actual body/data
|
||||
of the thing; field names that end in ``"_definition"`` represent the actual
|
||||
definition of the thing, with the body/data of the thing. (``"methoddef"``
|
||||
is special, it's the only one that ends with ``"_define"``, representing that
|
||||
it's a preprocessor #define.)
|
||||
|
||||
*destination*
|
||||
A destination is a place Clinic can write output to. There are
|
||||
five built-in destinations:
|
||||
|
||||
``block``
|
||||
The default destination: printed in the output section of
|
||||
the current Clinic block.
|
||||
|
||||
``buffer``
|
||||
A text buffer where you can save text for later. Text sent
|
||||
here is appended to the end of any exsiting text. It's an
|
||||
error to have any text left in the buffer when Clinic finishes
|
||||
processing a file.
|
||||
|
||||
``file``
|
||||
A separate "clinic file" that will be created automatically by Clinic.
|
||||
The filename chosen for the file is ``{basename}.clinic{extension}``,
|
||||
where ``basename`` and ``extension`` were assigned the output
|
||||
from ``os.path.splitext()`` run on the current file. (Example:
|
||||
the ``file`` destination for ``_pickle.c`` would be written to
|
||||
``_pickle.clinic.c``.)
|
||||
|
||||
**Important: When using a** ``file`` **destination, you**
|
||||
*must check in* **the generated file!**
|
||||
|
||||
``two-pass``
|
||||
A buffer like ``buffer``. However, a two-pass buffer can only
|
||||
be written once, and it prints out all text sent to it during
|
||||
all of processing, even from Clinic blocks *after* the
|
||||
|
||||
``suppress``
|
||||
The text is suppressed--thrown away.
|
||||
|
||||
|
||||
Clinic defines five new directives that let you reconfigure its output.
|
||||
|
||||
The first new directive is ``dump``::
|
||||
|
||||
dump <destination>
|
||||
|
||||
This dumps the current contents of the named destination into the output of
|
||||
the current block, and empties it. This only works with ``buffer`` and
|
||||
``two-pass`` destinations.
|
||||
|
||||
The second new directive is ``output``. The most basic form of ``output``
|
||||
is like this::
|
||||
|
||||
output <field> <destination>
|
||||
|
||||
This tells Clinic to output *field* to *destination*. ``output`` also
|
||||
supports a special meta-destination, called ``everything``, which tells
|
||||
Clinic to output *all* fields to that *destination*.
|
||||
|
||||
``output`` has a number of other functions::
|
||||
|
||||
output push
|
||||
output pop
|
||||
output preset <preset>
|
||||
|
||||
|
||||
``output push`` and ``output pop`` allow you to push and pop
|
||||
configurations on an internal configuration stack, so that you
|
||||
can temporarily modify the output configuration, then easily restore
|
||||
the previous configuration. Simply push before your change to save
|
||||
the current configuration, then pop when you wish to restore the
|
||||
previous configuration.
|
||||
|
||||
``output preset`` sets Clinic's output to one of several built-in
|
||||
preset configurations, as follows:
|
||||
|
||||
``original``
|
||||
Clinic's starting configuration.
|
||||
|
||||
Suppress the ``parser_prototype``
|
||||
and ``docstring_prototype``, write everything else to ``block``.
|
||||
|
||||
``file``
|
||||
Designed to write everything to the "clinic file" that it can.
|
||||
You then ``#include`` this file near the top of your file.
|
||||
You may need to rearrange your file to make this work, though
|
||||
usually this just means creating forward declarations for various
|
||||
``typedef`` and ``PyTypeObject`` definitions.
|
||||
|
||||
Suppress the ``parser_prototype``
|
||||
and ``docstring_prototype``, write the ``impl_definition`` to
|
||||
``block``, and write everything else to ``file``.
|
||||
|
||||
``buffer``
|
||||
Save up all most of the output from Clinic, to be written into
|
||||
your file near the end. For Python files implementing modules
|
||||
or builtin types, it's recommended that you dump the buffer
|
||||
just above the static structures for your module or
|
||||
builtin type; these are normally very near the end. Using
|
||||
``buffer`` may require even more editing than ``file``, if
|
||||
your file has static ``PyMethodDef`` arrays defined in the
|
||||
middle of the file.
|
||||
|
||||
Suppress the ``parser_prototype``, ``impl_prototype``,
|
||||
and ``docstring_prototype``, write the ``impl_definition`` to
|
||||
``block``, and write everything else to ``file``.
|
||||
|
||||
``two-pass``
|
||||
Similar to the ``buffer`` preset, but writes forward declarations to
|
||||
the ``two-pass`` buffer, and definitions to the ``buffer``.
|
||||
This is similar to the ``buffer`` preset, but may require
|
||||
less editing than ``buffer``. Dump the ``two-pass`` buffer
|
||||
near the top of your file, and dump the ``buffer`` near
|
||||
the end just like you would when using the ``buffer`` preset.
|
||||
|
||||
Suppresses the ``impl_prototype``, write the ``impl_definition``
|
||||
to ``block``, write ``docstring_prototype``, ``methoddef_define``,
|
||||
and ``parser_prototype`` to ``two-pass``, write everything else
|
||||
to ``buffer``.
|
||||
|
||||
``partial-buffer``
|
||||
Similar to the ``buffer`` preset, but writes more things to ``block``,
|
||||
only writing the really big chunks of generated code to ``buffer``.
|
||||
This avoids the definition-before-use problem of ``buffer`` completely,
|
||||
at the small cost of having slightly more stuff in the block's output.
|
||||
Dump the ``buffer`` near the end, just like you would when using
|
||||
the ``buffer`` preset.
|
||||
|
||||
Suppresses the ``impl_prototype``, write the ``docstring_definition``
|
||||
and ``parser_defintion`` to ``buffer``, write everything else to ``block``.
|
||||
|
||||
The third new directive is ``destination``::
|
||||
|
||||
destination <name> <command> [...]
|
||||
|
||||
This performs an operation on the destination named ``name``.
|
||||
|
||||
There are two defined subcommands: ``new`` and ``clear``.
|
||||
|
||||
The ``new`` subcommand works like this::
|
||||
|
||||
destination <name> new <type>
|
||||
|
||||
This creates a new destination with name ``<name>`` and type ``<type>``.
|
||||
|
||||
There are five destination types::
|
||||
|
||||
``suppress``
|
||||
Throws the text away.
|
||||
|
||||
``block``
|
||||
Writes the text to the current block. This is what Clinic
|
||||
originally did.
|
||||
|
||||
``buffer``
|
||||
A simple text buffer, like the "buffer" builtin destination above.
|
||||
|
||||
``file``
|
||||
A text file. The file destination takes an extra argument,
|
||||
a template to use for building the filename, like so:
|
||||
|
||||
destination <name> new <type> <file_template>
|
||||
|
||||
The template can use three strings internally that will be replaced
|
||||
by bits of the filename:
|
||||
|
||||
{filename}
|
||||
The full filename.
|
||||
{basename}
|
||||
Everything up to but not including the last '.'.
|
||||
{extension}
|
||||
The last '.' and everything after it.
|
||||
|
||||
If there are no periods in the filename, {basename} and {filename}
|
||||
are the same, and {extension} is empty. "{basename}{extension}"
|
||||
is always exactly the same as "{filename}"."
|
||||
|
||||
``two-pass``
|
||||
A two-pass buffer, like the "two-pass" builtin destination above.
|
||||
|
||||
|
||||
The ``clear`` subcommand works like this::
|
||||
|
||||
destination <name> clear
|
||||
|
||||
It removes all the accumulated text up to this point in the destination.
|
||||
(I don't know what you'd need this for, but I thought maybe it'd be
|
||||
useful while someone's experimenting.)
|
||||
|
||||
The fourth new directive is ``set``::
|
||||
|
||||
set line_prefix "string"
|
||||
set line_suffix "string"
|
||||
|
||||
``set`` lets you set two internal variables in Clinic.
|
||||
``line_prefix`` is a string that will be prepended to every line of Clinic's output;
|
||||
``line_suffix`` is a string that will be appended to every line of Clinic's output.
|
||||
|
||||
Both of these suport two format strings:
|
||||
|
||||
``{block comment start}``
|
||||
Turns into the string ``/*``, the start-comment text sequence for C files.
|
||||
|
||||
``{block comment end}``
|
||||
Turns into the string ``*/``, the end-comment text sequence for C files.
|
||||
|
||||
The final new directive is one you shouldn't need to use directly,
|
||||
called ``preserve``::
|
||||
|
||||
preserve
|
||||
|
||||
This tells Clinic that the current contents of the output should be kept, unmodifed.
|
||||
This is used internally by Clinic when dumping output into ``file`` files; wrapping
|
||||
it in a Clinic block lets Clinic use its existing checksum functionality to ensure
|
||||
the file was not modified by hand before it gets overwritten.
|
||||
|
||||
|
||||
Using Argument Clinic in Python files
|
||||
-------------------------------------
|
||||
|
||||
It's actually possible to use Argument Clinic to preprocess Python files.
|
||||
|
|
|
@ -88,6 +88,9 @@ Tests
|
|||
Tools/Demos
|
||||
-----------
|
||||
|
||||
- Issue #20287: Argument Clinic's output is now configurable, allowing
|
||||
delaying its output or even redirecting it to a separate file.
|
||||
|
||||
- Issue #20226: Argument Clinic now permits simple expressions
|
||||
(e.g. "sys.maxsize - 1") as default values for parameters.
|
||||
|
||||
|
|
|
@ -3906,16 +3906,12 @@ _pickle_Pickler_clear_memo_impl(PicklerObject *self);
|
|||
static PyObject *
|
||||
_pickle_Pickler_clear_memo(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
|
||||
return_value = _pickle_Pickler_clear_memo_impl((PicklerObject *)self);
|
||||
|
||||
return return_value;
|
||||
return _pickle_Pickler_clear_memo_impl((PicklerObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_pickle_Pickler_clear_memo_impl(PicklerObject *self)
|
||||
/*[clinic end generated code: checksum=0574593b102fffb8e781d7bb9b536ceffc525ac1]*/
|
||||
/*[clinic end generated code: checksum=015cc3c5befea86cb08b9396938477bebbea4157]*/
|
||||
{
|
||||
if (self->memo)
|
||||
PyMemoTable_Clear(self->memo);
|
||||
|
@ -4191,16 +4187,12 @@ _pickle_PicklerMemoProxy_clear_impl(PicklerMemoProxyObject *self);
|
|||
static PyObject *
|
||||
_pickle_PicklerMemoProxy_clear(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
|
||||
return_value = _pickle_PicklerMemoProxy_clear_impl((PicklerMemoProxyObject *)self);
|
||||
|
||||
return return_value;
|
||||
return _pickle_PicklerMemoProxy_clear_impl((PicklerMemoProxyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_pickle_PicklerMemoProxy_clear_impl(PicklerMemoProxyObject *self)
|
||||
/*[clinic end generated code: checksum=c6ca252530ccb3ea2f4b33507b51b183f23b24c7]*/
|
||||
/*[clinic end generated code: checksum=bf8dd8c8688d0c0f7a2e59a804c47375b740f2f0]*/
|
||||
{
|
||||
if (self->pickler->memo)
|
||||
PyMemoTable_Clear(self->pickler->memo);
|
||||
|
@ -4228,16 +4220,12 @@ _pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self);
|
|||
static PyObject *
|
||||
_pickle_PicklerMemoProxy_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
|
||||
return_value = _pickle_PicklerMemoProxy_copy_impl((PicklerMemoProxyObject *)self);
|
||||
|
||||
return return_value;
|
||||
return _pickle_PicklerMemoProxy_copy_impl((PicklerMemoProxyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self)
|
||||
/*[clinic end generated code: checksum=808c4d5a37359ed5fb2efe81dbe5ff480719f470]*/
|
||||
/*[clinic end generated code: checksum=72d46879dc658adbd3d28b5c82dd8dcfa6b9b124]*/
|
||||
{
|
||||
Py_ssize_t i;
|
||||
PyMemoTable *memo;
|
||||
|
@ -4295,16 +4283,12 @@ _pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self);
|
|||
static PyObject *
|
||||
_pickle_PicklerMemoProxy___reduce__(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
|
||||
return_value = _pickle_PicklerMemoProxy___reduce___impl((PicklerMemoProxyObject *)self);
|
||||
|
||||
return return_value;
|
||||
return _pickle_PicklerMemoProxy___reduce___impl((PicklerMemoProxyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self)
|
||||
/*[clinic end generated code: checksum=2293152bdf53951a012d430767b608f5fb4213b5]*/
|
||||
/*[clinic end generated code: checksum=aad71c4d81d1ed8bf0d32362dd80a29b9f3b0d03]*/
|
||||
{
|
||||
PyObject *reduce_value, *dict_args;
|
||||
PyObject *contents = _pickle_PicklerMemoProxy_copy_impl(self);
|
||||
|
@ -6342,16 +6326,12 @@ _pickle_Unpickler_load_impl(PyObject *self);
|
|||
static PyObject *
|
||||
_pickle_Unpickler_load(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
|
||||
return_value = _pickle_Unpickler_load_impl(self);
|
||||
|
||||
return return_value;
|
||||
return _pickle_Unpickler_load_impl(self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_pickle_Unpickler_load_impl(PyObject *self)
|
||||
/*[clinic end generated code: checksum=55f35fcaf034817e75c355ec50b7878577355899]*/
|
||||
/*[clinic end generated code: checksum=9477099fe6a90748c13ff1a6dd92ba7ab7a89602]*/
|
||||
{
|
||||
UnpicklerObject *unpickler = (UnpicklerObject*)self;
|
||||
|
||||
|
@ -6417,8 +6397,8 @@ _pickle_Unpickler_find_class(PyObject *self, PyObject *args)
|
|||
PyObject *module_name;
|
||||
PyObject *global_name;
|
||||
|
||||
if (!PyArg_ParseTuple(args,
|
||||
"OO:find_class",
|
||||
if (!PyArg_UnpackTuple(args, "find_class",
|
||||
2, 2,
|
||||
&module_name, &global_name))
|
||||
goto exit;
|
||||
return_value = _pickle_Unpickler_find_class_impl((UnpicklerObject *)self, module_name, global_name);
|
||||
|
@ -6429,7 +6409,7 @@ exit:
|
|||
|
||||
static PyObject *
|
||||
_pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyObject *module_name, PyObject *global_name)
|
||||
/*[clinic end generated code: checksum=1f353d13a32c9d94feb1466b3c2d0529a7e5650e]*/
|
||||
/*[clinic end generated code: checksum=15ed4836fd5860425fff9ea7855d4f1f4413c170]*/
|
||||
{
|
||||
PyObject *global;
|
||||
PyObject *modules_dict;
|
||||
|
@ -6752,16 +6732,12 @@ _pickle_UnpicklerMemoProxy_clear_impl(UnpicklerMemoProxyObject *self);
|
|||
static PyObject *
|
||||
_pickle_UnpicklerMemoProxy_clear(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
|
||||
return_value = _pickle_UnpicklerMemoProxy_clear_impl((UnpicklerMemoProxyObject *)self);
|
||||
|
||||
return return_value;
|
||||
return _pickle_UnpicklerMemoProxy_clear_impl((UnpicklerMemoProxyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_pickle_UnpicklerMemoProxy_clear_impl(UnpicklerMemoProxyObject *self)
|
||||
/*[clinic end generated code: checksum=e0f99c26d48444a3f58f598bec3190c66595fce7]*/
|
||||
/*[clinic end generated code: checksum=07adecee2181e5e268b2ff184360b1d88ad947f2]*/
|
||||
{
|
||||
_Unpickler_MemoCleanup(self->unpickler);
|
||||
self->unpickler->memo = _Unpickler_NewMemo(self->unpickler->memo_size);
|
||||
|
@ -6791,16 +6767,12 @@ _pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self);
|
|||
static PyObject *
|
||||
_pickle_UnpicklerMemoProxy_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
|
||||
return_value = _pickle_UnpicklerMemoProxy_copy_impl((UnpicklerMemoProxyObject *)self);
|
||||
|
||||
return return_value;
|
||||
return _pickle_UnpicklerMemoProxy_copy_impl((UnpicklerMemoProxyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self)
|
||||
/*[clinic end generated code: checksum=8c0ab91c0b694ea71a1774650898a760d1ab4765]*/
|
||||
/*[clinic end generated code: checksum=47b9f0cc12c5a54004252e1b4916822cdfa8a881]*/
|
||||
{
|
||||
Py_ssize_t i;
|
||||
PyObject *new_memo = PyDict_New();
|
||||
|
@ -6851,16 +6823,12 @@ _pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self);
|
|||
static PyObject *
|
||||
_pickle_UnpicklerMemoProxy___reduce__(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
|
||||
return_value = _pickle_UnpicklerMemoProxy___reduce___impl((UnpicklerMemoProxyObject *)self);
|
||||
|
||||
return return_value;
|
||||
return _pickle_UnpicklerMemoProxy___reduce___impl((UnpicklerMemoProxyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self)
|
||||
/*[clinic end generated code: checksum=4ee76a65511291f0de2e9e63db395d2e5d6d8df6]*/
|
||||
/*[clinic end generated code: checksum=2f061bb9ecd9ee8500184c135148a131c46a3b88]*/
|
||||
{
|
||||
PyObject *reduce_value;
|
||||
PyObject *constructor_args;
|
||||
|
|
|
@ -34,6 +34,7 @@ _weakref_getweakrefcount(PyModuleDef *module, PyObject *object)
|
|||
{
|
||||
PyObject *return_value = NULL;
|
||||
Py_ssize_t _return_value;
|
||||
|
||||
_return_value = _weakref_getweakrefcount_impl(module, object);
|
||||
if ((_return_value == -1) && PyErr_Occurred())
|
||||
goto exit;
|
||||
|
@ -45,7 +46,7 @@ exit:
|
|||
|
||||
static Py_ssize_t
|
||||
_weakref_getweakrefcount_impl(PyModuleDef *module, PyObject *object)
|
||||
/*[clinic end generated code: checksum=436e8fbe0297434375f039d8c2d9fc3a9bbe773c]*/
|
||||
/*[clinic end generated code: checksum=744fa73ba68c0ee89567e9cb9bea11863270d516]*/
|
||||
{
|
||||
PyWeakReference **list;
|
||||
|
||||
|
|
|
@ -1047,16 +1047,12 @@ zlib_Compress_copy_impl(compobject *self);
|
|||
static PyObject *
|
||||
zlib_Compress_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
|
||||
return_value = zlib_Compress_copy_impl((compobject *)self);
|
||||
|
||||
return return_value;
|
||||
return zlib_Compress_copy_impl((compobject *)self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
zlib_Compress_copy_impl(compobject *self)
|
||||
/*[clinic end generated code: checksum=2f454ee15be3bc53cfb4e845c3f891f68be4c8e4]*/
|
||||
/*[clinic end generated code: checksum=d57a7911deb7940e85a8d7e65af20b6e2df69000]*/
|
||||
{
|
||||
compobject *retval = NULL;
|
||||
int err;
|
||||
|
|
|
@ -246,16 +246,12 @@ _imp_lock_held_impl(PyModuleDef *module);
|
|||
static PyObject *
|
||||
_imp_lock_held(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
|
||||
return_value = _imp_lock_held_impl(module);
|
||||
|
||||
return return_value;
|
||||
return _imp_lock_held_impl(module);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_imp_lock_held_impl(PyModuleDef *module)
|
||||
/*[clinic end generated code: checksum=c5858b257881f94dee95526229a8d1a57ccff158]*/
|
||||
/*[clinic end generated code: checksum=ede1cafb78eb22e3009602f684c8b780e2b82d62]*/
|
||||
{
|
||||
#ifdef WITH_THREAD
|
||||
return PyBool_FromLong(import_lock_thread != -1);
|
||||
|
@ -289,16 +285,12 @@ _imp_acquire_lock_impl(PyModuleDef *module);
|
|||
static PyObject *
|
||||
_imp_acquire_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
|
||||
return_value = _imp_acquire_lock_impl(module);
|
||||
|
||||
return return_value;
|
||||
return _imp_acquire_lock_impl(module);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_imp_acquire_lock_impl(PyModuleDef *module)
|
||||
/*[clinic end generated code: checksum=badb56ed0079a6b902c9616fe068d572765b1863]*/
|
||||
/*[clinic end generated code: checksum=5b520b2416c5954a7cf0ed30955d68abe20b5868]*/
|
||||
{
|
||||
#ifdef WITH_THREAD
|
||||
_PyImport_AcquireLock();
|
||||
|
@ -330,16 +322,12 @@ _imp_release_lock_impl(PyModuleDef *module);
|
|||
static PyObject *
|
||||
_imp_release_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
|
||||
return_value = _imp_release_lock_impl(module);
|
||||
|
||||
return return_value;
|
||||
return _imp_release_lock_impl(module);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_imp_release_lock_impl(PyModuleDef *module)
|
||||
/*[clinic end generated code: checksum=f1c2a75e3136a113184e0af2a676d5f0b5b685b4]*/
|
||||
/*[clinic end generated code: checksum=efcd9d2923294c04371596e7f6d66a706d43fcac]*/
|
||||
{
|
||||
#ifdef WITH_THREAD
|
||||
if (_PyImport_ReleaseLock() < 0) {
|
||||
|
@ -1847,16 +1835,12 @@ _imp_extension_suffixes_impl(PyModuleDef *module);
|
|||
static PyObject *
|
||||
_imp_extension_suffixes(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
|
||||
return_value = _imp_extension_suffixes_impl(module);
|
||||
|
||||
return return_value;
|
||||
return _imp_extension_suffixes_impl(module);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_imp_extension_suffixes_impl(PyModuleDef *module)
|
||||
/*[clinic end generated code: checksum=835921e67fd698e22e101eea64839d1ad62b6451]*/
|
||||
/*[clinic end generated code: checksum=82fb35d8429a429a4dc80c84b45b1aad73ff1de7]*/
|
||||
{
|
||||
PyObject *list;
|
||||
const char *suffix;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -34,6 +34,9 @@ class FakeConvertersDict:
|
|||
def get(self, name, default):
|
||||
return self.used_converters.setdefault(name, FakeConverterFactory(name))
|
||||
|
||||
clinic.Clinic.presets_text = ''
|
||||
c = clinic.Clinic(language='C')
|
||||
|
||||
class FakeClinic:
|
||||
def __init__(self):
|
||||
self.converters = FakeConvertersDict()
|
||||
|
@ -44,6 +47,32 @@ class FakeClinic:
|
|||
self.modules = collections.OrderedDict()
|
||||
clinic.clinic = self
|
||||
self.name = "FakeClinic"
|
||||
self.line_prefix = self.line_suffix = ''
|
||||
self.destinations = {}
|
||||
self.add_destination("block", "buffer")
|
||||
self.add_destination("file", "buffer")
|
||||
self.add_destination("suppress", "suppress")
|
||||
d = self.destinations.get
|
||||
self.field_destinations = collections.OrderedDict((
|
||||
('docstring_prototype', d('suppress')),
|
||||
('docstring_definition', d('block')),
|
||||
('methoddef_define', d('block')),
|
||||
('impl_prototype', d('block')),
|
||||
('parser_prototype', d('suppress')),
|
||||
('parser_definition', d('block')),
|
||||
('impl_definition', d('block')),
|
||||
))
|
||||
|
||||
def get_destination(self, name):
|
||||
d = self.destinations.get(name)
|
||||
if not d:
|
||||
sys.exit("Destination does not exist: " + repr(name))
|
||||
return d
|
||||
|
||||
def add_destination(self, name, type, *args):
|
||||
if name in self.destinations:
|
||||
sys.exit("Destination already exists: " + repr(name))
|
||||
self.destinations[name] = clinic.Destination(name, type, self, *args)
|
||||
|
||||
def is_directive(self, name):
|
||||
return name == "module"
|
||||
|
|
Loading…
Reference in New Issue