Skip to content

Commit 4849dda

Browse files
committed
Fix ExecResult compare: allow subclassing. Re-raise auth errors ASAP. (#99)
* Make tests faster. * Bump to 3.1.1 (cherry picked from commit 2a64bbf) Signed-off-by: Alexey Stepanov <penguinolog@gmail.com>
1 parent 94d8cfe commit 4849dda

File tree

8 files changed

+656
-576
lines changed

8 files changed

+656
-576
lines changed

exec_helpers/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"ExecResult",
5050
)
5151

52-
__version__ = "2.9.0"
52+
__version__ = "2.9.1"
5353
__author__ = "Alexey Stepanov"
5454
__author_email__ = "penguinolog@gmail.com"
5555
__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/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

0 commit comments

Comments
 (0)