Open thomas-riccardi opened 6 years ago
Thanks for the detailed report. The edge method currently accepts :
-separated strings as node_id
s (DOT language), currently splitting them naively into node
, port
, and compass
:
https://github.com/xflr6/graphviz/blob/5eaf0b7c8b28c6e8f260175ecc3d1eecad92dc98/graphviz/lang.py#L55-L74
Unforunately, fixing the 'colons in node identifiers' use case might require an API change, so will need to check how to best do this in a backwards-compatible way.
In the mean time, you can use node names without literal colons (putting them into the label
instead):
In [1]: from graphviz import Digraph
...:
...: d = Digraph()
...: d.node('A')
...: d.node('B', label='::')
...: d.edge('A', 'B')
...:
...: d
Out[1]:
In [2]: d2 = Digraph()
...: d2.node('A')
...: d2.node('B', label="'B::C'")
...: d2.edge('A', 'B')
...:
...: d2
Out[2]:
Thanks @xflr6 for the workaround, I'll use that in the meantime.
I just encountered this issue when creating a graph with some C++ modifiers in it (::
is used as a namespace separator in C++). I'm not very familiar with DOT language so the way how graphviz treated colons was very surprising to me. I'm fine with pre-processing nodes though and it's not very hard to e.g. assign a number to each unique node identifier.
I think that situation would be better if special meaning of colons (and possibly other characters) was documented better, especially that Python library hides the details of DOT language behind a nice and clean API.
Thanks. I agree: let's try to better document the current behaviour (maybe you want to help with this?).
I'll try my best, but as I said I'm not very familiar with DOT language nor with implementation of your library, so I don't want to promise anything. :)
It might be nice if port and compass were kwargs, as opposed to things parsed out of the name; or even if name was allowed to be any of: 'id', ('id,), ('id', 'port'), or ('id', 'port', 'compass').
(Bringing this suggestion into this issue from here: https://github.com/xflr6/graphviz/issues/168#issuecomment-1100677538)
Having looked at the code a bit and thought about the different ways node()
and edge()
do their quoting, I actually think a NodeID
class would work quite well, instead of tuples. It's a bit more explicit, and allows you to pass "fully-qualified" node IDs (including port + compass) to node()
, which wasn't previously possible. (And is also totally useless, because node statements ignore ports and compasses. But it's nice to be consistent.)
Here's a draft PR for that: https://github.com/xflr6/graphviz/pull/169
Result:
Info: