dycw-utilities 0.174.3__py3-none-any.whl → 0.174.4__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.3
2
2
  Name: dycw-utilities
3
- Version: 0.174.3
3
+ Version: 0.174.4
4
4
  Author: Derek Wan
5
5
  Author-email: Derek Wan <d.wan@icloud.com>
6
6
  Requires-Dist: atomicwrites>=1.4.1,<1.5
@@ -1,4 +1,4 @@
1
- utilities/__init__.py,sha256=l_p1vPbF4nOs4tHjj2e93HKXxeAoQ_-FUBDK_Tm0K0I,60
1
+ utilities/__init__.py,sha256=IPAfPsoQRCu4p2HN4WqlBZlivN_FHMOLCjrLLfdu4EQ,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
@@ -12,7 +12,7 @@ utilities/contextvars.py,sha256=J8OhC7jqozAGYOCe2KUWysbPXNGe5JYz3HfaY_mIs08,883
12
12
  utilities/cryptography.py,sha256=5PFrzsNUGHay91dFgYnDKwYprXxahrBqztmUqViRzBk,956
13
13
  utilities/cvxpy.py,sha256=Rv1-fD-XYerosCavRF8Pohop2DBkU3AlFaGTfD8AEAA,13776
14
14
  utilities/dataclasses.py,sha256=xbU3QN1GFy7RC6hIJRZIeUZm7YRlodrgEWmahWG6k2g,32465
15
- utilities/docker.py,sha256=bLMXK1WCCoyVg92Yc4BNfaCXMaCIHRKEvqL2DiHTX4s,7270
15
+ utilities/docker.py,sha256=DBgSz-UPBDHk_XJLPNaNMkNym1kKK8l3Os8IqMwEyW8,7866
16
16
  utilities/enum.py,sha256=5l6pwZD1cjSlVW4ss-zBPspWvrbrYrdtJWcg6f5_J5w,5781
17
17
  utilities/errors.py,sha256=mFlDGSM0LI1jZ1pbqwLAH3ttLZ2JVIxyZLojw8tGVZU,1479
18
18
  utilities/fastapi.py,sha256=TqyKvBjiMS594sXPjrz-KRTLMb3l3D3rZ1zAYV7GfOk,1454
@@ -80,14 +80,14 @@ 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=FlE_SWoA6nUCTR7CregeXtjM6xtqNuuT9y6hqgnb8ZY,15407
83
+ utilities/subprocess.py,sha256=CWcaF5UUrR4JaXXTV-IwN9-4QFBN_bzl0AUileP2DJM,15452
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
87
87
  utilities/threading.py,sha256=GvBOp4CyhHfN90wGXZuA2VKe9fGzMaEa7oCl4f3nnPU,1009
88
88
  utilities/timer.py,sha256=BGlwEVznx67scuLOUohyWJ4d5rTnwtk-IR4yLXFiNfo,2574
89
89
  utilities/traceback.py,sha256=B_sc0TRUv-mGDnF-ek05nbqjmBiHr3-wvxliAqIF5hI,9608
90
- utilities/types.py,sha256=IlRrCtPdLkGYVfpe-QIg2qNUgBr8OJNN7BhTKxnhh-M,18817
90
+ utilities/types.py,sha256=UwxYajRnupKTCnzReaYWYqtKdpIPeSO-d97Wu4bLEq8,18878
91
91
  utilities/typing.py,sha256=xuR8LxzjD-XlSftTM3TNvGVdQyV1mzpdwWdDMzWwCPE,25310
92
92
  utilities/tzdata.py,sha256=fgNVj66yUbCSI_-vrRVzSD3gtf-L_8IEJEPjP_Jel5Y,266
93
93
  utilities/tzlocal.py,sha256=KyCXEgCTjqGFx-389JdTuhMRUaT06U1RCMdWoED-qro,728
@@ -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.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,,
100
+ dycw_utilities-0.174.4.dist-info/WHEEL,sha256=ZyFSCYkV2BrxH6-HRVRg3R9Fo7MALzer9KiPYqNxSbo,79
101
+ dycw_utilities-0.174.4.dist-info/entry_points.txt,sha256=ykGI1ArwOPHqm2g5Cqh3ENdMxEej_a_FcOUov5EM5Oc,155
102
+ dycw_utilities-0.174.4.dist-info/METADATA,sha256=4OEtGyGgCm1RvAqPsNsps7YbqYlfIc-AqnrcY2GguJQ,1709
103
+ dycw_utilities-0.174.4.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.174.3"
3
+ __version__ = "0.174.4"
utilities/docker.py CHANGED
@@ -5,6 +5,7 @@ from pathlib import Path
5
5
  from typing import TYPE_CHECKING, Literal, overload
6
6
 
7
7
  from utilities.errors import ImpossibleCaseError
8
+ from utilities.logging import to_logger
8
9
  from utilities.subprocess import (
9
10
  MKTEMP_DIR_CMD,
10
11
  maybe_sudo_cmd,
@@ -17,7 +18,7 @@ from utilities.subprocess import (
17
18
  if TYPE_CHECKING:
18
19
  from collections.abc import Iterator
19
20
 
20
- from utilities.types import LoggerLike, PathLike, StrStrMapping
21
+ from utilities.types import LoggerLike, PathLike, Retry, StrStrMapping
21
22
 
22
23
 
23
24
  @overload
@@ -106,6 +107,7 @@ def docker_exec(
106
107
  return_: Literal[True],
107
108
  return_stdout: bool = False,
108
109
  return_stderr: bool = False,
110
+ retry: Retry | None = None,
109
111
  logger: LoggerLike | None = None,
110
112
  **env_kwargs: str,
111
113
  ) -> str: ...
@@ -125,6 +127,7 @@ def docker_exec(
125
127
  return_: bool = False,
126
128
  return_stdout: Literal[True],
127
129
  return_stderr: bool = False,
130
+ retry: Retry | None = None,
128
131
  logger: LoggerLike | None = None,
129
132
  **env_kwargs: str,
130
133
  ) -> str: ...
@@ -144,6 +147,7 @@ def docker_exec(
144
147
  return_: bool = False,
145
148
  return_stdout: bool = False,
146
149
  return_stderr: Literal[True],
150
+ retry: Retry | None = None,
147
151
  logger: LoggerLike | None = None,
148
152
  **env_kwargs: str,
149
153
  ) -> str: ...
@@ -163,6 +167,7 @@ def docker_exec(
163
167
  return_: Literal[False] = False,
164
168
  return_stdout: Literal[False] = False,
165
169
  return_stderr: Literal[False] = False,
170
+ retry: Retry | None = None,
166
171
  logger: LoggerLike | None = None,
167
172
  **env_kwargs: str,
168
173
  ) -> None: ...
@@ -182,6 +187,7 @@ def docker_exec(
182
187
  return_: bool = False,
183
188
  return_stdout: bool = False,
184
189
  return_stderr: bool = False,
190
+ retry: Retry | None = None,
185
191
  logger: LoggerLike | None = None,
186
192
  **env_kwargs: str,
187
193
  ) -> str | None: ...
@@ -200,6 +206,7 @@ def docker_exec(
200
206
  return_: bool = False,
201
207
  return_stdout: bool = False,
202
208
  return_stderr: bool = False,
209
+ retry: Retry | None = None,
203
210
  logger: LoggerLike | None = None,
204
211
  **env_kwargs: str,
205
212
  ) -> str | None:
@@ -222,6 +229,7 @@ def docker_exec(
222
229
  return_=return_,
223
230
  return_stdout=return_stdout,
224
231
  return_stderr=return_stderr,
232
+ retry=retry,
225
233
  logger=logger,
226
234
  )
227
235
 
@@ -253,15 +261,32 @@ def docker_exec_cmd(
253
261
 
254
262
  @contextmanager
255
263
  def yield_docker_temp_dir(
256
- container: str, /, *, user: str | None = None, logger: LoggerLike | None = None
264
+ container: str,
265
+ /,
266
+ *,
267
+ user: str | None = None,
268
+ retry: Retry | None = None,
269
+ logger: LoggerLike | None = None,
270
+ keep: bool = False,
257
271
  ) -> Iterator[Path]:
258
272
  path = Path( # skipif-ci
259
- docker_exec(container, *MKTEMP_DIR_CMD, user=user, return_=True, logger=logger)
273
+ docker_exec(
274
+ container,
275
+ *MKTEMP_DIR_CMD,
276
+ user=user,
277
+ return_=True,
278
+ retry=retry,
279
+ logger=logger,
280
+ )
260
281
  )
261
282
  try: # skipif-ci
262
283
  yield path
263
284
  finally: # skipif-ci
264
- docker_exec(container, *rm_cmd(path), user=user, logger=logger)
285
+ if keep:
286
+ if logger is not None:
287
+ to_logger(logger).info("Keeping temporary directory '%s'...", path)
288
+ else:
289
+ docker_exec(container, *rm_cmd(path), user=user, retry=retry, logger=logger)
265
290
 
266
291
 
267
292
  __all__ = ["docker_cp_cmd", "docker_exec", "docker_exec_cmd", "yield_docker_temp_dir"]
utilities/subprocess.py CHANGED
@@ -13,16 +13,14 @@ 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
16
  from utilities.whenever import to_seconds
18
17
 
19
18
  if TYPE_CHECKING:
20
19
  from collections.abc import Iterator
21
20
 
22
- from utilities.types import LoggerLike, PathLike, StrMapping, StrStrMapping
21
+ from utilities.types import LoggerLike, PathLike, Retry, StrMapping, StrStrMapping
23
22
 
24
23
 
25
- type _Retry = tuple[int, Delta | None]
26
24
  _HOST_KEY_ALGORITHMS = ["ssh-ed25519"]
27
25
  BASH_LC = ["bash", "-lc"]
28
26
  BASH_LS = ["bash", "-ls"]
@@ -83,7 +81,7 @@ def run(
83
81
  return_: Literal[True],
84
82
  return_stdout: bool = False,
85
83
  return_stderr: bool = False,
86
- retry: _Retry | None = None,
84
+ retry: Retry | None = None,
87
85
  logger: LoggerLike | None = None,
88
86
  ) -> str: ...
89
87
  @overload
@@ -103,7 +101,7 @@ def run(
103
101
  return_: bool = False,
104
102
  return_stdout: Literal[True],
105
103
  return_stderr: bool = False,
106
- retry: _Retry | None = None,
104
+ retry: Retry | None = None,
107
105
  logger: LoggerLike | None = None,
108
106
  ) -> str: ...
109
107
  @overload
@@ -123,7 +121,7 @@ def run(
123
121
  return_: bool = False,
124
122
  return_stdout: bool = False,
125
123
  return_stderr: Literal[True],
126
- retry: _Retry | None = None,
124
+ retry: Retry | None = None,
127
125
  logger: LoggerLike | None = None,
128
126
  ) -> str: ...
129
127
  @overload
@@ -143,7 +141,7 @@ def run(
143
141
  return_: Literal[False] = False,
144
142
  return_stdout: Literal[False] = False,
145
143
  return_stderr: Literal[False] = False,
146
- retry: _Retry | None = None,
144
+ retry: Retry | None = None,
147
145
  logger: LoggerLike | None = None,
148
146
  ) -> None: ...
149
147
  @overload
@@ -163,7 +161,7 @@ def run(
163
161
  return_: bool = False,
164
162
  return_stdout: bool = False,
165
163
  return_stderr: bool = False,
166
- retry: _Retry | None = None,
164
+ retry: Retry | None = None,
167
165
  logger: LoggerLike | None = None,
168
166
  ) -> str | None: ...
169
167
  def run(
@@ -182,7 +180,7 @@ def run(
182
180
  return_: bool = False,
183
181
  return_stdout: bool = False,
184
182
  return_stderr: bool = False,
185
- retry: _Retry | None = None,
183
+ retry: Retry | None = None,
186
184
  logger: LoggerLike | None = None,
187
185
  ) -> str | None:
188
186
  args: list[str] = []
@@ -337,7 +335,7 @@ def ssh(
337
335
  return_: Literal[True],
338
336
  return_stdout: bool = False,
339
337
  return_stderr: bool = False,
340
- retry: _Retry | None = None,
338
+ retry: Retry | None = None,
341
339
  logger: LoggerLike | None = None,
342
340
  ) -> str: ...
343
341
  @overload
@@ -356,7 +354,7 @@ def ssh(
356
354
  return_: bool = False,
357
355
  return_stdout: Literal[True],
358
356
  return_stderr: bool = False,
359
- retry: _Retry | None = None,
357
+ retry: Retry | None = None,
360
358
  logger: LoggerLike | None = None,
361
359
  ) -> str: ...
362
360
  @overload
@@ -375,7 +373,7 @@ def ssh(
375
373
  return_: bool = False,
376
374
  return_stdout: bool = False,
377
375
  return_stderr: Literal[True],
378
- retry: _Retry | None = None,
376
+ retry: Retry | None = None,
379
377
  logger: LoggerLike | None = None,
380
378
  ) -> str: ...
381
379
  @overload
@@ -394,7 +392,7 @@ def ssh(
394
392
  return_: Literal[False] = False,
395
393
  return_stdout: Literal[False] = False,
396
394
  return_stderr: Literal[False] = False,
397
- retry: _Retry | None = None,
395
+ retry: Retry | None = None,
398
396
  logger: LoggerLike | None = None,
399
397
  ) -> None: ...
400
398
  @overload
@@ -413,7 +411,7 @@ def ssh(
413
411
  return_: bool = False,
414
412
  return_stdout: bool = False,
415
413
  return_stderr: bool = False,
416
- retry: _Retry | None = None,
414
+ retry: Retry | None = None,
417
415
  logger: LoggerLike | None = None,
418
416
  ) -> str | None: ...
419
417
  def ssh(
@@ -431,7 +429,7 @@ def ssh(
431
429
  return_: bool = False,
432
430
  return_stdout: bool = False,
433
431
  return_stderr: bool = False,
434
- retry: _Retry | None = None,
432
+ retry: Retry | None = None,
435
433
  logger: LoggerLike | None = None,
436
434
  ) -> str | None:
437
435
  cmd_and_args = ssh_cmd( # skipif-ci
@@ -484,9 +482,17 @@ def touch_cmd(path: PathLike, /) -> list[str]:
484
482
 
485
483
  @contextmanager
486
484
  def yield_ssh_temp_dir(
487
- user: str, hostname: str, /, *, keep: bool = False, logger: LoggerLike | None = None
485
+ user: str,
486
+ hostname: str,
487
+ /,
488
+ *,
489
+ retry: Retry | None = None,
490
+ logger: LoggerLike | None = None,
491
+ keep: bool = False,
488
492
  ) -> Iterator[Path]:
489
- path = Path(ssh(user, hostname, *MKTEMP_DIR_CMD, return_=True))
493
+ path = Path(
494
+ ssh(user, hostname, *MKTEMP_DIR_CMD, return_=True, retry=retry, logger=logger)
495
+ )
490
496
  try:
491
497
  yield path
492
498
  finally:
@@ -494,7 +500,7 @@ def yield_ssh_temp_dir(
494
500
  if logger is not None:
495
501
  to_logger(logger).info("Keeping temporary directory '%s'...", path)
496
502
  else:
497
- ssh(user, hostname, *rm_cmd(path))
503
+ ssh(user, hostname, *rm_cmd(path), retry=retry, logger=logger)
498
504
 
499
505
 
500
506
  __all__ = [
utilities/types.py CHANGED
@@ -231,6 +231,10 @@ type Seed = int | float | str | bytes | bytearray | Random
231
231
  type PatternLike = MaybeStr[Pattern[str]]
232
232
 
233
233
 
234
+ # retry
235
+ type Retry = tuple[int, Delta | None]
236
+
237
+
234
238
  # text
235
239
  type MaybeCallableStr = MaybeCallable[str]
236
240
 
@@ -332,6 +336,7 @@ __all__ = [
332
336
  "PathLike",
333
337
  "PatternLike",
334
338
  "PlainDateTimeLike",
339
+ "Retry",
335
340
  "Seed",
336
341
  "SequenceStr",
337
342
  "SerializeObjectExtra",