def test_klass_hierarchy(self): from traits.util.toposort import topological_sort from pgv.red.api import PythonNamespace namespace = PythonNamespace() package = namespace.lookup("quickblocks") def harvest_klasses(node): """ Recursively harvest all klasses from the given node. """ klasses = [] for child in node.children: if isinstance(child, Klass): klasses.append(child) klasses.extend(harvest_klasses(child)) return klasses klasses = harvest_klasses(package) # Build a dependency graph. graph = {} for klass in klasses: arcs = graph.setdefault(klass, []) # print 'Klass', klass.name, klass.module.filename arcs.extend(klass.bases) x = topological_sort(graph) print x return
def get_distributions_in_egg_order(working_set, distributions=None): """ Return all distributions in Egg dependency order. """ # If no specific list of distributions is specified then use all # distributions in the working set. if distributions is None: distributions = working_set # Build a dependency graph. graph = {} for distribution in distributions: arcs = graph.setdefault(distribution, []) arcs.extend(get_requires(working_set, distribution)) distributions = topological_sort(graph) distributions.reverse() return distributions
def closure(graph, sorted=True): """ Returns the transitive closure of the graph. If sorted is True then the successor nodes will be sorted into topological order. """ order = topological_sort(graph) # Map nodes to their index in the topologically sorted list for later use. idxorder = {} for i, obj in enumerate(order): idxorder[obj] = i reachable = {} for i in range(len(order) - 1, -1, -1): node = order[i] # We are going through in reverse topological order so we # are guaranteed that all of the children of the node # are already in reachable # We are using dicts to emulate sets for speed in Python 2.3. node_reachable = {} for child in graph.get(node, []): node_reachable[child] = 1 node_reachable.update(reachable[child]) reachable[node] = node_reachable # Now, build the return graph by doing a topological sort of # each reachable set, if required retval = {} for node, node_reachable in reachable.items(): if not sorted: retval[node] = node_reachable.keys() else: # Create a tuple list so the faster built-in sort # comparator can be used. tmp = [] reachable_list = node_reachable.keys() for n in reachable_list: tmp.append((idxorder[n], n)) tmp.sort() reachable_list = [x[1] for x in tmp] retval[node] = reachable_list return retval
def closure(graph, sorted=True): """ Returns the transitive closure of the graph. If sorted is True then the successor nodes will be sorted into topological order. """ order = topological_sort(graph) # Map nodes to their index in the topologically sorted list for later use. idxorder = {} for i, obj in enumerate(order): idxorder[obj] = i reachable = {} for i in range(len(order)-1, -1, -1): node = order[i] # We are going through in reverse topological order so we # are guaranteed that all of the children of the node # are already in reachable # We are using dicts to emulate sets for speed in Python 2.3. node_reachable = {} for child in graph.get(node, []): node_reachable[child] = 1 node_reachable.update(reachable[child]) reachable[node] = node_reachable # Now, build the return graph by doing a topological sort of # each reachable set, if required retval = {} for node, node_reachable in reachable.items(): if not sorted: retval[node] = list(node_reachable.keys()) else: # Create a tuple list so the faster built-in sort # comparator can be used. tmp = [] reachable_list = list(node_reachable.keys()) for n in reachable_list: tmp.append((idxorder[n], n)) tmp.sort() reachable_list = [x[1] for x in tmp] retval[node] = reachable_list return retval
# FIXME Implement graphs with sets of values instead of lists of values def eq(g1, g2): return map_values(set, g1) == map_values(set, g2) def reachable_graph(graph, nodes): ''' Return the subgraph of the given graph reachable from the given nodes. >>> reachable_graph({'a':'bc', 'b':'c' }, 'a') {'a': 'bc', 'b': 'c'} >>> reachable_graph({'a':'bc', 'b':'c' }, 'b') {'b': 'c'} >>> reachable_graph({'a':'bc', 'b':'c' }, 'c') {} ''' ret = {} closed = closure(graph) for n in chain(nodes, flatten([closed[n] for n in nodes])): if n in graph.keys(): ret[n] = graph[n] return ret if __name__ == "__main__": g = {1: [2, 3], 2: [3, 4], 6: [3], 4: [6]} print topological_sort(g) print closure(g) #### EOF ######################################################################
# FIXME Implement graphs with sets of values instead of lists of values def eq(g1, g2): return map_values(set, g1) == map_values(set, g2) def reachable_graph(graph, nodes): ''' Return the subgraph of the given graph reachable from the given nodes. >>> sorted(reachable_graph({'a':'bc', 'b':'c' }, 'a').items()) [('a', 'bc'), ('b', 'c')] >>> reachable_graph({'a':'bc', 'b':'c' }, 'b') {'b': 'c'} >>> reachable_graph({'a':'bc', 'b':'c' }, 'c') {} ''' ret = {} closed = closure(graph) for n in chain(nodes, flatten([closed[n] for n in nodes])): if n in list(graph.keys()): ret[n] = graph[n] return ret if __name__ == "__main__": g = {1: [2, 3], 2: [3, 4], 6: [3], 4: [6]} print((topological_sort(g))) print((closure(g))) #### EOF ######################################################################
# FIXME Implement graphs with sets of values instead of lists of values def eq(g1, g2): return map_values(set, g1) == map_values(set, g2) def reachable_graph(graph, nodes): ''' Return the subgraph of the given graph reachable from the given nodes. >>> sorted(reachable_graph({'a':'bc', 'b':'c' }, 'a').items()) [('a', 'bc'), ('b', 'c')] >>> reachable_graph({'a':'bc', 'b':'c' }, 'b') {'b': 'c'} >>> reachable_graph({'a':'bc', 'b':'c' }, 'c') {} ''' ret = {} closed = closure(graph) for n in chain(nodes, flatten([ closed[n] for n in nodes ])): if n in list(graph.keys()): ret[n] = graph[n] return ret if __name__ == "__main__": g = {1:[2,3], 2:[3,4], 6:[3], 4:[6]} print((topological_sort(g))) print((closure(g))) #### EOF ######################################################################
# FIXME Implement graphs with sets of values instead of lists of values def eq(g1, g2): return map_values(set, g1) == map_values(set, g2) def reachable_graph(graph, nodes): ''' Return the subgraph of the given graph reachable from the given nodes. >>> reachable_graph({'a':'bc', 'b':'c' }, 'a') {'a': 'bc', 'b': 'c'} >>> reachable_graph({'a':'bc', 'b':'c' }, 'b') {'b': 'c'} >>> reachable_graph({'a':'bc', 'b':'c' }, 'c') {} ''' ret = {} closed = closure(graph) for n in chain(nodes, flatten([ closed[n] for n in nodes ])): if n in graph.keys(): ret[n] = graph[n] return ret if __name__ == "__main__": g = {1:[2,3], 2:[3,4], 6:[3], 4:[6]} print topological_sort(g) print closure(g) #### EOF ######################################################################