Skip to content

Commit 72f9a6b

Browse files
committed
moved validation of output_file_template from application of the template (at runtime) to spec validation (at design time)
1 parent e58edac commit 72f9a6b

File tree

3 files changed

+23
-29
lines changed

3 files changed

+23
-29
lines changed

pydra/engine/helpers.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -496,12 +496,6 @@ def output_from_inputfields(output_spec, input_spec):
496496
new_fields = []
497497
for fld in attr.fields(make_klass(input_spec)):
498498
if "output_file_template" in fld.metadata:
499-
if fld.type not in (str, ty.Union[str, bool], Path, ty.Union[Path, bool]):
500-
raise TypeError(
501-
"Since 'output_file_template' is specified, the type of field "
502-
f"'{fld.name}' must a sub-class of str/Path or a "
503-
"str/Path subclass in union with a bool"
504-
)
505499
if "output_field_name" in fld.metadata:
506500
field_name = fld.metadata["output_field_name"]
507501
else:

pydra/engine/helpers_file.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ def template_update(inputs, output_dir, state_ind=None, map_copyfiles=None):
114114
inputs_dict_st[k] = inputs_dict_st[k][v]
115115

116116
from .specs import attr_fields
117-
from ..utils.typing import TypeParser
118117

119118
# Collect templated inputs for which all requirements are satisfied.
120119
fields_templ = [
@@ -129,13 +128,6 @@ def template_update(inputs, output_dir, state_ind=None, map_copyfiles=None):
129128

130129
dict_mod = {}
131130
for fld in fields_templ:
132-
if not TypeParser.is_subclass(
133-
fld.type, (str, Path, ty.Union[str, bool], ty.Union[Path, bool])
134-
):
135-
raise TypeError(
136-
"fields with output_file_template"
137-
" has to be a string or Union[str, bool]"
138-
)
139131
dict_mod[fld.name] = template_update_single(
140132
field=fld,
141133
inputs=inputs,
@@ -166,11 +158,6 @@ def template_update_single(
166158
inputs_dict_st = attr.asdict(inputs, recurse=False)
167159

168160
if spec_type == "input":
169-
if not TypeParser.is_subclass(field.type, VALID_TYPES):
170-
raise TypeError(
171-
f"'{field.name}' field has an 'output_file_template' and therefore "
172-
f"needs to be typed {VALID_TYPES}, not {field.type}" # <-- What is the bool option?
173-
)
174161
inp_val_set = inputs_dict_st[field.name]
175162
if inp_val_set is not attr.NOTHING and not TypeParser.is_instance(
176163
inp_val_set, VALID_TYPES

pydra/engine/specs.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
File,
1212
Directory,
1313
)
14-
1514
import pydra
1615
from .helpers_file import template_update_single
1716
from ..utils.hash import hash_function
@@ -366,22 +365,33 @@ def check_metadata(self):
366365
if set(mdata.keys()) - supported_keys:
367366
raise AttributeError(
368367
f"only these keys are supported {supported_keys}, but "
369-
f"{set(mdata.keys()) - supported_keys} provided"
368+
f"{set(mdata.keys()) - supported_keys} provided for '{fld.name}' "
369+
f"field in {self}"
370370
)
371371
# checking if the help string is provided (required field)
372372
if "help_string" not in mdata:
373-
raise AttributeError(f"{fld.name} doesn't have help_string field")
374-
# assuming that fields with output_file_template shouldn't have default
375-
if fld.default not in [attr.NOTHING, True, False] and mdata.get(
376-
"output_file_template"
377-
):
378373
raise AttributeError(
379-
"default value should not be set together with output_file_template"
374+
f"{fld.name} doesn't have help_string field in {self}"
380375
)
376+
# assuming that fields with output_file_template shouldn't have default
377+
if mdata.get("output_file_template"):
378+
if fld.type not in (Path, ty.Union[Path, bool]):
379+
raise TypeError(
380+
f"Type of '{fld.name}' should be either pathlib.Path or "
381+
f"typing.Union[pathlib.Path, bool] (not {fld.type}) because "
382+
f"it has a value for output_file_template ({mdata['output_file_template']})"
383+
)
384+
if fld.default not in [attr.NOTHING, True, False]:
385+
raise AttributeError(
386+
f"default value ({fld.default}) should not be set together with "
387+
f"output_file_template ({mdata['output_file_template']}) for "
388+
f"'{fld.name}' field in {self}"
389+
)
381390
# not allowing for default if the field is mandatory
382391
if not fld.default == attr.NOTHING and mdata.get("mandatory"):
383392
raise AttributeError(
384-
"default value should not be set when the field is mandatory"
393+
f"default value ({fld.default}) should not be set when the field "
394+
f"('{fld.name}' in {self}) is mandatory"
385395
)
386396
# setting default if value not provided and default is available
387397
if getattr(self, fld.name) is None:
@@ -571,7 +581,10 @@ def _field_metadata(
571581
)
572582
return callable_(**call_args_val)
573583
else:
574-
raise Exception("(_field_metadata) is not a current valid metadata key.")
584+
raise Exception(
585+
f"Metadata for '{fld.name}', does not not contain any of the required fields "
586+
f'("callable", "output_file_template" or "value"): {fld.metadata}.'
587+
)
575588

576589
def _check_requires(self, fld, inputs):
577590
"""checking if all fields from the requires and template are set in the input

0 commit comments

Comments
 (0)