From f7fd0c8ae1ff900a5c1ddde95d73607e33ce6d1a Mon Sep 17 00:00:00 2001 From: Alejandro Barrera Date: Wed, 11 May 2016 12:19:53 -0400 Subject: [PATCH 1/2] are_same_type return true if the intersection of src and sink is not empty --- cwltool/workflow.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/cwltool/workflow.py b/cwltool/workflow.py index c2ffad113..1c1a94470 100644 --- a/cwltool/workflow.py +++ b/cwltool/workflow.py @@ -93,16 +93,20 @@ def are_same_type(src, sink): # type: (Any, Any) -> bool """ if isinstance(src, dict) and isinstance(sink, dict): if src["type"] == "array" and sink["type"] == "array": - if 'null' in sink["items"]: - return are_same_type([src["items"]], [it for it in sink["items"] if it != 'null']) - return are_same_type(src["items"], sink["items"]) - elif src["type"] == sink["type"]: - return True + src_items = src["items"] + sink_items = sink["items"] + if not isinstance(src_items, list): + src_items = [src_items] + if not isinstance(sink_items, list): + sink_items = [sink_items] + return are_same_type(src_items, sink_items) else: - return False + return src["type"] == sink["type"] else: - return src == sink - + try: + return src == sink or len(set(src).intersection(set(sink))) > 0 + except TypeError: + return False def object_from_state(state, parms, frag_only, supportsMultipleInput): # type: (Dict[str,WorkflowStateItem], List[Dict[str, Any]], bool, bool) -> Dict[str, str] From 6c331dfe05bbd7101c3e01fe56c9be21b92dc17c Mon Sep 17 00:00:00 2001 From: Alejandro Barrera Date: Wed, 8 Jun 2016 16:28:37 -0400 Subject: [PATCH 2/2] HashDict for cases where src and sink contain objects (in order to compute the set intersection) --- cwltool/utils.py | 4 ++++ cwltool/workflow.py | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/cwltool/utils.py b/cwltool/utils.py index ec33cadf1..d764d9011 100644 --- a/cwltool/utils.py +++ b/cwltool/utils.py @@ -16,3 +16,7 @@ def get_feature(self, feature): # type: (Any, Any) -> Tuple[Any, bool] if t["class"] == feature: return (t, False) return (None, None) + +class HashableDict(dict): + def __hash__(self): + return hash(tuple(sorted(self.items()))) diff --git a/cwltool/workflow.py b/cwltool/workflow.py index 1c1a94470..3c54ee682 100644 --- a/cwltool/workflow.py +++ b/cwltool/workflow.py @@ -1,6 +1,6 @@ from . import job from . import draft2tool -from .utils import aslist +from .utils import aslist, HashableDict from .process import Process, get_feature, empty_subtree, shortname, uniquename from .errors import WorkflowException import copy @@ -88,6 +88,7 @@ def match_types(sinktype, src, iid, inputobj, linkMerge, valueFrom): return True return False + def are_same_type(src, sink): # type: (Any, Any) -> bool """Check for identical type specifications, ignoring extra keys like inputBinding. """ @@ -99,6 +100,8 @@ def are_same_type(src, sink): # type: (Any, Any) -> bool src_items = [src_items] if not isinstance(sink_items, list): sink_items = [sink_items] + src_items = [HashableDict(s) if isinstance(s, dict) else s for s in src_items] + sink_items = [HashableDict(s) if isinstance(s, dict) else s for s in sink_items] return are_same_type(src_items, sink_items) else: return src["type"] == sink["type"]