dycw-utilities 0.133.7__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.7.dist-info → dycw_utilities-0.134.0.dist-info}/METADATA +1 -1
- {dycw_utilities-0.133.7.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 +31 -51
- 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.7.dist-info → dycw_utilities-0.134.0.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.133.7.dist-info → dycw_utilities-0.134.0.dist-info}/licenses/LICENSE +0 -0
utilities/slack_sdk.py
CHANGED
@@ -18,7 +18,7 @@ if TYPE_CHECKING:
|
|
18
18
|
from slack_sdk.webhook import WebhookResponse
|
19
19
|
from whenever import TimeDelta
|
20
20
|
|
21
|
-
from utilities.types import
|
21
|
+
from utilities.types import Coro
|
22
22
|
|
23
23
|
|
24
24
|
_TIMEOUT: TimeDelta = MINUTE
|
@@ -48,7 +48,7 @@ class SlackHandlerService(Handler, Looper[str]):
|
|
48
48
|
timeout: TimeDelta | None = None,
|
49
49
|
_debug: bool = False,
|
50
50
|
level: int = NOTSET,
|
51
|
-
sender: Callable[[str, str],
|
51
|
+
sender: Callable[[str, str], Coro[None]] = _send_adapter,
|
52
52
|
send_timeout: TimeDelta = SECOND,
|
53
53
|
) -> None:
|
54
54
|
Looper.__init__( # Looper first
|
utilities/sqlalchemy.py
CHANGED
@@ -18,16 +18,7 @@ from itertools import chain
|
|
18
18
|
from math import floor
|
19
19
|
from operator import ge, le
|
20
20
|
from re import search
|
21
|
-
from typing import
|
22
|
-
TYPE_CHECKING,
|
23
|
-
Any,
|
24
|
-
Literal,
|
25
|
-
TypeGuard,
|
26
|
-
TypeVar,
|
27
|
-
assert_never,
|
28
|
-
cast,
|
29
|
-
override,
|
30
|
-
)
|
21
|
+
from typing import TYPE_CHECKING, Any, Literal, TypeGuard, assert_never, cast, override
|
31
22
|
|
32
23
|
from sqlalchemy import (
|
33
24
|
URL,
|
@@ -96,7 +87,6 @@ from utilities.whenever import SECOND
|
|
96
87
|
if TYPE_CHECKING:
|
97
88
|
from whenever import TimeDelta
|
98
89
|
|
99
|
-
_T = TypeVar("_T")
|
100
90
|
type _EngineOrConnectionOrAsync = Engine | Connection | AsyncEngine | AsyncConnection
|
101
91
|
type Dialect = Literal["mssql", "mysql", "oracle", "postgresql", "sqlite"]
|
102
92
|
type ORMInstOrClass = DeclarativeBase | type[DeclarativeBase]
|
@@ -957,9 +947,9 @@ def _is_pair_of_tuple_or_str_mapping_and_table(
|
|
957
947
|
return _is_pair_with_predicate_and_table(obj, is_tuple_or_str_mapping)
|
958
948
|
|
959
949
|
|
960
|
-
def _is_pair_with_predicate_and_table(
|
961
|
-
obj: Any, predicate: Callable[[Any], TypeGuard[
|
962
|
-
) -> TypeGuard[tuple[
|
950
|
+
def _is_pair_with_predicate_and_table[T](
|
951
|
+
obj: Any, predicate: Callable[[Any], TypeGuard[T]], /
|
952
|
+
) -> TypeGuard[tuple[T, TableOrORMInstOrClass]]:
|
963
953
|
"""Check if an object is pair and a table."""
|
964
954
|
return (
|
965
955
|
isinstance(obj, tuple)
|
utilities/timer.py
CHANGED
utilities/typed_settings.py
CHANGED
@@ -4,7 +4,7 @@ from dataclasses import dataclass
|
|
4
4
|
from ipaddress import IPv4Address, IPv6Address
|
5
5
|
from pathlib import Path
|
6
6
|
from re import search
|
7
|
-
from typing import TYPE_CHECKING, Any,
|
7
|
+
from typing import TYPE_CHECKING, Any, override
|
8
8
|
|
9
9
|
import typed_settings
|
10
10
|
from typed_settings import EnvLoader, FileLoader, find
|
@@ -32,9 +32,6 @@ if TYPE_CHECKING:
|
|
32
32
|
from utilities.types import MaybeIterable, PathLike
|
33
33
|
|
34
34
|
|
35
|
-
_T = TypeVar("_T")
|
36
|
-
|
37
|
-
|
38
35
|
##
|
39
36
|
|
40
37
|
|
@@ -65,10 +62,10 @@ class ExtendedTSConverter(TSConverter):
|
|
65
62
|
self.scalar_converters |= extras
|
66
63
|
|
67
64
|
|
68
|
-
def _make_converter(
|
69
|
-
cls: type[
|
65
|
+
def _make_converter[T](
|
66
|
+
cls: type[T], parser: Callable[[str], T], /
|
70
67
|
) -> Callable[[Any, type[Any]], Any]:
|
71
|
-
def hook(value:
|
68
|
+
def hook(value: T | str, _: type[T] = cls, /) -> Any:
|
72
69
|
if not isinstance(value, (cls, str)): # pragma: no cover
|
73
70
|
msg = f"Invalid type {type(value).__name__!r}; expected '{cls.__name__}' or 'str'"
|
74
71
|
raise TypeError(msg)
|
@@ -84,8 +81,8 @@ def _make_converter(
|
|
84
81
|
_BASE_DIR: Path = Path()
|
85
82
|
|
86
83
|
|
87
|
-
def load_settings(
|
88
|
-
cls: type[
|
84
|
+
def load_settings[T](
|
85
|
+
cls: type[T],
|
89
86
|
app_name: str,
|
90
87
|
/,
|
91
88
|
*,
|
@@ -94,7 +91,7 @@ def load_settings(
|
|
94
91
|
loaders: MaybeIterable[Loader] | None = None,
|
95
92
|
processors: MaybeIterable[Processor] = (),
|
96
93
|
base_dir: Path = _BASE_DIR,
|
97
|
-
) ->
|
94
|
+
) -> T:
|
98
95
|
if not search(r"^[A-Za-z]+(?:_[A-Za-z]+)*$", app_name):
|
99
96
|
raise LoadSettingsError(appname=app_name)
|
100
97
|
filenames_use = list(always_iterable(filenames))
|
utilities/types.py
CHANGED
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
import datetime as dt
|
4
4
|
from asyncio import Event
|
5
|
-
from collections.abc import
|
5
|
+
from collections.abc import Callable, Coroutine, Hashable, Iterable, Mapping
|
6
6
|
from enum import Enum
|
7
7
|
from ipaddress import IPv4Address, IPv6Address
|
8
8
|
from logging import Logger
|
@@ -58,36 +58,19 @@ type OpenMode = Literal[
|
|
58
58
|
"x+b",
|
59
59
|
"a+b",
|
60
60
|
]
|
61
|
-
type MaybeCallable[
|
62
|
-
type MaybeStr[
|
63
|
-
type MaybeType[
|
61
|
+
type MaybeCallable[T] = T | Callable[[], T]
|
62
|
+
type MaybeStr[T] = T | str
|
63
|
+
type MaybeType[T] = T | type[T]
|
64
64
|
type StrMapping = Mapping[str, Any]
|
65
65
|
type StrStrMapping = Mapping[str, str]
|
66
|
-
type TypeLike[
|
66
|
+
type TypeLike[T] = type[T] | tuple[type[T], ...]
|
67
67
|
type TupleOrStrMapping = tuple[Any, ...] | StrMapping
|
68
68
|
|
69
69
|
|
70
70
|
# asyncio
|
71
|
-
type
|
72
|
-
type MaybeAwaitable[_T] = _T | Awaitable[_T]
|
71
|
+
type Coro[T] = Coroutine[Any, Any, T]
|
73
72
|
type MaybeCallableEvent = MaybeCallable[Event]
|
74
|
-
type
|
75
|
-
type CallableCoroutine1[_T] = Callable[..., Coroutine1[_T]]
|
76
|
-
|
77
|
-
|
78
|
-
# callable
|
79
|
-
TCallable = TypeVar("TCallable", bound=Callable[..., Any])
|
80
|
-
TCallable1 = TypeVar("TCallable1", bound=Callable[..., Any])
|
81
|
-
TCallable2 = TypeVar("TCallable2", bound=Callable[..., Any])
|
82
|
-
TCallableCoroutine1 = TypeVar(
|
83
|
-
"TCallableCoroutine1", bound=Callable[..., Coroutine1[Any]]
|
84
|
-
)
|
85
|
-
TCallableCoroutine1None = TypeVar(
|
86
|
-
"TCallableCoroutine1None", bound=Callable[..., Coroutine1[None]]
|
87
|
-
)
|
88
|
-
TCallableMaybeCoroutine1None = TypeVar(
|
89
|
-
"TCallableMaybeCoroutine1None", bound=Callable[..., MaybeCoroutine1[None]]
|
90
|
-
)
|
73
|
+
type MaybeCoro[T] = T | Coro[T]
|
91
74
|
|
92
75
|
|
93
76
|
# concurrent
|
@@ -102,22 +85,8 @@ class Dataclass(Protocol):
|
|
102
85
|
__dataclass_fields__: ClassVar[dict[str, Any]]
|
103
86
|
|
104
87
|
|
105
|
-
TDataclass = TypeVar("TDataclass", bound=Dataclass)
|
106
|
-
|
107
|
-
|
108
88
|
# enum
|
109
|
-
type EnumLike[
|
110
|
-
TEnum = TypeVar("TEnum", bound=Enum)
|
111
|
-
|
112
|
-
|
113
|
-
# exceptions
|
114
|
-
TBaseException = TypeVar("TBaseException", bound=BaseException)
|
115
|
-
|
116
|
-
|
117
|
-
# hashable
|
118
|
-
THashable = TypeVar("THashable", bound=Hashable)
|
119
|
-
THashable1 = TypeVar("THashable1", bound=Hashable)
|
120
|
-
THashable2 = TypeVar("THashable2", bound=Hashable)
|
89
|
+
type EnumLike[E: Enum] = MaybeStr[E]
|
121
90
|
|
122
91
|
|
123
92
|
# ipaddress
|
@@ -164,77 +133,47 @@ class SupportsAbs(Protocol[_T_co]):
|
|
164
133
|
def __abs__(self) -> _T_co: ... # pragma: no cover
|
165
134
|
|
166
135
|
|
167
|
-
TSupportsAbs = TypeVar("TSupportsAbs", bound=SupportsAbs)
|
168
|
-
|
169
|
-
|
170
136
|
@runtime_checkable
|
171
137
|
class SupportsAdd(Protocol[_T_contra, _T_co]):
|
172
138
|
def __add__(self, x: _T_contra, /) -> _T_co: ... # pragma: no cover
|
173
139
|
|
174
140
|
|
175
|
-
TSupportsAdd = TypeVar("TSupportsAdd", bound=SupportsAdd)
|
176
|
-
|
177
|
-
|
178
141
|
@runtime_checkable
|
179
142
|
class SupportsBytes(Protocol):
|
180
143
|
def __bytes__(self) -> bytes: ... # pragma: no cover
|
181
144
|
|
182
145
|
|
183
|
-
TSupportsBytes = TypeVar("TSupportsBytes", bound=SupportsBytes)
|
184
|
-
|
185
|
-
|
186
146
|
@runtime_checkable
|
187
147
|
class SupportsComplex(Protocol):
|
188
148
|
def __complex__(self) -> complex: ... # pragma: no cover
|
189
149
|
|
190
150
|
|
191
|
-
TSupportsComplex = TypeVar("TSupportsComplex", bound=SupportsComplex)
|
192
|
-
|
193
|
-
|
194
151
|
@runtime_checkable
|
195
152
|
class SupportsFloat(Protocol):
|
196
153
|
def __float__(self) -> float: ... # pragma: no cover
|
197
154
|
|
198
155
|
|
199
|
-
TSupportsFloat = TypeVar("TSupportsFloat", bound=SupportsFloat)
|
200
|
-
|
201
|
-
|
202
156
|
@runtime_checkable
|
203
157
|
class SupportsGT(Protocol[_T_contra]):
|
204
158
|
def __gt__(self, other: _T_contra, /) -> bool: ... # pragma: no cover
|
205
159
|
|
206
160
|
|
207
|
-
TSupportsGT = TypeVar("TSupportsGT", bound=SupportsGT)
|
208
|
-
|
209
|
-
|
210
161
|
@runtime_checkable
|
211
162
|
class SupportsIndex(Protocol):
|
212
163
|
def __index__(self) -> int: ... # pragma: no cover
|
213
164
|
|
214
165
|
|
215
|
-
TSupportsIndex = TypeVar("TSupportsIndex", bound=SupportsIndex)
|
216
|
-
|
217
|
-
|
218
166
|
@runtime_checkable
|
219
167
|
class SupportsInt(Protocol):
|
220
168
|
def __int__(self) -> int: ... # pragma: no cover
|
221
169
|
|
222
170
|
|
223
|
-
TSupportsInt = TypeVar("TSupportsInt", bound=SupportsInt)
|
224
|
-
|
225
|
-
|
226
171
|
@runtime_checkable
|
227
172
|
class SupportsLT(Protocol[_T_contra]):
|
228
173
|
def __lt__(self, other: _T_contra, /) -> bool: ... # pragma: no cover
|
229
174
|
|
230
175
|
|
231
|
-
TSupportsLT = TypeVar("TSupportsLT", bound=SupportsLT)
|
232
|
-
|
233
|
-
|
234
176
|
SupportsRichComparison = SupportsLT[Any] | SupportsGT[Any]
|
235
|
-
TSupportsRichComparison = TypeVar(
|
236
|
-
"TSupportsRichComparison", bound=SupportsRichComparison
|
237
|
-
)
|
238
177
|
|
239
178
|
|
240
179
|
@runtime_checkable
|
@@ -299,8 +238,7 @@ type TimeZoneLike = (
|
|
299
238
|
|
300
239
|
|
301
240
|
__all__ = [
|
302
|
-
"
|
303
|
-
"Coroutine1",
|
241
|
+
"Coro",
|
304
242
|
"Dataclass",
|
305
243
|
"DateDeltaLike",
|
306
244
|
"DateLike",
|
@@ -315,13 +253,12 @@ __all__ = [
|
|
315
253
|
"LogLevel",
|
316
254
|
"LoggerOrName",
|
317
255
|
"MathRoundMode",
|
318
|
-
"MaybeAwaitable",
|
319
256
|
"MaybeCallable",
|
320
257
|
"MaybeCallableDate",
|
321
258
|
"MaybeCallableEvent",
|
322
259
|
"MaybeCallablePathLike",
|
323
260
|
"MaybeCallableZonedDateTime",
|
324
|
-
"
|
261
|
+
"MaybeCoro",
|
325
262
|
"MaybeIterable",
|
326
263
|
"MaybeIterableHashable",
|
327
264
|
"MaybeStr",
|
@@ -350,27 +287,6 @@ __all__ = [
|
|
350
287
|
"SupportsLT",
|
351
288
|
"SupportsRichComparison",
|
352
289
|
"SupportsRound",
|
353
|
-
"TBaseException",
|
354
|
-
"TCallable",
|
355
|
-
"TCallable1",
|
356
|
-
"TCallable2",
|
357
|
-
"TCallableCoroutine1",
|
358
|
-
"TCallableCoroutine1None",
|
359
|
-
"TCallableMaybeCoroutine1None",
|
360
|
-
"TDataclass",
|
361
|
-
"TEnum",
|
362
|
-
"THashable",
|
363
|
-
"THashable1",
|
364
|
-
"THashable2",
|
365
|
-
"TSupportsAbs",
|
366
|
-
"TSupportsAdd",
|
367
|
-
"TSupportsBytes",
|
368
|
-
"TSupportsComplex",
|
369
|
-
"TSupportsGT",
|
370
|
-
"TSupportsIndex",
|
371
|
-
"TSupportsInt",
|
372
|
-
"TSupportsLT",
|
373
|
-
"TSupportsRichComparison",
|
374
290
|
"TimeDeltaLike",
|
375
291
|
"TimeLike",
|
376
292
|
"TimeZone",
|
utilities/typing.py
CHANGED
@@ -13,7 +13,6 @@ from typing import (
|
|
13
13
|
Optional, # pyright: ignore[reportDeprecated]
|
14
14
|
TypeAliasType,
|
15
15
|
TypeGuard,
|
16
|
-
TypeVar,
|
17
16
|
Union, # pyright: ignore[reportDeprecated]
|
18
17
|
get_origin,
|
19
18
|
overload,
|
@@ -38,16 +37,6 @@ from utilities.iterables import unique_everseen
|
|
38
37
|
from utilities.sentinel import Sentinel
|
39
38
|
from utilities.types import StrMapping
|
40
39
|
|
41
|
-
_T = TypeVar("_T")
|
42
|
-
_T1 = TypeVar("_T1")
|
43
|
-
_T2 = TypeVar("_T2")
|
44
|
-
_T3 = TypeVar("_T3")
|
45
|
-
_T4 = TypeVar("_T4")
|
46
|
-
_T5 = TypeVar("_T5")
|
47
|
-
|
48
|
-
|
49
|
-
##
|
50
|
-
|
51
40
|
|
52
41
|
def get_args(obj: Any, /, *, optional_drop_none: bool = False) -> tuple[Any, ...]:
|
53
42
|
"""Get the arguments of an annotation."""
|
@@ -223,23 +212,25 @@ def is_frozenset_type(obj: Any, /) -> bool:
|
|
223
212
|
|
224
213
|
|
225
214
|
@overload
|
226
|
-
def is_instance_gen(obj: Any, type_: type[
|
215
|
+
def is_instance_gen[T](obj: Any, type_: type[T], /) -> TypeGuard[T]: ...
|
227
216
|
@overload
|
228
|
-
def is_instance_gen(obj: Any, type_: tuple[
|
217
|
+
def is_instance_gen[T1](obj: Any, type_: tuple[T1], /) -> TypeGuard[T1]: ...
|
229
218
|
@overload
|
230
|
-
def is_instance_gen
|
219
|
+
def is_instance_gen[T1, T2](
|
220
|
+
obj: Any, type_: tuple[T1, T2], /
|
221
|
+
) -> TypeGuard[T1 | T2]: ...
|
231
222
|
@overload
|
232
|
-
def is_instance_gen(
|
233
|
-
obj: Any, type_: tuple[
|
234
|
-
) -> TypeGuard[
|
223
|
+
def is_instance_gen[T1, T2, T3](
|
224
|
+
obj: Any, type_: tuple[T1, T2, T3], /
|
225
|
+
) -> TypeGuard[T1 | T2 | T3]: ...
|
235
226
|
@overload
|
236
|
-
def is_instance_gen(
|
237
|
-
obj: Any, type_: tuple[
|
238
|
-
) -> TypeGuard[
|
227
|
+
def is_instance_gen[T1, T2, T3, T4](
|
228
|
+
obj: Any, type_: tuple[T1, T2, T3, T4], /
|
229
|
+
) -> TypeGuard[T1 | T2 | T3 | T4]: ...
|
239
230
|
@overload
|
240
|
-
def is_instance_gen(
|
241
|
-
obj: Any, type_: tuple[
|
242
|
-
) -> TypeGuard[
|
231
|
+
def is_instance_gen[T1, T2, T3, T4, T5](
|
232
|
+
obj: Any, type_: tuple[T1, T2, T3, T4, T5], /
|
233
|
+
) -> TypeGuard[T1 | T2 | T3 | T4 | T5]: ...
|
243
234
|
@overload
|
244
235
|
def is_instance_gen(obj: Any, type_: Any, /) -> bool: ...
|
245
236
|
def is_instance_gen(obj: Any, type_: Any, /) -> bool:
|
@@ -265,7 +256,7 @@ def is_instance_gen(obj: Any, type_: Any, /) -> bool:
|
|
265
256
|
raise IsInstanceGenError(obj=obj, type_=type_)
|
266
257
|
|
267
258
|
|
268
|
-
def _is_instance_gen_type(obj: Any, type_: type[
|
259
|
+
def _is_instance_gen_type[T](obj: Any, type_: type[T], /) -> TypeGuard[T]:
|
269
260
|
return (
|
270
261
|
isinstance(obj, type_)
|
271
262
|
and not (
|
@@ -368,29 +359,27 @@ def is_set_type(obj: Any, /) -> bool:
|
|
368
359
|
|
369
360
|
|
370
361
|
@overload
|
371
|
-
def is_subclass_gen(cls: type[Any], parent: type[
|
362
|
+
def is_subclass_gen[T](cls: type[Any], parent: type[T], /) -> TypeGuard[type[T]]: ...
|
372
363
|
@overload
|
373
|
-
def is_subclass_gen(
|
374
|
-
cls: type[Any], parent: tuple[type[
|
375
|
-
) -> TypeGuard[type[
|
364
|
+
def is_subclass_gen[T1](
|
365
|
+
cls: type[Any], parent: tuple[type[T1]], /
|
366
|
+
) -> TypeGuard[type[T1]]: ...
|
376
367
|
@overload
|
377
|
-
def is_subclass_gen(
|
378
|
-
cls: type[Any], parent: tuple[type[
|
379
|
-
) -> TypeGuard[type[
|
368
|
+
def is_subclass_gen[T1, T2](
|
369
|
+
cls: type[Any], parent: tuple[type[T1], type[T2]], /
|
370
|
+
) -> TypeGuard[type[T1 | T2]]: ...
|
380
371
|
@overload
|
381
|
-
def is_subclass_gen(
|
382
|
-
cls: type[Any], parent: tuple[type[
|
383
|
-
) -> TypeGuard[type[
|
372
|
+
def is_subclass_gen[T1, T2, T3](
|
373
|
+
cls: type[Any], parent: tuple[type[T1], type[T2], type[T3]], /
|
374
|
+
) -> TypeGuard[type[T1 | T2 | T3]]: ...
|
384
375
|
@overload
|
385
|
-
def is_subclass_gen(
|
386
|
-
cls: type[Any], parent: tuple[type[
|
387
|
-
) -> TypeGuard[type[
|
376
|
+
def is_subclass_gen[T1, T2, T3, T4](
|
377
|
+
cls: type[Any], parent: tuple[type[T1], type[T2], type[T3], type[T4]], /
|
378
|
+
) -> TypeGuard[type[T1 | T2 | T3 | T4]]: ...
|
388
379
|
@overload
|
389
|
-
def is_subclass_gen(
|
390
|
-
cls: type[Any],
|
391
|
-
|
392
|
-
/,
|
393
|
-
) -> TypeGuard[type[_T1 | _T2 | _T3 | _T4 | _T5]]: ...
|
380
|
+
def is_subclass_gen[T1, T2, T3, T4, T5](
|
381
|
+
cls: type[Any], parent: tuple[type[T1], type[T2], type[T3], type[T4], type[T5]], /
|
382
|
+
) -> TypeGuard[type[T1 | T2 | T3 | T4 | T5]]: ...
|
394
383
|
@overload
|
395
384
|
def is_subclass_gen(cls: Any, parent: Any, /) -> bool: ...
|
396
385
|
def is_subclass_gen(cls: Any, parent: Any, /) -> bool:
|
@@ -426,7 +415,7 @@ def is_subclass_gen(cls: Any, parent: Any, /) -> bool:
|
|
426
415
|
raise IsSubclassGenError(cls=cls)
|
427
416
|
|
428
417
|
|
429
|
-
def _is_subclass_gen_type(cls: type[Any], parent: type[
|
418
|
+
def _is_subclass_gen_type[T](cls: type[Any], parent: type[T], /) -> TypeGuard[type[T]]:
|
430
419
|
return (
|
431
420
|
issubclass(cls, parent)
|
432
421
|
and not (
|
utilities/uuid.py
CHANGED
File without changes
|
File without changes
|