dycw-utilities 0.136.1__py3-none-any.whl → 0.136.3__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.136.1.dist-info → dycw_utilities-0.136.3.dist-info}/METADATA +1 -1
- {dycw_utilities-0.136.1.dist-info → dycw_utilities-0.136.3.dist-info}/RECORD +10 -10
- utilities/__init__.py +1 -1
- utilities/asyncio.py +17 -7
- utilities/functions.py +33 -1
- utilities/os.py +9 -0
- utilities/traceback.py +10 -18
- utilities/types.py +2 -0
- {dycw_utilities-0.136.1.dist-info → dycw_utilities-0.136.3.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.136.1.dist-info → dycw_utilities-0.136.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,8 +1,8 @@
|
|
1
|
-
utilities/__init__.py,sha256=
|
1
|
+
utilities/__init__.py,sha256=BmPyeyqP4do_46ks7_IMxZ-pOQGgO4-MnFQ9bw0zx_E,60
|
2
2
|
utilities/aiolimiter.py,sha256=mD0wEiqMgwpty4XTbawFpnkkmJS6R4JRsVXFUaoitSU,628
|
3
3
|
utilities/altair.py,sha256=HeZBVUocjkrTNwwKrClppsIqgNFF-ykv05HfZSoHYno,9104
|
4
4
|
utilities/arq.py,sha256=S-sfBfY-E1ErRKf4sSXt2YyCjKvu-pBlOECDfjBebRA,6399
|
5
|
-
utilities/asyncio.py,sha256=
|
5
|
+
utilities/asyncio.py,sha256=dcGeKQzjLBXxKzZkVIk5oZsFXEcynVbRB9iNB5XEDZk,38526
|
6
6
|
utilities/atomicwrites.py,sha256=geFjn9Pwn-tTrtoGjDDxWli9NqbYfy3gGL6ZBctiqSo,5393
|
7
7
|
utilities/atools.py,sha256=9im2g8OCf-Iynqa8bAv8N0Ycj9QvrJmGO7yLCZEdgII,986
|
8
8
|
utilities/cachetools.py,sha256=v1-9sXHLdOLiwmkq6NB0OUbxeKBuVVN6wmAWefWoaHI,2744
|
@@ -18,7 +18,7 @@ utilities/errors.py,sha256=nC7ZYtxxDBMfrTHtT_MByBfup_wfGQFRo3eDt-0ZPe8,1045
|
|
18
18
|
utilities/eventkit.py,sha256=cV76NIHKDPyrhnZRuhjCXse5CQqgRGXZ7p7Gon4Mu2g,12646
|
19
19
|
utilities/fastapi.py,sha256=E8T2J1-N_RbpkN4czthU6NPIxAZDzxy-k_WGJaxeJ48,2671
|
20
20
|
utilities/fpdf2.py,sha256=PmPj8ugr_SlxFEpw-9OsI8--mteLQ4MaXv_Cbmf7XXs,1852
|
21
|
-
utilities/functions.py,sha256=
|
21
|
+
utilities/functions.py,sha256=qefAfW0zz7OEiRuBtKF-3tI3NaufcwAULRIFv24gZ2Q,28533
|
22
22
|
utilities/functools.py,sha256=I00ru2gQPakZw2SHVeKIKXfTv741655s6HI0lUoE0D4,1552
|
23
23
|
utilities/getpass.py,sha256=DfN5UgMAtFCqS3dSfFHUfqIMZX2shXvwphOz_6J6f6A,103
|
24
24
|
utilities/git.py,sha256=oi7-_l5e9haSANSCvQw25ufYGoNahuUPHAZ6114s3JQ,1191
|
@@ -42,7 +42,7 @@ utilities/numpy.py,sha256=Xn23sA2ZbVNqwUYEgNJD3XBYH6IbCri_WkHSNhg3NkY,26122
|
|
42
42
|
utilities/operator.py,sha256=fZM2DBZdjtU8Lh9Z-eHC4ktNr0vO3JfX8hXgIYwdvBI,3826
|
43
43
|
utilities/optuna.py,sha256=C-fhWYiXHVPo1l8QctYkFJ4DyhbSrGorzP1dJb_qvd8,1933
|
44
44
|
utilities/orjson.py,sha256=y5ynSGhQjX7vikfvsHh_AklLnH7gjvsSkIC3h5tnx98,36474
|
45
|
-
utilities/os.py,sha256=
|
45
|
+
utilities/os.py,sha256=yMNAKMyY8oFgQ1yN3TQYnwa5-A_FXz4tCDbhIctQHSs,3736
|
46
46
|
utilities/parse.py,sha256=bCZW1bBfXM2j-yLGq0TGUshOnbL8V-U8amGu_OZTE_I,17907
|
47
47
|
utilities/pathlib.py,sha256=jCFPZm4rBKylEva9wDVTwQlTTVKMepu92WrTpoGa438,3248
|
48
48
|
utilities/period.py,sha256=QZsy2tCcoh0LGr70bkvlB5iWqEx6hdit3-iuaWJYXXc,4689
|
@@ -77,9 +77,9 @@ utilities/tempfile.py,sha256=VqmZJAhTJ1OaVywFzk5eqROV8iJbW9XQ_QYAV0bpdRo,1384
|
|
77
77
|
utilities/text.py,sha256=ymBFlP_cA8OgNnZRVNs7FAh7OG8HxE6YkiLEMZv5g_A,11297
|
78
78
|
utilities/threading.py,sha256=GvBOp4CyhHfN90wGXZuA2VKe9fGzMaEa7oCl4f3nnPU,1009
|
79
79
|
utilities/timer.py,sha256=oXfTii6ymu57niP0BDGZjFD55LEHi2a19kqZKiTgaFQ,2588
|
80
|
-
utilities/traceback.py,sha256=
|
80
|
+
utilities/traceback.py,sha256=YvNUQCTDLvrKYAsl5498a0zhfjJna0dEUvIaK7PmLlQ,8780
|
81
81
|
utilities/typed_settings.py,sha256=niNxgvVKrTy1c0j0D0Jp2tO3m231f4yJJ-38ni-xY3Q,3739
|
82
|
-
utilities/types.py,sha256=
|
82
|
+
utilities/types.py,sha256=98pwEfkBikg6UUrshNJZgc8l97FGBbi0twIsqVt-KNA,17247
|
83
83
|
utilities/typing.py,sha256=Z-_XDaWyT_6wIo3qfNK-hvRlzxP2Jxa9PgXzm5rDYRA,13790
|
84
84
|
utilities/tzdata.py,sha256=fgNVj66yUbCSI_-vrRVzSD3gtf-L_8IEJEPjP_Jel5Y,266
|
85
85
|
utilities/tzlocal.py,sha256=KyCXEgCTjqGFx-389JdTuhMRUaT06U1RCMdWoED-qro,728
|
@@ -89,7 +89,7 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
|
|
89
89
|
utilities/whenever.py,sha256=A-yoOqBqrcVD1yDINDsTFDw7dq9-zgUGn_f8CxVUQJs,23332
|
90
90
|
utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
|
91
91
|
utilities/zoneinfo.py,sha256=oEH-nL3t4h9uawyZqWDtNtDAl6M-CLpLYGI_nI6DulM,1971
|
92
|
-
dycw_utilities-0.136.
|
93
|
-
dycw_utilities-0.136.
|
94
|
-
dycw_utilities-0.136.
|
95
|
-
dycw_utilities-0.136.
|
92
|
+
dycw_utilities-0.136.3.dist-info/METADATA,sha256=Hi7aRq1msI4KXQLVrnun8CojINzZHpxfP26XxstkH7w,1637
|
93
|
+
dycw_utilities-0.136.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
94
|
+
dycw_utilities-0.136.3.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
|
95
|
+
dycw_utilities-0.136.3.dist-info/RECORD,,
|
utilities/__init__.py
CHANGED
utilities/asyncio.py
CHANGED
@@ -36,10 +36,10 @@ from typing_extensions import deprecated
|
|
36
36
|
|
37
37
|
from utilities.dataclasses import replace_non_sentinel
|
38
38
|
from utilities.errors import repr_error
|
39
|
-
from utilities.functions import ensure_int, ensure_not_none
|
39
|
+
from utilities.functions import ensure_int, ensure_not_none, to_bool
|
40
40
|
from utilities.random import SYSTEM_RANDOM
|
41
41
|
from utilities.sentinel import Sentinel, sentinel
|
42
|
-
from utilities.types import SupportsRichComparison
|
42
|
+
from utilities.types import MaybeCallableBool, SupportsRichComparison
|
43
43
|
from utilities.whenever import SECOND, get_now
|
44
44
|
|
45
45
|
if TYPE_CHECKING:
|
@@ -220,10 +220,11 @@ class EnhancedQueue[T](Queue[T]):
|
|
220
220
|
class EnhancedTaskGroup(TaskGroup):
|
221
221
|
"""Task group with enhanced features."""
|
222
222
|
|
223
|
+
_max_tasks: int | None
|
223
224
|
_semaphore: Semaphore | None
|
224
225
|
_timeout: TimeDelta | None
|
225
226
|
_error: MaybeType[BaseException]
|
226
|
-
_debug:
|
227
|
+
_debug: MaybeCallableBool
|
227
228
|
_stack: AsyncExitStack
|
228
229
|
_timeout_cm: _AsyncGeneratorContextManager[None] | None
|
229
230
|
|
@@ -234,10 +235,14 @@ class EnhancedTaskGroup(TaskGroup):
|
|
234
235
|
max_tasks: int | None = None,
|
235
236
|
timeout: TimeDelta | None = None,
|
236
237
|
error: MaybeType[BaseException] = TimeoutError,
|
237
|
-
debug:
|
238
|
+
debug: MaybeCallableBool = False,
|
238
239
|
) -> None:
|
239
240
|
super().__init__()
|
240
|
-
self.
|
241
|
+
self._max_tasks = max_tasks
|
242
|
+
if (max_tasks is None) or (max_tasks <= 0):
|
243
|
+
self._semaphore = None
|
244
|
+
else:
|
245
|
+
self._semaphore = Semaphore(max_tasks)
|
241
246
|
self._timeout = timeout
|
242
247
|
self._error = error
|
243
248
|
self._debug = debug
|
@@ -257,7 +262,7 @@ class EnhancedTaskGroup(TaskGroup):
|
|
257
262
|
tb: TracebackType | None,
|
258
263
|
) -> None:
|
259
264
|
_ = await self._stack.__aexit__(et, exc, tb)
|
260
|
-
match self.
|
265
|
+
match self._is_debug():
|
261
266
|
case True:
|
262
267
|
with suppress(Exception):
|
263
268
|
_ = await super().__aexit__(et, exc, tb)
|
@@ -293,7 +298,7 @@ class EnhancedTaskGroup(TaskGroup):
|
|
293
298
|
name: str | None = None,
|
294
299
|
context: Context | None = None,
|
295
300
|
) -> T | Task[T]:
|
296
|
-
match self.
|
301
|
+
match self._is_debug():
|
297
302
|
case True:
|
298
303
|
return await coro
|
299
304
|
case False:
|
@@ -301,6 +306,11 @@ class EnhancedTaskGroup(TaskGroup):
|
|
301
306
|
case _ as never:
|
302
307
|
assert_never(never)
|
303
308
|
|
309
|
+
def _is_debug(self) -> bool:
|
310
|
+
return to_bool(bool_=self._debug) or (
|
311
|
+
(self._max_tasks is not None) and (self._max_tasks <= 0)
|
312
|
+
)
|
313
|
+
|
304
314
|
async def _wrap_with_semaphore[T](
|
305
315
|
self, semaphore: Semaphore, coroutine: _CoroutineLike[T], /
|
306
316
|
) -> T:
|
utilities/functions.py
CHANGED
@@ -14,7 +14,16 @@ from types import (
|
|
14
14
|
MethodWrapperType,
|
15
15
|
WrapperDescriptorType,
|
16
16
|
)
|
17
|
-
from typing import
|
17
|
+
from typing import (
|
18
|
+
TYPE_CHECKING,
|
19
|
+
Any,
|
20
|
+
Literal,
|
21
|
+
TypeGuard,
|
22
|
+
assert_never,
|
23
|
+
cast,
|
24
|
+
overload,
|
25
|
+
override,
|
26
|
+
)
|
18
27
|
|
19
28
|
from whenever import Date, PlainDateTime, Time, TimeDelta, ZonedDateTime
|
20
29
|
|
@@ -22,6 +31,7 @@ from utilities.reprlib import get_repr, get_repr_and_class
|
|
22
31
|
from utilities.sentinel import Sentinel, sentinel
|
23
32
|
from utilities.types import (
|
24
33
|
Dataclass,
|
34
|
+
MaybeCallableBool,
|
25
35
|
Number,
|
26
36
|
StrMapping,
|
27
37
|
SupportsRichComparison,
|
@@ -935,6 +945,28 @@ def second[U](pair: tuple[Any, U], /) -> U:
|
|
935
945
|
##
|
936
946
|
|
937
947
|
|
948
|
+
@overload
|
949
|
+
def to_bool(*, bool_: MaybeCallableBool) -> bool: ...
|
950
|
+
@overload
|
951
|
+
def to_bool(*, bool_: None) -> None: ...
|
952
|
+
@overload
|
953
|
+
def to_bool(*, bool_: Sentinel) -> Sentinel: ...
|
954
|
+
def to_bool(
|
955
|
+
*, bool_: MaybeCallableBool | None | Sentinel = sentinel
|
956
|
+
) -> bool | None | Sentinel:
|
957
|
+
"""Get the bool."""
|
958
|
+
match bool_:
|
959
|
+
case bool() | None | Sentinel():
|
960
|
+
return bool_
|
961
|
+
case Callable() as func:
|
962
|
+
return to_bool(bool_=func())
|
963
|
+
case _ as never:
|
964
|
+
assert_never(never)
|
965
|
+
|
966
|
+
|
967
|
+
##
|
968
|
+
|
969
|
+
|
938
970
|
def yield_object_attributes(
|
939
971
|
obj: Any,
|
940
972
|
/,
|
utilities/os.py
CHANGED
@@ -123,6 +123,14 @@ class GetEnvVarError(Exception):
|
|
123
123
|
##
|
124
124
|
|
125
125
|
|
126
|
+
def is_debug() -> bool:
|
127
|
+
"""Check if we are in `DEBUG` mode."""
|
128
|
+
return get_env_var("DEBUG", nullable=True) is not None
|
129
|
+
|
130
|
+
|
131
|
+
##
|
132
|
+
|
133
|
+
|
126
134
|
@contextmanager
|
127
135
|
def temp_environ(
|
128
136
|
env: Mapping[str, str | None] | None = None, **env_kwargs: str | None
|
@@ -154,5 +162,6 @@ __all__ = [
|
|
154
162
|
"get_cpu_count",
|
155
163
|
"get_cpu_use",
|
156
164
|
"get_env_var",
|
165
|
+
"is_debug",
|
157
166
|
"temp_environ",
|
158
167
|
]
|
utilities/traceback.py
CHANGED
@@ -3,7 +3,6 @@ from __future__ import annotations
|
|
3
3
|
import re
|
4
4
|
import sys
|
5
5
|
from asyncio import run
|
6
|
-
from collections.abc import Callable
|
7
6
|
from dataclasses import dataclass
|
8
7
|
from functools import partial
|
9
8
|
from getpass import getuser
|
@@ -11,12 +10,12 @@ from itertools import repeat
|
|
11
10
|
from pathlib import Path
|
12
11
|
from socket import gethostname
|
13
12
|
from traceback import TracebackException
|
14
|
-
from typing import TYPE_CHECKING,
|
13
|
+
from typing import TYPE_CHECKING, override
|
15
14
|
|
16
15
|
from utilities.atomicwrites import writer
|
17
16
|
from utilities.errors import repr_error
|
17
|
+
from utilities.functions import to_bool
|
18
18
|
from utilities.iterables import OneEmptyError, one
|
19
|
-
from utilities.os import get_env_var
|
20
19
|
from utilities.pathlib import get_path
|
21
20
|
from utilities.reprlib import (
|
22
21
|
RICH_EXPAND_ALL,
|
@@ -31,11 +30,12 @@ from utilities.version import get_version
|
|
31
30
|
from utilities.whenever import format_compact, get_now, to_zoned_date_time
|
32
31
|
|
33
32
|
if TYPE_CHECKING:
|
34
|
-
from collections.abc import Iterator, Sequence
|
33
|
+
from collections.abc import Callable, Iterator, Sequence
|
35
34
|
from traceback import FrameSummary
|
36
35
|
from types import TracebackType
|
37
36
|
|
38
37
|
from utilities.types import (
|
38
|
+
MaybeCallableBool,
|
39
39
|
MaybeCallablePathLike,
|
40
40
|
MaybeCallableZonedDateTime,
|
41
41
|
PathLike,
|
@@ -203,7 +203,7 @@ def make_except_hook(
|
|
203
203
|
max_depth: int | None = RICH_MAX_DEPTH,
|
204
204
|
expand_all: bool = RICH_EXPAND_ALL,
|
205
205
|
slack_url: str | None = None,
|
206
|
-
pudb:
|
206
|
+
pudb: MaybeCallableBool = False,
|
207
207
|
) -> Callable[
|
208
208
|
[type[BaseException] | None, BaseException | None, TracebackType | None], None
|
209
209
|
]:
|
@@ -240,7 +240,7 @@ def _make_except_hook_inner(
|
|
240
240
|
max_depth: int | None = RICH_MAX_DEPTH,
|
241
241
|
expand_all: bool = RICH_EXPAND_ALL,
|
242
242
|
slack_url: str | None = None,
|
243
|
-
pudb:
|
243
|
+
pudb: MaybeCallableBool = False,
|
244
244
|
) -> None:
|
245
245
|
"""Exception hook to log the traceback."""
|
246
246
|
_ = (exc_type, traceback)
|
@@ -272,18 +272,10 @@ def _make_except_hook_inner(
|
|
272
272
|
|
273
273
|
send = f"```{slim}```"
|
274
274
|
run(send_to_slack(slack_url, send))
|
275
|
-
if pudb
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
case Callable() as func:
|
280
|
-
call_pudb = func()
|
281
|
-
case _ as never:
|
282
|
-
assert_never(never)
|
283
|
-
if call_pudb:
|
284
|
-
from pudb import post_mortem
|
285
|
-
|
286
|
-
post_mortem(tb=traceback, e_type=exc_type, e_value=exc_val)
|
275
|
+
if to_bool(bool_=pudb): # pragma: no cover
|
276
|
+
from pudb import post_mortem
|
277
|
+
|
278
|
+
post_mortem(tb=traceback, e_type=exc_type, e_value=exc_val)
|
287
279
|
|
288
280
|
|
289
281
|
@dataclass(kw_only=True, slots=True)
|
utilities/types.py
CHANGED
@@ -59,6 +59,7 @@ type OpenMode = Literal[
|
|
59
59
|
"a+b",
|
60
60
|
]
|
61
61
|
type MaybeCallable[T] = T | Callable[[], T]
|
62
|
+
type MaybeCallableBool = MaybeCallable[bool]
|
62
63
|
type MaybeStr[T] = T | str
|
63
64
|
type MaybeType[T] = T | type[T]
|
64
65
|
type StrMapping = Mapping[str, Any]
|
@@ -254,6 +255,7 @@ __all__ = [
|
|
254
255
|
"LoggerOrName",
|
255
256
|
"MathRoundMode",
|
256
257
|
"MaybeCallable",
|
258
|
+
"MaybeCallableBool",
|
257
259
|
"MaybeCallableDate",
|
258
260
|
"MaybeCallableEvent",
|
259
261
|
"MaybeCallablePathLike",
|
File without changes
|
File without changes
|