From: Mike Bayer Date: Tue, 6 Apr 2010 17:20:31 +0000 (-0400) Subject: - EdgeCollection can now go away X-Git-Tag: rel_0_6_0~45 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=57335697c6a0f629561ed8fe084687a0f847b0c8;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - EdgeCollection can now go away - fix reflection test --- diff --git a/lib/sqlalchemy/topological.py b/lib/sqlalchemy/topological.py index 07b1ba03e4..fbde7c6014 100644 --- a/lib/sqlalchemy/topological.py +++ b/lib/sqlalchemy/topological.py @@ -10,46 +10,26 @@ from sqlalchemy.exc import CircularDependencyError from sqlalchemy import util -__all__ = ['sort'] - -class _EdgeCollection(object): - """A collection of directed edges.""" - - def __init__(self, edges): - self.parent_to_children = util.defaultdict(set) - self.child_to_parents = util.defaultdict(set) - for parentnode, childnode in edges: - self.parent_to_children[parentnode].add(childnode) - self.child_to_parents[childnode].add(parentnode) - - def outgoing(self, node): - return self.parent_to_children[node] - - def incoming(self, node): - return self.child_to_parents[node] - - def __iter__(self): - for parent in self.parent_to_children: - for child in self.outgoing(parent): - yield (parent, child) - - def __repr__(self): - return repr(list(self)) +__all__ = ['sort', 'sort_as_subsets', 'find_cycles'] def sort_as_subsets(tuples, allitems): output = set() todo = set(allitems) - edges = _EdgeCollection(tuples) + + edges = util.defaultdict(set) + for parent, child in tuples: + edges[child].add(parent) + while todo: for node in list(todo): - if not todo.intersection(edges.incoming(node)): + if not todo.intersection(edges[node]): output.add(node) if not output: raise CircularDependencyError( - "Circular dependency detected: cycles: %r all edges: %r" % - (find_cycles(tuples, allitems), edges)) + "Circular dependency detected: cycles: %r all edges: %s" % + (find_cycles(tuples, allitems), _dump_edges(edges, True))) todo.difference_update(output) yield output @@ -68,7 +48,10 @@ def sort(tuples, allitems): def find_cycles(tuples, allitems): # straight from gvr with some mods todo = set(allitems) - edges = _EdgeCollection(tuples) + + edges = util.defaultdict(set) + for parent, child in tuples: + edges[parent].add(child) output = set() @@ -77,7 +60,7 @@ def find_cycles(tuples, allitems): stack = [node] while stack: top = stack[-1] - for node in edges.outgoing(top): + for node in edges[top]: if node in stack: cyc = stack[stack.index(node):] todo.difference_update(cyc) @@ -91,3 +74,14 @@ def find_cycles(tuples, allitems): node = stack.pop() return output +def _dump_edges(edges, reverse): + l = [] + for left in edges: + for right in edges[left]: + if reverse: + l.append((right, left)) + else: + l.append((left, right)) + return repr(l) + + diff --git a/test/engine/test_reflection.py b/test/engine/test_reflection.py index bf94cce657..18074337f2 100644 --- a/test/engine/test_reflection.py +++ b/test/engine/test_reflection.py @@ -742,7 +742,12 @@ class CreateDropTest(TestBase): def test_sorter( self ): tables = metadata.sorted_tables table_names = [t.name for t in tables] - self.assert_( table_names == ['users', 'orders', 'items', 'email_addresses'] or table_names == ['users', 'email_addresses', 'orders', 'items']) + ua = [n for n in table_names if n in ('users', 'email_addresses')] + oi = [n for n in table_names if n in ('orders', 'items')] + + eq_(ua, ['users', 'email_addresses']) + eq_(oi, ['orders', 'items']) + def testcheckfirst(self): try: