Skip to content

Misleading example in asyncio conceptual overview: work tasks(work_tasks) don't run "while" sleeping #144597

@OptaNol

Description

@OptaNol

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

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:

  1. Run to completion immediately (no yield points)
  2. Finish in microseconds
  3. 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 future

Output:

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:

  1. When async provides concurrency - This example shows no real concurrency benefit
  2. Task scheduling order - Tasks run FIFO from the backlog, not "during" other tasks
  3. The purpose of await - Without await in other_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

  1. Keep the current code as-is to demonstrate scheduling order
  2. Add a second example with await in other_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

No one assigned

    Labels

    Projects

    Status

    Done

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions