Predict the output
Two requests set their own id concurrently. What's printed?
import asyncio
import contextvars
request_id = contextvars.ContextVar("request_id", default="-")
async def handle(rid: str, out: list[str]) -> None:
request_id.set(rid)
await asyncio.sleep(0)
out.append(f"{rid}:{request_id.get()}")
async def main() -> None:
out: list[str] = []
async with asyncio.TaskGroup() as tg:
tg.create_task(handle("r1", out))
tg.create_task(handle("r2", out))
print(sorted(out), request_id.get())
asyncio.run(main())Hint 1 of 1
Does each task get its own context?
Choose an answer, then open Show answer below to check it.
Show answer
Answer: A ['r1:r1', 'r2:r2'] -
Correct. Each task has its own copy; the main task never set one.
Each asyncio task starts with a copy of the current context, so a set() inside a task only changes that task's copy. The parent's context never changed, so it still has the default.
Why not the others?
- B
['r1:r2', 'r2:r2'] r2. That's what a shared global would do. - C
['r1:r1', 'r2:r2'] r2. Child tasks' sets don't leak to the parent. - D A LookupError. The variable has a default.