@@ -770,16 +770,68 @@ def _check_nodes(self, nodes):
770770 def _has_attr (self , parameter , subtype = "in" ):
771771 """Checks if a parameter is available as an input or output
772772 """
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+
773821 if subtype == "in" :
774- subobject = self .inputs
822+ if not hasattr (targetnode .inputs , attrname ):
823+ return False
775824 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 ):
781826 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+
783835 return True
784836
785837 def _get_parameter_node (self , parameter , subtype = "in" ):
0 commit comments