Skip to content

Commit 781573d

Browse files
author
Alan Christie
committed
Use of pylint and mypy
1 parent 25005b5 commit 781573d

File tree

8 files changed

+53
-24
lines changed

8 files changed

+53
-24
lines changed

.github/workflows/build.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ jobs:
4141
pip install -r package-requirements.txt
4242
- name: Test
4343
run: |
44+
pylint jote
45+
mypy jote --install-types --non-interactive
4446
pyroma .
4547
- name: Build
4648
run: |

.pylintrc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[messages control]
2+
3+
# Disable some distracting checks.
4+
# See http://pylint.pycqa.org/en/latest/user_guide/message-control.html
5+
#
6+
# R : (Refactoring) warnings
7+
disable = import-error,
8+
too-many-arguments,
9+
too-many-locals,
10+
too-many-branches,
11+
too-many-statements

build-requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
pyroma == 3.2
22
pytest == 6.2.5
33
pytest-cov == 3.0.0
4+
mypy == 0.931
5+
pylint == 2.12.2

jote/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from .jote import main as jote_main
1010

1111

12-
def main():
12+
def main() -> int:
1313
"""The entry-point of the component."""
1414
return jote_main()
1515

jote/compose.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,13 @@
3535

3636
def _get_docker_compose_version() -> str:
3737

38-
result: subprocess.CompletedProcess =\
39-
subprocess.run(['docker-compose', 'version'],
40-
capture_output=True, timeout=4)
38+
result = subprocess.run(['docker-compose', 'version'],
39+
capture_output=True, check=False, timeout=4)
4140

4241
# stdout will contain the version on the first line: -
4342
# "docker-compose version 1.29.2, build unknown"
4443
# Ignore the first 23 characters of the first line...
45-
return result.stdout.decode("utf-8").split('\n')[0][23:]
44+
return str(result.stdout.decode("utf-8").split('\n')[0][23:])
4645

4746

4847
def get_test_root() -> str:
@@ -53,6 +52,9 @@ def get_test_root() -> str:
5352

5453

5554
class Compose:
55+
"""A class handling the execution of 'docker-compose'
56+
for an individual test.
57+
"""
5658

5759
# The docker-compose version (for the first test)
5860
_COMPOSE_VERSION: Optional[str] = None
@@ -104,7 +106,7 @@ def create(self) -> str:
104106
print(f'# docker-compose ({Compose._COMPOSE_VERSION})')
105107

106108
# Make the test directory...
107-
test_path: str = self.get_test_path()
109+
test_path = self.get_test_path()
108110
project_path: str = self.get_test_project_path()
109111
inst_path: str = f'{project_path}/{_INSTANCE_DIRECTORY}'
110112
if not os.path.exists(inst_path):
@@ -142,15 +144,16 @@ def run(self) -> Tuple[int, str, str]:
142144
try:
143145
# Run the container
144146
# and then cleanup
145-
test: subprocess.CompletedProcess =\
146-
subprocess.run(['docker-compose', 'up',
147-
'--exit-code-from', 'job',
148-
'--abort-on-container-exit'],
149-
capture_output=True,
150-
timeout=timeout)
147+
test = subprocess.run(['docker-compose', 'up',
148+
'--exit-code-from', 'job',
149+
'--abort-on-container-exit'],
150+
capture_output=True,
151+
timeout=timeout,
152+
check=False)
151153
_ = subprocess.run(['docker-compose', 'down'],
152154
capture_output=True,
153-
timeout=120)
155+
timeout=120,
156+
check=False)
154157
finally:
155158
os.chdir(cwd)
156159

jote/jote.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@
2020

2121
# Where can we expect to find Job definitions?
2222
_DEFINITION_DIRECTORY: str = 'data-manager'
23-
# Data directory
23+
# Where can we expect to find test data?
2424
_DATA_DIRECTORY: str = 'data'
2525

2626
# The yamllint configuration file of the repository under test.
27-
# Expected to be in the repo we're running from.
27+
# It must exist in the root of the repo we're running in.
2828
_YAMLLINT_FILE: str = '.yamllint'
2929

3030

@@ -105,9 +105,9 @@ def _load(skip_lint: bool = False) -> Tuple[List[DefaultMunch], int]:
105105
return [], -1
106106

107107
with open(jd_filename, 'r') as jd_file:
108-
jd: Dict[str, Any] = yaml.load(jd_file, Loader=yaml.FullLoader)
109-
if jd:
110-
jd_munch: DefaultMunch = DefaultMunch.fromDict(jd)
108+
job_def: Dict[str, Any] = yaml.load(jd_file, Loader=yaml.FullLoader)
109+
if job_def:
110+
jd_munch: DefaultMunch = DefaultMunch.fromDict(job_def)
111111
for jd_name in jd_munch.jobs:
112112
if jd_munch.jobs[jd_name].tests:
113113
num_tests += len(jd_munch.jobs[jd_name].tests)
@@ -158,7 +158,7 @@ def _check_exists(name: str, path: str, expected: bool) -> bool:
158158
print('! FAILURE')
159159
print(f'! Check exists "{name}" (does not exist)')
160160
return False
161-
elif not expected and exists:
161+
if not expected and exists:
162162
print(f'# exists ({expected}) [FAILED]')
163163
print('! FAILURE')
164164
print(f'! Check does not exist "{name}" (exists)')
@@ -329,7 +329,8 @@ def _test(args: argparse.Namespace,
329329
# Run the container
330330
if test_status and not args.dry_run:
331331
# Run the container
332-
exit_code, out, err = t_compose.run()
332+
assert t_compose
333+
exit_code, out, _ = t_compose.run()
333334

334335
# Delete the test directory?
335336
# Not if there's an error
@@ -353,12 +354,15 @@ def _test(args: argparse.Namespace,
353354
if test_status \
354355
and not args.dry_run \
355356
and job_definition.tests[job_test_name].checks.outputs:
357+
358+
assert t_compose
356359
test_status = \
357360
_check(t_compose,
358361
job_definition.tests[job_test_name].checks.outputs)
359362

360363
# Clean-up
361364
if test_status and not args.keep_results:
365+
assert t_compose
362366
t_compose.delete()
363367

364368
# Count?
@@ -383,7 +387,7 @@ def _wipe() -> None:
383387
# -----------------------------------------------------------------------------
384388
# main
385389
# -----------------------------------------------------------------------------
386-
def main() -> None:
390+
def main() -> int:
387391
"""The console script entry-point. Called when jote is executed
388392
or from __main__.py, which is used by the installed console script.
389393
"""
@@ -468,7 +472,7 @@ def main() -> None:
468472
if args.wipe:
469473
_wipe()
470474
print(f'Done [Wiped]')
471-
return
475+
return 0
472476

473477
# Load all the files we can and then run the tests.
474478
job_definitions, num_tests = _load(args.skip_lint)
@@ -503,7 +507,7 @@ def main() -> None:
503507
continue
504508

505509
if job_definition.jobs[job_name].tests:
506-
num_passed, num_ignored, num_failed =\
510+
_, num_ignored, num_failed =\
507511
_test(args,
508512
collection,
509513
job_name,
@@ -547,6 +551,8 @@ def main() -> None:
547551
if total_fail_count == 0 and not args.keep_results:
548552
_wipe()
549553

554+
return 0
555+
550556

551557
# -----------------------------------------------------------------------------
552558
# MAIN

mypy.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[mypy]
2+
# Strict
3+
strict = True
4+
# Now enable more rules
5+
ignore_missing_imports = True

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def get_long_description():
2929
author_email='[email protected]',
3030
url='https://github.com/informaticsmatters/data-manager-job-tester',
3131
license=copyright,
32-
description='test',
32+
description='The IM Data Manager Job Tester (jote)',
3333
long_description=get_long_description(),
3434
keywords='configuration',
3535
platforms=['any'],

0 commit comments

Comments
 (0)