This rule raises an issue when the sleep function is used in an asynchronous loop instead of an Event object.

Why is this an issue?

Asynchronous tasks often need to wait for a condition to change or an event to occur. A simple-looking but inefficient way to achieve this is by polling the condition within a loop, using sleep to pause between checks:

while not condition_is_met:
    await asyncio.sleep(0.1) # Noncompliant
# Condition is met, we can proceed

This busy-waiting approach is problematic in asynchronous code because it introduces increased latency. The task only notices the condition change after the sleep interval expires. If the condition becomes true just after the task starts sleeping, the reaction is delayed.

Instead of polling with sleep, use dedicated synchronization primitives like asyncio.Event, trio.Event or anyio.Event. Using an Event allows a task to efficiently pause (await event.wait()) until another part of the program signals the event (event.set()). The waiting task consumes almost no resources while paused and reacts immediately when the event is set.

How to fix it in Asyncio

Code examples

Noncompliant code example

import asyncio

SHARED_CONDITION = False

async def worker():
    while not SHARED_CONDITION: # Noncompliant
        await asyncio.sleep(0.01)
    print("Condition is now true")

asyncio.run(worker)

Compliant solution

import asyncio

SHARED_CONDITION = asyncio.Event()

async def worker():
    await SHARED_CONDITION.wait() # Compliant
    print("Condition is now true")

asyncio.run(worker)

How to fix it in Trio

Code examples

Noncompliant code example

import trio

SHARED_CONDITION = False

async def worker():
    while not SHARED_CONDITION: # Noncompliant
        await trio.sleep(0.01)
    print("Condition is now true")

trio.run(worker)

Compliant solution

import trio

SHARED_CONDITION = trio.Event()

async def worker():
    await SHARED_CONDITION.wait() # Compliant
    print("Condition is now true")

trio.run(worker)

How to fix it in AnyIO

Code examples

Noncompliant code example

import anyio

SHARED_CONDITION = False

async def worker():
    while not SHARED_CONDITION: # Noncompliant
        await anyio.sleep(0.01)
    print("Condition is now true")

anyio.run(worker)

Compliant solution

import anyio

SHARED_CONDITION = anyio.Event()

async def worker():
    await SHARED_CONDITION.wait() # Compliant
    print("Condition is now true")

anyio.run(worker)

Resources

Documentation