-
Notifications
You must be signed in to change notification settings - Fork 34.1k
gh-137026: Add an explainer guide for asyncio #137215
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
05b35b0
446534c
176096d
b745f88
0f2b8db
27d1dcd
3852bb1
8bf6d2c
397df8f
84aedf7
3d3e12c
a5fdd0e
b1aef5c
64a12b4
0fffd4b
bfd1212
c946563
3fc668c
ebfe542
3978837
0dd99eb
ff804fe
00a1a68
e982f9c
a033876
dbbc0ab
af9ba25
34f3335
dca3d38
db4ac35
bb8d018
5fdd4e9
fe3c732
1abe9a1
eadc0fb
1f7323d
99ac489
feb8634
49e9c65
daba131
c31f3c5
6756257
a730bd3
8fca2e3
776daeb
0b795a2
d10eeec
b2e90f3
9e07a36
d12b29f
86039b7
e5fafc4
1dc6e51
3c0b0a4
0f3931c
82a1967
9fa9fca
9ff73dc
be9629d
f7dbaa6
689d517
9da27dd
3c0c11c
671cc80
2a96782
def6157
a84827b
01710e2
b5f56f3
3344574
1ed21c0
b574f72
0fbd5b1
27785f3
a75b55b
53ac647
7b5ff84
a8030d6
b4d087a
9e5aaf6
55a268c
43c1c96
1f8f863
ef71d25
4796f85
1000ace
e649c07
d619868
52a90c0
08d4eec
1934aad
7a4eebe
a2fd17a
c944ff1
27c026b
0527218
8adebdc
1422011
a8fa7f6
9d3828d
ee5c4de
9f7d93f
a25b270
7211ef2
4f625b8
673a9f9
270ee6e
e025747
15aa0c5
5b3b697
585521e
6530adc
ac87e24
7e48175
f881bfd
2227e4b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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() | ||
|
|
@@ -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: | ||
|
|
||
|
|
@@ -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.") | ||
anordin95 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| async def main(): | ||
| # Add a few other tasks to the event loop, so there's something | ||
| # to do while asynchronously sleeping. | ||
|
|
@@ -444,7 +445,7 @@ Note this is also of true of ``asyncio.sleep``. | |
| class YieldToEventLoop: | ||
| def __await__(self): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm. I don't think this is an implementation detail of Instead, I think
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
No, asyncio libraries are built on top of futures and tasks and not objects implementing
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
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.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'm not sure! I haven't checked the docs. And yes I imagine it is! But that's not really my point. And yes, exactly @Dreamsorcerer! |
||
| yield | ||
|
|
||
| async def _sleep_watcher(future: asyncio.Future, time_to_wake: float): | ||
| while True: | ||
| if time.time() >= time_to_wake: | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.