dycw-utilities 0.152.0__py3-none-any.whl → 0.153.1__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.152.0
3
+ Version: 0.153.1
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -1,6 +1,6 @@
1
- utilities/__init__.py,sha256=yPinoOXl37WGTDQPnlJyr4YW7B9ojeL_vWBwenSrkaQ,60
1
+ utilities/__init__.py,sha256=tLMJ7LzsnMye2vQj1HzCBHT0fuYeBMXUcof9VDP_uyk,60
2
2
  utilities/altair.py,sha256=92E2lCdyHY4Zb-vCw6rEJIsWdKipuu-Tu2ab1ufUfAk,9079
3
- utilities/asyncio.py,sha256=r75HVwm6QoCOz7bEe3_KO47G4_IIhNCYcPDrJTi4i_4,16777
3
+ utilities/asyncio.py,sha256=QXkTtugXkqtYt7Do23zgYErqzdp6jwzPpV_SP9fJ1gI,16780
4
4
  utilities/atomicwrites.py,sha256=tPo6r-Rypd9u99u66B9z86YBPpnLrlHtwox_8Z7T34Y,5790
5
5
  utilities/atools.py,sha256=6neeCcgXxK2dlsc0xp15Za7nSucbCgFtAJepGI_-WXU,2549
6
6
  utilities/cachetools.py,sha256=v1-9sXHLdOLiwmkq6NB0OUbxeKBuVVN6wmAWefWoaHI,2744
@@ -8,15 +8,15 @@ utilities/click.py,sha256=NXGzWoFOJqIblGwFqSGgXEDCKoV8E_JR58Lu2xJJFAo,17309
8
8
  utilities/concurrent.py,sha256=fHeW2SZ_TEMfFY0C8pyQI6aPlnecvx9x6SuUwBWj_JY,2853
9
9
  utilities/contextlib.py,sha256=m2D5bwvtCZLJcJ3IwVqyErYODuwJ1gLrT2UfATAQl-w,7435
10
10
  utilities/contextvars.py,sha256=J8OhC7jqozAGYOCe2KUWysbPXNGe5JYz3HfaY_mIs08,883
11
- utilities/cryptography.py,sha256=_CiK_K6c_-uQuUhsUNjNjTL-nqxAh4_1zTfS11Xe120,972
11
+ utilities/cryptography.py,sha256=5PFrzsNUGHay91dFgYnDKwYprXxahrBqztmUqViRzBk,956
12
12
  utilities/cvxpy.py,sha256=Rv1-fD-XYerosCavRF8Pohop2DBkU3AlFaGTfD8AEAA,13776
13
13
  utilities/dataclasses.py,sha256=G05UH-fqUbcRPjQ8arK6K0Ap2fRbzEm0SZahJKCqYfY,32643
14
14
  utilities/enum.py,sha256=5l6pwZD1cjSlVW4ss-zBPspWvrbrYrdtJWcg6f5_J5w,5781
15
15
  utilities/errors.py,sha256=mFlDGSM0LI1jZ1pbqwLAH3ttLZ2JVIxyZLojw8tGVZU,1479
16
- utilities/eventkit.py,sha256=FRCZisJfY9hAS9GHV4ZO3ZHDs89XZod7Xf99WzBt7jQ,12636
16
+ utilities/eventkit.py,sha256=ddoleSwW9zdc2tjX5Ge0pMKtYwV_JMxhHYOxnWX2AGM,12609
17
17
  utilities/fastapi.py,sha256=3wpd63Tw9paSyy7STpAD7GGe8fLkLaRC6TPCwIGm1BU,1361
18
18
  utilities/fpdf2.py,sha256=776PkEX5xEK-whFOzqaVaQVHPy1Xf01kCSyj7TEp80g,1886
19
- utilities/functions.py,sha256=UII45tzfqchSsQs1Tfm1NANFlF11m16gaNeV5MzM1ZY,28528
19
+ utilities/functions.py,sha256=Teqm7ylOqEcBLHWhRwjKqouUfc6nv_6qO6fILpnOPyA,27937
20
20
  utilities/functools.py,sha256=I00ru2gQPakZw2SHVeKIKXfTv741655s6HI0lUoE0D4,1552
21
21
  utilities/getpass.py,sha256=DfN5UgMAtFCqS3dSfFHUfqIMZX2shXvwphOz_6J6f6A,103
22
22
  utilities/gzip.py,sha256=fkGP3KdsBfXlstodT4wtlp-PwNyUsogpbDCVVVGdsm4,781
@@ -31,7 +31,7 @@ utilities/json.py,sha256=-WcGtSsCr9Y42wHZzAMnfvU6ihAfVftylFfRUORaDFo,2102
31
31
  utilities/jupyter.py,sha256=ft5JA7fBxXKzP-L9W8f2-wbF0QeYc_2uLQNFDVk4Z-M,2917
32
32
  utilities/libcst.py,sha256=TKgKN4bNmtBNEE-TUfhTyd1BrTncfsl_7tTuhpesGYY,5585
33
33
  utilities/lightweight_charts.py,sha256=YM3ojBvJxuCSUBu_KrhFBmaMCvRPvupKC3qkm-UVZq4,2751
34
- utilities/logging.py,sha256=TnbdmDAZ9DGEkSl7VBhlh5mu_6AbRtefoIHZuFC1_sA,19406
34
+ utilities/logging.py,sha256=z2wIraTaTfQw-MjhhgIKeyWSyW5gCRX04gsdlknkTTs,19361
35
35
  utilities/math.py,sha256=7ve4RxX3g-FGGVnWV0K9bBeGnKUEjnTbH13VxdvFtGE,26847
36
36
  utilities/memory_profiler.py,sha256=XzN56jDCa5aqXS_DxEjb_K4L6aIWh_5zyKi6OhcIxw0,853
37
37
  utilities/modules.py,sha256=iuvLluJya-hvl1Q25-Jk3dLgx2Es3ck4SjJiEkAlVTs,3195
@@ -42,21 +42,20 @@ utilities/optuna.py,sha256=C-fhWYiXHVPo1l8QctYkFJ4DyhbSrGorzP1dJb_qvd8,1933
42
42
  utilities/orjson.py,sha256=Gzxn-s55pGFKV8DdsYXpp-Gr3r-5KdacYUd_GHMBogM,40088
43
43
  utilities/os.py,sha256=mFvjydySvjtSXpk7tLStUJcndauAoujxUUmj_CO7LWY,3778
44
44
  utilities/parse.py,sha256=JcJn5yXKhIWXBCwgBdPsyu7Hvcuw6kyEdqvaebCaI9k,17951
45
- utilities/pathlib.py,sha256=77wT9naY2Nnrbar8nJiIYd2r3MfabMQM9VguuuivrdQ,8481
46
- utilities/period.py,sha256=c4-N8N1GIUyomoHmSO7yPfYgK8tc__dxNSB79knlx2w,12471
45
+ utilities/pathlib.py,sha256=qGuU8XPmdgGpy8tOMUgelfXx3kxI8h9IaV3TI_06QGE,8428
47
46
  utilities/pickle.py,sha256=MBT2xZCsv0pH868IXLGKnlcqNx2IRVKYNpRcqiQQqxw,653
48
47
  utilities/platform.py,sha256=pTn7gw6N4T6LdKrf0virwarof_mze9WtoQlrGMzhGVI,2798
49
48
  utilities/polars.py,sha256=uxV4liIQoCO92aERDO-AMfa8Es_-xCKgwZoyTO3PazQ,74410
50
49
  utilities/polars_ols.py,sha256=Uc9V5kvlWZ5cU93lKZ-cfAKdVFFw81tqwLW9PxtUvMs,5618
51
- utilities/postgres.py,sha256=juXaOguCCX4oAw4y2JajRVIhhKKZarCyapNyyr4Tn4Q,12538
52
- utilities/pottery.py,sha256=u0uvyGgYyujxftEMlsv6ppYTKQoVVjHt5jnVxxYz9s4,6596
50
+ utilities/postgres.py,sha256=70BPcb_Na0LqDXJfqu0JwkHkGrwyuKpIVooSm6NlRn8,12467
51
+ utilities/pottery.py,sha256=HJ96oLRarTP37Vhg0WTyB3yAu2hETeg6HgRmpDIqyUs,6581
53
52
  utilities/pqdm.py,sha256=z8bSMS7QJmWun65FQZruAqT-R3wqPAzNzhWcX9Nvr0A,3087
54
53
  utilities/psutil.py,sha256=KUlu4lrUw9Zg1V7ZGetpWpGb9DB8l_SSDWGbANFNCPU,2104
55
54
  utilities/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
- utilities/pyinstrument.py,sha256=E3U4T6qzTGVcGzAiShl9BL3acO-uu_dHZVgSbkSBd7A,864
57
- utilities/pytest.py,sha256=xR-xG5aTfU9U7Qcb8Lle8uhLP1V0zc8EqZFfU0F8zfg,7899
55
+ utilities/pyinstrument.py,sha256=crJeEGOLxVt-tBGETb4E9v33kpaWmKrgXqL4PlFGRtk,850
56
+ utilities/pytest.py,sha256=2HHfAWkzZeK2OAzL2F49EDKooMkfDoGqg8Ev4cHC_N8,7869
58
57
  utilities/pytest_regressions.py,sha256=ocjHTtfOeiGfQAKIei8pKNd61sxN9dawrJJ9gPt2wzA,4097
59
- utilities/random.py,sha256=YWYzWxQDeyJRiuHGnO1OxF6dDucpq7qc1tH_ealwCRg,4130
58
+ utilities/random.py,sha256=sXYpWjiSTXdn0RYyBGmydpI1PldwNTG3ocZESBC5o4E,4119
60
59
  utilities/re.py,sha256=S4h-DLL6ScMPqjboZ_uQ1BVTJajrqV06r_81D--_HCE,4573
61
60
  utilities/redis.py,sha256=2fdveFbqL2pEAeyiVuN_Je8nSM_IZHeahPduMHhFRzY,28381
62
61
  utilities/reprlib.py,sha256=ssYTcBW-TeRh3fhCJv57sopTZHF5FrPyyUg9yp5XBlo,3953
@@ -70,26 +69,26 @@ utilities/sqlalchemy_polars.py,sha256=Mm-sShZfqqgnzTrupMQdCfSM2akrybXHXAErTs-ofM
70
69
  utilities/statsmodels.py,sha256=koyiBHvpMcSiBfh99wFUfSggLNx7cuAw3rwyfAhoKpQ,3410
71
70
  utilities/string.py,sha256=shmBK87zZwzGyixuNuXCiUbqzfeZ9xlrFwz6JTaRvDk,582
72
71
  utilities/tempfile.py,sha256=HxB2BF28CcecDJLQ3Bx2Ej-Pb6RJc6W9ngSpB9CnP4k,2018
73
- utilities/text.py,sha256=4EOtSnfU0z09WANxjVO8Td54VNNe1sS4dWCa7VUo4HI,11794
72
+ utilities/text.py,sha256=uwCDgpEunYruyh6sKMfNWK3Rp5H3ndpKRAkq86CBNys,13043
74
73
  utilities/threading.py,sha256=GvBOp4CyhHfN90wGXZuA2VKe9fGzMaEa7oCl4f3nnPU,1009
75
74
  utilities/timer.py,sha256=oXfTii6ymu57niP0BDGZjFD55LEHi2a19kqZKiTgaFQ,2588
76
- utilities/traceback.py,sha256=zofhzIedpUHrzDNiRJDVzm_wuu_tlTQvVqK4quxVlgM,9151
77
- utilities/typed_settings.py,sha256=ZzzlMgPntnGv6kAn0mGp43nHJCnU99V_8152QmpH9tY,4476
78
- utilities/types.py,sha256=-DUlUxqkVGaSVU_uTbfMIXWUDDUXnPuIDwQIsPE_mY8,18244
75
+ utilities/traceback.py,sha256=e0BpxNMybVmELHGsYM5N6LVbfmn0jLhefLoa81NjZBg,9100
76
+ utilities/typed_settings.py,sha256=SFWqS3lAzV7IfNRwqFcTk0YynTcQ7BmrcW2mr_KUnos,4466
77
+ utilities/types.py,sha256=DMHTom46_vSwM4taulNgw6SEzseVggCVxX7e2JZnij8,18404
79
78
  utilities/typing.py,sha256=Z-_XDaWyT_6wIo3qfNK-hvRlzxP2Jxa9PgXzm5rDYRA,13790
80
79
  utilities/tzdata.py,sha256=fgNVj66yUbCSI_-vrRVzSD3gtf-L_8IEJEPjP_Jel5Y,266
81
80
  utilities/tzlocal.py,sha256=KyCXEgCTjqGFx-389JdTuhMRUaT06U1RCMdWoED-qro,728
82
- utilities/uuid.py,sha256=32p7DGHGM2Btx6PcBvCZvERSWbpupMXqx6FppPoSoTU,612
83
- utilities/version.py,sha256=A8iLeY2kfj1mxjFyKJowiYrWKstJ5smoBj9QM93cUwI,5112
81
+ utilities/uuid.py,sha256=nQZs6tFX4mqtc2Ku3KqjloYCqwpTKeTj8eKwQwh3FQI,1572
82
+ utilities/version.py,sha256=ipBj5-WYY_nelp2uwFlApfWWCzTLzPwpovUi9x_OBMs,5085
84
83
  utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
85
- utilities/whenever.py,sha256=oBQziaMsvIozFfpwaJ8nm2oFrAkhnN6Zm4ypMuwBqiA,44678
84
+ utilities/whenever.py,sha256=_kMiXvmfuVud2i_2X3lO8h0U3KR7HrYqd-vwnShBAIg,57337
86
85
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
87
86
  utilities/zoneinfo.py,sha256=FBMcUQ4662Aq8SsuCL1OAhDQiyANmVjtb-C30DRrWoE,1966
88
87
  utilities/pytest_plugins/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
89
- utilities/pytest_plugins/pytest_randomly.py,sha256=NXzCcGKbpgYouz5yehKb4jmxmi2SexKKpgF4M65bi10,414
90
- utilities/pytest_plugins/pytest_regressions.py,sha256=Iwhfv_OJH7UCPZCfoh7ugZ2Xjqjil-BBBsOb8sDwiGI,1471
91
- dycw_utilities-0.152.0.dist-info/METADATA,sha256=JV_YGZDAfL333osSK-mawT3eeu0RHzt2PNkd-09o0yM,1696
92
- dycw_utilities-0.152.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
93
- dycw_utilities-0.152.0.dist-info/entry_points.txt,sha256=BOD_SoDxwsfJYOLxhrSXhHP_T7iw-HXI9f2WVkzYxvQ,135
94
- dycw_utilities-0.152.0.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
95
- dycw_utilities-0.152.0.dist-info/RECORD,,
88
+ utilities/pytest_plugins/pytest_randomly.py,sha256=B1qYVlExGOxTywq2r1SMi5o7btHLk2PNdY_b1p98dkE,409
89
+ utilities/pytest_plugins/pytest_regressions.py,sha256=9v8kAXDM2ycIXJBimoiF4EgrwbUvxTycFWJiGR_GHhM,1466
90
+ dycw_utilities-0.153.1.dist-info/METADATA,sha256=5qPYBod9hSVQarpW6SVN-iqMQgPfp9YYT6u5wPGAAVk,1696
91
+ dycw_utilities-0.153.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
+ dycw_utilities-0.153.1.dist-info/entry_points.txt,sha256=BOD_SoDxwsfJYOLxhrSXhHP_T7iw-HXI9f2WVkzYxvQ,135
93
+ dycw_utilities-0.153.1.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
94
+ dycw_utilities-0.153.1.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.152.0"
3
+ __version__ = "0.153.1"
utilities/asyncio.py CHANGED
@@ -37,11 +37,12 @@ from typing import (
37
37
  )
38
38
 
39
39
  from utilities.errors import ImpossibleCaseError, is_instance_error
40
- from utilities.functions import ensure_int, ensure_not_none, to_bool
41
- from utilities.logging import get_logger
40
+ from utilities.functions import ensure_int, ensure_not_none
41
+ from utilities.logging import to_logger
42
42
  from utilities.random import SYSTEM_RANDOM
43
43
  from utilities.sentinel import Sentinel, sentinel
44
44
  from utilities.shelve import yield_shelf
45
+ from utilities.text import to_bool
45
46
  from utilities.warnings import suppress_warnings
46
47
  from utilities.whenever import get_now, round_date_or_date_time, to_nanoseconds
47
48
 
@@ -70,8 +71,8 @@ if TYPE_CHECKING:
70
71
  Coro,
71
72
  Delta,
72
73
  ExceptionTypeLike,
73
- LoggerOrName,
74
- MaybeCallableBool,
74
+ LoggerLike,
75
+ MaybeCallableBoolLike,
75
76
  MaybeType,
76
77
  PathLike,
77
78
  SupportsKeysAndGetItem,
@@ -231,7 +232,7 @@ class EnhancedTaskGroup(TaskGroup):
231
232
  _semaphore: Semaphore | None
232
233
  _timeout: Delta | None
233
234
  _error: MaybeType[BaseException]
234
- _debug: MaybeCallableBool
235
+ _debug: MaybeCallableBoolLike
235
236
  _stack: AsyncExitStack
236
237
  _timeout_cm: _AsyncGeneratorContextManager[None] | None
237
238
 
@@ -242,7 +243,7 @@ class EnhancedTaskGroup(TaskGroup):
242
243
  max_tasks: int | None = None,
243
244
  timeout: Delta | None = None,
244
245
  error: MaybeType[BaseException] = TimeoutError,
245
- debug: MaybeCallableBool = False,
246
+ debug: MaybeCallableBoolLike = False,
246
247
  ) -> None:
247
248
  super().__init__()
248
249
  self._max_tasks = max_tasks
@@ -331,7 +332,7 @@ class EnhancedTaskGroup(TaskGroup):
331
332
  assert_never(never)
332
333
 
333
334
  def _is_debug(self) -> bool:
334
- return to_bool(bool_=self._debug) or (
335
+ return to_bool(self._debug) or (
335
336
  (self._max_tasks is not None) and (self._max_tasks <= 0)
336
337
  )
337
338
 
@@ -403,7 +404,7 @@ async def loop_until_succeed(
403
404
  func: Callable[[], Coro[None]],
404
405
  /,
405
406
  *,
406
- logger: LoggerOrName | None = None,
407
+ logger: LoggerLike | None = None,
407
408
  errors: ExceptionTypeLike[Exception] | None = None,
408
409
  sleep: Delta | None = None,
409
410
  ) -> bool:
@@ -414,7 +415,7 @@ async def loop_until_succeed(
414
415
  await func()
415
416
  except Exception as error: # noqa: BLE001
416
417
  if logger is not None:
417
- get_logger(logger=logger).error("Error running %r", name, exc_info=True)
418
+ to_logger(logger).error("Error running %r", name, exc_info=True)
418
419
  exc_type, exc_value, traceback = sys.exc_info()
419
420
  if (exc_type is None) or (exc_value is None): # pragma: no cover
420
421
  raise ImpossibleCaseError(
@@ -425,10 +426,10 @@ async def loop_until_succeed(
425
426
  return False
426
427
  if sleep is not None:
427
428
  if logger is not None:
428
- get_logger(logger=logger).info("Sleeping for %s...", sleep)
429
+ to_logger(logger).info("Sleeping for %s...", sleep)
429
430
  await sleep_td(sleep)
430
431
  if logger is not None:
431
- get_logger(logger=logger).info("Retrying %r...", name)
432
+ to_logger(logger).info("Retrying %r...", name)
432
433
  else:
433
434
  return True
434
435
 
utilities/cryptography.py CHANGED
@@ -11,18 +11,18 @@ _ENV_VAR = "FERNET_KEY"
11
11
 
12
12
  def encrypt(text: str, /, *, env_var: str = _ENV_VAR) -> bytes:
13
13
  """Encrypt a string."""
14
- return get_fernet(env_var=env_var).encrypt(text.encode())
14
+ return get_fernet(env_var).encrypt(text.encode())
15
15
 
16
16
 
17
17
  def decrypt(text: bytes, /, *, env_var: str = _ENV_VAR) -> str:
18
18
  """Encrypt a string."""
19
- return get_fernet(env_var=env_var).decrypt(text).decode()
19
+ return get_fernet(env_var).decrypt(text).decode()
20
20
 
21
21
 
22
22
  ##
23
23
 
24
24
 
25
- def get_fernet(*, env_var: str = _ENV_VAR) -> Fernet:
25
+ def get_fernet(env_var: str = _ENV_VAR, /) -> Fernet:
26
26
  """Get the Fernet key."""
27
27
  if (key := getenv(env_var)) is None:
28
28
  raise GetFernetError(env_var=env_var)
utilities/eventkit.py CHANGED
@@ -29,12 +29,12 @@ from eventkit import (
29
29
 
30
30
  from utilities.functions import apply_decorators
31
31
  from utilities.iterables import always_iterable
32
- from utilities.logging import get_logger
32
+ from utilities.logging import to_logger
33
33
 
34
34
  if TYPE_CHECKING:
35
35
  from collections.abc import Callable
36
36
 
37
- from utilities.types import Coro, LoggerOrName, MaybeCoro, MaybeIterable, TypeLike
37
+ from utilities.types import Coro, LoggerLike, MaybeCoro, MaybeIterable, TypeLike
38
38
 
39
39
 
40
40
  ##
@@ -47,7 +47,7 @@ def add_listener[E: Event, F: Callable](
47
47
  *,
48
48
  error: Callable[[Event, BaseException], MaybeCoro[None]] | None = None,
49
49
  ignore: TypeLike[BaseException] | None = None,
50
- logger: LoggerOrName | None = None,
50
+ logger: LoggerLike | None = None,
51
51
  decorators: MaybeIterable[Callable[[F], F]] | None = None,
52
52
  done: Callable[..., MaybeCoro[None]] | None = None,
53
53
  keep_ref: bool = False,
@@ -92,7 +92,7 @@ class LiftedEvent[F: Callable[..., MaybeCoro[None]]]:
92
92
  *,
93
93
  error: Callable[[Event, BaseException], MaybeCoro[None]] | None = None,
94
94
  ignore: TypeLike[BaseException] | None = None,
95
- logger: LoggerOrName | None = None,
95
+ logger: LoggerLike | None = None,
96
96
  decorators: MaybeIterable[Callable[[F2], F2]] | None = None,
97
97
  done: Callable[..., MaybeCoro[None]] | None = None,
98
98
  keep_ref: bool = False,
@@ -255,7 +255,7 @@ class TypedEvent[F: Callable[..., MaybeCoro[None]]](Event):
255
255
  keep_ref: bool = False,
256
256
  *,
257
257
  ignore: TypeLike[BaseException] | None = None,
258
- logger: LoggerOrName | None = None,
258
+ logger: LoggerLike | None = None,
259
259
  decorators: MaybeIterable[Callable[[F2], F2]] | None = None,
260
260
  ) -> Self:
261
261
  lifted = lift_listener(
@@ -283,7 +283,7 @@ def lift_listener[F1: Callable[..., MaybeCoro[None]], F2: Callable](
283
283
  *,
284
284
  error: Callable[[Event, BaseException], MaybeCoro[None]] | None = None,
285
285
  ignore: TypeLike[BaseException] | None = None,
286
- logger: LoggerOrName | None = None,
286
+ logger: LoggerLike | None = None,
287
287
  decorators: MaybeIterable[Callable[[F2], F2]] | None = None,
288
288
  ) -> F1:
289
289
  match error, bool(iscoroutinefunction(listener)):
@@ -297,7 +297,7 @@ def lift_listener[F1: Callable[..., MaybeCoro[None]], F2: Callable](
297
297
  except Exception as exc: # noqa: BLE001
298
298
  if (ignore is not None) and isinstance(exc, ignore):
299
299
  return
300
- get_logger(logger=logger).exception("")
300
+ to_logger(logger).exception("")
301
301
 
302
302
  lifted = listener_no_error_sync
303
303
 
@@ -311,7 +311,7 @@ def lift_listener[F1: Callable[..., MaybeCoro[None]], F2: Callable](
311
311
  except Exception as exc: # noqa: BLE001
312
312
  if (ignore is not None) and isinstance(exc, ignore):
313
313
  return
314
- get_logger(logger=logger).exception("")
314
+ to_logger(logger).exception("")
315
315
 
316
316
  lifted = listener_no_error_async
317
317
  case _, _:
utilities/functions.py CHANGED
@@ -14,16 +14,7 @@ from types import (
14
14
  MethodWrapperType,
15
15
  WrapperDescriptorType,
16
16
  )
17
- from typing import (
18
- TYPE_CHECKING,
19
- Any,
20
- Literal,
21
- TypeGuard,
22
- assert_never,
23
- cast,
24
- overload,
25
- override,
26
- )
17
+ from typing import TYPE_CHECKING, Any, Literal, TypeGuard, cast, overload, override
27
18
 
28
19
  from whenever import Date, PlainDateTime, Time, TimeDelta, ZonedDateTime
29
20
 
@@ -31,7 +22,6 @@ from utilities.reprlib import get_repr, get_repr_and_class
31
22
  from utilities.sentinel import Sentinel, sentinel
32
23
  from utilities.types import (
33
24
  Dataclass,
34
- MaybeCallableBool,
35
25
  Number,
36
26
  StrMapping,
37
27
  SupportsRichComparison,
@@ -945,28 +935,6 @@ def second[U](pair: tuple[Any, U], /) -> U:
945
935
  ##
946
936
 
947
937
 
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 never:
964
- assert_never(never)
965
-
966
-
967
- ##
968
-
969
-
970
938
  def yield_object_attributes(
971
939
  obj: Any,
972
940
  /,
utilities/logging.py CHANGED
@@ -37,7 +37,7 @@ from utilities.atomicwrites import move_many
37
37
  from utilities.dataclasses import replace_non_sentinel
38
38
  from utilities.errors import ImpossibleCaseError
39
39
  from utilities.iterables import OneEmptyError, always_iterable, one
40
- from utilities.pathlib import ensure_suffix, get_path
40
+ from utilities.pathlib import ensure_suffix, to_path
41
41
  from utilities.re import (
42
42
  ExtractGroupError,
43
43
  ExtractGroupsError,
@@ -59,7 +59,7 @@ if TYPE_CHECKING:
59
59
  from logging import _FilterType
60
60
 
61
61
  from utilities.types import (
62
- LoggerOrName,
62
+ LoggerLike,
63
63
  LogLevel,
64
64
  MaybeCallablePathLike,
65
65
  MaybeIterable,
@@ -87,7 +87,7 @@ def add_filters(handler: Handler, /, *filters: _FilterType) -> None:
87
87
 
88
88
  def basic_config(
89
89
  *,
90
- obj: LoggerOrName | Handler | None = None,
90
+ obj: LoggerLike | Handler | None = None,
91
91
  format_: str | None = None,
92
92
  prefix: str | None = None,
93
93
  hostname: bool = False,
@@ -121,7 +121,7 @@ def basic_config(
121
121
  )
122
122
  case str() as name:
123
123
  basic_config(
124
- obj=get_logger(logger=name),
124
+ obj=to_logger(name),
125
125
  format_=format_,
126
126
  prefix=prefix,
127
127
  hostname=hostname,
@@ -268,20 +268,6 @@ def _get_plain_formatter(
268
268
  ##
269
269
 
270
270
 
271
- def get_logger(*, logger: LoggerOrName | None = None) -> Logger:
272
- """Get a logger."""
273
- match logger:
274
- case Logger():
275
- return logger
276
- case str() | None:
277
- return getLogger(logger)
278
- case never:
279
- assert_never(never)
280
-
281
-
282
- ##
283
-
284
-
285
271
  def get_logging_level_number(level: LogLevel, /) -> int:
286
272
  """Get the logging level number."""
287
273
  mapping = getLevelNamesMapping()
@@ -305,13 +291,13 @@ class GetLoggingLevelNumberError(Exception):
305
291
 
306
292
  def setup_logging(
307
293
  *,
308
- logger: LoggerOrName | None = None,
294
+ logger: LoggerLike | None = None,
309
295
  format_: str | None = None,
310
296
  datefmt: str = _DEFAULT_DATEFMT,
311
297
  console_level: LogLevel = "INFO",
312
298
  console_prefix: str = "❯", # noqa: RUF001
313
299
  console_filters: MaybeIterable[_FilterType] | None = None,
314
- files_dir: MaybeCallablePathLike | None = None,
300
+ files_dir: MaybeCallablePathLike = Path.cwd,
315
301
  files_max_bytes: int = _DEFAULT_MAX_BYTES,
316
302
  files_when: _When = _DEFAULT_WHEN,
317
303
  files_interval: int = 1,
@@ -327,15 +313,14 @@ def setup_logging(
327
313
  level=console_level,
328
314
  filters=console_filters,
329
315
  )
330
- logger_use = get_logger(logger=logger)
316
+ logger_use = to_logger(logger)
331
317
  name = logger_use.name
332
- dir_ = get_path(path=files_dir)
333
318
  levels: list[LogLevel] = ["DEBUG", "INFO", "ERROR"]
334
319
  for level in levels:
335
320
  lower = level.lower()
336
321
  for stem in [lower, f"{name}-{lower}"]:
337
322
  handler = SizeAndTimeRotatingFileHandler(
338
- dir_.joinpath(stem).with_suffix(".txt"),
323
+ to_path(files_dir).joinpath(stem).with_suffix(".txt"),
339
324
  maxBytes=files_max_bytes,
340
325
  when=files_when,
341
326
  interval=files_interval,
@@ -626,6 +611,20 @@ class _Rotation:
626
611
  return self.file.replace(index=self.index, start=self.start, end=self.end).path
627
612
 
628
613
 
614
+ ##
615
+
616
+
617
+ def to_logger(logger: LoggerLike | None = None, /) -> Logger:
618
+ """Convert to a logger."""
619
+ match logger:
620
+ case Logger():
621
+ return logger
622
+ case str() | None:
623
+ return getLogger(logger)
624
+ case never:
625
+ assert_never(never)
626
+
627
+
629
628
  __all__ = [
630
629
  "FilterForKeyError",
631
630
  "GetLoggingLevelNumberError",
@@ -634,7 +633,7 @@ __all__ = [
634
633
  "basic_config",
635
634
  "filter_for_key",
636
635
  "get_format_str",
637
- "get_logger",
638
636
  "get_logging_level_number",
639
637
  "setup_logging",
638
+ "to_logger",
640
639
  ]
utilities/pathlib.py CHANGED
@@ -12,7 +12,7 @@ from typing import TYPE_CHECKING, Literal, assert_never, overload, override
12
12
 
13
13
  from utilities.contextlib import enhanced_context_manager
14
14
  from utilities.errors import ImpossibleCaseError
15
- from utilities.sentinel import Sentinel, sentinel
15
+ from utilities.sentinel import Sentinel
16
16
 
17
17
  if TYPE_CHECKING:
18
18
  from collections.abc import Iterator, Sequence
@@ -52,33 +52,9 @@ def expand_path(path: PathLike, /) -> Path:
52
52
  ##
53
53
 
54
54
 
55
- @overload
56
- def get_path(*, path: MaybeCallablePathLike | None) -> Path: ...
57
- @overload
58
- def get_path(*, path: Sentinel) -> Sentinel: ...
59
- def get_path(
60
- *, path: MaybeCallablePathLike | None | Sentinel = sentinel
61
- ) -> Path | None | Sentinel:
62
- """Get the path."""
63
- match path:
64
- case Path() | Sentinel():
65
- return path
66
- case str():
67
- return Path(path)
68
- case None:
69
- return Path.cwd()
70
- case Callable() as func:
71
- return get_path(path=func())
72
- case never:
73
- assert_never(never)
74
-
75
-
76
- ##
77
-
78
-
79
- def get_package_root(*, path: MaybeCallablePathLike | None = None) -> Path:
55
+ def get_package_root(path: MaybeCallablePathLike = Path.cwd, /) -> Path:
80
56
  """Get the package root."""
81
- path = get_path(path=path)
57
+ path = to_path(path)
82
58
  path_dir = path.parent if path.is_file() else path
83
59
  all_paths = list(chain([path_dir], path_dir.parents))
84
60
  try:
@@ -103,9 +79,9 @@ class GetPackageRootError(Exception):
103
79
  ##
104
80
 
105
81
 
106
- def get_repo_root(*, path: MaybeCallablePathLike | None = None) -> Path:
82
+ def get_repo_root(path: MaybeCallablePathLike = Path.cwd, /) -> Path:
107
83
  """Get the repo root."""
108
- path = get_path(path=path)
84
+ path = to_path(path)
109
85
  path_dir = path.parent if path.is_file() else path
110
86
  try:
111
87
  output = check_output(
@@ -136,15 +112,15 @@ class GetRepoRootError(Exception):
136
112
  ##
137
113
 
138
114
 
139
- def get_root(*, path: MaybeCallablePathLike | None = None) -> Path:
115
+ def get_root(path: MaybeCallablePathLike = Path.cwd, /) -> Path:
140
116
  """Get the root of a path."""
141
- path = get_path(path=path)
117
+ path = to_path(path)
142
118
  try:
143
- repo = get_repo_root(path=path)
119
+ repo = get_repo_root(path)
144
120
  except GetRepoRootError:
145
121
  repo = None
146
122
  try:
147
- package = get_package_root(path=path)
123
+ package = get_package_root(path)
148
124
  except GetPackageRootError:
149
125
  package = None
150
126
  match repo, package:
@@ -305,6 +281,30 @@ def temp_cwd(path: PathLike, /) -> Iterator[None]:
305
281
  chdir(prev)
306
282
 
307
283
 
284
+ ##
285
+
286
+
287
+ @overload
288
+ def to_path(path: Sentinel, /) -> Sentinel: ...
289
+ @overload
290
+ def to_path(path: MaybeCallablePathLike | None = Path.cwd, /) -> Path: ...
291
+ def to_path(
292
+ path: MaybeCallablePathLike | None | Sentinel = Path.cwd, /
293
+ ) -> Path | Sentinel:
294
+ """Get the path."""
295
+ match path:
296
+ case Path() | Sentinel():
297
+ return path
298
+ case None:
299
+ return Path.cwd()
300
+ case str():
301
+ return Path(path)
302
+ case Callable() as func:
303
+ return to_path(func())
304
+ case never:
305
+ assert_never(never)
306
+
307
+
308
308
  __all__ = [
309
309
  "PWD",
310
310
  "GetPackageRootError",
@@ -313,11 +313,11 @@ __all__ = [
313
313
  "ensure_suffix",
314
314
  "expand_path",
315
315
  "get_package_root",
316
- "get_path",
317
316
  "get_repo_root",
318
317
  "get_tail",
319
318
  "is_sub_path",
320
319
  "list_dir",
321
320
  "module_path",
322
321
  "temp_cwd",
322
+ "to_path",
323
323
  ]