pydot icon indicating copy to clipboard operation
pydot copied to clipboard

get_node() and get_edge() does not match correctly if the original name was quoted

Open qinyeli opened this issue 7 years ago • 4 comments

To replicate the error:

graph = pydot.Dot()
nodeA = pydot.Node('Node A')
graph.get_node('Node A')  # This return an empty list, whereas it should return [nodeA]

This error happens when the original names (given by the user) and the quoted names (used in inner dicts as keys) are mismatched.

qinyeli avatar Jul 11 '18 23:07 qinyeli

Still reproducible under current pydot 1.4.1:

import pydot
graph = pydot.Dot()
nodeA = pydot.Node('Node A')
graph.add_node(nodeA)
graph.get_node('Node A')   # returns: []
graph.get_node('"Node A"')  # returns: [<pydot.Node object at 0x7f08ea413470>]

peternowee avatar Aug 30 '20 13:08 peternowee

@qinyeli This is also in reply to your PR pydot/pydot#181. Sorry your work did not get reviewed earlier. I am actually thinking of solving this issue by having pydot internally store ID names unquoted and, if necessary, store information about quoting style in a separate pydot attribute, starting with pydot 2.0.0. See my comments in the last two paragraphs of https://github.com/pydot/pydot/issues/72#issuecomment-726333844. I assume that, once this new model is in place, changes to get_edge() and get_node() should not be necessary anymore. At the same time, PR pydot/pydot#181 is also not really suitable for the upcoming pydot 1.4.2 release, because that will just be a bug-fix/point release and probably the last in the pydot 1.x series, so we need to keep the risk of regressions low. So, I am afraid I will be closing your PR, unless you have any comments. Please let me know if want to get involved in implementing the new model I described, though be prepared it will cost a lot more time and effort, as it affects many parts of the code and raises many side questions, some already described in https://github.com/pydot/pydot/issues/72#issuecomment-726333844.

peternowee avatar Nov 28 '20 18:11 peternowee

As a workaround, this worked for me:

def getnode(dott,lbl): '''dott: dot object containing node to search for \n lbl: node name (str)''' nodez = dott.get_nodes() for noad in nodez: if noad.obj_dict['attributes']['label'].startswith(r'"{'+lbl+'|'): return noad

This works because all of my nodes have the shape "record", with the format below: 'label':"{Node_Name|HIGH : int\lLOW : int\lMEDIUM : int\loptions : set, NoneType\lsupported_ds : list\l|get_test(severity, name, variable)\lsetup(ds)\l}" You may need to adjust the validation function to taste depending on where your node name is located, I'm not sure. Just make sure it gives you a specific validation, using lbl in ... could be problematic if there is another name which includes the name being searched.

openSourcerer9000 avatar Feb 01 '21 14:02 openSourcerer9000