dycw-utilities 0.120.0__py3-none-any.whl → 0.121.0__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.120.0.dist-info → dycw_utilities-0.121.0.dist-info}/METADATA +1 -1
- {dycw_utilities-0.120.0.dist-info → dycw_utilities-0.121.0.dist-info}/RECORD +7 -7
- utilities/__init__.py +1 -1
- utilities/asyncio.py +21 -13
- utilities/types.py +2 -0
- {dycw_utilities-0.120.0.dist-info → dycw_utilities-0.121.0.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.120.0.dist-info → dycw_utilities-0.121.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,7 +1,7 @@
|
|
1
|
-
utilities/__init__.py,sha256=
|
1
|
+
utilities/__init__.py,sha256=FKqdZTwX6QRMMK9ehPxm3uM8OyIJA4Mgay0d8pgY6Nw,60
|
2
2
|
utilities/altair.py,sha256=Gpja-flOo-Db0PIPJLJsgzAlXWoKUjPU1qY-DQ829ek,9156
|
3
3
|
utilities/astor.py,sha256=xuDUkjq0-b6fhtwjhbnebzbqQZAjMSHR1IIS5uOodVg,777
|
4
|
-
utilities/asyncio.py,sha256=
|
4
|
+
utilities/asyncio.py,sha256=gn8dxBsNzFfFzrNpImF731LAmgLwEQM3uiwKuUPlg08,18822
|
5
5
|
utilities/atomicwrites.py,sha256=geFjn9Pwn-tTrtoGjDDxWli9NqbYfy3gGL6ZBctiqSo,5393
|
6
6
|
utilities/atools.py,sha256=IYMuFSFGSKyuQmqD6v5IUtDlz8PPw0Sr87Cub_gRU3M,1168
|
7
7
|
utilities/cachetools.py,sha256=C1zqOg7BYz0IfQFK8e3qaDDgEZxDpo47F15RTfJM37Q,2910
|
@@ -78,7 +78,7 @@ utilities/text.py,sha256=Fo12N4aA7k2rnb4W4vH9iiDh88Q5_nvRssTkfNsvVM8,10965
|
|
78
78
|
utilities/threading.py,sha256=GvBOp4CyhHfN90wGXZuA2VKe9fGzMaEa7oCl4f3nnPU,1009
|
79
79
|
utilities/timer.py,sha256=Rkc49KSpHuC8s7vUxGO9DU55U9I6yDKnchsQqrUCVBs,4075
|
80
80
|
utilities/traceback.py,sha256=p9WATV-e4_5AW6SvyRBiU-MY8XnEFcKgrFNUoFzalXI,27521
|
81
|
-
utilities/types.py,sha256=
|
81
|
+
utilities/types.py,sha256=2f1DqTZTMRlpCPWPd9-rh_uwmRPv9UdBoi_Bfv7Ccmo,18374
|
82
82
|
utilities/typing.py,sha256=H6ysJkI830aRwLsMKz0SZIw4cpcsm7d6KhQOwr-SDh0,13817
|
83
83
|
utilities/tzdata.py,sha256=yCf70NICwAeazN3_JcXhWvRqCy06XJNQ42j7r6gw3HY,1217
|
84
84
|
utilities/tzlocal.py,sha256=3upDNFBvGh1l9njmLR2z2S6K6VxQSb7QizYGUbAH3JU,960
|
@@ -88,7 +88,7 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
|
|
88
88
|
utilities/whenever.py,sha256=jS31ZAY5OMxFxLja_Yo5Fidi87Pd-GoVZ7Vi_teqVDA,16743
|
89
89
|
utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
|
90
90
|
utilities/zoneinfo.py,sha256=-5j7IQ9nb7gR43rdgA7ms05im-XuqhAk9EJnQBXxCoQ,1874
|
91
|
-
dycw_utilities-0.
|
92
|
-
dycw_utilities-0.
|
93
|
-
dycw_utilities-0.
|
94
|
-
dycw_utilities-0.
|
91
|
+
dycw_utilities-0.121.0.dist-info/METADATA,sha256=YvumB9cX9CE9qNSb60yruXQ-NlHPyugeA91GzOJLPUM,12943
|
92
|
+
dycw_utilities-0.121.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
93
|
+
dycw_utilities-0.121.0.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
|
94
|
+
dycw_utilities-0.121.0.dist-info/RECORD,,
|
utilities/__init__.py
CHANGED
utilities/asyncio.py
CHANGED
@@ -26,7 +26,6 @@ from typing import (
|
|
26
26
|
TYPE_CHECKING,
|
27
27
|
Any,
|
28
28
|
Generic,
|
29
|
-
Literal,
|
30
29
|
NoReturn,
|
31
30
|
TextIO,
|
32
31
|
TypeVar,
|
@@ -49,6 +48,7 @@ from utilities.reprlib import get_repr
|
|
49
48
|
from utilities.sentinel import Sentinel, sentinel
|
50
49
|
from utilities.types import (
|
51
50
|
Coroutine1,
|
51
|
+
DurationOrEveryDuration,
|
52
52
|
MaybeCallableEvent,
|
53
53
|
MaybeType,
|
54
54
|
THashable,
|
@@ -121,17 +121,14 @@ class EnhancedTaskGroup(TaskGroup):
|
|
121
121
|
##
|
122
122
|
|
123
123
|
|
124
|
-
type _DurationOrEvery = Duration | tuple[Literal["every"], Duration]
|
125
|
-
|
126
|
-
|
127
124
|
@dataclass(kw_only=True, unsafe_hash=True)
|
128
125
|
class InfiniteLooper(ABC, Generic[THashable]):
|
129
126
|
"""An infinite loop which can throw exceptions by setting events."""
|
130
127
|
|
131
|
-
sleep_core:
|
132
|
-
sleep_restart:
|
128
|
+
sleep_core: DurationOrEveryDuration = SECOND
|
129
|
+
sleep_restart: DurationOrEveryDuration = MINUTE
|
133
130
|
logger: str | None = None
|
134
|
-
_events: Mapping[THashable, Event] = field(
|
131
|
+
_events: Mapping[THashable | None, Event] = field(
|
135
132
|
default_factory=dict, init=False, repr=False, hash=False
|
136
133
|
)
|
137
134
|
|
@@ -229,7 +226,7 @@ class InfiniteLooper(ABC, Generic[THashable]):
|
|
229
226
|
msgs.append(f"Sleeping {self._sleep_restart_desc}...")
|
230
227
|
getLogger(name=self.logger).error("\n".join(msgs))
|
231
228
|
|
232
|
-
def _raise_error(self, event: THashable, /) -> NoReturn:
|
229
|
+
def _raise_error(self, event: THashable | None, /) -> NoReturn:
|
233
230
|
"""Raise the error corresponding to given event."""
|
234
231
|
mapping = dict(self._yield_events_and_exceptions())
|
235
232
|
error = mapping.get(event, InfiniteLooperError)
|
@@ -241,7 +238,7 @@ class InfiniteLooper(ABC, Generic[THashable]):
|
|
241
238
|
event: Event() for event, _ in self._yield_events_and_exceptions()
|
242
239
|
}
|
243
240
|
|
244
|
-
async def _run_sleep(self, sleep:
|
241
|
+
async def _run_sleep(self, sleep: DurationOrEveryDuration, /) -> None:
|
245
242
|
"""Sleep until the next part of the loop."""
|
246
243
|
match sleep:
|
247
244
|
case int() | float() | dt.timedelta() as duration:
|
@@ -264,12 +261,12 @@ class InfiniteLooper(ABC, Generic[THashable]):
|
|
264
261
|
case _ as never:
|
265
262
|
assert_never(never)
|
266
263
|
|
267
|
-
def _set_event(self, event: THashable
|
264
|
+
def _set_event(self, *, event: THashable | None = None) -> None:
|
268
265
|
"""Set the given event."""
|
269
266
|
try:
|
270
267
|
event_obj = self._events[event]
|
271
268
|
except KeyError:
|
272
|
-
raise
|
269
|
+
raise _InfiniteLooperNoSuchEventError(looper=self, event=event) from None
|
273
270
|
event_obj.set()
|
274
271
|
|
275
272
|
def _yield_coroutines(self) -> Iterator[Callable[[], Coroutine1[None]]]:
|
@@ -278,14 +275,18 @@ class InfiniteLooper(ABC, Generic[THashable]):
|
|
278
275
|
|
279
276
|
def _yield_events_and_exceptions(
|
280
277
|
self,
|
281
|
-
) -> Iterator[tuple[THashable, MaybeType[BaseException]]]:
|
278
|
+
) -> Iterator[tuple[THashable | None, MaybeType[BaseException]]]:
|
282
279
|
"""Yield the events & exceptions."""
|
283
|
-
yield
|
280
|
+
yield (None, _InfiniteLooperDefaultEventError)
|
284
281
|
|
285
282
|
|
286
283
|
@dataclass(kw_only=True, slots=True)
|
287
284
|
class InfiniteLooperError(Exception):
|
288
285
|
looper: InfiniteLooper[Any]
|
286
|
+
|
287
|
+
|
288
|
+
@dataclass(kw_only=True, slots=True)
|
289
|
+
class _InfiniteLooperNoSuchEventError(InfiniteLooperError):
|
289
290
|
event: Hashable
|
290
291
|
|
291
292
|
@override
|
@@ -293,6 +294,13 @@ class InfiniteLooperError(Exception):
|
|
293
294
|
return f"{get_class_name(self.looper)!r} does not have an event {self.event!r}"
|
294
295
|
|
295
296
|
|
297
|
+
@dataclass(kw_only=True, slots=True)
|
298
|
+
class _InfiniteLooperDefaultEventError(InfiniteLooperError):
|
299
|
+
@override
|
300
|
+
def __str__(self) -> str:
|
301
|
+
return f"{get_class_name(self.looper)!r} default event error"
|
302
|
+
|
303
|
+
|
296
304
|
##
|
297
305
|
|
298
306
|
|
utilities/types.py
CHANGED
@@ -92,6 +92,7 @@ type DateTimeLike = MaybeStr[dt.datetime]
|
|
92
92
|
type DateOrDateTime = dt.date | dt.datetime
|
93
93
|
type Duration = Number | dt.timedelta
|
94
94
|
type DurationLike = MaybeStr[Duration]
|
95
|
+
type DurationOrEveryDuration = Duration | tuple[Literal["every"], Duration]
|
95
96
|
type MaybeCallableDate = MaybeCallable[dt.date]
|
96
97
|
type MaybeCallableDateTime = MaybeCallable[dt.datetime]
|
97
98
|
type TimeLike = MaybeStr[dt.time]
|
@@ -270,6 +271,7 @@ __all__ = [
|
|
270
271
|
"DateTimeLike",
|
271
272
|
"Duration",
|
272
273
|
"DurationLike",
|
274
|
+
"DurationOrEveryDuration",
|
273
275
|
"EnumLike",
|
274
276
|
"ExcInfo",
|
275
277
|
"IterableHashable",
|
File without changes
|
File without changes
|