1
1
from __future__ import annotations
2
2
3
+ import asyncio
4
+ import inspect
3
5
import shutil
4
6
import time
5
7
from functools import wraps
@@ -26,9 +28,7 @@ def clear_idom_web_modules_dir() -> None:
26
28
_RC = TypeVar ("_RC" , covariant = True )
27
29
28
30
29
- class _UntilFunc (Protocol [_RC ]):
30
- def __call__ (self , condition : Callable [[_RC ], bool ], timeout : float = ...) -> Any :
31
- ...
31
+ _DEFAULT_POLL_DELAY = 0.1
32
32
33
33
34
34
class poll (Generic [_R ]): # noqa: N801
@@ -40,64 +40,54 @@ def __init__(
40
40
* args : _P .args ,
41
41
** kwargs : _P .kwargs ,
42
42
) -> None :
43
- self .until : _UntilFunc [_R ]
44
- """Check that the coroutines result meets a condition within the timeout"""
43
+ coro : Callable [_P , Awaitable [_R ]]
44
+ if not inspect .iscoroutinefunction (function ):
45
+
46
+ async def coro (* args : _P .args , ** kwargs : _P .kwargs ) -> _R :
47
+ return cast (_R , function (* args , ** kwargs ))
45
48
46
- if iscoroutinefunction (function ):
47
- coro_function = cast (Callable [_P , Awaitable [_R ]], function )
48
-
49
- async def coro_until (
50
- condition : Callable [[_R ], bool ],
51
- timeout : float = IDOM_TESTING_DEFAULT_TIMEOUT .current ,
52
- ) -> None :
53
- started_at = time .time ()
54
- while True :
55
- result = await coro_function (* args , ** kwargs )
56
- if condition (result ):
57
- break
58
- elif (time .time () - started_at ) > timeout : # pragma: no cover
59
- raise TimeoutError (
60
- f"Condition not met within { timeout } "
61
- f"seconds - last value was { result !r} "
62
- )
63
-
64
- self .until = coro_until
65
49
else :
66
- sync_function = cast (Callable [_P , _R ], function )
67
-
68
- def sync_until (
69
- condition : Callable [[_R ], bool ] | Any ,
70
- timeout : float = IDOM_TESTING_DEFAULT_TIMEOUT .current ,
71
- ) -> None :
72
- started_at = time .time ()
73
- while True :
74
- result = sync_function (* args , ** kwargs )
75
- if condition (result ):
76
- break
77
- elif (time .time () - started_at ) > timeout : # pragma: no cover
78
- raise TimeoutError (
79
- f"Condition not met within { timeout } "
80
- f"seconds - last value was { result !r} "
81
- )
82
-
83
- self .until = sync_until
84
-
85
- def until_is (
50
+ coro = cast (Callable [_P , Awaitable [_R ]], function )
51
+ self ._func = coro
52
+ self ._args = args
53
+ self ._kwargs = kwargs
54
+
55
+ async def until (
86
56
self ,
87
- right : Any ,
57
+ condition : Callable [[ _R ], bool ] ,
88
58
timeout : float = IDOM_TESTING_DEFAULT_TIMEOUT .current ,
89
- ) -> Any :
59
+ delay : float = _DEFAULT_POLL_DELAY ,
60
+ ) -> None :
61
+ """Check that the coroutines result meets a condition within the timeout"""
62
+ started_at = time .time ()
63
+ while True :
64
+ await asyncio .sleep (delay )
65
+ result = await self ._func (* self ._args , ** self ._kwargs )
66
+ if condition (result ):
67
+ break
68
+ elif (time .time () - started_at ) > timeout : # pragma: no cover
69
+ raise TimeoutError (
70
+ f"Condition not met within { timeout } "
71
+ f"seconds - last value was { result !r} "
72
+ )
73
+
74
+ async def until_is (
75
+ self ,
76
+ right : _R ,
77
+ timeout : float = IDOM_TESTING_DEFAULT_TIMEOUT .current ,
78
+ delay : float = _DEFAULT_POLL_DELAY ,
79
+ ) -> None :
90
80
"""Wait until the result is identical to the given value"""
91
- return self .until (lambda left : left is right , timeout )
81
+ return await self .until (lambda left : left is right , timeout , delay )
92
82
93
- def until_equals (
83
+ async def until_equals (
94
84
self ,
95
- right : Any ,
85
+ right : _R ,
96
86
timeout : float = IDOM_TESTING_DEFAULT_TIMEOUT .current ,
97
- ) -> Any :
87
+ delay : float = _DEFAULT_POLL_DELAY ,
88
+ ) -> None :
98
89
"""Wait until the result is equal to the given value"""
99
- # not really sure why I need a type ignore comment here
100
- return self .until (lambda left : left == right , timeout ) # type: ignore
90
+ return await self .until (lambda left : left == right , timeout , delay )
101
91
102
92
103
93
class HookCatcher :
0 commit comments