[Python-modules-commits] [python-altgraph] 01/03: Imported Upstream version 0.12~dfsg
IOhannes m zmölnig
umlaeute at moszumanska.debian.org
Mon Jul 6 13:41:09 UTC 2015
This is an automated email from the git hooks/post-receive script.
umlaeute pushed a commit to branch master
in repository python-altgraph.
commit d7ec67bcb921d07b63957e589b2a00446e304b48
Author: IOhannes m zmölnig <zmoelnig at umlautQ.umlaeute.mur.at>
Date: Mon Jul 6 15:34:42 2015 +0200
Imported Upstream version 0.12~dfsg
---
MANIFEST.in | 9 +
PKG-INFO | 216 +++++++++
README.txt | 6 +
altgraph/Dot.py | 299 +++++++++++++
altgraph/Graph.py | 677 ++++++++++++++++++++++++++++
altgraph/GraphAlgo.py | 147 ++++++
altgraph/GraphStat.py | 73 +++
altgraph/GraphUtil.py | 137 ++++++
altgraph/ObjectGraph.py | 202 +++++++++
altgraph/__init__.py | 135 ++++++
altgraph_tests/__init__.py | 1 +
altgraph_tests/test_altgraph.py | 45 ++
altgraph_tests/test_dot.py | 370 +++++++++++++++
altgraph_tests/test_graph.py | 644 ++++++++++++++++++++++++++
altgraph_tests/test_graphstat.py | 70 +++
altgraph_tests/test_graphutil.py | 140 ++++++
altgraph_tests/test_object_graph.py | 349 +++++++++++++++
doc/Makefile | 89 ++++
doc/changelog.rst | 185 ++++++++
doc/conf.py | 209 +++++++++
doc/core.rst | 26 ++
doc/dot.rst | 224 ++++++++++
doc/graph.rst | 305 +++++++++++++
doc/graphalgo.rst | 26 ++
doc/graphstat.rst | 25 ++
doc/graphutil.rst | 55 +++
doc/index.rst | 41 ++
doc/license.rst | 25 ++
doc/objectgraph.rst | 146 ++++++
setup.cfg | 36 ++
setup.py | 867 ++++++++++++++++++++++++++++++++++++
31 files changed, 5779 insertions(+)
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..9a9b960
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,9 @@
+include ReadMe.txt
+include *.txt MANIFEST.in *.py
+graft doc
+graft doc/_static
+graft doc/_templates
+graft altgraph_tests
+global-exclude .DS_Store
+global-exclude *.pyc
+global-exclude *.so
diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..87b602f
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,216 @@
+Metadata-Version: 1.1
+Name: altgraph
+Version: 0.12
+Summary: Python graph (network) package
+Home-page: http://packages.python.org/altgraph
+Author: Ronald Oussoren
+Author-email: ronaldoussoren at mac.com
+License: MIT
+Download-URL: http://pypi.python.org/pypi/altgraph
+Description: altgraph is a fork of graphlib: a graph (network) package for constructing
+ graphs, BFS and DFS traversals, topological sort, shortest paths, etc. with
+ graphviz output.
+
+ altgraph includes some additional usage of Python 2.6+ features and
+ enhancements related to modulegraph and macholib.
+
+
+ Release history
+ ===============
+
+ 0.12
+ ----
+
+ - Added ``ObjectGraph.edgeData`` to retrieve the edge data
+ from a specific edge.
+
+ - Added ``AltGraph.update_edge_data`` and ``ObjectGraph.updateEdgeData``
+ to update the data associated with a graph edge.
+
+ 0.11
+ ----
+
+ - Stabilize the order of elements in dot file exports,
+ patch from bitbucket user 'pombredanne'.
+
+ - Tweak setup.py file to remove dependency on distribute (but
+ keep the dependency on setuptools)
+
+
+ 0.10.2
+ ------
+
+ - There where no classifiers in the package metadata due to a bug
+ in setup.py
+
+ 0.10.1
+ ------
+
+ This is a bugfix release
+
+ Bug fixes:
+
+ - Issue #3: The source archive contains a README.txt
+ while the setup file refers to ReadMe.txt.
+
+ This is caused by a misfeature in distutils, as a
+ workaround I've renamed ReadMe.txt to README.txt
+ in the source tree and setup file.
+
+
+ 0.10
+ -----
+
+ This is a minor feature release
+
+ Features:
+
+ - Do not use "2to3" to support Python 3.
+
+ As a side effect of this altgraph now supports
+ Python 2.6 and later, and no longer supports
+ earlier releases of Python.
+
+ - The order of attributes in the Dot output
+ is now always alphabetical.
+
+ With this change the output will be consistent
+ between runs and Python versions.
+
+ 0.9
+ ---
+
+ This is a minor bugfix release
+
+ Features:
+
+ - Added ``altgraph.ObjectGraph.ObjectGraph.nodes``, a method
+ yielding all nodes in an object graph.
+
+ Bugfixes:
+
+ - The 0.8 release didn't work with py2app when using
+ python 3.x.
+
+
+ 0.8
+ -----
+
+ This is a minor feature release. The major new feature
+ is a extensive set of unittests, which explains almost
+ all other changes in this release.
+
+ Bugfixes:
+
+ - Installing failed with Python 2.5 due to using a distutils
+ class that isn't available in that version of Python
+ (issue #1 on the issue tracker)
+
+ - ``altgraph.GraphStat.degree_dist`` now actually works
+
+ - ``altgraph.Graph.add_edge(a, b, create_nodes=False)`` will
+ no longer create the edge when one of the nodes doesn't
+ exist.
+
+ - ``altgraph.Graph.forw_topo_sort`` failed for some sparse graphs.
+
+ - ``altgraph.Graph.back_topo_sort`` was completely broken in
+ previous releases.
+
+ - ``altgraph.Graph.forw_bfs_subgraph`` now actually works.
+
+ - ``altgraph.Graph.back_bfs_subgraph`` now actually works.
+
+ - ``altgraph.Graph.iterdfs`` now returns the correct result
+ when the ``forward`` argument is ``False``.
+
+ - ``altgraph.Graph.iterdata`` now returns the correct result
+ when the ``forward`` argument is ``False``.
+
+
+ Features:
+
+ - The ``altgraph.Graph`` constructor now accepts an argument
+ that contains 2- and 3-tuples instead of requireing that
+ all items have the same size. The (optional) argument can now
+ also be any iterator.
+
+ - ``altgraph.Graph.Graph.add_node`` has no effect when you
+ add a hidden node.
+
+ - The private method ``altgraph.Graph._bfs`` is no longer
+ present.
+
+ - The private method ``altgraph.Graph._dfs`` is no longer
+ present.
+
+ - ``altgraph.ObjectGraph`` now has a ``__contains__`` methods,
+ which means you can use the ``in`` operator to check if a
+ node is part of a graph.
+
+ - ``altgraph.GraphUtil.generate_random_graph`` will raise
+ ``GraphError`` instead of looping forever when it is
+ impossible to create the requested graph.
+
+ - ``altgraph.Dot.edge_style`` raises ``GraphError`` when
+ one of the nodes is not present in the graph. The method
+ silently added the tail in the past, but without ensuring
+ a consistent graph state.
+
+ - ``altgraph.Dot.save_img`` now works when the mode is
+ ``"neato"``.
+
+ 0.7.2
+ -----
+
+ This is a minor bugfix release
+
+ Bugfixes:
+
+ - distutils didn't include the documentation subtree
+
+ 0.7.1
+ -----
+
+ This is a minor feature release
+
+ Features:
+
+ - Documentation is now generated using `sphinx <http://pypi.python.org/pypi/sphinx>`_
+ and can be viewed at <http://packages.python.org/altgraph>.
+
+ - The repository has moved to bitbucket
+
+ - ``altgraph.GraphStat.avg_hops`` is no longer present, the function had no
+ implementation and no specified behaviour.
+
+ - the module ``altgraph.compat`` is gone, which means altgraph will no
+ longer work with Python 2.3.
+
+
+ 0.7.0
+ -----
+
+ This is a minor feature release.
+
+ Features:
+
+ - Support for Python 3
+
+ - It is now possible to run tests using 'python setup.py test'
+
+ (The actual testsuite is still very minimal though)
+
+Keywords: graph
+Platform: any
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Topic :: Scientific/Engineering :: Mathematics
+Classifier: Topic :: Scientific/Engineering :: Visualization
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..904a14b
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,6 @@
+altgraph is a fork of graphlib: a graph (network) package for constructing
+graphs, BFS and DFS traversals, topological sort, shortest paths, etc. with
+graphviz output.
+
+altgraph includes some additional usage of Python 2.6+ features and
+enhancements related to modulegraph and macholib.
diff --git a/altgraph/Dot.py b/altgraph/Dot.py
new file mode 100644
index 0000000..49a471e
--- /dev/null
+++ b/altgraph/Dot.py
@@ -0,0 +1,299 @@
+'''
+altgraph.Dot - Interface to the dot language
+============================================
+
+The :py:mod:`~altgraph.Dot` module provides a simple interface to the
+file format used in the `graphviz <http://www.research.att.com/sw/tools/graphviz/>`_
+program. The module is intended to offload the most tedious part of the process
+(the **dot** file generation) while transparently exposing most of its features.
+
+To display the graphs or to generate image files the `graphviz <http://www.research.att.com/sw/tools/graphviz/>`_
+package needs to be installed on the system, moreover the :command:`dot` and :command:`dotty` programs must
+be accesible in the program path so that they can be ran from processes spawned
+within the module.
+
+Example usage
+-------------
+
+Here is a typical usage::
+
+ from altgraph import Graph, Dot
+
+ # create a graph
+ edges = [ (1,2), (1,3), (3,4), (3,5), (4,5), (5,4) ]
+ graph = Graph.Graph(edges)
+
+ # create a dot representation of the graph
+ dot = Dot.Dot(graph)
+
+ # display the graph
+ dot.display()
+
+ # save the dot representation into the mydot.dot file
+ dot.save_dot(file_name='mydot.dot')
+
+ # save dot file as gif image into the graph.gif file
+ dot.save_img(file_name='graph', file_type='gif')
+
+Directed graph and non-directed graph
+-------------------------------------
+
+Dot class can use for both directed graph and non-directed graph
+by passing ``graphtype`` parameter.
+
+Example::
+
+ # create directed graph(default)
+ dot = Dot.Dot(graph, graphtype="digraph")
+
+ # create non-directed graph
+ dot = Dot.Dot(graph, graphtype="graph")
+
+Customizing the output
+----------------------
+
+The graph drawing process may be customized by passing
+valid :command:`dot` parameters for the nodes and edges. For a list of all
+parameters see the `graphviz <http://www.research.att.com/sw/tools/graphviz/>`_
+documentation.
+
+Example::
+
+ # customizing the way the overall graph is drawn
+ dot.style(size='10,10', rankdir='RL', page='5, 5' , ranksep=0.75)
+
+ # customizing node drawing
+ dot.node_style(1, label='BASE_NODE',shape='box', color='blue' )
+ dot.node_style(2, style='filled', fillcolor='red')
+
+ # customizing edge drawing
+ dot.edge_style(1, 2, style='dotted')
+ dot.edge_style(3, 5, arrowhead='dot', label='binds', labelangle='90')
+ dot.edge_style(4, 5, arrowsize=2, style='bold')
+
+
+.. note::
+
+ dotty (invoked via :py:func:`~altgraph.Dot.display`) may not be able to
+ display all graphics styles. To verify the output save it to an image file
+ and look at it that way.
+
+Valid attributes
+----------------
+
+ - dot styles, passed via the :py:meth:`Dot.style` method::
+
+ rankdir = 'LR' (draws the graph horizontally, left to right)
+ ranksep = number (rank separation in inches)
+
+ - node attributes, passed via the :py:meth:`Dot.node_style` method::
+
+ style = 'filled' | 'invisible' | 'diagonals' | 'rounded'
+ shape = 'box' | 'ellipse' | 'circle' | 'point' | 'triangle'
+
+ - edge attributes, passed via the :py:meth:`Dot.edge_style` method::
+
+ style = 'dashed' | 'dotted' | 'solid' | 'invis' | 'bold'
+ arrowhead = 'box' | 'crow' | 'diamond' | 'dot' | 'inv' | 'none' | 'tee' | 'vee'
+ weight = number (the larger the number the closer the nodes will be)
+
+ - valid `graphviz colors <http://www.research.att.com/~erg/graphviz/info/colors.html>`_
+
+ - for more details on how to control the graph drawing process see the
+ `graphviz reference <http://www.research.att.com/sw/tools/graphviz/refs.html>`_.
+'''
+import os
+import warnings
+
+from altgraph import GraphError
+
+
+class Dot(object):
+ '''
+ A class providing a **graphviz** (dot language) representation
+ allowing a fine grained control over how the graph is being
+ displayed.
+
+ If the :command:`dot` and :command:`dotty` programs are not in the current system path
+ their location needs to be specified in the contructor.
+ '''
+
+ def __init__(self, graph=None, nodes=None, edgefn=None, nodevisitor=None, edgevisitor=None, name="G", dot='dot', dotty='dotty', neato='neato', graphtype="digraph"):
+ '''
+ Initialization.
+ '''
+ self.name, self.attr = name, {}
+
+ assert graphtype in ['graph', 'digraph']
+ self.type = graphtype
+
+ self.temp_dot = "tmp_dot.dot"
+ self.temp_neo = "tmp_neo.dot"
+
+ self.dot, self.dotty, self.neato = dot, dotty, neato
+
+ # self.nodes: node styles
+ # self.edges: edge styles
+ self.nodes, self.edges = {}, {}
+
+ if graph is not None and nodes is None:
+ nodes = graph
+ if graph is not None and edgefn is None:
+ def edgefn(node, graph=graph):
+ return graph.out_nbrs(node)
+ if nodes is None:
+ nodes = ()
+
+ seen = set()
+ for node in nodes:
+ if nodevisitor is None:
+ style = {}
+ else:
+ style = nodevisitor(node)
+ if style is not None:
+ self.nodes[node] = {}
+ self.node_style(node, **style)
+ seen.add(node)
+ if edgefn is not None:
+ for head in seen:
+ for tail in (n for n in edgefn(head) if n in seen):
+ if edgevisitor is None:
+ edgestyle = {}
+ else:
+ edgestyle = edgevisitor(head, tail)
+ if edgestyle is not None:
+ if head not in self.edges:
+ self.edges[head] = {}
+ self.edges[head][tail] = {}
+ self.edge_style(head, tail, **edgestyle)
+
+ def style(self, **attr):
+ '''
+ Changes the overall style
+ '''
+ self.attr = attr
+
+ def display(self, mode='dot'):
+ '''
+ Displays the current graph via dotty
+ '''
+
+ if mode == 'neato':
+ self.save_dot(self.temp_neo)
+ neato_cmd = "%s -o %s %s" % (self.neato, self.temp_dot, self.temp_neo)
+ os.system(neato_cmd)
+ else:
+ self.save_dot(self.temp_dot)
+
+ plot_cmd = "%s %s" % (self.dotty, self.temp_dot)
+ os.system(plot_cmd)
+
+ def node_style(self, node, **kwargs):
+ '''
+ Modifies a node style to the dot representation.
+ '''
+ if node not in self.edges:
+ self.edges[node] = {}
+ self.nodes[node] = kwargs
+
+ def all_node_style(self, **kwargs):
+ '''
+ Modifies all node styles
+ '''
+ for node in self.nodes:
+ self.node_style(node, **kwargs)
+
+ def edge_style(self, head, tail, **kwargs):
+ '''
+ Modifies an edge style to the dot representation.
+ '''
+ if tail not in self.nodes:
+ raise GraphError("invalid node %s" % (tail,))
+
+ try:
+ if tail not in self.edges[head]:
+ self.edges[head][tail]= {}
+ self.edges[head][tail] = kwargs
+ except KeyError:
+ raise GraphError("invalid edge %s -> %s " % (head, tail) )
+
+ def iterdot(self):
+ # write graph title
+ if self.type == 'digraph':
+ yield 'digraph %s {\n' % (self.name,)
+ elif self.type == 'graph':
+ yield 'graph %s {\n' % (self.name,)
+
+ else:
+ raise GraphError("unsupported graphtype %s" % (self.type,))
+
+ # write overall graph attributes
+ for attr_name, attr_value in sorted(self.attr.items()):
+ yield '%s="%s";' % (attr_name, attr_value)
+ yield '\n'
+
+ # some reusable patterns
+ cpatt = '%s="%s",' # to separate attributes
+ epatt = '];\n' # to end attributes
+
+ # write node attributes
+ for node_name, node_attr in sorted(self.nodes.items()):
+ yield '\t"%s" [' % (node_name,)
+ for attr_name, attr_value in sorted(node_attr.items()):
+ yield cpatt % (attr_name, attr_value)
+ yield epatt
+
+ # write edge attributes
+ for head in sorted(self.edges):
+ for tail in sorted(self.edges[head]):
+ if self.type == 'digraph':
+ yield '\t"%s" -> "%s" [' % (head, tail)
+ else:
+ yield '\t"%s" -- "%s" [' % (head, tail)
+ for attr_name, attr_value in sorted(self.edges[head][tail].items()):
+ yield cpatt % (attr_name, attr_value)
+ yield epatt
+
+ # finish file
+ yield '}\n'
+
+ def __iter__(self):
+ return self.iterdot()
+
+ def save_dot(self, file_name=None):
+ '''
+ Saves the current graph representation into a file
+ '''
+
+ if not file_name:
+ warnings.warn(DeprecationWarning, "always pass a file_name")
+ file_name = self.temp_dot
+
+ fp = open(file_name, "w")
+ try:
+ for chunk in self.iterdot():
+ fp.write(chunk)
+ finally:
+ fp.close()
+
+ def save_img(self, file_name=None, file_type="gif", mode='dot'):
+ '''
+ Saves the dot file as an image file
+ '''
+
+ if not file_name:
+ warnings.warn(DeprecationWarning, "always pass a file_name")
+ file_name = "out"
+
+ if mode == 'neato':
+ self.save_dot(self.temp_neo)
+ neato_cmd = "%s -o %s %s" % (self.neato, self.temp_dot, self.temp_neo)
+ os.system(neato_cmd)
+ plot_cmd = self.dot
+ else:
+ self.save_dot(self.temp_dot)
+ plot_cmd = self.dot
+
+ file_name = "%s.%s" % (file_name, file_type)
+ create_cmd = "%s -T%s %s -o %s" % (plot_cmd, file_type, self.temp_dot, file_name)
+ os.system(create_cmd)
diff --git a/altgraph/Graph.py b/altgraph/Graph.py
new file mode 100644
index 0000000..491e5c2
--- /dev/null
+++ b/altgraph/Graph.py
@@ -0,0 +1,677 @@
+"""
+altgraph.Graph - Base Graph class
+=================================
+
+..
+ #--Version 2.1
+ #--Bob Ippolito October, 2004
+
+ #--Version 2.0
+ #--Istvan Albert June, 2004
+
+ #--Version 1.0
+ #--Nathan Denny, May 27, 1999
+"""
+
+from altgraph import GraphError
+from collections import deque
+
+class Graph(object):
+ """
+ The Graph class represents a directed graph with *N* nodes and *E* edges.
+
+ Naming conventions:
+
+ - the prefixes such as *out*, *inc* and *all* will refer to methods
+ that operate on the outgoing, incoming or all edges of that node.
+
+ For example: :py:meth:`inc_degree` will refer to the degree of the node
+ computed over the incoming edges (the number of neighbours linking to
+ the node).
+
+ - the prefixes such as *forw* and *back* will refer to the
+ orientation of the edges used in the method with respect to the node.
+
+ For example: :py:meth:`forw_bfs` will start at the node then use the outgoing
+ edges to traverse the graph (goes forward).
+ """
+
+ def __init__(self, edges=None):
+ """
+ Initialization
+ """
+
+ self.next_edge = 0
+ self.nodes, self.edges = {}, {}
+ self.hidden_edges, self.hidden_nodes = {}, {}
+
+ if edges is not None:
+ for item in edges:
+ if len(item) == 2:
+ head, tail = item
+ self.add_edge(head, tail)
+ elif len(item) == 3:
+ head, tail, data = item
+ self.add_edge(head, tail, data)
+ else:
+ raise GraphError("Cannot create edge from %s"%(item,))
+
+
+ def __repr__(self):
+ return '<Graph: %d nodes, %d edges>' % (
+ self.number_of_nodes(), self.number_of_edges())
+
+ def add_node(self, node, node_data=None):
+ """
+ Adds a new node to the graph. Arbitrary data can be attached to the
+ node via the node_data parameter. Adding the same node twice will be
+ silently ignored.
+
+ The node must be a hashable value.
+ """
+ #
+ # the nodes will contain tuples that will store incoming edges,
+ # outgoing edges and data
+ #
+ # index 0 -> incoming edges
+ # index 1 -> outgoing edges
+
+ if node in self.hidden_nodes:
+ # Node is present, but hidden
+ return
+
+ if node not in self.nodes:
+ self.nodes[node] = ([], [], node_data)
+
+ def add_edge(self, head_id, tail_id, edge_data=1, create_nodes=True):
+ """
+ Adds a directed edge going from head_id to tail_id.
+ Arbitrary data can be attached to the edge via edge_data.
+ It may create the nodes if adding edges between nonexisting ones.
+
+ :param head_id: head node
+ :param tail_id: tail node
+ :param edge_data: (optional) data attached to the edge
+ :param create_nodes: (optional) creates the head_id or tail_id node in case they did not exist
+ """
+ # shorcut
+ edge = self.next_edge
+
+ # add nodes if on automatic node creation
+ if create_nodes:
+ self.add_node(head_id)
+ self.add_node(tail_id)
+
+ # update the corresponding incoming and outgoing lists in the nodes
+ # index 0 -> incoming edges
+ # index 1 -> outgoing edges
+
+ try:
+ self.nodes[tail_id][0].append(edge)
+ self.nodes[head_id][1].append(edge)
+ except KeyError:
+ raise GraphError('Invalid nodes %s -> %s' % (head_id, tail_id))
+
+ # store edge information
+ self.edges[edge] = (head_id, tail_id, edge_data)
+
+
+ self.next_edge += 1
+
+ def hide_edge(self, edge):
+ """
+ Hides an edge from the graph. The edge may be unhidden at some later
+ time.
+ """
+ try:
+ head_id, tail_id, edge_data = self.hidden_edges[edge] = self.edges[edge]
+ self.nodes[tail_id][0].remove(edge)
+ self.nodes[head_id][1].remove(edge)
+ del self.edges[edge]
+ except KeyError:
+ raise GraphError('Invalid edge %s' % edge)
+
+ def hide_node(self, node):
+ """
+ Hides a node from the graph. The incoming and outgoing edges of the
+ node will also be hidden. The node may be unhidden at some later time.
+ """
+ try:
+ all_edges = self.all_edges(node)
+ self.hidden_nodes[node] = (self.nodes[node], all_edges)
+ for edge in all_edges:
+ self.hide_edge(edge)
+ del self.nodes[node]
+ except KeyError:
+ raise GraphError('Invalid node %s' % node)
+
+ def restore_node(self, node):
+ """
+ Restores a previously hidden node back into the graph and restores
+ all of its incoming and outgoing edges.
+ """
+ try:
+ self.nodes[node], all_edges = self.hidden_nodes[node]
+ for edge in all_edges:
+ self.restore_edge(edge)
+ del self.hidden_nodes[node]
+ except KeyError:
+ raise GraphError('Invalid node %s' % node)
+
+ def restore_edge(self, edge):
+ """
+ Restores a previously hidden edge back into the graph.
+ """
+ try:
+ head_id, tail_id, data = self.hidden_edges[edge]
+ self.nodes[tail_id][0].append(edge)
+ self.nodes[head_id][1].append(edge)
+ self.edges[edge] = head_id, tail_id, data
+ del self.hidden_edges[edge]
+ except KeyError:
+ raise GraphError('Invalid edge %s' % edge)
+
+ def restore_all_edges(self):
+ """
+ Restores all hidden edges.
+ """
+ for edge in list(self.hidden_edges.keys()):
+ try:
+ self.restore_edge(edge)
+ except GraphError:
+ pass
+
+ def restore_all_nodes(self):
+ """
+ Restores all hidden nodes.
+ """
+ for node in list(self.hidden_nodes.keys()):
+ self.restore_node(node)
+
+ def __contains__(self, node):
+ """
+ Test whether a node is in the graph
+ """
+ return node in self.nodes
+
+ def edge_by_id(self, edge):
+ """
+ Returns the edge that connects the head_id and tail_id nodes
+ """
+ try:
+ head, tail, data = self.edges[edge]
+ except KeyError:
+ head, tail = None, None
+ raise GraphError('Invalid edge %s' % edge)
+
+ return (head, tail)
+
+ def edge_by_node(self, head, tail):
+ """
+ Returns the edge that connects the head_id and tail_id nodes
+ """
+ for edge in self.out_edges(head):
+ if self.tail(edge) == tail:
+ return edge
+ return None
+
+ def number_of_nodes(self):
+ """
+ Returns the number of nodes
+ """
+ return len(self.nodes)
+
+ def number_of_edges(self):
+ """
+ Returns the number of edges
+ """
+ return len(self.edges)
+
+ def __iter__(self):
+ """
+ Iterates over all nodes in the graph
+ """
+ return iter(self.nodes)
+
+ def node_list(self):
+ """
+ Return a list of the node ids for all visible nodes in the graph.
+ """
+ return list(self.nodes.keys())
+
+ def edge_list(self):
+ """
+ Returns an iterator for all visible nodes in the graph.
+ """
+ return list(self.edges.keys())
+
+ def number_of_hidden_edges(self):
+ """
+ Returns the number of hidden edges
+ """
+ return len(self.hidden_edges)
+
+ def number_of_hidden_nodes(self):
+ """
+ Returns the number of hidden nodes
+ """
+ return len(self.hidden_nodes)
+
+ def hidden_node_list(self):
+ """
+ Returns the list with the hidden nodes
+ """
+ return list(self.hidden_nodes.keys())
+
+ def hidden_edge_list(self):
+ """
+ Returns a list with the hidden edges
+ """
+ return list(self.hidden_edges.keys())
+
+ def describe_node(self, node):
+ """
+ return node, node data, outgoing edges, incoming edges for node
+ """
+ incoming, outgoing, data = self.nodes[node]
+ return node, data, outgoing, incoming
+
+ def describe_edge(self, edge):
+ """
+ return edge, edge data, head, tail for edge
+ """
+ head, tail, data = self.edges[edge]
+ return edge, data, head, tail
+
+ def node_data(self, node):
+ """
+ Returns the data associated with a node
+ """
+ return self.nodes[node][2]
+
+ def edge_data(self, edge):
+ """
+ Returns the data associated with an edge
+ """
+ return self.edges[edge][2]
+
+ def update_edge_data(self, edge, edge_data):
+ """
+ Replace the edge data for a specific edge
+ """
+ self.edges[edge] = self.edges[edge][0:2] + (edge_data,)
+
+ def head(self, edge):
+ """
+ Returns the node of the head of the edge.
+ """
+ return self.edges[edge][0]
+
+ def tail(self, edge):
+ """
+ Returns node of the tail of the edge.
+ """
+ return self.edges[edge][1]
+
+ def out_nbrs(self, node):
+ """
+ List of nodes connected by outgoing edges
+ """
+ l = [self.tail(n) for n in self.out_edges(node)]
+ return l
+
+ def inc_nbrs(self, node):
+ """
+ List of nodes connected by incoming edges
+ """
+ l = [self.head(n) for n in self.inc_edges(node)]
+ return l
+
+ def all_nbrs(self, node):
+ """
+ List of nodes connected by incoming and outgoing edges
+ """
+ l = dict.fromkeys( self.inc_nbrs(node) + self.out_nbrs(node) )
+ return list(l)
+
+ def out_edges(self, node):
+ """
+ Returns a list of the outgoing edges
+ """
+ try:
+ return list(self.nodes[node][1])
+ except KeyError:
+ raise GraphError('Invalid node %s' % node)
+
+ return None
+
+ def inc_edges(self, node):
+ """
+ Returns a list of the incoming edges
+ """
+ try:
+ return list(self.nodes[node][0])
+ except KeyError:
+ raise GraphError('Invalid node %s' % node)
+
+ return None
+
+ def all_edges(self, node):
+ """
+ Returns a list of incoming and outging edges.
+ """
+ return set(self.inc_edges(node) + self.out_edges(node))
+
+ def out_degree(self, node):
+ """
+ Returns the number of outgoing edges
+ """
+ return len(self.out_edges(node))
+
+ def inc_degree(self, node):
+ """
+ Returns the number of incoming edges
+ """
+ return len(self.inc_edges(node))
+
+ def all_degree(self, node):
+ """
+ The total degree of a node
+ """
+ return self.inc_degree(node) + self.out_degree(node)
+
+ def _topo_sort(self, forward=True):
+ """
+ Topological sort.
+
+ Returns a list of nodes where the successors (based on outgoing and
+ incoming edges selected by the forward parameter) of any given node
+ appear in the sequence after that node.
+ """
+ topo_list = []
+ queue = deque()
+ indeg = {}
+
+ # select the operation that will be performed
+ if forward:
+ get_edges = self.out_edges
+ get_degree = self.inc_degree
+ get_next = self.tail
+ else:
+ get_edges = self.inc_edges
... 5004 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-altgraph.git
More information about the Python-modules-commits
mailing list