Skip to content

Commit 689d517

Browse files
committed
Make references point to asyncio. Wrap some long lines.
1 parent f7dbaa6 commit 689d517

File tree

1 file changed

+35
-28
lines changed

1 file changed

+35
-28
lines changed

Doc/howto/a-conceptual-overview-of-asyncio.rst

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
.. _a-conceptual-overview-of-asyncio:
22

3-
***************************************
4-
A Conceptual Overview of :mod:`asyncio`
5-
***************************************
3+
****************************************
4+
A Conceptual Overview of :mod:`!asyncio`
5+
****************************************
66

7-
This article seeks to help you build a sturdy mental model of how ``asyncio``
7+
This article seeks to help you build a sturdy mental model of how :mod:`asyncio`
88
fundamentally works, helping you understand the how and why behind the
99
recommended patterns.
1010

11-
You might be curious about some key ``asyncio`` concepts.
11+
You might be curious about some key :mod:`!asyncio` concepts.
1212
You'll be comfortably able to answer these questions by the end of this
1313
article.
1414

1515
- What's happening behind the scenes when an object is ``await``\ ed?
16-
- How does ``asyncio`` differentiate between a task which doesn't need CPU-time
17-
(such as a network request or file read) as opposed to a task that does
18-
(such as computing n-factorial)?
16+
- How does :mod:`!asyncio` differentiate between a task which doesn't need
17+
CPU-time (such as a network request or file read) as opposed to a task that
18+
does (such as computing n-factorial)?
1919
- How would I go about writing my own asynchronous variant of some operation?
2020
Something like an async sleep, database request, and so on.
2121

@@ -28,14 +28,14 @@ article.
2828
A conceptual overview part 1: the high-level
2929
--------------------------------------------
3030

31-
In part 1, we'll cover the main, high-level building blocks of ``asyncio``:
31+
In part 1, we'll cover the main, high-level building blocks of :mod:`!asyncio`:
3232
the event loop, coroutine functions, coroutine objects, tasks and ``await``.
3333

3434
==========
3535
Event Loop
3636
==========
3737

38-
Everything in ``asyncio`` happens relative to the event loop.
38+
Everything in :mod:`!asyncio` happens relative to the event loop.
3939
It's the star of the show.
4040
It's like an orchestra conductor.
4141
It's behind the scenes managing resources.
@@ -44,7 +44,7 @@ done comes from the respect and cooperation of its teammates.
4444

4545
In more technical terms, the event loop contains a queue of jobs (or "chunks
4646
of work") to be run.
47-
Some jobs are added directly by you, and some indirectly by ``asyncio``.
47+
Some jobs are added directly by you, and some indirectly by :mod:`!asyncio`.
4848
The event loop pops a job from the queue and invokes it (or "gives it control"),
4949
similar to calling a function, then that job runs.
5050
Once it pauses or completes, it returns control to the event loop.
@@ -107,8 +107,9 @@ as coroutine.
107107
That can be confusing!
108108
In this article, coroutine specifically refers to a coroutine object, or more
109109
precisely, an instance of :data:`types.CoroutineType` (native coroutine).
110-
Note that coroutines can also exist as instances of :class:`collections.abc.Coroutine`
111-
-- a distinction that matters for type checking.
110+
Note that coroutines can also exist as instances of
111+
:class:`collections.abc.Coroutine` -- a distinction that matters for type
112+
checking.
112113

113114
A coroutine represents the function's body or logic.
114115
A coroutine has to be explicitly started; again, merely creating the coroutine
@@ -120,7 +121,8 @@ That pausing and resuming ability is what allows for asynchronous behavior!
120121
Coroutines and coroutine functions were built by leveraging the functionality
121122
of :term:`generators <generator iterator>` and
122123
:term:`generator functions <generator>`.
123-
Recall, a generator function is a function that :keyword:`yield`\s, like this one::
124+
Recall, a generator function is a function that :keyword:`yield`\s, like this
125+
one::
124126

125127
def get_random_number():
126128
# This would be a bad random number generator!
@@ -162,7 +164,7 @@ clear in a moment when we discuss ``await``.
162164
The recommended way to create tasks is via :func:`asyncio.create_task`.
163165
Creating a task automatically adds it to the event loop's queue of tasks.
164166

165-
Since there's only one event loop (in each thread), ``asyncio`` takes care of
167+
Since there's only one event loop (in each thread), :mod:`!asyncio` takes care of
166168
associating the task with the event loop for you. As such, there's no need
167169
to specify the event loop.
168170

@@ -196,9 +198,10 @@ In practice, it's slightly more complex, but not by much.
196198
In part 2, we'll walk through the details that make this possible.
197199

198200
**Unlike tasks, awaiting a coroutine does not cede control!**
199-
Wrapping a coroutine in a task first, then ``await``\ ing that would cede control.
200-
The behavior of ``await coroutine`` is effectively the same as invoking a regular,
201-
synchronous Python function.
201+
Wrapping a coroutine in a task first, then ``await``\ ing that would cede
202+
control.
203+
The behavior of ``await coroutine`` is effectively the same as invoking a
204+
regular, synchronous Python function.
202205
Consider this program::
203206

204207
import asyncio
@@ -248,7 +251,8 @@ The event loop then works through its queue, calling ``coro_b()`` and then
248251
A conceptual overview part 2: the nuts and bolts
249252
------------------------------------------------
250253

251-
Part 2 goes into detail on the mechanisms ``asyncio`` uses to manage control flow.
254+
Part 2 goes into detail on the mechanisms :mod:`!asyncio` uses to manage
255+
control flow.
252256
This is where the magic happens.
253257
You'll come away from this section knowing what await does behind the scenes
254258
and how to make your own asynchronous operators.
@@ -257,16 +261,18 @@ and how to make your own asynchronous operators.
257261
coroutine.send(), await, yield and StopIteration
258262
================================================
259263

260-
``asyncio`` leverages 4 components to pass around control.
264+
:mod:`!asyncio` leverages 4 components to pass around control.
261265

262-
:meth:`coroutine.send(arg) <generator.send>` is the method used to start or resume a coroutine.
266+
:meth:`coroutine.send(arg) <generator.send>` is the method used to start or
267+
resume a coroutine.
263268
If the coroutine was paused and is now being resumed, the argument ``arg``
264269
will be sent in as the return value of the ``yield`` statement which originally
265270
paused it.
266271
If the coroutine is being started, as opposed to resumed, ``arg`` must be
267272
``None``.
268273

269-
:ref:`yield <yieldexpr>`, like usual, pauses execution and returns control to the caller.
274+
:ref:`yield <yieldexpr>`, like usual, pauses execution and returns control
275+
to the caller.
270276
In the example below, the ``yield``, on line 3, is called by
271277
``... = await rock`` on line 11.
272278
Generally, ``await`` calls the :meth:`~object.__await__` method of the given
@@ -407,10 +413,11 @@ preventing other tasks from running.
407413
await asyncio.gather(*work_tasks)
408414

409415

410-
Below, we use a future to enable custom control over when that task will be marked
411-
as done.
412-
If :meth:`future.set_result() <asyncio.Future.set_result>` (the method responsible for marking that future as
413-
done) is never called, then this task will never finish.
416+
Below, we use a future to enable custom control over when that task will be
417+
marked as done.
418+
If :meth:`future.set_result() <asyncio.Future.set_result>` (the method
419+
responsible for marking that future as done) is never called, then this task
420+
will never finish.
414421
We've also enlisted the help of another task, which we'll see in a moment, that
415422
will monitor how much time has elapsed and accordingly call
416423
``future.set_result()``.
@@ -435,8 +442,8 @@ As usual, the event loop cycles through its queue of tasks, giving them control
435442
and receiving control back when they pause or finish.
436443
The ``watcher_task``, which runs the coroutine ``_sleep_watcher(...)``, will
437444
be invoked once per full cycle of the event loop's queue.
438-
On each resumption, it'll check the time and if not enough has elapsed, then it'll
439-
pause once again and hand control back to the event loop.
445+
On each resumption, it'll check the time and if not enough has elapsed, then
446+
it'll pause once again and hand control back to the event loop.
440447
Eventually, enough time will have elapsed, and ``_sleep_watcher(...)`` will
441448
mark the future as done, and then itself finish too by breaking out of the
442449
infinite ``while`` loop.

0 commit comments

Comments
 (0)