File tree Expand file tree Collapse file tree 3 files changed +23
-5
lines changed Expand file tree Collapse file tree 3 files changed +23
-5
lines changed Original file line number Diff line number Diff line change 3434from .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 ()
Original file line number Diff line number Diff 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+
110115def 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 )}
Original file line number Diff line number Diff 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
You can’t perform that action at this time.
0 commit comments