From e8068e0a5f2502748778999651983cea6bf8a4df Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 19 Jul 2023 01:14:47 +0200 Subject: [PATCH 01/16] Docs: Add missing markup to Argument Clinic docs - Add :py:func:, :c:func:, etc. where appropriate - Remove repeated links within the same paragraph --- Doc/howto/clinic.rst | 161 ++++++++++++++++++++++--------------------- 1 file changed, 82 insertions(+), 79 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index efeb22c618b512..eef2078d6c1d5c 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -82,7 +82,8 @@ things with all the information you give it. Basic concepts and usage ======================== -Argument Clinic ships with CPython; you'll find it in ``Tools/clinic/clinic.py``. +Argument Clinic ships with CPython; you'll find it in +:source:`Tools/clinic/clinic.py`. If you run that script, specifying a C file as an argument: .. code-block:: shell-session @@ -162,9 +163,9 @@ Let's dive in! 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 ``_pickle.Pickler.dump()``. + For my example I'm using :py:meth:`!_pickle.Pickler.dump`. -2. If the call to the ``PyArg_Parse`` function uses any of the +2. If the call to the :c:func:`!PyArg_Parse*` function uses any of the following format units: .. code-block:: none @@ -181,7 +182,7 @@ 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` + 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 @@ -201,7 +202,7 @@ Let's dive in! 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, + 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.) @@ -248,7 +249,7 @@ Let's dive in! 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. + this class, and a pointer to the :c:type:`!PyTypeObject` for this class. Sample:: @@ -297,10 +298,10 @@ Let's dive in! Clinic easier. For each parameter, copy the "format unit" for that - parameter from the ``PyArg_Parse()`` format argument and + 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 + 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`.) @@ -333,7 +334,7 @@ Let's dive in! itself before the first keyword-only argument, indented the same as the parameter lines. - (``_pickle.Pickler.dump`` has neither, so our sample is unchanged.) + (:py:meth:`!_pickle.Pickler.dump` has neither, so our sample is unchanged.) 10. If the existing C function calls :c:func:`PyArg_ParseTuple` @@ -392,7 +393,7 @@ Let's dive in! Write a pickled representation of obj to the open file. [clinic start generated code]*/ -12. Save and close the file, then run ``Tools/clinic/clinic.py`` on +12. Save and close the file, then run :program:`Tools/clinic/clinic.py` on it. With luck everything worked---your block now has output, and a ``.c.h`` file has been generated! Reopen the file in your text editor to see:: @@ -430,8 +431,8 @@ Let's dive in! ensure that the code generated by Argument Clinic calls the *exact* same function. - Second, the format string passed in to :c:func:`PyArg_ParseTuple` or - :c:func:`PyArg_ParseTupleAndKeywords` should be *exactly* the same + 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. @@ -453,11 +454,11 @@ Let's dive in! {"dump", (PyCFunction)__pickle_Pickler_dump, METH_O, __pickle_Pickler_dump__doc__}, This static structure should be *exactly* the same as the existing static - :c:type:`PyMethodDef` structure for this builtin. + :c:type:`!PyMethodDef` structure for this builtin. 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. + :program:`Tools/clinic/clinic.py` until they *are* the same. 14. Notice that the last line of its output is the declaration @@ -523,14 +524,14 @@ Let's dive in! ... 15. Remember the macro with the :c:type:`PyMethodDef` structure for this - function? Find the existing :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. So when you - replace the existing static :c:type:`PyMethodDef` structure with the macro, + replace the existing static :c:type:`!PyMethodDef` structure with the macro, *don't* add a comma to the end. Sample:: @@ -546,7 +547,7 @@ Let's dive in! &_Py_ID(new_unique_py_id) - If it does, you'll have to run ``Tools/scripts/generate_global_objects.py`` + If it does, you'll have to run :program:`Tools/scripts/generate_global_objects.py` to regenerate the list of precompiled identifiers at this point. @@ -554,7 +555,7 @@ Let's dive in! This change should not introduce any new compile-time warnings or errors, and there should be no externally visible change to Python's behavior. - Well, except for one difference: ``inspect.signature()`` run on your function + Well, 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! @@ -576,15 +577,15 @@ Argument Clinic will use that function name for the base (generated) function, then add ``"_impl"`` to the end and use that for the name of the impl function. For example, if we wanted to rename the C function names generated for -``pickle.Pickler.dump``, it'd look like this:: +:py:meth:`!pickle.Pickler.dump`, it'd look like this:: /*[clinic input] pickle.Pickler.dump as pickler_dumper ... -The base function would now be named ``pickler_dumper()``, -and the impl function would now be named ``pickler_dumper_impl()``. +The base function would now be named :c:func:`!pickler_dumper`, +and the impl function would now be named c:func:`!pickler_dumper_impl`. Similarly, you may have a problem where you want to give a parameter @@ -602,9 +603,9 @@ using the same ``"as"`` syntax:: fix_imports: bool = True Here, the name used in Python (in the signature and the ``keywords`` -array) would be ``file``, but the C variable would be named ``file_obj``. +array) would be *file*, but the C variable would be named ``file_obj``. -You can use this to rename the ``self`` parameter too! +You can use this to rename the *self* parameter too! How to convert functions using ``PyArg_UnpackTuple`` @@ -612,7 +613,7 @@ How to convert 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 +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). @@ -631,16 +632,16 @@ keyword-only arguments.) This approach was used to simulate optional arguments back before :c:func:`PyArg_ParseTupleAndKeywords` was created. While functions using this approach can often be converted to -use :c:func:`PyArg_ParseTupleAndKeywords`, optional arguments, and default values, +use :c:func:`!PyArg_ParseTupleAndKeywords`, optional arguments, and default values, it's not always possible. Some of these legacy functions have -behaviors :c:func:`PyArg_ParseTupleAndKeywords` doesn't directly support. -The most obvious example is the builtin function ``range()``, which has +behaviors :c:func:`!PyArg_ParseTupleAndKeywords` doesn't directly support. +The most obvious example is the builtin function :py:func:`range`, which has 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 :py:meth:`curses.window.addch`, which has a group of two arguments that must always be specified together. (The arguments are -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 -pass in ``y`` either.) +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 +pass in *y* either.) In any case, the goal of Argument Clinic is to support argument parsing for all existing CPython builtins without changing their semantics. @@ -661,7 +662,7 @@ can *only* be used with positional-only parameters. To specify an optional group, add a ``[`` on a line by itself before the parameters you wish to group together, and a ``]`` on a line by itself -after these parameters. As an example, here's how ``curses.window.addch`` +after these parameters. As an example, here's how :py:meth:`curses.window.addch` uses optional groups to make the first two parameters and the last parameter optional:: @@ -804,7 +805,7 @@ of these arguments, along with their meanings: ``_length``. Please note, not every possible combination of arguments will work. -Usually these arguments are implemented by specific ``PyArg_ParseTuple`` +Usually these arguments are implemented by specific :c:func:`PyArg_ParseTuple` *format units*, with specific behavior. For example, currently you cannot call ``unsigned_short`` without also specifying ``bitwise=True``. Although it's perfectly reasonable to think this would work, these semantics don't @@ -881,13 +882,13 @@ negative numbers. You just can't do that with a legacy converter! Argument Clinic will show you all the converters it has 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. +Just run :program:`Tools/clinic/clinic.py --converters` to see the full list. How to use the ``Py_buffer`` converter -------------------------------------- -When using the ``Py_buffer`` converter +When using the :c:data:`Py_buffer` converter (or the ``'s*'``, ``'w*'``, ``'*y'``, or ``'z*'`` legacy converters), 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). @@ -910,12 +911,12 @@ or ``encoding`` (for all the format units that start with ``e``). When using ``subclass_of``, you may also want to use the other custom argument for ``object()``: ``type``, which lets you set the type actually used for the parameter. For example, if you want to ensure -that the object is a subclass of ``PyUnicode_Type``, you probably want +that the object is a subclass of :c:var:`PyUnicode_Type`, you probably want to use the converter ``object(type='PyUnicodeObject *', subclass_of='&PyUnicode_Type')``. One possible problem with using Argument Clinic: it takes away some possible flexibility for the format units starting with ``e``. When writing a -``PyArg_Parse`` call by hand, you could theoretically decide at runtime what +:c:func:`PyArg_Parse` call by hand, you could theoretically decide at runtime what encoding string to pass in to :c:func:`PyArg_ParseTuple`. But now this string must be hard-coded at Argument-Clinic-preprocessing-time. This limitation is deliberate; it made supporting this format unit much easier, and may allow for future optimizations. @@ -969,7 +970,7 @@ 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 +* Simple symbolic constants like :py:attr:`sys.maxsize`, which must start with the name of the module (In the future, this may need to get even more elaborate, @@ -990,28 +991,28 @@ Consider the following example: foo: Py_ssize_t = sys.maxsize - 1 -``sys.maxsize`` can have different values on different platforms. Therefore +:py:attr:`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: +attribute called :py:attr:`!max_widgets`, you may simply use it: .. code-block:: none 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 +:py:attr:`sys.modules`. That's how it can find :py:attr:`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: +in C, using the *c_default* parameter to the converter: .. code-block:: none @@ -1077,7 +1078,7 @@ indicate an error has occurred? Normally, a function returns a valid (non-``NUL pointer for success, and ``NULL`` for failure. But if you use an integer return converter, all integers are valid. How can Argument Clinic detect an error? Its solution: each return converter implicitly looks for a special value that indicates an error. If you return -that value, and an error has been set (``PyErr_Occurred()`` returns a true +that value, and an error has been set (c:func:`PyErr_Occurred` returns a true value), then the generated code will propagate the error. Otherwise it will encode the value you return like normal. @@ -1100,7 +1101,7 @@ For all of these, return ``-1`` to indicate error. 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. +just run :program:`Tools/clinic/clinic.py --converters` for the full list. How to clone existing functions @@ -1137,7 +1138,7 @@ Here's the syntax for cloning a function:: [clinic start generated code]*/ (The functions can be in different modules or classes. I wrote -``module.class`` in the sample just to illustrate that you must +:py:class:`!module.class` in the sample just to illustrate that you must use the full path to *both* functions.) Sorry, there's no syntax for partially cloning a function, or cloning a function @@ -1236,8 +1237,8 @@ module level state. Use :c:func:`PyType_FromModuleAndSpec` to associate a new heap type with a module. You can now use :c:func:`PyType_GetModuleState` on the defining class to fetch the module state, for example from a module method. -Example from ``Modules/zlibmodule.c``. First, ``defining_class`` is added to -the clinic input:: +Example from :source:`Modules/zlibmodule.c`. +First, ``defining_class`` is added to the clinic input:: /*[clinic input] zlib.Compress.compress @@ -1267,16 +1268,17 @@ module state:: Each method may only have one argument using this converter, and it must appear after ``self``, or, if ``self`` is not used, as the first argument. The argument will be of type ``PyTypeObject *``. The argument will not appear in the -``__text_signature__``. +:py:attr:`!__text_signature__`. -The ``defining_class`` converter is not compatible with ``__init__`` and ``__new__`` -methods, which cannot use the ``METH_METHOD`` convention. +The ``defining_class`` converter is not compatible with +:py:meth:`!__init__` and :py:meth:`!__new__` +methods, which cannot use the :c:data:`METH_METHOD` convention. It is not possible to use ``defining_class`` with slot methods. In order to fetch the module state from such methods, use :c:func:`PyType_GetModuleByDef` to look up the module and then :c:func:`PyModule_GetState` to fetch the module state. Example from the ``setattro`` slot method in -``Modules/_threadmodule.c``:: +:source:`Modules/_threadmodule.c`:: static int local_setattro(localobject *self, PyObject *name, PyObject *v) @@ -1294,7 +1296,7 @@ How to write a custom converter ------------------------------- 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 :py:class:`!CConverter`. The main purpose of a custom converter is if you have a parameter using the ``O&`` format unit—parsing this parameter means calling a :c:func:`PyArg_ParseTuple` "converter function". @@ -1305,36 +1307,36 @@ will be automatically registered with Argument Clinic; its name will be the name of your class with the ``_converter`` suffix stripped off. (This is accomplished with a metaclass.) -You shouldn't subclass ``CConverter.__init__``. Instead, you should -write a ``converter_init()`` function. ``converter_init()`` -always accepts a ``self`` parameter; after that, all additional +You shouldn't subclass :py:meth:`!CConverter.__init__`. Instead, you should +write a :py:meth:`!converter_init` function. :py:meth:`!converter_init` +always accepts a *self* parameter; after that, all additional parameters *must* be keyword-only. Any arguments passed in to the converter in Argument Clinic will be passed along to your -``converter_init()``. +:py:meth:`!converter_init`. -There are some additional members of ``CConverter`` you may wish +There are some additional members of :py:class:`!CConverter` you may wish to specify in your subclass. Here's the current list: -``type`` +:py:attr:`!type` The C type to use for this variable. ``type`` should be a Python string specifying the type, e.g. ``int``. If this is a pointer type, the type string should end with ``' *'``. -``default`` +:py:attr:`!default` The Python default value for this parameter, as a Python value. Or the magic value ``unspecified`` if there is no default. -``py_default`` +:py:attr:`!py_default` ``default`` as it should appear in Python code, as a string. Or ``None`` if there is no default. -``c_default`` +:py:attr:`!c_default` ``default`` as it should appear in C code, as a string. Or ``None`` if there is no default. -``c_ignored_default`` +:py:attr:`!c_ignored_default` The default value used to initialize the C variable when there is no default, but not specifying a default may result in an "uninitialized variable" warning. This can @@ -1345,21 +1347,21 @@ to specify in your subclass. Here's the current list: uninitialized value. This value should always be a non-empty string. -``converter`` +:py:attr:`!converter` The name of the C converter function, as a string. -``impl_by_reference`` +:py:attr:`!impl_by_reference` A boolean value. If true, Argument Clinic will add a ``&`` in front of the name of the variable when passing it into the impl function. -``parse_by_reference`` +:py:attr:`!parse_by_reference` A boolean value. If true, Argument Clinic will add a ``&`` in front of the name of the variable when passing it into :c:func:`PyArg_ParseTuple`. -Here's the simplest example of a custom converter, from ``Modules/zlibmodule.c``:: +Here's the simplest example of a custom converter, from :source:`Modules/zlibmodule.c`:: /*[python input] @@ -1379,7 +1381,7 @@ automatically support default values. More sophisticated custom converters can insert custom C code to handle initialization and cleanup. You can see more examples of custom converters in the CPython -source tree; grep the C files for the string ``CConverter``. +source tree; grep the C files for the string :py:class:`!CConverter`. How to write a custom return converter @@ -1389,18 +1391,18 @@ Writing a custom return converter is much like writing a custom converter. Except it's somewhat simpler, because return converters are themselves much simpler. -Return converters must subclass ``CReturnConverter``. +Return converters must subclass :py:class:`!CReturnConverter`. There are no examples yet of custom return converters, because they are not widely used yet. If you wish to -write your own return converter, please read ``Tools/clinic/clinic.py``, -specifically the implementation of ``CReturnConverter`` and +write your own return converter, please read :source:`Tools/clinic/clinic.py`, +specifically the implementation of :py:class:`!CReturnConverter` and all its subclasses. How to convert ``METH_O`` and ``METH_NOARGS`` functions ------------------------------------------------------- -To convert a function using ``METH_O``, make sure the function's +To convert a function using :c:data:`METH_O`, make sure the function's single argument is using the ``object`` converter, and mark the arguments as positional-only:: @@ -1412,24 +1414,25 @@ arguments as positional-only:: [clinic start generated code]*/ -To convert a function using ``METH_NOARGS``, just don't specify +To convert a function using :c:data:`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``. +a *type* argument to the object converter for :c:data:`METH_O`. How to convert ``tp_new`` and ``tp_init`` functions --------------------------------------------------- -You can convert ``tp_new`` and ``tp_init`` functions. Just name -them ``__new__`` or ``__init__`` as appropriate. Notes: +You can convert :c:member:`~PyTypeObject.tp_new` and +:c:member:`~PyTypeObject.tp_init` functions. +Just name them ``__new__`` or ``__init__`` as appropriate. Notes: * The function name generated for ``__new__`` doesn't end in ``__new__`` like it would by default. It's just the name of the class, converted into a valid C identifier. -* No ``PyMethodDef`` ``#define`` is generated for these functions. +* No :c:type:`PyMethodDef` ``#define`` is generated for these functions. * ``__init__`` functions return ``int``, not ``PyObject *``. @@ -1464,7 +1467,7 @@ 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 + For example, the ``#define`` for the :c:type:`PyMethodDef` structure is a field, called ``methoddef_define``. Clinic has seven different fields it can output per function definition: @@ -1762,7 +1765,7 @@ like so:: } #endif /* HAVE_FUNCTIONNAME */ -Then, remove those three lines from the ``PyMethodDef`` structure, +Then, remove those three lines from the :c:type:`PyMethodDef` structure, replacing them with the macro Argument Clinic generated: .. code-block:: none @@ -1803,7 +1806,7 @@ This may mean that you get a complaint from Argument Clinic: When this happens, just open your file, find the ``dump buffer`` block that Argument Clinic added to your file (it'll be at the very bottom), then -move it above the ``PyMethodDef`` structure where that macro is used. +move it above the :c:type:`PyMethodDef` structure where that macro is used. How to use Argument Clinic in Python files From cf661050170d53c27983a2f3e56358fb8e812113 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 19 Jul 2023 01:28:34 +0200 Subject: [PATCH 02/16] Add missing colon --- Doc/howto/clinic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index eef2078d6c1d5c..9f9ba2bcae2da5 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -585,7 +585,7 @@ For example, if we wanted to rename the C function names generated for ... The base function would now be named :c:func:`!pickler_dumper`, -and the impl function would now be named c:func:`!pickler_dumper_impl`. +and the impl function would now be named :c:func:`!pickler_dumper_impl`. Similarly, you may have a problem where you want to give a parameter From 6e5c44fec578b0de94b429b79787a60ace65b7ad Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 19 Jul 2023 13:03:49 +0200 Subject: [PATCH 03/16] Address reviews - line 166: link to pickle.Pickler.dump - line 187: markup PyArg_Parse* - line 580: link to pickle.Pickler.dump - line 891: revert Py_buffer change - line 919: markup PyArg_Parse - line 973: markup sys.maxsize as :data: - line 1008: markup sys.modules as :data: - markup CConverter and it's attributes as a proper Python class --- Doc/howto/clinic.rst | 116 ++++++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 51 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 9f9ba2bcae2da5..3b3a9ae54ec883 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -163,7 +163,8 @@ Let's dive in! 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`. + For my example I'm using + :py:meth:`_pickle.Pickler.dump `. 2. If the call to the :c:func:`!PyArg_Parse*` function uses any of the following format units: @@ -185,7 +186,7 @@ Let's dive in! 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 + :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. @@ -577,7 +578,7 @@ Argument Clinic will use that function name for the base (generated) function, then add ``"_impl"`` to the end and use that for the name of the impl function. For example, if we wanted to rename the C function names generated for -:py:meth:`!pickle.Pickler.dump`, it'd look like this:: +:py:meth:`pickle.Pickler.dump`, it'd look like this:: /*[clinic input] pickle.Pickler.dump as pickler_dumper @@ -888,7 +889,7 @@ Just run :program:`Tools/clinic/clinic.py --converters` to see the full list. How to use the ``Py_buffer`` converter -------------------------------------- -When using the :c:data:`Py_buffer` converter +When using the ``Py_buffer`` converter (or the ``'s*'``, ``'w*'``, ``'*y'``, or ``'z*'`` legacy converters), 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). @@ -916,7 +917,7 @@ to use the converter ``object(type='PyUnicodeObject *', subclass_of='&PyUnicode_ One possible problem with using Argument Clinic: it takes away some possible flexibility for the format units starting with ``e``. When writing a -:c:func:`PyArg_Parse` call by hand, you could theoretically decide at runtime what +:c:func:`!PyArg_Parse*` call by hand, you could theoretically decide at runtime what encoding string to pass in to :c:func:`PyArg_ParseTuple`. But now this string must be hard-coded at Argument-Clinic-preprocessing-time. This limitation is deliberate; it made supporting this format unit much easier, and may allow for future optimizations. @@ -970,7 +971,7 @@ expression. Currently the following are explicitly supported: * Numeric constants (integer and float) * String constants * ``True``, ``False``, and ``None`` -* Simple symbolic constants like :py:attr:`sys.maxsize`, which must +* Simple symbolic constants like :py:data:`sys.maxsize`, which must start with the name of the module (In the future, this may need to get even more elaborate, @@ -991,7 +992,7 @@ Consider the following example: foo: Py_ssize_t = sys.maxsize - 1 -:py:attr:`sys.maxsize` can have different values on different platforms. Therefore +:py:data:`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. @@ -1005,8 +1006,8 @@ attribute called :py:attr:`!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 -:py:attr:`sys.modules`. That's how it can find :py:attr:`sys.maxsize` for example. (Since you -don't know in advance what modules the user will load into their interpreter, +:py:data:`sys.modules`. That's how it can find :py:data:`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 @@ -1317,48 +1318,61 @@ the converter in Argument Clinic will be passed along to your There are some additional members of :py:class:`!CConverter` you may wish to specify in your subclass. Here's the current list: -:py:attr:`!type` - The C type to use for this variable. - ``type`` should be a Python string specifying the type, e.g. ``int``. - If this is a pointer type, the type string should end with ``' *'``. - -:py:attr:`!default` - The Python default value for this parameter, as a Python value. - Or the magic value ``unspecified`` if there is no default. - -:py:attr:`!py_default` - ``default`` as it should appear in Python code, - as a string. - Or ``None`` if there is no default. - -:py:attr:`!c_default` - ``default`` as it should appear in C code, - as a string. - Or ``None`` if there is no default. - -:py:attr:`!c_ignored_default` - The default value used to initialize the C variable when - there is no default, but not specifying a default may - result in an "uninitialized variable" warning. This can - easily happen when using option groups—although - properly written code will never actually use this value, - the variable does get passed in to the impl, and the - C compiler will complain about the "use" of the - uninitialized value. This value should always be a - non-empty string. - -:py:attr:`!converter` - The name of the C converter function, as a string. - -:py:attr:`!impl_by_reference` - A boolean value. If true, - Argument Clinic will add a ``&`` in front of the name of - the variable when passing it into the impl function. - -:py:attr:`!parse_by_reference` - A boolean value. If true, - Argument Clinic will add a ``&`` in front of the name of - the variable when passing it into :c:func:`PyArg_ParseTuple`. +.. module:: clinic + +.. class:: CConverter + + .. attribute:: type + + The C type to use for this variable. + :attr:`!type` should be a Python string specifying the type, + e.g. :class:`int`. + If this is a pointer type, the type string should end with ``' *'``. + + .. attribute:: default + + The Python default value for this parameter, as a Python value. + Or the magic value ``unspecified`` if there is no default. + + .. attribute:: py_default + + :attr:`!default` as it should appear in Python code, + as a string. + Or ``None`` if there is no default. + + .. attribute:: c_default + + :attr:`!default` as it should appear in C code, + as a string. + Or ``None`` if there is no default. + + .. attribute:: c_ignored_default + + The default value used to initialize the C variable when + there is no default, but not specifying a default may + result in an "uninitialized variable" warning. This can + easily happen when using option groups—although + properly written code will never actually use this value, + the variable does get passed in to the impl, and the + C compiler will complain about the "use" of the + uninitialized value. This value should always be a + non-empty string. + + .. attribute:: converter + + The name of the C converter function, as a string. + + .. attribute:: impl_by_reference + + A boolean value. If true, + Argument Clinic will add a ``&`` in front of the name of + the variable when passing it into the impl function. + + .. attribute:: parse_by_reference + + A boolean value. If true, + Argument Clinic will add a ``&`` in front of the name of + the variable when passing it into :c:func:`PyArg_ParseTuple`. Here's the simplest example of a custom converter, from :source:`Modules/zlibmodule.c`:: From 8f239567112a90ede907e3131e95da89a229efbb Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 19 Jul 2023 22:40:09 +0200 Subject: [PATCH 04/16] Use :data: for METH_O and METH_NOARGS --- Doc/howto/clinic.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 3b3a9ae54ec883..df73f7c67f3845 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1416,7 +1416,7 @@ all its subclasses. How to convert ``METH_O`` and ``METH_NOARGS`` functions ------------------------------------------------------- -To convert a function using :c:data:`METH_O`, make sure the function's +To convert a function using :data:`METH_O`, make sure the function's single argument is using the ``object`` converter, and mark the arguments as positional-only:: @@ -1428,11 +1428,11 @@ arguments as positional-only:: [clinic start generated code]*/ -To convert a function using :c:data:`METH_NOARGS`, just don't specify +To convert a function using :data:`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 :c:data:`METH_O`. +a *type* argument to the object converter for :data:`METH_O`. How to convert ``tp_new`` and ``tp_init`` functions From b155e3862df036ca4559290e35844db70e2616b9 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 19 Jul 2023 22:48:03 +0200 Subject: [PATCH 05/16] For now, disable the METH_METHOD link --- Doc/howto/clinic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index df73f7c67f3845..a49dd9a075fc10 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1273,7 +1273,7 @@ will be of type ``PyTypeObject *``. The argument will not appear in the The ``defining_class`` converter is not compatible with :py:meth:`!__init__` and :py:meth:`!__new__` -methods, which cannot use the :c:data:`METH_METHOD` convention. +methods, which cannot use the :data:`!METH_METHOD` convention. It is not possible to use ``defining_class`` with slot methods. In order to fetch the module state from such methods, use :c:func:`PyType_GetModuleByDef` From 971c0584fcb7da8809bd0da854963bdf4f5befcd Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 19 Jul 2023 22:56:09 +0200 Subject: [PATCH 06/16] Suggest 'make clinic' and 'make regen-global-objects' iso. running clinic directly --- Doc/Makefile | 2 +- Doc/howto/clinic.rst | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Doc/Makefile b/Doc/Makefile index 22691895068fea..ef1446740b5af8 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -20,7 +20,7 @@ SPHINXERRORHANDLING = -W PAPEROPT_a4 = -D latex_elements.papersize=a4paper PAPEROPT_letter = -D latex_elements.papersize=letterpaper -ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees $(PAPEROPT_$(PAPER)) -j $(JOBS) \ +ALLSPHINXOPTS = -b $(BUILDER) -W -d build/doctrees $(PAPEROPT_$(PAPER)) -j $(JOBS) \ $(SPHINXOPTS) $(SPHINXERRORHANDLING) . build/$(BUILDER) $(SOURCES) .PHONY: help diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index a49dd9a075fc10..57e85947163950 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -394,8 +394,9 @@ Let's dive in! Write a pickled representation of obj to the open file. [clinic start generated code]*/ -12. Save and close the file, then run :program:`Tools/clinic/clinic.py` on - it. With luck everything worked---your block now has output, and +12. Save and close the file, then run :program:`make clinic` + to regenerate the Argument Clinic code. + With luck everything worked---your block now has output, and a ``.c.h`` file has been generated! Reopen the file in your text editor to see:: @@ -459,7 +460,7 @@ Let's dive in! If any of these items differ in *any way*, adjust your Argument Clinic function specification and rerun - :program:`Tools/clinic/clinic.py` until they *are* the same. + :program:`make clinic` until they *are* the same. 14. Notice that the last line of its output is the declaration @@ -548,7 +549,7 @@ Let's dive in! &_Py_ID(new_unique_py_id) - If it does, you'll have to run :program:`Tools/scripts/generate_global_objects.py` + If it does, you'll have to run :program:`make regen-global-objects` to regenerate the list of precompiled identifiers at this point. @@ -1102,7 +1103,7 @@ For all of these, return ``-1`` to indicate error. To see all the return converters Argument Clinic supports, along with their parameters (if any), -just run :program:`Tools/clinic/clinic.py --converters` for the full list. +just run :program:`./Tools/clinic/clinic.py --converters` for the full list. How to clone existing functions From bc33f97b87a43576a28c451891f5a54eba9b629a Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 19 Jul 2023 22:58:14 +0200 Subject: [PATCH 07/16] Markup file suffixes and file paths with :file: --- Doc/howto/clinic.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 57e85947163950..a6a64a9aa30bcd 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -397,7 +397,7 @@ Let's dive in! 12. Save and close the file, then run :program:`make clinic` to regenerate the Argument Clinic code. With luck everything worked---your block now has output, and - a ``.c.h`` file has been generated! Reopen the file in your + a :file:`.c.h` file has been generated! Reopen the file in your text editor to see:: /*[clinic input] @@ -418,8 +418,8 @@ Let's dive in! it found an error in your input. Keep fixing your errors and retrying until Argument Clinic processes your file without complaint. - For readability, most of the glue code has been generated to a ``.c.h`` - file. You'll need to include that in your original ``.c`` file, + 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:: #include "clinic/_pickle.c.h" @@ -1526,8 +1526,8 @@ Let's start with defining some terminology: 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``.) + the ``file`` destination for :file:`_pickle.c` would be written to + :file:`_pickle.clinic.c`.) **Important: When using a** ``file`` **destination, you** *must check in* **the generated file!** From f5bb4a318f674840152338b4358b9fe956511ec4 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 19 Jul 2023 23:04:04 +0200 Subject: [PATCH 08/16] Address review: rewrite line 919 similar to suggestion by Serhiy --- Doc/howto/clinic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index a6a64a9aa30bcd..432971fc33e1a3 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -919,7 +919,7 @@ to use the converter ``object(type='PyUnicodeObject *', subclass_of='&PyUnicode_ One possible problem with using Argument Clinic: it takes away some possible flexibility for the format units starting with ``e``. When writing a :c:func:`!PyArg_Parse*` call by hand, you could theoretically decide at runtime what -encoding string to pass in to :c:func:`PyArg_ParseTuple`. But now this string must +encoding string to pass to that call. But now this string must be hard-coded at Argument-Clinic-preprocessing-time. This limitation is deliberate; it made supporting this format unit much easier, and may allow for future optimizations. This restriction doesn't seem unreasonable; CPython itself always passes in static From f892322ba8d9a1d1fb5b2f14a63cd3bd51e976ff Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 19 Jul 2023 23:23:33 +0200 Subject: [PATCH 09/16] fixup! Suggest 'make clinic' and 'make regen-global-objects' iso. running clinic directly --- Doc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/Makefile b/Doc/Makefile index ef1446740b5af8..22691895068fea 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -20,7 +20,7 @@ SPHINXERRORHANDLING = -W PAPEROPT_a4 = -D latex_elements.papersize=a4paper PAPEROPT_letter = -D latex_elements.papersize=letterpaper -ALLSPHINXOPTS = -b $(BUILDER) -W -d build/doctrees $(PAPEROPT_$(PAPER)) -j $(JOBS) \ +ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees $(PAPEROPT_$(PAPER)) -j $(JOBS) \ $(SPHINXOPTS) $(SPHINXERRORHANDLING) . build/$(BUILDER) $(SOURCES) .PHONY: help From d96fdebe8f252464eac9bfa6582eed29c54f9f30 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 19 Jul 2023 23:23:59 +0200 Subject: [PATCH 10/16] Address review: markup more params with ** --- Doc/howto/clinic.rst | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 432971fc33e1a3..fb3f94d11bd338 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -750,25 +750,25 @@ the same converters. All arguments to Argument Clinic converters are keyword-only. All Argument Clinic converters accept the following arguments: - ``c_default`` + *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 ` for how to use this. Specified as a string. - ``annotation`` + *annotation* The annotation value for this parameter. Not currently supported, because :pep:`8` mandates that the Python library may not use annotations. - ``unused`` + *unused* Wrap the argument with :c:macro:`Py_UNUSED` in the impl function signature. In addition, some converters accept additional arguments. Here is a list of these arguments, along with their meanings: - ``accept`` + *accept* A set 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 @@ -776,31 +776,31 @@ of these arguments, along with their meanings: To accept ``None``, add ``NoneType`` to this set. - ``bitwise`` + *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`` + *converter* Only supported by the ``object`` converter. Specifies the name of a :ref:`C "converter function" ` to use to convert this object to a native type. - ``encoding`` + *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. - ``subclass_of`` + *subclass_of* Only supported for the ``object`` converter. Requires that the Python value be a subclass of a Python type, as expressed in C. - ``type`` + *type* Only supported for the ``object`` and ``self`` converters. Specifies the C type that will be used to declare the variable. Default value is ``"PyObject *"``. - ``zeroes`` + *zeroes* Only supported for strings. If true, embedded NUL bytes (``'\\0'``) are permitted inside the value. The length of the string will be passed in to the impl function, just after the string parameter, as a parameter named @@ -907,11 +907,11 @@ conversion functions, or types, or strings specifying an encoding. (But "legacy converters" don't support arguments. That's why we skipped them for your first function.) The argument you specified to the format unit is now an argument to the converter; this -argument is either ``converter`` (for ``O&``), ``subclass_of`` (for ``O!``), -or ``encoding`` (for all the format units that start with ``e``). +argument is either *converter* (for ``O&``), *subclass_of* (for ``O!``), +or *encoding* (for all the format units that start with ``e``). -When using ``subclass_of``, you may also want to use the other -custom argument for ``object()``: ``type``, which lets you set the type +When using *subclass_of*, you may also want to use the other +custom argument for ``object()``: *type*, which lets you set the type actually used for the parameter. For example, if you want to ensure that the object is a subclass of :c:var:`PyUnicode_Type`, you probably want to use the converter ``object(type='PyUnicodeObject *', subclass_of='&PyUnicode_Type')``. @@ -1186,9 +1186,9 @@ using a default converter. It automatically sets the ``type`` of this parameter to the "pointer to an instance" you specified when you declared the type. However, you can override Argument Clinic's converter and specify one yourself. -Just add your own ``self`` parameter as the first parameter in a +Just add your own *self* parameter as the first parameter in a block, and ensure that its converter is an instance of -``self_converter`` or a subclass thereof. +:class:`!self_converter` or a subclass thereof. What's the point? This lets you override the type of ``self``, or give it a different default name. @@ -1196,7 +1196,7 @@ or give it a different default name. How do you specify the custom type you want to cast ``self`` to? If you only have one or two functions with the same type for ``self``, you can directly use Argument Clinic's existing ``self`` converter, -passing in the type you want to use as the ``type`` parameter:: +passing in the type you want to use as the *type* parameter:: /*[clinic input] @@ -1211,7 +1211,7 @@ passing in the type you want to use as the ``type`` parameter:: On the other hand, if you have a lot of functions that will use the same type for ``self``, it's best to create your own converter, subclassing -``self_converter`` but overwriting the ``type`` member:: +:class:`!self_converter` but overwriting the :py:attr:`!type` member:: /*[python input] class PicklerObject_converter(self_converter): From 47061df9dd03fb10c300f8c67d0d9121948ab79f Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Thu, 20 Jul 2023 10:37:43 +0200 Subject: [PATCH 11/16] Address review: revert :program: markups --- Doc/howto/clinic.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index fb3f94d11bd338..39907dbd1081a1 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -394,7 +394,7 @@ Let's dive in! Write a pickled representation of obj to the open file. [clinic start generated code]*/ -12. Save and close the file, then run :program:`make clinic` +12. Save and close the file, then run ``make clinic`` to regenerate the Argument Clinic code. With luck everything worked---your block now has output, and a :file:`.c.h` file has been generated! Reopen the file in your @@ -460,7 +460,7 @@ Let's dive in! If any of these items differ in *any way*, adjust your Argument Clinic function specification and rerun - :program:`make clinic` until they *are* the same. + ``make clinic`` until they *are* the same. 14. Notice that the last line of its output is the declaration @@ -549,7 +549,7 @@ Let's dive in! &_Py_ID(new_unique_py_id) - If it does, you'll have to run :program:`make regen-global-objects` + If it does, you'll have to run ``make regen-global-objects`` to regenerate the list of precompiled identifiers at this point. @@ -884,7 +884,7 @@ negative numbers. You just can't do that with a legacy converter! Argument Clinic will show you all the converters it has available. For each converter it'll show you all the parameters it accepts, along with the default value for each parameter. -Just run :program:`Tools/clinic/clinic.py --converters` to see the full list. +Just run ``./Tools/clinic/clinic.py --converters`` to see the full list. How to use the ``Py_buffer`` converter @@ -1103,7 +1103,7 @@ For all of these, return ``-1`` to indicate error. To see all the return converters Argument Clinic supports, along with their parameters (if any), -just run :program:`./Tools/clinic/clinic.py --converters` for the full list. +just run ``./Tools/clinic/clinic.py --converters`` for the full list. How to clone existing functions From fe52717c58828309065f94e360ed6f6dfe7bb2e3 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 21 Jul 2023 21:42:07 +0200 Subject: [PATCH 12/16] Address review: fix 'int' markup around line 1330 --- Doc/howto/clinic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index c83f3ad80f1dd6..f222cc5f6491dd 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1345,7 +1345,7 @@ to specify in your subclass. Here's the current list: The C type to use for this variable. :attr:`!type` should be a Python string specifying the type, - e.g. :class:`int`. + e.g. ``'int'``. If this is a pointer type, the type string should end with ``' *'``. .. attribute:: default From 1a30f3b661622d07ff29b0aafc8dda4546c5a999 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 21 Jul 2023 21:47:42 +0200 Subject: [PATCH 13/16] Address review: use new and correct directives for C constants/macros --- Doc/howto/clinic.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index f222cc5f6491dd..42a1a47fbe89aa 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1290,9 +1290,9 @@ after ``self``, or, if ``self`` is not used, as the first argument. The argumen will be of type ``PyTypeObject *``. The argument will not appear in the :py:attr:`!__text_signature__`. -The ``defining_class`` converter is not compatible with -:py:meth:`!__init__` and :py:meth:`!__new__` -methods, which cannot use the :data:`!METH_METHOD` convention. +The ``defining_class`` converter is not compatible with :py:meth:`!__init__` +and :py:meth:`!__new__` methods, which cannot use the :ref:`METH_METHOD +` convention. It is not possible to use ``defining_class`` with slot methods. In order to fetch the module state from such methods, use :c:func:`PyType_GetModuleByDef` @@ -1435,7 +1435,7 @@ all its subclasses. How to convert ``METH_O`` and ``METH_NOARGS`` functions ------------------------------------------------------- -To convert a function using :data:`METH_O`, make sure the function's +To convert a function using :c:macro:`METH_O`, make sure the function's single argument is using the ``object`` converter, and mark the arguments as positional-only:: @@ -1447,11 +1447,11 @@ arguments as positional-only:: [clinic start generated code]*/ -To convert a function using :data:`METH_NOARGS`, just don't specify +To convert a function using :c:macro:`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 :data:`METH_O`. +a *type* argument to the object converter for :c:macro:`METH_O`. How to convert ``tp_new`` and ``tp_init`` functions From 499ed66666be713b678fa465e24082e92ef61fc5 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 22 Jul 2023 22:49:28 +0200 Subject: [PATCH 14/16] Revert module.class markup --- Doc/howto/clinic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 42a1a47fbe89aa..9f8eac4d3b1eeb 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1158,7 +1158,7 @@ Here's the syntax for cloning a function:: [clinic start generated code]*/ (The functions can be in different modules or classes. I wrote -:py:class:`!module.class` in the sample just to illustrate that you must +``module.class`` in the sample just to illustrate that you must use the full path to *both* functions.) Sorry, there's no syntax for partially cloning a function, or cloning a function From d2f968a55281c11a3249d7f2052ec15cb75031ca Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 22 Jul 2023 22:54:15 +0200 Subject: [PATCH 15/16] Revert 'make clinic' changes --- Doc/howto/clinic.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 9f8eac4d3b1eeb..2f68370a9d4593 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -410,9 +410,8 @@ Let's dive in! Write a pickled representation of obj to the open file. [clinic start generated code]*/ -12. Save and close the file, then run ``make clinic`` - to regenerate the Argument Clinic code. - With luck everything worked---your block now has output, and +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:: @@ -476,7 +475,7 @@ Let's dive in! If any of these items differ in *any way*, adjust your Argument Clinic function specification and rerun - ``make clinic`` until they *are* the same. + ``Tools/clinic/clinic.py`` until they *are* the same. 14. Notice that the last line of its output is the declaration @@ -902,7 +901,7 @@ negative numbers. You just can't do that with a legacy converter! Argument Clinic will show you all the converters it has 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. +Just run ``Tools/clinic/clinic.py --converters`` to see the full list. How to use the ``Py_buffer`` converter @@ -1121,7 +1120,7 @@ For all of these, return ``-1`` to indicate error. 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. +just run ``Tools/clinic/clinic.py --converters`` for the full list. How to clone existing functions From 8454b7886dd98391f8d8f3dc254d2e880b1ca472 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 24 Jul 2023 17:09:44 +0200 Subject: [PATCH 16/16] METH_METHOD now has its own anchor --- Doc/howto/clinic.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index b32dcec86a6cc7..98d3632ff02325 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1290,8 +1290,8 @@ will be of type ``PyTypeObject *``. The argument will not appear in the :py:attr:`!__text_signature__`. The ``defining_class`` converter is not compatible with :py:meth:`!__init__` -and :py:meth:`!__new__` methods, which cannot use the :ref:`METH_METHOD -` convention. +and :py:meth:`!__new__` methods, which cannot use the :c:macro:`METH_METHOD` +convention. It is not possible to use ``defining_class`` with slot methods. In order to fetch the module state from such methods, use :c:func:`PyType_GetModuleByDef`