Skip to content

Commit eec1484

Browse files
authored
Merge pull request #374 from djarecka/enh/callable_updates
improving callable use in output spec
2 parents 18a4803 + e8d3e63 commit eec1484

File tree

2 files changed

+71
-3
lines changed

2 files changed

+71
-3
lines changed

pydra/engine/specs.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,25 @@ def _field_metadata(self, fld, inputs, output_dir):
542542
else:
543543
return Path(value)
544544
elif "callable" in fld.metadata:
545-
return fld.metadata["callable"](fld.name, output_dir)
545+
call_args = inspect.getargspec(fld.metadata["callable"])
546+
call_args_val = {}
547+
for argnm in call_args.args:
548+
if argnm == "field":
549+
call_args_val[argnm] = fld
550+
elif argnm == "output_dir":
551+
call_args_val[argnm] = output_dir
552+
elif argnm == "inputs":
553+
call_args_val[argnm] = inputs
554+
else:
555+
try:
556+
call_args_val[argnm] = getattr(inputs, argnm)
557+
except AttributeError:
558+
raise AttributeError(
559+
f"arguments of the callable function from {fld.name} "
560+
f"has to be in inputs or be field or output_dir, "
561+
f"but {argnm} is used"
562+
)
563+
return fld.metadata["callable"](**call_args_val)
546564
else:
547565
raise Exception("(_field_metadata) is not a current valid metadata key.")
548566

pydra/engine/tests/test_shelltask.py

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2545,11 +2545,12 @@ def test_shell_cmd_outputspec_4(plugin, results_function, tmpdir):
25452545
"""
25462546
customised output_spec, adding files to the output,
25472547
using a function to collect output, the function is saved in the field metadata
2548+
and uses output_dir and the glob function
25482549
"""
25492550
cmd = ["touch", "newfile_tmp1.txt", "newfile_tmp2.txt"]
25502551

2551-
def gather_output(keyname, output_dir):
2552-
if keyname == "newfile":
2552+
def gather_output(field, output_dir):
2553+
if field.name == "newfile":
25532554
return list(Path(output_dir).expanduser().glob("newfile*.txt"))
25542555

25552556
my_output_spec = SpecInfo(
@@ -2568,6 +2569,55 @@ def gather_output(keyname, output_dir):
25682569
assert all([file.exists for file in res.output.newfile])
25692570

25702571

2572+
@pytest.mark.parametrize("results_function", [result_no_submitter, result_submitter])
2573+
def test_shell_cmd_outputspec_4a(plugin, results_function):
2574+
"""
2575+
customised output_spec, adding files to the output,
2576+
using a function to collect output, the function is saved in the field metadata
2577+
and uses output_dir and inputs element
2578+
"""
2579+
cmd = ["touch", "newfile_tmp1.txt", "newfile_tmp2.txt"]
2580+
2581+
def gather_output(executable, output_dir):
2582+
files = executable[1:]
2583+
return [Path(output_dir) / file for file in files]
2584+
2585+
my_output_spec = SpecInfo(
2586+
name="Output",
2587+
fields=[("newfile", attr.ib(type=File, metadata={"callable": gather_output}))],
2588+
bases=(ShellOutSpec,),
2589+
)
2590+
shelly = ShellCommandTask(name="shelly", executable=cmd, output_spec=my_output_spec)
2591+
2592+
res = results_function(shelly, plugin)
2593+
assert res.output.stdout == ""
2594+
# newfile is a list
2595+
assert len(res.output.newfile) == 2
2596+
assert all([file.exists for file in res.output.newfile])
2597+
2598+
2599+
def test_shell_cmd_outputspec_4b_error():
2600+
"""
2601+
customised output_spec, adding files to the output,
2602+
using a function to collect output, the function is saved in the field metadata
2603+
with an argument that is not part of the inputs - error is raised
2604+
"""
2605+
cmd = ["touch", "newfile_tmp1.txt", "newfile_tmp2.txt"]
2606+
2607+
def gather_output(executable, output_dir, ble):
2608+
files = executable[1:]
2609+
return [Path(output_dir) / file for file in files]
2610+
2611+
my_output_spec = SpecInfo(
2612+
name="Output",
2613+
fields=[("newfile", attr.ib(type=File, metadata={"callable": gather_output}))],
2614+
bases=(ShellOutSpec,),
2615+
)
2616+
shelly = ShellCommandTask(name="shelly", executable=cmd, output_spec=my_output_spec)
2617+
with pytest.raises(AttributeError, match="ble"):
2618+
shelly()
2619+
2620+
25712621
@pytest.mark.parametrize("results_function", [result_no_submitter, result_submitter])
25722622
def test_shell_cmd_outputspec_5(plugin, results_function, tmpdir):
25732623
"""

0 commit comments

Comments
 (0)