dycw-utilities 0.138.7__py3-none-any.whl → 0.138.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.
- {dycw_utilities-0.138.7.dist-info → dycw_utilities-0.138.9.dist-info}/METADATA +1 -1
- {dycw_utilities-0.138.7.dist-info → dycw_utilities-0.138.9.dist-info}/RECORD +11 -11
- utilities/__init__.py +1 -1
- utilities/hypothesis.py +3 -3
- utilities/pathlib.py +90 -24
- utilities/pytest.py +8 -8
- utilities/pytest_regressions_plugin.py +6 -5
- utilities/traceback.py +2 -2
- {dycw_utilities-0.138.7.dist-info → dycw_utilities-0.138.9.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.138.7.dist-info → dycw_utilities-0.138.9.dist-info}/entry_points.txt +0 -0
- {dycw_utilities-0.138.7.dist-info → dycw_utilities-0.138.9.dist-info}/licenses/LICENSE +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
utilities/__init__.py,sha256=
|
1
|
+
utilities/__init__.py,sha256=ANddrXgdSTBQjO5buynEzt5zVNH6F2WJFjL8c1YlyV8,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=
|
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=
|
45
|
+
utilities/pathlib.py,sha256=5p9MI8m7iUFksNVGiLavN4MZ3cj1CpBiLBlgaCR0LCs,8334
|
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,9 +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=
|
57
|
+
utilities/pytest.py,sha256=WkdZVu5yrh-7y4O4AHSx4t6nlzWxBRoQsYG-kbPJcg8,8043
|
58
58
|
utilities/pytest_regressions.py,sha256=X5fN5MjRyTHWV_xe-K5a3f01I1FX0qcCMvtIQeQ93yE,4176
|
59
|
-
utilities/pytest_regressions_plugin.py,sha256=
|
59
|
+
utilities/pytest_regressions_plugin.py,sha256=Iwhfv_OJH7UCPZCfoh7ugZ2Xjqjil-BBBsOb8sDwiGI,1471
|
60
60
|
utilities/python_dotenv.py,sha256=dYooRYwqrvhSoZWuiVbCiKUWiS-M5b5yv2zDWGYPEvI,3209
|
61
61
|
utilities/random.py,sha256=YWYzWxQDeyJRiuHGnO1OxF6dDucpq7qc1tH_ealwCRg,4130
|
62
62
|
utilities/re.py,sha256=6qxeV0rQZaBDKWcB7apSBmxtg_XzoGY-EdegTkMn-ZY,4578
|
@@ -76,7 +76,7 @@ utilities/tempfile.py,sha256=VqmZJAhTJ1OaVywFzk5eqROV8iJbW9XQ_QYAV0bpdRo,1384
|
|
76
76
|
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
|
-
utilities/traceback.py,sha256=
|
79
|
+
utilities/traceback.py,sha256=YPD_MYNWc7k3vWF-YDWw4YUCZQyVR3ZLp6M1FAQR9Xw,8878
|
80
80
|
utilities/typed_settings.py,sha256=C2i2VK62us_Z5jjca9NLmDFiT3_mkoSCwgU6FDtDhMI,4501
|
81
81
|
utilities/types.py,sha256=-_pXQvmpJhTgEbI13N_zZWINdt0ODBpZ3WdJQUML9GA,17397
|
82
82
|
utilities/typing.py,sha256=Z-_XDaWyT_6wIo3qfNK-hvRlzxP2Jxa9PgXzm5rDYRA,13790
|
@@ -88,8 +88,8 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
|
|
88
88
|
utilities/whenever.py,sha256=R5d9UCNCdAOyjwLUmfH2Vn8Ykee8OHQi2skRTFfbZMM,20492
|
89
89
|
utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
|
90
90
|
utilities/zoneinfo.py,sha256=oEH-nL3t4h9uawyZqWDtNtDAl6M-CLpLYGI_nI6DulM,1971
|
91
|
-
dycw_utilities-0.138.
|
92
|
-
dycw_utilities-0.138.
|
93
|
-
dycw_utilities-0.138.
|
94
|
-
dycw_utilities-0.138.
|
95
|
-
dycw_utilities-0.138.
|
91
|
+
dycw_utilities-0.138.9.dist-info/METADATA,sha256=og-7pWHDQmHofzZTBE5WqHkkBAcqtjf6rxaKb8gKz-c,1638
|
92
|
+
dycw_utilities-0.138.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
93
|
+
dycw_utilities-0.138.9.dist-info/entry_points.txt,sha256=uLj5QWWVXv8tnMaRX3ZGYpt7w1xzLWU6LxbFhELEpkc,68
|
94
|
+
dycw_utilities-0.138.9.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
|
95
|
+
dycw_utilities-0.138.9.dist-info/RECORD,,
|
utilities/__init__.py
CHANGED
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 =
|
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 =
|
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
@@ -71,8 +71,35 @@ def get_path(
|
|
71
71
|
##
|
72
72
|
|
73
73
|
|
74
|
-
def
|
75
|
-
"""Get the root
|
74
|
+
def get_package_root(*, path: MaybeCallablePathLike | None = None) -> Path:
|
75
|
+
"""Get the package root."""
|
76
|
+
path = get_path(path=path)
|
77
|
+
path_dir = path.parent if path.is_file() else path
|
78
|
+
all_paths = list(chain([path_dir], path_dir.parents))
|
79
|
+
try:
|
80
|
+
return next(
|
81
|
+
p.resolve()
|
82
|
+
for p in all_paths
|
83
|
+
if any(p_i.name == "pyproject.toml" for p_i in p.iterdir())
|
84
|
+
)
|
85
|
+
except StopIteration:
|
86
|
+
raise GetPackageRootError(path=path) from None
|
87
|
+
|
88
|
+
|
89
|
+
@dataclass(kw_only=True, slots=True)
|
90
|
+
class GetPackageRootError(Exception):
|
91
|
+
path: PathLike
|
92
|
+
|
93
|
+
@override
|
94
|
+
def __str__(self) -> str:
|
95
|
+
return f"Path is not part of a package: {self.path}"
|
96
|
+
|
97
|
+
|
98
|
+
##
|
99
|
+
|
100
|
+
|
101
|
+
def get_repo_root(*, path: MaybeCallablePathLike | None = None) -> Path:
|
102
|
+
"""Get the repo root."""
|
76
103
|
path = get_path(path=path)
|
77
104
|
path_dir = path.parent if path.is_file() else path
|
78
105
|
try:
|
@@ -85,36 +112,52 @@ def get_root(*, path: MaybeCallablePathLike | None = None) -> Path:
|
|
85
112
|
except CalledProcessError as error:
|
86
113
|
# newer versions of git report "Not a git repository", whilst older
|
87
114
|
# versions report "not a git repository"
|
88
|
-
if
|
89
|
-
raise
|
90
|
-
|
115
|
+
if search("fatal: not a git repository", error.stderr, flags=IGNORECASE):
|
116
|
+
raise GetRepoRootError(path=path) from None
|
117
|
+
raise # pragma: no cover
|
91
118
|
else:
|
92
|
-
|
93
|
-
|
119
|
+
return Path(output.strip("\n"))
|
120
|
+
|
121
|
+
|
122
|
+
@dataclass(kw_only=True, slots=True)
|
123
|
+
class GetRepoRootError(Exception):
|
124
|
+
path: PathLike
|
125
|
+
|
126
|
+
@override
|
127
|
+
def __str__(self) -> str:
|
128
|
+
return f"Path is not part of a `git` repository: {self.path}"
|
129
|
+
|
130
|
+
|
131
|
+
##
|
132
|
+
|
133
|
+
|
134
|
+
def get_root(*, path: MaybeCallablePathLike | None = None) -> Path:
|
135
|
+
"""Get the root of a path."""
|
136
|
+
path = get_path(path=path)
|
94
137
|
try:
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
)
|
100
|
-
except
|
101
|
-
|
102
|
-
match
|
138
|
+
repo = get_repo_root(path=path)
|
139
|
+
except GetRepoRootError:
|
140
|
+
repo = None
|
141
|
+
try:
|
142
|
+
package = get_package_root(path=path)
|
143
|
+
except GetPackageRootError:
|
144
|
+
package = None
|
145
|
+
match repo, package:
|
103
146
|
case None, None:
|
104
147
|
raise GetRootError(path=path)
|
105
148
|
case Path(), None:
|
106
|
-
return
|
149
|
+
return repo
|
107
150
|
case None, Path():
|
108
|
-
return
|
151
|
+
return package
|
109
152
|
case Path(), Path():
|
110
|
-
if
|
111
|
-
return
|
112
|
-
if is_sub_path(
|
113
|
-
return
|
114
|
-
if is_sub_path(
|
115
|
-
return
|
153
|
+
if repo == package:
|
154
|
+
return repo
|
155
|
+
if is_sub_path(repo, package, strict=True):
|
156
|
+
return repo
|
157
|
+
if is_sub_path(package, repo, strict=True):
|
158
|
+
return package
|
116
159
|
raise ImpossibleCaseError( # pragma: no cover
|
117
|
-
case=[f"{
|
160
|
+
case=[f"{repo=}", f"{package=}"]
|
118
161
|
)
|
119
162
|
case _ as never:
|
120
163
|
assert_never(never)
|
@@ -211,6 +254,24 @@ class _GetTailNonUniqueError(GetTailError):
|
|
211
254
|
##
|
212
255
|
|
213
256
|
|
257
|
+
def module_path(
|
258
|
+
path: PathLike,
|
259
|
+
/,
|
260
|
+
*,
|
261
|
+
root: PathLike | None = None,
|
262
|
+
disambiguate: _GetTailDisambiguate = "raise",
|
263
|
+
) -> str:
|
264
|
+
"""Return a module path."""
|
265
|
+
path = Path(path)
|
266
|
+
if root is not None:
|
267
|
+
path = get_tail(path, root, disambiguate=disambiguate)
|
268
|
+
parts = path.with_suffix("").parts
|
269
|
+
return ".".join(parts)
|
270
|
+
|
271
|
+
|
272
|
+
##
|
273
|
+
|
274
|
+
|
214
275
|
def is_sub_path(x: PathLike, y: PathLike, /, *, strict: bool = False) -> bool:
|
215
276
|
"""Check if a path is a sub path of another."""
|
216
277
|
x, y = [Path(i).resolve() for i in [x, y]]
|
@@ -241,12 +302,17 @@ def temp_cwd(path: PathLike, /) -> Iterator[None]:
|
|
241
302
|
|
242
303
|
__all__ = [
|
243
304
|
"PWD",
|
305
|
+
"GetPackageRootError",
|
306
|
+
"GetRepoRootError",
|
244
307
|
"GetTailError",
|
245
308
|
"ensure_suffix",
|
246
309
|
"expand_path",
|
310
|
+
"get_package_root",
|
247
311
|
"get_path",
|
312
|
+
"get_repo_root",
|
248
313
|
"get_tail",
|
249
314
|
"is_sub_path",
|
250
315
|
"list_dir",
|
316
|
+
"module_path",
|
251
317
|
"temp_cwd",
|
252
318
|
]
|
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
|
127
|
-
node_id: str, /, *,
|
126
|
+
def node_id_path(
|
127
|
+
node_id: str, /, *, root: PathLike | None = None, suffix: str | None = None
|
128
128
|
) -> Path:
|
129
|
-
"""
|
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
|
136
|
-
path = path
|
137
|
-
path = Path(
|
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
|
-
"
|
270
|
+
"node_id_path",
|
271
271
|
"random_state",
|
272
272
|
"skipif_linux",
|
273
273
|
"skipif_mac",
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
from pathlib import Path
|
4
|
-
from typing import TYPE_CHECKING
|
4
|
+
from typing import TYPE_CHECKING, Any, cast
|
5
5
|
|
6
6
|
if TYPE_CHECKING:
|
7
7
|
from pytest import FixtureRequest
|
@@ -41,11 +41,12 @@ else:
|
|
41
41
|
|
42
42
|
def _get_path(request: FixtureRequest, /) -> Path:
|
43
43
|
from utilities.pathlib import get_root
|
44
|
-
from utilities.pytest import
|
44
|
+
from utilities.pytest import node_id_path
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
|
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)
|
49
50
|
|
50
51
|
|
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
|
184
|
+
return module_path(path_use)
|
185
185
|
|
186
186
|
|
187
187
|
def _trim_path(path: PathLike, pattern: str, /) -> Path | None:
|
File without changes
|
File without changes
|
File without changes
|