def ordered_nodes(graph): """takes a dependency graph dict as arguments and return an ordered tuple of nodes starting with nodes without dependencies and up to the outermost node. If there is some cycle in the graph, :exc:`UnorderableGraph` will be raised. Also the given graph dict will be emptied. """ cycles = get_cycles(graph) if cycles: cycles = '\n'.join([' -> '.join(cycle) for cycle in cycles]) raise UnorderableGraph(cycles) ordered = [] while graph: # sorted to get predictable results for node, deps in sorted(graph.items()): if not deps: ordered.append(node) del graph[node] for deps in graph.itervalues(): try: deps.remove(node) except KeyError: continue return tuple(reversed(ordered))
def test_reversed(self): from logilab.common.compat import reversed l = range(5) r = reversed(l) self.assertEquals(r, [4, 3, 2, 1, 0]) self.assertEquals(l, range(5))