-
-
Notifications
You must be signed in to change notification settings - Fork 34k
Description
Documentation
Problem
The asyncio conceptual overview documentation contains a misleading example that claims work tasks run "while asynchronously sleeping," but the actual execution shows they run before the sleep timer starts.
Location
- Page: https://docs.python.org/3/howto/a-conceptual-overview-of-asyncio.html
- Section: "Implementing a Custom Async Sleep Function"
- Source file:
Doc/howto/asyncio-conceptual.rst(approximate location)
Current Documentation Claims
The code comment states:
# Add a few other tasks to the event loop, so there's something
# to do while asynchronously sleeping.The text also says:
"We want that task to finish only after three seconds have elapsed, but without preventing other tasks from running."
This wording implies the work tasks run during the 3-second sleep period.
The Issue
The other_work() function contains no await statement:
async def other_work():
print("I like work. Work work.")Because of this, the work tasks:
- Run to completion immediately (no yield points)
- Finish in microseconds
- Complete before
async_sleep()even starts
Evidence
I added a debug print to verify when async_sleep() starts:
async def async_sleep(seconds: float):
future = asyncio.Future()
print("DEBUG: async_sleep starting") # Added this line
time_to_wake = time.time() + seconds
watcher_task = asyncio.create_task(_sleep_watcher(future, time_to_wake))
await futureOutput:
Beginning asynchronous sleep at time: 03:31:24.
I like work. Work work.
I like work. Work work.
I like work. Work work.
DEBUG: async_sleep starting ← Sleep starts AFTER all work completes
Done asynchronous sleep at time: 03:31:27.
This proves that:
- Work tasks complete first (FIFO queue order)
- The timer calculation (
time_to_wake = time.time() + seconds) happens after work finishes - Nothing runs "while" sleeping except the watcher's yield loop
Why This Is Misleading
This example confuses learners about:
- When async provides concurrency - This example shows no real concurrency benefit
- Task scheduling order - Tasks run FIFO from the backlog, not "during" other tasks
- The purpose of
await- Withoutawaitinother_work(), there's no yield point
Suggested Fixes
Option A: Fix the code to demonstrate real concurrency
async def other_work():
await asyncio.sleep(0.5) # Now it can pause and resume
print("I like work. Work work.")This would show:
- All tasks starting at ~0.0 seconds
- Work tasks printing at ~0.5 seconds (during the sleep)
- Sleep finishing at ~3.0 seconds
- Total time: 3 seconds (true concurrent execution)
Option B: Fix the documentation text
Change the comment to:
# Add a few other tasks to the event loop. These will run
# before async_sleep() starts, since they were scheduled first
# and contain no await statements to yield control.And clarify the explanation to say:
"These work tasks will execute before the sleep timer starts, demonstrating how the event loop processes its task queue in FIFO order."
Option C: Add both fixes
- Keep the current code as-is to demonstrate scheduling order
- Add a second example with
awaitinother_work()to demonstrate concurrency
Impact
This misleading example caused me (and likely many others) significant confusion when learning asyncio. A clearer example would help learners understand:
- The difference between task scheduling and task execution
- When async provides actual performance benefits
- How to write properly concurrent async code
Environment
- Python version: 3.x (issue exists in current documentation)
- Documentation version: Latest (as of February 2026)
Additional Context
I spent considerable time debugging this example trying to understand why the work tasks didn't overlap with the sleep period as the documentation suggested. Only by adding debug prints did I realize the execution order was different from what the docs implied.
Metadata
Metadata
Assignees
Labels
Projects
Status
Status