Skip to content

Commit b52a05b

Browse files
authored
Merge pull request #354 from djarecka/mnt/nipype_interf_convert_cont
[mnt] nipype conversion updates
2 parents 01682de + b301171 commit b52a05b

File tree

4 files changed

+97
-3
lines changed

4 files changed

+97
-3
lines changed

pydra/engine/core.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,9 +311,33 @@ def set_state(self, splitter, combiner=None):
311311

312312
@property
313313
def output_names(self):
314-
"""Get the names of the outputs generated by the task."""
314+
"""Get the names of the outputs from the task's output_spec
315+
(not everything has to be generated, see generated_output_names).
316+
"""
315317
return [f.name for f in attr.fields(make_klass(self.output_spec))]
316318

319+
@property
320+
def generated_output_names(self):
321+
""" Get the names of the outputs generated by the task.
322+
If the spec doesn't have generated_output_names method,
323+
it uses output_names.
324+
The results depends on the input provided to the task
325+
"""
326+
output_klass = make_klass(self.output_spec)
327+
if hasattr(output_klass, "generated_output_names"):
328+
output = output_klass(**{f.name: None for f in attr.fields(output_klass)})
329+
# using updated input (after filing the templates)
330+
_inputs = deepcopy(self.inputs)
331+
modified_inputs = template_update(_inputs, self.output_dir)
332+
if modified_inputs:
333+
_inputs = attr.evolve(_inputs, **modified_inputs)
334+
335+
return output.generated_output_names(
336+
inputs=_inputs, output_dir=self.output_dir
337+
)
338+
else:
339+
return self.output_names
340+
317341
@property
318342
def can_resume(self):
319343
"""Whether the task accepts checkpoint-restart."""

pydra/engine/helpers_file.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ def template_update(inputs, output_dir, map_copyfiles=None):
519519
if fld.type not in [str, ty.Union[str, bool]]:
520520
raise Exception(
521521
f"fields with output_file_template"
522-
"has to be a string or Union[str, bool]"
522+
" has to be a string or Union[str, bool]"
523523
)
524524
dict_[fld.name] = template_update_single(
525525
field=fld, inputs_dict=dict_, output_dir=output_dir

pydra/engine/specs.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ def collect_additional_outputs(self, inputs, output_dir):
408408
raise AttributeError(
409409
"File has to have default value or metadata"
410410
)
411-
elif not fld.default == attr.NOTHING:
411+
elif fld.default != attr.NOTHING:
412412
additional_out[fld.name] = self._field_defaultvalue(
413413
fld, output_dir
414414
)
@@ -420,6 +420,36 @@ def collect_additional_outputs(self, inputs, output_dir):
420420
raise Exception("not implemented (collect_additional_output)")
421421
return additional_out
422422

423+
def generated_output_names(self, inputs, output_dir):
424+
""" Returns a list of all outputs that will be generated by the task.
425+
Takes into account the task input and the requires list for the output fields.
426+
TODO: should be in all Output specs?
427+
"""
428+
# checking the input (if all mandatory fields are provided, etc.)
429+
inputs.check_fields_input_spec()
430+
output_names = ["return_code", "stdout", "stderr"]
431+
for fld in attr_fields(self):
432+
if fld.name not in ["return_code", "stdout", "stderr"]:
433+
if fld.type is File:
434+
# assuming that field should have either default or metadata, but not both
435+
if (
436+
fld.default is None or fld.default == attr.NOTHING
437+
) and not fld.metadata: # TODO: is it right?
438+
raise AttributeError(
439+
"File has to have default value or metadata"
440+
)
441+
elif fld.default != attr.NOTHING:
442+
output_names.append(fld.name)
443+
elif (
444+
fld.metadata
445+
and self._field_metadata(fld, inputs, output_dir)
446+
!= attr.NOTHING
447+
):
448+
output_names.append(fld.name)
449+
else:
450+
raise Exception("not implemented (collect_additional_output)")
451+
return output_names
452+
423453
def _field_defaultvalue(self, fld, output_dir):
424454
"""Collect output file if the default value specified."""
425455
if not isinstance(fld.default, (str, Path)):

pydra/engine/tests/test_shelltask.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2654,6 +2654,12 @@ def test_shell_cmd_inputspec_outputspec_2():
26542654
)
26552655
shelly.inputs.file1 = "new_file_1.txt"
26562656
shelly.inputs.file2 = "new_file_2.txt"
2657+
# all fileds from output_spec should be in output_names and generated_output_names
2658+
assert (
2659+
shelly.output_names
2660+
== shelly.generated_output_names
2661+
== ["return_code", "stdout", "stderr", "newfile1", "newfile2"]
2662+
)
26572663

26582664
res = shelly()
26592665
assert res.output.stdout == ""
@@ -2714,6 +2720,20 @@ def test_shell_cmd_inputspec_outputspec_2a():
27142720
output_spec=my_output_spec,
27152721
)
27162722
shelly.inputs.file1 = "new_file_1.txt"
2723+
# generated_output_names shoule know that newfile2 will not be generated
2724+
assert shelly.output_names == [
2725+
"return_code",
2726+
"stdout",
2727+
"stderr",
2728+
"newfile1",
2729+
"newfile2",
2730+
]
2731+
assert shelly.generated_output_names == [
2732+
"return_code",
2733+
"stdout",
2734+
"stderr",
2735+
"newfile1",
2736+
]
27172737

27182738
res = shelly()
27192739
assert res.output.stdout == ""
@@ -2834,6 +2854,20 @@ def test_shell_cmd_inputspec_outputspec_3a():
28342854
)
28352855
shelly.inputs.file1 = "new_file_1.txt"
28362856
shelly.inputs.file2 = "new_file_2.txt"
2857+
# generated_output_names shoule know that newfile2 will not be generated
2858+
assert shelly.output_names == [
2859+
"return_code",
2860+
"stdout",
2861+
"stderr",
2862+
"newfile1",
2863+
"newfile2",
2864+
]
2865+
assert shelly.generated_output_names == [
2866+
"return_code",
2867+
"stdout",
2868+
"stderr",
2869+
"newfile1",
2870+
]
28372871

28382872
res = shelly()
28392873
assert res.output.stdout == ""
@@ -2884,6 +2918,12 @@ def test_shell_cmd_inputspec_outputspec_4():
28842918
)
28852919
shelly.inputs.file1 = "new_file_1.txt"
28862920
shelly.inputs.additional_inp = 2
2921+
# generated_output_names should be the same as output_names
2922+
assert (
2923+
shelly.output_names
2924+
== shelly.generated_output_names
2925+
== ["return_code", "stdout", "stderr", "newfile1"]
2926+
)
28872927

28882928
res = shelly()
28892929
assert res.output.stdout == ""

0 commit comments

Comments
 (0)