Registry / testing / waiting

waiting

JSON →
library1.5.0pypypi✓ verified 24d ago

The 'waiting' library provides a simple utility for busy-waiting, where the program pauses execution until a specified predicate function returns `True`. It supports various modes, including timeouts, custom sleep intervals, exponential backoff, and aggregation of multiple predicates (ANY/ALL). The current version is 1.5.0, released in August 2024, with a sporadic but recently updated release cadence.

pip install waiting
INSTALL
IMPORT
SIG · WAITING
W
waiting
testingpythonv1.5.0
Install
1.5s avg
Import
108ms
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.5.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.110s · 17.8MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.5s · import 0.106s · 18MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

wait
from waiting import wait
The primary function to wait for a predicate to become true.
TimeoutExpired
from waiting import wait, TimeoutExpired
Exception raised when a wait operation exceeds its specified timeout.
ANY
from waiting import wait, ANY
Used with 'wait' to pause until any of a list of predicates returns true.
ALL
from waiting import wait, ALL
Used with 'wait' to pause until all of a list of predicates return true.

This quickstart demonstrates the core `wait` function, showing how to wait for a predicate to become true, handling timeouts, and customizing polling intervals. It also highlights the benefit of the `waiting_for` argument for clearer error messages.

import time from waiting import wait, TimeoutExpired def check_condition(): # Simulate a condition that eventually becomes true if not hasattr(check_condition, 'counter'): check_condition.counter = 0 check_condition.counter += 1 print(f"Checking condition (attempt {check_condition.counter})...") return check_condition.counter >= 3 print("Starting to wait...") try: # Wait for the condition for a maximum of 5 seconds, polling every 0.5 seconds # Use 'waiting_for' for more descriptive timeout messages result = wait( check_condition, timeout_seconds=5, sleep_seconds=0.5, waiting_for="the counter to reach 3" ) print(f"Condition met! Result: {result}") except TimeoutExpired as e: print(f"Wait timed out: {e}") print("--- Demonstrating TimeoutExpired without waiting_for ---") try: wait(lambda: False, timeout_seconds=0.1) except TimeoutExpired as e: print(f"TimeoutExpired message (less descriptive): {e}")
Debug
Known issues
gotchaThe `wait` function is a blocking operation. In asynchronous Python applications (e.g., using `asyncio`), directly calling `wait` will block the entire event loop, potentially freezing your application.
fix
For asynchronous contexts, consider `asyncio.sleep()` or async-compatible polling libraries. If `waiting` must be used, run it in a separate thread or process to avoid blocking the main event loop.
affects: All versions
gotchaBy default, the `TimeoutExpired` exception provides a generic message. When dealing with complex waiting conditions, this can make debugging difficult.
fix
Always use the `waiting_for` argument in `wait()` calls to provide a descriptive message. This message will be included in the `TimeoutExpired` exception, greatly aiding debugging. Example: `wait(predicate, timeout_seconds=..., waiting_for="database to be ready")`.
affects: All versions
gotchaWhen using `ANY` or `ALL` with multiple predicates, the library's documentation notes that it does not call a predicate once it has been satisfied (for efficiency). If a predicate has side effects that are expected to occur on every poll, this behavior for `ANY`/`ALL` could be unexpected.
fix
Ensure that predicates used with `ANY` or `ALL` are idempotent or that their side effects are not critical to occur on every single poll once satisfied. For predicates requiring continuous side effects, wrap them in a single predicate or handle side effects outside the predicate function.
affects: All versions
Errors
Common errors & fixes
waiting.TimeoutExpired
The predicate function passed to `waiting.wait()` did not return `True` within the specified `timeout_seconds`.
fix
Increase the `timeout_seconds` parameter or debug the `predicate` function to ensure the condition is eventually met.
ImportError: cannot import name 'Wait' from 'waiting'
The main function for busy-waiting in the `waiting` library is named `wait` (lowercase), not `Wait` (capitalized).
fix
Use `from waiting import wait` to import the function directly, or `import waiting` and then call `waiting.wait()`.
AttributeError: module 'waiting' has no attribute 'until'
The `waiting` library uses a single top-level function `wait()` for its core functionality, unlike some other waiting libraries that might expose methods like `until()` on a wait object.
fix
Call the `waiting.wait()` function directly, passing your predicate and other parameters as arguments.
Upgrade
Version history
1.5.0latest on PyPI · released Aug 28, 2024
Audit
Dependencies

No dependency data recorded yet.

Agent activity
11 hits · last 30 days
node
8
Resources
waiting — pip install waiting · libregistry