Skip to content

Commit 913fc68

Browse files
authored
Refactor add_sizes, add generalized size() call to StdFsAccess. (#855)
* Refactor add_sizes, add generalized size() call to StdFsAccess. * Fix add_sizes import * Mypy annotation fixes
1 parent 5921b51 commit 913fc68

File tree

7 files changed

+40
-33
lines changed

7 files changed

+40
-33
lines changed

cwltool/builder.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def get_requirement(self,
104104

105105
class Builder(HasReqsHints):
106106
def __init__(self,
107-
job, # type: Dict[Text, Union[Dict[Text, Any], List, Text]]
107+
job, # type: Dict[Text, Union[Dict[Text, Any], List, Text, None]]
108108
files=None, # type: List[Dict[Text, Text]]
109109
bindings=None, # type: List[Dict[Text, Any]]
110110
schemaDefs=None, # type: Dict[Text, Dict[Text, Any]]
@@ -142,11 +142,6 @@ def __init__(self,
142142
else:
143143
self.files = files
144144

145-
if fs_access is None:
146-
self.fs_access = StdFsAccess("")
147-
else:
148-
self.fs_access = fs_access
149-
150145
self.job = job
151146
self.requirements = requirements
152147
self.hints = hints
@@ -171,6 +166,11 @@ def __init__(self,
171166
else:
172167
self.make_fs_access = make_fs_access
173168

169+
if fs_access is None:
170+
self.fs_access = self.make_fs_access("")
171+
else:
172+
self.fs_access = fs_access
173+
174174
self.debug = debug
175175
self.js_console = js_console
176176
self.mutation_manager = mutation_manager

cwltool/expression.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ def needs_parsing(snippet): # type: (Any) -> bool
245245
and ("$(" in snippet or "${" in snippet)
246246

247247
def do_eval(ex, # type: Union[Text, Dict]
248-
jobinput, # type: Dict[Text, Union[Dict, List, Text]]
248+
jobinput, # type: Dict[Text, Union[Dict, List, Text, None]]
249249
requirements, # type: List[Dict[Text, Any]]
250250
outdir, # type: Optional[Text]
251251
tmpdir, # type: Optional[Text]

cwltool/job.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ def relink_initialworkdir(pathmapper, host_outdir, container_outdir, inplace_upd
136136
class JobBase(with_metaclass(ABCMeta, HasReqsHints)):
137137
def __init__(self,
138138
builder, # type: Builder
139-
joborder, # type: Dict[Text, Union[Dict[Text, Any], List, Text]]
139+
joborder, # type: Dict[Text, Union[Dict[Text, Any], List, Text, None]]
140140
make_path_mapper, # type: Callable[..., PathMapper]
141141
requirements, # type: List[Dict[Text, Text]]
142142
hints, # type: List[Dict[Text, Text]]

cwltool/main.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,15 @@
3939
from .pathmapper import (adjustDirObjs, normalizeFilesDirs, trim_listing,
4040
visit_class)
4141
from .process import (Process, scandeps, # pylint: disable=unused-import
42-
shortname, use_custom_schema, use_standard_schema)
42+
shortname, use_custom_schema, use_standard_schema, add_sizes)
4343
from .provenance import ResearchObject
4444
from .resolver import ga4gh_tool_registries, tool_resolver
4545
from .secrets import SecretStore
4646
from .software_requirements import (DependenciesConfiguration,
4747
get_container_from_software_requirements)
4848
from .stdfsaccess import StdFsAccess
4949
from .update import ALLUPDATES, UPDATES
50-
from .utils import (DEFAULT_TMP_PREFIX, add_sizes, json_dumps, onWindows,
50+
from .utils import (DEFAULT_TMP_PREFIX, json_dumps, onWindows,
5151
versionstring, windows_default_container_id,
5252
processes_to_kill)
5353
from .context import LoadingContext, RuntimeContext, getdefault
@@ -183,7 +183,7 @@ def init_job_order(job_order_object, # type: Optional[MutableMapping[Text
183183
print_input_deps=False, # type: bool
184184
provArgs=None, # type: ResearchObject
185185
relative_deps=False, # type: bool
186-
make_fs_access=None, # type: Callable[[Text], StdFsAccess]
186+
make_fs_access=StdFsAccess, # type: Callable[[Text], StdFsAccess]
187187
input_basedir="", # type: Text
188188
secret_store=None # type: SecretStore
189189
): # type: (...) -> Tuple[MutableMapping[Text, Any], Optional[MutableMapping[Text, Any]]]
@@ -274,7 +274,7 @@ def expand_formats(p):
274274
p["format"] = ld.expand_url(p["format"], "")
275275

276276
visit_class(job_order_object, ("File", "Directory"), pathToLoc)
277-
visit_class(job_order_object, ("File",), add_sizes)
277+
visit_class(job_order_object, ("File",), functools.partial(add_sizes, make_fs_access(input_basedir)))
278278
visit_class(job_order_object, ("File",), expand_formats)
279279
adjustDirObjs(job_order_object, trim_listing)
280280
normalizeFilesDirs(job_order_object)
@@ -599,12 +599,14 @@ def main(argsl=None, # type: List[str]
599599
runtimeContext.tmp_outdir_prefix = args.cachedir
600600

601601
runtimeContext.secret_store = getdefault(runtimeContext.secret_store, SecretStore())
602+
runtimeContext.make_fs_access = getdefault(runtimeContext.make_fs_access, StdFsAccess)
602603
try:
603604
initialized_job_order_object, input_for_prov = init_job_order(
604605
job_order_object, args, tool, jobloader, stdout,
605606
print_input_deps=args.print_input_deps,
606607
provArgs=runtimeContext.research_obj,
607608
relative_deps=args.relative_deps,
609+
make_fs_access=runtimeContext.make_fs_access,
608610
input_basedir=input_basedir,
609611
secret_store=runtimeContext.secret_store)
610612
except SystemExit as err:
@@ -633,7 +635,6 @@ def main(argsl=None, # type: List[str]
633635
find_default_container,
634636
default_container=runtimeContext.default_container,
635637
use_biocontainers=args.beta_use_biocontainers)
636-
runtimeContext.make_fs_access = getdefault(runtimeContext.make_fs_access, StdFsAccess)
637638
(out, status) = executor(tool,
638639
initialized_job_order_object,
639640
runtimeContext,

cwltool/process.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
from .software_requirements import ( # pylint: disable=unused-import
4242
DependenciesConfiguration)
4343
from .stdfsaccess import StdFsAccess
44-
from .utils import (DEFAULT_TMP_PREFIX, add_sizes, aslist, cmp_like_py2,
44+
from .utils import (DEFAULT_TMP_PREFIX, aslist, cmp_like_py2,
4545
copytree_with_merge, onWindows)
4646
from .validate_js import validate_js_expressions
4747
from .context import LoadingContext, RuntimeContext, getdefault
@@ -363,9 +363,20 @@ def cleanIntermediate(output_dirs): # type: (Set[Text]) -> None
363363
_logger.debug(u"Removing intermediate output directory %s", a)
364364
shutil.rmtree(a, True)
365365

366+
def add_sizes(fsaccess, obj): # type: (StdFsAccess, Dict[Text, Any]) -> None
367+
if 'location' in obj:
368+
try:
369+
obj["size"] = fsaccess.size(obj["location"])
370+
except OSError:
371+
pass
372+
elif 'contents' in obj:
373+
obj["size"] = len(obj['contents'])
374+
else:
375+
return # best effort
366376

367-
def fillInDefaults(inputs, # type: List[Dict[Text, Text]]
368-
job # Dict[Text, Union[Dict[Text, Any], Any, None]]
377+
def fill_in_defaults(inputs, # type: List[Dict[Text, Text]]
378+
job, # type: Dict[Text, Union[Dict[Text, Any], List[Any], Text, None]]
379+
fsaccess # type: StdFsAccess
369380
): # type: (...) -> None
370381
for e, inp in enumerate(inputs):
371382
with SourceLine(inputs, e, WorkflowException, _logger.isEnabledFor(logging.DEBUG)):
@@ -378,7 +389,7 @@ def fillInDefaults(inputs, # type: List[Dict[Text, Text]]
378389
job[fieldname] = None
379390
else:
380391
raise WorkflowException("Missing required input parameter '%s'" % shortname(inp["id"]))
381-
add_sizes(job)
392+
visit_class(job, ("File",), functools.partial(add_sizes, fsaccess))
382393

383394

384395
def avroize_type(field_type, name_prefix=""):
@@ -440,7 +451,7 @@ def var_spool_cwl_detector(obj, # type: Union[Dict, List, Text]
440451

441452
def eval_resource(builder, resource_req): # type: (Builder, Text) -> Any
442453
if expression.needs_parsing(resource_req):
443-
visit_class(builder.job, ("File",), add_sizes)
454+
visit_class(builder.job, ("File",), functools.partial(add_sizes, builder.fs_access))
444455
return builder.do_eval(resource_req)
445456
return resource_req
446457

@@ -572,11 +583,15 @@ def __init__(self,
572583
def _init_job(self, joborder, runtimeContext):
573584
# type: (Dict[Text, Text], RuntimeContext) -> Builder
574585

575-
job = cast(Dict[Text, Union[Dict[Text, Any], List,
576-
Text]], copy.deepcopy(joborder))
586+
job = cast(Dict[Text, Union[Dict[Text, Any], List[Any], Text, None]],
587+
copy.deepcopy(joborder))
588+
589+
make_fs_access = getdefault(runtimeContext.make_fs_access, StdFsAccess)
590+
fs_access = make_fs_access(runtimeContext.basedir)
591+
577592
# Validate job order
578593
try:
579-
fillInDefaults(self.tool[u"inputs"], job)
594+
fill_in_defaults(self.tool[u"inputs"], job, fs_access)
580595
normalizeFilesDirs(job)
581596
validate.validate_ex(self.names.get_name("input_record_schema", ""),
582597
job, strict=False, logger=_logger_validation_warnings)
@@ -585,8 +600,6 @@ def _init_job(self, joborder, runtimeContext):
585600

586601
files = [] # type: List[Dict[Text, Text]]
587602
bindings = CommentedSeq()
588-
make_fs_access = getdefault(runtimeContext.make_fs_access, StdFsAccess)
589-
fs_access = make_fs_access(runtimeContext.basedir)
590603
tmpdir = u""
591604
stagedir = u""
592605

cwltool/stdfsaccess.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ def open(self, fn, mode):
5151
def exists(self, fn): # type: (Text) -> bool
5252
return os.path.exists(self._abs(fn))
5353

54+
def size(self, fn): # type: (Text) -> int
55+
return os.stat(self._abs(fn)).st_size
56+
5457
def isfile(self, fn): # type: (Text) -> bool
5558
return os.path.isfile(self._abs(fn))
5659

cwltool/utils.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -211,16 +211,6 @@ def bytes2str_in_dicts(inp # type: Union[Dict[Text, Any], List[Any], Any]
211211
# simply return elements itself
212212
return inp
213213

214-
def add_sizes(obj): # type: (Dict[Text, Any]) -> None
215-
if 'location' in obj:
216-
try:
217-
obj["size"] = os.stat(obj["location"][7:]).st_size # strip off file://
218-
except OSError:
219-
pass
220-
elif 'contents' in obj:
221-
obj["size"] = len(obj['contents'])
222-
else:
223-
return # best effort
224214

225215

226216
def visit_class(rec, cls, op): # type: (Any, Iterable, Union[Callable[..., Any], partial[Any]]) -> None

0 commit comments

Comments
 (0)