dycw-utilities 0.136.7__py3-none-any.whl → 0.136.9__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.136.7
3
+ Version: 0.136.9
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -1,4 +1,4 @@
1
- utilities/__init__.py,sha256=_gHgMWM-7wftYvG3CuC0fVylv31uuRdfxSdp2fJbITs,60
1
+ utilities/__init__.py,sha256=TfRJ5LJDqhQMm2y-jbpj1oPenJALJoqsiY7i5XiMjcE,60
2
2
  utilities/aiolimiter.py,sha256=mD0wEiqMgwpty4XTbawFpnkkmJS6R4JRsVXFUaoitSU,628
3
3
  utilities/altair.py,sha256=HeZBVUocjkrTNwwKrClppsIqgNFF-ykv05HfZSoHYno,9104
4
4
  utilities/asyncio.py,sha256=dcGeKQzjLBXxKzZkVIk5oZsFXEcynVbRB9iNB5XEDZk,38526
@@ -36,7 +36,7 @@ utilities/luigi.py,sha256=wK7cB3y8NXeSa8d6r_yTKRmjMguNmIPmy52yg10vPaI,4774
36
36
  utilities/math.py,sha256=_6vrDyjtaqE_OFE-F2DNWrDG_J_kMl3nFAJsok9v_bY,26862
37
37
  utilities/memory_profiler.py,sha256=XzN56jDCa5aqXS_DxEjb_K4L6aIWh_5zyKi6OhcIxw0,853
38
38
  utilities/modules.py,sha256=iuvLluJya-hvl1Q25-Jk3dLgx2Es3ck4SjJiEkAlVTs,3195
39
- utilities/more_itertools.py,sha256=EX4P5JTc3p9fF3Ia3ZzPy9CEUe6OZcFqrrVplZ4pMaQ,10937
39
+ utilities/more_itertools.py,sha256=NEGXDT8COaxziaJFTiXYKX0gffwfKhCAMrq-Kgh0w8c,10937
40
40
  utilities/numpy.py,sha256=Xn23sA2ZbVNqwUYEgNJD3XBYH6IbCri_WkHSNhg3NkY,26122
41
41
  utilities/operator.py,sha256=fZM2DBZdjtU8Lh9Z-eHC4ktNr0vO3JfX8hXgIYwdvBI,3826
42
42
  utilities/optuna.py,sha256=C-fhWYiXHVPo1l8QctYkFJ4DyhbSrGorzP1dJb_qvd8,1933
@@ -77,7 +77,7 @@ utilities/text.py,sha256=ymBFlP_cA8OgNnZRVNs7FAh7OG8HxE6YkiLEMZv5g_A,11297
77
77
  utilities/threading.py,sha256=GvBOp4CyhHfN90wGXZuA2VKe9fGzMaEa7oCl4f3nnPU,1009
78
78
  utilities/timer.py,sha256=oXfTii6ymu57niP0BDGZjFD55LEHi2a19kqZKiTgaFQ,2588
79
79
  utilities/traceback.py,sha256=YvNUQCTDLvrKYAsl5498a0zhfjJna0dEUvIaK7PmLlQ,8780
80
- utilities/typed_settings.py,sha256=niNxgvVKrTy1c0j0D0Jp2tO3m231f4yJJ-38ni-xY3Q,3739
80
+ utilities/typed_settings.py,sha256=cZqA2IjG1erF1SUZFSsjIHmZX7BP5iIfPd6CixHllA0,4367
81
81
  utilities/types.py,sha256=98pwEfkBikg6UUrshNJZgc8l97FGBbi0twIsqVt-KNA,17247
82
82
  utilities/typing.py,sha256=Z-_XDaWyT_6wIo3qfNK-hvRlzxP2Jxa9PgXzm5rDYRA,13790
83
83
  utilities/tzdata.py,sha256=fgNVj66yUbCSI_-vrRVzSD3gtf-L_8IEJEPjP_Jel5Y,266
@@ -88,7 +88,7 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
88
88
  utilities/whenever.py,sha256=A-yoOqBqrcVD1yDINDsTFDw7dq9-zgUGn_f8CxVUQJs,23332
89
89
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
90
90
  utilities/zoneinfo.py,sha256=oEH-nL3t4h9uawyZqWDtNtDAl6M-CLpLYGI_nI6DulM,1971
91
- dycw_utilities-0.136.7.dist-info/METADATA,sha256=Y-Pj2EJoFNikG1cNjmfA9b8mzZdMzR_XpxuZX6hzBEc,1637
92
- dycw_utilities-0.136.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
93
- dycw_utilities-0.136.7.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
94
- dycw_utilities-0.136.7.dist-info/RECORD,,
91
+ dycw_utilities-0.136.9.dist-info/METADATA,sha256=MOcxHEd2C4kHuMPGAw3BKehTyJMq0qejj7XF1I3KYYc,1637
92
+ dycw_utilities-0.136.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
93
+ dycw_utilities-0.136.9.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
94
+ dycw_utilities-0.136.9.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.136.7"
3
+ __version__ = "0.136.9"
@@ -28,50 +28,59 @@ if TYPE_CHECKING:
28
28
 
29
29
 
30
30
  @overload
31
- def bucket_mapping[T, U, UH: Hashable](
31
+ def bucket_mapping[T, UH: Hashable](
32
32
  iterable: Iterable[T],
33
33
  func: Callable[[T], UH],
34
34
  /,
35
35
  *,
36
- pre: Callable[[T], U],
36
+ pre: None = None,
37
+ post: None = None,
38
+ ) -> Mapping[UH, Iterator[T]]: ...
39
+ @overload
40
+ def bucket_mapping[T, UH: Hashable](
41
+ iterable: Iterable[T],
42
+ func: Callable[[T], UH],
43
+ /,
44
+ *,
45
+ pre: None = None,
37
46
  post: Literal["list"],
38
- ) -> Mapping[UH, list[U]]: ...
47
+ ) -> Mapping[UH, list[T]]: ...
39
48
  @overload
40
- def bucket_mapping[T, U, UH: Hashable](
49
+ def bucket_mapping[T, UH: Hashable](
41
50
  iterable: Iterable[T],
42
51
  func: Callable[[T], UH],
43
52
  /,
44
53
  *,
45
- pre: Callable[[T], U],
54
+ pre: None = None,
46
55
  post: Literal["tuple"],
47
- ) -> Mapping[UH, tuple[U, ...]]: ...
56
+ ) -> Mapping[UH, tuple[T, ...]]: ...
48
57
  @overload
49
- def bucket_mapping[T, U, UH: Hashable](
58
+ def bucket_mapping[T, UH: Hashable](
50
59
  iterable: Iterable[T],
51
60
  func: Callable[[T], UH],
52
61
  /,
53
62
  *,
54
- pre: Callable[[T], U],
63
+ pre: None = None,
55
64
  post: Literal["set"],
56
- ) -> Mapping[UH, set[U]]: ...
65
+ ) -> Mapping[UH, set[T]]: ...
57
66
  @overload
58
- def bucket_mapping[T, U, UH: Hashable](
67
+ def bucket_mapping[T, UH: Hashable](
59
68
  iterable: Iterable[T],
60
69
  func: Callable[[T], UH],
61
70
  /,
62
71
  *,
63
- pre: Callable[[T], U],
72
+ pre: None = None,
64
73
  post: Literal["frozenset"],
65
- ) -> Mapping[UH, frozenset[U]]: ...
74
+ ) -> Mapping[UH, frozenset[T]]: ...
66
75
  @overload
67
- def bucket_mapping[T, U, UH: Hashable](
76
+ def bucket_mapping[T, UH: Hashable](
68
77
  iterable: Iterable[T],
69
78
  func: Callable[[T], UH],
70
79
  /,
71
80
  *,
72
- pre: Callable[[T], U] | None = None,
81
+ pre: None = None,
73
82
  post: Literal["unique"],
74
- ) -> Mapping[UH, U]: ...
83
+ ) -> Mapping[UH, T]: ...
75
84
  @overload
76
85
  def bucket_mapping[T, U, UH: Hashable](
77
86
  iterable: Iterable[T],
@@ -82,59 +91,50 @@ def bucket_mapping[T, U, UH: Hashable](
82
91
  post: None = None,
83
92
  ) -> Mapping[UH, Iterator[U]]: ...
84
93
  @overload
85
- def bucket_mapping[T, UH: Hashable](
94
+ def bucket_mapping[T, U, UH: Hashable](
86
95
  iterable: Iterable[T],
87
96
  func: Callable[[T], UH],
88
97
  /,
89
98
  *,
90
- pre: None = None,
99
+ pre: Callable[[T], U],
91
100
  post: Literal["list"],
92
- ) -> Mapping[UH, list[T]]: ...
101
+ ) -> Mapping[UH, list[U]]: ...
93
102
  @overload
94
- def bucket_mapping[T, UH: Hashable](
103
+ def bucket_mapping[T, U, UH: Hashable](
95
104
  iterable: Iterable[T],
96
105
  func: Callable[[T], UH],
97
106
  /,
98
107
  *,
99
- pre: None = None,
108
+ pre: Callable[[T], U],
100
109
  post: Literal["tuple"],
101
- ) -> Mapping[UH, tuple[T, ...]]: ...
110
+ ) -> Mapping[UH, tuple[U, ...]]: ...
102
111
  @overload
103
- def bucket_mapping[T, UH: Hashable](
112
+ def bucket_mapping[T, U, UH: Hashable](
104
113
  iterable: Iterable[T],
105
114
  func: Callable[[T], UH],
106
115
  /,
107
116
  *,
108
- pre: None = None,
117
+ pre: Callable[[T], U],
109
118
  post: Literal["set"],
110
- ) -> Mapping[UH, set[T]]: ...
119
+ ) -> Mapping[UH, set[U]]: ...
111
120
  @overload
112
- def bucket_mapping[T, UH: Hashable](
121
+ def bucket_mapping[T, U, UH: Hashable](
113
122
  iterable: Iterable[T],
114
123
  func: Callable[[T], UH],
115
124
  /,
116
125
  *,
117
- pre: None = None,
126
+ pre: Callable[[T], U],
118
127
  post: Literal["frozenset"],
119
- ) -> Mapping[UH, frozenset[T]]: ...
128
+ ) -> Mapping[UH, frozenset[U]]: ...
120
129
  @overload
121
- def bucket_mapping[T, UH: Hashable](
130
+ def bucket_mapping[T, U, UH: Hashable](
122
131
  iterable: Iterable[T],
123
132
  func: Callable[[T], UH],
124
133
  /,
125
134
  *,
126
- pre: None = None,
135
+ pre: Callable[[T], U] | None = None,
127
136
  post: Literal["unique"],
128
- ) -> Mapping[UH, T]: ...
129
- @overload
130
- def bucket_mapping[T, UH: Hashable](
131
- iterable: Iterable[T],
132
- func: Callable[[T], UH],
133
- /,
134
- *,
135
- pre: None = None,
136
- post: None = None,
137
- ) -> Mapping[UH, Iterator[T]]: ...
137
+ ) -> Mapping[UH, U]: ...
138
138
  @overload
139
139
  def bucket_mapping[T, U, UH: Hashable](
140
140
  iterable: Iterable[T],
@@ -1,10 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass
4
+ from functools import partial
4
5
  from ipaddress import IPv4Address, IPv6Address
6
+ from os import environ
5
7
  from pathlib import Path
6
8
  from re import search
7
- from typing import TYPE_CHECKING, Any, override
9
+ from typing import TYPE_CHECKING, Any, assert_never, override
8
10
 
9
11
  import typed_settings
10
12
  from typed_settings import EnvLoader, FileLoader, find
@@ -21,6 +23,8 @@ from whenever import (
21
23
  )
22
24
 
23
25
  from utilities.iterables import always_iterable
26
+ from utilities.pathlib import get_path
27
+ from utilities.string import substitute_environ
24
28
  from utilities.whenever import Freq
25
29
 
26
30
  if TYPE_CHECKING:
@@ -29,7 +33,7 @@ if TYPE_CHECKING:
29
33
  from typed_settings.loaders import Loader
30
34
  from typed_settings.processors import Processor
31
35
 
32
- from utilities.types import MaybeIterable, PathLike
36
+ from utilities.types import MaybeCallablePathLike, MaybeIterable, PathLike
33
37
 
34
38
 
35
39
  ##
@@ -53,6 +57,7 @@ class ExtendedTSConverter(TSConverter):
53
57
  (Freq, Freq.parse),
54
58
  (IPv4Address, IPv4Address),
55
59
  (IPv6Address, IPv6Address),
60
+ (Path, partial(_parse_path, resolve=resolve_paths, pwd=Path.cwd())),
56
61
  (PlainDateTime, PlainDateTime.parse_common_iso),
57
62
  (Time, Time.parse_common_iso),
58
63
  (TimeDelta, TimeDelta.parse_common_iso),
@@ -76,6 +81,19 @@ def _make_converter[T](
76
81
  return hook
77
82
 
78
83
 
84
+ def _parse_path(
85
+ path: str, /, *, resolve: bool = False, pwd: MaybeCallablePathLike | None = None
86
+ ) -> Path:
87
+ path = substitute_environ(path, **environ)
88
+ match resolve:
89
+ case True:
90
+ return get_path(path=pwd).joinpath(path).resolve()
91
+ case False:
92
+ return Path(path)
93
+ case _ as never:
94
+ assert_never(never)
95
+
96
+
79
97
  ##
80
98
 
81
99
  _BASE_DIR: Path = Path()