Skip to content

Commit ca3fcfc

Browse files
committed
more type checking
1 parent b43e7b8 commit ca3fcfc

15 files changed

+261
-182
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
MODULE1=wes_client
2424
MODULE2=wes_service
2525
PACKAGE=wes-service
26-
EXTRAS=[toil,arvados]
26+
EXTRAS=[toil]
2727

2828
# `SHELL=bash` doesn't work for some, so don't use BASH-isms like
2929
# `[[` conditional expressions.

cwl_flask.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,38 @@
11
import copy
22
import json
3+
import shutil
34
import signal
45
import subprocess
56
import tempfile
67
import threading
78
import time
9+
from typing import Any, Dict, Generator, List, Tuple
810

11+
import werkzeug.wrappers.response
912
import yaml
1013
from flask import Flask, Response, redirect, request
1114

1215
app = Flask(__name__)
1316

1417
jobs_lock = threading.Lock()
15-
jobs = []
18+
jobs: List["Job"] = []
1619

1720

1821
class Job(threading.Thread):
19-
def __init__(self, jobid, path, inputobj):
22+
def __init__(self, jobid: int, path: str, inputobj: bytes) -> None:
2023
super().__init__()
2124
self.jobid = jobid
2225
self.path = path
2326
self.inputobj = inputobj
2427
self.updatelock = threading.Lock()
2528
self.begin()
2629

27-
def begin(self):
30+
def begin(self) -> None:
2831
loghandle, self.logname = tempfile.mkstemp()
2932
with self.updatelock:
3033
self.outdir = tempfile.mkdtemp()
3134
self.proc = subprocess.Popen(
32-
["cwl-runner", self.path, "-"],
35+
[shutil.which("cwl-runner") or "cwl-runner", self.path, "-"],
3336
stdin=subprocess.PIPE,
3437
stdout=subprocess.PIPE,
3538
stderr=loghandle,
@@ -45,7 +48,7 @@ def begin(self):
4548
"output": None,
4649
}
4750

48-
def run(self):
51+
def run(self) -> None:
4952
self.stdoutdata, self.stderrdata = self.proc.communicate(self.inputobj)
5053
if self.proc.returncode == 0:
5154
outobj = yaml.load(self.stdoutdata, Loader=yaml.FullLoader)
@@ -56,31 +59,31 @@ def run(self):
5659
with self.updatelock:
5760
self.status["state"] = "Failed"
5861

59-
def getstatus(self):
62+
def getstatus(self) -> Dict[str, Any]:
6063
with self.updatelock:
6164
return self.status.copy()
6265

63-
def cancel(self):
66+
def cancel(self) -> None:
6467
if self.status["state"] == "Running":
6568
self.proc.send_signal(signal.SIGQUIT)
6669
with self.updatelock:
6770
self.status["state"] = "Canceled"
6871

69-
def pause(self):
72+
def pause(self) -> None:
7073
if self.status["state"] == "Running":
7174
self.proc.send_signal(signal.SIGTSTP)
7275
with self.updatelock:
7376
self.status["state"] = "Paused"
7477

75-
def resume(self):
78+
def resume(self) -> None:
7679
if self.status["state"] == "Paused":
7780
self.proc.send_signal(signal.SIGCONT)
7881
with self.updatelock:
7982
self.status["state"] = "Running"
8083

8184

8285
@app.route("/run", methods=["POST"])
83-
def runworkflow():
86+
def runworkflow() -> werkzeug.wrappers.response.Response:
8487
path = request.args["wf"]
8588
with jobs_lock:
8689
jobid = len(jobs)
@@ -91,7 +94,7 @@ def runworkflow():
9194

9295

9396
@app.route("/jobs/<int:jobid>", methods=["GET", "POST"])
94-
def jobcontrol(jobid):
97+
def jobcontrol(jobid: int) -> Tuple[str, int]:
9598
with jobs_lock:
9699
job = jobs[jobid]
97100
if request.method == "POST":
@@ -105,10 +108,10 @@ def jobcontrol(jobid):
105108
job.resume()
106109

107110
status = job.getstatus()
108-
return json.dumps(status, indent=4), 200, ""
111+
return json.dumps(status, indent=4), 200
109112

110113

111-
def logspooler(job):
114+
def logspooler(job: Job) -> Generator[str, None, None]:
112115
with open(job.logname) as f:
113116
while True:
114117
r = f.read(4096)
@@ -122,18 +125,18 @@ def logspooler(job):
122125

123126

124127
@app.route("/jobs/<int:jobid>/log", methods=["GET"])
125-
def getlog(jobid):
128+
def getlog(jobid: int) -> Response:
126129
with jobs_lock:
127130
job = jobs[jobid]
128131
return Response(logspooler(job))
129132

130133

131134
@app.route("/jobs", methods=["GET"])
132-
def getjobs():
135+
def getjobs() -> Response:
133136
with jobs_lock:
134137
jobscopy = copy.copy(jobs)
135138

136-
def spool(jc):
139+
def spool(jc: List[Job]) -> Generator[str, None, None]:
137140
yield "["
138141
first = True
139142
for j in jc:

cwltool_stream.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,34 @@
44
import logging
55
import sys
66
import tempfile
7+
from io import StringIO
8+
from typing import List, Union
79

810
import cwltool.main
9-
import StringIO
1011

1112
_logger = logging.getLogger("cwltool")
1213
_logger.setLevel(logging.ERROR)
1314

1415

15-
def main(args=None):
16-
if args is None:
17-
args = sys.argv[1:]
18-
16+
def main(args: List[str] = sys.argv[1:]) -> int:
1917
if len(args) == 0:
2018
print("Workflow must be on command line")
2119
return 1
2220

23-
parser = cwltool.main.arg_parser()
21+
parser = cwltool.argparser.arg_parser()
2422
parsedargs = parser.parse_args(args)
2523

26-
a = True
24+
a: Union[bool, str] = True
2725
while a:
28-
a = True
2926
msg = ""
3027
while a and a != "\n":
3128
a = sys.stdin.readline()
3229
msg += a
3330

3431
outdir = tempfile.mkdtemp("", parsedargs.tmp_outdir_prefix)
3532

36-
t = StringIO.StringIO(msg)
37-
err = StringIO.StringIO()
33+
t = StringIO(msg)
34+
err = StringIO()
3835
if (
3936
cwltool.main.main(
4037
["--outdir=" + outdir] + args + ["-"], stdin=t, stderr=err
@@ -44,6 +41,8 @@ def main(args=None):
4441
sys.stdout.write(json.dumps({"cwl:error": err.getvalue()}))
4542
sys.stdout.write("\n\n")
4643
sys.stdout.flush()
44+
a = True
45+
return 0
4746

4847

4948
if __name__ == "__main__":

mypy-requirements.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
mypy==1.10.1
1+
mypy==1.15
2+
types-PyYAML
3+
types-requests
4+
types-setuptools
5+
arvados-cwl-runner

mypy.ini

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[mypy]
2+
show_error_context = true
3+
show_column_numbers = true
4+
show_error_codes = true
5+
pretty = true
6+
strict = true
7+
[mypy-ruamel.*]
8+
ignore_errors = True

test/test_client_util.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212

1313
class IntegrationTest(unittest.TestCase):
14-
def setUp(self):
14+
def setUp(self) -> None:
1515
dirname, filename = os.path.split(os.path.abspath(__file__))
1616
self.testdata_dir = dirname + "data"
1717
self.local = {
@@ -37,26 +37,28 @@ def setUp(self):
3737
"pyWithPrefix": ("3", "PY"),
3838
}
3939

40-
def tearDown(self):
40+
def tearDown(self) -> None:
4141
unittest.TestCase.tearDown(self)
4242

43-
def test_expand_globs(self):
43+
def test_expand_globs(self) -> None:
4444
"""Asserts that wes_client.expand_globs() sees the same files in the cwd as 'ls'."""
4545
files = subprocess.check_output(["ls", "-1", "."])
4646

4747
# python 2/3 bytestring/utf-8 compatibility
4848
if isinstance(files, str):
49-
files = files.split("\n")
49+
files2 = files.split("\n")
5050
else:
51-
files = files.decode("utf-8").split("\n")
51+
files2 = files.decode("utf-8").split("\n")
5252

53-
if "" in files:
54-
files.remove("")
55-
files = ["file://" + os.path.abspath(f) for f in files]
53+
if "" in files2:
54+
files2.remove("")
55+
files2 = ["file://" + os.path.abspath(f) for f in files2]
5656
glob_files = expand_globs("*")
57-
assert set(files) == glob_files, "\n" + str(set(files)) + "\n" + str(glob_files)
57+
assert set(files2) == glob_files, (
58+
"\n" + str(set(files2)) + "\n" + str(glob_files)
59+
)
5860

59-
def testSupportedFormatChecking(self):
61+
def testSupportedFormatChecking(self) -> None:
6062
"""
6163
Check that non-wdl, -python, -cwl files are rejected.
6264
@@ -75,7 +77,7 @@ def testSupportedFormatChecking(self):
7577
with self.assertRaises(TypeError):
7678
wf_info(location)
7779

78-
def testFileLocationChecking(self):
80+
def testFileLocationChecking(self) -> None:
7981
"""
8082
Check that the function rejects unsupported file locations.
8183

0 commit comments

Comments
 (0)