dycw-utilities 0.173.5__tar.gz → 0.174.0__tar.gz
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.173.5 → dycw_utilities-0.174.0}/PKG-INFO +1 -1
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/pyproject.toml +2 -2
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/__init__.py +1 -1
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/docker.py +12 -15
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/subprocess.py +166 -64
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/README.md +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/aeventkit.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/altair.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/asyncio.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/atomicwrites.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/atools.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/cachetools.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/click.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/concurrent.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/contextlib.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/contextvars.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/cryptography.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/cvxpy.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/dataclasses.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/enum.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/errors.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/fastapi.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/fpdf2.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/functions.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/functools.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/getpass.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/git.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/grp.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/gzip.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/hashlib.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/http.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/hypothesis.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/importlib.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/inflect.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/ipython.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/iterables.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/jinja2.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/json.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/jupyter.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/libcst.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/lightweight_charts.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/logging.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/math.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/memory_profiler.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/modules.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/more_itertools.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/numpy.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/operator.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/optuna.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/orjson.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/os.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/parse.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/pathlib.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/pickle.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/platform.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/polars.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/polars_ols.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/postgres.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/pottery.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/pqdm.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/psutil.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/pwd.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/py.typed +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/pydantic.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/pydantic_settings.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/pydantic_settings_sops.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/pyinstrument.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/pytest.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/pytest_plugins/__init__.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/pytest_plugins/pytest_randomly.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/pytest_plugins/pytest_regressions.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/pytest_regressions.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/random.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/re.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/redis.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/reprlib.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/scipy.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/sentinel.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/shelve.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/shutil.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/slack_sdk.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/socket.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/sqlalchemy.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/sqlalchemy_polars.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/statsmodels.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/string.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/tempfile.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/testbook.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/text.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/threading.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/timer.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/traceback.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/types.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/typing.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/tzdata.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/tzlocal.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/uuid.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/version.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/warnings.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/whenever.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/zipfile.py +0 -0
- {dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/zoneinfo.py +0 -0
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
name = "dycw-utilities"
|
|
102
102
|
readme = "README.md"
|
|
103
103
|
requires-python = ">= 3.12"
|
|
104
|
-
version = "0.
|
|
104
|
+
version = "0.174.0"
|
|
105
105
|
|
|
106
106
|
[project.entry-points.pytest11]
|
|
107
107
|
pytest-randomly = "utilities.pytest_plugins.pytest_randomly"
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
# bump-my-version
|
|
136
136
|
[tool.bumpversion]
|
|
137
137
|
allow_dirty = true
|
|
138
|
-
current_version = "0.
|
|
138
|
+
current_version = "0.174.0"
|
|
139
139
|
|
|
140
140
|
[[tool.bumpversion.files]]
|
|
141
141
|
filename = "src/utilities/__init__.py"
|
|
@@ -7,7 +7,6 @@ from typing import TYPE_CHECKING, Literal, overload
|
|
|
7
7
|
from utilities.errors import ImpossibleCaseError
|
|
8
8
|
from utilities.subprocess import (
|
|
9
9
|
MKTEMP_DIR_CMD,
|
|
10
|
-
bash_cmd_and_args,
|
|
11
10
|
maybe_sudo_cmd,
|
|
12
11
|
mkdir,
|
|
13
12
|
mkdir_cmd,
|
|
@@ -100,7 +99,7 @@ def docker_exec(
|
|
|
100
99
|
env: StrStrMapping | None = None,
|
|
101
100
|
user: str | None = None,
|
|
102
101
|
workdir: PathLike | None = None,
|
|
103
|
-
|
|
102
|
+
input: str | None = None,
|
|
104
103
|
print: bool = False,
|
|
105
104
|
print_stdout: bool = False,
|
|
106
105
|
print_stderr: bool = False,
|
|
@@ -119,7 +118,7 @@ def docker_exec(
|
|
|
119
118
|
env: StrStrMapping | None = None,
|
|
120
119
|
user: str | None = None,
|
|
121
120
|
workdir: PathLike | None = None,
|
|
122
|
-
|
|
121
|
+
input: str | None = None,
|
|
123
122
|
print: bool = False,
|
|
124
123
|
print_stdout: bool = False,
|
|
125
124
|
print_stderr: bool = False,
|
|
@@ -138,7 +137,7 @@ def docker_exec(
|
|
|
138
137
|
env: StrStrMapping | None = None,
|
|
139
138
|
user: str | None = None,
|
|
140
139
|
workdir: PathLike | None = None,
|
|
141
|
-
|
|
140
|
+
input: str | None = None,
|
|
142
141
|
print: bool = False,
|
|
143
142
|
print_stdout: bool = False,
|
|
144
143
|
print_stderr: bool = False,
|
|
@@ -157,7 +156,7 @@ def docker_exec(
|
|
|
157
156
|
env: StrStrMapping | None = None,
|
|
158
157
|
user: str | None = None,
|
|
159
158
|
workdir: PathLike | None = None,
|
|
160
|
-
|
|
159
|
+
input: str | None = None,
|
|
161
160
|
print: bool = False,
|
|
162
161
|
print_stdout: bool = False,
|
|
163
162
|
print_stderr: bool = False,
|
|
@@ -176,7 +175,7 @@ def docker_exec(
|
|
|
176
175
|
env: StrStrMapping | None = None,
|
|
177
176
|
user: str | None = None,
|
|
178
177
|
workdir: PathLike | None = None,
|
|
179
|
-
|
|
178
|
+
input: str | None = None,
|
|
180
179
|
print: bool = False,
|
|
181
180
|
print_stdout: bool = False,
|
|
182
181
|
print_stderr: bool = False,
|
|
@@ -194,7 +193,7 @@ def docker_exec(
|
|
|
194
193
|
env: StrStrMapping | None = None,
|
|
195
194
|
user: str | None = None,
|
|
196
195
|
workdir: PathLike | None = None,
|
|
197
|
-
|
|
196
|
+
input: str | None = None, # noqa: A002
|
|
198
197
|
print: bool = False, # noqa: A002
|
|
199
198
|
print_stdout: bool = False,
|
|
200
199
|
print_stderr: bool = False,
|
|
@@ -209,13 +208,14 @@ def docker_exec(
|
|
|
209
208
|
cmd,
|
|
210
209
|
*cmds_or_args,
|
|
211
210
|
env=env,
|
|
211
|
+
interactive=input is not None,
|
|
212
212
|
user=user,
|
|
213
213
|
workdir=workdir,
|
|
214
|
-
bash=bash,
|
|
215
214
|
**env_kwargs,
|
|
216
215
|
)
|
|
217
216
|
return run( # skipif-ci
|
|
218
217
|
*cmd_and_args,
|
|
218
|
+
input=input,
|
|
219
219
|
print=print,
|
|
220
220
|
print_stdout=print_stdout,
|
|
221
221
|
print_stderr=print_stderr,
|
|
@@ -232,9 +232,9 @@ def docker_exec_cmd(
|
|
|
232
232
|
/,
|
|
233
233
|
*cmds_or_args: str,
|
|
234
234
|
env: StrStrMapping | None = None,
|
|
235
|
+
interactive: bool = False,
|
|
235
236
|
user: str | None = None,
|
|
236
237
|
workdir: PathLike | None = None,
|
|
237
|
-
bash: bool = False,
|
|
238
238
|
**env_kwargs: str,
|
|
239
239
|
) -> list[str]:
|
|
240
240
|
"""Build a command for `docker exec`."""
|
|
@@ -242,16 +242,13 @@ def docker_exec_cmd(
|
|
|
242
242
|
mapping: dict[str, str] = ({} if env is None else dict(env)) | env_kwargs
|
|
243
243
|
for key, value in mapping.items():
|
|
244
244
|
args.extend(["--env", f"{key}={value}"])
|
|
245
|
+
if interactive:
|
|
246
|
+
args.append("--interactive")
|
|
245
247
|
if user is not None:
|
|
246
248
|
args.extend(["--user", user])
|
|
247
249
|
if workdir is not None:
|
|
248
250
|
args.extend(["--workdir", str(workdir)])
|
|
249
|
-
args
|
|
250
|
-
if bash:
|
|
251
|
-
args.extend(bash_cmd_and_args(cmd, *cmds_or_args))
|
|
252
|
-
else:
|
|
253
|
-
args.extend([cmd, *cmds_or_args])
|
|
254
|
-
return args
|
|
251
|
+
return [*args, container, cmd, *cmds_or_args]
|
|
255
252
|
|
|
256
253
|
|
|
257
254
|
@contextmanager
|
|
@@ -20,13 +20,11 @@ if TYPE_CHECKING:
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
_HOST_KEY_ALGORITHMS = ["ssh-ed25519"]
|
|
23
|
+
BASH_LC = ["bash", "-lc"]
|
|
24
|
+
BASH_LS = ["bash", "-ls"]
|
|
23
25
|
MKTEMP_DIR_CMD = ["mktemp", "-d"]
|
|
24
26
|
|
|
25
27
|
|
|
26
|
-
def bash_cmd_and_args(cmd: str, /, *cmds: str) -> list[str]:
|
|
27
|
-
return ["bash", "-lc", "\n".join([cmd, *cmds])]
|
|
28
|
-
|
|
29
|
-
|
|
30
28
|
def echo_cmd(text: str, /) -> list[str]:
|
|
31
29
|
return ["echo", text]
|
|
32
30
|
|
|
@@ -69,12 +67,12 @@ def run(
|
|
|
69
67
|
cmd: str,
|
|
70
68
|
/,
|
|
71
69
|
*cmds_or_args: str,
|
|
72
|
-
bash: bool = False,
|
|
73
70
|
user: str | int | None = None,
|
|
74
71
|
executable: str | None = None,
|
|
75
72
|
shell: bool = False,
|
|
76
73
|
cwd: PathLike | None = None,
|
|
77
74
|
env: StrStrMapping | None = None,
|
|
75
|
+
input: str | None = None,
|
|
78
76
|
print: bool = False,
|
|
79
77
|
print_stdout: bool = False,
|
|
80
78
|
print_stderr: bool = False,
|
|
@@ -88,12 +86,12 @@ def run(
|
|
|
88
86
|
cmd: str,
|
|
89
87
|
/,
|
|
90
88
|
*cmds_or_args: str,
|
|
91
|
-
bash: bool = False,
|
|
92
89
|
user: str | int | None = None,
|
|
93
90
|
executable: str | None = None,
|
|
94
91
|
shell: bool = False,
|
|
95
92
|
cwd: PathLike | None = None,
|
|
96
93
|
env: StrStrMapping | None = None,
|
|
94
|
+
input: str | None = None,
|
|
97
95
|
print: bool = False,
|
|
98
96
|
print_stdout: bool = False,
|
|
99
97
|
print_stderr: bool = False,
|
|
@@ -107,12 +105,12 @@ def run(
|
|
|
107
105
|
cmd: str,
|
|
108
106
|
/,
|
|
109
107
|
*cmds_or_args: str,
|
|
110
|
-
bash: bool = False,
|
|
111
108
|
user: str | int | None = None,
|
|
112
109
|
executable: str | None = None,
|
|
113
110
|
shell: bool = False,
|
|
114
111
|
cwd: PathLike | None = None,
|
|
115
112
|
env: StrStrMapping | None = None,
|
|
113
|
+
input: str | None = None,
|
|
116
114
|
print: bool = False,
|
|
117
115
|
print_stdout: bool = False,
|
|
118
116
|
print_stderr: bool = False,
|
|
@@ -126,12 +124,12 @@ def run(
|
|
|
126
124
|
cmd: str,
|
|
127
125
|
/,
|
|
128
126
|
*cmds_or_args: str,
|
|
129
|
-
bash: bool = False,
|
|
130
127
|
user: str | int | None = None,
|
|
131
128
|
executable: str | None = None,
|
|
132
129
|
shell: bool = False,
|
|
133
130
|
cwd: PathLike | None = None,
|
|
134
131
|
env: StrStrMapping | None = None,
|
|
132
|
+
input: str | None = None,
|
|
135
133
|
print: bool = False,
|
|
136
134
|
print_stdout: bool = False,
|
|
137
135
|
print_stderr: bool = False,
|
|
@@ -145,12 +143,12 @@ def run(
|
|
|
145
143
|
cmd: str,
|
|
146
144
|
/,
|
|
147
145
|
*cmds_or_args: str,
|
|
148
|
-
bash: bool = False,
|
|
149
146
|
user: str | int | None = None,
|
|
150
147
|
executable: str | None = None,
|
|
151
148
|
shell: bool = False,
|
|
152
149
|
cwd: PathLike | None = None,
|
|
153
150
|
env: StrStrMapping | None = None,
|
|
151
|
+
input: str | None = None,
|
|
154
152
|
print: bool = False,
|
|
155
153
|
print_stdout: bool = False,
|
|
156
154
|
print_stderr: bool = False,
|
|
@@ -163,12 +161,12 @@ def run(
|
|
|
163
161
|
cmd: str,
|
|
164
162
|
/,
|
|
165
163
|
*cmds_or_args: str,
|
|
166
|
-
bash: bool = False,
|
|
167
164
|
user: str | int | None = None,
|
|
168
165
|
executable: str | None = None,
|
|
169
166
|
shell: bool = False,
|
|
170
167
|
cwd: PathLike | None = None,
|
|
171
168
|
env: StrStrMapping | None = None,
|
|
169
|
+
input: str | None = None, # noqa: A002
|
|
172
170
|
print: bool = False, # noqa: A002
|
|
173
171
|
print_stdout: bool = False,
|
|
174
172
|
print_stderr: bool = False,
|
|
@@ -177,55 +175,46 @@ def run(
|
|
|
177
175
|
return_stderr: bool = False,
|
|
178
176
|
logger: LoggerLike | None = None,
|
|
179
177
|
) -> str | None:
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
args: list[str] = bash_cmd_and_args(cmd, *cmds_or_args)
|
|
185
|
-
user_use = None
|
|
186
|
-
case True, str() | int(): # skipif-ci-or-mac
|
|
187
|
-
args: list[str] = [
|
|
188
|
-
"su",
|
|
189
|
-
"-",
|
|
190
|
-
str(user),
|
|
191
|
-
*bash_cmd_and_args(cmd, *cmds_or_args),
|
|
192
|
-
]
|
|
193
|
-
user_use = None
|
|
194
|
-
case never:
|
|
195
|
-
assert_never(never)
|
|
178
|
+
args: list[str] = []
|
|
179
|
+
if user is not None:
|
|
180
|
+
args.extend(["su", "-", str(user)])
|
|
181
|
+
args.extend([cmd, *cmds_or_args])
|
|
196
182
|
buffer = StringIO()
|
|
197
183
|
stdout = StringIO()
|
|
198
184
|
stderr = StringIO()
|
|
185
|
+
stdout_outputs: list[IO[str]] = [buffer, stdout]
|
|
186
|
+
if print or print_stdout:
|
|
187
|
+
stdout_outputs.append(sys.stdout)
|
|
188
|
+
stderr_outputs: list[IO[str]] = [buffer, stderr]
|
|
189
|
+
if print or print_stderr:
|
|
190
|
+
stderr_outputs.append(sys.stderr)
|
|
199
191
|
with Popen(
|
|
200
192
|
args,
|
|
201
193
|
bufsize=1,
|
|
202
194
|
executable=executable,
|
|
195
|
+
stdin=PIPE,
|
|
203
196
|
stdout=PIPE,
|
|
204
197
|
stderr=PIPE,
|
|
205
198
|
shell=shell,
|
|
206
199
|
cwd=cwd,
|
|
207
200
|
env=env,
|
|
208
201
|
text=True,
|
|
209
|
-
user=
|
|
202
|
+
user=user,
|
|
210
203
|
) as proc:
|
|
204
|
+
if proc.stdin is None: # pragma: no cover
|
|
205
|
+
raise ImpossibleCaseError(case=[f"{proc.stdin=}"])
|
|
211
206
|
if proc.stdout is None: # pragma: no cover
|
|
212
207
|
raise ImpossibleCaseError(case=[f"{proc.stdout=}"])
|
|
213
208
|
if proc.stderr is None: # pragma: no cover
|
|
214
209
|
raise ImpossibleCaseError(case=[f"{proc.stderr=}"])
|
|
215
210
|
with (
|
|
216
|
-
_yield_write(
|
|
217
|
-
|
|
218
|
-
buffer,
|
|
219
|
-
stdout,
|
|
220
|
-
*([sys.stdout] if print or print_stdout else []),
|
|
221
|
-
),
|
|
222
|
-
_yield_write(
|
|
223
|
-
proc.stderr,
|
|
224
|
-
buffer,
|
|
225
|
-
stderr,
|
|
226
|
-
*([sys.stderr] if print or print_stderr else []),
|
|
227
|
-
),
|
|
211
|
+
_yield_write(proc.stdout, "proc.stdout", *stdout_outputs),
|
|
212
|
+
_yield_write(proc.stderr, "proc.stderr", *stderr_outputs),
|
|
228
213
|
):
|
|
214
|
+
if input is not None:
|
|
215
|
+
_ = proc.stdin.write(input)
|
|
216
|
+
proc.stdin.flush()
|
|
217
|
+
proc.stdin.close()
|
|
229
218
|
return_code = proc.wait()
|
|
230
219
|
match return_code, return_ or return_stdout, return_ or return_stderr:
|
|
231
220
|
case 0, True, True:
|
|
@@ -247,14 +236,14 @@ def run(
|
|
|
247
236
|
if logger is not None:
|
|
248
237
|
msg = strip_and_dedent(f"""
|
|
249
238
|
'run' failed with:
|
|
250
|
-
- cmd
|
|
251
|
-
-
|
|
252
|
-
-
|
|
253
|
-
-
|
|
254
|
-
-
|
|
255
|
-
-
|
|
256
|
-
-
|
|
257
|
-
-
|
|
239
|
+
- cmd = {cmd}
|
|
240
|
+
- cmds_or_args = {cmds_or_args}
|
|
241
|
+
- user = {user}
|
|
242
|
+
- executable = {executable}
|
|
243
|
+
- shell = {shell}
|
|
244
|
+
- cwd = {cwd}
|
|
245
|
+
- env = {env}
|
|
246
|
+
- input = {input}
|
|
258
247
|
|
|
259
248
|
-- stdout ---------------------------------------------------------------------
|
|
260
249
|
{stdout_text}-------------------------------------------------------------------------------
|
|
@@ -270,8 +259,8 @@ def run(
|
|
|
270
259
|
|
|
271
260
|
|
|
272
261
|
@contextmanager
|
|
273
|
-
def _yield_write(input_: IO[str], /, *outputs: IO[str]) -> Iterator[None]:
|
|
274
|
-
thread = Thread(target=_run_target, args=(input_, *outputs), daemon=True)
|
|
262
|
+
def _yield_write(input_: IO[str], desc: str, /, *outputs: IO[str]) -> Iterator[None]:
|
|
263
|
+
thread = Thread(target=_run_target, args=(input_, desc, *outputs), daemon=True)
|
|
275
264
|
thread.start()
|
|
276
265
|
try:
|
|
277
266
|
yield
|
|
@@ -279,23 +268,139 @@ def _yield_write(input_: IO[str], /, *outputs: IO[str]) -> Iterator[None]:
|
|
|
279
268
|
thread.join()
|
|
280
269
|
|
|
281
270
|
|
|
282
|
-
def _run_target(input_: IO[str], /, *outputs: IO[str]) -> None:
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
for
|
|
286
|
-
|
|
271
|
+
def _run_target(input_: IO[str], desc: str, /, *outputs: IO[str]) -> None:
|
|
272
|
+
try:
|
|
273
|
+
with input_:
|
|
274
|
+
for text in iter(input_.readline, ""):
|
|
275
|
+
_write_to_streams(text, *outputs)
|
|
276
|
+
except ValueError:
|
|
277
|
+
_ = sys.stderr.write(f"Failed to write to {desc!r}...")
|
|
278
|
+
raise
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
def _write_to_streams(text: str, /, *outputs: IO[str]) -> None:
|
|
282
|
+
for output in outputs:
|
|
283
|
+
_ = output.write(text)
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
@overload
|
|
287
|
+
def ssh(
|
|
288
|
+
user: str,
|
|
289
|
+
hostname: str,
|
|
290
|
+
/,
|
|
291
|
+
*cmd_and_cmds_or_args: str,
|
|
292
|
+
batch_mode: bool = True,
|
|
293
|
+
host_key_algorithms: list[str] = _HOST_KEY_ALGORITHMS,
|
|
294
|
+
strict_host_key_checking: bool = True,
|
|
295
|
+
input: str | None = None,
|
|
296
|
+
print: bool = False,
|
|
297
|
+
print_stdout: bool = False,
|
|
298
|
+
print_stderr: bool = False,
|
|
299
|
+
return_: Literal[True],
|
|
300
|
+
return_stdout: bool = False,
|
|
301
|
+
return_stderr: bool = False,
|
|
302
|
+
logger: LoggerLike | None = None,
|
|
303
|
+
) -> str: ...
|
|
304
|
+
@overload
|
|
305
|
+
def ssh(
|
|
306
|
+
user: str,
|
|
307
|
+
hostname: str,
|
|
308
|
+
/,
|
|
309
|
+
*cmd_and_cmds_or_args: str,
|
|
310
|
+
batch_mode: bool = True,
|
|
311
|
+
host_key_algorithms: list[str] = _HOST_KEY_ALGORITHMS,
|
|
312
|
+
strict_host_key_checking: bool = True,
|
|
313
|
+
input: str | None = None,
|
|
314
|
+
print: bool = False,
|
|
315
|
+
print_stdout: bool = False,
|
|
316
|
+
print_stderr: bool = False,
|
|
317
|
+
return_: bool = False,
|
|
318
|
+
return_stdout: Literal[True],
|
|
319
|
+
return_stderr: bool = False,
|
|
320
|
+
logger: LoggerLike | None = None,
|
|
321
|
+
) -> str: ...
|
|
322
|
+
@overload
|
|
323
|
+
def ssh(
|
|
324
|
+
user: str,
|
|
325
|
+
hostname: str,
|
|
326
|
+
/,
|
|
327
|
+
*cmd_and_cmds_or_args: str,
|
|
328
|
+
batch_mode: bool = True,
|
|
329
|
+
host_key_algorithms: list[str] = _HOST_KEY_ALGORITHMS,
|
|
330
|
+
strict_host_key_checking: bool = True,
|
|
331
|
+
input: str | None = None,
|
|
332
|
+
print: bool = False,
|
|
333
|
+
print_stdout: bool = False,
|
|
334
|
+
print_stderr: bool = False,
|
|
335
|
+
return_: bool = False,
|
|
336
|
+
return_stdout: bool = False,
|
|
337
|
+
return_stderr: Literal[True],
|
|
338
|
+
logger: LoggerLike | None = None,
|
|
339
|
+
) -> str: ...
|
|
340
|
+
@overload
|
|
341
|
+
def ssh(
|
|
342
|
+
user: str,
|
|
343
|
+
hostname: str,
|
|
344
|
+
/,
|
|
345
|
+
*cmd_and_cmds_or_args: str,
|
|
346
|
+
batch_mode: bool = True,
|
|
347
|
+
host_key_algorithms: list[str] = _HOST_KEY_ALGORITHMS,
|
|
348
|
+
strict_host_key_checking: bool = True,
|
|
349
|
+
input: str | None = None,
|
|
350
|
+
print: bool = False,
|
|
351
|
+
print_stdout: bool = False,
|
|
352
|
+
print_stderr: bool = False,
|
|
353
|
+
return_: Literal[False] = False,
|
|
354
|
+
return_stdout: Literal[False] = False,
|
|
355
|
+
return_stderr: Literal[False] = False,
|
|
356
|
+
logger: LoggerLike | None = None,
|
|
357
|
+
) -> None: ...
|
|
358
|
+
def ssh(
|
|
359
|
+
user: str,
|
|
360
|
+
hostname: str,
|
|
361
|
+
/,
|
|
362
|
+
*cmd_and_cmds_or_args: str,
|
|
363
|
+
batch_mode: bool = True,
|
|
364
|
+
host_key_algorithms: list[str] = _HOST_KEY_ALGORITHMS,
|
|
365
|
+
strict_host_key_checking: bool = True,
|
|
366
|
+
input: str | None = None, # noqa: A002
|
|
367
|
+
print: bool = False, # noqa: A002
|
|
368
|
+
print_stdout: bool = False,
|
|
369
|
+
print_stderr: bool = False,
|
|
370
|
+
return_: bool = False,
|
|
371
|
+
return_stdout: bool = False,
|
|
372
|
+
return_stderr: bool = False,
|
|
373
|
+
logger: LoggerLike | None = None,
|
|
374
|
+
) -> str | None:
|
|
375
|
+
cmd_and_args = ssh_cmd( # skipif-ci
|
|
376
|
+
user,
|
|
377
|
+
hostname,
|
|
378
|
+
*cmd_and_cmds_or_args,
|
|
379
|
+
batch_mode=batch_mode,
|
|
380
|
+
host_key_algorithms=host_key_algorithms,
|
|
381
|
+
strict_host_key_checking=strict_host_key_checking,
|
|
382
|
+
)
|
|
383
|
+
return run( # skipif-ci
|
|
384
|
+
*cmd_and_args,
|
|
385
|
+
input=input,
|
|
386
|
+
print=print,
|
|
387
|
+
print_stdout=print_stdout,
|
|
388
|
+
print_stderr=print_stderr,
|
|
389
|
+
return_=return_,
|
|
390
|
+
return_stdout=return_stdout,
|
|
391
|
+
return_stderr=return_stderr,
|
|
392
|
+
logger=logger,
|
|
393
|
+
)
|
|
287
394
|
|
|
288
395
|
|
|
289
396
|
def ssh_cmd(
|
|
290
397
|
user: str,
|
|
291
398
|
hostname: str,
|
|
292
|
-
cmd: str,
|
|
293
399
|
/,
|
|
294
|
-
*
|
|
400
|
+
*cmd_and_cmds_or_args: str,
|
|
295
401
|
batch_mode: bool = True,
|
|
296
402
|
host_key_algorithms: list[str] = _HOST_KEY_ALGORITHMS,
|
|
297
403
|
strict_host_key_checking: bool = True,
|
|
298
|
-
bash: bool = False,
|
|
299
404
|
) -> list[str]:
|
|
300
405
|
args: list[str] = ["ssh"]
|
|
301
406
|
if batch_mode:
|
|
@@ -303,12 +408,7 @@ def ssh_cmd(
|
|
|
303
408
|
args.extend(["-o", f"HostKeyAlgorithms={','.join(host_key_algorithms)}"])
|
|
304
409
|
if strict_host_key_checking:
|
|
305
410
|
args.extend(["-o", "StrictHostKeyChecking=yes"])
|
|
306
|
-
args
|
|
307
|
-
if bash:
|
|
308
|
-
args.extend(bash_cmd_and_args(cmd, *cmds_or_args))
|
|
309
|
-
else:
|
|
310
|
-
args.extend([cmd, *cmds_or_args])
|
|
311
|
-
return args
|
|
411
|
+
return [*args, "-T", f"{user}@{hostname}", *cmd_and_cmds_or_args]
|
|
312
412
|
|
|
313
413
|
|
|
314
414
|
def sudo_cmd(cmd: str, /, *args: str) -> list[str]:
|
|
@@ -320,8 +420,9 @@ def touch_cmd(path: PathLike, /) -> list[str]:
|
|
|
320
420
|
|
|
321
421
|
|
|
322
422
|
__all__ = [
|
|
423
|
+
"BASH_LC",
|
|
424
|
+
"BASH_LS",
|
|
323
425
|
"MKTEMP_DIR_CMD",
|
|
324
|
-
"bash_cmd_and_args",
|
|
325
426
|
"echo_cmd",
|
|
326
427
|
"expand_path",
|
|
327
428
|
"maybe_sudo_cmd",
|
|
@@ -329,6 +430,7 @@ __all__ = [
|
|
|
329
430
|
"mkdir_cmd",
|
|
330
431
|
"rm_cmd",
|
|
331
432
|
"run",
|
|
433
|
+
"ssh",
|
|
332
434
|
"ssh_cmd",
|
|
333
435
|
"sudo_cmd",
|
|
334
436
|
"touch_cmd",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/pytest_plugins/pytest_randomly.py
RENAMED
|
File without changes
|
{dycw_utilities-0.173.5 → dycw_utilities-0.174.0}/src/utilities/pytest_plugins/pytest_regressions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|