Skip to content

Commit 95f7066

Browse files
committed
debugging docker unittests
1 parent 4b6ac3b commit 95f7066

File tree

8 files changed

+310
-286
lines changed

8 files changed

+310
-286
lines changed

pydra/design/shell.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,13 +140,28 @@ class out(Out):
140140
passed) or any input field name (a specific input field will be sent).
141141
"""
142142

143-
callable: ty.Callable | None = None
143+
callable: ty.Callable | None = attrs.field(default=None)
144144

145145
def __attrs_post_init__(self):
146146
# Set type from return annotation of callable if not set
147147
if self.type is ty.Any and self.callable:
148148
self.type = ty.get_type_hints(self.callable).get("return", ty.Any)
149149

150+
@callable.validator
151+
def _callable_validator(self, _, value):
152+
153+
if value:
154+
if not callable(value):
155+
raise ValueError(f"callable must be a function, not {value!r}")
156+
elif not getattr(self, "path_template", None) and self.name not in [
157+
"return_code",
158+
"stdout",
159+
"stderr",
160+
]: # ShellOutputs.BASE_NAMES
161+
raise ValueError(
162+
"A shell output field must have either a callable or a path_template"
163+
)
164+
150165

151166
@attrs.define(kw_only=True)
152167
class outarg(arg, Out):

pydra/engine/core.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
)
4545
from .helpers_file import copy_nested_files, template_update
4646
from pydra.utils.messenger import AuditFlag
47-
from pydra.engine.environments import Environment, Native
47+
from pydra.engine.environments import Environment
4848

4949
logger = logging.getLogger("pydra")
5050

@@ -134,7 +134,9 @@ def __init__(
134134
# We save the submitter is the definition is a workflow otherwise we don't
135135
# so the task can be pickled
136136
self.submitter = submitter
137-
self.environment = environment if environment is not None else Native()
137+
self.environment = (
138+
environment if environment is not None else submitter.environment
139+
)
138140
self.name = name
139141
self.state_index = state_index
140142

pydra/engine/specs.py

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -946,48 +946,46 @@ def _resolve_value(
946946

947947
if not cls._required_fields_satisfied(fld, task.definition):
948948
return None
949-
elif isinstance(fld, shell.outarg) and fld.path_template:
949+
if isinstance(fld, shell.outarg) and fld.path_template:
950950
return template_update_single(
951951
fld,
952952
definition=task.definition,
953953
output_dir=task.output_dir,
954954
spec_type="output",
955955
)
956-
elif fld.callable:
957-
callable_ = fld.callable
958-
if isinstance(fld.callable, staticmethod):
959-
# In case callable is defined as a static method,
960-
# retrieve the function wrapped in the descriptor.
961-
callable_ = fld.callable.__func__
962-
call_args = inspect.getfullargspec(callable_)
963-
call_args_val = {}
964-
for argnm in call_args.args:
965-
if argnm == "field":
966-
call_args_val[argnm] = fld
967-
elif argnm == "output_dir":
968-
call_args_val[argnm] = task.output_dir
969-
elif argnm == "inputs":
970-
call_args_val[argnm] = task.inputs
971-
elif argnm == "stdout":
972-
call_args_val[argnm] = task.return_values["stdout"]
973-
elif argnm == "stderr":
974-
call_args_val[argnm] = task.return_values["stderr"]
975-
else:
976-
try:
977-
call_args_val[argnm] = task.inputs[argnm]
978-
except KeyError as e:
979-
e.add_note(
980-
f"arguments of the callable function from {fld.name} "
981-
f"has to be in inputs or be field or output_dir, "
982-
f"but {argnm} is used"
983-
)
984-
raise
985-
return callable_(**call_args_val)
986-
else:
987-
raise Exception(
988-
f"Metadata for '{fld.name}', does not not contain any of the required fields "
989-
f'("callable", "output_file_template" or "value"): {fld}.'
990-
)
956+
assert fld.callable, (
957+
f"Output field '{fld.name}', does not not contain any of the required fields "
958+
f'("callable", "output_file_template" or "value"): {fld}.'
959+
)
960+
callable_ = fld.callable
961+
if isinstance(fld.callable, staticmethod):
962+
# In case callable is defined as a static method,
963+
# retrieve the function wrapped in the descriptor.
964+
callable_ = fld.callable.__func__
965+
call_args = inspect.getfullargspec(callable_)
966+
call_args_val = {}
967+
for argnm in call_args.args:
968+
if argnm == "field":
969+
call_args_val[argnm] = fld
970+
elif argnm == "output_dir":
971+
call_args_val[argnm] = task.output_dir
972+
elif argnm == "inputs":
973+
call_args_val[argnm] = task.inputs
974+
elif argnm == "stdout":
975+
call_args_val[argnm] = task.return_values["stdout"]
976+
elif argnm == "stderr":
977+
call_args_val[argnm] = task.return_values["stderr"]
978+
else:
979+
try:
980+
call_args_val[argnm] = task.inputs[argnm]
981+
except KeyError as e:
982+
e.add_note(
983+
f"arguments of the callable function from {fld.name} "
984+
f"has to be in inputs or be field or output_dir, "
985+
f"but {argnm} is used"
986+
)
987+
raise
988+
return callable_(**call_args_val)
991989

992990

993991
ShellOutputsType = ty.TypeVar("OutputType", bound=ShellOutputs)

pydra/engine/submitter.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,9 @@ def __call__(
207207
output_types = {o.name: list[o.type] for o in list_fields(task_def.Outputs)}
208208

209209
@workflow.define(outputs=output_types)
210-
def Split(defn: TaskDef, output_types: dict, environment: Environment):
210+
def Split(
211+
defn: TaskDef, output_types: dict, environment: Environment | None
212+
):
211213
node = workflow.add(defn, environment=environment, hooks=hooks)
212214
return tuple(getattr(node, o) for o in output_types)
213215

pydra/engine/tests/test_boutiques.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import attr
44
import pytest
55
from pydra.engine.helpers import attrs_values
6-
from .utils import result_no_submitter, result_submitter, no_win
6+
from .utils import run_no_submitter, run_submitter, no_win
77
from pydra.design import workflow, boutiques, shell
88

99
need_bosh_docker = pytest.mark.skipif(
@@ -22,7 +22,7 @@
2222
@pytest.mark.parametrize(
2323
"maskfile", ["test_brain.nii.gz", "test_brain", "test_brain.nii"]
2424
)
25-
@pytest.mark.parametrize("results_function", [result_no_submitter, result_submitter])
25+
@pytest.mark.parametrize("results_function", [run_no_submitter, run_submitter])
2626
def test_boutiques_1(maskfile, plugin, results_function, tmpdir, data_tests_dir):
2727
"""simple task to run fsl.bet using BoshTask"""
2828
btask = boutiques.define(zenodo_id="1482743")

0 commit comments

Comments
 (0)