dycw-utilities 0.138.6__py3-none-any.whl → 0.138.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.138.6
3
+ Version: 0.138.8
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=V7k67oxstsllNw_dt-tpMRsylqRrsJMOdAMNNakV9po,60
1
+ utilities/__init__.py,sha256=PNZtdWOozZol0q-8PP5HDXblyuTImCmKVhJDZ6aPzOM,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
@@ -22,7 +22,7 @@ utilities/functools.py,sha256=I00ru2gQPakZw2SHVeKIKXfTv741655s6HI0lUoE0D4,1552
22
22
  utilities/getpass.py,sha256=DfN5UgMAtFCqS3dSfFHUfqIMZX2shXvwphOz_6J6f6A,103
23
23
  utilities/hashlib.py,sha256=SVTgtguur0P4elppvzOBbLEjVM3Pea0eWB61yg2ilxo,309
24
24
  utilities/http.py,sha256=WcahTcKYRtZ04WXQoWt5EGCgFPcyHD3EJdlMfxvDt-0,946
25
- utilities/hypothesis.py,sha256=2VJy9Pxqjy4_ldAwZAR6XEGuG2ZmAN1ycpA_VIGnKew,38819
25
+ utilities/hypothesis.py,sha256=GLw1crgjrPUhCkIMgFkJKNYnixiQAAQ1XjzJBsabkWc,38826
26
26
  utilities/importlib.py,sha256=mV1xT_O_zt_GnZZ36tl3xOmMaN_3jErDWY54fX39F6Y,429
27
27
  utilities/inflect.py,sha256=DbqB5Q9FbRGJ1NbvEiZBirRMxCxgrz91zy5jCO9ZIs0,347
28
28
  utilities/ipython.py,sha256=V2oMYHvEKvlNBzxDXdLvKi48oUq2SclRg5xasjaXStw,763
@@ -42,7 +42,7 @@ utilities/optuna.py,sha256=C-fhWYiXHVPo1l8QctYkFJ4DyhbSrGorzP1dJb_qvd8,1933
42
42
  utilities/orjson.py,sha256=WWV2QukCIuwT8OAOtmKhLhxezXPVbeA_fQCucmGmbRA,37106
43
43
  utilities/os.py,sha256=yMNAKMyY8oFgQ1yN3TQYnwa5-A_FXz4tCDbhIctQHSs,3736
44
44
  utilities/parse.py,sha256=JcJn5yXKhIWXBCwgBdPsyu7Hvcuw6kyEdqvaebCaI9k,17951
45
- utilities/pathlib.py,sha256=1QTfoMze_RYX0wrbm9F9FSaZNfO8n1bSFD60-E1Vmc0,6912
45
+ utilities/pathlib.py,sha256=NT0EzXBzkVMByO1GZdZYN1wLt0_pikAV7rLBtgLKF-Y,7291
46
46
  utilities/period.py,sha256=6jEff_qAiE7xdFaQ1DnKgNf10D2wHhzt7hQXCBoKlgc,6842
47
47
  utilities/pickle.py,sha256=MBT2xZCsv0pH868IXLGKnlcqNx2IRVKYNpRcqiQQqxw,653
48
48
  utilities/platform.py,sha256=5uCKRf_ij7ukJDcbnNfhY2ay9fbrpiNLRO1t2QvcwqQ,2825
@@ -54,8 +54,9 @@ utilities/psutil.py,sha256=0j4YxtVb8VjaaKKiHg6UEK95SUPkEcENgPtLgPJsNv0,3760
54
54
  utilities/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
55
  utilities/pydantic.py,sha256=CmxCi4sukeHM3JGjJ1Rbp8UAvcx4MZapLg10mFYJ-nk,1771
56
56
  utilities/pyinstrument.py,sha256=HrTGJ2niUAHUFMSN3im9BeedC0faq2DqoFccDxPpsP8,884
57
- utilities/pytest.py,sha256=f6Yl2vHimin2Ulg0aUsNhdWmf6dC1Hs6nDTFOCOpRJI,8029
58
- utilities/pytest_regressions.py,sha256=YI55B7EtLjhz7zPJZ6NK9bWrxrKCKabWZJe1cwcbA5o,5082
57
+ utilities/pytest.py,sha256=WkdZVu5yrh-7y4O4AHSx4t6nlzWxBRoQsYG-kbPJcg8,8043
58
+ utilities/pytest_regressions.py,sha256=X5fN5MjRyTHWV_xe-K5a3f01I1FX0qcCMvtIQeQ93yE,4176
59
+ utilities/pytest_regressions_plugin.py,sha256=Iwhfv_OJH7UCPZCfoh7ugZ2Xjqjil-BBBsOb8sDwiGI,1471
59
60
  utilities/python_dotenv.py,sha256=dYooRYwqrvhSoZWuiVbCiKUWiS-M5b5yv2zDWGYPEvI,3209
60
61
  utilities/random.py,sha256=YWYzWxQDeyJRiuHGnO1OxF6dDucpq7qc1tH_ealwCRg,4130
61
62
  utilities/re.py,sha256=6qxeV0rQZaBDKWcB7apSBmxtg_XzoGY-EdegTkMn-ZY,4578
@@ -75,7 +76,7 @@ utilities/tempfile.py,sha256=VqmZJAhTJ1OaVywFzk5eqROV8iJbW9XQ_QYAV0bpdRo,1384
75
76
  utilities/text.py,sha256=ymBFlP_cA8OgNnZRVNs7FAh7OG8HxE6YkiLEMZv5g_A,11297
76
77
  utilities/threading.py,sha256=GvBOp4CyhHfN90wGXZuA2VKe9fGzMaEa7oCl4f3nnPU,1009
77
78
  utilities/timer.py,sha256=oXfTii6ymu57niP0BDGZjFD55LEHi2a19kqZKiTgaFQ,2588
78
- utilities/traceback.py,sha256=h9yt4C2XkGHXW9e9bz93IGluhIR_Qil8zu5dhC8DXY0,8884
79
+ utilities/traceback.py,sha256=YPD_MYNWc7k3vWF-YDWw4YUCZQyVR3ZLp6M1FAQR9Xw,8878
79
80
  utilities/typed_settings.py,sha256=C2i2VK62us_Z5jjca9NLmDFiT3_mkoSCwgU6FDtDhMI,4501
80
81
  utilities/types.py,sha256=-_pXQvmpJhTgEbI13N_zZWINdt0ODBpZ3WdJQUML9GA,17397
81
82
  utilities/typing.py,sha256=Z-_XDaWyT_6wIo3qfNK-hvRlzxP2Jxa9PgXzm5rDYRA,13790
@@ -87,7 +88,8 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
87
88
  utilities/whenever.py,sha256=R5d9UCNCdAOyjwLUmfH2Vn8Ykee8OHQi2skRTFfbZMM,20492
88
89
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
89
90
  utilities/zoneinfo.py,sha256=oEH-nL3t4h9uawyZqWDtNtDAl6M-CLpLYGI_nI6DulM,1971
90
- dycw_utilities-0.138.6.dist-info/METADATA,sha256=EMQ0EEZfe_ywhxuelhNvMoXkahxUom89cJL4Hh40abU,1638
91
- dycw_utilities-0.138.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
- dycw_utilities-0.138.6.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
93
- dycw_utilities-0.138.6.dist-info/RECORD,,
91
+ dycw_utilities-0.138.8.dist-info/METADATA,sha256=MVaYliyhueRarnK_LZuye5BRShl7DtclUDjY6wyVfdU,1638
92
+ dycw_utilities-0.138.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
93
+ dycw_utilities-0.138.8.dist-info/entry_points.txt,sha256=uLj5QWWVXv8tnMaRX3ZGYpt7w1xzLWU6LxbFhELEpkc,68
94
+ dycw_utilities-0.138.8.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
95
+ dycw_utilities-0.138.8.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [pytest11]
2
+ pytest-regressions = utilities.pytest_regressions_plugin
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.138.6"
3
+ __version__ = "0.138.8"
utilities/hypothesis.py CHANGED
@@ -66,7 +66,7 @@ from utilities.math import (
66
66
  is_zero,
67
67
  )
68
68
  from utilities.os import get_env_var
69
- from utilities.pathlib import temp_cwd
69
+ from utilities.pathlib import module_path, temp_cwd
70
70
  from utilities.platform import IS_WINDOWS
71
71
  from utilities.sentinel import Sentinel, sentinel
72
72
  from utilities.tempfile import TEMP_DIR, TemporaryDirectory
@@ -567,7 +567,7 @@ def import_froms(
567
567
  max_depth=max_depth_,
568
568
  )
569
569
  )
570
- module = ".".join(path.parts)
570
+ module = module_path(path)
571
571
  name = draw(text_ascii(min_size=1))
572
572
  asname = draw(text_ascii(min_size=1) | none())
573
573
  return generate_import_from(module, name, asname=asname)
@@ -594,7 +594,7 @@ def imports(
594
594
  max_depth=max_depth_,
595
595
  )
596
596
  )
597
- module = ".".join(path.parts)
597
+ module = module_path(path)
598
598
  asname = draw(text_ascii(min_size=1) | none())
599
599
  return generate_import(module, asname=asname)
600
600
 
utilities/pathlib.py CHANGED
@@ -211,6 +211,24 @@ class _GetTailNonUniqueError(GetTailError):
211
211
  ##
212
212
 
213
213
 
214
+ def module_path(
215
+ path: PathLike,
216
+ /,
217
+ *,
218
+ root: PathLike | None = None,
219
+ disambiguate: _GetTailDisambiguate = "raise",
220
+ ) -> str:
221
+ """Return a module path."""
222
+ path = Path(path)
223
+ if root is not None:
224
+ path = get_tail(path, root, disambiguate=disambiguate)
225
+ parts = path.with_suffix("").parts
226
+ return ".".join(parts)
227
+
228
+
229
+ ##
230
+
231
+
214
232
  def is_sub_path(x: PathLike, y: PathLike, /, *, strict: bool = False) -> bool:
215
233
  """Check if a path is a sub path of another."""
216
234
  x, y = [Path(i).resolve() for i in [x, y]]
@@ -248,5 +266,6 @@ __all__ = [
248
266
  "get_tail",
249
267
  "is_sub_path",
250
268
  "list_dir",
269
+ "module_path",
251
270
  "temp_cwd",
252
271
  ]
utilities/pytest.py CHANGED
@@ -13,7 +13,7 @@ from whenever import ZonedDateTime
13
13
  from utilities.atomicwrites import writer
14
14
  from utilities.functools import cache
15
15
  from utilities.hashlib import md5_hash
16
- from utilities.pathlib import ensure_suffix, get_root
16
+ from utilities.pathlib import ensure_suffix, get_root, get_tail, module_path
17
17
  from utilities.platform import (
18
18
  IS_LINUX,
19
19
  IS_MAC,
@@ -123,18 +123,18 @@ def is_pytest() -> bool:
123
123
  ##
124
124
 
125
125
 
126
- def node_id_to_path(
127
- node_id: str, /, *, head: PathLike | None = None, suffix: str | None = None
126
+ def node_id_path(
127
+ node_id: str, /, *, root: PathLike | None = None, suffix: str | None = None
128
128
  ) -> Path:
129
- """Map a node ID to a path."""
129
+ """Get the path of a node ID."""
130
130
  path_file, *parts = node_id.split("::")
131
131
  path_file = Path(path_file)
132
132
  if path_file.suffix != ".py":
133
133
  raise NodeIdToPathError(node_id=node_id)
134
134
  path = path_file.with_suffix("")
135
- if head is not None:
136
- path = path.relative_to(head)
137
- path = Path(".".join(path.parts), "__".join(parts))
135
+ if root is not None:
136
+ path = get_tail(path, root)
137
+ path = Path(module_path(path), "__".join(parts))
138
138
  if suffix is not None:
139
139
  path = ensure_suffix(path, suffix)
140
140
  return path
@@ -267,7 +267,7 @@ __all__ = [
267
267
  "add_pytest_collection_modifyitems",
268
268
  "add_pytest_configure",
269
269
  "is_pytest",
270
- "node_id_to_path",
270
+ "node_id_path",
271
271
  "random_state",
272
272
  "skipif_linux",
273
273
  "skipif_mac",
@@ -6,13 +6,10 @@ from pathlib import Path
6
6
  from shutil import copytree
7
7
  from typing import TYPE_CHECKING, Any, assert_never
8
8
 
9
- from pytest import fixture
10
9
  from pytest_regressions.file_regression import FileRegressionFixture
11
10
 
12
11
  from utilities.functions import ensure_str
13
12
  from utilities.operator import is_equal
14
- from utilities.pathlib import get_root
15
- from utilities.pytest import node_id_to_path
16
13
 
17
14
  if TYPE_CHECKING:
18
15
  from polars import DataFrame, Series
@@ -21,9 +18,6 @@ if TYPE_CHECKING:
21
18
  from utilities.types import PathLike, StrMapping
22
19
 
23
20
 
24
- _PATH_TESTS = Path("src", "tests")
25
-
26
-
27
21
  ##
28
22
 
29
23
 
@@ -84,15 +78,6 @@ class OrjsonRegressionFixture:
84
78
  assert is_equal(left, right), f"{left=}, {right=}"
85
79
 
86
80
 
87
- @fixture
88
- def orjson_regression(
89
- *, request: FixtureRequest, tmp_path: Path
90
- ) -> OrjsonRegressionFixture:
91
- """Instance of the `OrjsonRegressionFixture`."""
92
- path = _get_path(request)
93
- return OrjsonRegressionFixture(path, request, tmp_path)
94
-
95
-
96
81
  ##
97
82
 
98
83
 
@@ -139,26 +124,4 @@ class PolarsRegressionFixture:
139
124
  self._fixture.check(data, suffix=suffix)
140
125
 
141
126
 
142
- @fixture
143
- def polars_regression(
144
- *, request: FixtureRequest, tmp_path: Path
145
- ) -> PolarsRegressionFixture:
146
- """Instance of the `PolarsRegressionFixture`."""
147
- path = _get_path(request)
148
- return PolarsRegressionFixture(path, request, tmp_path)
149
-
150
-
151
- ##
152
-
153
-
154
- def _get_path(request: FixtureRequest, /) -> Path:
155
- tail = node_id_to_path(request.node.nodeid, head=_PATH_TESTS)
156
- return get_root().joinpath(_PATH_TESTS, "regressions", tail)
157
-
158
-
159
- __all__ = [
160
- "OrjsonRegressionFixture",
161
- "PolarsRegressionFixture",
162
- "orjson_regression",
163
- "polars_regression",
164
- ]
127
+ __all__ = ["OrjsonRegressionFixture", "PolarsRegressionFixture"]
@@ -0,0 +1,52 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+ from typing import TYPE_CHECKING, Any, cast
5
+
6
+ if TYPE_CHECKING:
7
+ from pytest import FixtureRequest
8
+
9
+ from utilities.pytest_regressions import (
10
+ OrjsonRegressionFixture,
11
+ PolarsRegressionFixture,
12
+ )
13
+
14
+
15
+ try:
16
+ from pytest import fixture
17
+ except ModuleNotFoundError:
18
+ pass
19
+ else:
20
+
21
+ @fixture
22
+ def orjson_regression(
23
+ *, request: FixtureRequest, tmp_path: Path
24
+ ) -> OrjsonRegressionFixture:
25
+ """Instance of the `OrjsonRegressionFixture`."""
26
+ from utilities.pytest_regressions import OrjsonRegressionFixture
27
+
28
+ path = _get_path(request)
29
+ return OrjsonRegressionFixture(path, request, tmp_path)
30
+
31
+ @fixture
32
+ def polars_regression(
33
+ *, request: FixtureRequest, tmp_path: Path
34
+ ) -> PolarsRegressionFixture:
35
+ """Instance of the `PolarsRegressionFixture`."""
36
+ from utilities.pytest_regressions import PolarsRegressionFixture
37
+
38
+ path = _get_path(request)
39
+ return PolarsRegressionFixture(path, request, tmp_path)
40
+
41
+
42
+ def _get_path(request: FixtureRequest, /) -> Path:
43
+ from utilities.pathlib import get_root
44
+ from utilities.pytest import node_id_path
45
+
46
+ path = Path(cast("Any", request).fspath)
47
+ root = Path("src", "tests")
48
+ tail = node_id_path(request.node.nodeid, root=root)
49
+ return get_root(path=path).joinpath(root, "regressions", tail)
50
+
51
+
52
+ __all__ = ["orjson_regression", "polars_regression"]
utilities/traceback.py CHANGED
@@ -16,7 +16,7 @@ from utilities.atomicwrites import writer
16
16
  from utilities.errors import repr_error
17
17
  from utilities.functions import to_bool
18
18
  from utilities.iterables import OneEmptyError, one
19
- from utilities.pathlib import get_path
19
+ from utilities.pathlib import get_path, module_path
20
20
  from utilities.reprlib import (
21
21
  RICH_EXPAND_ALL,
22
22
  RICH_INDENT_SIZE,
@@ -181,7 +181,7 @@ def _path_to_dots(path: PathLike, /) -> str:
181
181
  if (new_path := _trim_path(path, pattern)) is not None:
182
182
  break
183
183
  path_use = Path(path) if new_path is None else new_path
184
- return ".".join(path_use.with_suffix("").parts)
184
+ return module_path(path_use)
185
185
 
186
186
 
187
187
  def _trim_path(path: PathLike, pattern: str, /) -> Path | None: