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.
Files changed (47) hide show
  1. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/.pre-commit-config.yaml +4 -4
  2. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/PKG-INFO +1 -1
  3. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/__init__.py +17 -20
  4. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/__init__.pyi +16 -19
  5. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/_helpers.py +18 -16
  6. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/_ssh_base.py +326 -308
  7. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/_ssh_helpers.py +57 -57
  8. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/_subprocess_helpers.py +3 -3
  9. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/_version.py +2 -2
  10. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/api.py +204 -146
  11. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/async_api/__init__.py +2 -2
  12. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/async_api/__init__.pyi +3 -5
  13. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/async_api/api.py +186 -130
  14. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/async_api/exec_result.py +12 -12
  15. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/async_api/subprocess.py +120 -109
  16. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/exceptions.py +37 -108
  17. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/exec_result.py +94 -94
  18. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/proc_enums.py +7 -7
  19. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/ssh.py +9 -9
  20. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/ssh_auth.py +51 -51
  21. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/subprocess.py +120 -109
  22. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers.egg-info/PKG-INFO +1 -1
  23. exec_helpers-8.1.0/flake8_requirements.txt +14 -0
  24. exec_helpers-8.1.0/mypy_requirements.txt +1 -0
  25. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/pyproject.toml +8 -8
  26. exec-helpers-8.0.1/flake8_requirements.txt +0 -4
  27. exec-helpers-8.0.1/mypy_requirements.txt +0 -1
  28. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/.editorconfig +0 -0
  29. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/.readthedocs.yaml +0 -0
  30. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/CI_REQUIREMENTS.txt +0 -0
  31. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/LICENSE +0 -0
  32. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/MANIFEST.in +0 -0
  33. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/README.rst +0 -0
  34. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/build_requirements.txt +0 -0
  35. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/classifiers.txt +0 -0
  36. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/_log_templates.py +0 -0
  37. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/constants.py +0 -0
  38. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers/py.typed +0 -0
  39. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers.egg-info/SOURCES.txt +0 -0
  40. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers.egg-info/dependency_links.txt +0 -0
  41. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers.egg-info/not-zip-safe +0 -0
  42. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers.egg-info/requires.txt +0 -0
  43. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/exec_helpers.egg-info/top_level.txt +0 -0
  44. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/pytest_requirements.txt +0 -0
  45. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/requirements.txt +0 -0
  46. {exec-helpers-8.0.1 → exec_helpers-8.1.0}/setup.cfg +0 -0
  47. {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.5.0
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.12.0
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.7.0
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.1.5
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.1
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
- # lazy load
35
- # API
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: attribute by name
94
- :raises AttributeError: attribute is not defined for lazy load
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
- # pylint: disable=undefined-all-variable
43
- # lazy load
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 bytes string from string/bytes/bytearray union.
15
+ """Get byte string from string/bytes/bytearray union.
16
16
 
17
- :param src: source string or bytes-like object
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: source text
34
+ :param text: Source text.
35
35
  :type text: str
36
- :param rules: regex rules to mask.
36
+ :param rules: Regex rules to mask.
37
37
  :type rules: str | re.Pattern
38
- :return: source with all MATCHED groups replaced by '<*masked*>'
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: source text
58
+ :param text: Source text.
59
59
  :type text: str
60
- :param rules: regex rules to mask.
60
+ :param rules: Regex rules to mask.
61
61
  :type rules: str | re.Pattern[str] | None
62
- :return: source with all MATCHED groups replaced by '<*masked*>'
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: original command.
71
+ :param command: Original command.
72
72
  :type command: str | Iterable[str]
73
- :return: command as single string
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: original 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
- :return: command to be executed with chroot rules if applicable
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'chroot {chroot_dst} sh -c {shlex.quote(f"eval {quoted_command}")}'
96
+ return f'{chroot_exe} {chroot_dst} sh -c {shlex.quote(f"eval {quoted_command}")}'
95
97
  return command