dycw-utilities 0.165.0__py3-none-any.whl → 0.165.2__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.165.0.dist-info → dycw_utilities-0.165.2.dist-info}/METADATA +1 -1
- {dycw_utilities-0.165.0.dist-info → dycw_utilities-0.165.2.dist-info}/RECORD +8 -8
- utilities/__init__.py +1 -1
- utilities/contextlib.py +3 -1
- utilities/typing.py +53 -10
- {dycw_utilities-0.165.0.dist-info → dycw_utilities-0.165.2.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.165.0.dist-info → dycw_utilities-0.165.2.dist-info}/entry_points.txt +0 -0
- {dycw_utilities-0.165.0.dist-info → dycw_utilities-0.165.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
utilities/__init__.py,sha256=
|
1
|
+
utilities/__init__.py,sha256=ZnsWqCnQBd7LRuMGzf7ent48hxqCg33kMckVmWtmXfo,60
|
2
2
|
utilities/aeventkit.py,sha256=ddoleSwW9zdc2tjX5Ge0pMKtYwV_JMxhHYOxnWX2AGM,12609
|
3
3
|
utilities/altair.py,sha256=92E2lCdyHY4Zb-vCw6rEJIsWdKipuu-Tu2ab1ufUfAk,9079
|
4
4
|
utilities/asyncio.py,sha256=PUedzQ5deqlSECQ33sam9cRzI9TnygHz3FdOqWJWPTM,15288
|
@@ -7,7 +7,7 @@ utilities/atools.py,sha256=6neeCcgXxK2dlsc0xp15Za7nSucbCgFtAJepGI_-WXU,2549
|
|
7
7
|
utilities/cachetools.py,sha256=v1-9sXHLdOLiwmkq6NB0OUbxeKBuVVN6wmAWefWoaHI,2744
|
8
8
|
utilities/click.py,sha256=N-6lnXPYwiiciEdiwQbIp0C9UqwpWpBPmA2jMl_lmGY,17471
|
9
9
|
utilities/concurrent.py,sha256=fHeW2SZ_TEMfFY0C8pyQI6aPlnecvx9x6SuUwBWj_JY,2853
|
10
|
-
utilities/contextlib.py,sha256=
|
10
|
+
utilities/contextlib.py,sha256=iP7R2tIm6ZsbfLD5ks6UKBYwj50e9gBI8AkpLN-chro,7476
|
11
11
|
utilities/contextvars.py,sha256=J8OhC7jqozAGYOCe2KUWysbPXNGe5JYz3HfaY_mIs08,883
|
12
12
|
utilities/cryptography.py,sha256=5PFrzsNUGHay91dFgYnDKwYprXxahrBqztmUqViRzBk,956
|
13
13
|
utilities/cvxpy.py,sha256=Rv1-fD-XYerosCavRF8Pohop2DBkU3AlFaGTfD8AEAA,13776
|
@@ -76,7 +76,7 @@ utilities/timer.py,sha256=oXfTii6ymu57niP0BDGZjFD55LEHi2a19kqZKiTgaFQ,2588
|
|
76
76
|
utilities/traceback.py,sha256=b1nSvlyrGmI1MyZLkkoLVET3DQBSGt9qqIlAAQbyjEw,9629
|
77
77
|
utilities/typed_settings.py,sha256=SFWqS3lAzV7IfNRwqFcTk0YynTcQ7BmrcW2mr_KUnos,4466
|
78
78
|
utilities/types.py,sha256=oeH-hEC3-67Eja4nLz-Nj9WvK6Z9-3T1zobO_XJpuVg,18735
|
79
|
-
utilities/typing.py,sha256=
|
79
|
+
utilities/typing.py,sha256=QYoCIc71e_u5W-kBeiNzrD-GXxpLtMOGc9PqgZjMXeE,25274
|
80
80
|
utilities/tzdata.py,sha256=fgNVj66yUbCSI_-vrRVzSD3gtf-L_8IEJEPjP_Jel5Y,266
|
81
81
|
utilities/tzlocal.py,sha256=KyCXEgCTjqGFx-389JdTuhMRUaT06U1RCMdWoED-qro,728
|
82
82
|
utilities/uuid.py,sha256=nQZs6tFX4mqtc2Ku3KqjloYCqwpTKeTj8eKwQwh3FQI,1572
|
@@ -88,8 +88,8 @@ utilities/zoneinfo.py,sha256=tdIScrTB2-B-LH0ukb1HUXKooLknOfJNwHk10MuMYvA,3619
|
|
88
88
|
utilities/pytest_plugins/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
|
89
89
|
utilities/pytest_plugins/pytest_randomly.py,sha256=B1qYVlExGOxTywq2r1SMi5o7btHLk2PNdY_b1p98dkE,409
|
90
90
|
utilities/pytest_plugins/pytest_regressions.py,sha256=9v8kAXDM2ycIXJBimoiF4EgrwbUvxTycFWJiGR_GHhM,1466
|
91
|
-
dycw_utilities-0.165.
|
92
|
-
dycw_utilities-0.165.
|
93
|
-
dycw_utilities-0.165.
|
94
|
-
dycw_utilities-0.165.
|
95
|
-
dycw_utilities-0.165.
|
91
|
+
dycw_utilities-0.165.2.dist-info/METADATA,sha256=jw-a2WMCwJGXlvhvV3CVjpssOr7e-1QUnw-3i4WuM2k,1696
|
92
|
+
dycw_utilities-0.165.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
93
|
+
dycw_utilities-0.165.2.dist-info/entry_points.txt,sha256=BOD_SoDxwsfJYOLxhrSXhHP_T7iw-HXI9f2WVkzYxvQ,135
|
94
|
+
dycw_utilities-0.165.2.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
|
95
|
+
dycw_utilities-0.165.2.dist-info/RECORD,,
|
utilities/__init__.py
CHANGED
utilities/contextlib.py
CHANGED
@@ -8,7 +8,7 @@ from contextlib import (
|
|
8
8
|
asynccontextmanager,
|
9
9
|
contextmanager,
|
10
10
|
)
|
11
|
-
from functools import partial
|
11
|
+
from functools import partial, wraps
|
12
12
|
from signal import SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM, getsignal, signal
|
13
13
|
from typing import TYPE_CHECKING, Any, assert_never, cast, overload
|
14
14
|
|
@@ -77,6 +77,7 @@ def enhanced_context_manager[**P, T_co](
|
|
77
77
|
make_gcm = contextmanager(func)
|
78
78
|
|
79
79
|
@contextmanager
|
80
|
+
@wraps(func)
|
80
81
|
def wrapped(*args: P.args, **kwargs: P.kwargs) -> Iterator[T_co]:
|
81
82
|
gcm = make_gcm(*args, **kwargs)
|
82
83
|
sigabrt0 = _swap_handler(SIGABRT, gcm) if sigabrt else None
|
@@ -159,6 +160,7 @@ def enhanced_async_context_manager[**P, T_co](
|
|
159
160
|
make_agcm = asynccontextmanager(func)
|
160
161
|
|
161
162
|
@asynccontextmanager
|
163
|
+
@wraps(func)
|
162
164
|
async def wrapped(*args: P.args, **kwargs: P.kwargs) -> AsyncIterator[T_co]:
|
163
165
|
agcm = make_agcm(*args, **kwargs)
|
164
166
|
sigabrt0 = _swap_handler(SIGABRT, agcm) if sigabrt else None
|
utilities/typing.py
CHANGED
@@ -6,12 +6,14 @@ from dataclasses import dataclass, is_dataclass
|
|
6
6
|
from functools import partial
|
7
7
|
from itertools import chain
|
8
8
|
from pathlib import Path
|
9
|
+
from re import search
|
9
10
|
from types import NoneType, UnionType
|
10
11
|
from typing import (
|
11
12
|
Any,
|
12
13
|
ForwardRef,
|
13
14
|
Literal,
|
14
15
|
NamedTuple,
|
16
|
+
NotRequired,
|
15
17
|
Optional, # pyright: ignore[reportDeprecated]
|
16
18
|
TypeAliasType,
|
17
19
|
TypeGuard,
|
@@ -56,6 +58,18 @@ def get_args(obj: Any, /, *, optional_drop_none: bool = False) -> tuple[Any, ...
|
|
56
58
|
##
|
57
59
|
|
58
60
|
|
61
|
+
def get_forward_ref_args(obj: Any, /) -> Mapping[str, str]:
|
62
|
+
"""Get the forward args."""
|
63
|
+
return {
|
64
|
+
k: v.__forward_arg__
|
65
|
+
for k, v in obj.__annotations__.items()
|
66
|
+
if isinstance(v, ForwardRef)
|
67
|
+
}
|
68
|
+
|
69
|
+
|
70
|
+
##
|
71
|
+
|
72
|
+
|
59
73
|
def get_literal_elements(obj: Any, /) -> list[Any]:
|
60
74
|
"""Get the elements of a literal annotation."""
|
61
75
|
return _get_literal_elements_inner(obj)
|
@@ -151,21 +165,20 @@ def get_type_hints(
|
|
151
165
|
globalns_use = globals() | ({} if globalns is None else dict(globalns))
|
152
166
|
localns_use = {} if localns is None else dict(localns)
|
153
167
|
result: dict[str, Any] = obj.__annotations__
|
154
|
-
result =
|
155
|
-
k: v.__forward_arg__ if isinstance(v, ForwardRef) else v
|
156
|
-
for k, v in result.items()
|
157
|
-
}
|
168
|
+
result = result | dict(get_forward_ref_args(obj))
|
158
169
|
try:
|
159
|
-
hints = _get_type_hints(
|
170
|
+
hints = _get_type_hints(
|
171
|
+
obj, globalns=globalns_use, localns=localns_use, include_extras=True
|
172
|
+
)
|
160
173
|
except NameError as error:
|
161
174
|
if warn_name_errors:
|
162
175
|
warn(f"Error getting type hints for {obj!r}; {error}", stacklevel=2)
|
163
176
|
else:
|
164
|
-
result
|
177
|
+
result = result | {
|
165
178
|
key: value
|
166
179
|
for key, value in hints.items()
|
167
180
|
if (key not in result) or isinstance(result[key], str)
|
168
|
-
}
|
181
|
+
}
|
169
182
|
return result
|
170
183
|
|
171
184
|
|
@@ -393,17 +406,21 @@ def _is_instance_typed_dict[T: _TypedDictMeta](
|
|
393
406
|
hints = get_type_hints(
|
394
407
|
type_, globalns=globalns, localns=localns, warn_name_errors=warn_name_errors
|
395
408
|
)
|
396
|
-
|
409
|
+
optional = {
|
410
|
+
k for k, v in type_.__annotations__.items() if is_not_required_annotation(v)
|
411
|
+
}
|
412
|
+
required = {k: v for k, v in hints.items() if k not in optional}
|
413
|
+
if not set(obj).issuperset(required):
|
397
414
|
return False
|
398
415
|
return all(
|
399
416
|
is_instance_gen(
|
400
417
|
obj[k],
|
401
|
-
|
418
|
+
required[k],
|
402
419
|
globalns=globalns,
|
403
420
|
localns=localns,
|
404
421
|
warn_name_errors=warn_name_errors,
|
405
422
|
)
|
406
|
-
for k in
|
423
|
+
for k in required
|
407
424
|
)
|
408
425
|
|
409
426
|
|
@@ -577,6 +594,30 @@ def _is_namedtuple_core(obj: Any, /) -> bool:
|
|
577
594
|
##
|
578
595
|
|
579
596
|
|
597
|
+
def is_not_required_annotation(obj: Any) -> bool:
|
598
|
+
"""Check if an annotation is not required."""
|
599
|
+
if is_not_required_type(obj):
|
600
|
+
return True
|
601
|
+
match obj:
|
602
|
+
case str() as text:
|
603
|
+
return bool(search("NotRequired", text))
|
604
|
+
case ForwardRef() as fr:
|
605
|
+
return is_not_required_annotation(fr.__forward_arg__)
|
606
|
+
case _:
|
607
|
+
return False
|
608
|
+
|
609
|
+
|
610
|
+
##
|
611
|
+
|
612
|
+
|
613
|
+
def is_not_required_type(obj: Any, /) -> bool:
|
614
|
+
"""Check if an object is a not-required type annotation."""
|
615
|
+
return (obj is NotRequired) or _is_annotation_of_type(obj, NotRequired)
|
616
|
+
|
617
|
+
|
618
|
+
##
|
619
|
+
|
620
|
+
|
580
621
|
def is_optional_type(obj: Any, /) -> bool:
|
581
622
|
"""Check if an object is an optional type annotation."""
|
582
623
|
is_optional = _is_annotation_of_type(obj, Optional) # pyright: ignore[reportDeprecated]
|
@@ -889,6 +930,8 @@ __all__ = [
|
|
889
930
|
"is_mapping_type",
|
890
931
|
"is_namedtuple_class",
|
891
932
|
"is_namedtuple_instance",
|
933
|
+
"is_not_required_annotation",
|
934
|
+
"is_not_required_type",
|
892
935
|
"is_optional_type",
|
893
936
|
"is_sequence_of",
|
894
937
|
"is_sequence_of_tuple_or_str_mapping",
|
File without changes
|
File without changes
|
File without changes
|