@@ -166,16 +166,42 @@ def job(
166
166
# empty/default inputs of a workflow step).
167
167
#
168
168
# 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).
172
178
#
173
179
# This prevents evaluation at the step level (i.e. the values
174
180
# were already loaded earlier/eagerly).
175
181
def _fix_hints_and_requirements (
176
182
hints_or_requirements : List [CWLObjectType ],
183
+ requirements_or_hints_to_evaluate : List [str ],
177
184
) -> 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
+ """
178
188
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 ):
179
205
for key , value in hint_or_requirement .items ():
180
206
hint_or_requirement [key ] = expression .do_eval (
181
207
ex = value ,
@@ -187,12 +213,13 @@ def _fix_hints_and_requirements(
187
213
context = None ,
188
214
timeout = runtimeContext .eval_timeout ,
189
215
)
216
+ parent_entries .append (key )
190
217
191
- for key in ["hints" , "requirements" ]:
192
- _fix_hints_and_requirements (getattr (self , key ))
193
218
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
+ )
196
223
197
224
builder = self ._init_job (job_order , runtimeContext )
198
225
0 commit comments