exec-helpers 8.1.0__tar.gz → 8.1.2__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 (45) hide show
  1. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/PKG-INFO +1 -1
  2. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/_helpers.py +3 -2
  3. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/_ssh_base.py +15 -13
  4. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/_version.py +2 -2
  5. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/api.py +28 -24
  6. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/async_api/api.py +31 -25
  7. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/async_api/subprocess.py +7 -7
  8. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/exec_result.py +2 -2
  9. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/subprocess.py +7 -7
  10. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers.egg-info/PKG-INFO +1 -1
  11. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/pyproject.toml +5 -0
  12. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/.editorconfig +0 -0
  13. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/.pre-commit-config.yaml +0 -0
  14. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/.readthedocs.yaml +0 -0
  15. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/CI_REQUIREMENTS.txt +0 -0
  16. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/LICENSE +0 -0
  17. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/MANIFEST.in +0 -0
  18. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/README.rst +0 -0
  19. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/build_requirements.txt +0 -0
  20. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/classifiers.txt +0 -0
  21. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/__init__.py +0 -0
  22. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/__init__.pyi +0 -0
  23. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/_log_templates.py +0 -0
  24. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/_ssh_helpers.py +0 -0
  25. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/_subprocess_helpers.py +0 -0
  26. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/async_api/__init__.py +0 -0
  27. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/async_api/__init__.pyi +0 -0
  28. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/async_api/exec_result.py +0 -0
  29. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/constants.py +0 -0
  30. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/exceptions.py +0 -0
  31. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/proc_enums.py +0 -0
  32. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/py.typed +0 -0
  33. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/ssh.py +0 -0
  34. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers/ssh_auth.py +0 -0
  35. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers.egg-info/SOURCES.txt +0 -0
  36. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers.egg-info/dependency_links.txt +0 -0
  37. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers.egg-info/not-zip-safe +0 -0
  38. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers.egg-info/requires.txt +0 -0
  39. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/exec_helpers.egg-info/top_level.txt +0 -0
  40. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/flake8_requirements.txt +0 -0
  41. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/mypy_requirements.txt +0 -0
  42. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/pytest_requirements.txt +0 -0
  43. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/requirements.txt +0 -0
  44. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/setup.cfg +0 -0
  45. {exec_helpers-8.1.0 → exec_helpers-8.1.2}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: exec-helpers
3
- Version: 8.1.0
3
+ Version: 8.1.2
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>
@@ -78,7 +78,7 @@ 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, chroot_exe: str = "chroot") -> str:
81
+ def chroot_command(command: str, chroot_path: str | None = None, chroot_exe: str | None = None) -> str:
82
82
  """Prepare command for chroot execution.
83
83
 
84
84
  :param command: Original command.
@@ -86,10 +86,11 @@ def chroot_command(command: str, chroot_path: str | None = None, chroot_exe: str
86
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
89
+ :type chroot_exe: str | None
90
90
  :return: Command to be executed with chroot rules if applicable.
91
91
  :rtype: str
92
92
  """
93
+ chroot_exe = chroot_exe or "chroot"
93
94
  if chroot_path and chroot_path != "/":
94
95
  chroot_dst: str = shlex.quote(chroot_path.strip())
95
96
  quoted_command = shlex.quote(command)
@@ -982,7 +982,7 @@ class SSHClientBase(api.ExecHelper):
982
982
  """
983
983
  return _KeepAliveContext(ssh=self, enforce=int(enforce))
984
984
 
985
- def _prepare_command(self, cmd: str, chroot_path: str | None = None, chroot_exe: str = "chroot") -> str:
985
+ def _prepare_command(self, cmd: str, chroot_path: str | None = None, chroot_exe: str | None = None) -> str:
986
986
  """Prepare command: cover chroot and other cases.
987
987
 
988
988
  :param cmd: Main command.
@@ -990,6 +990,7 @@ class SSHClientBase(api.ExecHelper):
990
990
  :param chroot_exe: chroot executable, default "chroot".
991
991
  :return: The final command includes chroot, if required.
992
992
  """
993
+ chroot_exe = chroot_exe or "chroot"
993
994
  if not self.sudo_mode:
994
995
  return super()._prepare_command(cmd=cmd, chroot_path=chroot_path, chroot_exe=chroot_exe)
995
996
  quoted_command: str = shlex.quote(cmd)
@@ -1096,7 +1097,7 @@ class SSHClientBase(api.ExecHelper):
1096
1097
  open_stdout: bool = True,
1097
1098
  open_stderr: bool = True,
1098
1099
  chroot_path: str | None = None,
1099
- chroot_exe: str = "chroot",
1100
+ chroot_exe: str | None = None,
1100
1101
  get_pty: bool = False,
1101
1102
  width: int = 80,
1102
1103
  height: int = 24,
@@ -1116,7 +1117,7 @@ class SSHClientBase(api.ExecHelper):
1116
1117
  :param chroot_path: chroot path override.
1117
1118
  :type chroot_path: str | None
1118
1119
  :param chroot_exe: chroot exe override.
1119
- :type chroot_exe: str
1120
+ :type chroot_exe: str | None
1120
1121
  :param get_pty: Get PTY for connection.
1121
1122
  :type get_pty: bool
1122
1123
  :param width: PTY width.
@@ -1160,7 +1161,7 @@ class SSHClientBase(api.ExecHelper):
1160
1161
  open_stderr: bool = True,
1161
1162
  log_stderr: bool = True,
1162
1163
  chroot_path: str | None = None,
1163
- chroot_exe: str = "chroot",
1164
+ chroot_exe: str | None = None,
1164
1165
  get_pty: bool = False,
1165
1166
  width: int = 80,
1166
1167
  height: int = 24,
@@ -1190,7 +1191,7 @@ class SSHClientBase(api.ExecHelper):
1190
1191
  :param chroot_path: chroot path override.
1191
1192
  :type chroot_path: str | None
1192
1193
  :param chroot_exe: chroot exe override.
1193
- :type chroot_exe: str
1194
+ :type chroot_exe: str | None
1194
1195
  :param get_pty: Get PTY for connection.
1195
1196
  :type get_pty: bool
1196
1197
  :param width: PTY width.
@@ -1240,7 +1241,7 @@ class SSHClientBase(api.ExecHelper):
1240
1241
  open_stderr: bool = True,
1241
1242
  log_stderr: bool = True,
1242
1243
  chroot_path: str | None = None,
1243
- chroot_exe: str = "chroot",
1244
+ chroot_exe: str | None = None,
1244
1245
  get_pty: bool = False,
1245
1246
  width: int = 80,
1246
1247
  height: int = 24,
@@ -1270,7 +1271,7 @@ class SSHClientBase(api.ExecHelper):
1270
1271
  :param chroot_path: Chroot path override.
1271
1272
  :type chroot_path: str | None
1272
1273
  :param chroot_exe: Chroot exe override.
1273
- :type chroot_exe: str
1274
+ :type chroot_exe: str | None
1274
1275
  :param get_pty: Get PTY for connection.
1275
1276
  :type get_pty: bool
1276
1277
  :param width: PTY width.
@@ -1658,7 +1659,7 @@ class SSHClientBase(api.ExecHelper):
1658
1659
  open_stdout: bool = True,
1659
1660
  open_stderr: bool = True,
1660
1661
  chroot_path: str | None = None,
1661
- chroot_exe: str = "chroot",
1662
+ chroot_exe: str | None = None,
1662
1663
  verbose: bool = False,
1663
1664
  log_mask_re: LogMaskReT = None,
1664
1665
  exception_class: type[exceptions.ParallelCallProcessError] = exceptions.ParallelCallProcessError,
@@ -1685,7 +1686,7 @@ class SSHClientBase(api.ExecHelper):
1685
1686
  :param chroot_path: chroot path override.
1686
1687
  :type chroot_path: str | None
1687
1688
  :param chroot_exe: chroot exe override.
1688
- :type chroot_exe: str
1689
+ :type chroot_exe: str | None
1689
1690
  :param verbose: Produce verbose log record on command call.
1690
1691
  :type verbose: bool
1691
1692
  :param log_mask_re: Regex lookup rule to mask command for logger.
@@ -1744,7 +1745,8 @@ class SSHClientBase(api.ExecHelper):
1744
1745
  if done:
1745
1746
  res.exit_code = async_result.interface.recv_exit_status()
1746
1747
  return res
1747
- result.set_timestamp()
1748
+
1749
+ res.set_timestamp()
1748
1750
 
1749
1751
  wait_err_msg: str = _log_templates.CMD_WAIT_ERROR.format(result=res, timeout=timeout)
1750
1752
  remote.logger.debug(wait_err_msg)
@@ -1772,11 +1774,11 @@ class SSHClientBase(api.ExecHelper):
1772
1774
  for remote, future in futures.items():
1773
1775
  try:
1774
1776
  result = future.result(timeout=0.1)
1775
- results[(remote.hostname, remote.port)] = result
1777
+ results[remote.hostname, remote.port] = result
1776
1778
  if result.exit_code not in prep_expected:
1777
- errors[(remote.hostname, remote.port)] = result
1779
+ errors[remote.hostname, remote.port] = result
1778
1780
  except Exception as e: # noqa: PERF203
1779
- raised_exceptions[(remote.hostname, remote.port)] = e
1781
+ raised_exceptions[remote.hostname, remote.port] = e
1780
1782
 
1781
1783
  if raised_exceptions: # always raise
1782
1784
  raise exceptions.ParallelCallExceptionsError(
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '8.1.0'
16
- __version_tuple__ = version_tuple = (8, 1, 0)
15
+ __version__ = version = '8.1.2'
16
+ __version_tuple__ = version_tuple = (8, 1, 2)
@@ -173,7 +173,7 @@ class _ChRootContext(typing.ContextManager[None]):
173
173
  :param path: chroot path or None for no chroot.
174
174
  :type path: str | pathlib.Path | None
175
175
  :param chroot_exe: chroot executable.
176
- :type chroot_exe: str
176
+ :type chroot_exe: str | None
177
177
  :raises TypeError: Incorrect type of path or chroot_exe variable.
178
178
 
179
179
  .. versionadded:: 4.1.0
@@ -181,24 +181,24 @@ class _ChRootContext(typing.ContextManager[None]):
181
181
 
182
182
  __slots__ = ("_chroot_exe_status", "_chroot_status", "_conn", "_exe", "_path")
183
183
 
184
- def __init__(self, conn: ExecHelper, path: ChRootPathSetT = None, chroot_exe: str = "chroot") -> None:
184
+ def __init__(self, conn: ExecHelper, path: ChRootPathSetT = None, chroot_exe: str | None = None) -> None:
185
185
  """Context manager for call commands with sudo.
186
186
 
187
187
  :raises TypeError: Incorrect type of path or chroot_exe variable.
188
188
  """
189
189
  self._conn: ExecHelper = conn
190
190
  self._chroot_status: str | None = conn._chroot_path
191
- self._chroot_exe_status: str = conn._chroot_exe
191
+ self._chroot_exe_status: str | None = conn._chroot_exe
192
192
  if path is None or isinstance(path, str):
193
193
  self._path: str | None = path
194
194
  elif isinstance(path, pathlib.Path):
195
195
  self._path = path.as_posix() # get absolute path
196
196
  else:
197
197
  raise TypeError(f"path={path!r} is not instance of {ChRootPathSetT}")
198
- if isinstance(chroot_exe, str):
199
- self._exe: str = chroot_exe
198
+ if chroot_exe is None or isinstance(chroot_exe, str):
199
+ self._exe: str | None = chroot_exe
200
200
  else:
201
- raise TypeError(f"chroot_exe={chroot_exe!r} is not instance of str")
201
+ raise TypeError(f"chroot_exe={chroot_exe!r} is not None or instance of str")
202
202
 
203
203
  def __enter__(self) -> None:
204
204
  self._conn.__enter__()
@@ -252,7 +252,7 @@ class ExecHelper(
252
252
  self.__logger: logging.Logger = logger
253
253
  self.log_mask_re: LogMaskReT = log_mask_re
254
254
  self.__chroot_path: str | None = None
255
- self.__chroot_exe: str = "chroot"
255
+ self.__chroot_exe: str | None = None
256
256
  self.__context_count = 0
257
257
 
258
258
  @property
@@ -306,27 +306,27 @@ class ExecHelper(
306
306
  self.__chroot_path = None
307
307
 
308
308
  @property
309
- def _chroot_exe(self) -> str:
309
+ def _chroot_exe(self) -> str | None:
310
310
  """Exe for chroot
311
311
 
312
- :rtype: str
312
+ :rtype: str | None
313
313
  .. versionadded:: 8.1.0
314
314
  """
315
315
  return self.__chroot_exe
316
316
 
317
317
  @_chroot_exe.setter
318
- def _chroot_exe(self, new_state: str) -> None:
318
+ def _chroot_exe(self, new_state: str | None) -> None:
319
319
  """Executable for chroot if set.
320
320
 
321
321
  :param new_state: New exe.
322
- :type new_state: str
322
+ :type new_state: str | None
323
323
  :raises TypeError: Not supported exe information.
324
324
  .. versionadded:: 8.1.0
325
325
  """
326
- if isinstance(new_state, str):
326
+ if new_state is None or isinstance(new_state, str):
327
327
  self.__chroot_exe = new_state
328
328
  else:
329
- raise TypeError(f"chroot_exe is expected to be string, but set {new_state!r}")
329
+ raise TypeError(f"chroot_exe is expected to be None or string, but set {new_state!r}")
330
330
 
331
331
  @_chroot_exe.deleter
332
332
  def _chroot_exe(self) -> None:
@@ -334,15 +334,15 @@ class ExecHelper(
334
334
 
335
335
  .. versionadded:: 8.1.0
336
336
  """
337
- self.__chroot_exe = "chroot"
337
+ self.__chroot_exe = None
338
338
 
339
- def chroot(self, path: ChRootPathSetT, chroot_exe: str = "chroot") -> _ChRootContext:
339
+ def chroot(self, path: ChRootPathSetT, chroot_exe: str | None = None) -> _ChRootContext:
340
340
  """Context manager for changing chroot rules.
341
341
 
342
342
  :param path: chroot path or none for working without chroot.
343
343
  :type path: str | pathlib.Path | None
344
344
  :param chroot_exe: chroot exe.
345
- :type chroot_exe: str
345
+ :type chroot_exe: str | None
346
346
  :return: Context manager with selected chroot state inside.
347
347
  :rtype: typing.ContextManager
348
348
 
@@ -394,7 +394,7 @@ class ExecHelper(
394
394
 
395
395
  return _helpers.mask_command(cmd.rstrip(), self.log_mask_re, log_mask_re)
396
396
 
397
- def _prepare_command(self, cmd: str, chroot_path: str | None = None, chroot_exe: str = "chroot") -> str:
397
+ def _prepare_command(self, cmd: str, chroot_path: str | None = None, chroot_exe: str | None = None) -> str:
398
398
  """Prepare command: cower chroot and other cases.
399
399
 
400
400
  :param cmd: Main command.
@@ -404,7 +404,11 @@ class ExecHelper(
404
404
  :return: Final command, includes chroot, if required.
405
405
  :rtype: str
406
406
  """
407
- return _helpers.chroot_command(cmd, chroot_path=chroot_path or self._chroot_path, chroot_exe=chroot_exe)
407
+ return _helpers.chroot_command(
408
+ cmd,
409
+ chroot_path=chroot_path or self._chroot_path,
410
+ chroot_exe=chroot_exe or self._chroot_exe,
411
+ )
408
412
 
409
413
  @abc.abstractmethod
410
414
  def _exec_command(
@@ -473,7 +477,7 @@ class ExecHelper(
473
477
  open_stdout: bool = True,
474
478
  open_stderr: bool = True,
475
479
  chroot_path: str | None = None,
476
- chroot_exe: str = "chroot",
480
+ chroot_exe: str | None = None,
477
481
  **kwargs: typing.Any,
478
482
  ) -> ExecuteContext:
479
483
  """Get execution context manager.
@@ -489,7 +493,7 @@ class ExecHelper(
489
493
  :param chroot_path: chroot path override.
490
494
  :type chroot_path: str | None
491
495
  :param chroot_exe: chroot exe override.
492
- :type chroot_exe: str
496
+ :type chroot_exe: str | None
493
497
  :param kwargs: Additional parameters for call.
494
498
  :type kwargs: typing.Any
495
499
 
@@ -509,7 +513,7 @@ class ExecHelper(
509
513
  open_stderr: bool = True,
510
514
  log_stderr: bool = True,
511
515
  chroot_path: str | None = None,
512
- chroot_exe: str = "chroot",
516
+ chroot_exe: str | None = None,
513
517
  **kwargs: typing.Any,
514
518
  ) -> exec_result.ExecResult:
515
519
  """Execute command and wait for return code.
@@ -536,7 +540,7 @@ class ExecHelper(
536
540
  :param chroot_path: chroot path override.
537
541
  :type chroot_path: str | None
538
542
  :param chroot_exe: chroot exe override.
539
- :type chroot_exe: str
543
+ :type chroot_exe: str | None
540
544
  :param kwargs: Additional parameters for call.
541
545
  :type kwargs: typing.Any
542
546
  :return: Execution result.
@@ -594,7 +598,7 @@ class ExecHelper(
594
598
  open_stderr: bool = True,
595
599
  log_stderr: bool = True,
596
600
  chroot_path: str | None = None,
597
- chroot_exe: str = "chroot",
601
+ chroot_exe: str | None = None,
598
602
  **kwargs: typing.Any,
599
603
  ) -> exec_result.ExecResult:
600
604
  """Execute command and wait for return code.
@@ -621,7 +625,7 @@ class ExecHelper(
621
625
  :param chroot_path: chroot path override.
622
626
  :type chroot_path: str | None
623
627
  :param chroot_exe: chroot exe override.
624
- :type chroot_exe: str
628
+ :type chroot_exe: str | None
625
629
  :param kwargs: Additional parameters for call.
626
630
  :type kwargs: typing.Any
627
631
  :return: Execution result.
@@ -161,28 +161,28 @@ class _ChRootContext(typing.AsyncContextManager[None]):
161
161
  :param path: chroot path or None for no chroot.
162
162
  :type path: str | pathlib.Path | None
163
163
  :param chroot_exe: chroot executable.
164
- :type chroot_exe: str
164
+ :type chroot_exe: str | None
165
165
  :raises TypeError: incorrect type of path or chroot_exe variable.
166
166
  """
167
167
 
168
- def __init__(self, conn: ExecHelper, path: ChRootPathSetT = None, chroot_exe: str = "chroot") -> None:
168
+ def __init__(self, conn: ExecHelper, path: ChRootPathSetT = None, chroot_exe: str | None = None) -> None:
169
169
  """Context manager for call commands with sudo.
170
170
 
171
171
  :raises TypeError: incorrect type of path or chroot_exe variable
172
172
  """
173
173
  self._conn: ExecHelper = conn
174
174
  self._chroot_status: str | None = conn._chroot_path
175
- self._chroot_exe_status: str = conn._chroot_exe
175
+ self._chroot_exe_status: str | None = conn._chroot_exe
176
176
  if path is None or isinstance(path, str):
177
177
  self._path: str | None = path
178
178
  elif isinstance(path, pathlib.Path):
179
179
  self._path = path.as_posix() # get an absolute path
180
180
  else:
181
181
  raise TypeError(f"path={path!r} is not instance of {ChRootPathSetT}")
182
- if isinstance(chroot_exe, str):
183
- self._exe: str = chroot_exe
182
+ if chroot_exe is None or isinstance(chroot_exe, str):
183
+ self._exe: str | None = chroot_exe
184
184
  else:
185
- raise TypeError(f"chroot_exe={chroot_exe!r} is not instance of str")
185
+ raise TypeError(f"chroot_exe={chroot_exe!r} is not None or instance of str")
186
186
 
187
187
  async def __aenter__(self) -> None:
188
188
  await self._conn.__aenter__()
@@ -224,7 +224,7 @@ class ExecHelper(
224
224
  self.__logger: logging.Logger = logger
225
225
  self.log_mask_re: LogMaskReT = log_mask_re
226
226
  self.__chroot_path: str | None = None
227
- self.__chroot_exe: str = "chroot"
227
+ self.__chroot_exe: str | None = None
228
228
 
229
229
  @property
230
230
  def logger(self) -> logging.Logger:
@@ -269,27 +269,27 @@ class ExecHelper(
269
269
  self.__chroot_path = None
270
270
 
271
271
  @property
272
- def _chroot_exe(self) -> str:
272
+ def _chroot_exe(self) -> str | None:
273
273
  """Exe for chroot
274
274
 
275
- :rtype: str
275
+ :rtype: str | None
276
276
  .. versionadded:: 8.1.0
277
277
  """
278
278
  return self.__chroot_exe
279
279
 
280
280
  @_chroot_exe.setter
281
- def _chroot_exe(self, new_state: str) -> None:
281
+ def _chroot_exe(self, new_state: str | None) -> None:
282
282
  """Executable for chroot if set.
283
283
 
284
284
  :param new_state: New exe.
285
- :type new_state: str
285
+ :type new_state: str | None
286
286
  :raises TypeError: Not supported exe information.
287
287
  .. versionadded:: 8.1.0
288
288
  """
289
- if isinstance(new_state, str):
289
+ if new_state is None or isinstance(new_state, str):
290
290
  self.__chroot_exe = new_state
291
291
  else:
292
- raise TypeError(f"chroot_exe is expected to be string, but set {new_state!r}")
292
+ raise TypeError(f"chroot_exe is expected to be None or string, but set {new_state!r}")
293
293
 
294
294
  @_chroot_exe.deleter
295
295
  def _chroot_exe(self) -> None:
@@ -297,15 +297,15 @@ class ExecHelper(
297
297
 
298
298
  .. versionadded:: 8.1.0
299
299
  """
300
- self.__chroot_exe = "chroot"
300
+ self.__chroot_exe = None
301
301
 
302
- def chroot(self, path: ChRootPathSetT, chroot_exe: str = "chroot") -> _ChRootContext:
302
+ def chroot(self, path: ChRootPathSetT, chroot_exe: str | None = None) -> _ChRootContext:
303
303
  """Context manager for changing chroot rules.
304
304
 
305
305
  :param path: chroot path or none for working without chroot.
306
306
  :type path: str | pathlib.Path | None
307
- :param chroot_exe: chroot exe.
308
- :type chroot_exe: str
307
+ :param chroot_exe: chroot executable.
308
+ :type chroot_exe: str | None
309
309
  :return: Context manager with selected chroot state inside.
310
310
  :rtype: typing.ContextManager
311
311
 
@@ -351,17 +351,23 @@ class ExecHelper(
351
351
 
352
352
  return _helpers.mask_command(cmd.rstrip(), self.log_mask_re, log_mask_re)
353
353
 
354
- def _prepare_command(self, cmd: str, chroot_path: str | None = None, chroot_exe: str = "chroot") -> str:
354
+ def _prepare_command(self, cmd: str, chroot_path: str | None = None, chroot_exe: str | None = None) -> str:
355
355
  """Prepare command: cower chroot and other cases.
356
356
 
357
357
  :param cmd: Main command.
358
358
  :type cmd: str
359
359
  :param chroot_path: Path to make chroot for execution.
360
360
  :type chroot_path: str | None
361
+ :param chroot_exe: chroot exe override
362
+ :type chroot_exe: str | None
361
363
  :return: Final command, includes chroot, if required.
362
364
  :rtype: str
363
365
  """
364
- return _helpers.chroot_command(cmd, chroot_path=chroot_path or self._chroot_path, chroot_exe=chroot_exe)
366
+ return _helpers.chroot_command(
367
+ cmd,
368
+ chroot_path=chroot_path or self._chroot_path,
369
+ chroot_exe=chroot_exe or self._chroot_exe,
370
+ )
365
371
 
366
372
  @abc.abstractmethod
367
373
  async def _exec_command(
@@ -428,7 +434,7 @@ class ExecHelper(
428
434
  open_stdout: bool = True,
429
435
  open_stderr: bool = True,
430
436
  chroot_path: str | None = None,
431
- chroot_exe: str = "chroot",
437
+ chroot_exe: str | None = None,
432
438
  **kwargs: typing.Any,
433
439
  ) -> ExecuteContext:
434
440
  """Get execution context manager.
@@ -444,7 +450,7 @@ class ExecHelper(
444
450
  :param chroot_path: Chroot path override.
445
451
  :type chroot_path: str | None
446
452
  :param chroot_exe: Chroot exe override.
447
- :type chroot_exe: str
453
+ :type chroot_exe: str | None
448
454
  :param kwargs: Additional parameters for call.
449
455
  :type kwargs: typing.Any
450
456
  .. versionadded:: 8.0.0
@@ -463,7 +469,7 @@ class ExecHelper(
463
469
  open_stderr: bool = True,
464
470
  log_stderr: bool = True,
465
471
  chroot_path: str | None = None,
466
- chroot_exe: str = "chroot",
472
+ chroot_exe: str | None = None,
467
473
  **kwargs: typing.Any,
468
474
  ) -> exec_result.ExecResult:
469
475
  """Execute command and wait for return code.
@@ -490,7 +496,7 @@ class ExecHelper(
490
496
  :param chroot_path: chroot path override.
491
497
  :type chroot_path: str | None
492
498
  :param chroot_exe: chroot exe override.
493
- :type chroot_exe: str
499
+ :type chroot_exe: str | None
494
500
  :param kwargs: Additional parameters for call.
495
501
  :type kwargs: typing.Any
496
502
  :return: Execution result.
@@ -546,7 +552,7 @@ class ExecHelper(
546
552
  open_stderr: bool = True,
547
553
  log_stderr: bool = True,
548
554
  chroot_path: str | None = None,
549
- chroot_exe: str = "chroot",
555
+ chroot_exe: str | None = None,
550
556
  **kwargs: typing.Any,
551
557
  ) -> exec_result.ExecResult:
552
558
  """Execute command and wait for return code.
@@ -573,7 +579,7 @@ class ExecHelper(
573
579
  :param chroot_path: chroot path override.
574
580
  :type chroot_path: str | None
575
581
  :param chroot_exe: chroot exe override.
576
- :type chroot_exe: str
582
+ :type chroot_exe: str | None
577
583
  :param kwargs: Additional parameters for call.
578
584
  :type kwargs: typing.Any
579
585
  :return: Execution result.
@@ -355,7 +355,7 @@ class Subprocess(api.ExecHelper):
355
355
  open_stdout: bool = True,
356
356
  open_stderr: bool = True,
357
357
  chroot_path: str | None = None,
358
- chroot_exe: str = "chroot",
358
+ chroot_exe: str | None = None,
359
359
  cwd: CwdT = None,
360
360
  env: EnvT = None,
361
361
  env_patch: EnvT = None,
@@ -374,7 +374,7 @@ class Subprocess(api.ExecHelper):
374
374
  :param chroot_path: chroot path override.
375
375
  :type chroot_path: str | None
376
376
  :param chroot_exe: chroot exe override.
377
- :type chroot_exe: str
377
+ :type chroot_exe: str | None
378
378
  :param cwd: Sets the current directory before the child is executed.
379
379
  :type cwd: str | bytes | pathlib.Path | None
380
380
  :param env: Defines the environment variables for the new process.
@@ -415,7 +415,7 @@ class Subprocess(api.ExecHelper):
415
415
  open_stderr: bool = True,
416
416
  log_stderr: bool = True,
417
417
  chroot_path: str | None = None,
418
- chroot_exe: str = "chroot",
418
+ chroot_exe: str | None = None,
419
419
  cwd: CwdT = None,
420
420
  env: EnvT = None,
421
421
  env_patch: EnvT = None,
@@ -445,7 +445,7 @@ class Subprocess(api.ExecHelper):
445
445
  :param chroot_path: chroot path override.
446
446
  :type chroot_path: str | None
447
447
  :param chroot_exe: chroot exe override.
448
- :type chroot_exe: str
448
+ :type chroot_exe: str | None
449
449
  :param cwd: Sets the current directory before the child is executed.
450
450
  :type cwd: str | bytes | pathlib.Path | None
451
451
  :param env: Defines the environment variables for the new process.
@@ -494,7 +494,7 @@ class Subprocess(api.ExecHelper):
494
494
  open_stderr: bool = True,
495
495
  log_stderr: bool = True,
496
496
  chroot_path: str | None = None,
497
- chroot_exe: str = "chroot",
497
+ chroot_exe: str | None = None,
498
498
  cwd: CwdT = None,
499
499
  env: EnvT = None,
500
500
  env_patch: EnvT = None,
@@ -523,8 +523,8 @@ class Subprocess(api.ExecHelper):
523
523
  :type log_stderr: bool
524
524
  :param chroot_path: chroot path override.
525
525
  :type chroot_path: str | None
526
- :param chroot_exe: chroot path override.
527
- :type chroot_exe: str
526
+ :param chroot_exe: chroot exe override.
527
+ :type chroot_exe: str | None
528
528
  :param cwd: Sets the current directory before the child is executed.
529
529
  :type cwd: str | bytes | pathlib.Path | None
530
530
  :param env: Defines the environment variables for the new process.
@@ -50,7 +50,7 @@ except ImportError:
50
50
  lxml = None # pylint: disable=invalid-name
51
51
 
52
52
  if typing.TYPE_CHECKING:
53
- import xml.etree.ElementTree # nosec # for typing only
53
+ import xml.etree.ElementTree as ET # nosec # for typing only
54
54
  from collections.abc import Callable
55
55
  from collections.abc import Collection
56
56
  from collections.abc import Iterable
@@ -677,7 +677,7 @@ class ExecResult:
677
677
  # noinspection PyUnresolvedReferences
678
678
  @property
679
679
  @_handle_deserialize("xml")
680
- def stdout_xml(self) -> xml.etree.ElementTree.Element:
680
+ def stdout_xml(self) -> ET.Element:
681
681
  """XML from stdout.
682
682
 
683
683
  :return: Decoded XML document.
@@ -377,7 +377,7 @@ class Subprocess(api.ExecHelper):
377
377
  open_stdout: bool = True,
378
378
  open_stderr: bool = True,
379
379
  chroot_path: str | None = None,
380
- chroot_exe: str = "chroot",
380
+ chroot_exe: str | None = None,
381
381
  cwd: CwdT = None,
382
382
  env: EnvT = None,
383
383
  env_patch: EnvT = None,
@@ -396,7 +396,7 @@ class Subprocess(api.ExecHelper):
396
396
  :param chroot_path: chroot path override.
397
397
  :type chroot_path: str | None
398
398
  :param chroot_exe: chroot exe override.
399
- :type chroot_exe: str
399
+ :type chroot_exe: str | None
400
400
  :param cwd: Sets the current directory before the child is executed.
401
401
  :type cwd: str | bytes | pathlib.Path | None
402
402
  :param env: Defines the environment variables for the new process.
@@ -437,7 +437,7 @@ class Subprocess(api.ExecHelper):
437
437
  open_stderr: bool = True,
438
438
  log_stderr: bool = True,
439
439
  chroot_path: str | None = None,
440
- chroot_exe: str = "chroot",
440
+ chroot_exe: str | None = None,
441
441
  cwd: CwdT = None,
442
442
  env: EnvT = None,
443
443
  env_patch: EnvT = None,
@@ -467,7 +467,7 @@ class Subprocess(api.ExecHelper):
467
467
  :param chroot_path: chroot path override.
468
468
  :type chroot_path: str | None
469
469
  :param chroot_exe: chroot exe override.
470
- :type chroot_exe: str
470
+ :type chroot_exe: str | None
471
471
  :param cwd: Sets the current directory before the child is executed.
472
472
  :type cwd: str | bytes | pathlib.Path | None
473
473
  :param env: Defines the environment variables for the new process.
@@ -516,7 +516,7 @@ class Subprocess(api.ExecHelper):
516
516
  open_stderr: bool = True,
517
517
  log_stderr: bool = True,
518
518
  chroot_path: str | None = None,
519
- chroot_exe: str = "chroot",
519
+ chroot_exe: str | None = None,
520
520
  cwd: CwdT = None,
521
521
  env: EnvT = None,
522
522
  env_patch: EnvT = None,
@@ -545,8 +545,8 @@ class Subprocess(api.ExecHelper):
545
545
  :type log_stderr: bool
546
546
  :param chroot_path: chroot path override.
547
547
  :type chroot_path: str | None
548
- :param chroot_exe: chroot path override.
549
- :type chroot_exe: str
548
+ :param chroot_exe: chroot exe override.
549
+ :type chroot_exe: str | None
550
550
  :param cwd: Sets the current directory before the child is executed.
551
551
  :type cwd: str | bytes | pathlib.Path | None
552
552
  :param env: Defines the environment variables for the new process.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: exec-helpers
3
- Version: 8.1.0
3
+ Version: 8.1.2
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>
@@ -179,6 +179,7 @@ extend-select = [
179
179
  "ISC", # flake8-implicit-str-concat
180
180
  "RET", "SIM", "C4", # flake8-return, flake8-simplify, flake8-comprehensions
181
181
  "ICN", "PGH", # flake8-import-conventions, pygrep-hooks
182
+ "TID", # flake8-tidy-imports
182
183
  "Q", # quotes
183
184
  "FLY", # Flynt
184
185
  "FURB", # Refurb
@@ -191,6 +192,7 @@ extend-ignore = [
191
192
  "RET504", # Unnecessary variable assignment before return statement
192
193
  "SIM108", # Use ternary operator,
193
194
  "TRY003", # long messages prepare outside, ...
195
+ "TID252", # relative imports from parent modules
194
196
  ]
195
197
 
196
198
  [tool.ruff.lint.isort]
@@ -203,6 +205,9 @@ allow-dunder-method-names = ["__pretty_repr__", "__pretty_str__", "__rich_repr__
203
205
  [tool.ruff.lint.pydocstyle]
204
206
  convention = "pep257"
205
207
 
208
+ [tool.ruff.format]
209
+ docstring-code-format = true
210
+
206
211
  [tool.refurb]
207
212
  python_version = "3.8"
208
213
  enable_all = true
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes