Skip to content

Commit 0449c39

Browse files
authored
Expose ExecHelper base class to use as interface (#56)
* `ExecHelper` abstract class is expexcted to be used as interface, so make it public * Update typehints * Run mypy check on travis side Signed-off-by: Alexey Stepanov <penguinolog@gmail.com>
1 parent 730f2a9 commit 0449c39

File tree

10 files changed

+34
-28
lines changed

10 files changed

+34
-28
lines changed

.travis.yml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,16 @@ jobs:
2222
include:
2323
- stage: Static analisys
2424
python: 3.6
25-
services: skip
25+
services: []
2626
install:
2727
- *upgrade_python_toolset
2828
- pip install tox
2929
script:
30-
- tox -e pylint,bandit
30+
- tox -e pylint,bandit,mypy
3131
after_success: skip
3232

3333
- stage: Code style check
3434
python: *mainstream_python
35-
services: skip
3635
install:
3736
- *upgrade_python_toolset
3837
- pip install tox
@@ -45,8 +44,7 @@ jobs:
4544
if: tag IS present
4645
# Run on pypy to build not cythonized wheel
4746
python: *pypy
48-
services:
49-
- docker
47+
services: []
5048
install:
5149
- *upgrade_python_toolset
5250
script:

exec_helpers/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
)
2929

3030
from .exec_result import ExecResult
31+
from .api import ExecHelper
3132
from .ssh_auth import SSHAuth
3233
from .ssh_client import SSHClient
3334
from .subprocess_runner import Subprocess # nosec # Expected
@@ -39,6 +40,7 @@
3940
'ParallelCallExceptions',
4041
'ParallelCallProcessError',
4142
'ExecHelperTimeoutError',
43+
'ExecHelper',
4244
'SSHClient',
4345
'SSHAuth',
4446
'Subprocess',

exec_helpers/_ssh_client_base.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
import threaded
4141
import six
4242

43-
from exec_helpers import _api
43+
from exec_helpers import api
4444
from exec_helpers import constants
4545
from exec_helpers import exec_result
4646
from exec_helpers import exceptions
@@ -97,10 +97,10 @@ class _MemorizedSSH(type):
9797

9898
@classmethod
9999
def __prepare__(
100-
mcs,
100+
mcs, # type: typing.Type[_MemorizedSSH]
101101
name, # type: str
102102
bases, # type: typing.Iterable[typing.Type]
103-
**kwargs
103+
**kwargs # type: typing.Dict
104104
): # type: (...) -> collections.OrderedDict # pylint: disable=unused-argument
105105
"""Metaclass magic for object storage.
106106
@@ -109,7 +109,7 @@ def __prepare__(
109109
return collections.OrderedDict() # pragma: no cover
110110

111111
def __call__(
112-
cls,
112+
cls, # type: _MemorizedSSH
113113
host, # type: str
114114
port=22, # type: int
115115
username=None, # type: typing.Optional[str]
@@ -167,7 +167,7 @@ def __call__(
167167
return ssh
168168

169169
@classmethod
170-
def clear_cache(mcs): # type: () -> None
170+
def clear_cache(mcs): # type: (typing.Type[_MemorizedSSH]) -> None
171171
"""Clear cached connections for initialize new instance on next call.
172172
173173
getrefcount is used to check for usage.
@@ -185,14 +185,14 @@ def clear_cache(mcs): # type: () -> None
185185
mcs.__cache = {}
186186

187187
@classmethod
188-
def close_connections(mcs): # type: (...) -> None
188+
def close_connections(mcs): # type: (typing.Type[_MemorizedSSH]) -> None
189189
"""Close connections for selected or all cached records."""
190190
for ssh in mcs.__cache.values():
191191
if ssh.is_alive:
192192
ssh.close()
193193

194194

195-
class SSHClientBase(six.with_metaclass(_MemorizedSSH, _api.ExecHelper)):
195+
class SSHClientBase(six.with_metaclass(_MemorizedSSH, api.ExecHelper)):
196196
"""SSH Client helper."""
197197

198198
__slots__ = (
@@ -454,7 +454,9 @@ def close(self):
454454

455455
# noinspection PyMethodParameters
456456
@close.class_method
457-
def close(cls): # pylint: disable=no-self-argument
457+
def close( # pylint: disable=no-self-argument
458+
cls # type: typing.Type[SSHClientBase]
459+
): # type: (...) -> None
458460
"""Close all memorized SSH and SFTP sessions."""
459461
# noinspection PyUnresolvedReferences
460462
cls.__class__.close_connections()

exec_helpers/_ssh_client_base.pyi

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@ import typing
33

44
import paramiko # type: ignore
55

6-
from exec_helpers import exec_result, ssh_auth, _api
6+
from exec_helpers import exec_result, ssh_auth, api
7+
8+
CPYTHON: bool = ...
79

810

911
class _MemorizedSSH(type):
1012
@classmethod
11-
def __prepare__(mcs: typing.Type, name: str, bases: typing.Iterable[typing.Type], **kwargs: typing.Dict) -> collections.OrderedDict: ...
13+
def __prepare__(mcs: typing.Type[_MemorizedSSH], name: str, bases: typing.Iterable[typing.Type], **kwargs: typing.Dict) -> collections.OrderedDict: ...
1214

1315
def __call__( # type: ignore
14-
cls: typing.Type[SSHClientBase],
16+
cls: _MemorizedSSH,
1517
host: str,
1618
port: int=...,
1719
username: typing.Optional[str]=...,
@@ -22,13 +24,13 @@ class _MemorizedSSH(type):
2224
) -> SSHClientBase: ...
2325

2426
@classmethod
25-
def clear_cache(mcs: typing.Type[SSHClientBase]) -> None: ... # type: ignore
27+
def clear_cache(mcs: typing.Type[_MemorizedSSH]) -> None: ...
2628

2729
@classmethod
28-
def close_connections(mcs: typing.Type[SSHClientBase]) -> None: ... # type: ignore
30+
def close_connections(mcs: typing.Type[_MemorizedSSH]) -> None: ...
2931

3032

31-
class SSHClientBase(_api.ExecHelper, metaclass=_MemorizedSSH):
33+
class SSHClientBase(api.ExecHelper, metaclass=_MemorizedSSH):
3234
def __hash__(self) -> int: ...
3335

3436
def __init__(
@@ -65,7 +67,7 @@ class SSHClientBase(_api.ExecHelper, metaclass=_MemorizedSSH):
6567
def _sftp(self) -> paramiko.sftp_client.SFTPClient: ...
6668

6769
@classmethod
68-
def close(cls) -> None: ...
70+
def close(cls: typing.Union[SSHClientBase, typing.Type[SSHClientBase]]) -> None: ...
6971

7072
@classmethod
7173
def _clear_cache(cls) -> None: ...

exec_helpers/_api.py renamed to exec_helpers/api.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"""ExecHelpers global API.
1717
1818
.. versionadded:: 1.2.0
19+
.. versionchanged:: 1.3.5 make API public to use as interface
1920
"""
2021

2122
from __future__ import absolute_import
@@ -54,6 +55,7 @@ def __init__(
5455
:type log_mask_re: typing.Optional[str]
5556
5657
.. versionchanged:: 1.2.0 log_mask_re regex rule for masking cmd
58+
.. versionchanged:: 1.3.5 make API public to use as interface
5759
"""
5860
self.__lock = threading.RLock()
5961
self.__logger = logger
File renamed without changes.

exec_helpers/subprocess_runner.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
import six
3737
import threaded
3838

39-
from exec_helpers import _api
39+
from exec_helpers import api
4040
from exec_helpers import exec_result
4141
from exec_helpers import exceptions
4242
from exec_helpers import _log_templates
@@ -122,7 +122,7 @@ def set_nonblocking_pipe(pipe): # type: (typing.Any) -> None
122122
)
123123

124124

125-
class Subprocess(six.with_metaclass(SingletonMeta, _api.ExecHelper)):
125+
class Subprocess(six.with_metaclass(SingletonMeta, api.ExecHelper)):
126126
"""Subprocess helper with timeouts and lock-free FIFO."""
127127

128128
def __init__(

exec_helpers/subprocess_runner.pyi

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import subprocess
44
import threading
55
import typing
66

7-
from exec_helpers import exec_result, _api
7+
from exec_helpers import exec_result, api
88

99
logger: logging.Logger
1010
devnull: typing.IO
@@ -16,16 +16,16 @@ class SingletonMeta(type):
1616
_instances: typing.Dict[typing.Type, typing.Any] = ...
1717
_lock: threading.RLock = ...
1818

19-
def __call__(cls: typing.Type, *args: typing.Tuple, **kwargs: typing.Dict) -> typing.Any: ...
19+
def __call__(cls: SingletonMeta, *args: typing.Tuple, **kwargs: typing.Dict) -> typing.Any: ...
2020

2121
@classmethod
22-
def __prepare__(mcs: typing.Type, name: str, bases: typing.Iterable[typing.Type], **kwargs: typing.Dict) -> collections.OrderedDict: ...
22+
def __prepare__(mcs: typing.Type[SingletonMeta], name: str, bases: typing.Iterable[typing.Type], **kwargs: typing.Dict) -> collections.OrderedDict: ...
2323

2424

2525
def set_nonblocking_pipe(pipe: typing.Any) -> None: ...
2626

2727

28-
class Subprocess(_api.ExecHelper, metaclass=SingletonMeta):
28+
class Subprocess(api.ExecHelper, metaclass=SingletonMeta):
2929
def __init__(
3030
self,
3131
log_mask_re: typing.Optional[str]=...

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def _extension(modpath):
6464

6565

6666
requires_optimization = [
67-
_extension('exec_helpers._api'),
67+
_extension('exec_helpers.api'),
6868
_extension('exec_helpers.constants'),
6969
_extension('exec_helpers._log_templates'),
7070
_extension('exec_helpers.exceptions'),

tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
[tox]
77
minversion = 2.0
8-
envlist = pep8, pep257, py{27,34,35,36,37,py,py3}, pylint, bandit, py{34,35,36,37}-nocov, docs,
8+
envlist = pep8, pep257, py{27,34,35,36,37,py,py3}, pylint, bandit, py{34,35,36,37}-nocov, mypy, docs
99
skipsdist = True
1010
skip_missing_interpreters = True
1111

0 commit comments

Comments
 (0)