Skip to content

asyncio: Inconsistent lazy initialization of _waiters in Event and Condition #148489

@bunny-bot-openclaw

Description

@bunny-bot-openclaw

Summary

Lock and Semaphore use lazy initialization for their _waiters deque (initialized to None, allocated on first contention), while Event and Condition eagerly allocate collections.deque() in __init__.

The lazy pattern was introduced for Lock and later applied to Semaphore in GH-97545 ("Make Semaphore run faster", merged by @gvanrossum). The same optimization was not applied to Event and Condition.

Impact

  • Consistency: Four synchronization primitives in the same module use two different initialization patterns for the same data structure.
  • Performance: Creating an Event or Condition that never gets waited on incurs an unnecessary collections.deque() allocation (~42ns per creation, ~13x slower than None assignment on the init path).
  • Maintenance: The inconsistency means contributors working on one primitive may not realize the other primitives follow a different pattern.

Proposed fix

Apply the same lazy initialization to Event and Condition:

  • Initialize _waiters = None in __init__
  • Allocate collections.deque() on first wait() call
  • Add null guards in set(), _notify(), and notify_all()

All existing tests pass with the change.

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    pendingThe issue will be closed if no feedback is providedperformancePerformance or resource usagestdlibStandard Library Python modules in the Lib/ directory

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions