dycw-utilities 0.135.1__py3-none-any.whl → 0.136.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.135.1
3
+ Version: 0.136.0
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -13,6 +13,7 @@ Requires-Dist: coloredlogs<15.1,>=15.0.1; extra == 'logging'
13
13
  Provides-Extra: test
14
14
  Requires-Dist: dycw-pytest-only<2.2,>=2.1.1; extra == 'test'
15
15
  Requires-Dist: hypothesis<6.136,>=6.135.2; extra == 'test'
16
+ Requires-Dist: pudb<2025.2,>=2025.1; extra == 'test'
16
17
  Requires-Dist: pytest-asyncio<1.1,>=1.0.0; extra == 'test'
17
18
  Requires-Dist: pytest-cov<6.2,>=6.1.1; extra == 'test'
18
19
  Requires-Dist: pytest-instafail<0.6,>=0.5.0; extra == 'test'
@@ -1,4 +1,4 @@
1
- utilities/__init__.py,sha256=fd7dlmu-Le53NgKruzJmKZxnXhzb2Q5mfIFs0t3mJlI,60
1
+ utilities/__init__.py,sha256=0ew7YXcLdtzxH-7q4GWgY3emjEZ_c9LZ173C_Q0J4xI,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
@@ -53,7 +53,6 @@ utilities/polars_ols.py,sha256=Uc9V5kvlWZ5cU93lKZ-cfAKdVFFw81tqwLW9PxtUvMs,5618
53
53
  utilities/pottery.py,sha256=RN3XwOEsVAPXvEfsRPmn3ZSKgTzK_c182PNrtksq-bg,3429
54
54
  utilities/pqdm.py,sha256=BTsYPtbKQWwX-iXF4qCkfPG7DPxIB54J989n83bXrIo,3092
55
55
  utilities/psutil.py,sha256=0j4YxtVb8VjaaKKiHg6UEK95SUPkEcENgPtLgPJsNv0,3760
56
- utilities/pudb.py,sha256=Dte7P9J0VWrWTNYvwxZX6kgaEtdTt5ZnnmOAUTjltqU,1771
57
56
  utilities/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
57
  utilities/pydantic.py,sha256=CmxCi4sukeHM3JGjJ1Rbp8UAvcx4MZapLg10mFYJ-nk,1771
59
58
  utilities/pyinstrument.py,sha256=_Rfq6Gg4NKV2NF0dRYOpK2IRyyePxI7-3UmHIQLYrlQ,852
@@ -78,7 +77,7 @@ utilities/tempfile.py,sha256=VqmZJAhTJ1OaVywFzk5eqROV8iJbW9XQ_QYAV0bpdRo,1384
78
77
  utilities/text.py,sha256=ymBFlP_cA8OgNnZRVNs7FAh7OG8HxE6YkiLEMZv5g_A,11297
79
78
  utilities/threading.py,sha256=GvBOp4CyhHfN90wGXZuA2VKe9fGzMaEa7oCl4f3nnPU,1009
80
79
  utilities/timer.py,sha256=oXfTii6ymu57niP0BDGZjFD55LEHi2a19kqZKiTgaFQ,2588
81
- utilities/traceback.py,sha256=i-790AQbTrDA8MiYyOcYPFpm48I558VR_kL_7x4ypfY,8503
80
+ utilities/traceback.py,sha256=nvnhlsxLiViFkGLj5zQFNMs2IOoBEOzMZYjsEW_ESQM,9091
82
81
  utilities/typed_settings.py,sha256=niNxgvVKrTy1c0j0D0Jp2tO3m231f4yJJ-38ni-xY3Q,3739
83
82
  utilities/types.py,sha256=DrFWZQqpkekHdnr2-G2eBaxGX8FoND6ON2XFRvhm8Jo,17177
84
83
  utilities/typing.py,sha256=Z-_XDaWyT_6wIo3qfNK-hvRlzxP2Jxa9PgXzm5rDYRA,13790
@@ -90,7 +89,7 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
90
89
  utilities/whenever.py,sha256=A-yoOqBqrcVD1yDINDsTFDw7dq9-zgUGn_f8CxVUQJs,23332
91
90
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
92
91
  utilities/zoneinfo.py,sha256=oEH-nL3t4h9uawyZqWDtNtDAl6M-CLpLYGI_nI6DulM,1971
93
- dycw_utilities-0.135.1.dist-info/METADATA,sha256=tswCMdL1NHJH_VeKHYyY6tEZbGnOGzFlN45k2iOhJls,1584
94
- dycw_utilities-0.135.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
95
- dycw_utilities-0.135.1.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
96
- dycw_utilities-0.135.1.dist-info/RECORD,,
92
+ dycw_utilities-0.136.0.dist-info/METADATA,sha256=IM9-dR9bLGWxZvhPixn8lYPDBpR-51PXzrwvgQXPDyI,1637
93
+ dycw_utilities-0.136.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
94
+ dycw_utilities-0.136.0.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
95
+ dycw_utilities-0.136.0.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.135.1"
3
+ __version__ = "0.136.0"
utilities/traceback.py CHANGED
@@ -11,11 +11,12 @@ from itertools import repeat
11
11
  from pathlib import Path
12
12
  from socket import gethostname
13
13
  from traceback import TracebackException
14
- from typing import TYPE_CHECKING, override
14
+ from typing import TYPE_CHECKING, assert_never, override
15
15
 
16
16
  from utilities.atomicwrites import writer
17
17
  from utilities.errors import repr_error
18
18
  from utilities.iterables import OneEmptyError, one
19
+ from utilities.os import get_env_var
19
20
  from utilities.pathlib import get_path
20
21
  from utilities.reprlib import (
21
22
  RICH_EXPAND_ALL,
@@ -30,7 +31,7 @@ from utilities.version import get_version
30
31
  from utilities.whenever import format_compact, get_now, to_zoned_date_time
31
32
 
32
33
  if TYPE_CHECKING:
33
- from collections.abc import Callable, Iterator, Sequence
34
+ from collections.abc import Iterator, Sequence
34
35
  from traceback import FrameSummary
35
36
  from types import TracebackType
36
37
 
@@ -202,6 +203,7 @@ def make_except_hook(
202
203
  max_depth: int | None = RICH_MAX_DEPTH,
203
204
  expand_all: bool = RICH_EXPAND_ALL,
204
205
  slack_url: str | None = None,
206
+ pudb: str | None = None,
205
207
  ) -> Callable[
206
208
  [type[BaseException] | None, BaseException | None, TracebackType | None], None
207
209
  ]:
@@ -218,6 +220,7 @@ def make_except_hook(
218
220
  max_depth=max_depth,
219
221
  expand_all=expand_all,
220
222
  slack_url=slack_url,
223
+ pudb=pudb,
221
224
  )
222
225
 
223
226
 
@@ -237,6 +240,7 @@ def _make_except_hook_inner(
237
240
  max_depth: int | None = RICH_MAX_DEPTH,
238
241
  expand_all: bool = RICH_EXPAND_ALL,
239
242
  slack_url: str | None = None,
243
+ pudb: str | Callable[[], bool] | None = None,
240
244
  ) -> None:
241
245
  """Exception hook to log the traceback."""
242
246
  _ = (exc_type, traceback)
@@ -268,6 +272,18 @@ def _make_except_hook_inner(
268
272
 
269
273
  send = f"```{slim}```"
270
274
  run(send_to_slack(slack_url, send))
275
+ if pudb is not None: # pragma: no cover
276
+ match pudb:
277
+ case str() as env_var:
278
+ call_pudb = get_env_var(env_var, nullable=True) is not None
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)
271
287
 
272
288
 
273
289
  @dataclass(kw_only=True, slots=True)
utilities/pudb.py DELETED
@@ -1,62 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from asyncio import iscoroutinefunction
4
- from functools import partial, wraps
5
- from typing import TYPE_CHECKING, Any, NoReturn, cast, overload
6
-
7
- from utilities.os import GetEnvVarError, get_env_var
8
-
9
- if TYPE_CHECKING:
10
- from collections.abc import Callable
11
-
12
-
13
- _ENV_VAR = "DEBUG"
14
-
15
-
16
- @overload
17
- def call_pudb[F: Callable](func: F, /, *, env_var: str = _ENV_VAR) -> F: ...
18
- @overload
19
- def call_pudb[F: Callable](
20
- func: None = None, /, *, env_var: str = _ENV_VAR
21
- ) -> Callable[[F], F]: ...
22
- def call_pudb[F: Callable](
23
- func: F | None = None, /, *, env_var: str = _ENV_VAR
24
- ) -> F | Callable[[F], F]:
25
- """Call `pudb` upon failure, if the required environment variable is set."""
26
- if func is None:
27
- result = partial(call_pudb, env_var=env_var)
28
- return cast("Callable[[F], F]", result)
29
-
30
- if not iscoroutinefunction(func):
31
-
32
- @wraps(func)
33
- def wrapped_sync(*args: Any, **kwargs: Any) -> Any:
34
- try:
35
- return func(*args, **kwargs)
36
- except Exception as error: # noqa: BLE001
37
- _call_pudb(error, env_var=env_var)
38
-
39
- return cast("F", wrapped_sync)
40
-
41
- @wraps(func)
42
- async def wrapped_async(*args: Any, **kwargs: Any) -> Any:
43
- try:
44
- return await func(*args, **kwargs)
45
- except Exception as error: # noqa: BLE001
46
- _call_pudb(error, env_var=env_var)
47
-
48
- return cast("F", wrapped_async)
49
-
50
-
51
- def _call_pudb(error: Exception, /, *, env_var: str = _ENV_VAR) -> NoReturn:
52
- try:
53
- _ = get_env_var(env_var)
54
- except GetEnvVarError:
55
- raise error from None
56
- from pudb import post_mortem # pragma: no cover
57
-
58
- post_mortem() # pragma: no cover
59
- raise error # pragma: no cover
60
-
61
-
62
- __all__ = ["call_pudb"]