Skip to content

Commit 16a3423

Browse files
committed
fixed direct output setting in workflow
1 parent 7e1428c commit 16a3423

File tree

3 files changed

+23
-5
lines changed

3 files changed

+23
-5
lines changed

pydra/engine/core.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from .helpers import (
3535
attrs_fields,
3636
attrs_values,
37+
fields_values,
3738
load_result,
3839
save,
3940
record_error,
@@ -680,11 +681,20 @@ def construct(
680681
constructor = input_values.pop("constructor")
681682
# Call the user defined constructor to set the outputs
682683
output_lazy_fields = constructor(**input_values)
683-
if output_lazy_fields is None:
684+
if output_lazy_fields is None and all(
685+
v is attrs.NOTHING for v in fields_values(outputs).values()
686+
):
684687
raise ValueError(
685688
f"Constructor function for {definition} returned None, must a lazy field "
686689
"or a tuple of lazy fields"
687690
)
691+
elif unset_outputs := [
692+
n for n, v in fields_values(outputs).items() if v is attrs.NOTHING
693+
]:
694+
raise ValueError(
695+
f"Mandatory outputs {unset_outputs} are not set by the "
696+
f"constructor of {workflow!r}"
697+
)
688698
# Check to see whether any mandatory inputs are not set
689699
for node in workflow.nodes:
690700
node._definition._check_rules()

pydra/engine/helpers.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ def list_fields(definition: "type[TaskDef] | TaskDef") -> list["Field"]:
107107
]
108108

109109

110+
def fields_values(obj, **kwargs) -> dict[str, ty.Any]:
111+
"""Get the values of an attrs object."""
112+
return {f.name: getattr(obj, f.name) for f in list_fields(obj)}
113+
114+
110115
def fields_dict(definition: "type[TaskDef] | TaskDef") -> dict[str, "Field"]:
111116
"""Returns the fields of a definition in a dictionary"""
112117
return {f.name: f for f in list_fields(definition)}

pydra/engine/tests/test_workflow.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4482,10 +4482,10 @@ class EvenException(Exception):
44824482
@python.define
44834483
def PassOdds(x):
44844484
if x % 2 == 0:
4485-
print(f"x={x}, x%2 = {x % 2} (error)\n")
4485+
print(f"x={x}, running x%2 = {x % 2} (even error)\n")
44864486
raise EvenException("even error")
44874487
else:
4488-
print(f"x={x}, x%2 = {x % 2}\n")
4488+
print(f"x={x}, running x%2 = {x % 2}\n")
44894489
return x
44904490

44914491
@workflow.define
@@ -4507,13 +4507,16 @@ def WorkyPassOdds(x):
45074507
out, err = capfd.readouterr()
45084508
stdout_lines = out.splitlines()
45094509

4510+
with open("/Users/tclose/Desktop/pytest-stdout.txt", "w") as f:
4511+
f.write(out)
4512+
45104513
tasks_run = 0
45114514
errors_found = 0
45124515

45134516
for line in stdout_lines:
4514-
if "x%2" in line:
4517+
if "running x%2" in line:
45154518
tasks_run += 1
4516-
if "(error)" in line:
4519+
if "(even error)" in line:
45174520
errors_found += 1
45184521

45194522
# There should have been 5 messages of the form "x%2 = XXX" after calling task() the first time

0 commit comments

Comments
 (0)