Skip to content

Commit fc2f1b8

Browse files
committed
Handle the case where children processes may define requirements with expressions too (fixing conformance test)
1 parent 4abf8ed commit fc2f1b8

File tree

1 file changed

+34
-7
lines changed

1 file changed

+34
-7
lines changed

cwltool/workflow.py

+34-7
Original file line numberDiff line numberDiff line change
@@ -166,16 +166,42 @@ def job(
166166
# empty/default inputs of a workflow step).
167167
#
168168
# The solution below evaluates the requirements and hints for
169-
# the workflow, for each step of the workflow, and for the
170-
# embedded tool (command-line or expression tools) of each
171-
# step.
169+
# the workflow (parent), keeping track of the name of the
170+
# requirements and hints. For each step of the workflow and of
171+
# the embedded tool (command-line or expression tools) it will
172+
# then evaluate the requirements or hints that have the same
173+
# name - even though they may be re-evaluated at the step
174+
# level (e.g. a workflow defines a requirement resource that
175+
# uses inputs.threads_max, and a command-line tool of the same
176+
# workflow also defines a requirement with the same name, but
177+
# using the command-line tool input values).
172178
#
173179
# This prevents evaluation at the step level (i.e. the values
174180
# were already loaded earlier/eagerly).
175181
def _fix_hints_and_requirements(
176182
hints_or_requirements: List[CWLObjectType],
183+
requirements_or_hints_to_evaluate: List[str],
177184
) -> None:
185+
"""Internal function to iterate the hints or requirements of steps
186+
provided and evaluate the ones that exist in the parent process.
187+
"""
178188
for hint_or_requirement in hints_or_requirements:
189+
for key, value in hint_or_requirement.items():
190+
if key in requirements_or_hints_to_evaluate:
191+
hint_or_requirement[key] = expression.do_eval(
192+
ex=value,
193+
jobinput=job_order,
194+
requirements=self.requirements,
195+
outdir=runtimeContext.outdir,
196+
tmpdir=runtimeContext.tmpdir,
197+
resources={},
198+
context=None,
199+
timeout=runtimeContext.eval_timeout,
200+
)
201+
202+
for attr_key in ["hints", "requirements"]:
203+
parent_entries = []
204+
for hint_or_requirement in getattr(self, attr_key):
179205
for key, value in hint_or_requirement.items():
180206
hint_or_requirement[key] = expression.do_eval(
181207
ex=value,
@@ -187,12 +213,13 @@ def _fix_hints_and_requirements(
187213
context=None,
188214
timeout=runtimeContext.eval_timeout,
189215
)
216+
parent_entries.append(key)
190217

191-
for key in ["hints", "requirements"]:
192-
_fix_hints_and_requirements(getattr(self, key))
193218
for step in self.steps:
194-
_fix_hints_and_requirements(getattr(step, key))
195-
_fix_hints_and_requirements(getattr(step.embedded_tool, key))
219+
_fix_hints_and_requirements(getattr(step, attr_key), parent_entries)
220+
_fix_hints_and_requirements(
221+
getattr(step.embedded_tool, attr_key), parent_entries
222+
)
196223

197224
builder = self._init_job(job_order, runtimeContext)
198225

0 commit comments

Comments
 (0)