Skip to content

Commit 61c27ae

Browse files
committed
Deploying to gh-pages from @ ead1032 🚀
1 parent 7b94972 commit 61c27ae

607 files changed

Lines changed: 10931 additions & 10135 deletions

File tree

Some content is hidden

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

.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 records the configuration used when building these files. When it is not found, a full rebuild will be done.
3-
config: 7a01c5ca1c710ac068e940d7a4e237da
3+
config: dd2be1ec916c30cc094164266e8a5c26
44
tags: b5e2c454ba7771976391ed0cecdde553

_sources/c-api/memory.rst.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ memory footprint as a whole. Consequently, under certain circumstances, the
8181
Python memory manager may or may not trigger appropriate actions, like garbage
8282
collection, memory compaction or other preventive procedures. Note that by using
8383
the C library allocator as shown in the previous example, the allocated memory
84-
for the I/O buffer escapes completely the Python memory manager.
84+
for the I/O buffer completely escapes the Python memory manager.
8585

8686
.. seealso::
8787

@@ -161,7 +161,7 @@ zero bytes.
161161
162162
.. c:function:: void* PyMem_RawCalloc(size_t nelem, size_t elsize)
163163
164-
Allocates *nelem* elements each whose size in bytes is *elsize* and returns
164+
Allocates *nelem* elements each of size *elsize* bytes and returns
165165
a pointer of type :c:expr:`void*` to the allocated memory, or ``NULL`` if the
166166
request fails. The memory is initialized to zeros.
167167
@@ -239,7 +239,7 @@ In the GIL-enabled build (default build) the
239239
240240
.. c:function:: void* PyMem_Calloc(size_t nelem, size_t elsize)
241241
242-
Allocates *nelem* elements each whose size in bytes is *elsize* and returns
242+
Allocates *nelem* elements each of size *elsize* bytes and returns
243243
a pointer of type :c:expr:`void*` to the allocated memory, or ``NULL`` if the
244244
request fails. The memory is initialized to zeros.
245245
@@ -372,7 +372,7 @@ The :ref:`default object allocator <default-memory-allocators>` uses the
372372
373373
.. c:function:: void* PyObject_Calloc(size_t nelem, size_t elsize)
374374
375-
Allocates *nelem* elements each whose size in bytes is *elsize* and returns
375+
Allocates *nelem* elements each of size *elsize* bytes and returns
376376
a pointer of type :c:expr:`void*` to the allocated memory, or ``NULL`` if the
377377
request fails. The memory is initialized to zeros.
378378

_sources/c-api/typeobj.rst.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3045,13 +3045,13 @@ Buffer Object Structures
30453045
steps:
30463046

30473047
(1) Check if the request can be met. If not, raise :exc:`BufferError`,
3048-
set :c:expr:`view->obj` to ``NULL`` and return ``-1``.
3048+
set ``view->obj`` to ``NULL`` and return ``-1``.
30493049

30503050
(2) Fill in the requested fields.
30513051

30523052
(3) Increment an internal counter for the number of exports.
30533053

3054-
(4) Set :c:expr:`view->obj` to *exporter* and increment :c:expr:`view->obj`.
3054+
(4) Set ``view->obj`` to *exporter* and increment ``view->obj``.
30553055

30563056
(5) Return ``0``.
30573057

@@ -3077,10 +3077,10 @@ Buffer Object Structures
30773077
schemes can be used:
30783078

30793079
* Re-export: Each member of the tree acts as the exporting object and
3080-
sets :c:expr:`view->obj` to a new reference to itself.
3080+
sets ``view->obj`` to a new reference to itself.
30813081

30823082
* Redirect: The buffer request is redirected to the root object of the
3083-
tree. Here, :c:expr:`view->obj` will be a new reference to the root
3083+
tree. Here, ``view->obj`` will be a new reference to the root
30843084
object.
30853085

30863086
The individual fields of *view* are described in section
@@ -3134,7 +3134,7 @@ Buffer Object Structures
31343134
*view* argument.
31353135

31363136

3137-
This function MUST NOT decrement :c:expr:`view->obj`, since that is
3137+
This function MUST NOT decrement ``view->obj``, since that is
31383138
done automatically in :c:func:`PyBuffer_Release` (this scheme is
31393139
useful for breaking reference cycles).
31403140

_sources/c-api/weakref.rst.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ as much as it can.
4242
callable object that receives notification when *ob* is garbage collected; it
4343
should accept a single parameter, which will be the weak reference object
4444
itself. *callback* may also be ``None`` or ``NULL``. If *ob* is not a
45-
weakly referenceable object, or if *callback* is not callable, ``None``, or
46-
``NULL``, this will return ``NULL`` and raise :exc:`TypeError`.
45+
weakly referenceable object, this will raise :exc:`TypeError` and return
46+
``NULL``.
4747
4848
.. seealso::
4949
:c:func:`PyType_SUPPORTS_WEAKREFS` for checking if *ob* is weakly
@@ -58,8 +58,8 @@ as much as it can.
5858
be a callable object that receives notification when *ob* is garbage
5959
collected; it should accept a single parameter, which will be the weak
6060
reference object itself. *callback* may also be ``None`` or ``NULL``. If *ob*
61-
is not a weakly referenceable object, or if *callback* is not callable,
62-
``None``, or ``NULL``, this will return ``NULL`` and raise :exc:`TypeError`.
61+
weakly referenceable object, this will raise :exc:`TypeError` and return
62+
``NULL``.
6363
6464
.. seealso::
6565
:c:func:`PyType_SUPPORTS_WEAKREFS` for checking if *ob* is weakly

_sources/deprecations/pending-removal-in-3.15.rst.txt

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,6 @@ Pending removal in Python 3.15
3333

3434
* ``load_module()`` method: use ``exec_module()`` instead.
3535

36-
* :class:`locale`:
37-
38-
* The :func:`~locale.getdefaultlocale` function
39-
has been deprecated since Python 3.11.
40-
Its removal was originally planned for Python 3.13 (:gh:`90817`),
41-
but has been postponed to Python 3.15.
42-
Use :func:`~locale.getlocale`, :func:`~locale.setlocale`,
43-
and :func:`~locale.getencoding` instead.
44-
(Contributed by Hugo van Kemenade in :gh:`111187`.)
45-
4636
* :mod:`pathlib`:
4737

4838
* :meth:`.PurePath.is_reserved`

_sources/library/argparse.rst.txt

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -442,9 +442,8 @@ is considered equivalent to the expression ``['-f', 'foo', '-f', 'bar']``.
442442

443443
.. note::
444444

445-
Empty lines are treated as empty strings (``''``), which are allowed as values but
446-
not as arguments. Empty lines that are read as arguments will result in an
447-
"unrecognized arguments" error.
445+
Each line is treated as a single argument, so an empty line is read as an
446+
empty string (``''``).
448447

449448
:class:`ArgumentParser` uses :term:`filesystem encoding and error handler`
450449
to read the file containing arguments.
@@ -1048,6 +1047,10 @@ is used when no command-line argument was present::
10481047
>>> parser.parse_args([])
10491048
Namespace(foo=42)
10501049

1050+
Because ``nargs='*'`` gathers any supplied values into a list, an absent
1051+
positional argument yields an empty list (``[]``). Only a non-``None``
1052+
*default* overrides this (so ``default=None`` still gives ``[]``).
1053+
10511054
For required_ arguments, the ``default`` value is ignored. For example, this
10521055
applies to positional arguments with nargs_ values other than ``?`` or ``*``,
10531056
or optional arguments marked as ``required=True``.
@@ -1360,6 +1363,10 @@ behavior::
13601363
>>> parser.parse_args('--foo XXX'.split())
13611364
Namespace(bar='XXX')
13621365

1366+
Multiple arguments may share the same ``dest``. By default, the value from the
1367+
last such argument given on the command line wins. Use ``action='append'`` to
1368+
collect values from all of them into a list instead. For conflicting *option
1369+
strings* rather than ``dest`` names, see conflict_handler_.
13631370

13641371
.. _deprecated:
13651372

@@ -1755,6 +1762,11 @@ Subcommands
17551762
present, and when the ``b`` command is specified, only the ``foo`` and
17561763
``baz`` attributes are present.
17571764

1765+
If a subparser defines an argument with the same ``dest`` as the parent
1766+
parser, the two share a single namespace attribute, so the parent's value
1767+
won't be retained. Users should give them distinct ``dest`` values to
1768+
keep both.
1769+
17581770
Similarly, when a help message is requested from a subparser, only the help
17591771
for that particular parser will be printed. The help message will not
17601772
include parent parser or sibling parser messages. (A help message for each
@@ -2199,6 +2211,9 @@ Customizing file parsing
21992211
def convert_arg_line_to_args(self, arg_line):
22002212
return arg_line.split()
22012213

2214+
Note that with this override an argument can no longer contain spaces, since
2215+
each space-separated word becomes a separate argument.
2216+
22022217

22032218
Exiting methods
22042219
^^^^^^^^^^^^^^^
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
.. currentmodule:: asyncio
2+
3+
.. _asyncio-threading:
4+
5+
asyncio and free-threaded Python
6+
================================
7+
8+
asyncio uses an event loop as a scheduler to enable highly efficient
9+
concurrency by switching between tasks to allow non-blocking I/O
10+
operations. This results in better performance for I/O-bound use
11+
cases. It also allows off-loading CPU-bound work to a thread or
12+
process pool, but that is still limited by the :term:`global
13+
interpreter lock` in CPython.
14+
15+
However, in :ref:`free-threaded Python <freethreading-python-howto>`,
16+
the GIL is disabled and Python can run true multi-threaded code. This
17+
means that asyncio can now take advantage of multiple CPU cores without
18+
the limitations imposed by the GIL.
19+
20+
Since Python 3.14, asyncio has first-class support for free-threaded
21+
Python, and the implementation of asyncio is safe to use in a
22+
multi-threaded environment.
23+
24+
A single event loop on one core can handle many connections
25+
concurrently, but the Python code that runs to handle each one still
26+
executes serially. Once requests involve a non-trivial amount of
27+
per-request computation, that handling becomes the bottleneck, and a
28+
single core can no longer keep up. Combining asyncio with threads is
29+
most useful here: by running an event loop per thread, the handling of
30+
different requests can run in parallel across multiple CPU cores. It is
31+
also useful when you need to run blocking or CPU-bound code from an
32+
asyncio application.
33+
34+
35+
.. seealso::
36+
37+
`Scaling asyncio on Free-Threaded Python
38+
<https://labs.quansight.org/blog/scaling-asyncio-on-free-threaded-python>`__,
39+
a blog post by Kumar Aditya which explains the internal changes
40+
that make asyncio safe and efficient under free-threaded Python,
41+
together with benchmarks of the resulting improvements.
42+
43+
44+
Thread safety considerations
45+
----------------------------
46+
47+
While asyncio is designed to be thread-safe in a free-threaded Python
48+
environment, there are still some considerations to keep in mind when
49+
using asyncio with threads:
50+
51+
1. **Event loop**: Each thread should have its own event loop which
52+
should not be shared across threads. This ensures that the event loop
53+
can manage its own tasks and callbacks without interference from
54+
other threads.
55+
56+
2. **Task management**: Tasks and futures created in one thread should
57+
not be awaited or manipulated from another thread.
58+
59+
3. **Thread-safe APIs**: When interacting with asyncio from multiple
60+
threads, it's important to use thread-safe APIs provided by asyncio,
61+
such as :func:`asyncio.run_coroutine_threadsafe` for submitting
62+
coroutines to an event loop from another thread. If you need to
63+
call a callback from a different thread, you can use
64+
:meth:`loop.call_soon_threadsafe` to schedule it safely.
65+
66+
4. **Synchronization**: The synchronization primitives provided by
67+
asyncio (like :class:`asyncio.Lock` and :class:`asyncio.Event`)
68+
are not designed to be used across threads. If you need to
69+
synchronize between threads, you should use the synchronization
70+
primitives from the :mod:`threading` module instead.
71+
72+
73+
Using asyncio with threads
74+
--------------------------
75+
76+
asyncio supports running one event loop per thread, which allows you to
77+
take advantage of multiple CPU cores in a free-threaded Python
78+
environment. Each thread can run its own event loop, and tasks can be
79+
scheduled on those loops independently.
80+
81+
Here's an example of how to use asyncio with threads::
82+
83+
import asyncio
84+
import threading
85+
86+
async def worker(name: str) -> None:
87+
print(f"Worker {name} starting")
88+
await asyncio.sleep(1)
89+
print(f"Worker {name} done")
90+
91+
def run_loop(name: str) -> None:
92+
asyncio.run(worker(name))
93+
94+
threads = [
95+
threading.Thread(target=run_loop, args=(f"T{i}",))
96+
for i in range(4)
97+
]
98+
for t in threads:
99+
t.start()
100+
for t in threads:
101+
t.join()
102+
103+
In this example, each thread creates its own event loop with
104+
:func:`asyncio.run` and runs a coroutine on it. The threads execute
105+
concurrently, and in a free-threaded build they can run on separate
106+
CPU cores in parallel.
107+
108+
109+
Producer/consumer across threads
110+
--------------------------------
111+
112+
When a regular (non-asyncio) thread needs to hand work to an asyncio
113+
event loop running in another thread, use a thread-safe primitive such
114+
as :class:`queue.Queue` rather than :class:`asyncio.Queue`, which is
115+
only safe within a single event loop.::
116+
117+
import asyncio
118+
import queue
119+
import threading
120+
121+
def producer(q: queue.Queue[int]) -> None:
122+
for i in range(5):
123+
print(f"Producing {i}")
124+
q.put(i)
125+
q.shutdown()
126+
127+
async def consumer(q: queue.Queue[int]) -> None:
128+
while True:
129+
try:
130+
item = q.get_nowait()
131+
except queue.Empty:
132+
await asyncio.sleep(0.1)
133+
continue
134+
except queue.ShutDown:
135+
break
136+
print(f"Consumed {item}")
137+
await asyncio.sleep(item)
138+
139+
q: queue.Queue[int] = queue.Queue()
140+
consumer_thread = threading.Thread(
141+
target=lambda: asyncio.run(consumer(q))
142+
)
143+
consumer_thread.start()
144+
producer(q)
145+
consumer_thread.join()
146+
147+
The producer runs on the main thread while the consumer runs inside an
148+
event loop on its own thread, yet they communicate safely through
149+
``queue.Queue``. When the queue is empty the consumer sleeps briefly
150+
and tries again. When the producer is done it calls
151+
:meth:`~queue.Queue.shutdown`, which causes subsequent
152+
:meth:`~queue.Queue.get_nowait` calls to raise :exc:`queue.ShutDown`
153+
so the consumer can exit cleanly.
154+

_sources/library/asyncio.rst.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ for full functionality and the latest features.
128128
asyncio-api-index.rst
129129
asyncio-llapi-index.rst
130130
asyncio-dev.rst
131+
asyncio-threading.rst
131132

132133
.. note::
133134
The source code for asyncio can be found in :source:`Lib/asyncio/`.

_sources/library/bisect.rst.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ example uses :py:func:`~bisect.bisect` to look up a letter grade for an exam sco
203203
based on a set of ordered numeric breakpoints: 90 and up is an 'A', 80 to 89 is
204204
a 'B', and so on::
205205

206-
>>> def grade(score)
206+
>>> def grade(score):
207207
... i = bisect([60, 70, 80, 90], score)
208208
... return "FDCBA"[i]
209209
...

_sources/library/collections.abc.rst.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ Notes on using :class:`Set` and :class:`MutableSet` as a mixin:
459459
The :class:`Set` mixin provides a :meth:`!_hash` method to compute a hash value
460460
for the set; however, :meth:`~object.__hash__` is not defined because not all sets
461461
are :term:`hashable` or immutable. To add set hashability using mixins,
462-
inherit from both :meth:`Set` and :meth:`Hashable`, then define
462+
inherit from both :class:`Set` and :class:`Hashable`, then define
463463
``__hash__ = Set._hash``.
464464

465465
.. seealso::

0 commit comments

Comments
 (0)