dycw-utilities 0.175.14__py3-none-any.whl → 0.175.16__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.175.14.dist-info → dycw_utilities-0.175.16.dist-info}/METADATA +1 -1
- {dycw_utilities-0.175.14.dist-info → dycw_utilities-0.175.16.dist-info}/RECORD +7 -7
- utilities/__init__.py +1 -1
- utilities/importlib.py +17 -1
- utilities/subprocess.py +61 -10
- {dycw_utilities-0.175.14.dist-info → dycw_utilities-0.175.16.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.175.14.dist-info → dycw_utilities-0.175.16.dist-info}/entry_points.txt +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
utilities/__init__.py,sha256=
|
|
1
|
+
utilities/__init__.py,sha256=T7O3-BYhuabAFjqxaQs9o5WOToPVSLS3TN_UrDKm1-o,61
|
|
2
2
|
utilities/altair.py,sha256=TLfRFbG9HwG7SLXoJ-v0r-t49ZaGgTQZD82cpjVi4vs,9085
|
|
3
3
|
utilities/asyncio.py,sha256=aJySVxBY0gqsIYnoNmH7-1r8djKuf4vSsU69VCD08t8,16772
|
|
4
4
|
utilities/atomicwrites.py,sha256=tPo6r-Rypd9u99u66B9z86YBPpnLrlHtwox_8Z7T34Y,5790
|
|
@@ -25,7 +25,7 @@ utilities/gzip.py,sha256=fkGP3KdsBfXlstodT4wtlp-PwNyUsogpbDCVVVGdsm4,781
|
|
|
25
25
|
utilities/hashlib.py,sha256=SVTgtguur0P4elppvzOBbLEjVM3Pea0eWB61yg2ilxo,309
|
|
26
26
|
utilities/http.py,sha256=TsavEfHlRtlLaeV21Z6KZh0qbPw-kvD1zsQdZ7Kep5Q,977
|
|
27
27
|
utilities/hypothesis.py,sha256=NUu30pl5kjL3tzo-m8SMRwTqLAmTWK-_Sau2NemJcQo,46773
|
|
28
|
-
utilities/importlib.py,sha256=
|
|
28
|
+
utilities/importlib.py,sha256=SkVVtIjVC7bjJ36doXnmnmFiYe5tLbip4YAfYJj8Ycg,892
|
|
29
29
|
utilities/inflect.py,sha256=v7YkOWSu8NAmVghPcf4F3YBZQoJCS47_DLf9jbfWIs0,581
|
|
30
30
|
utilities/ipython.py,sha256=V2oMYHvEKvlNBzxDXdLvKi48oUq2SclRg5xasjaXStw,763
|
|
31
31
|
utilities/iterables.py,sha256=t2TsW-K3rVlS6y4_tqcc1fk9RwJV-bi7G_VwduMABK0,42558
|
|
@@ -80,7 +80,7 @@ utilities/sqlalchemy.py,sha256=HQYpd7LFxdTF5WYVWYtCJeEBI71EJm7ytvCGyAH9B-U,37163
|
|
|
80
80
|
utilities/sqlalchemy_polars.py,sha256=JCGhB37raSR7fqeWV5dTsciRTMVzIdVT9YSqKT0piT0,13370
|
|
81
81
|
utilities/statsmodels.py,sha256=koyiBHvpMcSiBfh99wFUfSggLNx7cuAw3rwyfAhoKpQ,3410
|
|
82
82
|
utilities/string.py,sha256=shmBK87zZwzGyixuNuXCiUbqzfeZ9xlrFwz6JTaRvDk,582
|
|
83
|
-
utilities/subprocess.py,sha256=
|
|
83
|
+
utilities/subprocess.py,sha256=nFPIXVzXomI_Oby8PYF9HNWrsWtcSsCtgFnj_22QYlI,43753
|
|
84
84
|
utilities/tempfile.py,sha256=QyvIdfV4r4YZ0NeNYsg0tCijThLKa7Z32u5Kxy6ZsGo,3619
|
|
85
85
|
utilities/testbook.py,sha256=j1KmaVbrX9VrbeMgtPh5gk55myAsn3dyRUn7jGbPbRk,1294
|
|
86
86
|
utilities/text.py,sha256=7SvwcSR2l_5cOrm1samGnR4C-ZI6qyFLHLzSpO1zeHQ,13958
|
|
@@ -97,7 +97,7 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
|
|
|
97
97
|
utilities/whenever.py,sha256=F4ek0-OBWxHYrZdmoZt76N2RnNyKY5KrEHt7rqO4AQE,60183
|
|
98
98
|
utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
|
|
99
99
|
utilities/zoneinfo.py,sha256=tdIScrTB2-B-LH0ukb1HUXKooLknOfJNwHk10MuMYvA,3619
|
|
100
|
-
dycw_utilities-0.175.
|
|
101
|
-
dycw_utilities-0.175.
|
|
102
|
-
dycw_utilities-0.175.
|
|
103
|
-
dycw_utilities-0.175.
|
|
100
|
+
dycw_utilities-0.175.16.dist-info/WHEEL,sha256=RRVLqVugUmFOqBedBFAmA4bsgFcROUBiSUKlERi0Hcg,79
|
|
101
|
+
dycw_utilities-0.175.16.dist-info/entry_points.txt,sha256=cOGtKeJI0KXLSV7MJ8Dhc2G8jPgDcBDm53MVNJU4ycI,136
|
|
102
|
+
dycw_utilities-0.175.16.dist-info/METADATA,sha256=I6NeFafea7kKkUKz82clljp9LupC0JkQ0AgxoPvke34,1443
|
|
103
|
+
dycw_utilities-0.175.16.dist-info/RECORD,,
|
utilities/__init__.py
CHANGED
utilities/importlib.py
CHANGED
|
@@ -1,7 +1,23 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import importlib.resources
|
|
3
4
|
from importlib import import_module
|
|
4
5
|
from importlib.util import find_spec
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
8
|
+
|
|
9
|
+
from utilities.errors import ImpossibleCaseError
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from importlib.resources import Anchor
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def files(*, anchor: Anchor | None = None) -> Path:
|
|
16
|
+
"""Get the path for an anchor."""
|
|
17
|
+
path = importlib.resources.files(anchor)
|
|
18
|
+
if isinstance(path, Path):
|
|
19
|
+
return path
|
|
20
|
+
raise ImpossibleCaseError(case=[f"{path=}"]) # pragma: no cover
|
|
5
21
|
|
|
6
22
|
|
|
7
23
|
def is_valid_import(module: str, /, *, name: str | None = None) -> bool:
|
|
@@ -15,4 +31,4 @@ def is_valid_import(module: str, /, *, name: str | None = None) -> bool:
|
|
|
15
31
|
return hasattr(mod, name)
|
|
16
32
|
|
|
17
33
|
|
|
18
|
-
__all__ = ["is_valid_import"]
|
|
34
|
+
__all__ = ["files", "is_valid_import"]
|
utilities/subprocess.py
CHANGED
|
@@ -43,6 +43,7 @@ _HOST_KEY_ALGORITHMS = ["ssh-ed25519"]
|
|
|
43
43
|
APT_UPDATE = ["apt", "update", "-y"]
|
|
44
44
|
BASH_LC = ["bash", "-lc"]
|
|
45
45
|
BASH_LS = ["bash", "-ls"]
|
|
46
|
+
CHPASSWD = "chpasswd"
|
|
46
47
|
GIT_BRANCH_SHOW_CURRENT = ["git", "branch", "--show-current"]
|
|
47
48
|
KNOWN_HOSTS = Path.home() / ".ssh/known_hosts"
|
|
48
49
|
MKTEMP_DIR_CMD = ["mktemp", "-d"]
|
|
@@ -92,9 +93,6 @@ def chmod(path: PathLike, perms: PermissionsLike, /, *, sudo: bool = False) -> N
|
|
|
92
93
|
Path(path).chmod(int(ensure_perms(perms)))
|
|
93
94
|
|
|
94
95
|
|
|
95
|
-
##
|
|
96
|
-
|
|
97
|
-
|
|
98
96
|
def chmod_cmd(path: PathLike, perms: PermissionsLike, /) -> list[str]:
|
|
99
97
|
"""Command to use 'chmod' to change file mode."""
|
|
100
98
|
return ["chmod", str(ensure_perms(perms)), str(path)]
|
|
@@ -134,9 +132,6 @@ def chown(
|
|
|
134
132
|
assert_never(never)
|
|
135
133
|
|
|
136
134
|
|
|
137
|
-
##
|
|
138
|
-
|
|
139
|
-
|
|
140
135
|
def chown_cmd(
|
|
141
136
|
path: PathLike, /, *, user: str | int | None = None, group: str | int | None = None
|
|
142
137
|
) -> list[str]:
|
|
@@ -165,6 +160,16 @@ class ChownCmdError(Exception):
|
|
|
165
160
|
##
|
|
166
161
|
|
|
167
162
|
|
|
163
|
+
def chpasswd(user_name: str, password: str, /, *, sudo: bool = False) -> None:
|
|
164
|
+
"""Update passwords."""
|
|
165
|
+
run( # pragma: no cover
|
|
166
|
+
*maybe_sudo_cmd(CHPASSWD, sudo=sudo), input=f"{user_name}:{password}"
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
##
|
|
171
|
+
|
|
172
|
+
|
|
168
173
|
def cp(
|
|
169
174
|
src: PathLike,
|
|
170
175
|
dest: PathLike,
|
|
@@ -1232,15 +1237,15 @@ def sudo_nopasswd_cmd(user: str, /) -> str:
|
|
|
1232
1237
|
##
|
|
1233
1238
|
|
|
1234
1239
|
|
|
1235
|
-
def symlink(
|
|
1240
|
+
def symlink(target: PathLike, link: PathLike, /, *, sudo: bool = False) -> None:
|
|
1236
1241
|
"""Make a symbolic link."""
|
|
1237
1242
|
rm(link, sudo=sudo)
|
|
1238
1243
|
mkdir(link, sudo=sudo, parent=True)
|
|
1239
1244
|
if sudo: # pragma: no cover
|
|
1240
|
-
run(*sudo_cmd(*symlink_cmd(
|
|
1245
|
+
run(*sudo_cmd(*symlink_cmd(target, link)))
|
|
1241
1246
|
else:
|
|
1242
|
-
|
|
1243
|
-
link.symlink_to(
|
|
1247
|
+
target, link = map(Path, [target, link])
|
|
1248
|
+
link.symlink_to(target)
|
|
1244
1249
|
|
|
1245
1250
|
|
|
1246
1251
|
def symlink_cmd(target: PathLike, link: PathLike, /) -> list[str]:
|
|
@@ -1288,12 +1293,54 @@ def touch_cmd(path: PathLike, /) -> list[str]:
|
|
|
1288
1293
|
|
|
1289
1294
|
|
|
1290
1295
|
def update_ca_certificates(*, sudo: bool = False) -> None:
|
|
1296
|
+
"""Update the system CA certificates."""
|
|
1291
1297
|
run(*maybe_sudo_cmd(UPDATE_CA_CERTIFICATES, sudo=sudo)) # pragma: no cover
|
|
1292
1298
|
|
|
1293
1299
|
|
|
1294
1300
|
##
|
|
1295
1301
|
|
|
1296
1302
|
|
|
1303
|
+
def useradd(
|
|
1304
|
+
login: str,
|
|
1305
|
+
/,
|
|
1306
|
+
*,
|
|
1307
|
+
create_home: bool = True,
|
|
1308
|
+
groups: MaybeIterable[str] | None = None,
|
|
1309
|
+
shell: PathLike | None = None,
|
|
1310
|
+
sudo: bool = False,
|
|
1311
|
+
password: str | None = None,
|
|
1312
|
+
) -> None:
|
|
1313
|
+
"""Create a new user."""
|
|
1314
|
+
args = maybe_sudo_cmd( # pragma: no cover
|
|
1315
|
+
*useradd_cmd(login, create_home=create_home, groups=groups, shell=shell)
|
|
1316
|
+
)
|
|
1317
|
+
run(*args) # pragma: no cover
|
|
1318
|
+
if password is not None: # pragma: no cover
|
|
1319
|
+
chpasswd(login, password, sudo=sudo)
|
|
1320
|
+
|
|
1321
|
+
|
|
1322
|
+
def useradd_cmd(
|
|
1323
|
+
login: str,
|
|
1324
|
+
/,
|
|
1325
|
+
*,
|
|
1326
|
+
create_home: bool = True,
|
|
1327
|
+
groups: MaybeIterable[str] | None = None,
|
|
1328
|
+
shell: PathLike | None = None,
|
|
1329
|
+
) -> list[str]:
|
|
1330
|
+
"""Command to use 'useradd' to create a new user."""
|
|
1331
|
+
args: list[str] = ["useradd"]
|
|
1332
|
+
if create_home:
|
|
1333
|
+
args.append("--create-home")
|
|
1334
|
+
if groups is not None:
|
|
1335
|
+
args.extend(["--groups", *always_iterable(groups)])
|
|
1336
|
+
if shell is not None:
|
|
1337
|
+
args.extend(["--shell", str(shell)])
|
|
1338
|
+
return [*args, login]
|
|
1339
|
+
|
|
1340
|
+
|
|
1341
|
+
##
|
|
1342
|
+
|
|
1343
|
+
|
|
1297
1344
|
@overload
|
|
1298
1345
|
def uv_run(
|
|
1299
1346
|
module: str,
|
|
@@ -1456,6 +1503,7 @@ __all__ = [
|
|
|
1456
1503
|
"APT_UPDATE",
|
|
1457
1504
|
"BASH_LC",
|
|
1458
1505
|
"BASH_LS",
|
|
1506
|
+
"CHPASSWD",
|
|
1459
1507
|
"GIT_BRANCH_SHOW_CURRENT",
|
|
1460
1508
|
"MKTEMP_DIR_CMD",
|
|
1461
1509
|
"RESTART_SSHD",
|
|
@@ -1473,6 +1521,7 @@ __all__ = [
|
|
|
1473
1521
|
"chmod_cmd",
|
|
1474
1522
|
"chown",
|
|
1475
1523
|
"chown_cmd",
|
|
1524
|
+
"chpasswd",
|
|
1476
1525
|
"cp",
|
|
1477
1526
|
"cp_cmd",
|
|
1478
1527
|
"echo_cmd",
|
|
@@ -1514,6 +1563,8 @@ __all__ = [
|
|
|
1514
1563
|
"touch",
|
|
1515
1564
|
"touch_cmd",
|
|
1516
1565
|
"update_ca_certificates",
|
|
1566
|
+
"useradd",
|
|
1567
|
+
"useradd_cmd",
|
|
1517
1568
|
"uv_run",
|
|
1518
1569
|
"uv_run_cmd",
|
|
1519
1570
|
"yield_git_repo",
|
|
File without changes
|
|
File without changes
|