Documenting async functions outside of asyncio (original) (raw)
December 5, 2023, 11:41pm 1
Currently, async
functions and generators are documented entirely in the context of the asyncio
module, with no further explanation of how they work internally, or how they could be used in non-asyncio
code. However, digging through the relevant PEPs and Lib/asyncio/tasks.py
, I was surprised by how little magic is involved (essentially just a coroutine with a bare yield
to suspend the current chain of coroutines).
Would it make sense to add an example of non-asyncio
use of async
functions to the documentation, or are async
functions purposely considered the exclusive domain of asyncio
?
An example
Here is a simple example that I used to try and understand how async
functions work. I am not proposing to add this to the documentation, as I am sure more instructive examples can be found.
import types
import collections
@types.coroutine
def suspend():
yield
async def produce(k):
for i in range(k):
yield i
await suspend()
async def consume(n, k):
async for i in produce(k):
print(f"coro{n}, consume {i}")
return n
queue = collections.deque()
queue.append(consume(1, 3))
queue.append(consume(2, 5))
while queue:
coro = queue.popleft()
try:
coro.send(None)
except StopIteration as exc:
result = exc.value
print(f"{result=}")
else:
queue.append(coro)
kknechtel (Karl Knechtel) December 6, 2023, 12:20am 2
I like the idea of having a separate guide for choosing asynchronous programming strategies (async
/await
keywords etc., asyncio
on top of that; but separately, select
, threading, multiprocessing…), and tutorials for each; then ideally the documentation for asyncio
itself would be freed from actually needing to explain any theory.