Skip to content

Commit aa260f2

Browse files
committed
fix(retry): Improve retry_until_extended function with better error messaging
- Add descriptive timeout message to WaitTimeout exception - Ensure consistent handling of timeout errors - Fix type hints for function return values
1 parent a438f2d commit aa260f2

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed
+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"""Extended retry functionality for libtmux."""
2+
3+
from __future__ import annotations
4+
5+
import logging
6+
import time
7+
import typing as t
8+
9+
from libtmux.exc import WaitTimeout
10+
from libtmux.test.constants import (
11+
RETRY_INTERVAL_SECONDS,
12+
RETRY_TIMEOUT_SECONDS,
13+
)
14+
15+
logger = logging.getLogger(__name__)
16+
17+
if t.TYPE_CHECKING:
18+
from collections.abc import Callable
19+
20+
21+
def retry_until_extended(
22+
fun: Callable[[], bool],
23+
seconds: float = RETRY_TIMEOUT_SECONDS,
24+
*,
25+
interval: float = RETRY_INTERVAL_SECONDS,
26+
raises: bool | None = True,
27+
) -> tuple[bool, Exception | None]:
28+
"""
29+
Retry a function until a condition meets or the specified time passes.
30+
31+
Extended version that returns both success state and exception.
32+
33+
Parameters
34+
----------
35+
fun : callable
36+
A function that will be called repeatedly until it returns ``True`` or
37+
the specified time passes.
38+
seconds : float
39+
Seconds to retry. Defaults to ``8``, which is configurable via
40+
``RETRY_TIMEOUT_SECONDS`` environment variables.
41+
interval : float
42+
Time in seconds to wait between calls. Defaults to ``0.05`` and is
43+
configurable via ``RETRY_INTERVAL_SECONDS`` environment variable.
44+
raises : bool
45+
Whether or not to raise an exception on timeout. Defaults to ``True``.
46+
47+
Returns
48+
-------
49+
tuple[bool, Exception | None]
50+
Tuple containing (success, exception). If successful, the exception will
51+
be None.
52+
"""
53+
ini = time.time()
54+
exception = None
55+
56+
while not fun():
57+
end = time.time()
58+
if end - ini >= seconds:
59+
timeout_msg = f"Timed out after {seconds} seconds"
60+
exception = WaitTimeout(timeout_msg)
61+
if raises:
62+
raise exception
63+
return False, exception
64+
time.sleep(interval)
65+
return True, None

0 commit comments

Comments
 (0)