Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-pydot for openSUSE:Factory checked in at 2021-04-26 16:38:45 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pydot (Old) and /work/SRC/openSUSE:Factory/.python-pydot.new.12324 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pydot" Mon Apr 26 16:38:45 2021 rev:10 rq:887871 version:1.4.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pydot/python-pydot.changes 2020-02-29 21:18:40.758042606 +0100 +++ /work/SRC/openSUSE:Factory/.python-pydot.new.12324/python-pydot.changes 2021-04-26 16:38:56.846010987 +0200 @@ -1,0 +2,34 @@ +Thu Apr 22 19:34:13 UTC 2021 - Dirk M??ller <dmuel...@suse.com> + +- update to 1.4.2: + - Documentation: Basic usage examples in `README.md`. (#141) + + Changed: + - More detailed error message in case of Graphviz errors. (#239) + - More detailed warning message in case of failure to import the DOT + parser module. (#241) + + Deprecated: + - A future pydot 2.0.0 will drop support for Python 2, 3.4 and + possibly other Python versions that are end-of-life at that time. + Pydot does not emit any deprecation warnings about this. Further + pydot 1.x.x releases are currently not foreseen, but if there are + any, should still support the mentioned Python versions. (#229) + + Fixed: + - On Python 2, non-equality comparison (`!=`) between two separate, but + equal `Edge` instances will now correctly return `False`, as it + already did on Python 3. (#248) + - Prevent `TypeError` in handling of DOT parser error. (#176) + - Prevent `TypeError` in `graph_from_adjacency_matrix()` and + `graph_from_incidence_matrix()`. (#98) + - Prevent `TypeError` when creating an edge with a `Subgraph` or + `Cluster` object (as opposed to name string) as an edge point. (#89) + - Windows only: Fixed most failures to find Graphviz when a conda or + Anaconda installation exists, but Graphviz was installed manually or + through pip (`.bat`/`.exe` suffix problem). (#205) + - Windows only: Fixed failure to run Graphviz related to side-by-side + assembly (SxS) by now propagating the `SYSTEMROOT` environment + variable. (#208) + +------------------------------------------------------------------- Old: ---- pydot-1.4.1.tar.gz New: ---- pydot-1.4.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pydot.spec ++++++ --- /var/tmp/diff_new_pack.7QowDJ/_old 2021-04-26 16:38:57.290011694 +0200 +++ /var/tmp/diff_new_pack.7QowDJ/_new 2021-04-26 16:38:57.294011701 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-pydot # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-pydot -Version: 1.4.1 +Version: 1.4.2 Release: 0 Summary: Module to create (dot) graphs from Python License: MIT ++++++ pydot-1.4.1.tar.gz -> pydot-1.4.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pydot-1.4.1/ChangeLog new/pydot-1.4.2/ChangeLog --- old/pydot-1.4.1/ChangeLog 2018-12-12 21:59:45.000000000 +0100 +++ new/pydot-1.4.2/ChangeLog 2021-02-15 14:15:54.000000000 +0100 @@ -1,5 +1,43 @@ # `pydot` changelog +Pydot versions since 1.4.2 adhere to [PEP 440-style semantic versioning] +(https://www.python.org/dev/peps/pep-0440/#semantic-versioning). + + +1.4.2 (2021-02-15) +------------------ + +Added: +- Documentation: Basic usage examples in `README.md`. (#141) + +Changed: +- More detailed error message in case of Graphviz errors. (#239) +- More detailed warning message in case of failure to import the DOT + parser module. (#241) + +Deprecated: +- A future pydot 2.0.0 will drop support for Python 2, 3.4 and + possibly other Python versions that are end-of-life at that time. + Pydot does not emit any deprecation warnings about this. Further + pydot 1.x.x releases are currently not foreseen, but if there are + any, should still support the mentioned Python versions. (#229) + +Fixed: +- On Python 2, non-equality comparison (`!=`) between two separate, but + equal `Edge` instances will now correctly return `False`, as it + already did on Python 3. (#248) +- Prevent `TypeError` in handling of DOT parser error. (#176) +- Prevent `TypeError` in `graph_from_adjacency_matrix()` and + `graph_from_incidence_matrix()`. (#98) +- Prevent `TypeError` when creating an edge with a `Subgraph` or + `Cluster` object (as opposed to name string) as an edge point. (#89) +- Windows only: Fixed most failures to find Graphviz when a conda or + Anaconda installation exists, but Graphviz was installed manually or + through pip (`.bat`/`.exe` suffix problem). (#205) +- Windows only: Fixed failure to run Graphviz related to side-by-side + assembly (SxS) by now propagating the `SYSTEMROOT` environment + variable. (#208) + 1.4.1 (2018-12-12) ------------------ @@ -98,7 +136,7 @@ 1.0.29 (2016-05-16) ------------------- +------------------- - Maintenance release that keeps the same API - pin `pyparsing == 1.5.7` @@ -106,6 +144,298 @@ - update `setup.py` +1.0.28 (2012-01-03) +------------------- + +- Fixed issue 52. Improved handling of BOM-less UTF-8 encoded files. +- Fixed issue 55 regarding unicode handling. +- Fixed issue 50 where an ending colon in a node name was understood + as a port separator. Colons as the last character of node names will + be left as-is. +- Issue 59 (and duplicate issue 62): Program arguments are mishandled + in `Dot.create` - Patch merged. +- Fixed issue 49, handling of quotes in unicode html-labels. +- Fixed issue 60. Added an additional check in `__get_attribute__` to not + assume the parent graph is always retrievable. +- Fixed issue 61. Graph names will be adequately quoted when necessary. + + +1.0.25 (2011-04-10) +------------------- + +- Improved the message raised by `TypeErrors`. +- If arguments need to be specified for 'dot', 'neato' and rest of + graph layout engines they can now be passed to the `create()` and + `create_*()` family of functions. If a string is passed it's expected + to be simply the name of the program. If a list is passed it's + assumed to contain strings, the name of the layout engine as the + first element, followed by any optional arguments that will be later + appended to the command line. +- Improved parsing of DOT files where a subgraph was given inline as + the source or destination of an edge. + + +1.0.23 (around 2011-03-03) +-------------------------- + +- Fixed Issue 46 and modified the version number to include the + subversion revision number, hence the small jump from 1.0.4 to 1.0.23 + ;-) + + +1.0.4 (2010-12-31) +------------------ + +- Merged fixes by Nelson Elhage + - The "id_re_with_port" regex was too lax, and let through many + illegal strings just because they contained colons. Fix it to + require that both the ID and port component be independently safe. + - Even when the code detected that a string needed quoting, ", \n, + and \r were left alone inside the double quotes, which is illegal. + Replace them with appropriately escaped versions. +- We also add a test that pydot is correctly able to quote Python's + "string.printable" string, which exercises both of the above cases. +- Added testing script and test data +- Fixed issue 42. Graphviz's executable "sfdp" has been included in the + list of executables to search for and will now be found if available. +- Updated main docstring +- Fixed setup.py script to not include the dot-underscore files in OSX + (the resource fork) when building the tar.gz for distribution + + +1.0.3 (2010-11-02) +------------------ + +The release 1.0.3 of **pydot** is mainly a maintenance release. It +badly needed some attention. Most of the open issues have been +addressed. + +dot_parser.py: +- Improved the parsing of attributes with no explicit value but + implicit defaults +- Improved handling of subgraphs +- Improved handling of whitespace within HTML node names/labels + +pydot.py: +- Updated Graph, Cluster, Subgraph, Node and Edge attributes to reflect + the latest GraphViz version (2.26.3) +- Improved the parsing of attributes with no explicit value but + implicit defaults +- Improved handling of boolean attributes +- Fixed issue 17, 12 +- Fixed issues 19, 29, 35, 37 finding the Graphviz binary in Windows +- Added method del_node() to delete Nodes from the graph +- Added method del_edges() to delete Edges from the graph +- get_node() will now always return a list of nodes +- get_edge() will now always return a list of edges +- get_subgraph() will now always return a list of edges +- Other minor improvements + + +1.0.2 (2008-02-14) +------------------ + +The release 1.0.2 of **pydot** boasts the following: + +- The parser has been improved a lot. It passes all of GraphViz's + regression tests (which I consider quite an accomplishment seeing the + kind of crazy constructs on those ) +- Different charsets should now be dealt with properly. +- The search of GraphViz's executables has been improved for all + platforms. On Windows, paths and registry keys are searched. On Unix + now it should exhibit the same behavior as the traditional shell path + search. (Thanks Andy Gimblett and many others) +- Double-quoted paths in Windows are nor properly handled. The + os.path.exists() check fails if a valid path is enclosed within + quotes. +- 'type' keyword has been changed everywhere to 'graph_type' +- Better handling of Node/Edge/Graph defaults. Added methods: + set_graph_defaults, set_node_defaults, set_edge_defaults, + get_graph_defaults, get_node_defaults, get_edge_defaults +- Now it's possible to use rank to lay out nodes at the same level + + graph = pydot.Dot('graphname', graph_type='digraph') + subg = pydot.Subgraph('', rank='same') + subg.add_node(pydot.Node('a')) + graph.add_subgraph(subg) + subg.add_node(pydot.Node('b')) + subg.add_node(pydot.Node('c')) + +- Multiple main graphs in a file are now supported, will be returned as + a list of graph instances +- Handling of shapefiles Dot().set_shape_files() +- Added method "add_style()" to the Node class to easily append styles + to a node +- Attribute lists updated to reflect the available ones in graphviz 2.16 +- Added error reporting when rendering graphs with GraphViz + executables. There was an often reported problem where the output + graphs would have 0 size. In most cases this was due to Graphviz + missing a library for a format that pydot assumed to be there. Now + the error given by the executable will be reported instead of being + silently ignored (Thanks Jarno) +- Improved parsing of identifiers +- Added non-GraphViz attributes needed by dot2tex +- Jose Fonseca contributed a fix dealing with quoted strings the the + dot parsing module +- setup.py updated so that it's possible to install pydot through + Setuptools' easy_install +- Edge()'s can be created passing two Node objects as well as, the + previously supported, two strings with node names. Warning: when + passing two Node instances, the attributes won't be taken into + account. The edge will only read the Nodes' names to create an edge, + the Nodes must be separately added to the graph so all their + attributes are "remembered". +- Substituted all str()'s for unicode()'s +- It's possible now to manually specify the path to GraphViz's + executables in the case they can't be found automatically. The method + 'set_graphviz_executables(paths)' will take a dictionary specifying + the location of the executables. Please refer to the documentation + for usage detailed information. +- And too many bugfixes to list... + +**Performance:** + +The new pydot stores graphs and their objects using a hierarchy of +nested dictionaries and lists. Graph, Node, Edge objects are mere +proxies to the data and are created on demand. So that now it's +possible to have a graph with a 1 million edges and there will not be a +single Edge instance (only if requested, then they will be created on +demand, mapping the data and providing with all the methods to act on +the data in the global dictionary). + +Storing a graph with 1 million edges in pydot 1.0 has approximately the +same memory requirements (~813MiB) as dealing with one with only 40.000 +edges in pydot 0.9 (~851MiB), the 40.000 edges graph needs ~35MiB in +pydot 1.0 . Handling graphs should be much faster, as no linear +searches are performed in pydot 1.0 + + +0.9.10 (2004-12-21) and earlier +------------------------------- + +2004-12-21 09:12 carrer + + * dot_parser.py, pydot.py: Updated docstrings + +2004-12-20 11:19 carrer + + * dot_parser.py: Parsing of dot files greatly improved + +2004-12-20 11:17 carrer + + * pydot.py: Added new attributes introduced in Graphviz 1.16. + Added support to pickle graphs. Parsing of dot files greatly + improved. Bumped version to 0.9.10. + +2004-12-14 07:48 carrer + + * pydot.py: Improved the processing of the graph's default values + +2004-10-11 21:10 carrer + + * README: + Added list of required software to the README + +2004-10-11 21:09 carrer + + * MANIFEST, setup.py: + Added dot_parser module + +2004-10-11 21:06 carrer + + * dot_parser.py, pydot.py: + Thanks to a great contribution from Michael Krause, pydot is now + able to load DOT files. The loader has been tested against + plethora of test DOT files, and the results written to PS files, + which ended up being identical to the ones obtained straight from + running them through dot. Functions 'graph_from_dot_file' and + 'graph_from_dot_data' have been added. This feature requires the + pyparsing module. + + Note that if using pyparsing <1.2 the tabs in labels are + converted to whitespaces. 1.2 fixed that. + + Adrian Heilbut noticed that there was no way of telling pydot to + create HTML labels. Starting from this version, if the label's + first character is '<' and last is '>', the label will be treated + as HTML. If this is not the desired behaviour it suffices with + adding a whitespace before the first '<' character or after the + last '>'. + + Version bumped to 0.9.9 + +2004-10-11 21:02 carrer + + * pydot.py: + Added check to add_node() avoid creating nodes with the same + names. + +2004-10-11 20:59 carrer + + * pydot.py: + When adding an edge through add_edge() the correspoding Node + objects were not being created. While the graph was correctly + displayed it was not possible to modify the node attributes, as + it did not exist. Thus now, everytime an edge is added, the + corresponding nodes are created if they did not previously exist. + +2004-07-08 01:44 carrer + + * pydot.py: Fixed bug reported by Hector Villafuerte. + +2004-07-08 00:11 carrer + + * pydot.py: Fixed bug reported by Colin Gillespie regarding the + problem creating clusters due to the 'simplify' attribute + missing. + +2004-07-07 23:51 carrer + + * pydot.py: Set default program with which to process the output + and added some minor enhacement enabling to pass non-str objects + as Node names, which will be converted to str by retrieving their + string representation with str() + +2004-05-20 10:47 carrer + + * pydot.py: Bumped version to 0.9.4 + +2004-05-20 10:41 carrer + + * pydot.py: Minor bugfix + +2004-05-03 23:45 carrer + + * pydot.py: Merged fixes by Ramon Felciano: -Better handling of + default 'node' and 'edge' definitions. -Subgraph class now + accepts the same parametes as Graph. + +2004-05-01 14:24 carrer + + * README, setup.py: Changed license from GPL to MIT. + +2004-05-01 14:00 carrer + + * pydot.py: Minor bugfix. Added methods to retrieve an edge's + source and destination. + +2004-05-01 13:49 carrer + + * pydot.py: Minor bugfixes. License has been changed from GPL to + MIT. The following features have been implemented, as suggested + by Ramon Felciano: -Ability to retrieve nodes/subgraphs (by + name) and edges (by src+target) from a graph. -Ability to get + the graph's node/edge/subgraph lists. -Ability to get the + attributes from the objects, not only set them. + +2004-05-01 13:34 carrer + + * LICENSE: Changed license from GPL to MIT. + +2004-04-28 21:52 carrer + + * ChangeLog: [no log message] + 2004-04-28 21:50 carrer * pydot.py: Some of the changes already made should allow pydot to diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pydot-1.4.1/LICENSE new/pydot-1.4.2/LICENSE --- old/pydot-1.4.1/LICENSE 2018-11-19 00:10:22.000000000 +0100 +++ new/pydot-1.4.2/LICENSE 2021-02-15 14:15:27.000000000 +0100 @@ -1,5 +1,5 @@ Copyright (c) 2014 Carlos Jenkins -Copyright (c) 2014 Lance Helper +Copyright (c) 2014 Lance Hepler Copyright (c) 2004 Ero Carrera Permission is hereby granted, free of charge, to any person obtaining a copy diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pydot-1.4.1/PKG-INFO new/pydot-1.4.2/PKG-INFO --- old/pydot-1.4.1/PKG-INFO 2018-12-12 22:00:23.000000000 +0100 +++ new/pydot-1.4.2/PKG-INFO 2021-02-15 14:30:09.000000000 +0100 @@ -1,13 +1,15 @@ Metadata-Version: 2.1 Name: pydot -Version: 1.4.1 +Version: 1.4.2 Summary: Python interface to Graphviz's Dot Home-page: https://github.com/pydot/pydot Author: Ero Carrera -Author-email: e...@dkbza.org -Maintainer: Sebastian Kalinowski -Maintainer-email: sebast...@kalinowski.eu +Author-email: ero.carr...@gmail.com +Maintainer: Peter Nowee +Maintainer-email: pe...@peternowee.com License: MIT +Project-URL: Changelog, https://github.com/pydot/pydot/blob/master/ChangeLog +Project-URL: Bug Tracker, https://github.com/pydot/pydot/issues Description: [](https://www.travis-ci.com/pydot/pydot) [](https://pypi.org/project/pydot/) @@ -22,8 +24,193 @@ - is written in pure Python, and [`networkx`][3] can convert its graphs to `pydot`. - Development occurs at [GitHub][11] (under branch `dev`), - where you can report issues and contribute code. + + Development occurs at [GitHub][11], where you can report issues and + contribute code. + + + Examples + ======== + + The examples here will show you the most common input, editing and + output methods. + + Input + ----- + + No matter what you want to do with `pydot`, it will need some input to + start with. Here are 3 common options: + + 1. Import a graph from an existing DOT-file. + + Use this method if you already have a DOT-file describing a graph, + for example as output of another program. Let's say you already + have this `example.dot` (based on an [example from Wikipedia][12]): + + ```dot + graph my_graph { + bgcolor="yellow"; + a [label="Foo"]; + b [shape=circle]; + a -- b -- c [color=blue]; + } + ``` + + Just read the graph from the DOT-file: + + ```python + import pydot + + graphs = pydot.graph_from_dot_file('example.dot') + graph = graphs[0] + ``` + + 2. or: Parse a graph from an existing DOT-string. + + Use this method if you already have a DOT-string describing a + graph in a Python variable: + + ```python + import pydot + + dot_string = """graph my_graph { + bgcolor="yellow"; + a [label="Foo"]; + b [shape=circle]; + a -- b -- c [color=blue]; + }""" + + graphs = pydot.graph_from_dot_data(dot_string) + graph = graphs[0] + ``` + + 3. or: Create a graph from scratch using pydot objects. + + Now this is where the cool stuff starts. Use this method if you + want to build new graphs from Python. + + ```python + import pydot + + graph = pydot.Dot('my_graph', graph_type='graph', bgcolor='yellow') + + # Add nodes + my_node = pydot.Node('a', label='Foo') + graph.add_node(my_node) + # Or, without using an intermediate variable: + graph.add_node(pydot.Node('b', shape='circle')) + + # Add edges + my_edge = pydot.Edge('a', 'b', color='blue') + graph.add_edge(my_edge) + # Or, without using an intermediate variable: + graph.add_edge(pydot.Edge('b', 'c', color='blue')) + ``` + + Imagine using these basic building blocks from your Python program + to dynamically generate a graph. For example, start out with a + basic `pydot.Dot` graph object, then loop through your data while + adding nodes and edges. Use values from your data as labels, to + determine shapes, edges and so forth. This way, you can easily + build visualizations of thousands of interconnected items. + + 4. or: Convert a NetworkX graph to a pydot graph. + + NetworkX has conversion methods for pydot graphs: + + ```python + import networkx + import pydot + + # See NetworkX documentation on how to build a NetworkX graph. + + graph = networkx.drawing.nx_pydot.to_pydot(my_networkx_graph) + ``` + + Edit + ---- + + You can now further manipulate your graph using pydot methods: + + - Add further nodes and edges: + + ```python + graph.add_edge(pydot.Edge('b', 'd', style='dotted')) + ``` + + - Edit attributes of graph, nodes and edges: + + ```python + graph.set_bgcolor('lightyellow') + graph.get_node('b')[0].set_shape('box') + ``` + + Output + ------ + + Here are 3 different output options: + + 1. Generate an image. + + To generate an image of the graph, use one of the `create_*()` or + `write_*()` methods. + + - If you need to further process the output in Python, the + `create_*` methods will get you a Python bytes object: + + ```python + output_graphviz_svg = graph.create_svg() + ``` + + - If instead you just want to save the image to a file, use one of + the `write_*` methods: + + ```python + graph.write_png('output.png') + ``` + + 2. Retrieve the DOT string. + + There are two different DOT strings you can retrieve: + + - The "raw" pydot DOT: This is generated the fastest and will + usually still look quite similar to the DOT you put in. It is + generated by pydot itself, without calling Graphviz. + + ```python + # As a string: + output_raw_dot = graph.to_string() + # Or, save it as a DOT-file: + graph.write_raw('output_raw.dot') + ``` + + - The Graphviz DOT: You can use it to check how Graphviz lays out + the graph before it produces an image. It is generated by + Graphviz. + + ```python + # As a bytes literal: + output_graphviz_dot = graph.create_dot() + # Or, save it as a DOT-file: + graph.write_dot('output_graphviz.dot') + ``` + + 3. Convert to a NetworkX graph. + + Here as well, NetworkX has a conversion method for pydot graphs: + + ```python + my_networkx_graph = networkx.drawing.nx_pydot.from_pydot(graph) + ``` + + More help + --------- + + For more help, see the docstrings of the various pydot objects and + methods. For example, `help(pydot)`, `help(pydot.Graph)` and + `help(pydot.Dot.write)`. + + More [documentation contributions welcome][13]. Installation @@ -55,6 +242,17 @@ Distributed under an [MIT license][10]. + + Contacts + ======== + + Maintainers: + - Sebastian Kalinowski <sebast...@kalinowski.eu> (GitHub: @prmtl) + - Peter Nowee <pe...@peternowee.com> (GitHub: @peternowee) + + Original author: Ero Carrera <ero.carr...@gmail.com> + + [1]: https://www.graphviz.org [2]: https://en.wikipedia.org/wiki/DOT_%28graph_description_language%29 [3]: https://github.com/networkx/networkx @@ -63,12 +261,14 @@ [6]: https://github.com/pyparsing/pyparsing [7]: https://en.wikipedia.org/wiki/Package_manager [8]: https://www.macports.org - [9]: https://github.com/ellson/graphviz + [9]: https://gitlab.com/graphviz/graphviz [10]: https://github.com/pydot/pydot/blob/master/LICENSE [11]: https://github.com/pydot/pydot + [12]: https://en.wikipedia.org/w/index.php?title=DOT_(graph_description_language)&oldid=1003001464#Attributes + [13]: https://github.com/pydot/pydot/issues/130 Keywords: graphviz dot graphs visualization -Platform: UNKNOWN +Platform: any Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Science/Research @@ -82,6 +282,8 @@ Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 Classifier: Topic :: Scientific/Engineering :: Visualization Classifier: Topic :: Software Development :: Libraries :: Python Modules Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pydot-1.4.1/README.md new/pydot-1.4.2/README.md --- old/pydot-1.4.1/README.md 2018-11-30 22:23:39.000000000 +0100 +++ new/pydot-1.4.2/README.md 2021-02-15 14:15:27.000000000 +0100 @@ -12,8 +12,193 @@ - is written in pure Python, and [`networkx`][3] can convert its graphs to `pydot`. -Development occurs at [GitHub][11] (under branch `dev`), -where you can report issues and contribute code. + +Development occurs at [GitHub][11], where you can report issues and +contribute code. + + +Examples +======== + +The examples here will show you the most common input, editing and +output methods. + +Input +----- + +No matter what you want to do with `pydot`, it will need some input to +start with. Here are 3 common options: + +1. Import a graph from an existing DOT-file. + + Use this method if you already have a DOT-file describing a graph, + for example as output of another program. Let's say you already + have this `example.dot` (based on an [example from Wikipedia][12]): + + ```dot + graph my_graph { + bgcolor="yellow"; + a [label="Foo"]; + b [shape=circle]; + a -- b -- c [color=blue]; + } + ``` + + Just read the graph from the DOT-file: + + ```python + import pydot + + graphs = pydot.graph_from_dot_file('example.dot') + graph = graphs[0] + ``` + +2. or: Parse a graph from an existing DOT-string. + + Use this method if you already have a DOT-string describing a + graph in a Python variable: + + ```python + import pydot + + dot_string = """graph my_graph { + bgcolor="yellow"; + a [label="Foo"]; + b [shape=circle]; + a -- b -- c [color=blue]; + }""" + + graphs = pydot.graph_from_dot_data(dot_string) + graph = graphs[0] + ``` + +3. or: Create a graph from scratch using pydot objects. + + Now this is where the cool stuff starts. Use this method if you + want to build new graphs from Python. + + ```python + import pydot + + graph = pydot.Dot('my_graph', graph_type='graph', bgcolor='yellow') + + # Add nodes + my_node = pydot.Node('a', label='Foo') + graph.add_node(my_node) + # Or, without using an intermediate variable: + graph.add_node(pydot.Node('b', shape='circle')) + + # Add edges + my_edge = pydot.Edge('a', 'b', color='blue') + graph.add_edge(my_edge) + # Or, without using an intermediate variable: + graph.add_edge(pydot.Edge('b', 'c', color='blue')) + ``` + + Imagine using these basic building blocks from your Python program + to dynamically generate a graph. For example, start out with a + basic `pydot.Dot` graph object, then loop through your data while + adding nodes and edges. Use values from your data as labels, to + determine shapes, edges and so forth. This way, you can easily + build visualizations of thousands of interconnected items. + +4. or: Convert a NetworkX graph to a pydot graph. + + NetworkX has conversion methods for pydot graphs: + + ```python + import networkx + import pydot + + # See NetworkX documentation on how to build a NetworkX graph. + + graph = networkx.drawing.nx_pydot.to_pydot(my_networkx_graph) + ``` + +Edit +---- + +You can now further manipulate your graph using pydot methods: + +- Add further nodes and edges: + + ```python + graph.add_edge(pydot.Edge('b', 'd', style='dotted')) + ``` + +- Edit attributes of graph, nodes and edges: + + ```python + graph.set_bgcolor('lightyellow') + graph.get_node('b')[0].set_shape('box') + ``` + +Output +------ + +Here are 3 different output options: + +1. Generate an image. + + To generate an image of the graph, use one of the `create_*()` or + `write_*()` methods. + + - If you need to further process the output in Python, the + `create_*` methods will get you a Python bytes object: + + ```python + output_graphviz_svg = graph.create_svg() + ``` + + - If instead you just want to save the image to a file, use one of + the `write_*` methods: + + ```python + graph.write_png('output.png') + ``` + +2. Retrieve the DOT string. + + There are two different DOT strings you can retrieve: + + - The "raw" pydot DOT: This is generated the fastest and will + usually still look quite similar to the DOT you put in. It is + generated by pydot itself, without calling Graphviz. + + ```python + # As a string: + output_raw_dot = graph.to_string() + # Or, save it as a DOT-file: + graph.write_raw('output_raw.dot') + ``` + + - The Graphviz DOT: You can use it to check how Graphviz lays out + the graph before it produces an image. It is generated by + Graphviz. + + ```python + # As a bytes literal: + output_graphviz_dot = graph.create_dot() + # Or, save it as a DOT-file: + graph.write_dot('output_graphviz.dot') + ``` + +3. Convert to a NetworkX graph. + + Here as well, NetworkX has a conversion method for pydot graphs: + + ```python + my_networkx_graph = networkx.drawing.nx_pydot.from_pydot(graph) + ``` + +More help +--------- + +For more help, see the docstrings of the various pydot objects and +methods. For example, `help(pydot)`, `help(pydot.Graph)` and +`help(pydot.Dot.write)`. + +More [documentation contributions welcome][13]. Installation @@ -45,6 +230,17 @@ Distributed under an [MIT license][10]. + +Contacts +======== + +Maintainers: +- Sebastian Kalinowski <sebast...@kalinowski.eu> (GitHub: @prmtl) +- Peter Nowee <pe...@peternowee.com> (GitHub: @peternowee) + +Original author: Ero Carrera <ero.carr...@gmail.com> + + [1]: https://www.graphviz.org [2]: https://en.wikipedia.org/wiki/DOT_%28graph_description_language%29 [3]: https://github.com/networkx/networkx @@ -53,6 +249,8 @@ [6]: https://github.com/pyparsing/pyparsing [7]: https://en.wikipedia.org/wiki/Package_manager [8]: https://www.macports.org -[9]: https://github.com/ellson/graphviz +[9]: https://gitlab.com/graphviz/graphviz [10]: https://github.com/pydot/pydot/blob/master/LICENSE [11]: https://github.com/pydot/pydot +[12]: https://en.wikipedia.org/w/index.php?title=DOT_(graph_description_language)&oldid=1003001464#Attributes +[13]: https://github.com/pydot/pydot/issues/130 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pydot-1.4.1/dot_parser.py new/pydot-1.4.2/dot_parser.py --- old/pydot-1.4.1/dot_parser.py 2018-11-19 00:10:22.000000000 +0100 +++ new/pydot-1.4.2/dot_parser.py 2021-02-15 14:15:27.000000000 +0100 @@ -5,7 +5,7 @@ into a class representation defined by `pydot`. Author: Michael Krause <mich...@krause-software.de> -Fixes by: Ero Carrera <e...@dkbza.org> +Fixes by: Ero Carrera <ero.carr...@gmail.com> """ from __future__ import division from __future__ import print_function @@ -548,8 +548,7 @@ tokens = graphparser.parseString(s) return list(tokens) except ParseException as err: - print( - err.line + - " "*(err.column-1) + "^" + - err) + print(err.line) + print(" " * (err.column - 1) + "^") + print(err) return None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pydot-1.4.1/pydot.egg-info/PKG-INFO new/pydot-1.4.2/pydot.egg-info/PKG-INFO --- old/pydot-1.4.1/pydot.egg-info/PKG-INFO 2018-12-12 22:00:22.000000000 +0100 +++ new/pydot-1.4.2/pydot.egg-info/PKG-INFO 2021-02-15 14:30:09.000000000 +0100 @@ -1,13 +1,15 @@ Metadata-Version: 2.1 Name: pydot -Version: 1.4.1 +Version: 1.4.2 Summary: Python interface to Graphviz's Dot Home-page: https://github.com/pydot/pydot Author: Ero Carrera -Author-email: e...@dkbza.org -Maintainer: Sebastian Kalinowski -Maintainer-email: sebast...@kalinowski.eu +Author-email: ero.carr...@gmail.com +Maintainer: Peter Nowee +Maintainer-email: pe...@peternowee.com License: MIT +Project-URL: Changelog, https://github.com/pydot/pydot/blob/master/ChangeLog +Project-URL: Bug Tracker, https://github.com/pydot/pydot/issues Description: [](https://www.travis-ci.com/pydot/pydot) [](https://pypi.org/project/pydot/) @@ -22,8 +24,193 @@ - is written in pure Python, and [`networkx`][3] can convert its graphs to `pydot`. - Development occurs at [GitHub][11] (under branch `dev`), - where you can report issues and contribute code. + + Development occurs at [GitHub][11], where you can report issues and + contribute code. + + + Examples + ======== + + The examples here will show you the most common input, editing and + output methods. + + Input + ----- + + No matter what you want to do with `pydot`, it will need some input to + start with. Here are 3 common options: + + 1. Import a graph from an existing DOT-file. + + Use this method if you already have a DOT-file describing a graph, + for example as output of another program. Let's say you already + have this `example.dot` (based on an [example from Wikipedia][12]): + + ```dot + graph my_graph { + bgcolor="yellow"; + a [label="Foo"]; + b [shape=circle]; + a -- b -- c [color=blue]; + } + ``` + + Just read the graph from the DOT-file: + + ```python + import pydot + + graphs = pydot.graph_from_dot_file('example.dot') + graph = graphs[0] + ``` + + 2. or: Parse a graph from an existing DOT-string. + + Use this method if you already have a DOT-string describing a + graph in a Python variable: + + ```python + import pydot + + dot_string = """graph my_graph { + bgcolor="yellow"; + a [label="Foo"]; + b [shape=circle]; + a -- b -- c [color=blue]; + }""" + + graphs = pydot.graph_from_dot_data(dot_string) + graph = graphs[0] + ``` + + 3. or: Create a graph from scratch using pydot objects. + + Now this is where the cool stuff starts. Use this method if you + want to build new graphs from Python. + + ```python + import pydot + + graph = pydot.Dot('my_graph', graph_type='graph', bgcolor='yellow') + + # Add nodes + my_node = pydot.Node('a', label='Foo') + graph.add_node(my_node) + # Or, without using an intermediate variable: + graph.add_node(pydot.Node('b', shape='circle')) + + # Add edges + my_edge = pydot.Edge('a', 'b', color='blue') + graph.add_edge(my_edge) + # Or, without using an intermediate variable: + graph.add_edge(pydot.Edge('b', 'c', color='blue')) + ``` + + Imagine using these basic building blocks from your Python program + to dynamically generate a graph. For example, start out with a + basic `pydot.Dot` graph object, then loop through your data while + adding nodes and edges. Use values from your data as labels, to + determine shapes, edges and so forth. This way, you can easily + build visualizations of thousands of interconnected items. + + 4. or: Convert a NetworkX graph to a pydot graph. + + NetworkX has conversion methods for pydot graphs: + + ```python + import networkx + import pydot + + # See NetworkX documentation on how to build a NetworkX graph. + + graph = networkx.drawing.nx_pydot.to_pydot(my_networkx_graph) + ``` + + Edit + ---- + + You can now further manipulate your graph using pydot methods: + + - Add further nodes and edges: + + ```python + graph.add_edge(pydot.Edge('b', 'd', style='dotted')) + ``` + + - Edit attributes of graph, nodes and edges: + + ```python + graph.set_bgcolor('lightyellow') + graph.get_node('b')[0].set_shape('box') + ``` + + Output + ------ + + Here are 3 different output options: + + 1. Generate an image. + + To generate an image of the graph, use one of the `create_*()` or + `write_*()` methods. + + - If you need to further process the output in Python, the + `create_*` methods will get you a Python bytes object: + + ```python + output_graphviz_svg = graph.create_svg() + ``` + + - If instead you just want to save the image to a file, use one of + the `write_*` methods: + + ```python + graph.write_png('output.png') + ``` + + 2. Retrieve the DOT string. + + There are two different DOT strings you can retrieve: + + - The "raw" pydot DOT: This is generated the fastest and will + usually still look quite similar to the DOT you put in. It is + generated by pydot itself, without calling Graphviz. + + ```python + # As a string: + output_raw_dot = graph.to_string() + # Or, save it as a DOT-file: + graph.write_raw('output_raw.dot') + ``` + + - The Graphviz DOT: You can use it to check how Graphviz lays out + the graph before it produces an image. It is generated by + Graphviz. + + ```python + # As a bytes literal: + output_graphviz_dot = graph.create_dot() + # Or, save it as a DOT-file: + graph.write_dot('output_graphviz.dot') + ``` + + 3. Convert to a NetworkX graph. + + Here as well, NetworkX has a conversion method for pydot graphs: + + ```python + my_networkx_graph = networkx.drawing.nx_pydot.from_pydot(graph) + ``` + + More help + --------- + + For more help, see the docstrings of the various pydot objects and + methods. For example, `help(pydot)`, `help(pydot.Graph)` and + `help(pydot.Dot.write)`. + + More [documentation contributions welcome][13]. Installation @@ -55,6 +242,17 @@ Distributed under an [MIT license][10]. + + Contacts + ======== + + Maintainers: + - Sebastian Kalinowski <sebast...@kalinowski.eu> (GitHub: @prmtl) + - Peter Nowee <pe...@peternowee.com> (GitHub: @peternowee) + + Original author: Ero Carrera <ero.carr...@gmail.com> + + [1]: https://www.graphviz.org [2]: https://en.wikipedia.org/wiki/DOT_%28graph_description_language%29 [3]: https://github.com/networkx/networkx @@ -63,12 +261,14 @@ [6]: https://github.com/pyparsing/pyparsing [7]: https://en.wikipedia.org/wiki/Package_manager [8]: https://www.macports.org - [9]: https://github.com/ellson/graphviz + [9]: https://gitlab.com/graphviz/graphviz [10]: https://github.com/pydot/pydot/blob/master/LICENSE [11]: https://github.com/pydot/pydot + [12]: https://en.wikipedia.org/w/index.php?title=DOT_(graph_description_language)&oldid=1003001464#Attributes + [13]: https://github.com/pydot/pydot/issues/130 Keywords: graphviz dot graphs visualization -Platform: UNKNOWN +Platform: any Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Science/Research @@ -82,6 +282,8 @@ Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 Classifier: Topic :: Scientific/Engineering :: Visualization Classifier: Topic :: Software Development :: Libraries :: Python Modules Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pydot-1.4.1/pydot.py new/pydot-1.4.2/pydot.py --- old/pydot-1.4.1/pydot.py 2018-12-12 21:59:45.000000000 +0100 +++ new/pydot-1.4.2/pydot.py 2021-02-15 14:15:37.000000000 +0100 @@ -15,12 +15,13 @@ import dot_parser except Exception as e: warnings.warn( - "Couldn't import dot_parser, " - "loading of dot files will not be possible.") + "`pydot` could not import `dot_parser`, " + "so `pydot` will be unable to parse DOT files. " + "The error was: {e}".format(e=e)) __author__ = 'Ero Carrera' -__version__ = '1.4.1' +__version__ = '1.4.2' __license__ = 'MIT' @@ -95,15 +96,16 @@ return os.name == 'nt' -def is_anacoda(): +def is_anaconda(): # type: () -> bool - return os.path.exists(os.path.join(sys.prefix, 'conda-meta')) + import glob + return glob.glob(os.path.join(sys.prefix, 'conda-meta\\graphviz*.json')) != [] def get_executable_extension(): # type: () -> str if is_windows(): - return '.bat' if is_anacoda() else '.exe' + return '.bat' if is_anaconda() else '.exe' else: return '' @@ -122,6 +124,7 @@ env = { 'PATH': os.environ.get('PATH', ''), 'LD_LIBRARY_PATH': os.environ.get('LD_LIBRARY_PATH', ''), + 'SYSTEMROOT': os.environ.get('SYSTEMROOT', ''), } program_with_args = [program, ] + arguments @@ -245,7 +248,7 @@ def quote_if_necessary(s): - """Enclode attribute value in quotes, if needed.""" + """Enclose attribute value in quotes, if needed.""" if isinstance(s, bool): if s is True: return 'True' @@ -364,15 +367,14 @@ for e in r: if e: graph.add_edge( - Edge( node_prefix + node_orig, - node_prefix + node_dest) ) + Edge('%s%s' % (node_prefix, node_orig), + '%s%s' % (node_prefix, node_dest))) node_dest += 1 node_orig += 1 return graph - def graph_from_incidence_matrix(matrix, node_prefix='', directed=False): """Creates a basic graph out of an incidence matrix. @@ -401,8 +403,8 @@ if len(nodes) == 2: graph.add_edge( - Edge( node_prefix + abs(nodes[0]), - node_prefix + nodes[1] )) + Edge('%s%s' % (node_prefix, abs(nodes[0])), + '%s%s' % (node_prefix, nodes[1]))) if not directed: graph.set_simplify(True) @@ -554,7 +556,7 @@ class InvocationException(Exception): - """Indicate ploblem while running any GraphViz executable. + """Indicate problem while running any GraphViz executable. """ def __init__(self, value): self.value = value @@ -694,11 +696,11 @@ edge(src, dst, attribute=value, ...) - src: source node - dst: destination node + src: source node, subgraph or cluster + dst: destination node, subgraph or cluster - `src` and `dst` can be specified as a `Node` object, - or as the node's name string. + `src` and `dst` can be specified as a `Node`, `Subgraph` or + `Cluster` object, or as the name string of such a component. All the attributes defined in the Graphviz dot language should be supported. @@ -718,9 +720,9 @@ def __init__(self, src='', dst='', obj_dict=None, **attrs): self.obj_dict = dict() - if isinstance(src, Node): + if isinstance(src, (Node, Subgraph, Cluster)): src = src.get_name() - if isinstance(dst, Node): + if isinstance(dst, (Node, Subgraph, Cluster)): dst = dst.get_name() points = (quote_if_necessary(src), quote_if_necessary(dst)) @@ -792,7 +794,12 @@ return False - + if not PY3: + def __ne__(self, other): + result = self.__eq__(other) + if result is NotImplemented: + return NotImplemented + return not result def parse_node_ref(self, node_str): @@ -989,7 +996,11 @@ def set_node_defaults(self, **attrs): + """Define default node attributes. + These attributes only apply to nodes added to the graph after + calling this method. + """ self.add_node( Node('node', **attrs) ) @@ -1942,6 +1953,12 @@ ) print(message) - assert process.returncode == 0, process.returncode + assert process.returncode == 0, ( + '"{prog}" with args {arguments} returned code: {code}'.format( + prog=prog, + arguments=arguments, + code=process.returncode, + ) + ) return stdout_data diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pydot-1.4.1/setup.py new/pydot-1.4.2/setup.py --- old/pydot-1.4.1/setup.py 2018-12-05 22:07:40.000000000 +0100 +++ new/pydot-1.4.2/setup.py 2021-02-15 14:15:27.000000000 +0100 @@ -34,12 +34,17 @@ version=get_version(), description="Python interface to Graphviz's Dot", author='Ero Carrera', - author_email='e...@dkbza.org', - maintainer='Sebastian Kalinowski', - maintainer_email='sebast...@kalinowski.eu', + author_email='ero.carr...@gmail.com', + maintainer='Peter Nowee', + maintainer_email='pe...@peternowee.com', url='https://github.com/pydot/pydot', + project_urls={ + "Changelog": "https://github.com/pydot/pydot/blob/master/ChangeLog", + "Bug Tracker": "https://github.com/pydot/pydot/issues", + }, license='MIT', keywords='graphviz dot graphs visualization', + platforms=['any'], python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', classifiers=[ 'Development Status :: 5 - Production/Stable', @@ -55,6 +60,8 @@ 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', 'Topic :: Scientific/Engineering :: Visualization', 'Topic :: Software Development :: Libraries :: Python Modules'], long_description=get_long_description(), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pydot-1.4.1/test/pydot_unittest.py new/pydot-1.4.2/test/pydot_unittest.py --- old/pydot-1.4.1/test/pydot_unittest.py 2018-12-10 09:01:14.000000000 +0100 +++ new/pydot-1.4.2/test/pydot_unittest.py 2021-02-09 16:36:27.000000000 +0100 @@ -138,6 +138,36 @@ self.assertEqual( g2.get_edges()[0].get_source(), node1 ) self.assertEqual( g2.get_edges()[0].get_destination(), node2 ) + def test_graph_simplify(self): + # Fail example: pydot 1.0.2. GH pydot/pydot#92 OP patch 1. + g = pydot.Graph() + g.add_edge(pydot.Edge('a', 'b')) + g.add_edge(pydot.Edge('a', 'b')) + g.add_edge(pydot.Edge('b', 'a')) + g.add_edge(pydot.Edge('b', 'a')) + test_combinations = [ + ('graph', False, + 'graph G { a -- b; a -- b; b -- a; b -- a; }'), + ('graph', True, + 'graph G { a -- b; }'), + ('digraph', False, + 'digraph G { a -> b; a -> b; b -> a; b -> a; }'), + ('digraph', True, + 'digraph G { a -> b; b -> a; }')] + expected_concat = observed_concat = '' + for (graph_type, simplify, expected) in test_combinations: + expected_concat += 'graph_type %s, simplify %s: %s\n' % ( + graph_type, simplify, expected) + g.set_type(graph_type) + g.set_simplify(simplify) + try: + observed = ' '.join(g.to_string().split()) + except (NameError, TypeError) as e: + observed = '%s: %s' % (type(e).__name__, e) + observed_concat += 'graph_type %s, simplify %s: %s\n' % ( + graph_type, simplify, observed) + self.maxDiff = None + self.assertMultiLineEqual(expected_concat, observed_concat) def test_graph_with_shapefiles(self): shapefile_dir = os.path.join(test_dir, 'from-past-to-future') @@ -194,11 +224,11 @@ def _render_with_pydot(self, filename, encoding): c = pydot.graph_from_dot_file(filename, encoding=encoding) - sha = '' + jpe_data = bytearray() for g in c: - jpe_data = g.create(prog=TEST_PROGRAM, format='jpe', encoding=encoding) - sha += sha256(jpe_data).hexdigest() - return sha + jpe_data.extend(g.create(prog=TEST_PROGRAM, format='jpe', + encoding=encoding)) + return sha256(jpe_data).hexdigest() def test_my_regression_tests(self): path = os.path.join(test_dir, TESTS_DIR_1) @@ -346,6 +376,63 @@ g.add_node(u) g.write_svg('test.svg', prog=['twopi', '-Goverlap=scale']) + def test_edge_equality_basics_3_same_points_not_not_equal(self): + # Fail example: pydot 1.4.1 on Python 2. + g = pydot.Graph() + e1 = pydot.Edge('a', 'b') + e2 = pydot.Edge('a', 'b') + g.add_edge(e1) + g.add_edge(e2) + self.assertFalse(e1 != e2) + + def test_edge_point_namestr(self): + self._reset_graphs() + self.graph_directed.add_edge(pydot.Edge('a', 'b')) + self.assertEqual( + self.graph_directed.get_edges()[0].to_string(), 'a -> b;') + + def test_edge_point_object_node(self): + self._reset_graphs() + self.graph_directed.add_edge(pydot.Edge(pydot.Node('a'), + pydot.Node('b'))) + self.assertEqual( + self.graph_directed.get_edges()[0].to_string(), 'a -> b;') + + def test_edge_point_object_subgraph(self): + self._reset_graphs() + self.graph_directed.add_edge(pydot.Edge(pydot.Subgraph('a'), + pydot.Subgraph('b'))) + self.assertEqual( + self.graph_directed.get_edges()[0].to_string(), 'a -> b;') + + def test_edge_point_object_cluster(self): + self._reset_graphs() + self.graph_directed.add_edge(pydot.Edge(pydot.Cluster('a'), + pydot.Cluster('b'))) + self.assertEqual( + self.graph_directed.get_edges()[0].to_string(), + 'cluster_a -> cluster_b;') + + def test_graph_from_adjacency_matrix(self): + g = pydot.graph_from_adjacency_matrix( + [[0, 1, 0], [1, 0, 0], [0, 1, 1]], directed=True) + s = ' '.join(g.to_string().split()) + self.assertEqual(s, 'digraph G { 1 -> 2; 2 -> 1; 3 -> 2; 3 -> 3; }') + g = pydot.graph_from_adjacency_matrix( + [[0, 1, 0], [1, 0, 0], [0, 0, 1]], directed=False) + s = ' '.join(g.to_string().split()) + self.assertEqual(s, 'graph G { 1 -- 2; 3 -- 3; }') + + def test_graph_from_incidence_matrix(self): + g = pydot.graph_from_incidence_matrix( + [[-1, 1, 0], [1, -1, 0], [0, 1, -1]], directed=True) + s = ' '.join(g.to_string().split()) + self.assertEqual(s, 'digraph G { 1 -> 2; 2 -> 1; 3 -> 2; }') + g = pydot.graph_from_incidence_matrix( + [[1, 1, 0], [0, 1, 1]], directed=False) + s = ' '.join(g.to_string().split()) + self.assertEqual(s, 'graph G { 1 -- 2; 2 -- 3; }') + def check_path(): not_check = parse_args()