dycw-utilities 0.125.6__py3-none-any.whl → 0.125.8__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.125.6
3
+ Version: 0.125.8
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -17,7 +17,7 @@ Requires-Dist: pytest-regressions<2.8,>=2.7.0; extra == 'test'
17
17
  Requires-Dist: pytest-rerunfailures<16,>=15.1; extra == 'test'
18
18
  Requires-Dist: pytest-rng<1.1,>=1.0.0; extra == 'test'
19
19
  Requires-Dist: pytest-timeout<2.5,>=2.4.0; extra == 'test'
20
- Requires-Dist: pytest-xdist<3.7,>=3.6.1; extra == 'test'
20
+ Requires-Dist: pytest-xdist<3.8,>=3.7.0; extra == 'test'
21
21
  Requires-Dist: pytest<8.4,>=8.3.5; extra == 'test'
22
22
  Requires-Dist: setuptools>=78.0.2; extra == 'test'
23
23
  Provides-Extra: zzz-test-altair
@@ -174,7 +174,7 @@ Requires-Dist: scipy<1.16,>=1.15.3; extra == 'zzz-test-scipy'
174
174
  Provides-Extra: zzz-test-sentinel
175
175
  Provides-Extra: zzz-test-shelve
176
176
  Provides-Extra: zzz-test-slack-sdk
177
- Requires-Dist: aiohttp<3.13,>=3.12.0; extra == 'zzz-test-slack-sdk'
177
+ Requires-Dist: aiohttp<3.12.1,>=3.12.0; extra == 'zzz-test-slack-sdk'
178
178
  Requires-Dist: slack-sdk<3.36,>=3.35.0; extra == 'zzz-test-slack-sdk'
179
179
  Provides-Extra: zzz-test-socket
180
180
  Provides-Extra: zzz-test-sqlalchemy
@@ -1,6 +1,6 @@
1
- utilities/__init__.py,sha256=K4Ol-gD9v9XdDt841jszphCBL7t-hLho9smh0baUu8Y,60
1
+ utilities/__init__.py,sha256=NMu0lmH61a5876HTROVqniekCmmFD7fjHMGBEq4s2LA,60
2
2
  utilities/altair.py,sha256=Gpja-flOo-Db0PIPJLJsgzAlXWoKUjPU1qY-DQ829ek,9156
3
- utilities/asyncio.py,sha256=gr2eUx0E6LiCup6VKgUGwh8lAUriGdX2TlK-PZdlvfo,28284
3
+ utilities/asyncio.py,sha256=3OVbJKTYCucrIkM7WSMMkQA9jYJFCQMnGNM4H5rBNgA,29154
4
4
  utilities/atomicwrites.py,sha256=geFjn9Pwn-tTrtoGjDDxWli9NqbYfy3gGL6ZBctiqSo,5393
5
5
  utilities/atools.py,sha256=IYMuFSFGSKyuQmqD6v5IUtDlz8PPw0Sr87Cub_gRU3M,1168
6
6
  utilities/cachetools.py,sha256=C1zqOg7BYz0IfQFK8e3qaDDgEZxDpo47F15RTfJM37Q,2910
@@ -13,7 +13,7 @@ utilities/cvxpy.py,sha256=Rv1-fD-XYerosCavRF8Pohop2DBkU3AlFaGTfD8AEAA,13776
13
13
  utilities/dataclasses.py,sha256=iiC1wpGXWhaocIikzwBt8bbLWyImoUlOlcDZJGejaIg,33011
14
14
  utilities/datetime.py,sha256=uYoaOi_C1YtNXGfTN9xlTrW62Re2b1_4Skuv14_MeYQ,38985
15
15
  utilities/enum.py,sha256=HoRwVCWzsnH0vpO9ZEcAAIZLMv0Sn2vJxxA4sYMQgDs,5793
16
- utilities/errors.py,sha256=gxsaa7eq7jbYl41Of40-ivjXqJB5gt4QAcJ0smZZMJE,829
16
+ utilities/errors.py,sha256=C89Xm-DHUjfqJKROo1pW-RGat8zDvTzZuy6zBNMkj_s,837
17
17
  utilities/eventkit.py,sha256=6M5Xu1SzN-juk9PqBHwy5dS-ta7T0qA6SMpDsakOJ0E,13039
18
18
  utilities/fastapi.py,sha256=LG1-Q8RDi7wsyVN6v74qptPYX8WGXPkFOQFniMvtzjc,2439
19
19
  utilities/fpdf2.py,sha256=y1NGXR5chWqLXWpewGV3hlRGMr_5yV1lVRkPBhPEgJI,1843
@@ -28,7 +28,7 @@ utilities/importlib.py,sha256=mV1xT_O_zt_GnZZ36tl3xOmMaN_3jErDWY54fX39F6Y,429
28
28
  utilities/ipython.py,sha256=V2oMYHvEKvlNBzxDXdLvKi48oUq2SclRg5xasjaXStw,763
29
29
  utilities/iterables.py,sha256=wqq2lKfEAq1qncE-lR848DHX627aerFaq4BXmLen-NE,43589
30
30
  utilities/jupyter.py,sha256=ft5JA7fBxXKzP-L9W8f2-wbF0QeYc_2uLQNFDVk4Z-M,2917
31
- utilities/libcst.py,sha256=zqZxfvTdcsi83Ph-HC4lP8zyOqAun7eKABeRdhMtoMM,4846
31
+ utilities/libcst.py,sha256=L0IkwAWXPuNpYyceeJGOC8CAwHdVPRpbXC8MQphCXh4,4954
32
32
  utilities/lightweight_charts.py,sha256=0xNfcsrgFI0R9xL25LtSm-W5yhfBI93qQNT6HyaXAhg,2769
33
33
  utilities/logging.py,sha256=gwo3pusPjnWO1ollrtn1VKYyRAQJTue4SkCbMeNvec4,25715
34
34
  utilities/loguru.py,sha256=MEMQVWrdECxk1e3FxGzmOf21vWT9j8CAir98SEXFKPA,3809
@@ -88,7 +88,7 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
88
88
  utilities/whenever.py,sha256=jS31ZAY5OMxFxLja_Yo5Fidi87Pd-GoVZ7Vi_teqVDA,16743
89
89
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
90
90
  utilities/zoneinfo.py,sha256=-5j7IQ9nb7gR43rdgA7ms05im-XuqhAk9EJnQBXxCoQ,1874
91
- dycw_utilities-0.125.6.dist-info/METADATA,sha256=kXfKuSjErFLMEk1B4eslticFk-Outr7LtYTGXOwHdcw,12849
92
- dycw_utilities-0.125.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
93
- dycw_utilities-0.125.6.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
94
- dycw_utilities-0.125.6.dist-info/RECORD,,
91
+ dycw_utilities-0.125.8.dist-info/METADATA,sha256=TWxcCoaCSvt2oxBQq7vNPceZ3qJb1ba9ODTLakKrhxc,12851
92
+ dycw_utilities-0.125.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
93
+ dycw_utilities-0.125.8.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
94
+ dycw_utilities-0.125.8.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.125.6"
3
+ __version__ = "0.125.8"
utilities/asyncio.py CHANGED
@@ -400,6 +400,8 @@ class InfiniteLooper(ABC, Generic[THashable]):
400
400
 
401
401
  async def _run_looper_by_itself(self) -> None:
402
402
  """Run the looper by itself."""
403
+ whitelisted = tuple(self._yield_whitelisted_errors())
404
+ blacklisted = tuple(self._yield_blacklisted_errors())
403
405
  while True:
404
406
  try:
405
407
  self._reset_events()
@@ -423,12 +425,21 @@ class InfiniteLooper(ABC, Generic[THashable]):
423
425
  self._raise_error(event)
424
426
  except InfiniteLooperError:
425
427
  raise
426
- except Exception as error: # noqa: BLE001
427
- self._error_upon_core(error)
428
+ except BaseException as error1:
429
+ match error1:
430
+ case Exception():
431
+ if isinstance(error1, blacklisted):
432
+ raise
433
+ case BaseException():
434
+ if not isinstance(error1, whitelisted):
435
+ raise
436
+ case _ as never:
437
+ assert_never(never)
438
+ self._error_upon_core(error1)
428
439
  try:
429
440
  await self._teardown()
430
- except Exception as error: # noqa: BLE001
431
- self._error_upon_teardown(error)
441
+ except BaseException as error2: # noqa: BLE001
442
+ self._error_upon_teardown(error2)
432
443
  finally:
433
444
  await self._run_sleep(self.sleep_restart)
434
445
 
@@ -471,7 +482,7 @@ class InfiniteLooper(ABC, Generic[THashable]):
471
482
  self._sleep_restart_desc,
472
483
  )
473
484
 
474
- def _error_upon_core(self, error: Exception, /) -> None:
485
+ def _error_upon_core(self, error: BaseException, /) -> None:
475
486
  """Handle any errors upon running the core function."""
476
487
  if self.logger is not None:
477
488
  getLogger(name=self.logger).error(
@@ -481,7 +492,7 @@ class InfiniteLooper(ABC, Generic[THashable]):
481
492
  self._sleep_restart_desc,
482
493
  )
483
494
 
484
- def _error_upon_teardown(self, error: Exception, /) -> None:
495
+ def _error_upon_teardown(self, error: BaseException, /) -> None:
485
496
  """Handle any errors upon tearing down the looper."""
486
497
  if self.logger is not None:
487
498
  getLogger(name=self.logger).error(
@@ -561,6 +572,14 @@ class InfiniteLooper(ABC, Generic[THashable]):
561
572
  """Yield any other loopers which must also be run."""
562
573
  yield from []
563
574
 
575
+ def _yield_blacklisted_errors(self) -> Iterator[type[Exception]]:
576
+ """Yield any exceptions which the looper ought to catch terminate upon."""
577
+ yield from []
578
+
579
+ def _yield_whitelisted_errors(self) -> Iterator[type[BaseException]]:
580
+ """Yield any exceptions which the looper ought to catch and allow running."""
581
+ yield from []
582
+
564
583
 
565
584
  @dataclass(kw_only=True, slots=True)
566
585
  class InfiniteLooperError(Exception):
utilities/errors.py CHANGED
@@ -20,10 +20,10 @@ class ImpossibleCaseError(Exception):
20
20
  ##
21
21
 
22
22
 
23
- def repr_error(error: MaybeType[Exception], /) -> str:
23
+ def repr_error(error: MaybeType[BaseException], /) -> str:
24
24
  """Get a string representation of an error."""
25
25
  match error:
26
- case Exception() as error_obj:
26
+ case BaseException() as error_obj:
27
27
  return f"{error_obj.__class__.__name__}({error_obj})"
28
28
  case type() as error_cls:
29
29
  return error_cls.__name__
utilities/libcst.py CHANGED
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from collections.abc import Sequence
4
4
  from dataclasses import dataclass
5
- from subprocess import check_output
5
+ from subprocess import CalledProcessError, check_output
6
6
  from typing import assert_never, override
7
7
 
8
8
  from libcst import (
@@ -154,7 +154,10 @@ def render_module(source: str | Module, /) -> str:
154
154
  """Render a module."""
155
155
  match source: # skipif-ci
156
156
  case str() as text:
157
- return check_output(["ruff", "format", "-"], input=text, text=True)
157
+ try:
158
+ return check_output(["ruff", "format", "-"], input=text, text=True)
159
+ except CalledProcessError:
160
+ return text
158
161
  case Module() as module:
159
162
  return render_module(module.code)
160
163
  case _ as never: