exec-helpers 8.0.1__tar.gz → 8.1.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.
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/.pre-commit-config.yaml +4 -4
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/PKG-INFO +1 -1
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/__init__.py +17 -20
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/__init__.pyi +16 -19
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/_helpers.py +18 -16
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/_ssh_base.py +326 -308
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/_ssh_helpers.py +57 -57
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/_subprocess_helpers.py +3 -3
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/_version.py +2 -2
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/api.py +204 -146
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/async_api/__init__.py +2 -2
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/async_api/__init__.pyi +3 -5
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/async_api/api.py +186 -130
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/async_api/exec_result.py +12 -12
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/async_api/subprocess.py +120 -109
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/exceptions.py +37 -108
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/exec_result.py +94 -94
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/proc_enums.py +7 -7
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/ssh.py +9 -9
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/ssh_auth.py +51 -51
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/subprocess.py +120 -109
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers.egg-info/PKG-INFO +1 -1
- exec_helpers-8.1.0/flake8_requirements.txt +14 -0
- exec_helpers-8.1.0/mypy_requirements.txt +1 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/pyproject.toml +8 -8
- exec-helpers-8.0.1/flake8_requirements.txt +0 -4
- exec-helpers-8.0.1/mypy_requirements.txt +0 -1
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/.editorconfig +0 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/.readthedocs.yaml +0 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/CI_REQUIREMENTS.txt +0 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/LICENSE +0 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/MANIFEST.in +0 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/README.rst +0 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/build_requirements.txt +0 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/classifiers.txt +0 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/_log_templates.py +0 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/constants.py +0 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/py.typed +0 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers.egg-info/SOURCES.txt +0 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers.egg-info/dependency_links.txt +0 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers.egg-info/not-zip-safe +0 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers.egg-info/requires.txt +0 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers.egg-info/top_level.txt +0 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/pytest_requirements.txt +0 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/requirements.txt +0 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/setup.cfg +0 -0
- {exec-helpers-8.0.1 → exec_helpers-8.1.0}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
repos:
|
|
2
2
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
-
rev: v4.
|
|
3
|
+
rev: v4.6.0
|
|
4
4
|
hooks:
|
|
5
5
|
- id: check-yaml
|
|
6
6
|
- id: end-of-file-fixer
|
|
@@ -8,7 +8,7 @@ repos:
|
|
|
8
8
|
- id: mixed-line-ending
|
|
9
9
|
|
|
10
10
|
- repo: https://github.com/pycqa/isort
|
|
11
|
-
rev: 5.
|
|
11
|
+
rev: 5.13.2
|
|
12
12
|
hooks:
|
|
13
13
|
- id: isort
|
|
14
14
|
name: isort (python)
|
|
@@ -20,7 +20,7 @@ repos:
|
|
|
20
20
|
types: [pyi]
|
|
21
21
|
|
|
22
22
|
- repo: https://github.com/psf/black
|
|
23
|
-
rev:
|
|
23
|
+
rev: 24.4.2
|
|
24
24
|
hooks:
|
|
25
25
|
- id: black
|
|
26
26
|
# It is recommended to specify the latest version of Python
|
|
@@ -30,7 +30,7 @@ repos:
|
|
|
30
30
|
|
|
31
31
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
32
32
|
# Ruff version.
|
|
33
|
-
rev: v0.
|
|
33
|
+
rev: v0.4.6
|
|
34
34
|
hooks:
|
|
35
35
|
- id: ruff
|
|
36
36
|
args: [ --fix, --exit-non-zero-on-fix ]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: exec-helpers
|
|
3
|
-
Version: 8.0
|
|
3
|
+
Version: 8.1.0
|
|
4
4
|
Summary: Execution helpers for simplified usage of subprocess and ssh.
|
|
5
5
|
Home-page: https://github.com/python-useful-helpers/exec-helpers
|
|
6
6
|
Author-email: Alexey Stepanov <penguinolog@gmail.com>
|
|
@@ -28,31 +28,28 @@ except ImportError:
|
|
|
28
28
|
if typing.TYPE_CHECKING:
|
|
29
29
|
from collections.abc import Sequence
|
|
30
30
|
|
|
31
|
+
|
|
31
32
|
# noinspection PyUnresolvedReferences
|
|
32
33
|
__all__ = (
|
|
33
34
|
# pylint: disable=undefined-all-variable
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"async_api",
|
|
37
|
-
"ExitCodes",
|
|
38
|
-
"ExecResult",
|
|
35
|
+
"CalledProcessError",
|
|
36
|
+
"ExecCalledProcessError",
|
|
39
37
|
"ExecHelper",
|
|
40
|
-
"mask_command",
|
|
41
|
-
# Expensive
|
|
42
|
-
"Subprocess",
|
|
43
|
-
"SSHClient",
|
|
44
|
-
"SSHAuth",
|
|
45
|
-
"SSHConfig",
|
|
46
|
-
"HostsSSHConfigs",
|
|
47
|
-
# Exceptions
|
|
48
|
-
"exceptions",
|
|
49
38
|
"ExecHelperError",
|
|
50
|
-
"ExecCalledProcessError",
|
|
51
|
-
"CalledProcessError",
|
|
52
|
-
"ParallelCallExceptionsError",
|
|
53
|
-
"ParallelCallProcessError",
|
|
54
39
|
"ExecHelperNoKillError",
|
|
55
40
|
"ExecHelperTimeoutError",
|
|
41
|
+
"ExecResult",
|
|
42
|
+
"ExitCodes",
|
|
43
|
+
"HostsSSHConfigs",
|
|
44
|
+
"ParallelCallExceptionsError",
|
|
45
|
+
"ParallelCallProcessError",
|
|
46
|
+
"SSHAuth",
|
|
47
|
+
"SSHClient",
|
|
48
|
+
"SSHConfig",
|
|
49
|
+
"Subprocess",
|
|
50
|
+
"async_api",
|
|
51
|
+
"exceptions",
|
|
52
|
+
"mask_command",
|
|
56
53
|
)
|
|
57
54
|
|
|
58
55
|
__locals: dict[str, typing.Any] = locals() # use mutable access for pure lazy loading
|
|
@@ -90,8 +87,8 @@ _deprecated: dict[str, str] = {}
|
|
|
90
87
|
def __getattr__(name: str) -> typing.Any:
|
|
91
88
|
"""Get attributes lazy.
|
|
92
89
|
|
|
93
|
-
:return:
|
|
94
|
-
:raises AttributeError:
|
|
90
|
+
:return: Attribute by name.
|
|
91
|
+
:raises AttributeError: Attribute is not defined for the lazy load.
|
|
95
92
|
"""
|
|
96
93
|
if name in _deprecated:
|
|
97
94
|
warnings.warn(
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# License for the specific language governing permissions and limitations
|
|
13
13
|
# under the License.
|
|
14
14
|
|
|
15
|
+
# pylint: disable=missing-module-docstring
|
|
16
|
+
|
|
15
17
|
import typing
|
|
16
18
|
|
|
17
19
|
from . import async_api
|
|
@@ -39,33 +41,28 @@ except ImportError:
|
|
|
39
41
|
|
|
40
42
|
# noinspection PyUnresolvedReferences
|
|
41
43
|
__all__ = (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
# API
|
|
45
|
-
"async_api",
|
|
46
|
-
"ExitCodes",
|
|
47
|
-
"ExecResult",
|
|
44
|
+
"CalledProcessError",
|
|
45
|
+
"ExecCalledProcessError",
|
|
48
46
|
"ExecHelper",
|
|
49
|
-
"mask_command",
|
|
50
|
-
# Expensive
|
|
51
|
-
"Subprocess",
|
|
52
|
-
"SSHClient",
|
|
53
|
-
"SSHAuth",
|
|
54
|
-
"SSHConfig",
|
|
55
|
-
"HostsSSHConfigs",
|
|
56
|
-
# Exceptions
|
|
57
47
|
"ExecHelperError",
|
|
58
|
-
"ExecCalledProcessError",
|
|
59
|
-
"CalledProcessError",
|
|
60
|
-
"ParallelCallExceptionsError",
|
|
61
|
-
"ParallelCallProcessError",
|
|
62
48
|
"ExecHelperNoKillError",
|
|
63
49
|
"ExecHelperTimeoutError",
|
|
50
|
+
"ExecResult",
|
|
51
|
+
"ExitCodes",
|
|
52
|
+
"HostsSSHConfigs",
|
|
53
|
+
"ParallelCallExceptionsError",
|
|
54
|
+
"ParallelCallProcessError",
|
|
55
|
+
"SSHAuth",
|
|
56
|
+
"SSHClient",
|
|
57
|
+
"SSHConfig",
|
|
58
|
+
"Subprocess",
|
|
59
|
+
"async_api",
|
|
60
|
+
"mask_command",
|
|
64
61
|
)
|
|
65
62
|
|
|
66
63
|
_deprecated: dict[str, str] = ...
|
|
67
64
|
|
|
68
|
-
def __getattr__(name: str) -> typing.Any: ...
|
|
65
|
+
def __getattr__(name: str) -> typing.Any: ... # pylint: disable=unused-argument
|
|
69
66
|
|
|
70
67
|
__author__: str = ...
|
|
71
68
|
__author_email__: str = ...
|
|
@@ -12,10 +12,10 @@ if typing.TYPE_CHECKING:
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def string_bytes_bytearray_as_bytes(src: str | bytes | bytearray) -> bytes:
|
|
15
|
-
"""Get
|
|
15
|
+
"""Get byte string from string/bytes/bytearray union.
|
|
16
16
|
|
|
17
|
-
:param src:
|
|
18
|
-
:return: Byte string
|
|
17
|
+
:param src: Source string or bytes-like object.
|
|
18
|
+
:return: Byte string.
|
|
19
19
|
:rtype: bytes
|
|
20
20
|
:raises TypeError: unexpected source type.
|
|
21
21
|
"""
|
|
@@ -31,11 +31,11 @@ def string_bytes_bytearray_as_bytes(src: str | bytes | bytearray) -> bytes:
|
|
|
31
31
|
def _mask_command(text: str, rules: str | re.Pattern[str]) -> str:
|
|
32
32
|
"""Mask part of text using rules.
|
|
33
33
|
|
|
34
|
-
:param text:
|
|
34
|
+
:param text: Source text.
|
|
35
35
|
:type text: str
|
|
36
|
-
:param rules:
|
|
36
|
+
:param rules: Regex rules to mask.
|
|
37
37
|
:type rules: str | re.Pattern
|
|
38
|
-
:return:
|
|
38
|
+
:return: Source with all MATCHED groups replaced by '<*masked*>'.
|
|
39
39
|
:rtype: str
|
|
40
40
|
"""
|
|
41
41
|
masked: list[str] = []
|
|
@@ -55,11 +55,11 @@ def _mask_command(text: str, rules: str | re.Pattern[str]) -> str:
|
|
|
55
55
|
def mask_command(text: str, *rules: str | re.Pattern[str] | None) -> str:
|
|
56
56
|
"""Apply all rules to command.
|
|
57
57
|
|
|
58
|
-
:param text:
|
|
58
|
+
:param text: Source text.
|
|
59
59
|
:type text: str
|
|
60
|
-
:param rules:
|
|
60
|
+
:param rules: Regex rules to mask.
|
|
61
61
|
:type rules: str | re.Pattern[str] | None
|
|
62
|
-
:return:
|
|
62
|
+
:return: Source with all MATCHED groups replaced by '<*masked*>'.
|
|
63
63
|
:rtype: str
|
|
64
64
|
"""
|
|
65
65
|
return functools.reduce(_mask_command, (rule for rule in rules if rule is not None), text)
|
|
@@ -68,9 +68,9 @@ def mask_command(text: str, *rules: str | re.Pattern[str] | None) -> str:
|
|
|
68
68
|
def cmd_to_string(command: str | Iterable[str]) -> str:
|
|
69
69
|
"""Convert command to string for usage with shell.
|
|
70
70
|
|
|
71
|
-
:param command:
|
|
71
|
+
:param command: Original command.
|
|
72
72
|
:type command: str | Iterable[str]
|
|
73
|
-
:return:
|
|
73
|
+
:return: Command as single string.
|
|
74
74
|
:rtype: str
|
|
75
75
|
"""
|
|
76
76
|
if isinstance(command, str):
|
|
@@ -78,18 +78,20 @@ def cmd_to_string(command: str | Iterable[str]) -> str:
|
|
|
78
78
|
return shlex.join(command)
|
|
79
79
|
|
|
80
80
|
|
|
81
|
-
def chroot_command(command: str, chroot_path: str | None = None) -> str:
|
|
81
|
+
def chroot_command(command: str, chroot_path: str | None = None, chroot_exe: str = "chroot") -> str:
|
|
82
82
|
"""Prepare command for chroot execution.
|
|
83
83
|
|
|
84
|
-
:param command:
|
|
84
|
+
:param command: Original command.
|
|
85
85
|
:type command: str
|
|
86
|
-
:param chroot_path: chroot path
|
|
86
|
+
:param chroot_path: chroot path.
|
|
87
87
|
:type chroot_path: str | None
|
|
88
|
-
:
|
|
88
|
+
:param chroot_exe: chroot executable.
|
|
89
|
+
:type chroot_exe: str
|
|
90
|
+
:return: Command to be executed with chroot rules if applicable.
|
|
89
91
|
:rtype: str
|
|
90
92
|
"""
|
|
91
93
|
if chroot_path and chroot_path != "/":
|
|
92
94
|
chroot_dst: str = shlex.quote(chroot_path.strip())
|
|
93
95
|
quoted_command = shlex.quote(command)
|
|
94
|
-
return f'
|
|
96
|
+
return f'{chroot_exe} {chroot_dst} sh -c {shlex.quote(f"eval {quoted_command}")}'
|
|
95
97
|
return command
|