Skip to content

Commit 33ca248

Browse files
committed
Deploying to gh-pages from @ aa39396 🚀
1 parent 270c2cc commit 33ca248

File tree

536 files changed

+4416
-3964
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

536 files changed

+4416
-3964
lines changed

.buildinfo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# Sphinx build info version 1
22
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
3-
config: 0c2706cf595ac434c1f8ebdc6482e4c9
3+
config: 41a5cdda6dc98c136d4cb54063f53c68
44
tags: 645f666f9bcd5a90fca523b33c5a78b7

_sources/howto/isolating-extensions.rst.txt

Lines changed: 97 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -339,12 +339,44 @@ That is, heap types should:
339339
- Define a traverse function using ``Py_tp_traverse``, which
340340
visits the type (e.g. using :c:expr:`Py_VISIT(Py_TYPE(self))`).
341341

342-
Please refer to the :ref:`the documentation <type-structs>` of
342+
Please refer to the the documentation of
343343
:c:macro:`Py_TPFLAGS_HAVE_GC` and :c:member:`~PyTypeObject.tp_traverse`
344344
for additional considerations.
345345

346-
If your traverse function delegates to the ``tp_traverse`` of its base class
347-
(or another type), ensure that ``Py_TYPE(self)`` is visited only once.
346+
The API for defining heap types grew organically, leaving it
347+
somewhat awkward to use in its current state.
348+
The following sections will guide you through common issues.
349+
350+
351+
``tp_traverse`` in Python 3.8 and lower
352+
.......................................
353+
354+
The requirement to visit the type from ``tp_traverse`` was added in Python 3.9.
355+
If you support Python 3.8 and lower, the traverse function must *not*
356+
visit the type, so it must be more complicated::
357+
358+
static int my_traverse(PyObject *self, visitproc visit, void *arg)
359+
{
360+
if (Py_Version >= 0x03090000) {
361+
Py_VISIT(Py_TYPE(self));
362+
}
363+
return 0;
364+
}
365+
366+
Unfortunately, :c:data:`Py_Version` was only added in Python 3.11.
367+
As a replacement, use:
368+
369+
* :c:macro:`PY_VERSION_HEX`, if not using the stable ABI, or
370+
* :py:data:`sys.version_info` (via :c:func:`PySys_GetObject` and
371+
:c:func:`PyArg_ParseTuple`).
372+
373+
374+
Delegating ``tp_traverse``
375+
..........................
376+
377+
If your traverse function delegates to the :c:member:`~PyTypeObject.tp_traverse`
378+
of its base class (or another type), ensure that ``Py_TYPE(self)`` is visited
379+
only once.
348380
Note that only heap type are expected to visit the type in ``tp_traverse``.
349381

350382
For example, if your traverse function includes::
@@ -356,11 +388,70 @@ For example, if your traverse function includes::
356388
if (base->tp_flags & Py_TPFLAGS_HEAPTYPE) {
357389
// a heap type's tp_traverse already visited Py_TYPE(self)
358390
} else {
359-
Py_VISIT(Py_TYPE(self));
391+
if (Py_Version >= 0x03090000) {
392+
Py_VISIT(Py_TYPE(self));
393+
}
360394
}
361395

362-
It is not necessary to handle the type's reference count in ``tp_new``
363-
and ``tp_clear``.
396+
It is not necessary to handle the type's reference count in
397+
:c:member:`~PyTypeObject.tp_new` and :c:member:`~PyTypeObject.tp_clear`.
398+
399+
400+
Defining ``tp_dealloc``
401+
.......................
402+
403+
If your type has a custom :c:member:`~PyTypeObject.tp_dealloc` function,
404+
it needs to:
405+
406+
- call :c:func:`PyObject_GC_UnTrack` before any fields are invalidated, and
407+
- decrement the reference count of the type.
408+
409+
To keep the type valid while ``tp_free`` is called, the type's refcount needs
410+
to be decremented *after* the instance is deallocated. For example::
411+
412+
static void my_dealloc(PyObject *self)
413+
{
414+
PyObject_GC_UnTrack(self);
415+
...
416+
PyTypeObject *type = Py_TYPE(self);
417+
type->tp_free(self);
418+
Py_DECREF(type);
419+
}
420+
421+
The default ``tp_dealloc`` function does this, so
422+
if your type does *not* override
423+
``tp_dealloc`` you don't need to add it.
424+
425+
426+
Not overriding ``tp_free``
427+
..........................
428+
429+
The :c:member:`~PyTypeObject.tp_free` slot of a heap type must be set to
430+
:c:func:`PyObject_GC_Del`.
431+
This is the default; do not override it.
432+
433+
434+
Avoiding ``PyObject_New``
435+
.........................
436+
437+
GC-tracked objects need to be allocated using GC-aware functions.
438+
439+
If you use use :c:func:`PyObject_New` or :c:func:`PyObject_NewVar`:
440+
441+
- Get and call type's :c:member:`~PyTypeObject.tp_alloc` slot, if possible.
442+
That is, replace ``TYPE *o = PyObject_New(TYPE, typeobj)`` with::
443+
444+
TYPE *o = typeobj->tp_alloc(typeobj, 0);
445+
446+
Replace ``o = PyObject_NewVar(TYPE, typeobj, size)`` with the same,
447+
but use size instead of the 0.
448+
449+
- If the above is not possible (e.g. inside a custom ``tp_alloc``),
450+
call :c:func:`PyObject_GC_New` or :c:func:`PyObject_GC_NewVar`::
451+
452+
TYPE *o = PyObject_GC_New(TYPE, typeobj);
453+
454+
TYPE *o = PyObject_GC_NewVar(TYPE, typeobj, size);
364455

365456

366457
Module State Access from Classes

_sources/howto/perf_profiling.rst.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ Then we can use ``perf report`` to analyze the data:
9797
| | | | | |--2.97%--_PyObject_Malloc
9898
...
9999
100-
As you can see, the Python functions are not shown in the output, only ``_Py_Eval_EvalFrameDefault``
100+
As you can see, the Python functions are not shown in the output, only ``_PyEval_EvalFrameDefault``
101101
(the function that evaluates the Python bytecode) shows up. Unfortunately that's not very useful because all Python
102102
functions use the same C function to evaluate bytecode so we cannot know which Python function corresponds to which
103103
bytecode-evaluating function.

_sources/library/__main__.rst.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ students::
227227
import sys
228228
from .student import search_students
229229

230-
student_name = sys.argv[2] if len(sys.argv) >= 2 else ''
230+
student_name = sys.argv[1] if len(sys.argv) >= 2 else ''
231231
print(f'Found student: {search_students(student_name)}')
232232

233233
Note that ``from .student import search_students`` is an example of a relative

_sources/library/itertools.rst.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -798,10 +798,10 @@ which incur interpreter overhead.
798798
"Return first n items of the iterable as a list"
799799
return list(islice(iterable, n))
800800

801-
def prepend(value, iterator):
802-
"Prepend a single value in front of an iterator"
801+
def prepend(value, iterable):
802+
"Prepend a single value in front of an iterable"
803803
# prepend(1, [2, 3, 4]) --> 1 2 3 4
804-
return chain([value], iterator)
804+
return chain([value], iterable)
805805

806806
def tabulate(function, start=0):
807807
"Return function(0), function(1), ..."

_sources/library/profile.rst.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ the following::
8282

8383
The first line indicates that 214 calls were monitored. Of those calls, 207
8484
were :dfn:`primitive`, meaning that the call was not induced via recursion. The
85-
next line: ``Ordered by: cumulative time``, indicates that the text string in the
86-
far right column was used to sort the output. The column headings include:
85+
next line: ``Ordered by: cumulative time`` indicates the output is sorted
86+
by the ``cumtime`` values. The column headings include:
8787

8888
ncalls
8989
for the number of calls.

_sources/library/stdtypes.rst.txt

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4752,14 +4752,17 @@ support membership tests:
47524752

47534753
.. versionadded:: 3.10
47544754

4755-
Keys views are set-like since their entries are unique and :term:`hashable`. If all
4756-
values are hashable, so that ``(key, value)`` pairs are unique and hashable,
4757-
then the items view is also set-like. (Values views are not treated as set-like
4755+
Keys views are set-like since their entries are unique and :term:`hashable`.
4756+
Items views also have set-like operations since the (key, value) pairs
4757+
are unique and the keys are hashable.
4758+
If all values in an items view are hashable as well,
4759+
then the items view can interoperate with other sets.
4760+
(Values views are not treated as set-like
47584761
since the entries are generally not unique.) For set-like views, all of the
47594762
operations defined for the abstract base class :class:`collections.abc.Set` are
47604763
available (for example, ``==``, ``<``, or ``^``). While using set operators,
4761-
set-like views accept any iterable as the other operand, unlike sets which only
4762-
accept sets as the input.
4764+
set-like views accept any iterable as the other operand,
4765+
unlike sets which only accept sets as the input.
47634766

47644767
An example of dictionary view usage::
47654768

_sources/library/sys.monitoring.rst.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ Registering and using tools
5454

5555
Should be called once a tool no longer requires *tool_id*.
5656

57+
.. note::
58+
59+
:func:`free_tool_id` will not disable global or local events associated
60+
with *tool_id*, nor will it unregister any callback functions. This
61+
function is only intended to be used to notify the VM that the
62+
particular *tool_id* is no longer in use.
63+
5764
.. function:: get_tool(tool_id: int, /) -> str | None
5865

5966
Returns the name of the tool if *tool_id* is in use,

_sources/library/typing.rst.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1941,7 +1941,7 @@ without the dedicated syntax, as documented below.
19411941

19421942
.. doctest::
19431943

1944-
>>> from typing import ParamSpec
1944+
>>> from typing import ParamSpec, get_origin
19451945
>>> P = ParamSpec("P")
19461946
>>> get_origin(P.args) is P
19471947
True

_sources/reference/expressions.rst.txt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1774,10 +1774,11 @@ Or, when processing a file stream in chunks:
17741774
while chunk := file.read(9000):
17751775
process(chunk)
17761776
1777-
Assignment expressions must be surrounded by parentheses when used
1778-
as sub-expressions in slicing, conditional, lambda,
1779-
keyword-argument, and comprehension-if expressions
1780-
and in ``assert`` and ``with`` statements.
1777+
Assignment expressions must be surrounded by parentheses when
1778+
used as expression statements and when used as sub-expressions in
1779+
slicing, conditional, lambda,
1780+
keyword-argument, and comprehension-if expressions and
1781+
in ``assert``, ``with``, and ``assignment`` statements.
17811782
In all other places where they can be used, parentheses are not required,
17821783
including in ``if`` and ``while`` statements.
17831784

0 commit comments

Comments
 (0)