From: Mike Bayer Date: Sun, 31 May 2009 21:41:20 +0000 (+0000) Subject: - some topological fixup to work around inconsistent string interning in py3k X-Git-Tag: rel_0_6_6~184 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a21750c6e4f7d922556c679eed9e0b5ae140856a;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - some topological fixup to work around inconsistent string interning in py3k - pg8000 in py3k needs description_encoding, turn this back on, switch off for py3k sqlite --- diff --git a/lib/sqlalchemy/dialects/sqlite/pysqlite.py b/lib/sqlalchemy/dialects/sqlite/pysqlite.py index 13e5c16f5c..0eb4e9ede5 100644 --- a/lib/sqlalchemy/dialects/sqlite/pysqlite.py +++ b/lib/sqlalchemy/dialects/sqlite/pysqlite.py @@ -121,6 +121,10 @@ class SQLite_pysqlite(SQLiteDialect): default_paramstyle = 'qmark' poolclass = pool.SingletonThreadPool execution_ctx_cls = SQLite_pysqliteExecutionContext + + # Py3K + #description_encoding = None + driver = 'pysqlite' def __init__(self, **kwargs): diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index 9cae28f450..7d2ab0a12a 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -1605,11 +1605,8 @@ class ResultProxy(object): for i, item in enumerate(metadata): colname = item[0] - # Py3K - # Py2K if self.dialect.description_encoding: colname = colname.decode(self.dialect.description_encoding) - # end Py2K if '.' in colname: # sqlite will in some circumstances prepend table name to colnames, so strip diff --git a/lib/sqlalchemy/topological.py b/lib/sqlalchemy/topological.py index 77945b173c..fbdb17963b 100644 --- a/lib/sqlalchemy/topological.py +++ b/lib/sqlalchemy/topological.py @@ -19,6 +19,7 @@ conditions. """ from sqlalchemy.exc import CircularDependencyError +from sqlalchemy import util __all__ = ['sort', 'sort_with_cycles', 'sort_as_tree'] @@ -93,18 +94,14 @@ class _EdgeCollection(object): """A collection of directed edges.""" def __init__(self): - self.parent_to_children = {} - self.child_to_parents = {} + self.parent_to_children = util.defaultdict(set) + self.child_to_parents = util.defaultdict(set) def add(self, edge): """Add an edge to this collection.""" - (parentnode, childnode) = edge - if parentnode not in self.parent_to_children: - self.parent_to_children[parentnode] = set() + parentnode, childnode = edge self.parent_to_children[parentnode].add(childnode) - if childnode not in self.child_to_parents: - self.child_to_parents[childnode] = set() self.child_to_parents[childnode].add(parentnode) parentnode.dependencies.add(childnode) @@ -117,13 +114,13 @@ class _EdgeCollection(object): (parentnode, childnode) = edge self.parent_to_children[parentnode].remove(childnode) self.child_to_parents[childnode].remove(parentnode) - if len(self.child_to_parents[childnode]) == 0: + if not self.child_to_parents[childnode]: return childnode else: return None def has_parents(self, node): - return node in self.child_to_parents and len(self.child_to_parents[node]) > 0 + return node in self.child_to_parents and bool(self.child_to_parents[node]) def edges_by_parent(self, node): if node in self.parent_to_children: @@ -166,11 +163,10 @@ def _sort(tuples, allitems, allow_cycles=False, ignore_self_cycles=False): for item in list(allitems) + [t[0] for t in tuples] + [t[1] for t in tuples]: item_id = id(item) if item_id not in nodes: - node = _Node(item) - nodes[item_id] = node + nodes[item_id] = _Node(item) for t in tuples: - id0 = id(t[0]) + id0, id1 = id(t[0]), id(t[1]) if t[0] is t[1]: if allow_cycles: n = nodes[id0] @@ -178,7 +174,7 @@ def _sort(tuples, allitems, allow_cycles=False, ignore_self_cycles=False): elif not ignore_self_cycles: raise CircularDependencyError("Self-referential dependency detected " + repr(t)) continue - childnode = nodes[id(t[1])] + childnode = nodes[id1] parentnode = nodes[id0] edges.add((parentnode, childnode)) @@ -298,8 +294,8 @@ def _find_cycles(edges): for parent in edges.get_parents(): traverse(parent) - # sets are not hashable, so uniquify with id - unique_cycles = dict((id(s), s) for s in cycles.values()).values() + unique_cycles = set(tuple(s) for s in cycles.values()) + for cycle in unique_cycles: edgecollection = [edge for edge in edges if edge[0] in cycle and edge[1] in cycle] diff --git a/test/base/dependency.py b/test/base/dependency.py index ca6b4b42e2..c4d97f8d88 100644 --- a/test/base/dependency.py +++ b/test/base/dependency.py @@ -24,16 +24,16 @@ class DependencySortTest(TestBase): assert_tuple(list(tuple), node) if collection is None: - collection = [] + collection = set() items = set() - def assert_unique(node): - for item in [i for i in node[1] or [node[0]]]: - assert item not in items, str(node) + def assert_unique(n): + for item in [i for i in n[1] or [n[0]]]: + assert item not in items, node items.add(item) if item in collection: collection.remove(item) - for c in node[2]: - assert_unique(c) + for item in n[2]: + assert_unique(item) assert_unique(node) assert len(collection) == 0 @@ -171,8 +171,10 @@ class DependencySortTest(TestBase): self.assert_sort(tuples, head) def testcircular3(self): - nodes = {} - tuples = [('Question', 'Issue'), ('ProviderService', 'Issue'), ('Provider', 'Question'), ('Question', 'Provider'), ('ProviderService', 'Question'), ('Provider', 'ProviderService'), ('Question', 'Answer'), ('Issue', 'Question')] + question, issue, providerservice, answer, provider = "Question", "Issue", "ProviderService", "Answer", "Provider" + + tuples = [(question, issue), (providerservice, issue), (provider, question), (question, provider), (providerservice, question), (provider, providerservice), (question, answer), (issue, question)] + head = topological.sort_as_tree(tuples, [], with_cycles=True) self.assert_sort(tuples, head)