Skip to content

Commit 2a64bbf

Browse files
authored
Fix ExecResult compare: allow subclassing. Re-raise auth errors ASAP. (#99)
* Make tests faster. * Bump to 3.1.1
1 parent f120cae commit 2a64bbf

File tree

11 files changed

+658
-582
lines changed

11 files changed

+658
-582
lines changed

exec_helpers/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"async_api",
5252
)
5353

54-
__version__ = "3.1.0"
54+
__version__ = "3.1.1"
5555
__author__ = "Alexey Stepanov"
5656
__author_email__ = "penguinolog@gmail.com"
5757
__maintainers__ = {

exec_helpers/_ssh_client_base.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@
4949
logging.getLogger("iso8601").setLevel(logging.WARNING)
5050

5151

52+
class RetryOnExceptions(tenacity.retry_if_exception): # type: ignore
53+
"""Advanced retry on exceptions."""
54+
55+
def __init__(
56+
self,
57+
retry_on: typing.Union[typing.Type[BaseException], typing.Tuple[typing.Type[BaseException], ...]],
58+
reraise: typing.Union[typing.Type[BaseException], typing.Tuple[typing.Type[BaseException], ...]],
59+
) -> None:
60+
"""Retry on exceptions, except several types."""
61+
super(RetryOnExceptions, self).__init__(lambda e: isinstance(e, retry_on) and not isinstance(e, reraise))
62+
63+
5264
# noinspection PyTypeHints
5365
class SshExecuteAsyncResult(api.ExecuteAsyncResult):
5466
"""Override original NamedTuple with proper typing."""
@@ -376,7 +388,7 @@ def _ssh(self) -> paramiko.SSHClient:
376388
return self.__ssh
377389

378390
@tenacity.retry( # type: ignore
379-
retry=tenacity.retry_if_exception_type(paramiko.SSHException),
391+
retry=RetryOnExceptions(retry_on=paramiko.SSHException, reraise=paramiko.AuthenticationException),
380392
stop=tenacity.stop_after_attempt(3),
381393
wait=tenacity.wait_fixed(3),
382394
reraise=True,

exec_helpers/async_api/exec_result.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,3 @@ async def read_stderr( # type: ignore
103103
with self.stderr_lock:
104104
self._stderr_str = self._stderr_brief = None
105105
self._stderr += tuple(await self._poll_stream(src, log, verbose))
106-
107-
def __hash__(self) -> int:
108-
"""Hash for usage as dict key and in sets."""
109-
return hash((super(ExecResult, self).__class__, self.cmd, self.stdin, self.stdout, self.stderr, self.exit_code))

exec_helpers/exec_result.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,17 @@ def __str__(self) -> str:
465465

466466
def __eq__(self, other: typing.Any) -> bool:
467467
"""Comparision."""
468-
return hash(self) == hash(other)
468+
return (
469+
self.__class__ is other.__class__
470+
or issubclass(self.__class__, other.__class__)
471+
or issubclass(other.__class__, self.__class__)
472+
) and (
473+
self.cmd == other.cmd
474+
and self.stdin == other.stdin
475+
and self.stdout == other.stdout
476+
and self.stderr == other.stderr
477+
and self.exit_code == other.exit_code
478+
)
469479

470480
def __ne__(self, other: typing.Any) -> bool:
471481
"""Comparision."""

pytest.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
[pytest]
22
addopts = -vvv -s -p no:django -p no:ipdb
33
testpaths = test
4+
mock_use_standalone_module = true

test/async_api/test_subprocess.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ def run_parameters(request):
127127

128128
@pytest.fixture
129129
def exec_result(run_parameters):
130-
return exec_helpers.async_api.ExecResult(
130+
return exec_helpers.ExecResult(
131131
cmd=command,
132132
stdin=run_parameters["stdin"],
133133
stdout=tuple([line for line in run_parameters["stdout"]]) if run_parameters["stdout"] else None,

test/async_api/test_subprocess_special.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ def exec_result(run_parameters):
142142
else:
143143
stdout_res = tuple([elem for elem in run_parameters["stdout"] if isinstance(elem, bytes)])
144144

145-
return exec_helpers.async_api.ExecResult(
145+
return exec_helpers.ExecResult(
146146
cmd=run_parameters.get("masked_cmd", command),
147147
stdin=run_parameters.get("stdin", None),
148148
stdout=stdout_res,

0 commit comments

Comments
 (0)