Add vendored packages back
This commit is contained in:
committed by
Todd Gamblin
parent
5175189412
commit
033cb86fd6
212
lib/spack/external/_vendoring/altgraph/ObjectGraph.py
vendored
Normal file
212
lib/spack/external/_vendoring/altgraph/ObjectGraph.py
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
"""
|
||||
altgraph.ObjectGraph - Graph of objects with an identifier
|
||||
==========================================================
|
||||
|
||||
A graph of objects that have a "graphident" attribute.
|
||||
graphident is the key for the object in the graph
|
||||
"""
|
||||
|
||||
from altgraph import GraphError
|
||||
from altgraph.Graph import Graph
|
||||
from altgraph.GraphUtil import filter_stack
|
||||
|
||||
|
||||
class ObjectGraph(object):
|
||||
"""
|
||||
A graph of objects that have a "graphident" attribute.
|
||||
graphident is the key for the object in the graph
|
||||
"""
|
||||
|
||||
def __init__(self, graph=None, debug=0):
|
||||
if graph is None:
|
||||
graph = Graph()
|
||||
self.graphident = self
|
||||
self.graph = graph
|
||||
self.debug = debug
|
||||
self.indent = 0
|
||||
graph.add_node(self, None)
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s>" % (type(self).__name__,)
|
||||
|
||||
def flatten(self, condition=None, start=None):
|
||||
"""
|
||||
Iterate over the subgraph that is entirely reachable by condition
|
||||
starting from the given start node or the ObjectGraph root
|
||||
"""
|
||||
if start is None:
|
||||
start = self
|
||||
start = self.getRawIdent(start)
|
||||
return self.graph.iterdata(start=start, condition=condition)
|
||||
|
||||
def nodes(self):
|
||||
for ident in self.graph:
|
||||
node = self.graph.node_data(ident)
|
||||
if node is not None:
|
||||
yield self.graph.node_data(ident)
|
||||
|
||||
def get_edges(self, node):
|
||||
if node is None:
|
||||
node = self
|
||||
start = self.getRawIdent(node)
|
||||
_, _, outraw, incraw = self.graph.describe_node(start)
|
||||
|
||||
def iter_edges(lst, n):
|
||||
seen = set()
|
||||
for tpl in (self.graph.describe_edge(e) for e in lst):
|
||||
ident = tpl[n]
|
||||
if ident not in seen:
|
||||
yield self.findNode(ident)
|
||||
seen.add(ident)
|
||||
|
||||
return iter_edges(outraw, 3), iter_edges(incraw, 2)
|
||||
|
||||
def edgeData(self, fromNode, toNode):
|
||||
if fromNode is None:
|
||||
fromNode = self
|
||||
start = self.getRawIdent(fromNode)
|
||||
stop = self.getRawIdent(toNode)
|
||||
edge = self.graph.edge_by_node(start, stop)
|
||||
return self.graph.edge_data(edge)
|
||||
|
||||
def updateEdgeData(self, fromNode, toNode, edgeData):
|
||||
if fromNode is None:
|
||||
fromNode = self
|
||||
start = self.getRawIdent(fromNode)
|
||||
stop = self.getRawIdent(toNode)
|
||||
edge = self.graph.edge_by_node(start, stop)
|
||||
self.graph.update_edge_data(edge, edgeData)
|
||||
|
||||
def filterStack(self, filters):
|
||||
"""
|
||||
Filter the ObjectGraph in-place by removing all edges to nodes that
|
||||
do not match every filter in the given filter list
|
||||
|
||||
Returns a tuple containing the number of:
|
||||
(nodes_visited, nodes_removed, nodes_orphaned)
|
||||
"""
|
||||
visited, removes, orphans = filter_stack(self.graph, self, filters)
|
||||
|
||||
for last_good, tail in orphans:
|
||||
self.graph.add_edge(last_good, tail, edge_data="orphan")
|
||||
|
||||
for node in removes:
|
||||
self.graph.hide_node(node)
|
||||
|
||||
return len(visited) - 1, len(removes), len(orphans)
|
||||
|
||||
def removeNode(self, node):
|
||||
"""
|
||||
Remove the given node from the graph if it exists
|
||||
"""
|
||||
ident = self.getIdent(node)
|
||||
if ident is not None:
|
||||
self.graph.hide_node(ident)
|
||||
|
||||
def removeReference(self, fromnode, tonode):
|
||||
"""
|
||||
Remove all edges from fromnode to tonode
|
||||
"""
|
||||
if fromnode is None:
|
||||
fromnode = self
|
||||
fromident = self.getIdent(fromnode)
|
||||
toident = self.getIdent(tonode)
|
||||
if fromident is not None and toident is not None:
|
||||
while True:
|
||||
edge = self.graph.edge_by_node(fromident, toident)
|
||||
if edge is None:
|
||||
break
|
||||
self.graph.hide_edge(edge)
|
||||
|
||||
def getIdent(self, node):
|
||||
"""
|
||||
Get the graph identifier for a node
|
||||
"""
|
||||
ident = self.getRawIdent(node)
|
||||
if ident is not None:
|
||||
return ident
|
||||
node = self.findNode(node)
|
||||
if node is None:
|
||||
return None
|
||||
return node.graphident
|
||||
|
||||
def getRawIdent(self, node):
|
||||
"""
|
||||
Get the identifier for a node object
|
||||
"""
|
||||
if node is self:
|
||||
return node
|
||||
ident = getattr(node, "graphident", None)
|
||||
return ident
|
||||
|
||||
def __contains__(self, node):
|
||||
return self.findNode(node) is not None
|
||||
|
||||
def findNode(self, node):
|
||||
"""
|
||||
Find the node on the graph
|
||||
"""
|
||||
ident = self.getRawIdent(node)
|
||||
if ident is None:
|
||||
ident = node
|
||||
try:
|
||||
return self.graph.node_data(ident)
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
def addNode(self, node):
|
||||
"""
|
||||
Add a node to the graph referenced by the root
|
||||
"""
|
||||
self.msg(4, "addNode", node)
|
||||
|
||||
try:
|
||||
self.graph.restore_node(node.graphident)
|
||||
except GraphError:
|
||||
self.graph.add_node(node.graphident, node)
|
||||
|
||||
def createReference(self, fromnode, tonode, edge_data=None):
|
||||
"""
|
||||
Create a reference from fromnode to tonode
|
||||
"""
|
||||
if fromnode is None:
|
||||
fromnode = self
|
||||
fromident, toident = self.getIdent(fromnode), self.getIdent(tonode)
|
||||
if fromident is None or toident is None:
|
||||
return
|
||||
self.msg(4, "createReference", fromnode, tonode, edge_data)
|
||||
self.graph.add_edge(fromident, toident, edge_data=edge_data)
|
||||
|
||||
def createNode(self, cls, name, *args, **kw):
|
||||
"""
|
||||
Add a node of type cls to the graph if it does not already exist
|
||||
by the given name
|
||||
"""
|
||||
m = self.findNode(name)
|
||||
if m is None:
|
||||
m = cls(name, *args, **kw)
|
||||
self.addNode(m)
|
||||
return m
|
||||
|
||||
def msg(self, level, s, *args):
|
||||
"""
|
||||
Print a debug message with the given level
|
||||
"""
|
||||
if s and level <= self.debug:
|
||||
print("%s%s %s" % (" " * self.indent, s, " ".join(map(repr, args))))
|
||||
|
||||
def msgin(self, level, s, *args):
|
||||
"""
|
||||
Print a debug message and indent
|
||||
"""
|
||||
if level <= self.debug:
|
||||
self.msg(level, s, *args)
|
||||
self.indent = self.indent + 1
|
||||
|
||||
def msgout(self, level, s, *args):
|
||||
"""
|
||||
Dedent and print a debug message
|
||||
"""
|
||||
if level <= self.debug:
|
||||
self.indent = self.indent - 1
|
||||
self.msg(level, s, *args)
|
||||
Reference in New Issue
Block a user