dycw-utilities 0.174.2__py3-none-any.whl → 0.174.3__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.174.2.dist-info → dycw_utilities-0.174.3.dist-info}/METADATA +1 -1
- {dycw_utilities-0.174.2.dist-info → dycw_utilities-0.174.3.dist-info}/RECORD +6 -6
- utilities/__init__.py +1 -1
- utilities/subprocess.py +70 -78
- {dycw_utilities-0.174.2.dist-info → dycw_utilities-0.174.3.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.174.2.dist-info → dycw_utilities-0.174.3.dist-info}/entry_points.txt +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
utilities/__init__.py,sha256=
|
|
1
|
+
utilities/__init__.py,sha256=l_p1vPbF4nOs4tHjj2e93HKXxeAoQ_-FUBDK_Tm0K0I,60
|
|
2
2
|
utilities/aeventkit.py,sha256=OmDBhYGgbsKrB7cdC5FFpJHUatX9O76eTeKVVTksp2Y,12673
|
|
3
3
|
utilities/altair.py,sha256=rUK99g9x6CYDDfiZrf-aTx5fSRbL1Q8ctgKORowzXHg,9060
|
|
4
4
|
utilities/asyncio.py,sha256=aJySVxBY0gqsIYnoNmH7-1r8djKuf4vSsU69VCD08t8,16772
|
|
@@ -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=FlE_SWoA6nUCTR7CregeXtjM6xtqNuuT9y6hqgnb8ZY,15407
|
|
84
84
|
utilities/tempfile.py,sha256=Lx6qa16lL1XVH6WdmD_G9vlN6gLI8nrIurxmsFkPKvg,3022
|
|
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.174.
|
|
101
|
-
dycw_utilities-0.174.
|
|
102
|
-
dycw_utilities-0.174.
|
|
103
|
-
dycw_utilities-0.174.
|
|
100
|
+
dycw_utilities-0.174.3.dist-info/WHEEL,sha256=ZyFSCYkV2BrxH6-HRVRg3R9Fo7MALzer9KiPYqNxSbo,79
|
|
101
|
+
dycw_utilities-0.174.3.dist-info/entry_points.txt,sha256=ykGI1ArwOPHqm2g5Cqh3ENdMxEej_a_FcOUov5EM5Oc,155
|
|
102
|
+
dycw_utilities-0.174.3.dist-info/METADATA,sha256=XSqrLMadX1FSoqYHcNS8LSzYZ0eTrmXvGWWQk72wVhM,1709
|
|
103
|
+
dycw_utilities-0.174.3.dist-info/RECORD,,
|
utilities/__init__.py
CHANGED
utilities/subprocess.py
CHANGED
|
@@ -13,15 +13,16 @@ from typing import IO, TYPE_CHECKING, Literal, assert_never, overload
|
|
|
13
13
|
from utilities.errors import ImpossibleCaseError
|
|
14
14
|
from utilities.logging import to_logger
|
|
15
15
|
from utilities.text import strip_and_dedent
|
|
16
|
+
from utilities.types import Delta
|
|
17
|
+
from utilities.whenever import to_seconds
|
|
16
18
|
|
|
17
19
|
if TYPE_CHECKING:
|
|
18
20
|
from collections.abc import Iterator
|
|
19
21
|
|
|
20
|
-
from whenever import TimeDelta
|
|
21
|
-
|
|
22
22
|
from utilities.types import LoggerLike, PathLike, StrMapping, StrStrMapping
|
|
23
23
|
|
|
24
24
|
|
|
25
|
+
type _Retry = tuple[int, Delta | None]
|
|
25
26
|
_HOST_KEY_ALGORITHMS = ["ssh-ed25519"]
|
|
26
27
|
BASH_LC = ["bash", "-lc"]
|
|
27
28
|
BASH_LS = ["bash", "-ls"]
|
|
@@ -82,6 +83,7 @@ def run(
|
|
|
82
83
|
return_: Literal[True],
|
|
83
84
|
return_stdout: bool = False,
|
|
84
85
|
return_stderr: bool = False,
|
|
86
|
+
retry: _Retry | None = None,
|
|
85
87
|
logger: LoggerLike | None = None,
|
|
86
88
|
) -> str: ...
|
|
87
89
|
@overload
|
|
@@ -101,6 +103,7 @@ def run(
|
|
|
101
103
|
return_: bool = False,
|
|
102
104
|
return_stdout: Literal[True],
|
|
103
105
|
return_stderr: bool = False,
|
|
106
|
+
retry: _Retry | None = None,
|
|
104
107
|
logger: LoggerLike | None = None,
|
|
105
108
|
) -> str: ...
|
|
106
109
|
@overload
|
|
@@ -120,6 +123,7 @@ def run(
|
|
|
120
123
|
return_: bool = False,
|
|
121
124
|
return_stdout: bool = False,
|
|
122
125
|
return_stderr: Literal[True],
|
|
126
|
+
retry: _Retry | None = None,
|
|
123
127
|
logger: LoggerLike | None = None,
|
|
124
128
|
) -> str: ...
|
|
125
129
|
@overload
|
|
@@ -139,6 +143,7 @@ def run(
|
|
|
139
143
|
return_: Literal[False] = False,
|
|
140
144
|
return_stdout: Literal[False] = False,
|
|
141
145
|
return_stderr: Literal[False] = False,
|
|
146
|
+
retry: _Retry | None = None,
|
|
142
147
|
logger: LoggerLike | None = None,
|
|
143
148
|
) -> None: ...
|
|
144
149
|
@overload
|
|
@@ -158,6 +163,7 @@ def run(
|
|
|
158
163
|
return_: bool = False,
|
|
159
164
|
return_stdout: bool = False,
|
|
160
165
|
return_stderr: bool = False,
|
|
166
|
+
retry: _Retry | None = None,
|
|
161
167
|
logger: LoggerLike | None = None,
|
|
162
168
|
) -> str | None: ...
|
|
163
169
|
def run(
|
|
@@ -176,10 +182,11 @@ def run(
|
|
|
176
182
|
return_: bool = False,
|
|
177
183
|
return_stdout: bool = False,
|
|
178
184
|
return_stderr: bool = False,
|
|
185
|
+
retry: _Retry | None = None,
|
|
179
186
|
logger: LoggerLike | None = None,
|
|
180
187
|
) -> str | None:
|
|
181
188
|
args: list[str] = []
|
|
182
|
-
if user is not None:
|
|
189
|
+
if user is not None: # pragma: no cover
|
|
183
190
|
args.extend(["su", "-", str(user)])
|
|
184
191
|
args.extend([cmd, *cmds_or_args])
|
|
185
192
|
buffer = StringIO()
|
|
@@ -211,8 +218,8 @@ def run(
|
|
|
211
218
|
if proc.stderr is None: # pragma: no cover
|
|
212
219
|
raise ImpossibleCaseError(case=[f"{proc.stderr=}"])
|
|
213
220
|
with (
|
|
214
|
-
_yield_write(proc.stdout,
|
|
215
|
-
_yield_write(proc.stderr,
|
|
221
|
+
_yield_write(proc.stdout, *stdout_outputs),
|
|
222
|
+
_yield_write(proc.stderr, *stderr_outputs),
|
|
216
223
|
):
|
|
217
224
|
if input is not None:
|
|
218
225
|
_ = proc.stdin.write(input)
|
|
@@ -232,6 +239,10 @@ def run(
|
|
|
232
239
|
case 0, False, False:
|
|
233
240
|
return None
|
|
234
241
|
case _, _, _:
|
|
242
|
+
if retry is None:
|
|
243
|
+
attempts = delta = None
|
|
244
|
+
else:
|
|
245
|
+
attempts, delta = retry
|
|
235
246
|
_ = stdout.seek(0)
|
|
236
247
|
stdout_text = stdout.read()
|
|
237
248
|
_ = stderr.seek(0)
|
|
@@ -246,24 +257,52 @@ def run(
|
|
|
246
257
|
- shell = {shell}
|
|
247
258
|
- cwd = {cwd}
|
|
248
259
|
- env = {env}
|
|
249
|
-
- input = {input}
|
|
250
260
|
|
|
261
|
+
-- stdin ----------------------------------------------------------------------
|
|
262
|
+
{"" if input is None else input}-------------------------------------------------------------------------------
|
|
251
263
|
-- stdout ---------------------------------------------------------------------
|
|
252
264
|
{stdout_text}-------------------------------------------------------------------------------
|
|
253
265
|
-- stderr ---------------------------------------------------------------------
|
|
254
266
|
{stderr_text}-------------------------------------------------------------------------------
|
|
255
267
|
""")
|
|
268
|
+
if (attempts is not None) and (attempts >= 1):
|
|
269
|
+
if delta is None:
|
|
270
|
+
msg = f"{msg}\n\nRetrying {attempts} more time(s)..."
|
|
271
|
+
else:
|
|
272
|
+
msg = f"{msg}\n\nRetrying {attempts} more time(s) after {delta}..."
|
|
256
273
|
to_logger(logger).error(msg)
|
|
257
|
-
|
|
274
|
+
error = CalledProcessError(
|
|
258
275
|
return_code, args, output=stdout_text, stderr=stderr_text
|
|
259
276
|
)
|
|
277
|
+
if (attempts is None) or (attempts <= 0):
|
|
278
|
+
raise error
|
|
279
|
+
if delta is not None:
|
|
280
|
+
sleep(to_seconds(delta))
|
|
281
|
+
return run(
|
|
282
|
+
cmd,
|
|
283
|
+
*cmds_or_args,
|
|
284
|
+
user=user,
|
|
285
|
+
executable=executable,
|
|
286
|
+
shell=shell,
|
|
287
|
+
cwd=cwd,
|
|
288
|
+
env=env,
|
|
289
|
+
input=input,
|
|
290
|
+
print=print,
|
|
291
|
+
print_stdout=print_stdout,
|
|
292
|
+
print_stderr=print_stderr,
|
|
293
|
+
return_=return_,
|
|
294
|
+
return_stdout=return_stdout,
|
|
295
|
+
return_stderr=return_stderr,
|
|
296
|
+
retry=(attempts - 1, delta),
|
|
297
|
+
logger=logger,
|
|
298
|
+
)
|
|
260
299
|
case never:
|
|
261
300
|
assert_never(never)
|
|
262
301
|
|
|
263
302
|
|
|
264
303
|
@contextmanager
|
|
265
|
-
def _yield_write(input_: IO[str],
|
|
266
|
-
thread = Thread(target=_run_target, args=(input_,
|
|
304
|
+
def _yield_write(input_: IO[str], /, *outputs: IO[str]) -> Iterator[None]:
|
|
305
|
+
thread = Thread(target=_run_target, args=(input_, *outputs), daemon=True)
|
|
267
306
|
thread.start()
|
|
268
307
|
try:
|
|
269
308
|
yield
|
|
@@ -271,14 +310,10 @@ def _yield_write(input_: IO[str], desc: str, /, *outputs: IO[str]) -> Iterator[N
|
|
|
271
310
|
thread.join()
|
|
272
311
|
|
|
273
312
|
|
|
274
|
-
def _run_target(input_: IO[str],
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
_write_to_streams(text, *outputs)
|
|
279
|
-
except ValueError:
|
|
280
|
-
_ = sys.stderr.write(f"Failed to write to {desc!r}...")
|
|
281
|
-
raise
|
|
313
|
+
def _run_target(input_: IO[str], /, *outputs: IO[str]) -> None:
|
|
314
|
+
with input_:
|
|
315
|
+
for text in iter(input_.readline, ""):
|
|
316
|
+
_write_to_streams(text, *outputs)
|
|
282
317
|
|
|
283
318
|
|
|
284
319
|
def _write_to_streams(text: str, /, *outputs: IO[str]) -> None:
|
|
@@ -302,8 +337,8 @@ def ssh(
|
|
|
302
337
|
return_: Literal[True],
|
|
303
338
|
return_stdout: bool = False,
|
|
304
339
|
return_stderr: bool = False,
|
|
340
|
+
retry: _Retry | None = None,
|
|
305
341
|
logger: LoggerLike | None = None,
|
|
306
|
-
retry: tuple[int, TimeDelta] | None = None,
|
|
307
342
|
) -> str: ...
|
|
308
343
|
@overload
|
|
309
344
|
def ssh(
|
|
@@ -321,8 +356,8 @@ def ssh(
|
|
|
321
356
|
return_: bool = False,
|
|
322
357
|
return_stdout: Literal[True],
|
|
323
358
|
return_stderr: bool = False,
|
|
359
|
+
retry: _Retry | None = None,
|
|
324
360
|
logger: LoggerLike | None = None,
|
|
325
|
-
retry: tuple[int, TimeDelta] | None = None,
|
|
326
361
|
) -> str: ...
|
|
327
362
|
@overload
|
|
328
363
|
def ssh(
|
|
@@ -340,8 +375,8 @@ def ssh(
|
|
|
340
375
|
return_: bool = False,
|
|
341
376
|
return_stdout: bool = False,
|
|
342
377
|
return_stderr: Literal[True],
|
|
378
|
+
retry: _Retry | None = None,
|
|
343
379
|
logger: LoggerLike | None = None,
|
|
344
|
-
retry: tuple[int, TimeDelta] | None = None,
|
|
345
380
|
) -> str: ...
|
|
346
381
|
@overload
|
|
347
382
|
def ssh(
|
|
@@ -359,8 +394,8 @@ def ssh(
|
|
|
359
394
|
return_: Literal[False] = False,
|
|
360
395
|
return_stdout: Literal[False] = False,
|
|
361
396
|
return_stderr: Literal[False] = False,
|
|
397
|
+
retry: _Retry | None = None,
|
|
362
398
|
logger: LoggerLike | None = None,
|
|
363
|
-
retry: tuple[int, TimeDelta] | None = None,
|
|
364
399
|
) -> None: ...
|
|
365
400
|
@overload
|
|
366
401
|
def ssh(
|
|
@@ -378,8 +413,8 @@ def ssh(
|
|
|
378
413
|
return_: bool = False,
|
|
379
414
|
return_stdout: bool = False,
|
|
380
415
|
return_stderr: bool = False,
|
|
416
|
+
retry: _Retry | None = None,
|
|
381
417
|
logger: LoggerLike | None = None,
|
|
382
|
-
retry: tuple[int, TimeDelta] | None = None,
|
|
383
418
|
) -> str | None: ...
|
|
384
419
|
def ssh(
|
|
385
420
|
user: str,
|
|
@@ -396,8 +431,8 @@ def ssh(
|
|
|
396
431
|
return_: bool = False,
|
|
397
432
|
return_stdout: bool = False,
|
|
398
433
|
return_stderr: bool = False,
|
|
434
|
+
retry: _Retry | None = None,
|
|
399
435
|
logger: LoggerLike | None = None,
|
|
400
|
-
retry: tuple[int, TimeDelta] | None = None,
|
|
401
436
|
) -> str | None:
|
|
402
437
|
cmd_and_args = ssh_cmd( # skipif-ci
|
|
403
438
|
user,
|
|
@@ -407,61 +442,18 @@ def ssh(
|
|
|
407
442
|
host_key_algorithms=host_key_algorithms,
|
|
408
443
|
strict_host_key_checking=strict_host_key_checking,
|
|
409
444
|
)
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
except CalledProcessError as error: # skipif-ci
|
|
423
|
-
if retry is None:
|
|
424
|
-
raise
|
|
425
|
-
attempts, delta = retry
|
|
426
|
-
if attempts <= 0:
|
|
427
|
-
raise
|
|
428
|
-
if logger is not None:
|
|
429
|
-
msg = strip_and_dedent(f"""
|
|
430
|
-
'ssh' failed with:
|
|
431
|
-
- user = {user}
|
|
432
|
-
- hostname = {hostname}
|
|
433
|
-
- cmd_and_cmds_or_args = {cmd_and_cmds_or_args}
|
|
434
|
-
- batch_mode = {batch_mode}
|
|
435
|
-
- host_key_algorithms = {host_key_algorithms}
|
|
436
|
-
- strict_host_key_checking = {strict_host_key_checking}
|
|
437
|
-
- input = {input}
|
|
438
|
-
|
|
439
|
-
-- stdout ---------------------------------------------------------------------
|
|
440
|
-
{error.stdout}-------------------------------------------------------------------------------
|
|
441
|
-
-- stderr ---------------------------------------------------------------------
|
|
442
|
-
{error.stderr}-------------------------------------------------------------------------------
|
|
443
|
-
|
|
444
|
-
Retrying {attempts} more time(s) after {delta}...
|
|
445
|
-
""")
|
|
446
|
-
to_logger(logger).error(msg)
|
|
447
|
-
sleep(delta.in_seconds())
|
|
448
|
-
return ssh(
|
|
449
|
-
user,
|
|
450
|
-
hostname,
|
|
451
|
-
*cmd_and_cmds_or_args,
|
|
452
|
-
batch_mode=batch_mode,
|
|
453
|
-
host_key_algorithms=host_key_algorithms,
|
|
454
|
-
strict_host_key_checking=strict_host_key_checking,
|
|
455
|
-
input=input,
|
|
456
|
-
print=print,
|
|
457
|
-
print_stdout=print_stdout,
|
|
458
|
-
print_stderr=print_stderr,
|
|
459
|
-
return_=return_,
|
|
460
|
-
return_stdout=return_stdout,
|
|
461
|
-
return_stderr=return_stderr,
|
|
462
|
-
logger=logger,
|
|
463
|
-
retry=(attempts - 1, delta),
|
|
464
|
-
)
|
|
445
|
+
return run( # skipif-ci
|
|
446
|
+
*cmd_and_args,
|
|
447
|
+
input=input,
|
|
448
|
+
print=print,
|
|
449
|
+
print_stdout=print_stdout,
|
|
450
|
+
print_stderr=print_stderr,
|
|
451
|
+
return_=return_,
|
|
452
|
+
return_stdout=return_stdout,
|
|
453
|
+
return_stderr=return_stderr,
|
|
454
|
+
retry=retry,
|
|
455
|
+
logger=logger,
|
|
456
|
+
)
|
|
465
457
|
|
|
466
458
|
|
|
467
459
|
def ssh_cmd(
|
|
File without changes
|
|
File without changes
|