mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
[3.11] gh-107298: Fix more Sphinx warnings in the C API doc (GH-107329) (GH-107377)
Declare the following functions as macros, since they are actually
macros. It avoids a warning on "TYPE" or "macro" argument.
* PyMem_New()
* PyMem_Resize()
* PyModule_AddIntMacro()
* PyModule_AddStringMacro()
* PyObject_GC_New()
* PyObject_GC_NewVar()
* PyObject_New()
* PyObject_NewVar()
(cherry picked from commit 8d61a71f9c
)
Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
parent
dcfdfa5399
commit
32e17d4a3c
22 changed files with 119 additions and 113 deletions
|
@ -230,7 +230,7 @@ with an exception object::
|
|||
return m;
|
||||
}
|
||||
|
||||
Note that the Python name for the exception object is :exc:`spam.error`. The
|
||||
Note that the Python name for the exception object is :exc:`!spam.error`. The
|
||||
:c:func:`PyErr_NewException` function may create a class with the base class
|
||||
being :exc:`Exception` (unless another class is passed in instead of ``NULL``),
|
||||
described in :ref:`bltin-exceptions`.
|
||||
|
@ -245,7 +245,7 @@ raises the exception could cause a core dump or other unintended side effects.
|
|||
We discuss the use of ``PyMODINIT_FUNC`` as a function return type later in this
|
||||
sample.
|
||||
|
||||
The :exc:`spam.error` exception can be raised in your extension module using a
|
||||
The :exc:`!spam.error` exception can be raised in your extension module using a
|
||||
call to :c:func:`PyErr_SetString` as shown below::
|
||||
|
||||
static PyObject *
|
||||
|
@ -315,7 +315,7 @@ contexts, as we have seen.
|
|||
The Module's Method Table and Initialization Function
|
||||
=====================================================
|
||||
|
||||
I promised to show how :c:func:`spam_system` is called from Python programs.
|
||||
I promised to show how :c:func:`!spam_system` is called from Python programs.
|
||||
First, we need to list its name and address in a "method table"::
|
||||
|
||||
static PyMethodDef SpamMethods[] = {
|
||||
|
@ -1030,13 +1030,13 @@ Let's follow the control flow into :c:func:`PyList_SetItem`. The list owns
|
|||
references to all its items, so when item 1 is replaced, it has to dispose of
|
||||
the original item 1. Now let's suppose the original item 1 was an instance of a
|
||||
user-defined class, and let's further suppose that the class defined a
|
||||
:meth:`__del__` method. If this class instance has a reference count of 1,
|
||||
disposing of it will call its :meth:`__del__` method.
|
||||
:meth:`!__del__` method. If this class instance has a reference count of 1,
|
||||
disposing of it will call its :meth:`!__del__` method.
|
||||
|
||||
Since it is written in Python, the :meth:`__del__` method can execute arbitrary
|
||||
Since it is written in Python, the :meth:`!__del__` method can execute arbitrary
|
||||
Python code. Could it perhaps do something to invalidate the reference to
|
||||
``item`` in :c:func:`bug`? You bet! Assuming that the list passed into
|
||||
:c:func:`bug` is accessible to the :meth:`__del__` method, it could execute a
|
||||
``item`` in :c:func:`!bug`? You bet! Assuming that the list passed into
|
||||
:c:func:`!bug` is accessible to the :meth:`!__del__` method, it could execute a
|
||||
statement to the effect of ``del list[0]``, and assuming this was the last
|
||||
reference to that object, it would free the memory associated with it, thereby
|
||||
invalidating ``item``.
|
||||
|
@ -1057,7 +1057,7 @@ increment the reference count. The correct version of the function reads::
|
|||
|
||||
This is a true story. An older version of Python contained variants of this bug
|
||||
and someone spent a considerable amount of time in a C debugger to figure out
|
||||
why his :meth:`__del__` methods would fail...
|
||||
why his :meth:`!__del__` methods would fail...
|
||||
|
||||
The second case of problems with a borrowed reference is a variant involving
|
||||
threads. Normally, multiple threads in the Python interpreter can't get in each
|
||||
|
@ -1224,7 +1224,7 @@ The function :c:func:`PySpam_System` is a plain C function, declared
|
|||
return system(command);
|
||||
}
|
||||
|
||||
The function :c:func:`spam_system` is modified in a trivial way::
|
||||
The function :c:func:`!spam_system` is modified in a trivial way::
|
||||
|
||||
static PyObject *
|
||||
spam_system(PyObject *self, PyObject *args)
|
||||
|
|
|
@ -36,7 +36,7 @@ So, if you want to define a new extension type, you need to create a new type
|
|||
object.
|
||||
|
||||
This sort of thing can only be explained by example, so here's a minimal, but
|
||||
complete, module that defines a new type named :class:`Custom` inside a C
|
||||
complete, module that defines a new type named :class:`!Custom` inside a C
|
||||
extension module :mod:`!custom`:
|
||||
|
||||
.. note::
|
||||
|
@ -50,9 +50,9 @@ extension module :mod:`!custom`:
|
|||
Now that's quite a bit to take in at once, but hopefully bits will seem familiar
|
||||
from the previous chapter. This file defines three things:
|
||||
|
||||
#. What a :class:`Custom` **object** contains: this is the ``CustomObject``
|
||||
struct, which is allocated once for each :class:`Custom` instance.
|
||||
#. How the :class:`Custom` **type** behaves: this is the ``CustomType`` struct,
|
||||
#. What a :class:`!Custom` **object** contains: this is the ``CustomObject``
|
||||
struct, which is allocated once for each :class:`!Custom` instance.
|
||||
#. How the :class:`!Custom` **type** behaves: this is the ``CustomType`` struct,
|
||||
which defines a set of flags and function pointers that the interpreter
|
||||
inspects when specific operations are requested.
|
||||
#. How to initialize the :mod:`!custom` module: this is the ``PyInit_custom``
|
||||
|
@ -128,7 +128,7 @@ our objects and in some error messages, for example:
|
|||
|
||||
Note that the name is a dotted name that includes both the module name and the
|
||||
name of the type within the module. The module in this case is :mod:`!custom` and
|
||||
the type is :class:`Custom`, so we set the type name to :class:`custom.Custom`.
|
||||
the type is :class:`!Custom`, so we set the type name to :class:`!custom.Custom`.
|
||||
Using the real dotted import path is important to make your type compatible
|
||||
with the :mod:`pydoc` and :mod:`pickle` modules. ::
|
||||
|
||||
|
@ -136,7 +136,7 @@ with the :mod:`pydoc` and :mod:`pickle` modules. ::
|
|||
.tp_itemsize = 0,
|
||||
|
||||
This is so that Python knows how much memory to allocate when creating
|
||||
new :class:`Custom` instances. :c:member:`~PyTypeObject.tp_itemsize` is
|
||||
new :class:`!Custom` instances. :c:member:`~PyTypeObject.tp_itemsize` is
|
||||
only used for variable-sized objects and should otherwise be zero.
|
||||
|
||||
.. note::
|
||||
|
@ -188,7 +188,7 @@ set to ``NULL``. ::
|
|||
}
|
||||
|
||||
This adds the type to the module dictionary. This allows us to create
|
||||
:class:`Custom` instances by calling the :class:`Custom` class:
|
||||
:class:`!Custom` instances by calling the :class:`!Custom` class:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
|
@ -246,7 +246,7 @@ We've added an extra include::
|
|||
This include provides declarations that we use to handle attributes, as
|
||||
described a bit later.
|
||||
|
||||
The :class:`Custom` type now has three data attributes in its C struct,
|
||||
The :class:`!Custom` type now has three data attributes in its C struct,
|
||||
*first*, *last*, and *number*. The *first* and *last* variables are Python
|
||||
strings containing first and last names. The *number* attribute is a C integer.
|
||||
|
||||
|
@ -321,7 +321,7 @@ The ``tp_new`` handler is responsible for creating (as opposed to initializing)
|
|||
objects of the type. It is exposed in Python as the :meth:`__new__` method.
|
||||
It is not required to define a ``tp_new`` member, and indeed many extension
|
||||
types will simply reuse :c:func:`PyType_GenericNew` as done in the first
|
||||
version of the ``Custom`` type above. In this case, we use the ``tp_new``
|
||||
version of the :class:`!Custom` type above. In this case, we use the ``tp_new``
|
||||
handler to initialize the ``first`` and ``last`` attributes to non-``NULL``
|
||||
default values.
|
||||
|
||||
|
@ -460,7 +460,7 @@ Further, the attributes can be deleted, setting the C pointers to ``NULL``. Eve
|
|||
though we can make sure the members are initialized to non-``NULL`` values, the
|
||||
members can be set to ``NULL`` if the attributes are deleted.
|
||||
|
||||
We define a single method, :meth:`Custom.name()`, that outputs the objects name as the
|
||||
We define a single method, :meth:`!Custom.name()`, that outputs the objects name as the
|
||||
concatenation of the first and last names. ::
|
||||
|
||||
static PyObject *
|
||||
|
@ -477,8 +477,8 @@ concatenation of the first and last names. ::
|
|||
return PyUnicode_FromFormat("%S %S", self->first, self->last);
|
||||
}
|
||||
|
||||
The method is implemented as a C function that takes a :class:`Custom` (or
|
||||
:class:`Custom` subclass) instance as the first argument. Methods always take an
|
||||
The method is implemented as a C function that takes a :class:`!Custom` (or
|
||||
:class:`!Custom` subclass) instance as the first argument. Methods always take an
|
||||
instance as the first argument. Methods often take positional and keyword
|
||||
arguments as well, but in this case we don't take any and don't need to accept
|
||||
a positional argument tuple or keyword argument dictionary. This method is
|
||||
|
@ -489,8 +489,8 @@ equivalent to the Python method:
|
|||
def name(self):
|
||||
return "%s %s" % (self.first, self.last)
|
||||
|
||||
Note that we have to check for the possibility that our :attr:`first` and
|
||||
:attr:`last` members are ``NULL``. This is because they can be deleted, in which
|
||||
Note that we have to check for the possibility that our :attr:`!first` and
|
||||
:attr:`!last` members are ``NULL``. This is because they can be deleted, in which
|
||||
case they are set to ``NULL``. It would be better to prevent deletion of these
|
||||
attributes and to restrict the attribute values to be strings. We'll see how to
|
||||
do that in the next section.
|
||||
|
@ -519,7 +519,7 @@ to add the :c:macro:`Py_TPFLAGS_BASETYPE` to our class flag definition::
|
|||
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
|
||||
We rename :c:func:`PyInit_custom` to :c:func:`PyInit_custom2`, update the
|
||||
We rename :c:func:`!PyInit_custom` to :c:func:`!PyInit_custom2`, update the
|
||||
module name in the :c:type:`PyModuleDef` struct, and update the full class
|
||||
name in the :c:type:`PyTypeObject` struct.
|
||||
|
||||
|
@ -538,18 +538,18 @@ Finally, we update our :file:`setup.py` file to build the new module:
|
|||
Providing finer control over data attributes
|
||||
============================================
|
||||
|
||||
In this section, we'll provide finer control over how the :attr:`first` and
|
||||
:attr:`last` attributes are set in the :class:`Custom` example. In the previous
|
||||
version of our module, the instance variables :attr:`first` and :attr:`last`
|
||||
In this section, we'll provide finer control over how the :attr:`!first` and
|
||||
:attr:`!last` attributes are set in the :class:`!Custom` example. In the previous
|
||||
version of our module, the instance variables :attr:`!first` and :attr:`!last`
|
||||
could be set to non-string values or even deleted. We want to make sure that
|
||||
these attributes always contain strings.
|
||||
|
||||
.. literalinclude:: ../includes/custom3.c
|
||||
|
||||
|
||||
To provide greater control, over the :attr:`first` and :attr:`last` attributes,
|
||||
To provide greater control, over the :attr:`!first` and :attr:`!last` attributes,
|
||||
we'll use custom getter and setter functions. Here are the functions for
|
||||
getting and setting the :attr:`first` attribute::
|
||||
getting and setting the :attr:`!first` attribute::
|
||||
|
||||
static PyObject *
|
||||
Custom_getfirst(CustomObject *self, void *closure)
|
||||
|
@ -578,13 +578,13 @@ getting and setting the :attr:`first` attribute::
|
|||
return 0;
|
||||
}
|
||||
|
||||
The getter function is passed a :class:`Custom` object and a "closure", which is
|
||||
The getter function is passed a :class:`!Custom` object and a "closure", which is
|
||||
a void pointer. In this case, the closure is ignored. (The closure supports an
|
||||
advanced usage in which definition data is passed to the getter and setter. This
|
||||
could, for example, be used to allow a single set of getter and setter functions
|
||||
that decide the attribute to get or set based on data in the closure.)
|
||||
|
||||
The setter function is passed the :class:`Custom` object, the new value, and the
|
||||
The setter function is passed the :class:`!Custom` object, the new value, and the
|
||||
closure. The new value may be ``NULL``, in which case the attribute is being
|
||||
deleted. In our setter, we raise an error if the attribute is deleted or if its
|
||||
new value is not a string.
|
||||
|
@ -673,11 +673,11 @@ still has a reference from itself. Its reference count doesn't drop to zero.
|
|||
Fortunately, Python's cyclic garbage collector will eventually figure out that
|
||||
the list is garbage and free it.
|
||||
|
||||
In the second version of the :class:`Custom` example, we allowed any kind of
|
||||
object to be stored in the :attr:`first` or :attr:`last` attributes [#]_.
|
||||
In the second version of the :class:`!Custom` example, we allowed any kind of
|
||||
object to be stored in the :attr:`!first` or :attr:`!last` attributes [#]_.
|
||||
Besides, in the second and third versions, we allowed subclassing
|
||||
:class:`Custom`, and subclasses may add arbitrary attributes. For any of
|
||||
those two reasons, :class:`Custom` objects can participate in cycles:
|
||||
:class:`!Custom`, and subclasses may add arbitrary attributes. For any of
|
||||
those two reasons, :class:`!Custom` objects can participate in cycles:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
|
@ -687,8 +687,8 @@ those two reasons, :class:`Custom` objects can participate in cycles:
|
|||
>>> n = Derived()
|
||||
>>> n.some_attribute = n
|
||||
|
||||
To allow a :class:`Custom` instance participating in a reference cycle to
|
||||
be properly detected and collected by the cyclic GC, our :class:`Custom` type
|
||||
To allow a :class:`!Custom` instance participating in a reference cycle to
|
||||
be properly detected and collected by the cyclic GC, our :class:`!Custom` type
|
||||
needs to fill two additional slots and to enable a flag that enables these slots:
|
||||
|
||||
.. literalinclude:: ../includes/custom4.c
|
||||
|
@ -818,7 +818,7 @@ increases an internal counter:
|
|||
.. literalinclude:: ../includes/sublist.c
|
||||
|
||||
|
||||
As you can see, the source code closely resembles the :class:`Custom` examples in
|
||||
As you can see, the source code closely resembles the :class:`!Custom` examples in
|
||||
previous sections. We will break down the main differences between them. ::
|
||||
|
||||
typedef struct {
|
||||
|
@ -886,7 +886,7 @@ slot with :c:func:`PyType_GenericNew` -- the allocation function from the base
|
|||
type will be inherited.
|
||||
|
||||
After that, calling :c:func:`PyType_Ready` and adding the type object to the
|
||||
module is the same as with the basic :class:`Custom` examples.
|
||||
module is the same as with the basic :class:`!Custom` examples.
|
||||
|
||||
|
||||
.. rubric:: Footnotes
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue