Skip to content

Commit 4a77081

Browse files
committed
debugged test_shelltask_inputspec
1 parent af65aab commit 4a77081

File tree

3 files changed

+54
-63
lines changed

3 files changed

+54
-63
lines changed

pydra/design/shell.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ class outarg(arg, Out):
236236
"""
237237

238238
path_template: str | None = attrs.field(default=None)
239-
keep_extension: bool = attrs.field(default=False)
239+
keep_extension: bool = attrs.field(default=True)
240240

241241
@path_template.validator
242242
def _validate_path_template(self, attribute, value):
@@ -256,13 +256,13 @@ def _validate_path_template(self, attribute, value):
256256
# f"path_template ({value!r}) can only be provided when argstr is not None"
257257
# )
258258

259-
@keep_extension.validator
260-
def _validate_keep_extension(self, attribute, value):
261-
if value and self.path_template is None:
262-
raise ValueError(
263-
f"keep_extension ({value!r}) can only be provided when path_template "
264-
f"is provided"
265-
)
259+
# @keep_extension.validator
260+
# def _validate_keep_extension(self, attribute, value):
261+
# if value and self.path_template is None:
262+
# raise ValueError(
263+
# f"keep_extension ({value!r}) can only be provided when path_template "
264+
# f"is provided"
265+
# )
266266

267267

268268
@dataclass_transform(

pydra/engine/helpers_file.py

Lines changed: 39 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,11 @@
88
from copy import copy
99
import subprocess as sp
1010
from contextlib import contextmanager
11-
import attr
1211
from fileformats.generic import FileSet
1312
from pydra.engine.helpers import is_lazy, attrs_values, list_fields
1413

1514
if ty.TYPE_CHECKING:
16-
from pydra.engine.specs import TaskDef
15+
from pydra.engine.specs import ShellDef
1716
from pydra.design import shell
1817

1918
logger = logging.getLogger("pydra")
@@ -122,9 +121,9 @@ def template_update(
122121
123122
"""
124123

125-
inputs_dict_st = attrs_values(definition)
124+
values = attrs_values(definition)
126125
if map_copyfiles is not None:
127-
inputs_dict_st.update(map_copyfiles)
126+
values.update(map_copyfiles)
128127

129128
from pydra.design import shell
130129

@@ -143,7 +142,7 @@ def template_update(
143142
dict_mod[fld.name] = template_update_single(
144143
field=fld,
145144
definition=definition,
146-
input_values=inputs_dict_st,
145+
values=values,
147146
output_dir=output_dir,
148147
)
149148
# adding elements from map_copyfiles to fields with templates
@@ -153,9 +152,9 @@ def template_update(
153152

154153

155154
def template_update_single(
156-
field,
157-
definition,
158-
input_values: dict[str, ty.Any] = None,
155+
field: "shell.outarg",
156+
definition: "ShellDef",
157+
values: dict[str, ty.Any] = None,
159158
output_dir: Path | None = None,
160159
spec_type: str = "input",
161160
) -> Path | None:
@@ -167,17 +166,17 @@ def template_update_single(
167166
# the dictionary will be created from inputs object
168167
from pydra.utils.typing import TypeParser, OUTPUT_TEMPLATE_TYPES # noqa
169168

170-
if input_values is None:
171-
input_values = attrs_values(definition)
169+
if values is None:
170+
values = attrs_values(definition)
172171

173172
if spec_type == "input":
174-
inp_val_set = input_values[field.name]
175-
if isinstance(inp_val_set, bool) and field.type in (Path, str):
173+
field_value = values[field.name]
174+
if isinstance(field_value, bool) and field.type in (Path, str):
176175
raise TypeError(
177176
f"type of '{field.name}' is Path, consider using Union[Path, bool]"
178177
)
179-
if inp_val_set is not None and not is_lazy(inp_val_set):
180-
inp_val_set = TypeParser(ty.Union[OUTPUT_TEMPLATE_TYPES])(inp_val_set)
178+
if field_value is not None and not is_lazy(field_value):
179+
field_value = TypeParser(ty.Union[OUTPUT_TEMPLATE_TYPES])(field_value)
181180
elif spec_type == "output":
182181
if not TypeParser.contains_type(FileSet, field.type):
183182
raise TypeError(
@@ -188,13 +187,13 @@ def template_update_single(
188187
raise TypeError(f"spec_type can be input or output, but {spec_type} provided")
189188
# for inputs that the value is set (so the template is ignored)
190189
if spec_type == "input":
191-
if isinstance(inp_val_set, (Path, list)):
192-
return inp_val_set
193-
if inp_val_set is False:
190+
if isinstance(field_value, (Path, list)):
191+
return field_value
192+
if field_value is False:
194193
# if input fld is set to False, the fld shouldn't be used (setting NOTHING)
195194
return None
196195
# inputs_dict[field.name] is True or spec_type is output
197-
value = _template_formatting(field, definition, input_values)
196+
value = _template_formatting(field, definition, values)
198197
# changing path so it is in the output_dir
199198
if output_dir and value is not None:
200199
# should be converted to str, it is also used for input fields that should be str
@@ -206,7 +205,7 @@ def template_update_single(
206205
return None
207206

208207

209-
def _template_formatting(field, definition, input_values):
208+
def _template_formatting(field, definition, values):
210209
"""Formatting the field template based on the values from inputs.
211210
Taking into account that the field with a template can be a MultiOutputFile
212211
and the field values needed in the template can be a list -
@@ -218,9 +217,9 @@ def _template_formatting(field, definition, input_values):
218217
----------
219218
field : pydra.engine.helpers.Field
220219
field with a template
221-
inputs : pydra.engine.helpers.Input
222-
inputs object
223-
inputs_dict_st : dict
220+
definition : pydra.engine.specs.TaskDef
221+
the task definition
222+
values : dict
224223
dictionary with values from inputs object
225224
226225
Returns
@@ -235,23 +234,17 @@ def _template_formatting(field, definition, input_values):
235234

236235
# as default, we assume that keep_extension is True
237236
if isinstance(template, (tuple, list)):
238-
formatted = [
239-
_single_template_formatting(field, t, definition, input_values)
240-
for t in template
241-
]
237+
formatted = [_single_template_formatting(field, t, values) for t in template]
242238
else:
243239
assert isinstance(template, str)
244-
formatted = _single_template_formatting(
245-
field, template, definition, input_values
246-
)
240+
formatted = _single_template_formatting(field, template, values)
247241
return formatted
248242

249243

250244
def _single_template_formatting(
251245
field: "shell.outarg",
252246
template: str,
253-
definition: "TaskDef",
254-
input_values: dict[str, ty.Any],
247+
values: dict[str, ty.Any],
255248
) -> Path | None:
256249
from pydra.utils.typing import MultiInputObj, MultiOutputFile
257250

@@ -274,29 +267,24 @@ def _single_template_formatting(
274267

275268
for fld in inp_fields:
276269
fld_name = fld[1:-1] # extracting the name form {field_name}
277-
if fld_name not in input_values:
270+
if fld_name not in values:
278271
raise AttributeError(f"{fld_name} is not provided in the input")
279-
fld_value = input_values[fld_name]
280-
if isinstance(fld_value, Path): # Remove path
281-
fld_value = fld_value.name
282-
if fld_value is attr.NOTHING:
272+
fld_value = values[fld_name]
273+
if fld_value is None:
283274
# if value is NOTHING, nothing should be added to the command
284-
return attr.NOTHING
285-
else:
286-
# checking for fields that can be treated as a file:
287-
# have type File, or value that is path like (including str with extensions)
288-
if isinstance(fld_value, os.PathLike) or (
289-
isinstance(fld_value, str) and "." in fld_value
290-
):
291-
if file_template:
292-
raise Exception(
293-
f"can't have multiple paths in {field.name} template,"
294-
f" but {template} provided"
295-
)
296-
else:
297-
file_template = (fld_name, fld_value)
275+
return None
276+
# checking for fields that can be treated as a file:
277+
# have type File, or value that is path like (including str with extensions)
278+
if isinstance(fld_value, os.PathLike):
279+
if file_template:
280+
raise Exception(
281+
f"can't have multiple paths in {field.name} template,"
282+
f" but {template} provided"
283+
)
298284
else:
299-
val_dict[fld_name] = fld_value
285+
file_template = (fld_name, fld_value)
286+
else:
287+
val_dict[fld_name] = fld_value
300288

301289
# if field is MultiOutputFile and some elements from val_dict are lists,
302290
# each element of the list should be used separately in the template

pydra/engine/tests/test_shelltask_inputspec.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,10 +1319,12 @@ class Outputs(ShellOutputs):
13191319
allowed_values=[2, 3, 4, None],
13201320
default=None,
13211321
argstr="-d",
1322+
position=1,
13221323
)
13231324
inputImageFilename: File = shell.arg(
13241325
help="A scalar image is expected as input for noise correction.",
13251326
argstr="-i",
1327+
position=2,
13261328
)
13271329
noise_model: str | None = shell.arg(
13281330
default=None,
@@ -1344,12 +1346,13 @@ class Outputs(ShellOutputs):
13441346
The shrink factor, specified as a single integer, describes this
13451347
resampling. Shrink factor = 1 is the default. """,
13461348
argstr="-s",
1349+
position=3,
13471350
)
13481351
patch_radius: int = shell.arg(
1349-
default=1, help="Patch radius. Default = 1x1x1", argstr="-p", position=2
1352+
default=1, help="Patch radius. Default = 1x1x1", argstr="-p", position=4
13501353
)
13511354
search_radius: int = shell.arg(
1352-
default=2, help="Search radius. Default = 2x2x2.", argstr="-r", position=3
1355+
default=2, help="Search radius. Default = 2x2x2.", argstr="-r", position=5
13531356
)
13541357
output: str = shell.arg(
13551358
help="Combined output",
@@ -1419,11 +1422,11 @@ class Outputs(ShellOutputs):
14191422
)
14201423

14211424
assert get_output_names(denoise_image) == [
1425+
"correctedImage",
1426+
"noiseImage",
14221427
"return_code",
14231428
"stderr",
14241429
"stdout",
1425-
"correctedImage",
1426-
"noiseImage",
14271430
]
14281431

14291432
# adding image_dimensionality that has allowed_values [2, 3, 4]

0 commit comments

Comments
 (0)