summaryrefslogtreecommitdiffstats
path: root/Doc/howto/clinic.rst
diff options
context:
space:
mode:
authorErlend E. Aasland <erlend@python.org>2023-07-26 20:54:25 (GMT)
committerGitHub <noreply@github.com>2023-07-26 20:54:25 (GMT)
commit592395577c679543d899e68a3cff538b8b4df80d (patch)
tree10f63421cece8f2552d91c999e999a96ab13f98c /Doc/howto/clinic.rst
parent5aa6964a5ca60dff5c5ab40b968d92b49bd13b3d (diff)
downloadcpython-592395577c679543d899e68a3cff538b8b4df80d.zip
cpython-592395577c679543d899e68a3cff538b8b4df80d.tar.gz
cpython-592395577c679543d899e68a3cff538b8b4df80d.tar.bz2
Docs: Remove the numbered steps from the Argument Clinic tutorial (#107203)
Instead, order the tutorial as one body of prose, making it easier to align the tutorial according to Diátaxis principles.
Diffstat (limited to 'Doc/howto/clinic.rst')
-rw-r--r--Doc/howto/clinic.rst624
1 files changed, 310 insertions, 314 deletions
diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst
index 98d3632..ea3b453 100644
--- a/Doc/howto/clinic.rst
+++ b/Doc/howto/clinic.rst
@@ -167,23 +167,23 @@ 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").
+using some of the :ref:`advanced concepts <clinic-howtos>`
+you'll see later on in the document,
+like :ref:`clinic-howto-return-converters`
+and :ref:`clinic-howto-self-converter`.
But we'll keep it simple for this walkthrough so you can learn.
-Let's dive in!
+First, make sure you're working with a freshly updated checkout
+of the CPython trunk.
-0. Make sure you're working with a freshly updated checkout
- of the CPython trunk.
+Next, find a Python builtin that calls either :c:func:`PyArg_ParseTuple`
+or :c:func:`PyArg_ParseTupleAndKeywords`, and hasn't been converted
+to work with Argument Clinic yet.
+For this tutorial, we'll be using
+:py:meth:`_pickle.Pickler.dump <pickle.Pickler.dump>`.
-1. Find a Python builtin that calls either :c:func:`PyArg_ParseTuple`
- or :c:func:`PyArg_ParseTupleAndKeywords`, and hasn't been converted
- to work with Argument Clinic yet.
- For my example I'm using
- :py:meth:`_pickle.Pickler.dump <pickle.Pickler.dump>`.
-
-2. If the call to the :c:func:`!PyArg_Parse*` function uses any of the
- following format units:
+If the call to the :c:func:`!PyArg_Parse*` function uses any of the
+following format units...:
.. code-block:: none
@@ -194,388 +194,377 @@ Let's dive in!
et
et#
- or if it has multiple calls to :c:func:`PyArg_ParseTuple`,
- you should choose a different function. Argument Clinic *does*
- 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
- :c:func:`!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]
- [clinic start generated code]*/
-
-4. Cut the docstring and paste it in between the ``[clinic]`` lines,
- removing all the junk that makes it a properly quoted C string.
- When you're done you should have just the text, based at the left
- 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 :py:func:`help` on your builtin in the future,
- the first line will be built automatically based on the function's
- signature.)
-
- Sample::
+... or if it has multiple calls to :c:func:`PyArg_ParseTuple`,
+you should choose a different function.
+(See :ref:`clinic-howto-advanced-converters` for those scenarios.)
- /*[clinic input]
- Write a pickled representation of obj to the open file.
- [clinic start generated code]*/
-
-5. If your docstring doesn't have a "summary" line, Argument Clinic will
- complain. So let's make sure it has one. The "summary" line should
- be a paragraph consisting of a single 80-column line
- at the beginning of the docstring.
-
- (Our example docstring consists solely of a summary line, so the sample
- code doesn't have to change for this step.)
+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
+:c:func:`!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.
-6. Above the docstring, enter the name of the function, followed
- by a blank line. This should be the Python name of the function,
- and should be the full dotted path
- to the function—it should start with the name of the module,
- include any sub-modules, and if the function is a method on
- a class it should include the class name too.
-
- Sample::
+Next, add the following boilerplate above the function,
+creating our input block::
/*[clinic input]
- _pickle.Pickler.dump
-
- Write a pickled representation of obj to the open file.
[clinic start generated code]*/
-7. If this is the first time that module or class has been used with Argument
- Clinic in this C file,
- you must declare the module and/or class. Proper Argument Clinic hygiene
- prefers declaring these in a separate block somewhere near the
- top of the C file, in the same way that include files and statics go at
- the top. (In our sample code we'll just show the two blocks next to
- each other.)
+Cut the docstring and paste it in between the ``[clinic]`` lines,
+removing all the junk that makes it a properly quoted C string.
+When you're done you should have just the text, based at the left
+margin, with no line wider than 80 characters.
+Argument Clinic will preserve indents inside the docstring.
- 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.
+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 :py:func:`help` on your builtin in the future,
+the first line will be built automatically based on the function's signature.
- When you declare a class, you must also specify two aspects of its type
- in C: the type declaration you'd use for a pointer to an instance of
- this class, and a pointer to the :c:type:`!PyTypeObject` for this class.
+Example docstring summary line::
- Sample::
-
- /*[clinic input]
- module _pickle
- class _pickle.Pickler "PicklerObject *" "&Pickler_Type"
- [clinic start generated code]*/
-
- /*[clinic input]
- _pickle.Pickler.dump
-
- Write a pickled representation of obj to the open file.
- [clinic start generated code]*/
-
-
-
-
-8. Declare each of the parameters to the function. Each parameter
- should get its own line. All the parameter lines should be
- indented from the function name and the docstring.
-
- The general form of these parameter lines is as follows:
-
- .. code-block:: none
-
- name_of_parameter: converter
-
- If the parameter has a default value, add that after the
- converter:
-
- .. code-block:: none
+ /*[clinic input]
+ Write a pickled representation of obj to the open file.
+ [clinic start generated code]*/
- name_of_parameter: converter = default_value
+If your docstring doesn't have a "summary" line, Argument Clinic will
+complain, so let's make sure it has one. The "summary" line should
+be a paragraph consisting of a single 80-column line
+at the beginning of the docstring.
+(See :pep:`257` regarding docstring conventions.)
- Argument Clinic's support for "default values" is quite sophisticated;
- please see :ref:`the section below on default values <default_values>`
- for more information.
+Our example docstring consists solely of a summary line, so the sample
+code doesn't have to change for this step.
- Add a blank line below the parameters.
+Now, above the docstring, enter the name of the function, followed
+by a blank line. This should be the Python name of the function,
+and should be the full dotted path to the function ---
+it should start with the name of the module,
+include any sub-modules, and if the function is a method on
+a class it should include the class name too.
- What's a "converter"? It establishes both the type
- of the variable used in C, and the method to convert the Python
- value into a C value at runtime.
- For now you're going to use what's called a "legacy converter"—a
- convenience syntax intended to make porting old code into Argument
- Clinic easier.
+In our example, :mod:`!_pickle` is the module, :py:class:`!Pickler` is the class,
+and :py:meth:`!dump` is the method, so the name becomes
+:py:meth:`!_pickle.Pickler.dump`::
- For each parameter, copy the "format unit" for that
- parameter from the :c:func:`PyArg_Parse` format argument and
- specify *that* as its converter, as a quoted
- string. ("format unit" is the formal name for the one-to-three
- character substring of the *format* parameter that tells
- the argument parsing function what the type of the variable
- is and how to convert it. For more on format units please
- see :ref:`arg-parsing`.)
+ /*[clinic input]
+ _pickle.Pickler.dump
- For multicharacter format units like ``z#``, use the
- entire two-or-three character string.
+ Write a pickled representation of obj to the open file.
+ [clinic start generated code]*/
- Sample::
+If this is the first time that module or class has been used with Argument
+Clinic in this C file,
+you must declare the module and/or class. Proper Argument Clinic hygiene
+prefers declaring these in a separate block somewhere near the
+top of the C file, in the same way that include files and statics go at
+the top.
+In our sample code we'll just show the two blocks next to each other.
- /*[clinic input]
- module _pickle
- class _pickle.Pickler "PicklerObject *" "&Pickler_Type"
- [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.
- /*[clinic input]
- _pickle.Pickler.dump
+When you declare a class, you must also specify two aspects of its type
+in C: the type declaration you'd use for a pointer to an instance of
+this class, and a pointer to the :c:type:`!PyTypeObject` for this class::
- obj: 'O'
+ /*[clinic input]
+ module _pickle
+ class _pickle.Pickler "PicklerObject *" "&Pickler_Type"
+ [clinic start generated code]*/
- Write a pickled representation of obj to the open file.
- [clinic start generated code]*/
+ /*[clinic input]
+ _pickle.Pickler.dump
-9. If your function has ``|`` in the format string, meaning some
- parameters have default values, you can ignore it. Argument
- Clinic infers which parameters are optional based on whether
- or not they have default values.
+ Write a pickled representation of obj to the open file.
+ [clinic start generated code]*/
- If your function has ``$`` in the format string, meaning it
- takes keyword-only arguments, specify ``*`` on a line by
- itself before the first keyword-only argument, indented the
- same as the parameter lines.
+Declare each of the parameters to the function. Each parameter
+should get its own line. All the parameter lines should be
+indented from the function name and the docstring.
+The general form of these parameter lines is as follows:
- (:py:meth:`!_pickle.Pickler.dump` has neither, so our sample is unchanged.)
+.. code-block:: none
+ name_of_parameter: converter
-10. If the existing C function calls :c:func:`PyArg_ParseTuple`
- (as opposed to :c:func:`PyArg_ParseTupleAndKeywords`), then all its
- arguments are positional-only.
+If the parameter has a default value, add that after the
+converter:
- To mark all parameters as positional-only in Argument Clinic,
- add a ``/`` on a line by itself after the last parameter,
- indented the same as the parameter lines.
+.. code-block:: none
- Currently this is all-or-nothing; either all parameters are
- positional-only, or none of them are. (In the future Argument
- Clinic may relax this restriction.)
+ name_of_parameter: converter = default_value
- Sample::
+Argument Clinic's support for "default values" is quite sophisticated;
+see :ref:`clinic-howto-default-values` for more information.
- /*[clinic input]
- module _pickle
- class _pickle.Pickler "PicklerObject *" "&Pickler_Type"
- [clinic start generated code]*/
+Next, add a blank line below the parameters.
- /*[clinic input]
- _pickle.Pickler.dump
+What's a "converter"?
+It establishes both the type of the variable used in C,
+and the method to convert the Python value into a C value at runtime.
+For now you're going to use what's called a "legacy converter" ---
+a convenience syntax intended to make porting old code into Argument
+Clinic easier.
- obj: 'O'
- /
+For each parameter, copy the "format unit" for that
+parameter from the :c:func:`PyArg_Parse` format argument and
+specify *that* as its converter, as a quoted string.
+The "format unit" is the formal name for the one-to-three
+character substring of the *format* parameter that tells
+the argument parsing function what the type of the variable
+is and how to convert it.
+For more on format units please see :ref:`arg-parsing`.
- Write a pickled representation of obj to the open file.
- [clinic start generated code]*/
+For multicharacter format units like ``z#``,
+use the entire two-or-three character string.
-11. It's helpful to write a per-parameter docstring for each parameter.
- But per-parameter docstrings are optional; you can skip this step
- if you prefer.
+Sample::
- Here's how to add a per-parameter docstring. The first line
- of the per-parameter docstring must be indented further than the
- parameter definition. The left margin of this first line establishes
- the left margin for the whole per-parameter docstring; all the text
- you write will be outdented by this amount. You can write as much
- text as you like, across multiple lines if you wish.
+ /*[clinic input]
+ module _pickle
+ class _pickle.Pickler "PicklerObject *" "&Pickler_Type"
+ [clinic start generated code]*/
- Sample::
+ /*[clinic input]
+ _pickle.Pickler.dump
- /*[clinic input]
- module _pickle
- class _pickle.Pickler "PicklerObject *" "&Pickler_Type"
- [clinic start generated code]*/
+ obj: 'O'
- /*[clinic input]
- _pickle.Pickler.dump
+ Write a pickled representation of obj to the open file.
+ [clinic start generated code]*/
- obj: 'O'
- The object to be pickled.
- /
+If your function has ``|`` in the format string,
+meaning some parameters have default values, you can ignore it.
+Argument Clinic infers which parameters are optional
+based on whether or not they have default values.
- Write a pickled representation of obj to the open file.
- [clinic start generated code]*/
+If your function has ``$`` in the format string,
+meaning it takes keyword-only arguments,
+specify ``*`` on a line by itself before the first keyword-only argument,
+indented the same as the parameter lines.
-12. Save and close the file, then run ``Tools/clinic/clinic.py`` on
- it. With luck everything worked---your block now has output, and
- a :file:`.c.h` file has been generated! Reopen the file in your
- text editor to see::
+:py:meth:`!_pickle.Pickler.dump` has neither, so our sample is unchanged.
- /*[clinic input]
- _pickle.Pickler.dump
+Next, if the existing C function calls :c:func:`PyArg_ParseTuple`
+(as opposed to :c:func:`PyArg_ParseTupleAndKeywords`), then all its
+arguments are positional-only.
- obj: 'O'
- The object to be pickled.
- /
+To mark parameters as positional-only in Argument Clinic,
+add a ``/`` on a line by itself after the last positional-only parameter,
+indented the same as the parameter lines.
- Write a pickled representation of obj to the open file.
- [clinic start generated code]*/
+Sample::
- static PyObject *
- _pickle_Pickler_dump(PicklerObject *self, PyObject *obj)
- /*[clinic end generated code: output=87ecad1261e02ac7 input=552eb1c0f52260d9]*/
+ /*[clinic input]
+ module _pickle
+ class _pickle.Pickler "PicklerObject *" "&Pickler_Type"
+ [clinic start generated code]*/
- Obviously, if Argument Clinic didn't produce any output, it's because
- it found an error in your input. Keep fixing your errors and retrying
- until Argument Clinic processes your file without complaint.
+ /*[clinic input]
+ _pickle.Pickler.dump
- For readability, most of the glue code has been generated to a :file:`.c.h`
- file. You'll need to include that in your original :file:`.c` file,
- typically right after the clinic module block::
+ obj: 'O'
+ /
- #include "clinic/_pickle.c.h"
+ Write a pickled representation of obj to the open file.
+ [clinic start generated code]*/
-13. Double-check that the argument-parsing code Argument Clinic generated
- looks basically the same as the existing code.
+It can be helpful to write a per-parameter docstring for each parameter.
+Since per-parameter docstrings are optional,
+you can skip this step if you prefer.
- First, ensure both places use the same argument-parsing function.
- The existing code must call either
- :c:func:`PyArg_ParseTuple` or :c:func:`PyArg_ParseTupleAndKeywords`;
- ensure that the code generated by Argument Clinic calls the
- *exact* same function.
+Nevertheless, here's how to add a per-parameter docstring.
+The first line of the per-parameter docstring
+must be indented further than the parameter definition.
+The left margin of this first line establishes
+the left margin for the whole per-parameter docstring;
+all the text you write will be outdented by this amount.
+You can write as much text as you like, across multiple lines if you wish.
- Second, the format string passed in to :c:func:`!PyArg_ParseTuple` or
- :c:func:`!PyArg_ParseTupleAndKeywords` should be *exactly* the same
- as the hand-written one in the existing function, up to the colon
- or semi-colon.
+Sample::
- (Argument Clinic always generates its format strings
- with a ``:`` followed by the name of the function. If the
- existing code's format string ends with ``;``, to provide
- usage help, this change is harmless—don't worry about it.)
+ /*[clinic input]
+ module _pickle
+ class _pickle.Pickler "PicklerObject *" "&Pickler_Type"
+ [clinic start generated code]*/
- Third, for parameters whose format units require two arguments
- (like a length variable, or an encoding string, or a pointer
- to a conversion function), ensure that the second argument is
- *exactly* the same between the two invocations.
+ /*[clinic input]
+ _pickle.Pickler.dump
- Fourth, inside the output portion of the block you'll find a preprocessor
- macro defining the appropriate static :c:type:`PyMethodDef` structure for
- this builtin::
+ obj: 'O'
+ The object to be pickled.
+ /
- #define __PICKLE_PICKLER_DUMP_METHODDEF \
- {"dump", (PyCFunction)__pickle_Pickler_dump, METH_O, __pickle_Pickler_dump__doc__},
+ Write a pickled representation of obj to the open file.
+ [clinic start generated code]*/
- This static structure should be *exactly* the same as the existing static
- :c:type:`!PyMethodDef` structure for this builtin.
+Save and close the file, then run ``Tools/clinic/clinic.py`` on it.
+With luck everything worked---your block now has output,
+and a :file:`.c.h` file has been generated!
+Reload the file in your text editor to see the generated code::
- If any of these items differ in *any way*,
- adjust your Argument Clinic function specification and rerun
- ``Tools/clinic/clinic.py`` until they *are* the same.
+ /*[clinic input]
+ _pickle.Pickler.dump
+ obj: 'O'
+ The object to be pickled.
+ /
-14. Notice that the last line of its output is the declaration
- of your "impl" function. This is where the builtin's implementation goes.
- Delete the existing prototype of the function you're modifying, but leave
- the opening curly brace. Now delete its argument parsing code and the
- declarations of all the variables it dumps the arguments into.
- Notice how the Python arguments are now arguments to this impl function;
- if the implementation used different names for these variables, fix it.
+ Write a pickled representation of obj to the open file.
+ [clinic start generated code]*/
- Let's reiterate, just because it's kind of weird. Your code should now
- look like this::
+ static PyObject *
+ _pickle_Pickler_dump(PicklerObject *self, PyObject *obj)
+ /*[clinic end generated code: output=87ecad1261e02ac7 input=552eb1c0f52260d9]*/
- static return_type
- your_function_impl(...)
- /*[clinic end generated code: checksum=...]*/
- {
- ...
+Obviously, if Argument Clinic didn't produce any output,
+it's because it found an error in your input.
+Keep fixing your errors and retrying until Argument Clinic processes your file
+without complaint.
- Argument Clinic generated the checksum line and the function prototype just
- above it. You should write the opening (and closing) curly braces for the
- function, and the implementation inside.
+For readability, most of the glue code has been generated to a :file:`.c.h`
+file. You'll need to include that in your original :file:`.c` file,
+typically right after the clinic module block::
- Sample::
+ #include "clinic/_pickle.c.h"
- /*[clinic input]
- module _pickle
- class _pickle.Pickler "PicklerObject *" "&Pickler_Type"
- [clinic start generated code]*/
- /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
+Double-check that the argument-parsing code Argument Clinic generated
+looks basically the same as the existing code.
- /*[clinic input]
- _pickle.Pickler.dump
+First, ensure both places use the same argument-parsing function.
+The existing code must call either
+:c:func:`PyArg_ParseTuple` or :c:func:`PyArg_ParseTupleAndKeywords`;
+ensure that the code generated by Argument Clinic calls the
+*exact* same function.
- obj: 'O'
- The object to be pickled.
- /
+Second, the format string passed in to :c:func:`!PyArg_ParseTuple` or
+:c:func:`!PyArg_ParseTupleAndKeywords` should be *exactly* the same
+as the hand-written one in the existing function,
+up to the colon or semi-colon.
- Write a pickled representation of obj to the open file.
- [clinic start generated code]*/
+Argument Clinic always generates its format strings
+with a ``:`` followed by the name of the function.
+If the existing code's format string ends with ``;``,
+to provide usage help, this change is harmless --- don't worry about it.
- PyDoc_STRVAR(__pickle_Pickler_dump__doc__,
- "Write a pickled representation of obj to the open file.\n"
- "\n"
- ...
- static PyObject *
- _pickle_Pickler_dump_impl(PicklerObject *self, PyObject *obj)
- /*[clinic end generated code: checksum=3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/
- {
- /* Check whether the Pickler was initialized correctly (issue3664).
- Developers often forget to call __init__() in their subclasses, which
- would trigger a segfault without this check. */
- if (self->write == NULL) {
- PyErr_Format(PicklingError,
- "Pickler.__init__() was not called by %s.__init__()",
- Py_TYPE(self)->tp_name);
- return NULL;
- }
+Third, for parameters whose format units require two arguments,
+like a length variable, an encoding string, or a pointer
+to a conversion function, ensure that the second argument is
+*exactly* the same between the two invocations.
- if (_Pickler_ClearBuffer(self) < 0)
- return NULL;
+Fourth, inside the output portion of the block,
+you'll find a preprocessor macro defining the appropriate static
+:c:type:`PyMethodDef` structure for this builtin::
- ...
+ #define __PICKLE_PICKLER_DUMP_METHODDEF \
+ {"dump", (PyCFunction)__pickle_Pickler_dump, METH_O, __pickle_Pickler_dump__doc__},
-15. Remember the macro with the :c:type:`PyMethodDef` structure for this
- function? Find the existing :c:type:`!PyMethodDef` structure for this
- function and replace it with a reference to the macro. (If the builtin
- is at module scope, this will probably be very near the end of the file;
- if the builtin is a class method, this will probably be below but relatively
- near to the implementation.)
+This static structure should be *exactly* the same as the existing static
+:c:type:`!PyMethodDef` structure for this builtin.
- Note that the body of the macro contains a trailing comma. So when you
- replace the existing static :c:type:`!PyMethodDef` structure with the macro,
- *don't* add a comma to the end.
+If any of these items differ in *any way*,
+adjust your Argument Clinic function specification and rerun
+``Tools/clinic/clinic.py`` until they *are* the same.
- Sample::
+Notice that the last line of its output is the declaration
+of your "impl" function. This is where the builtin's implementation goes.
+Delete the existing prototype of the function you're modifying, but leave
+the opening curly brace. Now delete its argument parsing code and the
+declarations of all the variables it dumps the arguments into.
+Notice how the Python arguments are now arguments to this impl function;
+if the implementation used different names for these variables, fix it.
- static struct PyMethodDef Pickler_methods[] = {
- __PICKLE_PICKLER_DUMP_METHODDEF
- __PICKLE_PICKLER_CLEAR_MEMO_METHODDEF
- {NULL, NULL} /* sentinel */
- };
+Let's reiterate, just because it's kind of weird.
+Your code should now look like this::
+ static return_type
+ your_function_impl(...)
+ /*[clinic end generated code: input=..., output=...]*/
+ {
+ ...
-16. Argument Clinic may generate new instances of ``_Py_ID``. For example::
+Argument Clinic generated the checksum line and the function prototype just
+above it. You should write the opening and closing curly braces for the
+function, and the implementation inside.
- &_Py_ID(new_unique_py_id)
+Sample::
- If it does, you'll have to run ``make regen-global-objects``
- to regenerate the list of precompiled identifiers at this point.
+ /*[clinic input]
+ module _pickle
+ class _pickle.Pickler "PicklerObject *" "&Pickler_Type"
+ [clinic start generated code]*/
+ /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
+ /*[clinic input]
+ _pickle.Pickler.dump
-17. Compile, then run the relevant portions of the regression-test suite.
- This change should not introduce any new compile-time warnings or errors,
- and there should be no externally visible change to Python's behavior.
+ obj: 'O'
+ The object to be pickled.
+ /
- Well, except for one difference: :py:func:`inspect.signature` run on your function
- should now provide a valid signature!
+ Write a pickled representation of obj to the open file.
+ [clinic start generated code]*/
- Congratulations, you've ported your first function to work with Argument Clinic!
+ PyDoc_STRVAR(__pickle_Pickler_dump__doc__,
+ "Write a pickled representation of obj to the open file.\n"
+ "\n"
+ ...
+ static PyObject *
+ _pickle_Pickler_dump_impl(PicklerObject *self, PyObject *obj)
+ /*[clinic end generated code: checksum=3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/
+ {
+ /* Check whether the Pickler was initialized correctly (issue3664).
+ Developers often forget to call __init__() in their subclasses, which
+ would trigger a segfault without this check. */
+ if (self->write == NULL) {
+ PyErr_Format(PicklingError,
+ "Pickler.__init__() was not called by %s.__init__()",
+ Py_TYPE(self)->tp_name);
+ return NULL;
+ }
+
+ if (_Pickler_ClearBuffer(self) < 0) {
+ return NULL;
+ }
+
+ ...
+
+Remember the macro with the :c:type:`PyMethodDef` structure for this function?
+Find the existing :c:type:`!PyMethodDef` structure for this
+function and replace it with a reference to the macro. If the builtin
+is at module scope, this will probably be very near the end of the file;
+if the builtin is a class method, this will probably be below but relatively
+near to the implementation.
+
+Note that the body of the macro contains a trailing comma; when you
+replace the existing static :c:type:`!PyMethodDef` structure with the macro,
+*don't* add a comma to the end.
+
+Sample::
+
+ static struct PyMethodDef Pickler_methods[] = {
+ __PICKLE_PICKLER_DUMP_METHODDEF
+ __PICKLE_PICKLER_CLEAR_MEMO_METHODDEF
+ {NULL, NULL} /* sentinel */
+ };
+
+Argument Clinic may generate new instances of ``_Py_ID``. For example::
+
+ &_Py_ID(new_unique_py_id)
+
+If it does, you'll have to run ``make regen-global-objects``
+to regenerate the list of precompiled identifiers at this point.
+
+Finally, compile, then run the relevant portions of the regression-test suite.
+This change should not introduce any new compile-time warnings or errors,
+and there should be no externally visible change to Python's behavior,
+except for one difference: :py:func:`inspect.signature` run on your function
+should now provide a valid signature!
+
+Congratulations, you've ported your first function to work with Argument Clinic!
.. _clinic-howtos:
@@ -913,6 +902,8 @@ you *must* not call :c:func:`PyBuffer_Release` on the provided buffer.
Argument Clinic generates code that does it for you (in the parsing function).
+.. _clinic-howto-advanced-converters:
+
How to use advanced converters
------------------------------
@@ -943,6 +934,7 @@ This restriction doesn't seem unreasonable; CPython itself always passes in stat
hard-coded encoding strings for parameters whose format units start with ``e``.
+.. _clinic-howto-default-values:
.. _default_values:
How to assign default values to parameter
@@ -1053,6 +1045,8 @@ you're not permitted to use:
* Tuple/list/set/dict literals.
+.. _clinic-howto-return-converters:
+
How to use return converters
----------------------------
@@ -1195,6 +1189,8 @@ variable to the C code::
/*[python checksum:...]*/
+.. _clinic-howto-self-converter:
+
How to use the "self converter"
-------------------------------