Skip to content

[MRG] Working towards python3 compatible codebase #442

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
e10b38a
setup.py: install schema_salad >= 3.0
manu-chroma May 27, 2017
85710a6
tests: run modernize fixer
manu-chroma Jun 1, 2017
c3d5b94
cwltool: run modernize fixer
manu-chroma Jun 1, 2017
cd92d93
use urllib from six.moves for py3 compat
manu-chroma Jun 1, 2017
a733696
fix: minor: py3 compatibility wrt avro
manu-chroma Jun 1, 2017
1213313
fix: pesky byte string comparision bug causing unit test to hang in p…
manu-chroma Jun 4, 2017
307c758
cwltool/job.py: use io.IOBase rather than file class in isinstance()
manu-chroma Jun 4, 2017
c4b1084
test_relax_path_checks: open temp file with 'w' mode
manu-chroma Jun 13, 2017
278b88b
test_toolargparse: open temp file in 'w' mode rather than 'w+b'
manu-chroma Jun 13, 2017
255ccb1
update mypy package to 0.511
manu-chroma Jun 13, 2017
381057e
typesheds/2.7: remove stub files which already come with mypy==0.511
manu-chroma Jun 14, 2017
5cffdf8
update mistune stub file
manu-chroma Jun 14, 2017
1d78137
Makefile: remove --fast-parser option. comes by default in mypy now
manu-chroma Jun 14, 2017
336c22d
typeshed: minor import fix
manu-chroma Jun 14, 2017
7829a08
mypy: add missing import statments from typing package
manu-chroma Jun 14, 2017
a4eb157
expression.py: use unicode in regex and fix minor type annotation
manu-chroma Jun 14, 2017
1cf4edc
typesheds: re-organise
manu-chroma Jun 14, 2017
52e3795
Makefile: update folders in MYPYPATH
manu-chroma Jun 14, 2017
345beef
move shellescape stub files to typeshed/2and3
manu-chroma Jun 14, 2017
0bbde24
cwltool: replace annotations unicode->Text
manu-chroma Jun 14, 2017
45f17c1
use __future__ unicode_literals everywhere
manu-chroma Jun 14, 2017
06a46c6
expression.py: use unicode in constucting regex strings and pass expl…
manu-chroma Jun 14, 2017
b9733c4
mypy: convert to unicode strings on return from urllib api
manu-chroma Jun 14, 2017
e652d94
docker.py: pass native py2 string as mode paramter to open()
manu-chroma Jun 14, 2017
0ded86e
builder.py: use Text inplace of str type annotation
manu-chroma Jun 14, 2017
cdd53ad
main.py: use py3 compatible dict to list syntax, import unicode_literals
manu-chroma Jun 16, 2017
a39cb18
sandboxjs.py: encode and decode strings when dealing with BytesIO()
manu-chroma Jun 16, 2017
bbdd479
tests: add utf-8 encoding directive to all .py files
manu-chroma Jun 17, 2017
b3ee9fb
add mypy config file to silence ruamel package errors
manu-chroma Jun 17, 2017
885149e
typshed/2.7: add urllib, urlparse typesheds with minor changes
manu-chroma Jun 17, 2017
2342373
typesheds/rdflib: allow unicode strings to be passed
manu-chroma Jun 17, 2017
4524816
typeshed/pkg_resources: use Text inplace of str
manu-chroma Jun 17, 2017
135209e
tox.ini: better naming of mypy tests
manu-chroma Jun 17, 2017
deac875
.gitignore: update
manu-chroma Jun 17, 2017
63cf519
add utf-8 encoding line to the top of the files
manu-chroma Jun 17, 2017
6554940
add select.pyi stub fiile until next release of mypy and updated type…
manu-chroma Jun 17, 2017
2bdc44b
draf2tool: use explicit binary content marking, decoding
manu-chroma Jun 19, 2017
6da479c
update .gitignore
manu-chroma Jun 19, 2017
9f1a051
docker.py: decode subprocess output to str in py3
manu-chroma Jun 23, 2017
de1e787
cwltool.py: use absolute imports
manu-chroma Jun 25, 2017
5d35493
utils.py: add cmp_like_py2 and bytes2str_in_dicts function
manu-chroma Jun 25, 2017
d916579
cwltool: add utf-8 encoding directive on top of the module
manu-chroma Jun 25, 2017
bd2bec7
utils.py: fix typo, import Union type
manu-chroma Jun 25, 2017
fc8ffe5
builder.py: use avro-py2 for now
manu-chroma Jun 25, 2017
1701fc8
expression.py: convert byte strings to unicode strings in rootvars dict
manu-chroma Jun 25, 2017
c940d9d
cwltool/process.py: misc improvements
manu-chroma Jun 25, 2017
8c964c1
sandboxjs.py: decode strings to unicode before passing to json, fix t…
manu-chroma Jun 25, 2017
9b33da2
makefile: fix paths for populating typeshed with schema_salad
manu-chroma Jun 29, 2017
4bb7654
explicit conversion of urldfrag to unicode,to avoid mypy error
manu-chroma Jun 29, 2017
2d68d8c
stdfsaccess.py: mypy: use Text in place of str
manu-chroma Jun 29, 2017
bafd7f9
Merge remote-tracking branch 'upstream/master' into unicode_literal_u…
manu-chroma Jun 29, 2017
0abf187
fix linting errors
manu-chroma Jun 29, 2017
0909a1e
more linting fixes
manu-chroma Jun 29, 2017
cb4a93e
tox.ini: cleanup and fix failing travis build
manu-chroma Jun 29, 2017
d395c1e
add future imports
manu-chroma Jun 29, 2017
cbd20ab
remove unicode_literals import from entire codebase
manu-chroma Jun 30, 2017
932464d
expression.py: type annotations improvements
manu-chroma Jun 30, 2017
bb5f105
Merge remote-tracking branch 'upstream/master' into unicode_literal_u…
manu-chroma Jun 30, 2017
1255619
cwltool: misc improvements in type annotations and six lib integration
manu-chroma Jun 30, 2017
df59833
tests: remove unicode_literals import statement
manu-chroma Jun 30, 2017
d4d42aa
misc type improvements for mypy3
manu-chroma Jun 30, 2017
c191642
type annotation: mypy2: make build_job_script callable return str
manu-chroma Jun 30, 2017
76b017e
Merge branch 'master' into unicode_literal_usage
mr-c Jul 7, 2017
c51e2ef
drop encoding utf-8 directive from the file beginning
manu-chroma Jul 8, 2017
9f964a8
Merge branch 'unicode_literal_usage' of github.com:manu-chroma/cwltoo…
manu-chroma Jul 8, 2017
aec5bb5
Merge remote-tracking branch 'upstream/master' into unicode_literal_u…
manu-chroma Jul 8, 2017
03ebaea
minor fix in galaxy typesheds
manu-chroma Jul 8, 2017
550c8f2
job.py: pass bytes to f.write()
manu-chroma Jul 8, 2017
7f776fa
cwltool/software_requirements.py: add future absolute import
manu-chroma Jul 9, 2017
e9c9cef
add absolute import from __future__
manu-chroma Jul 9, 2017
fd2eff0
cwltool: use _logger.warning
manu-chroma Jul 9, 2017
a6bb3f9
Merge branch 'master' into unicode_literal_usage
manu-chroma Jul 9, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,18 @@ eggs/
*~
\#*\#
.desktop

# virtualenv
venv/
venv3/

# pycharm
.idea/

# typshed repo
typeshed/2and3/schema_salad
typeshed/2and3/ruamel/yaml


#mypy
.mypy_cache/
26 changes: 13 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -152,26 +152,26 @@ list-author-emails:
@git log --format='%aN,%aE' | sort -u | grep -v 'root'


mypy: ${PYSOURCES}
rm -Rf typeshed/2.7/ruamel/yaml
mypy2: ${PYSOURCES}
rm -Rf typeshed/2and3/ruamel/yaml
ln -s $(shell python -c 'from __future__ import print_function; import ruamel.yaml; import os.path; print(os.path.dirname(ruamel.yaml.__file__))') \
typeshed/2.7/ruamel/yaml
rm -Rf typeshed/2.7/schema_salad
typeshed/2and3/ruamel/yaml
rm -Rf typeshed/2and3/schema_salad
ln -s $(shell python -c 'from __future__ import print_function; import schema_salad; import os.path; print(os.path.dirname(schema_salad.__file__))') \
typeshed/2.7/schema_salad
MYPYPATH=typeshed/2.7 mypy --py2 --disallow-untyped-calls \
--warn-redundant-casts --warn-unused-ignores --fast-parser \
typeshed/2and3/schema_salad
MYPYPATH=$MYPYPATH:typeshed/2.7:typeshed/2and3 mypy --py2 --disallow-untyped-calls \
--warn-redundant-casts --warn-unused-ignores \
cwltool

mypy3: ${PYSOURCES}
rm -Rf typeshed/3/ruamel/yaml
rm -Rf typeshed/2and3/ruamel/yaml
ln -s $(shell python3 -c 'from __future__ import print_function; import ruamel.yaml; import os.path; print(os.path.dirname(ruamel.yaml.__file__))') \
typeshed/3/ruamel/yaml
rm -Rf typeshed/3/schema_salad
typeshed/2and3/ruamel/yaml
rm -Rf typeshed/2and3/schema_salad
ln -s $(shell python3 -c 'from __future__ import print_function; import schema_salad; import os.path; print(os.path.dirname(schema_salad.__file__))') \
typeshed/3/schema_salad
MYPYPATH=typeshed/3 mypy --disallow-untyped-calls \
--warn-redundant-casts --warn-unused-ignores --fast-parser \
typeshed/2and3/schema_salad
MYPYPATH=$MYPYPATH:typeshed/3:typeshed/2and3 mypy --disallow-untyped-calls \
--warn-redundant-casts --warn-unused-ignores \
cwltool

FORCE:
2 changes: 1 addition & 1 deletion cwlref-runner/setup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env python

from __future__ import absolute_import
import os

from setuptools import setup, find_packages
Expand Down
1 change: 1 addition & 0 deletions cwltool.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env python
from __future__ import absolute_import
"""Convienance entry point for cwltool.

This can be used instead of the recommended method of `./setup.py install`
Expand Down
1 change: 1 addition & 0 deletions cwltool/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from __future__ import absolute_import
__author__ = '[email protected]'
1 change: 1 addition & 0 deletions cwltool/__main__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from __future__ import absolute_import
import sys

from . import main
Expand Down
11 changes: 9 additions & 2 deletions cwltool/builder.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from __future__ import absolute_import
import copy
from typing import Any, Callable, Text, Type, Union
from typing import Any, Callable, Dict, List, Text, Type, Union

import six
from six import iteritems, string_types

import avro
Expand All @@ -15,6 +17,11 @@
from .stdfsaccess import StdFsAccess
from .utils import aslist

# if six.PY3:
# AvroSchemaFromJSONData = avro.schema.SchemaFromJSONData
# else:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

commented out python3 lines until futher resolution of avro issue.

AvroSchemaFromJSONData = avro.schema.make_avsc_object

CONTENT_LIMIT = 64 * 1024


Expand Down Expand Up @@ -86,7 +93,7 @@ def bind_input(self, schema, datum, lead_pos=None, tail_pos=None):
elif isinstance(t, dict) and "name" in t and self.names.has_name(t["name"], ""):
avsc = self.names.get_name(t["name"], "")
else:
avsc = avro.schema.make_avsc_object(t, self.names)
avsc = AvroSchemaFromJSONData(t, self.names)
if validate.validate(avsc, datum):
schema = copy.deepcopy(schema)
schema["type"] = t
Expand Down
1 change: 1 addition & 0 deletions cwltool/cwlrdf.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from __future__ import absolute_import
from typing import IO, Any, Dict, Text

from rdflib import Graph
Expand Down
13 changes: 7 additions & 6 deletions cwltool/docker.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from __future__ import absolute_import
import logging
import os
import re
import subprocess
import sys
import tempfile
from typing import Text
from typing import Dict, List, Text

import requests

Expand All @@ -21,7 +22,7 @@ def get_image(dockerRequirement, pull_image, dry_run=False):
dockerRequirement["dockerImageId"] = dockerRequirement["dockerPull"]

for ln in subprocess.check_output(
["docker", "images", "--no-trunc", "--all"]).splitlines():
["docker", "images", "--no-trunc", "--all"]).decode('utf-8').splitlines():
try:
m = re.match(r"^([^ ]+)\s+([^ ]+)\s+([^ ]+)", ln)
sp = dockerRequirement["dockerImageId"].split(":")
Expand All @@ -46,7 +47,7 @@ def get_image(dockerRequirement, pull_image, dry_run=False):
pass

if not found and pull_image:
cmd = [] # type: List[str]
cmd = [] # type: List[Text]
if "dockerPull" in dockerRequirement:
cmd = ["docker", "pull", str(dockerRequirement["dockerPull"])]
_logger.info(Text(cmd))
Expand All @@ -55,8 +56,8 @@ def get_image(dockerRequirement, pull_image, dry_run=False):
found = True
elif "dockerFile" in dockerRequirement:
dockerfile_dir = str(tempfile.mkdtemp())
with open(os.path.join(dockerfile_dir, "Dockerfile"), "w") as df:
df.write(dockerRequirement["dockerFile"])
with open(os.path.join(dockerfile_dir, "Dockerfile"), str("w")) as df:
df.write(dockerRequirement["dockerFile"].encode('utf-8'))
cmd = ["docker", "build", "--tag=%s" %
str(dockerRequirement["dockerImageId"]), dockerfile_dir]
_logger.info(Text(cmd))
Expand All @@ -69,7 +70,7 @@ def get_image(dockerRequirement, pull_image, dry_run=False):
if not dry_run:
if os.path.exists(dockerRequirement["dockerLoad"]):
_logger.info(u"Loading docker image from %s", dockerRequirement["dockerLoad"])
with open(dockerRequirement["dockerLoad"], "rb") as f:
with open(dockerRequirement["dockerLoad"], str("rb")) as f:
loadproc = subprocess.Popen(cmd, stdin=f, stdout=sys.stderr)
else:
loadproc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=sys.stderr)
Expand Down
4 changes: 3 additions & 1 deletion cwltool/docker_uid.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from __future__ import print_function
from __future__ import absolute_import

import subprocess
from typing import Text
from typing import List, Text


def docker_vm_uid(): # type: () -> int
Expand Down Expand Up @@ -91,6 +92,7 @@ def cmd_output_to_int(cmd): # type: (List[Text]) -> int
except ValueError:
# ValueError is raised if int conversion fails
return None
return None


def boot2docker_uid(): # type: () -> int
Expand Down
18 changes: 10 additions & 8 deletions cwltool/draft2tool.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from __future__ import absolute_import
import copy
import hashlib
import json
Expand All @@ -7,7 +8,7 @@
import shutil
import tempfile
from functools import partial
from typing import Any, Callable, Dict, Generator, Optional, Text, Union, cast
from typing import Any, Callable, Dict, Generator, List, Optional, Set, Text, Union, cast

from six import string_types, u

Expand All @@ -28,6 +29,7 @@
normalizeFilesDirs, shortname, uniquename)
from .stdfsaccess import StdFsAccess
from .utils import aslist
from six.moves import map

ACCEPTLIST_EN_STRICT_RE = re.compile(r"^[a-zA-Z0-9._+-]+$")
ACCEPTLIST_EN_RELAXED_RE = re.compile(r".*") # Accept anything
Expand Down Expand Up @@ -60,7 +62,7 @@ def run(self, **kwargs): # type: (**Any) -> None
normalizeFilesDirs(ev)
self.output_callback(ev, "success")
except Exception as e:
_logger.warn(u"Failed to evaluate expression:\n%s",
_logger.warning(u"Failed to evaluate expression:\n%s",
e, exc_info=kwargs.get('debug'))
self.output_callback({}, "permanentFail")

Expand Down Expand Up @@ -224,7 +226,7 @@ def job(self,
visit_class([cachebuilder.files, cachebuilder.bindings],
("File", "Directory"), _check_adjust)

cmdline = flatten(map(cachebuilder.generate_arg, cachebuilder.bindings))
cmdline = flatten(list(map(cachebuilder.generate_arg, cachebuilder.bindings)))
(docker_req, docker_is_req) = self.get_requirement("DockerRequirement")
if docker_req and kwargs.get("use_container") is not False:
dockerimg = docker_req.get("dockerImageId") or docker_req.get("dockerPull")
Expand Down Expand Up @@ -253,7 +255,7 @@ def job(self,
keydict[r["class"]] = r

keydictstr = json.dumps(keydict, separators=(',', ':'), sort_keys=True)
cachekey = hashlib.md5(keydictstr).hexdigest()
cachekey = hashlib.md5(keydictstr.encode('utf-8')).hexdigest()

_logger.debug("[job %s] keydictstr is %s -> %s", jobname,
keydictstr, cachekey)
Expand Down Expand Up @@ -446,7 +448,7 @@ def register_reader(f):
cmd.extend(aslist(arg))
j.command_line = ["/bin/sh", "-c", " ".join(cmd)]
else:
j.command_line = flatten(map(builder.generate_arg, builder.bindings))
j.command_line = flatten(list(map(builder.generate_arg, builder.bindings)))

j.pathmapper = builder.pathmapper
j.collect_outputs = partial(
Expand Down Expand Up @@ -535,7 +537,7 @@ def collect_output(self, schema, builder, outdir, fs_access, compute_checksum=Tr
"class": "File" if fs_access.isfile(g) else "Directory"}
for g in fs_access.glob(fs_access.join(outdir, gb))])
except (OSError, IOError) as e:
_logger.warn(Text(e))
_logger.warning(Text(e))
except:
_logger.error("Unexpected error from fs_access", exc_info=True)
raise
Expand All @@ -547,14 +549,14 @@ def collect_output(self, schema, builder, outdir, fs_access, compute_checksum=Tr
get_listing(fs_access, files, (ll == "deep_listing"))
else:
with fs_access.open(files["location"], "rb") as f:
contents = ""
contents = b""
if binding.get("loadContents") or compute_checksum:
contents = f.read(CONTENT_LIMIT)
if binding.get("loadContents"):
files["contents"] = contents
if compute_checksum:
checksum = hashlib.sha1()
while contents != "":
while contents != b"":
checksum.update(contents)
contents = f.read(1024 * 1024)
files["checksum"] = "sha1$%s" % checksum.hexdigest()
Expand Down
20 changes: 16 additions & 4 deletions cwltool/expression.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,41 @@
from __future__ import absolute_import
import copy
import json
import logging
import re
from typing import Any, AnyStr, Dict, List, Text, Union

import six
from six import u

from . import sandboxjs
from .errors import WorkflowException
from .utils import bytes2str_in_dicts

_logger = logging.getLogger("cwltool")


def jshead(engineConfig, rootvars):
# type: (List[Text], Dict[Text, Any]) -> Text

# make sure all the byte strings are converted
# to str in `rootvars` dict.
# TODO: need to make sure the `rootvars dict`
# contains no bytes type in the first place.
if six.PY3:
rootvars = bytes2str_in_dicts(rootvars) # type -> ignore

return u"\n".join(engineConfig + [u"var %s = %s;" % (k, json.dumps(v, indent=4)) for k, v in rootvars.items()])


# decode all raw strings to unicode
seg_symbol = r"""\w+"""
seg_single = r"""\['([^']|\\')+'\]"""
seg_double = r"""\["([^"]|\\")+"\]"""
seg_index = r"""\[[0-9]+\]"""
segments = r"(\.%s|%s|%s|%s)" % (seg_symbol, seg_single, seg_double, seg_index)
segment_re = re.compile(segments, flags=re.UNICODE)
param_re = re.compile(r"\((%s)%s*\)$" % (seg_symbol, segments), flags=re.UNICODE)
segment_re = re.compile(u(segments), flags=re.UNICODE)
param_str = r"\((%s)%s*\)$" % (seg_symbol, segments)
param_re = re.compile(u(param_str), flags=re.UNICODE)

JSON = Union[Dict[Any, Any], List[Any], Text, int, float, bool, None]

Expand Down Expand Up @@ -110,7 +122,7 @@ def scanner(scan): # type: (Text) -> List[int]
def next_seg(remain, obj): # type: (Text, Any) -> Any
if remain:
m = segment_re.match(remain)
key = None # type: Union[str, int]
key = None # type: Union[Text, int]
if m.group(0)[0] == '.':
key = m.group(0)[1:]
elif m.group(0)[1] in ("'", '"'):
Expand Down
3 changes: 2 additions & 1 deletion cwltool/factory.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import absolute_import
import os
from typing import Callable as tCallable
from typing import Any, Text, Tuple, Union
from typing import Any, Dict, Text, Tuple, Union

from . import load_tool, main, workflow
from .process import Process
Expand Down
1 change: 1 addition & 0 deletions cwltool/flatten.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from __future__ import absolute_import
from typing import Any, Callable, List, cast

# http://rightfootin.blogspot.com/2006/09/more-on-python-flatten.html
Expand Down
Loading