dycw-utilities 0.133.6__py3-none-any.whl → 0.134.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.133.6.dist-info → dycw_utilities-0.134.0.dist-info}/METADATA +1 -1
- {dycw_utilities-0.133.6.dist-info → dycw_utilities-0.134.0.dist-info}/RECORD +39 -39
- utilities/__init__.py +1 -1
- utilities/arq.py +13 -20
- utilities/asyncio.py +59 -74
- utilities/atools.py +10 -13
- utilities/cachetools.py +11 -17
- utilities/click.py +61 -55
- utilities/concurrent.py +7 -10
- utilities/dataclasses.py +69 -91
- utilities/enum.py +24 -21
- utilities/eventkit.py +34 -48
- utilities/functions.py +133 -168
- utilities/functools.py +14 -18
- utilities/hypothesis.py +34 -44
- utilities/iterables.py +165 -179
- utilities/luigi.py +3 -15
- utilities/memory_profiler.py +11 -15
- utilities/more_itertools.py +85 -94
- utilities/operator.py +5 -7
- utilities/optuna.py +6 -6
- utilities/pathlib.py +1 -0
- utilities/period.py +7 -9
- utilities/polars.py +5 -16
- utilities/pqdm.py +7 -8
- utilities/pydantic.py +2 -4
- utilities/pytest.py +14 -23
- utilities/python_dotenv.py +5 -9
- utilities/random.py +2 -3
- utilities/redis.py +163 -181
- utilities/slack_sdk.py +2 -2
- utilities/sqlalchemy.py +4 -14
- utilities/timer.py +6 -0
- utilities/typed_settings.py +7 -10
- utilities/types.py +10 -94
- utilities/typing.py +32 -43
- utilities/uuid.py +1 -0
- {dycw_utilities-0.133.6.dist-info → dycw_utilities-0.134.0.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.133.6.dist-info → dycw_utilities-0.134.0.dist-info}/licenses/LICENSE +0 -0
utilities/eventkit.py
CHANGED
@@ -3,16 +3,7 @@ from __future__ import annotations
|
|
3
3
|
from asyncio import iscoroutinefunction
|
4
4
|
from dataclasses import dataclass
|
5
5
|
from functools import wraps
|
6
|
-
from typing import
|
7
|
-
TYPE_CHECKING,
|
8
|
-
Any,
|
9
|
-
Generic,
|
10
|
-
Self,
|
11
|
-
TypeVar,
|
12
|
-
assert_never,
|
13
|
-
cast,
|
14
|
-
override,
|
15
|
-
)
|
6
|
+
from typing import TYPE_CHECKING, Any, Self, assert_never, cast, override
|
16
7
|
|
17
8
|
from eventkit import (
|
18
9
|
Constant,
|
@@ -39,32 +30,28 @@ from eventkit import (
|
|
39
30
|
from utilities.functions import apply_decorators
|
40
31
|
from utilities.iterables import always_iterable
|
41
32
|
from utilities.logging import get_logger
|
42
|
-
from utilities.types import TCallable, TCallableMaybeCoroutine1None, TypeLike
|
43
33
|
|
44
34
|
if TYPE_CHECKING:
|
45
35
|
from collections.abc import Callable
|
46
36
|
|
47
|
-
from utilities.types import
|
48
|
-
|
49
|
-
|
50
|
-
_TEvent = TypeVar("_TEvent", bound=Event)
|
37
|
+
from utilities.types import Coro, LoggerOrName, MaybeCoro, MaybeIterable, TypeLike
|
51
38
|
|
52
39
|
|
53
40
|
##
|
54
41
|
|
55
42
|
|
56
|
-
def add_listener(
|
57
|
-
event:
|
58
|
-
listener: Callable[...,
|
43
|
+
def add_listener[E: Event, F: Callable](
|
44
|
+
event: E,
|
45
|
+
listener: Callable[..., MaybeCoro[None]],
|
59
46
|
/,
|
60
47
|
*,
|
61
|
-
error: Callable[[Event, BaseException],
|
48
|
+
error: Callable[[Event, BaseException], MaybeCoro[None]] | None = None,
|
62
49
|
ignore: TypeLike[BaseException] | None = None,
|
63
50
|
logger: LoggerOrName | None = None,
|
64
|
-
decorators: MaybeIterable[Callable[[
|
65
|
-
done: Callable[...,
|
51
|
+
decorators: MaybeIterable[Callable[[F], F]] | None = None,
|
52
|
+
done: Callable[..., MaybeCoro[None]] | None = None,
|
66
53
|
keep_ref: bool = False,
|
67
|
-
) ->
|
54
|
+
) -> E:
|
68
55
|
"""Connect a listener to an event."""
|
69
56
|
lifted = lift_listener(
|
70
57
|
listener,
|
@@ -74,14 +61,14 @@ def add_listener(
|
|
74
61
|
logger=logger,
|
75
62
|
decorators=decorators,
|
76
63
|
)
|
77
|
-
return cast("
|
64
|
+
return cast("E", event.connect(lifted, done=done, keep_ref=keep_ref))
|
78
65
|
|
79
66
|
|
80
67
|
##
|
81
68
|
|
82
69
|
|
83
70
|
@dataclass(repr=False, kw_only=True)
|
84
|
-
class LiftedEvent
|
71
|
+
class LiftedEvent[F: Callable[..., MaybeCoro[None]]]:
|
85
72
|
"""A lifted version of `Event`."""
|
86
73
|
|
87
74
|
event: Event
|
@@ -98,16 +85,16 @@ class LiftedEvent(Generic[TCallableMaybeCoroutine1None]):
|
|
98
85
|
def value(self) -> Any:
|
99
86
|
return self.event.value() # pragma: no cover
|
100
87
|
|
101
|
-
def connect(
|
88
|
+
def connect[F2: Callable](
|
102
89
|
self,
|
103
|
-
listener:
|
90
|
+
listener: F,
|
104
91
|
/,
|
105
92
|
*,
|
106
|
-
error: Callable[[Event, BaseException],
|
93
|
+
error: Callable[[Event, BaseException], MaybeCoro[None]] | None = None,
|
107
94
|
ignore: TypeLike[BaseException] | None = None,
|
108
95
|
logger: LoggerOrName | None = None,
|
109
|
-
decorators: MaybeIterable[Callable[[
|
110
|
-
done: Callable[...,
|
96
|
+
decorators: MaybeIterable[Callable[[F2], F2]] | None = None,
|
97
|
+
done: Callable[..., MaybeCoro[None]] | None = None,
|
111
98
|
keep_ref: bool = False,
|
112
99
|
) -> Event:
|
113
100
|
return add_listener(
|
@@ -256,26 +243,26 @@ class LiftedEvent(Generic[TCallableMaybeCoroutine1None]):
|
|
256
243
|
##
|
257
244
|
|
258
245
|
|
259
|
-
class TypedEvent
|
246
|
+
class TypedEvent[F: Callable[..., MaybeCoro[None]]](Event):
|
260
247
|
"""A typed version of `Event`."""
|
261
248
|
|
262
249
|
@override
|
263
|
-
def connect(
|
250
|
+
def connect[F2: Callable](
|
264
251
|
self,
|
265
|
-
listener:
|
266
|
-
error: Callable[[Self, BaseException],
|
267
|
-
done: Callable[[Self],
|
252
|
+
listener: F,
|
253
|
+
error: Callable[[Self, BaseException], MaybeCoro[None]] | None = None,
|
254
|
+
done: Callable[[Self], MaybeCoro[None]] | None = None,
|
268
255
|
keep_ref: bool = False,
|
269
256
|
*,
|
270
257
|
ignore: TypeLike[BaseException] | None = None,
|
271
258
|
logger: LoggerOrName | None = None,
|
272
|
-
decorators: MaybeIterable[Callable[[
|
259
|
+
decorators: MaybeIterable[Callable[[F2], F2]] | None = None,
|
273
260
|
) -> Self:
|
274
261
|
lifted = lift_listener(
|
275
262
|
listener,
|
276
263
|
self,
|
277
264
|
error=cast(
|
278
|
-
"Callable[[Event, BaseException],
|
265
|
+
"Callable[[Event, BaseException], MaybeCoro[None]] | None", error
|
279
266
|
),
|
280
267
|
ignore=ignore,
|
281
268
|
logger=logger,
|
@@ -289,16 +276,16 @@ class TypedEvent(Event, Generic[TCallableMaybeCoroutine1None]):
|
|
289
276
|
##
|
290
277
|
|
291
278
|
|
292
|
-
def lift_listener(
|
293
|
-
listener:
|
279
|
+
def lift_listener[F1: Callable[..., MaybeCoro[None]], F2: Callable](
|
280
|
+
listener: F1,
|
294
281
|
event: Event,
|
295
282
|
/,
|
296
283
|
*,
|
297
|
-
error: Callable[[Event, BaseException],
|
284
|
+
error: Callable[[Event, BaseException], MaybeCoro[None]] | None = None,
|
298
285
|
ignore: TypeLike[BaseException] | None = None,
|
299
286
|
logger: LoggerOrName | None = None,
|
300
|
-
decorators: MaybeIterable[Callable[[
|
301
|
-
) ->
|
287
|
+
decorators: MaybeIterable[Callable[[F2], F2]] | None = None,
|
288
|
+
) -> F1:
|
302
289
|
match error, bool(iscoroutinefunction(listener)):
|
303
290
|
case None, False:
|
304
291
|
listener_typed = cast("Callable[..., None]", listener)
|
@@ -315,7 +302,7 @@ def lift_listener(
|
|
315
302
|
lifted = listener_no_error_sync
|
316
303
|
|
317
304
|
case None, True:
|
318
|
-
listener_typed = cast("Callable[...,
|
305
|
+
listener_typed = cast("Callable[..., Coro[None]]", listener)
|
319
306
|
|
320
307
|
@wraps(listener)
|
321
308
|
async def listener_no_error_async(*args: Any, **kwargs: Any) -> None:
|
@@ -346,11 +333,11 @@ def lift_listener(
|
|
346
333
|
case False, True:
|
347
334
|
listener_typed = cast("Callable[..., None]", listener)
|
348
335
|
error_typed = cast(
|
349
|
-
"Callable[[Event, Exception],
|
336
|
+
"Callable[[Event, Exception], Coro[None]]", error
|
350
337
|
)
|
351
338
|
raise LiftListenerError(listener=listener_typed, error=error_typed)
|
352
339
|
case True, _:
|
353
|
-
listener_typed = cast("Callable[...,
|
340
|
+
listener_typed = cast("Callable[..., Coro[None]]", listener)
|
354
341
|
|
355
342
|
@wraps(listener)
|
356
343
|
async def listener_have_error_async(
|
@@ -363,8 +350,7 @@ def lift_listener(
|
|
363
350
|
return None
|
364
351
|
if iscoroutinefunction(error):
|
365
352
|
error_typed = cast(
|
366
|
-
"Callable[[Event, Exception],
|
367
|
-
error,
|
353
|
+
"Callable[[Event, Exception], Coro[None]]", error
|
368
354
|
)
|
369
355
|
return await error_typed(event, exc)
|
370
356
|
error_typed = cast(
|
@@ -380,13 +366,13 @@ def lift_listener(
|
|
380
366
|
|
381
367
|
if decorators is not None:
|
382
368
|
lifted = apply_decorators(lifted, *always_iterable(decorators))
|
383
|
-
return lifted
|
369
|
+
return cast("F1", lifted)
|
384
370
|
|
385
371
|
|
386
372
|
@dataclass(kw_only=True, slots=True)
|
387
373
|
class LiftListenerError(Exception):
|
388
374
|
listener: Callable[..., None]
|
389
|
-
error: Callable[[Event, Exception],
|
375
|
+
error: Callable[[Event, Exception], Coro[None]]
|
390
376
|
|
391
377
|
@override
|
392
378
|
def __str__(self) -> str:
|