dycw-utilities 0.152.0__py3-none-any.whl → 0.153.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.
utilities/postgres.py CHANGED
@@ -10,7 +10,7 @@ from sqlalchemy.orm import DeclarativeBase
10
10
 
11
11
  from utilities.asyncio import stream_command
12
12
  from utilities.iterables import always_iterable
13
- from utilities.logging import get_logger
13
+ from utilities.logging import to_logger
14
14
  from utilities.os import temp_environ
15
15
  from utilities.pathlib import ensure_suffix
16
16
  from utilities.sqlalchemy import extract_url, get_table_name
@@ -22,7 +22,7 @@ if TYPE_CHECKING:
22
22
 
23
23
  from utilities.sqlalchemy import TableOrORMInstOrClass
24
24
  from utilities.types import (
25
- LoggerOrName,
25
+ LoggerLike,
26
26
  MaybeCollection,
27
27
  MaybeCollectionStr,
28
28
  PathLike,
@@ -53,7 +53,7 @@ async def pg_dump(
53
53
  role: str | None = None,
54
54
  docker: str | None = None,
55
55
  dry_run: bool = False,
56
- logger: LoggerOrName | None = None,
56
+ logger: LoggerLike | None = None,
57
57
  ) -> None:
58
58
  """Run `pg_dump`."""
59
59
  path = _path_pg_dump(path, format_=format_)
@@ -79,14 +79,14 @@ async def pg_dump(
79
79
  )
80
80
  if dry_run:
81
81
  if logger is not None:
82
- get_logger(logger=logger).info("Would run:\n\t%r", str(cmd))
82
+ to_logger(logger).info("Would run:\n\t%r", str(cmd))
83
83
  return
84
84
  with temp_environ(PGPASSWORD=url.password), Timer() as timer: # pragma: no cover
85
85
  try:
86
86
  output = await stream_command(cmd)
87
87
  except KeyboardInterrupt:
88
88
  if logger is not None:
89
- get_logger(logger=logger).info(
89
+ to_logger(logger).info(
90
90
  "Cancelled backup to %r after %s", str(path), timer
91
91
  )
92
92
  rmtree(path, ignore_errors=True)
@@ -94,12 +94,12 @@ async def pg_dump(
94
94
  match output.return_code:
95
95
  case 0:
96
96
  if logger is not None:
97
- get_logger(logger=logger).info(
97
+ to_logger(logger).info(
98
98
  "Backup to %r finished after %s", str(path), timer
99
99
  )
100
100
  case _:
101
101
  if logger is not None:
102
- get_logger(logger=logger).exception(
102
+ to_logger(logger).exception(
103
103
  "Backup to %r failed after %s\nstderr:\n%s",
104
104
  str(path),
105
105
  timer,
@@ -217,7 +217,7 @@ async def restore(
217
217
  role: str | None = None,
218
218
  docker: str | None = None,
219
219
  dry_run: bool = False,
220
- logger: LoggerOrName | None = None,
220
+ logger: LoggerLike | None = None,
221
221
  ) -> None:
222
222
  """Run `pg_restore`/`psql`."""
223
223
  cmd = _build_pg_restore_or_psql(
@@ -236,26 +236,26 @@ async def restore(
236
236
  )
237
237
  if dry_run:
238
238
  if logger is not None:
239
- get_logger(logger=logger).info("Would run:\n\t%r", str(cmd))
239
+ to_logger(logger).info("Would run:\n\t%r", str(cmd))
240
240
  return
241
241
  with temp_environ(PGPASSWORD=url.password), Timer() as timer: # pragma: no cover
242
242
  try:
243
243
  output = await stream_command(cmd)
244
244
  except KeyboardInterrupt:
245
245
  if logger is not None:
246
- get_logger(logger=logger).info(
246
+ to_logger(logger).info(
247
247
  "Cancelled restore from %r after %s", str(path), timer
248
248
  )
249
249
  else:
250
250
  match output.return_code:
251
251
  case 0:
252
252
  if logger is not None:
253
- get_logger(logger=logger).info(
253
+ to_logger(logger).info(
254
254
  "Restore from %r finished after %s", str(path), timer
255
255
  )
256
256
  case _:
257
257
  if logger is not None:
258
- get_logger(logger=logger).exception(
258
+ to_logger(logger).exception(
259
259
  "Restore from %r failed after %s\nstderr:\n%s",
260
260
  str(path),
261
261
  timer,
utilities/pottery.py CHANGED
@@ -14,7 +14,7 @@ from utilities.asyncio import loop_until_succeed, sleep_td, timeout_td
14
14
  from utilities.contextlib import enhanced_async_context_manager
15
15
  from utilities.contextvars import yield_set_context
16
16
  from utilities.iterables import always_iterable
17
- from utilities.logging import get_logger
17
+ from utilities.logging import to_logger
18
18
  from utilities.whenever import MILLISECOND, SECOND, to_seconds
19
19
 
20
20
  if TYPE_CHECKING:
@@ -23,7 +23,7 @@ if TYPE_CHECKING:
23
23
 
24
24
  from whenever import Delta
25
25
 
26
- from utilities.types import Coro, LoggerOrName, MaybeIterable
26
+ from utilities.types import Coro, LoggerLike, MaybeIterable
27
27
 
28
28
  _NUM: int = 1
29
29
  _TIMEOUT_TRY_ACQUIRE: Delta = SECOND
@@ -57,7 +57,7 @@ async def try_yield_coroutine_looper(
57
57
  timeout_acquire: Delta = _TIMEOUT_TRY_ACQUIRE,
58
58
  sleep_acquire: Delta = _SLEEP,
59
59
  throttle: Delta | None = None,
60
- logger: LoggerOrName | None = None,
60
+ logger: LoggerLike | None = None,
61
61
  sleep_error: Delta | None = None,
62
62
  context: ContextVar[bool] | None = None,
63
63
  ) -> AsyncIterator[CoroutineLooper | None]:
@@ -81,7 +81,7 @@ async def try_yield_coroutine_looper(
81
81
  yield looper
82
82
  except _YieldAccessUnableToAcquireLockError as error: # skipif-ci-and-not-linux
83
83
  if logger is not None:
84
- get_logger(logger=logger).info("%s", error)
84
+ to_logger(logger).info("%s", error)
85
85
  async with nullcontext():
86
86
  yield
87
87
 
@@ -91,7 +91,7 @@ class CoroutineLooper:
91
91
  """Looper, guarded by a lock, to repeatedly call a coroutine until it succeeds."""
92
92
 
93
93
  lock: AIORedlock
94
- logger: LoggerOrName | None = None
94
+ logger: LoggerLike | None = None
95
95
  sleep: Delta | None = None
96
96
 
97
97
  async def __call__[**P](
utilities/pyinstrument.py CHANGED
@@ -7,7 +7,7 @@ from typing import TYPE_CHECKING
7
7
  from pyinstrument.profiler import Profiler
8
8
 
9
9
  from utilities.atomicwrites import writer
10
- from utilities.pathlib import get_path
10
+ from utilities.pathlib import to_path
11
11
  from utilities.whenever import format_compact, get_now, to_local_plain
12
12
 
13
13
  if TYPE_CHECKING:
@@ -17,11 +17,11 @@ if TYPE_CHECKING:
17
17
 
18
18
 
19
19
  @contextmanager
20
- def profile(*, path: MaybeCallablePathLike | None = Path.cwd) -> Iterator[None]:
20
+ def profile(path: MaybeCallablePathLike = Path.cwd, /) -> Iterator[None]:
21
21
  """Profile the contents of a block."""
22
22
  with Profiler() as profiler:
23
23
  yield
24
- filename = get_path(path=path).joinpath(
24
+ filename = to_path(path).joinpath(
25
25
  f"profile__{format_compact(to_local_plain(get_now()))}.html"
26
26
  )
27
27
  with writer(filename) as temp:
utilities/pytest.py CHANGED
@@ -173,7 +173,7 @@ def _throttle_inner[F: Callable[..., MaybeCoro[None]]](
173
173
  def throttle_sync_on_pass(*args: Any, **kwargs: Any) -> None:
174
174
  _skipif_recent(root=root, delta=delta)
175
175
  cast("Callable[..., None]", func)(*args, **kwargs)
176
- _write(root=root)
176
+ _write(root)
177
177
 
178
178
  return cast("Any", throttle_sync_on_pass)
179
179
 
@@ -182,7 +182,7 @@ def _throttle_inner[F: Callable[..., MaybeCoro[None]]](
182
182
  @wraps(func)
183
183
  def throttle_sync_on_try(*args: Any, **kwargs: Any) -> None:
184
184
  _skipif_recent(root=root, delta=delta)
185
- _write(root=root)
185
+ _write(root)
186
186
  cast("Callable[..., None]", func)(*args, **kwargs)
187
187
 
188
188
  return cast("Any", throttle_sync_on_try)
@@ -193,7 +193,7 @@ def _throttle_inner[F: Callable[..., MaybeCoro[None]]](
193
193
  async def throttle_async_on_pass(*args: Any, **kwargs: Any) -> None:
194
194
  _skipif_recent(root=root, delta=delta)
195
195
  await cast("Callable[..., Coro[None]]", func)(*args, **kwargs)
196
- _write(root=root)
196
+ _write(root)
197
197
 
198
198
  return cast("Any", throttle_async_on_pass)
199
199
 
@@ -202,7 +202,7 @@ def _throttle_inner[F: Callable[..., MaybeCoro[None]]](
202
202
  @wraps(func)
203
203
  async def throttle_async_on_try(*args: Any, **kwargs: Any) -> None:
204
204
  _skipif_recent(root=root, delta=delta)
205
- _write(root=root)
205
+ _write(root)
206
206
  await cast("Callable[..., Coro[None]]", func)(*args, **kwargs)
207
207
 
208
208
  return cast("Any", throttle_async_on_try)
@@ -214,7 +214,7 @@ def _throttle_inner[F: Callable[..., MaybeCoro[None]]](
214
214
  def _skipif_recent(*, root: PathLike | None = None, delta: Delta = SECOND) -> None:
215
215
  if skip is None:
216
216
  return # pragma: no cover
217
- path = _get_path(root=root)
217
+ path = _get_path(root)
218
218
  try:
219
219
  contents = path.read_text()
220
220
  except FileNotFoundError:
@@ -229,7 +229,7 @@ def _skipif_recent(*, root: PathLike | None = None, delta: Delta = SECOND) -> No
229
229
  _ = skip(reason=f"{_get_name()} throttled (age {age})")
230
230
 
231
231
 
232
- def _get_path(*, root: PathLike | None = None) -> Path:
232
+ def _get_path(root: PathLike | None = None, /) -> Path:
233
233
  if root is None:
234
234
  root_use = get_root().joinpath(".pytest_cache", "throttle") # pragma: no cover
235
235
  else:
@@ -246,8 +246,8 @@ def _get_name() -> str:
246
246
  return environ["PYTEST_CURRENT_TEST"]
247
247
 
248
248
 
249
- def _write(*, root: PathLike | None = None) -> None:
250
- path = _get_path(root=root)
249
+ def _write(root: PathLike | None = None, /) -> None:
250
+ path = _get_path(root)
251
251
  with writer(path, overwrite=True) as temp:
252
252
  _ = temp.write_text(get_now_local().format_common_iso())
253
253
 
@@ -17,7 +17,7 @@ else:
17
17
  """Fixture for a random state."""
18
18
  from utilities.random import get_state
19
19
 
20
- return get_state(seed=seed)
20
+ return get_state(seed)
21
21
 
22
22
 
23
23
  __all__ = ["random_state"]
@@ -46,7 +46,7 @@ def _get_path(request: FixtureRequest, /) -> Path:
46
46
  path = Path(cast("Any", request).fspath)
47
47
  root = Path("src", "tests")
48
48
  tail = node_id_path(request.node.nodeid, root=root)
49
- return get_root(path=path).joinpath(root, "regressions", tail)
49
+ return get_root(path).joinpath(root, "regressions", tail)
50
50
 
51
51
 
52
52
  __all__ = ["orjson_regression", "polars_regression"]
utilities/random.py CHANGED
@@ -17,16 +17,16 @@ SYSTEM_RANDOM = SystemRandom()
17
17
 
18
18
  def bernoulli(*, true: float = 0.5, seed: Seed | None = None) -> bool:
19
19
  """Return a Bernoulli random variate."""
20
- seed = get_state(seed=seed)
21
- return bool(seed.binomialvariate(p=true))
20
+ state = get_state(seed)
21
+ return bool(state.binomialvariate(p=true))
22
22
 
23
23
 
24
24
  ##
25
25
 
26
26
 
27
- def get_docker_name(*, seed: Seed | None = None) -> str:
27
+ def get_docker_name(seed: Seed | None = None, /) -> str:
28
28
  """Get a docker name."""
29
- state = get_state(seed=seed)
29
+ state = get_state(seed)
30
30
  prefix = state.choice(_DOCKER_PREFIXES)
31
31
  suffix = state.choice(_DOCKER_SUFFIXES)
32
32
  digit = state.randint(0, 9)
@@ -47,16 +47,18 @@ _DOCKER_SUFFIXES = [
47
47
  ##
48
48
 
49
49
 
50
- def get_state(*, seed: Seed | None = None) -> Random:
50
+ def get_state(seed: Seed | None = None, /) -> Random:
51
51
  """Get a random state."""
52
52
  return seed if isinstance(seed, Random) else Random(x=seed)
53
53
 
54
54
 
55
55
  ##
56
+
57
+
56
58
  def shuffle[T](iterable: Iterable[T], /, *, seed: Seed | None = None) -> list[T]:
57
59
  """Shuffle an iterable."""
58
60
  copy = list(iterable).copy()
59
- state = get_state(seed=seed)
61
+ state = get_state(seed)
60
62
  state.shuffle(copy)
61
63
  return copy
62
64
 
utilities/text.py CHANGED
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import re
4
4
  from collections import deque
5
+ from collections.abc import Callable
5
6
  from dataclasses import dataclass
6
7
  from itertools import chain
7
8
  from os import getpid
@@ -9,16 +10,25 @@ from re import IGNORECASE, Match, escape, search
9
10
  from textwrap import dedent
10
11
  from threading import get_ident
11
12
  from time import time_ns
12
- from typing import TYPE_CHECKING, Any, ClassVar, Literal, overload, override
13
+ from typing import (
14
+ TYPE_CHECKING,
15
+ Any,
16
+ ClassVar,
17
+ Literal,
18
+ assert_never,
19
+ overload,
20
+ override,
21
+ )
13
22
  from uuid import uuid4
14
23
 
15
24
  from utilities.iterables import CheckDuplicatesError, check_duplicates, transpose
16
25
  from utilities.reprlib import get_repr
26
+ from utilities.sentinel import Sentinel
17
27
 
18
28
  if TYPE_CHECKING:
19
29
  from collections.abc import Iterable, Mapping, Sequence
20
30
 
21
- from utilities.types import StrStrMapping
31
+ from utilities.types import MaybeCallableBoolLike, StrStrMapping
22
32
 
23
33
 
24
34
  DEFAULT_SEPARATOR = ","
@@ -428,6 +438,30 @@ def strip_and_dedent(text: str, /, *, trailing: bool = False) -> str:
428
438
  ##
429
439
 
430
440
 
441
+ @overload
442
+ def to_bool(bool_: MaybeCallableBoolLike, /) -> bool: ...
443
+ @overload
444
+ def to_bool(bool_: None, /) -> None: ...
445
+ @overload
446
+ def to_bool(bool_: Sentinel, /) -> Sentinel: ...
447
+ def to_bool(
448
+ bool_: MaybeCallableBoolLike | None | Sentinel, /
449
+ ) -> bool | None | Sentinel:
450
+ """Convert to a bool."""
451
+ match bool_:
452
+ case bool() | None | Sentinel():
453
+ return bool_
454
+ case str():
455
+ return parse_bool(bool_)
456
+ case Callable() as func:
457
+ return to_bool(func())
458
+ case never:
459
+ assert_never(never)
460
+
461
+
462
+ ##
463
+
464
+
431
465
  def unique_str() -> str:
432
466
  """Generate at unique string."""
433
467
  now = time_ns()
@@ -456,5 +490,6 @@ __all__ = [
456
490
  "split_str",
457
491
  "str_encode",
458
492
  "strip_and_dedent",
493
+ "to_bool",
459
494
  "unique_str",
460
495
  ]
utilities/traceback.py CHANGED
@@ -15,9 +15,8 @@ from typing import TYPE_CHECKING, override
15
15
 
16
16
  from utilities.atomicwrites import writer
17
17
  from utilities.errors import repr_error
18
- from utilities.functions import to_bool
19
18
  from utilities.iterables import OneEmptyError, one
20
- from utilities.pathlib import get_path, module_path
19
+ from utilities.pathlib import module_path, to_path
21
20
  from utilities.reprlib import (
22
21
  RICH_EXPAND_ALL,
23
22
  RICH_INDENT_SIZE,
@@ -27,8 +26,9 @@ from utilities.reprlib import (
27
26
  RICH_MAX_WIDTH,
28
27
  yield_mapping_repr,
29
28
  )
29
+ from utilities.text import to_bool
30
30
  from utilities.tzlocal import LOCAL_TIME_ZONE_NAME
31
- from utilities.version import get_version
31
+ from utilities.version import to_version
32
32
  from utilities.whenever import (
33
33
  format_compact,
34
34
  get_now,
@@ -43,9 +43,9 @@ if TYPE_CHECKING:
43
43
  from types import TracebackType
44
44
 
45
45
  from utilities.types import (
46
- MaybeCallableBool,
46
+ MaybeCallableBoolLike,
47
47
  MaybeCallablePathLike,
48
- MaybeCallableZonedDateTime,
48
+ MaybeCallableZonedDateTimeLike,
49
49
  PathLike,
50
50
  )
51
51
  from utilities.version import MaybeCallableVersionLike
@@ -54,15 +54,12 @@ if TYPE_CHECKING:
54
54
  ##
55
55
 
56
56
 
57
- _START = get_now()
58
-
59
-
60
57
  def format_exception_stack(
61
58
  error: BaseException,
62
59
  /,
63
60
  *,
64
61
  header: bool = False,
65
- start: MaybeCallableZonedDateTime | None = _START,
62
+ start: MaybeCallableZonedDateTimeLike = get_now,
66
63
  version: MaybeCallableVersionLike | None = None,
67
64
  capture_locals: bool = False,
68
65
  max_width: int = RICH_MAX_WIDTH,
@@ -93,12 +90,12 @@ def format_exception_stack(
93
90
 
94
91
  def _yield_header_lines(
95
92
  *,
96
- start: MaybeCallableZonedDateTime | None = _START,
93
+ start: MaybeCallableZonedDateTimeLike = get_now,
97
94
  version: MaybeCallableVersionLike | None = None,
98
95
  ) -> Iterator[str]:
99
96
  """Yield the header lines."""
100
97
  now = get_now_local()
101
- start_use = to_zoned_date_time(date_time=start)
98
+ start_use = to_zoned_date_time(start)
102
99
  yield f"Date/time | {format_compact(now)}"
103
100
  if start_use is None:
104
101
  start_str = ""
@@ -111,7 +108,7 @@ def _yield_header_lines(
111
108
  yield f"User | {getuser()}"
112
109
  yield f"Host | {gethostname()}"
113
110
  yield f"Process ID | {getpid()}"
114
- version_use = "" if version is None else get_version(version=version)
111
+ version_use = "" if version is None else to_version(version)
115
112
  yield f"Version | {version_use}"
116
113
  yield ""
117
114
 
@@ -205,7 +202,7 @@ def _trim_path(path: PathLike, pattern: str, /) -> Path | None:
205
202
 
206
203
  def make_except_hook(
207
204
  *,
208
- start: MaybeCallableZonedDateTime | None = _START,
205
+ start: MaybeCallableZonedDateTimeLike = get_now,
209
206
  version: MaybeCallableVersionLike | None = None,
210
207
  path: MaybeCallablePathLike | None = None,
211
208
  max_width: int = RICH_MAX_WIDTH,
@@ -215,7 +212,7 @@ def make_except_hook(
215
212
  max_depth: int | None = RICH_MAX_DEPTH,
216
213
  expand_all: bool = RICH_EXPAND_ALL,
217
214
  slack_url: str | None = None,
218
- pudb: MaybeCallableBool = False,
215
+ pudb: MaybeCallableBoolLike = False,
219
216
  ) -> Callable[
220
217
  [type[BaseException] | None, BaseException | None, TracebackType | None], None
221
218
  ]:
@@ -242,7 +239,7 @@ def _make_except_hook_inner(
242
239
  traceback: TracebackType | None,
243
240
  /,
244
241
  *,
245
- start: MaybeCallableZonedDateTime | None = _START,
242
+ start: MaybeCallableZonedDateTimeLike = get_now,
246
243
  version: MaybeCallableVersionLike | None = None,
247
244
  path: MaybeCallablePathLike | None = None,
248
245
  max_width: int = RICH_MAX_WIDTH,
@@ -252,7 +249,7 @@ def _make_except_hook_inner(
252
249
  max_depth: int | None = RICH_MAX_DEPTH,
253
250
  expand_all: bool = RICH_EXPAND_ALL,
254
251
  slack_url: str | None = None,
255
- pudb: MaybeCallableBool = False,
252
+ pudb: MaybeCallableBoolLike = False,
256
253
  ) -> None:
257
254
  """Exception hook to log the traceback."""
258
255
  _ = (exc_type, traceback)
@@ -262,7 +259,7 @@ def _make_except_hook_inner(
262
259
  _ = sys.stderr.write(f"{slim}\n") # don't 'from sys import stderr'
263
260
  if path is not None:
264
261
  path = (
265
- get_path(path=path)
262
+ to_path(path)
266
263
  .joinpath(format_compact(to_local_plain(get_now())))
267
264
  .with_suffix(".txt")
268
265
  )
@@ -289,7 +286,7 @@ def _make_except_hook_inner(
289
286
  except SendToSlackError as error:
290
287
  _ = stderr.write(f"{error}\n")
291
288
 
292
- if to_bool(bool_=pudb): # pragma: no cover
289
+ if to_bool(pudb): # pragma: no cover
293
290
  from pudb import post_mortem
294
291
 
295
292
  post_mortem(tb=traceback, e_type=exc_type, e_value=exc_val)
@@ -26,7 +26,7 @@ from whenever import (
26
26
  )
27
27
 
28
28
  from utilities.iterables import always_iterable
29
- from utilities.pathlib import get_path
29
+ from utilities.pathlib import to_path
30
30
  from utilities.string import substitute_environ
31
31
 
32
32
  if TYPE_CHECKING:
@@ -86,12 +86,12 @@ def _make_converter[T](
86
86
 
87
87
 
88
88
  def _parse_path(
89
- path: str, /, *, resolve: bool = False, pwd: MaybeCallablePathLike | None = None
89
+ path: str, /, *, resolve: bool = False, pwd: MaybeCallablePathLike = Path.cwd
90
90
  ) -> Path:
91
91
  path = substitute_environ(path, **environ)
92
92
  match resolve:
93
93
  case True:
94
- return get_path(path=pwd).joinpath(path).resolve()
94
+ return to_path(pwd).joinpath(path).resolve()
95
95
  case False:
96
96
  return Path(path)
97
97
  case never:
utilities/types.py CHANGED
@@ -1,7 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import datetime as dt
4
- from asyncio import Event
5
4
  from collections.abc import Callable, Collection, Coroutine, Iterable, Mapping
6
5
  from enum import Enum
7
6
  from ipaddress import IPv4Address, IPv6Address
@@ -19,6 +18,7 @@ from typing import (
19
18
  overload,
20
19
  runtime_checkable,
21
20
  )
21
+ from uuid import UUID
22
22
  from zoneinfo import ZoneInfo
23
23
 
24
24
  from whenever import (
@@ -39,6 +39,7 @@ _T_contra = TypeVar("_T_contra", contravariant=True)
39
39
 
40
40
 
41
41
  # basic
42
+ type BoolLike = MaybeStr[bool]
42
43
  type OpenMode = Literal[
43
44
  "r",
44
45
  "w",
@@ -62,8 +63,7 @@ type OpenMode = Literal[
62
63
  "a+b",
63
64
  ]
64
65
  type MaybeCallable[T] = T | Callable[[], T]
65
- type MaybeCallableBool = MaybeCallable[bool]
66
- type MaybeCallableStr = MaybeCallable[str]
66
+ type MaybeCallableBoolLike = MaybeCallable[BoolLike]
67
67
  type MaybeStr[T] = T | str
68
68
  type MaybeType[T] = T | type[T]
69
69
  type StrMapping = Mapping[str, Any]
@@ -74,7 +74,6 @@ type TupleOrStrMapping = tuple[Any, ...] | StrMapping
74
74
 
75
75
  # asyncio
76
76
  type Coro[T] = Coroutine[Any, Any, T]
77
- type MaybeCallableEvent = MaybeCallable[Event]
78
77
  type MaybeCoro[T] = T | Coro[T]
79
78
 
80
79
 
@@ -115,10 +114,11 @@ IPv6AddressLike = MaybeStr[IPv6Address]
115
114
 
116
115
 
117
116
  # iterables
117
+ type SequenceLT[T] = list[T] | tuple[T, ...]
118
+ # iterables - maybe
118
119
  type MaybeCollection[T] = T | Collection[T]
119
120
  type MaybeIterable[T] = T | Iterable[T]
120
121
  type MaybeSequence[T] = T | SequenceLT[T]
121
- type SequenceLT[T] = list[T] | tuple[T, ...]
122
122
  # iterables - str
123
123
  type SequenceStr = SequenceLT[str]
124
124
  type CollectionStr = dict[str, Any] | frozenset[str] | set[str] | SequenceStr
@@ -129,7 +129,7 @@ type MaybeSequenceStr = str | SequenceStr
129
129
 
130
130
  # logging
131
131
  type LogLevel = Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
132
- type LoggerOrName = MaybeStr[Logger]
132
+ type LoggerLike = MaybeStr[Logger]
133
133
 
134
134
 
135
135
  # math
@@ -213,8 +213,8 @@ type SerializeObjectExtra = Mapping[Any, Callable[[Any], str]]
213
213
 
214
214
 
215
215
  # pathlib
216
- type MaybeCallablePathLike = MaybeCallable[PathLike]
217
216
  type PathLike = MaybeStr[Path]
217
+ type MaybeCallablePathLike = MaybeCallable[PathLike]
218
218
 
219
219
 
220
220
  # random
@@ -225,11 +225,20 @@ type Seed = int | float | str | bytes | bytearray | Random
225
225
  type PatternLike = MaybeStr[Pattern[str]]
226
226
 
227
227
 
228
+ # text
229
+ type MaybeCallableStr = MaybeCallable[str]
230
+
231
+
228
232
  # traceback
229
233
  type ExcInfo = tuple[type[BaseException], BaseException, TracebackType]
230
234
  type OptExcInfo = ExcInfo | tuple[None, None, None]
231
235
 
232
236
 
237
+ # uuid
238
+ type UUIDLike = MaybeStr[UUID]
239
+ type MaybeCallableUUIDLike = MaybeCallable[UUIDLike | Seed]
240
+
241
+
233
242
  # whenever
234
243
  type DateDeltaLike = MaybeStr[DateDelta]
235
244
  type DateLike = MaybeStr[Date]
@@ -239,8 +248,8 @@ type DateTimeRoundMode = Literal[
239
248
  "ceil", "floor", "half_ceil", "half_floor", "half_even"
240
249
  ]
241
250
  type Delta = DateDelta | TimeDelta | DateTimeDelta
242
- type MaybeCallableDate = MaybeCallable[Date]
243
- type MaybeCallableZonedDateTime = MaybeCallable[ZonedDateTime]
251
+ type MaybeCallableDateLike = MaybeCallable[DateLike]
252
+ type MaybeCallableZonedDateTimeLike = MaybeCallable[ZonedDateTimeLike]
244
253
  type MonthDayLike = MaybeStr[MonthDay]
245
254
  type PlainDateTimeLike = MaybeStr[PlainDateTime]
246
255
  type TimeDeltaLike = MaybeStr[TimeDelta]
@@ -277,15 +286,15 @@ __all__ = [
277
286
  "IPv4AddressLike",
278
287
  "IPv6AddressLike",
279
288
  "LogLevel",
280
- "LoggerOrName",
289
+ "LoggerLike",
281
290
  "MathRoundMode",
282
291
  "MaybeCallable",
283
- "MaybeCallableBool",
284
- "MaybeCallableDate",
285
- "MaybeCallableEvent",
292
+ "MaybeCallableBoolLike",
293
+ "MaybeCallableDateLike",
286
294
  "MaybeCallablePathLike",
287
295
  "MaybeCallableStr",
288
- "MaybeCallableZonedDateTime",
296
+ "MaybeCallableUUIDLike",
297
+ "MaybeCallableZonedDateTimeLike",
289
298
  "MaybeCollection",
290
299
  "MaybeCollectionStr",
291
300
  "MaybeCoro",
@@ -329,6 +338,7 @@ __all__ = [
329
338
  "TimeZoneLike",
330
339
  "TupleOrStrMapping",
331
340
  "TypeLike",
341
+ "UUIDLike",
332
342
  "WeekDay",
333
343
  "YearMonthLike",
334
344
  "ZonedDateTimeLike",