From a6152c03c5f2e5dfc7725d7004c97bb2b3d32080 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 13 Mar 2023 18:53:12 +0100 Subject: [PATCH 1/3] FIX: Provide templated fields to cmdline only when requirements are met --- pydra/engine/helpers_file.py | 12 ++++- .../engine/tests/test_shelltask_inputspec.py | 52 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/pydra/engine/helpers_file.py b/pydra/engine/helpers_file.py index 73d59b718f..44346be7cd 100644 --- a/pydra/engine/helpers_file.py +++ b/pydra/engine/helpers_file.py @@ -591,9 +591,19 @@ def template_update(inputs, output_dir, state_ind=None, map_copyfiles=None): from .specs import attr_fields + # Collect templated inputs for which all requirements are satisfied. fields_templ = [ - fld for fld in attr_fields(inputs) if fld.metadata.get("output_file_template") + field + for field in attr_fields(inputs) + if field.metadata.get("output_file_template") + and all( + [ + getattr(inputs, required_field) is not attr.NOTHING + for required_field in field.metadata.get("requires", []) + ] + ) ] + dict_mod = {} for fld in fields_templ: if fld.type not in [str, ty.Union[str, bool]]: diff --git a/pydra/engine/tests/test_shelltask_inputspec.py b/pydra/engine/tests/test_shelltask_inputspec.py index f18103572f..215c995d5f 100644 --- a/pydra/engine/tests/test_shelltask_inputspec.py +++ b/pydra/engine/tests/test_shelltask_inputspec.py @@ -1721,6 +1721,58 @@ def test_shell_cmd_inputs_template_10(): assert shelly.output_names == ["return_code", "stdout", "stderr", "outA"] +def test_shell_cmd_inputs_template_requires_1(): + """Given an input specification with a templated output file subject to required fields, + ensure the field is set only when all requirements are met.""" + + my_input_spec = SpecInfo( + name="Input", + fields=[ + ( + "in_file", + attr.ib( + type=str, + metadata={ + "help_string": "input file", + "mandatory": True, + "argstr": "", + }, + ), + ), + ( + "with_tpl", + attr.ib( + type=bool, + metadata={"help_string": "enable template"}, + ), + ), + ( + "out_file", + attr.ib( + type=str, + metadata={ + "help_string": "output file", + "argstr": "--tpl", + "output_file_template": "tpl.{in_file}", + "requires": {"with_tpl"}, + }, + ), + ), + ], + bases=(ShellSpec,), + ) + + # When requirements are not met. + shelly = ShellCommandTask( + executable="cmd", input_spec=my_input_spec, in_file="in.file" + ) + assert "--tpl" not in shelly.cmdline + + # When requirements are met. + shelly.inputs.with_tpl = True + assert "tpl.in.file" in shelly.cmdline + + def test_shell_cmd_inputs_template_function_1(): """one input field uses output_file_template that is a simple function this can be easily done by simple template as in test_shell_cmd_inputs_template_1 From b8b2f50edc0122e6ae6b32a0aa25d46b6a38766c Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 13 Mar 2023 20:46:44 +0100 Subject: [PATCH 2/3] REF: Optimize filter in list comprehension Co-authored-by: Chris Markiewicz --- pydra/engine/helpers_file.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pydra/engine/helpers_file.py b/pydra/engine/helpers_file.py index 44346be7cd..5481c5d784 100644 --- a/pydra/engine/helpers_file.py +++ b/pydra/engine/helpers_file.py @@ -597,10 +597,8 @@ def template_update(inputs, output_dir, state_ind=None, map_copyfiles=None): for field in attr_fields(inputs) if field.metadata.get("output_file_template") and all( - [ - getattr(inputs, required_field) is not attr.NOTHING - for required_field in field.metadata.get("requires", []) - ] + getattr(inputs, required_field) is not attr.NOTHING + for required_field in field.metadata.get("requires", ()) ) ] From 2ef6d4f76bb615a6e0bb8d142545cea17f154d0d Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 13 Mar 2023 21:36:31 +0100 Subject: [PATCH 3/3] FIX: Correct typos caught by codespell --- pydra/engine/tests/test_workflow.py | 2 +- pydra/utils/profiler.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pydra/engine/tests/test_workflow.py b/pydra/engine/tests/test_workflow.py index bdae9e135b..df11b08a8c 100644 --- a/pydra/engine/tests/test_workflow.py +++ b/pydra/engine/tests/test_workflow.py @@ -4843,7 +4843,7 @@ def printer(a): @pytest.mark.timeout(40) def test_inner_outer_wf_duplicate(tmpdir): """checking if the execution gets stuck if there is an inner and outer workflows - thar run two nodes with the exact same inputs. + that run two nodes with the exact same inputs. """ task_list = ["First", "Second"] start_list = [3] diff --git a/pydra/utils/profiler.py b/pydra/utils/profiler.py index 9b417ef987..7b09887977 100644 --- a/pydra/utils/profiler.py +++ b/pydra/utils/profiler.py @@ -9,7 +9,7 @@ class ResourceMonitor(threading.Thread): - """A thread to monitor a specific PID with a certain frequence to a file.""" + """A thread to monitor a specific PID with a certain frequency to a file.""" def __init__(self, pid, interval=5, logdir=None, fname=None): """