Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
05b35b0
- Add an explainer guide (aka HOWTO, not how-to) for asyncio.
anordin95 Jul 29, 2025
446534c
Fix linter errors.
anordin95 Jul 29, 2025
176096d
- Enforce max line length of roughly 79 chars.
anordin95 Jul 29, 2025
b745f88
Add reference to subinterpreters.
anordin95 Jul 29, 2025
0f2b8db
- Significantly reduce article size. Remove both example sections & "…
anordin95 Jul 29, 2025
27d1dcd
Align section-header lengths with section names.
anordin95 Jul 29, 2025
3852bb1
- Remove reference to deleted section.
anordin95 Jul 29, 2025
8bf6d2c
- Fix a variety of rote style guide items like title-alignment, use o…
anordin95 Jul 31, 2025
397df8f
- One last title alignment.
anordin95 Jul 31, 2025
84aedf7
- Style nit.
anordin95 Jul 31, 2025
3d3e12c
- Rework a variety of I statements.
anordin95 Jul 31, 2025
a5fdd0e
Lint fix.
anordin95 Jul 31, 2025
b1aef5c
- Firm up commentary on yield from in corotuines.
anordin95 Aug 1, 2025
64a12b4
Update language comparing await and yield from.
anordin95 Aug 1, 2025
0fffd4b
- Remove await-ing Tasks and futures section
anordin95 Aug 1, 2025
bfd1212
Update Doc/howto/a-conceptual-overview-of-asyncio.rst
anordin95 Aug 1, 2025
c946563
Update Doc/howto/a-conceptual-overview-of-asyncio.rst
anordin95 Aug 1, 2025
3fc668c
- Address comments related to style & writing flow.
anordin95 Aug 1, 2025
ebfe542
per-thread event loop note.
anordin95 Aug 1, 2025
3978837
Add section describing coroutines roots in generators.
anordin95 Aug 1, 2025
0dd99eb
Phrasing tweak.
anordin95 Aug 1, 2025
ff804fe
Use asyncio.create_task instead of asyncio.Task
anordin95 Aug 1, 2025
00a1a68
Update Doc/howto/a-conceptual-overview-of-asyncio.rst
anordin95 Aug 1, 2025
e982f9c
Update Doc/howto/a-conceptual-overview-of-asyncio.rst
anordin95 Aug 1, 2025
a033876
small phrasing.
anordin95 Aug 1, 2025
dbbc0ab
Update Doc/howto/a-conceptual-overview-of-asyncio.rst
anordin95 Aug 1, 2025
af9ba25
phrasing nit.
anordin95 Aug 1, 2025
34f3335
style nits
anordin95 Aug 1, 2025
dca3d38
Update Doc/howto/a-conceptual-overview-of-asyncio.rst
anordin95 Aug 1, 2025
db4ac35
phrasing nit
anordin95 Aug 1, 2025
bb8d018
Fix misnaming of async generator.
anordin95 Aug 1, 2025
5fdd4e9
phrasing nits.
anordin95 Aug 1, 2025
fe3c732
Update Doc/howto/a-conceptual-overview-of-asyncio.rst
anordin95 Aug 1, 2025
1abe9a1
Update Doc/howto/a-conceptual-overview-of-asyncio.rst
anordin95 Aug 1, 2025
eadc0fb
consistent spacing
anordin95 Aug 1, 2025
1f7323d
Update Doc/howto/a-conceptual-overview-of-asyncio.rst
anordin95 Aug 1, 2025
99ac489
phrasing nits
anordin95 Aug 2, 2025
feb8634
Update Doc/howto/a-conceptual-overview-of-asyncio.rst
anordin95 Aug 2, 2025
49e9c65
Update Doc/howto/a-conceptual-overview-of-asyncio.rst
anordin95 Aug 2, 2025
daba131
Update Doc/howto/a-conceptual-overview-of-asyncio.rst
anordin95 Aug 2, 2025
c31f3c5
Update Doc/howto/a-conceptual-overview-of-asyncio.rst
anordin95 Aug 2, 2025
6756257
add conclusion
anordin95 Aug 2, 2025
a730bd3
nits
anordin95 Aug 2, 2025
8fca2e3
- Variety of style & grammar improvements thanks to ZeroIntensity's c…
anordin95 Aug 2, 2025
776daeb
- Make all directives start with a 3 space indent. Then 4 thereafter.
anordin95 Aug 2, 2025
0b795a2
- Use :linenos: instead of manually writing the line numbers.
anordin95 Aug 2, 2025
d10eeec
- Fix label typo for article.
anordin95 Aug 2, 2025
b2e90f3
fix label link.
anordin95 Aug 3, 2025
9e07a36
Apply suggestions from code review
anordin95 Aug 3, 2025
d12b29f
- introduce async-sleep name
anordin95 Aug 3, 2025
86039b7
Phrasing
anordin95 Aug 3, 2025
e5fafc4
nit
anordin95 Aug 3, 2025
1dc6e51
ungendered octopus
anordin95 Aug 3, 2025
3c0b0a4
teammates
anordin95 Aug 3, 2025
0f3931c
jobs
anordin95 Aug 3, 2025
82a1967
rework fella to penguin
anordin95 Aug 3, 2025
9fa9fca
- remove byline; add seealso
anordin95 Aug 3, 2025
9ff73dc
Change ref from asyncio to use seealso block.
anordin95 Aug 3, 2025
be9629d
Remove typehints. Fix indentation in one code example.
anordin95 Aug 3, 2025
f7dbaa6
Slight rephrase for clarity.
anordin95 Aug 3, 2025
689d517
Make references point to asyncio. Wrap some long lines.
anordin95 Aug 3, 2025
9da27dd
- Variety of style/phrasing improvements based on PR feedback.
anordin95 Aug 4, 2025
3c0c11c
phrasing.
anordin95 Aug 4, 2025
671cc80
phrasing nit.
anordin95 Aug 4, 2025
2a96782
Apply suggestions from code review
anordin95 Aug 4, 2025
def6157
Update Doc/howto/a-conceptual-overview-of-asyncio.rst
anordin95 Aug 4, 2025
a84827b
nit
anordin95 Aug 5, 2025
01710e2
Apply suggestions from code review
anordin95 Aug 5, 2025
b5f56f3
fix backticks.
anordin95 Aug 5, 2025
3344574
nits
anordin95 Aug 5, 2025
1ed21c0
nit
anordin95 Aug 6, 2025
b574f72
add section on asyncio.run
anordin95 Aug 6, 2025
0fbd5b1
title change under the hood.
anordin95 Aug 6, 2025
27785f3
modify task coro example.
anordin95 Aug 6, 2025
a75b55b
howtos article link.
anordin95 Aug 6, 2025
53ac647
prefer await without backticks.
anordin95 Aug 6, 2025
7b5ff84
phrasing tweak.
anordin95 Aug 6, 2025
a8030d6
Rework phrasing around how await tasks pauses and returns control in …
anordin95 Aug 6, 2025
b4d087a
move code block to beforfe explanation in coroutine under the hood.
anordin95 Aug 6, 2025
9e5aaf6
phrasing.
anordin95 Aug 6, 2025
55a268c
link to yield from.
anordin95 Aug 7, 2025
43c1c96
style nits
anordin95 Aug 7, 2025
1f8f863
nit
anordin95 Aug 7, 2025
ef71d25
- Modify language re: event-loop cycling endlessly.
anordin95 Aug 7, 2025
4796f85
- Add a note about debug=True on asyncio.run to await coro section.
anordin95 Aug 7, 2025
1000ace
clarity nit
anordin95 Aug 7, 2025
e649c07
- Add two other references in seealso block.
anordin95 Aug 7, 2025
d619868
nit
anordin95 Aug 7, 2025
52a90c0
Language simplification
anordin95 Aug 7, 2025
08d4eec
Apply suggestions from code review
anordin95 Aug 7, 2025
1934aad
nit
anordin95 Aug 7, 2025
7a4eebe
grammar fix.
anordin95 Aug 7, 2025
a2fd17a
fix
anordin95 Aug 7, 2025
c944ff1
worker bees
anordin95 Aug 7, 2025
27c026b
rework event loop paragraph to significantly deemphasize queues
anordin95 Aug 7, 2025
0527218
remove all references to queue besides the initial analogy.
anordin95 Aug 8, 2025
8adebdc
add note about garbage collection of tasks
anordin95 Aug 8, 2025
1422011
add practical note re: garbage collection
anordin95 Aug 8, 2025
a8fa7f6
phrasing nits
anordin95 Aug 8, 2025
9d3828d
re arrange note on task gc.
anordin95 Aug 8, 2025
ee5c4de
line wrap nit
anordin95 Aug 8, 2025
9f7d93f
Update Doc/howto/a-conceptual-overview-of-asyncio.rst
anordin95 Aug 8, 2025
a25b270
link to debug mode docs.
anordin95 Aug 8, 2025
7211ef2
readd part2 prefix.
anordin95 Aug 8, 2025
4f625b8
simplify title.
anordin95 Aug 8, 2025
673a9f9
fix titles. tihnk I messed this up earlier.
anordin95 Aug 8, 2025
270ee6e
avoid idiom in title.
anordin95 Aug 8, 2025
e025747
fix titles once agian.
anordin95 Aug 8, 2025
15aa0c5
Apply suggestions from code review
anordin95 Aug 8, 2025
5b3b697
rework task gc example.
anordin95 Aug 8, 2025
585521e
phrasing tweak.
anordin95 Aug 8, 2025
6530adc
tewak.
anordin95 Aug 8, 2025
ac87e24
nit
anordin95 Aug 8, 2025
7e48175
nit
anordin95 Aug 8, 2025
f881bfd
nit
anordin95 Aug 8, 2025
2227e4b
nit
anordin95 Aug 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
- Use :linenos: instead of manually writing the line numbers.
  • Loading branch information
anordin95 committed Aug 2, 2025
commit 0b795a23d82fe58595a4a2c87a3b376f2c6fa6eb
59 changes: 30 additions & 29 deletions Doc/howto/a-conceptual-overview-of-asyncio.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ approach rather useless.
::

import asyncio

# This creates an event loop and indefinitely cycles through
# its queue of tasks.
event_loop = asyncio.new_event_loop()
Expand Down Expand Up @@ -277,32 +277,33 @@ and executes the remaining statements in its body.
When a coroutine finishes, it raises a :exc:`StopIteration` exception with the
return value attached in the :attr:`~StopIteration.value` attribute.

::
.. code-block::
:linenos:

1 class Rock:
2 def __await__(self):
3 value_sent_in = yield 7
4 print(f"Rock.__await__ resuming with value: {value_sent_in}.")
5 return value_sent_in
6
7 async def main():
8 print("Beginning coroutine main().")
9 rock = Rock()
10 print("Awaiting rock...")
11 value_from_rock = await rock
12 print(f"Coroutine received value: {value_from_rock} from rock.")
13 return 23
14
15 coroutine = main()
16 intermediate_result = coroutine.send(None)
17 print(f"Coroutine paused and returned intermediate value: {intermediate_result}.")
18
19 print(f"Resuming coroutine and sending in value: 42.")
20 try:
21 coroutine.send(42)
22 except StopIteration as e:
23 returned_value = e.value
24 print(f"Coroutine main() finished and provided value: {returned_value}.")
class Rock:
def __await__(self):
value_sent_in = yield 7
print(f"Rock.__await__ resuming with value: {value_sent_in}.")
return value_sent_in

async def main():
print("Beginning coroutine main().")
rock = Rock()
print("Awaiting rock...")
value_from_rock = await rock
print(f"Coroutine received value: {value_from_rock} from rock.")
return 23

coroutine = main()
intermediate_result = coroutine.send(None)
print(f"Coroutine paused and returned intermediate value: {intermediate_result}.")

print(f"Resuming coroutine and sending in value: 42.")
try:
coroutine.send(42)
except StopIteration as e:
returned_value = e.value
print(f"Coroutine main() finished and provided value: {returned_value}.")

That snippet produces this output:

Expand Down Expand Up @@ -378,8 +379,8 @@ preventing other tasks from running.
::

async def other_work():
print(f"I am worker. Work work.")
print("I am worker. Work work.")

async def main():
# Add a few other tasks to the event loop, so there's something
# to do while asynchronously sleeping.
Expand Down Expand Up @@ -444,7 +445,7 @@ Note this is also of true of ``asyncio.sleep``.
class YieldToEventLoop:
def __await__(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bare yield is used internally by asyncio to implement asyncio.sleep(0) and is special cased, I don't think this is a good example to document as it relies too much on implementation detail.

Copy link
Contributor Author

@anordin95 anordin95 Aug 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm. I don't think this is an implementation detail of asyncio. If we momentarily ignore asyncio completely, this (yielding from an __await__) is the only way to cede control from a Python coroutine. Could you say more about it being special cased?

Instead, I think asyncio.sleep(0), this example and any other async library likely use this same fundamental pattern exposed by Python.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm. I don't think this is an implementation detail of asyncio.

Why? Is this documented somewhere?

Could you say more about it being special cased?

yielding None is special cased and is used for relinquishing control for one event loop iteration. You can see this in implementation of tasks.

Instead, I think asyncio.sleep(0), this example and any other async library likely use this same fundamental pattern exposed by Python.

No, asyncio libraries are built on top of futures and tasks and not objects implementing __await__ from scratch.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, asyncio libraries are built on top of futures and tasks and not objects implementing __await__ from scratch.

I think they mean alternatives to asyncio such as trio, not asyncio libraries. The point is to understand how asyncio actually works, rather than the bare minimum needed to build something on top of it. Understanding this point helps advanced users understand when (and why) code may or may not yield to the event loop.

Copy link
Contributor Author

@anordin95 anordin95 Aug 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? Is this documented somewhere?

yielding None is special cased and is used for relinquishing control for one event loop iteration. You can see this in implementation of tasks.

I'm not sure! I haven't checked the docs. And yes I imagine it is! But that's not really my point. asyncio happens to use yielding from an __await__ to cede control. But, that's also the only way to cede control from a coroutine. This is illustrated in the example earlier in the article which features no usage of asyncio nor an event loop.

And yes, exactly @Dreamsorcerer!

yield

async def _sleep_watcher(future: asyncio.Future, time_to_wake: float):
while True:
if time.time() >= time_to_wake:
Expand Down