dycw-utilities 0.131.16__py3-none-any.whl → 0.131.18__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dycw_utilities-0.131.16.dist-info → dycw_utilities-0.131.18.dist-info}/METADATA +1 -1
- {dycw_utilities-0.131.16.dist-info → dycw_utilities-0.131.18.dist-info}/RECORD +18 -19
- utilities/__init__.py +1 -1
- utilities/asyncio.py +47 -60
- utilities/datetime.py +2 -279
- utilities/iterables.py +1 -30
- utilities/operator.py +21 -15
- utilities/orjson.py +67 -84
- utilities/parse.py +24 -53
- utilities/pottery.py +16 -19
- utilities/psutil.py +8 -7
- utilities/redis.py +108 -116
- utilities/slack_sdk.py +17 -18
- utilities/sqlalchemy.py +36 -30
- utilities/sqlalchemy_polars.py +12 -27
- utilities/whenever.py +2 -216
- utilities/tenacity.py +0 -145
- {dycw_utilities-0.131.16.dist-info → dycw_utilities-0.131.18.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.131.16.dist-info → dycw_utilities-0.131.18.dist-info}/licenses/LICENSE +0 -0
@@ -1,7 +1,7 @@
|
|
1
|
-
utilities/__init__.py,sha256=
|
1
|
+
utilities/__init__.py,sha256=653kI0IdCJCyIvZc8ekfN8j8dOnjrRtGJKRx9UDXVvM,61
|
2
2
|
utilities/aiolimiter.py,sha256=mD0wEiqMgwpty4XTbawFpnkkmJS6R4JRsVXFUaoitSU,628
|
3
3
|
utilities/altair.py,sha256=HeZBVUocjkrTNwwKrClppsIqgNFF-ykv05HfZSoHYno,9104
|
4
|
-
utilities/asyncio.py,sha256=
|
4
|
+
utilities/asyncio.py,sha256=mHnlSA4KPeDaBRts8Rn4sNA_4urodj7gQzs-_8Z-F7A,37587
|
5
5
|
utilities/atomicwrites.py,sha256=geFjn9Pwn-tTrtoGjDDxWli9NqbYfy3gGL6ZBctiqSo,5393
|
6
6
|
utilities/atools.py,sha256=-bFGIrwYMFR7xl39j02DZMsO_u5x5_Ph7bRlBUFVYyw,1048
|
7
7
|
utilities/cachetools.py,sha256=uBtEv4hD-TuCPX_cQy1lOpLF-QqfwnYGSf0o4Soqydc,2826
|
@@ -12,7 +12,7 @@ utilities/contextvars.py,sha256=RsSGGrbQqqZ67rOydnM7WWIsM2lIE31UHJLejnHJPWY,505
|
|
12
12
|
utilities/cryptography.py,sha256=_CiK_K6c_-uQuUhsUNjNjTL-nqxAh4_1zTfS11Xe120,972
|
13
13
|
utilities/cvxpy.py,sha256=Rv1-fD-XYerosCavRF8Pohop2DBkU3AlFaGTfD8AEAA,13776
|
14
14
|
utilities/dataclasses.py,sha256=iiC1wpGXWhaocIikzwBt8bbLWyImoUlOlcDZJGejaIg,33011
|
15
|
-
utilities/datetime.py,sha256=
|
15
|
+
utilities/datetime.py,sha256=bt9tgxHfjSbl0g5H7W2YSwNm-1HsbKjX5AsYcyEO1mU,30361
|
16
16
|
utilities/enum.py,sha256=HoRwVCWzsnH0vpO9ZEcAAIZLMv0Sn2vJxxA4sYMQgDs,5793
|
17
17
|
utilities/errors.py,sha256=nC7ZYtxxDBMfrTHtT_MByBfup_wfGQFRo3eDt-0ZPe8,1045
|
18
18
|
utilities/eventkit.py,sha256=6M5Xu1SzN-juk9PqBHwy5dS-ta7T0qA6SMpDsakOJ0E,13039
|
@@ -28,7 +28,7 @@ utilities/hypothesis.py,sha256=fcklSUIagoDZOTn8ITbkIU7BOZMV4g1Owj0khiz9yBY,43401
|
|
28
28
|
utilities/importlib.py,sha256=mV1xT_O_zt_GnZZ36tl3xOmMaN_3jErDWY54fX39F6Y,429
|
29
29
|
utilities/inflect.py,sha256=DbqB5Q9FbRGJ1NbvEiZBirRMxCxgrz91zy5jCO9ZIs0,347
|
30
30
|
utilities/ipython.py,sha256=V2oMYHvEKvlNBzxDXdLvKi48oUq2SclRg5xasjaXStw,763
|
31
|
-
utilities/iterables.py,sha256=
|
31
|
+
utilities/iterables.py,sha256=cuebB4ivKlZuKm8S3PQIfjavn9h-5mBGmvYq4FpSxFg,43812
|
32
32
|
utilities/jupyter.py,sha256=ft5JA7fBxXKzP-L9W8f2-wbF0QeYc_2uLQNFDVk4Z-M,2917
|
33
33
|
utilities/libcst.py,sha256=Jto5ppzRzsxn4AD32IS8n0lbgLYXwsVJB6EY8giNZyY,4974
|
34
34
|
utilities/lightweight_charts.py,sha256=JrkrAZMo6JID2Eoc9QCc05Y_pK4l2zsApIhmii1z2Ig,2764
|
@@ -39,20 +39,20 @@ utilities/memory_profiler.py,sha256=tf2C51P2lCujPGvRt2Rfc7VEw5LDXmVPCG3z_AvBmbU,
|
|
39
39
|
utilities/modules.py,sha256=iuvLluJya-hvl1Q25-Jk3dLgx2Es3ck4SjJiEkAlVTs,3195
|
40
40
|
utilities/more_itertools.py,sha256=tBbjjKx8_Uv_TCjxhPwrGfAx_jRHtvLIZqXVWAsjzqA,8842
|
41
41
|
utilities/numpy.py,sha256=Xn23sA2ZbVNqwUYEgNJD3XBYH6IbCri_WkHSNhg3NkY,26122
|
42
|
-
utilities/operator.py,sha256=
|
42
|
+
utilities/operator.py,sha256=DuiWdkmK0D-ddvFqOayDkazTQE1Ysvtl6-UiBN5gns8,3857
|
43
43
|
utilities/optuna.py,sha256=loyJGWTzljgdJaoLhP09PT8Jz6o_pwBOwehY33lHkhw,1923
|
44
|
-
utilities/orjson.py,sha256=
|
44
|
+
utilities/orjson.py,sha256=7CraMEtaJtKTDTTVS4fQU6PeuFcG0V8SGwD3sqZ8kSI,36475
|
45
45
|
utilities/os.py,sha256=D_FyyT-6TtqiN9KSS7c9g1fnUtgxmyMtzAjmYLkk46A,3587
|
46
|
-
utilities/parse.py,sha256=
|
46
|
+
utilities/parse.py,sha256=YE2VWYKDm9WYf5wcOWrOxVfM6UWvhkSxSkwdxRQNsA0,17633
|
47
47
|
utilities/pathlib.py,sha256=PK41rf1c9Wqv7h8f5R7H3_Lhq_gQZTUJD5tu3gMHVaU,3247
|
48
48
|
utilities/period.py,sha256=opqpBevBGSGXbA7NYfRJjtthi1JPxdMaZ7QV3xosnTc,4774
|
49
49
|
utilities/pickle.py,sha256=MBT2xZCsv0pH868IXLGKnlcqNx2IRVKYNpRcqiQQqxw,653
|
50
50
|
utilities/platform.py,sha256=48IOKx1IC6ZJXWG-b56ZQptITcNFhWRjELW72o2dGTA,2398
|
51
51
|
utilities/polars.py,sha256=QlmUpYTqHNkcLnWOQh1TW22W2QyLzvifCvBcbsqhpdE,63272
|
52
52
|
utilities/polars_ols.py,sha256=Uc9V5kvlWZ5cU93lKZ-cfAKdVFFw81tqwLW9PxtUvMs,5618
|
53
|
-
utilities/pottery.py,sha256
|
53
|
+
utilities/pottery.py,sha256=2w3YuoH1KmLaCVqkwSghHTOT8S4xiUskwRHSRqrUEQY,3430
|
54
54
|
utilities/pqdm.py,sha256=foRytQybmOQ05pjt5LF7ANyzrIa--4ScDE3T2wd31a4,3118
|
55
|
-
utilities/psutil.py,sha256=
|
55
|
+
utilities/psutil.py,sha256=ZkwBGfTqAv8hxCyJVVJFctIVQvxhYuB28re3mIPBodc,3761
|
56
56
|
utilities/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
57
57
|
utilities/pydantic.py,sha256=aP6OKowg2Md4rgQuQ5qTSF4bTbBuq7WtRb7zS3JSRGY,1841
|
58
58
|
utilities/pyinstrument.py,sha256=3MPNDbZW_1Aj1aA1_f-yqPStgmjIFxPwIafYq2dsaTs,853
|
@@ -62,20 +62,19 @@ utilities/pytest_regressions.py,sha256=YI55B7EtLjhz7zPJZ6NK9bWrxrKCKabWZJe1cwcbA
|
|
62
62
|
utilities/python_dotenv.py,sha256=edXsvHZhZnYeqfMfrsRRpj7_9eJI6uizh3xLx8Q9B3w,3228
|
63
63
|
utilities/random.py,sha256=lYdjgxB7GCfU_fwFVl5U-BIM_HV3q6_urL9byjrwDM8,4157
|
64
64
|
utilities/re.py,sha256=6qxeV0rQZaBDKWcB7apSBmxtg_XzoGY-EdegTkMn-ZY,4578
|
65
|
-
utilities/redis.py,sha256=
|
65
|
+
utilities/redis.py,sha256=oA70YoFnSaSqTBzMHrbHkkGIBWU69-97MQEwH_0iX3g,35762
|
66
66
|
utilities/reprlib.py,sha256=ssYTcBW-TeRh3fhCJv57sopTZHF5FrPyyUg9yp5XBlo,3953
|
67
67
|
utilities/scipy.py,sha256=wZJM7fEgBAkLSYYvSmsg5ac-QuwAI0BGqHVetw1_Hb0,947
|
68
68
|
utilities/sentinel.py,sha256=3jIwgpMekWgDAxPDA_hXMP2St43cPhciKN3LWiZ7kv0,1248
|
69
69
|
utilities/shelve.py,sha256=HZsMwK4tcIfg3sh0gApx4-yjQnrY4o3V3ZRimvRhoW0,738
|
70
|
-
utilities/slack_sdk.py,sha256=
|
70
|
+
utilities/slack_sdk.py,sha256=ZpPzV_oHpSJbontGo2_YVVjKH08PjLjsx5Me-nLy918,4246
|
71
71
|
utilities/socket.py,sha256=K77vfREvzoVTrpYKo6MZakol0EYu2q1sWJnnZqL0So0,118
|
72
|
-
utilities/sqlalchemy.py,sha256=
|
73
|
-
utilities/sqlalchemy_polars.py,sha256=
|
72
|
+
utilities/sqlalchemy.py,sha256=sTlxK-Is-XCj7srTRh3Nz68axzIdDYZWLQdTeXnOdkQ,38015
|
73
|
+
utilities/sqlalchemy_polars.py,sha256=bDiKqHxOWu0Dj4ZDuGcVgR7ulm7sB90iVNINAKaeaKc,14290
|
74
74
|
utilities/statsmodels.py,sha256=koyiBHvpMcSiBfh99wFUfSggLNx7cuAw3rwyfAhoKpQ,3410
|
75
75
|
utilities/streamlit.py,sha256=U9PJBaKP1IdSykKhPZhIzSPTZsmLsnwbEPZWzNhJPKk,2955
|
76
76
|
utilities/string.py,sha256=XmU-s04qIV_tODnKl2pQiwmHaxzgOqRKU-RyzdrfvSE,620
|
77
77
|
utilities/tempfile.py,sha256=VqmZJAhTJ1OaVywFzk5eqROV8iJbW9XQ_QYAV0bpdRo,1384
|
78
|
-
utilities/tenacity.py,sha256=1PUvODiBVgeqIh7G5TRt5WWMSqjLYkEqP53itT97WQc,4914
|
79
78
|
utilities/text.py,sha256=ymBFlP_cA8OgNnZRVNs7FAh7OG8HxE6YkiLEMZv5g_A,11297
|
80
79
|
utilities/threading.py,sha256=GvBOp4CyhHfN90wGXZuA2VKe9fGzMaEa7oCl4f3nnPU,1009
|
81
80
|
utilities/timer.py,sha256=VeSl3ot8-f4D1d3HjjSsgKvjxHJGXd_sW4KcTExOR64,2475
|
@@ -88,11 +87,11 @@ utilities/tzlocal.py,sha256=xbBBzVIUKMk8AkhuIp1qxGRNBioIa5I09dpeoBnIOOU,662
|
|
88
87
|
utilities/uuid.py,sha256=jJTFxz-CWgltqNuzmythB7iEQ-Q1mCwPevUfKthZT3c,611
|
89
88
|
utilities/version.py,sha256=ufhJMmI6KPs1-3wBI71aj5wCukd3sP_m11usLe88DNA,5117
|
90
89
|
utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
|
91
|
-
utilities/whenever.py,sha256=
|
90
|
+
utilities/whenever.py,sha256=tUNfGB_72YSCxbDKiQ7ulWtISC3AgVBrW1s3XlFPkuw,6883
|
92
91
|
utilities/whenever2.py,sha256=Jd_fEavXCWTdMj29L7j-HbeMvrl8e3Ah_nxcLEFAwOU,12026
|
93
92
|
utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
|
94
93
|
utilities/zoneinfo.py,sha256=gJPr9l7V8s3Y7TXpCGYEM1S81Rplb9e4MoV9Nvy2VU8,1852
|
95
|
-
dycw_utilities-0.131.
|
96
|
-
dycw_utilities-0.131.
|
97
|
-
dycw_utilities-0.131.
|
98
|
-
dycw_utilities-0.131.
|
94
|
+
dycw_utilities-0.131.18.dist-info/METADATA,sha256=nfjJB5vwmQGGegP4Ma-fxV0cKOE67JbPGxKLmZ0Rd78,1585
|
95
|
+
dycw_utilities-0.131.18.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
96
|
+
dycw_utilities-0.131.18.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
|
97
|
+
dycw_utilities-0.131.18.dist-info/RECORD,,
|
utilities/__init__.py
CHANGED
utilities/asyncio.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
+
import asyncio
|
3
4
|
from asyncio import (
|
4
5
|
Event,
|
5
6
|
Lock,
|
@@ -14,7 +15,6 @@ from asyncio import (
|
|
14
15
|
create_subprocess_shell,
|
15
16
|
create_task,
|
16
17
|
sleep,
|
17
|
-
timeout,
|
18
18
|
)
|
19
19
|
from collections.abc import Callable, Iterable, Iterator
|
20
20
|
from contextlib import (
|
@@ -43,28 +43,22 @@ from typing import (
|
|
43
43
|
)
|
44
44
|
|
45
45
|
from typing_extensions import deprecated
|
46
|
-
from whenever import TimeDelta
|
47
46
|
|
48
47
|
from utilities.dataclasses import replace_non_sentinel
|
49
|
-
from utilities.datetime import (
|
50
|
-
SECOND,
|
51
|
-
datetime_duration_to_float,
|
52
|
-
get_now,
|
53
|
-
round_datetime,
|
54
|
-
)
|
55
48
|
from utilities.errors import repr_error
|
56
49
|
from utilities.functions import ensure_int, ensure_not_none
|
57
50
|
from utilities.random import SYSTEM_RANDOM
|
58
51
|
from utilities.sentinel import Sentinel, sentinel
|
59
52
|
from utilities.types import (
|
53
|
+
DateTimeRoundUnit,
|
60
54
|
MaybeCallableEvent,
|
61
55
|
MaybeType,
|
62
56
|
THashable,
|
63
57
|
TSupportsRichComparison,
|
64
58
|
)
|
59
|
+
from utilities.whenever2 import SECOND, get_now
|
65
60
|
|
66
61
|
if TYPE_CHECKING:
|
67
|
-
import datetime as dt
|
68
62
|
from asyncio import _CoroutineLike
|
69
63
|
from asyncio.subprocess import Process
|
70
64
|
from collections import deque
|
@@ -73,7 +67,7 @@ if TYPE_CHECKING:
|
|
73
67
|
from random import Random
|
74
68
|
from types import TracebackType
|
75
69
|
|
76
|
-
from
|
70
|
+
from whenever import TimeDelta, ZonedDateTime
|
77
71
|
|
78
72
|
|
79
73
|
_T = TypeVar("_T")
|
@@ -244,7 +238,7 @@ class EnhancedTaskGroup(TaskGroup):
|
|
244
238
|
"""Task group with enhanced features."""
|
245
239
|
|
246
240
|
_semaphore: Semaphore | None
|
247
|
-
_timeout:
|
241
|
+
_timeout: TimeDelta | None
|
248
242
|
_error: MaybeType[BaseException]
|
249
243
|
_stack: AsyncExitStack
|
250
244
|
_timeout_cm: _AsyncGeneratorContextManager[None] | None
|
@@ -254,7 +248,7 @@ class EnhancedTaskGroup(TaskGroup):
|
|
254
248
|
self,
|
255
249
|
*,
|
256
250
|
max_tasks: int | None = None,
|
257
|
-
timeout:
|
251
|
+
timeout: TimeDelta | None = None,
|
258
252
|
error: MaybeType[BaseException] = TimeoutError,
|
259
253
|
) -> None:
|
260
254
|
super().__init__()
|
@@ -306,7 +300,7 @@ class EnhancedTaskGroup(TaskGroup):
|
|
306
300
|
return await coroutine
|
307
301
|
|
308
302
|
async def _wrap_with_timeout(self, coroutine: _CoroutineLike[_T], /) -> _T:
|
309
|
-
async with
|
303
|
+
async with timeout_td(self._timeout, error=self._error):
|
310
304
|
return await coroutine
|
311
305
|
|
312
306
|
|
@@ -331,15 +325,13 @@ class Looper(Generic[_T]):
|
|
331
325
|
"""A looper of a core coroutine, handling errors."""
|
332
326
|
|
333
327
|
auto_start: bool = field(default=False, repr=False)
|
334
|
-
freq:
|
335
|
-
backoff:
|
328
|
+
freq: TimeDelta = field(default=SECOND, repr=False)
|
329
|
+
backoff: TimeDelta = field(default=10 * SECOND, repr=False)
|
336
330
|
empty_upon_exit: bool = field(default=False, repr=False)
|
337
331
|
logger: str | None = field(default=None, repr=False)
|
338
|
-
timeout:
|
332
|
+
timeout: TimeDelta | None = field(default=None, repr=False)
|
339
333
|
# settings
|
340
|
-
_backoff: float = field(init=False, repr=False)
|
341
334
|
_debug: bool = field(default=False, repr=False)
|
342
|
-
_freq: float = field(init=False, repr=False)
|
343
335
|
# counts
|
344
336
|
_entries: int = field(default=0, init=False, repr=False)
|
345
337
|
_core_attempts: int = field(default=0, init=False, repr=False)
|
@@ -379,8 +371,6 @@ class Looper(Generic[_T]):
|
|
379
371
|
_task: Task[None] | None = field(default=None, init=False, repr=False, hash=False)
|
380
372
|
|
381
373
|
def __post_init__(self) -> None:
|
382
|
-
self._backoff = datetime_duration_to_float(self.backoff)
|
383
|
-
self._freq = datetime_duration_to_float(self.freq)
|
384
374
|
self._logger = getLogger(name=self.logger)
|
385
375
|
self._logger.setLevel(DEBUG)
|
386
376
|
|
@@ -448,7 +438,7 @@ class Looper(Generic[_T]):
|
|
448
438
|
|
449
439
|
async def _apply_back_off(self) -> None:
|
450
440
|
"""Apply a back off period."""
|
451
|
-
await
|
441
|
+
await sleep_td(self.backoff)
|
452
442
|
self._is_pending_back_off.clear()
|
453
443
|
|
454
444
|
async def core(self) -> None:
|
@@ -541,10 +531,10 @@ class Looper(Generic[_T]):
|
|
541
531
|
*,
|
542
532
|
auto_start: bool | Sentinel = sentinel,
|
543
533
|
empty_upon_exit: bool | Sentinel = sentinel,
|
544
|
-
freq:
|
545
|
-
backoff:
|
534
|
+
freq: TimeDelta | Sentinel = sentinel,
|
535
|
+
backoff: TimeDelta | Sentinel = sentinel,
|
546
536
|
logger: str | None | Sentinel = sentinel,
|
547
|
-
timeout:
|
537
|
+
timeout: TimeDelta | None | Sentinel = sentinel,
|
548
538
|
_debug: bool | Sentinel = sentinel,
|
549
539
|
**kwargs: Any,
|
550
540
|
) -> Self:
|
@@ -670,7 +660,7 @@ class Looper(Generic[_T]):
|
|
670
660
|
async def run_looper(self) -> None:
|
671
661
|
"""Run the looper."""
|
672
662
|
try:
|
673
|
-
async with
|
663
|
+
async with timeout_td(self.timeout):
|
674
664
|
while True:
|
675
665
|
if self._is_stopped.is_set():
|
676
666
|
_ = self._debug and self._logger.debug("%s: stopped", self)
|
@@ -705,7 +695,7 @@ class Looper(Generic[_T]):
|
|
705
695
|
else:
|
706
696
|
async with self._lock:
|
707
697
|
self._core_successes += 1
|
708
|
-
await
|
698
|
+
await sleep_td(self.freq)
|
709
699
|
except RuntimeError as error: # pragma: no cover
|
710
700
|
if error.args[0] == "generator didn't stop after athrow()":
|
711
701
|
return
|
@@ -718,7 +708,7 @@ class Looper(Generic[_T]):
|
|
718
708
|
while not self.empty():
|
719
709
|
await self.core()
|
720
710
|
if not self.empty():
|
721
|
-
await
|
711
|
+
await sleep_td(self.freq)
|
722
712
|
|
723
713
|
@property
|
724
714
|
def stats(self) -> _LooperStats:
|
@@ -962,47 +952,41 @@ def put_items_nowait(items: Iterable[_T], queue: Queue[_T], /) -> None:
|
|
962
952
|
##
|
963
953
|
|
964
954
|
|
965
|
-
async def
|
966
|
-
|
967
|
-
|
955
|
+
async def sleep_max(
|
956
|
+
sleep: TimeDelta | None = None, /, *, random: Random = SYSTEM_RANDOM
|
957
|
+
) -> None:
|
958
|
+
"""Sleep which accepts deltas."""
|
959
|
+
if sleep is None:
|
968
960
|
return
|
969
|
-
|
970
|
-
await sleep(duration.in_seconds())
|
971
|
-
else:
|
972
|
-
await sleep(datetime_duration_to_float(duration))
|
961
|
+
await asyncio.sleep(random.uniform(0.0, sleep.in_seconds()))
|
973
962
|
|
974
963
|
|
975
964
|
##
|
976
965
|
|
977
966
|
|
978
|
-
async def
|
979
|
-
*,
|
967
|
+
async def sleep_rounded(
|
968
|
+
*, unit: DateTimeRoundUnit = "second", increment: int = 1
|
980
969
|
) -> None:
|
981
|
-
"""Sleep
|
982
|
-
|
983
|
-
return
|
984
|
-
await sleep(random.uniform(0.0, datetime_duration_to_float(duration)))
|
970
|
+
"""Sleep until a rounded time."""
|
971
|
+
await sleep_until(get_now().round(unit, increment=increment, mode="ceil"))
|
985
972
|
|
986
973
|
|
987
974
|
##
|
988
975
|
|
989
976
|
|
990
|
-
async def
|
991
|
-
"""Sleep
|
992
|
-
|
977
|
+
async def sleep_td(delta: TimeDelta | None = None, /) -> None:
|
978
|
+
"""Sleep which accepts deltas."""
|
979
|
+
if delta is None:
|
980
|
+
return
|
981
|
+
await sleep(delta.in_seconds())
|
993
982
|
|
994
983
|
|
995
984
|
##
|
996
985
|
|
997
986
|
|
998
|
-
async def
|
999
|
-
|
1000
|
-
|
1001
|
-
"""Sleep until a rounded time; accepts durations."""
|
1002
|
-
datetime = round_datetime(
|
1003
|
-
get_now(), duration, mode="ceil", rel_tol=rel_tol, abs_tol=abs_tol
|
1004
|
-
)
|
1005
|
-
await sleep_until(datetime)
|
987
|
+
async def sleep_until(datetime: ZonedDateTime, /) -> None:
|
988
|
+
"""Sleep until a given time."""
|
989
|
+
await sleep_td(datetime - get_now())
|
1006
990
|
|
1007
991
|
|
1008
992
|
##
|
@@ -1059,13 +1043,16 @@ async def _stream_one(
|
|
1059
1043
|
|
1060
1044
|
|
1061
1045
|
@asynccontextmanager
|
1062
|
-
async def
|
1063
|
-
|
1046
|
+
async def timeout_td(
|
1047
|
+
timeout: TimeDelta | None = None,
|
1048
|
+
/,
|
1049
|
+
*,
|
1050
|
+
error: MaybeType[BaseException] = TimeoutError,
|
1064
1051
|
) -> AsyncIterator[None]:
|
1065
|
-
"""Timeout context manager which accepts
|
1066
|
-
|
1052
|
+
"""Timeout context manager which accepts deltas."""
|
1053
|
+
timeout_use = None if timeout is None else timeout.in_seconds()
|
1067
1054
|
try:
|
1068
|
-
async with timeout(
|
1055
|
+
async with asyncio.timeout(timeout_use):
|
1069
1056
|
yield
|
1070
1057
|
except TimeoutError:
|
1071
1058
|
raise error from None
|
@@ -1084,10 +1071,10 @@ __all__ = [
|
|
1084
1071
|
"get_items_nowait",
|
1085
1072
|
"put_items",
|
1086
1073
|
"put_items_nowait",
|
1087
|
-
"
|
1088
|
-
"
|
1074
|
+
"sleep_max",
|
1075
|
+
"sleep_rounded",
|
1076
|
+
"sleep_td",
|
1089
1077
|
"sleep_until",
|
1090
|
-
"sleep_until_rounded",
|
1091
1078
|
"stream_command",
|
1092
|
-
"
|
1079
|
+
"timeout_td",
|
1093
1080
|
]
|