def copyNode(self, srcNode, withEdges=False): """ Get a copy instance of a node outside the graph. Args: srcNode (Node): the node to copy withEdges (bool): whether to copy edges Returns: Node, dict: the created node instance, a dictionary of linked attributes with their original value (empty if withEdges is True) """ with GraphModification(self): # create a new node of the same type and with the same attributes values # keep links as-is so that CompatibilityNodes attributes can be created with correct automatic description # (File params for link expressions) node = nodeFactory(srcNode.toDict(), srcNode.nodeType) # use nodeType as name # skip edges: filter out attributes which are links by resetting default values skippedEdges = {} if not withEdges: for n, attr in node.attributes.items(): # find top-level links if Attribute.isLinkExpression(attr.value): skippedEdges[attr] = attr.value attr.resetValue() # find links in ListAttribute children elif isinstance(attr, ListAttribute): for child in attr.value: if Attribute.isLinkExpression(child.value): skippedEdges[child] = child.value child.resetValue() return node, skippedEdges
def attributeDescFromValue(attrName, value, isOutput): """ Generate an attribute description (desc.Attribute) that best matches 'value'. Args: attrName (str): the name of the attribute value: the value of the attribute isOutput (bool): whether the attribute is an output Returns: desc.Attribute: the generated attribute description """ params = { "name": attrName, "label": attrName, "description": "Incompatible parameter", "value": value, "uid": (), "group": "incompatible" } if isinstance(value, bool): return desc.BoolParam(**params) if isinstance(value, int): return desc.IntParam(range=None, **params) elif isinstance(value, float): return desc.FloatParam(range=None, **params) elif isinstance(value, pyCompatibility.basestring): if isOutput or os.path.isabs(value) or Attribute.isLinkExpression( value): return desc.File(**params) else: return desc.StringParam(**params) # List/GroupAttribute: recursively build descriptions elif isinstance(value, (list, dict)): del params["value"] del params["uid"] attrDesc = None if isinstance(value, list): elt = value[ 0] if value else "" # fallback: empty string value if list is empty eltDesc = CompatibilityNode.attributeDescFromValue( "element", elt, isOutput) attrDesc = desc.ListAttribute(elementDesc=eltDesc, **params) elif isinstance(value, dict): groupDesc = [] for key, value in value.items(): eltDesc = CompatibilityNode.attributeDescFromValue( key, value, isOutput) groupDesc.append(eltDesc) attrDesc = desc.GroupAttribute(groupDesc=groupDesc, **params) # override empty default value with attrDesc._value = value return attrDesc # handle any other type of parameters as Strings return desc.StringParam(**params)
def attributeDescFromName(refAttributes, name, value, conform=False): """ Try to find a matching attribute description in refAttributes for given attribute 'name' and 'value'. Args: refAttributes ([desc.Attribute]): reference Attributes to look for a description name (str): attribute's name value: attribute's value Returns: desc.Attribute: an attribute description from refAttributes if a match is found, None otherwise. """ # from original node description based on attribute's name attrDesc = next((d for d in refAttributes if d.name == name), None) # consider this value matches description: # - if it's a serialized link expression (no proper value to set/evaluate) # - or if it passes the 'matchDescription' test if attrDesc and (Attribute.isLinkExpression(value) or attrDesc.matchDescription(value, conform)): return attrDesc return None