Skip to content

Commit 9b78759

Browse files
authored
pedantic pylint & optimized travis.yml (#80)
1 parent dc294c8 commit 9b78759

File tree

8 files changed

+568
-327
lines changed

8 files changed

+568
-327
lines changed

.pylintrc

Lines changed: 421 additions & 271 deletions
Large diffs are not rendered by default.

.travis.yml

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,32 @@ install:
77
- &install_deps pip install -r CI_REQUIREMENTS.txt
88
- pip install --upgrade pytest-cov coveralls
99

10+
_python:
11+
- &python34
12+
name: "Python 3.4"
13+
python: 3.4
14+
- &python35
15+
name: "Python 3.5"
16+
python: 3.5
17+
- &python36
18+
name: "Python 3.6"
19+
python: 3.6
20+
- &python37
21+
name: "Python 3.7"
22+
python: 3.7
23+
dist: xenial
24+
sudo: true
25+
- &pypy3
26+
name: "PyPy3"
27+
python: pypy3.5
28+
1029
_helpers:
1130
- &install_cython pip install --upgrade Cython
1231
- &build_package python setup.py bdist_wheel
1332
- &install_built pip install exec_helpers --no-index -f dist
1433
- &test_no_cov py.test -vv test
1534
- &test_cythonized
35+
stage: Test cythonized
1636
install:
1737
- *upgrade_python_toolset
1838
- *install_test_deps
@@ -24,112 +44,92 @@ _helpers:
2444
- *test_no_cov
2545
after_success: skip
2646

47+
- &static_analysis
48+
stage: Static analysis
49+
<<: *python36
50+
after_success: skip
51+
52+
- &code_style_check
53+
stage: Code style check
54+
<<: *python36
55+
after_success: skip
56+
2757
script:
2858
- pip install -e .
2959
- py.test -vv --cov-config .coveragerc --cov-report= --cov=exec_helpers test
30-
- coverage report -m --fail-under 90
60+
- coverage report -m --fail-under 87
3161
after_success:
3262
- coveralls
3363

3464
jobs:
3565
fast_finish: true
3666
include:
3767
- stage: test
38-
name: "Python 3.4"
39-
python: 3.4
68+
<<: *python34
4069
- stage: test
41-
name: "Python 3.5"
42-
python: 3.5
70+
<<: *python35
4371
- stage: test
44-
name: "Python 3.6"
45-
python: 3.6
72+
<<: *python36
4673
- stage: test
47-
name: "Python 3.7"
48-
python: 3.7
49-
dist: xenial
50-
sudo: true
74+
<<: *python37
5175
- stage: test
52-
name: "PyPy3"
53-
python: pypy3.5
76+
<<: *pypy3
5477

55-
- stage: Static analisys
78+
- <<: *static_analysis
5679
name: "PyLint"
57-
python: 3.6
58-
services: []
5980
install:
6081
- *upgrade_python_toolset
6182
- *install_deps
62-
- pip install --upgrade "pylint >= 2.0"
83+
- pip install --upgrade "pylint >= 2.1"
6384
script:
6485
- pylint exec_helpers
65-
after_success: skip
66-
- stage: Static analisys
86+
- <<: *static_analysis
6787
name: "Bandit"
68-
python: 3.6
69-
services: []
7088
install:
7189
- *upgrade_python_toolset
7290
- pip install --upgrade bandit
7391
script:
7492
- bandit -r exec_helpers
75-
after_success: skip
76-
- stage: Static analisys
93+
- <<: *static_analysis
94+
<<: *python37
7795
name: "MyPy"
78-
python: 3.7
79-
dist: xenial
80-
sudo: true
81-
services: []
8296
install:
8397
- *upgrade_python_toolset
8498
- *install_deps
8599
- pip install --upgrade "mypy >= 0.620"
86100
script:
87101
- mypy --strict exec_helpers
88-
after_success: skip
89102

90-
- stage: Test cythonized
91-
name: "Python 3.4"
92-
python: 3.4
93-
<<: *test_cythonized
94-
- stage: Test cythonized
95-
name: "Python 3.5"
96-
python: 3.5
97-
<<: *test_cythonized
98-
- stage: Test cythonized
99-
name: "Python 3.6"
100-
python: 3.6
101-
<<: *test_cythonized
102-
- stage: Test cythonized
103-
name: "Python 3.7"
104-
python: 3.7
105-
dist: xenial
106-
sudo: true
107-
<<: *test_cythonized
103+
- <<: *test_cythonized
104+
<<: *python34
105+
- <<: *test_cythonized
106+
<<: *python35
107+
- <<: *test_cythonized
108+
<<: *python36
109+
- <<: *test_cythonized
110+
<<: *python37
108111

109-
- stage: Code style check
112+
- <<: *code_style_check
110113
name: "PEP8"
111-
python: 3.6
112114
install:
113115
- *upgrade_python_toolset
114116
- pip install --upgrade flake8
115117
script:
116118
- flake8
117-
after_success: skip
118-
- stage: Code style check
119+
- <<: *code_style_check
119120
name: "PEP257"
120-
python: 3.6
121121
install:
122122
- *upgrade_python_toolset
123123
- pip install --upgrade pydocstyle
124124
script:
125125
- pydocstyle exec_helpers
126-
after_success: skip
127126

128127
- stage: deploy
129128
# This prevents job from appearing in test plan unless commit is tagged:
130129
if: tag IS present
131130
# Run on pypy to build not cythonized wheel
132-
python: pypy3.5
131+
<<: *pypy3
132+
name: Build universal and cythonized bdist_wheel. Deploy bdist and sdist.
133133
services:
134134
- docker
135135
install:

exec_helpers/_ssh_client_base.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ def __call__( # type: ignore
129129
:type auth: typing.Optional[ssh_auth.SSHAuth]
130130
:param verbose: show additional error/warning messages
131131
:type verbose: bool
132+
:return: SSH client instance
132133
:rtype: SSHClientBase
133134
"""
134135
if (host, port) in cls.__cache:
@@ -218,7 +219,9 @@ def __init__(
218219
) -> None:
219220
"""Context manager for call commands with sudo.
220221
222+
:param ssh: connection instance
221223
:type ssh: SSHClientBase
224+
:param enforce: sudo mode for context manager
222225
:type enforce: typing.Optional[bool]
223226
"""
224227
self.__ssh = ssh
@@ -249,7 +252,9 @@ def __init__(
249252
) -> None:
250253
"""Context manager for keepalive management.
251254
255+
:param ssh: connection instance
252256
:type ssh: SSHClientBase
257+
:param enforce: keepalive mode for context manager
253258
:type enforce: bool
254259
:param enforce: Keep connection alive after context manager exit
255260
"""
@@ -526,6 +531,7 @@ def keepalive_mode(self) -> bool:
526531
def keepalive_mode(self, mode: bool) -> None:
527532
"""Persistent keepalive mode change for connection object.
528533
534+
:param mode: keepalive mode enable/disable
529535
:type mode: bool
530536
"""
531537
self.__keepalive_mode = bool(mode)
@@ -548,6 +554,7 @@ def sudo(
548554
549555
:param enforce: Enforce sudo enabled or disabled. By default: None
550556
:type enforce: typing.Optional[bool]
557+
:return: context manager with selected sudo state inside
551558
:rtype: typing.ContextManager
552559
"""
553560
return self.__get_sudo(ssh=self, enforce=enforce)
@@ -560,6 +567,7 @@ def keepalive(
560567
561568
:param enforce: Enforce keepalive enabled or disabled.
562569
:type enforce: bool
570+
:return: context manager with selected keepalive state inside
563571
:rtype: typing.ContextManager
564572
565573
.. Note:: Enter and exit ssh context manager is produced as well.
@@ -592,6 +600,9 @@ def execute_async(
592600
:param log_mask_re: regex lookup rule to mask command for logger.
593601
all MATCHED groups will be replaced by '<*masked*>'
594602
:type log_mask_re: typing.Optional[str]
603+
:param kwargs: additional parameters for call.
604+
:type kwargs: typing.Any
605+
:return: Tuple with control interface and file-like objects for STDIN/STDERR/STDOUT
595606
:rtype: typing.Tuple[
596607
paramiko.Channel,
597608
paramiko.ChannelFile,
@@ -661,15 +672,24 @@ def _exec_command(
661672
) -> exec_result.ExecResult:
662673
"""Get exit status from channel with timeout.
663674
675+
:param command: executed command (for logs)
664676
:type command: str
677+
:param interface: interface to control execution
665678
:type interface: paramiko.channel.Channel
679+
:param stdout: source for STDOUT read
666680
:type stdout: typing.Optional[paramiko.ChannelFile]
681+
:param stderr: source for STDERR read
667682
:type stderr: typing.Optional[paramiko.ChannelFile]
683+
:param timeout: timeout before stop execution with TimeoutError
668684
:type timeout: typing.Union[int, float, None]
685+
:param verbose: produce log.info records for STDOUT/STDERR
669686
:type verbose: bool
670687
:param log_mask_re: regex lookup rule to mask command for logger.
671688
all MATCHED groups will be replaced by '<*masked*>'
672689
:type log_mask_re: typing.Optional[str]
690+
:param kwargs: additional parameters for call.
691+
:type kwargs: typing.Any
692+
:return: Execution result
673693
:rtype: ExecResult
674694
:raises ExecHelperTimeoutError: Timeout exceeded
675695
@@ -776,6 +796,9 @@ def execute_through_host(
776796
:type timeout: typing.Union[int, float, None]
777797
:param get_pty: open PTY on target machine
778798
:type get_pty: bool
799+
:param kwargs: additional parameters for call.
800+
:type kwargs: typing.Any
801+
:return: Execution result
779802
:rtype: ExecResult
780803
:raises ExecHelperTimeoutError: Timeout exceeded
781804
@@ -851,6 +874,8 @@ def execute_together(
851874
:type expected: typing.Optional[typing.Iterable[]]
852875
:param raise_on_err: Raise exception on unexpected return code
853876
:type raise_on_err: bool
877+
:param kwargs: additional parameters for execute_async call.
878+
:type kwargs: typing.Any
854879
:return: dictionary {(hostname, port): result}
855880
:rtype: typing.Dict[typing.Tuple[str, int], exec_result.ExecResult]
856881
:raises ParallelCallProcessError: Unexpected any code at lest on one target
@@ -938,16 +963,21 @@ def get_result(remote: 'SSHClientBase') -> exec_result.ExecResult:
938963
def open(self, path: str, mode: str = 'r') -> paramiko.SFTPFile:
939964
"""Open file on remote using SFTP session.
940965
966+
:param path: filesystem object path
941967
:type path: str
968+
:param mode: open file mode ('t' is not supported)
942969
:type mode: str
943970
:return: file.open() stream
971+
:rtype: paramiko.SFTPFile
944972
"""
945973
return self._sftp.open(path, mode) # pragma: no cover
946974

947975
def exists(self, path: str) -> bool:
948976
"""Check for file existence using SFTP session.
949977
978+
:param path: filesystem object path
950979
:type path: str
980+
:return: path is valid (object exists)
951981
:rtype: bool
952982
"""
953983
try:
@@ -959,7 +989,9 @@ def exists(self, path: str) -> bool:
959989
def stat(self, path: str) -> paramiko.sftp_attr.SFTPAttributes:
960990
"""Get stat info for path with following symlinks.
961991
992+
:param path: filesystem object path
962993
:type path: str
994+
:return: stat like information for remote path
963995
:rtype: paramiko.sftp_attr.SFTPAttributes
964996
"""
965997
return self._sftp.stat(path) # pragma: no cover
@@ -983,7 +1015,9 @@ def utime(
9831015
def isfile(self, path: str) -> bool:
9841016
"""Check, that path is file using SFTP session.
9851017
1018+
:param path: remote path to validate
9861019
:type path: str
1020+
:return: path is file
9871021
:rtype: bool
9881022
"""
9891023
try:
@@ -995,7 +1029,9 @@ def isfile(self, path: str) -> bool:
9951029
def isdir(self, path: str) -> bool:
9961030
"""Check, that path is directory using SFTP session.
9971031
1032+
:param path: remote path to validate
9981033
:type path: str
1034+
:return: path is directory
9991035
:rtype: bool
10001036
"""
10011037
try:

0 commit comments

Comments
 (0)