@@ -770,16 +770,68 @@ def _check_nodes(self, nodes):
770
770
def _has_attr (self , parameter , subtype = "in" ):
771
771
"""Checks if a parameter is available as an input or output
772
772
"""
773
+ hierarchy = parameter .split ("." )
774
+
775
+ # Connecting to a workflow needs at least two values,
776
+ # the name of the child node and the name of the input/output
777
+ if len (hierarchy ) < 2 :
778
+ return False
779
+
780
+ attrname = hierarchy .pop ()
781
+ nodename = hierarchy .pop ()
782
+
783
+ def _check_is_already_connected (workflow , node , attrname ):
784
+ for _ , _ , d in workflow ._graph .in_edges (nbunch = node , data = True ):
785
+ for cd in d ["connect" ]:
786
+ if attrname == cd [1 ]:
787
+ return False
788
+ return True
789
+
790
+ targetworkflow = self
791
+ while hierarchy :
792
+ workflowname = hierarchy .pop (0 )
793
+ workflow = None
794
+ for node in targetworkflow ._graph .nodes ():
795
+ if node .name == workflowname :
796
+ if isinstance (node , Workflow ):
797
+ workflow = node
798
+ break
799
+ if workflow is None :
800
+ return False
801
+ # Verify input does not already have an incoming connection
802
+ # in the hierarchy of workflows
803
+ if subtype == "in" :
804
+ hierattrname = "." .join (hierarchy + [nodename , attrname ])
805
+ if not _check_is_already_connected (
806
+ targetworkflow , workflow , hierattrname ):
807
+ return False
808
+ targetworkflow = workflow
809
+
810
+ targetnode = None
811
+ for node in targetworkflow ._graph .nodes ():
812
+ if node .name == nodename :
813
+ if isinstance (node , Workflow ):
814
+ return False
815
+ else :
816
+ targetnode = node
817
+ break
818
+ if targetnode is None :
819
+ return False
820
+
773
821
if subtype == "in" :
774
- subobject = self .inputs
822
+ if not hasattr (targetnode .inputs , attrname ):
823
+ return False
775
824
else :
776
- subobject = self .outputs
777
- attrlist = parameter .split ("." )
778
- cur_out = subobject
779
- for attr in attrlist :
780
- if not hasattr (cur_out , attr ):
825
+ if not hasattr (targetnode .outputs , attrname ):
781
826
return False
782
- cur_out = getattr (cur_out , attr )
827
+
828
+ # Verify input does not already have an incoming connection
829
+ # in the target workflow
830
+ if subtype == "in" :
831
+ if not _check_is_already_connected (
832
+ targetworkflow , targetnode , attrname ):
833
+ return False
834
+
783
835
return True
784
836
785
837
def _get_parameter_node (self , parameter , subtype = "in" ):
0 commit comments