mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-05-16 05:37:16 -04:00
1e278de4cc
Applied on top of a pure run of black -l 79 in I7eda77fed3d8e73df84b3651fd6cfcfe858d4dc9, this set of changes resolves all remaining flake8 conditions for those codes we have enabled in setup.cfg. Included are resolutions for all remaining flake8 issues including shadowed builtins, long lines, import order, unused imports, duplicate imports, and docstring issues. Change-Id: I4f72d3ba1380dd601610ff80b8fb06a2aff8b0fe
374 lines
11 KiB
Python
374 lines
11 KiB
Python
from sqlalchemy import exc
|
|
from sqlalchemy.testing import assert_raises
|
|
from sqlalchemy.testing import eq_
|
|
from sqlalchemy.testing import fixtures
|
|
from sqlalchemy.testing.util import conforms_partial_ordering
|
|
from sqlalchemy.util import topological
|
|
|
|
|
|
class DependencySortTest(fixtures.TestBase):
|
|
def assert_sort(self, tuples, allitems=None):
|
|
if allitems is None:
|
|
allitems = self._nodes_from_tuples(tuples)
|
|
else:
|
|
allitems = self._nodes_from_tuples(tuples).union(allitems)
|
|
result = list(topological.sort(tuples, allitems))
|
|
assert conforms_partial_ordering(tuples, result)
|
|
|
|
def assert_sort_deterministic(self, tuples, allitems, expected):
|
|
result = list(
|
|
topological.sort(tuples, allitems, deterministic_order=True)
|
|
)
|
|
assert conforms_partial_ordering(tuples, result)
|
|
assert result == expected
|
|
|
|
def _nodes_from_tuples(self, tups):
|
|
s = set()
|
|
for tup in tups:
|
|
s.update(tup)
|
|
return s
|
|
|
|
def test_sort_one(self):
|
|
rootnode = "root"
|
|
node2 = "node2"
|
|
node3 = "node3"
|
|
node4 = "node4"
|
|
subnode1 = "subnode1"
|
|
subnode2 = "subnode2"
|
|
subnode3 = "subnode3"
|
|
subnode4 = "subnode4"
|
|
subsubnode1 = "subsubnode1"
|
|
tuples = [
|
|
(subnode3, subsubnode1),
|
|
(node2, subnode1),
|
|
(node2, subnode2),
|
|
(rootnode, node2),
|
|
(rootnode, node3),
|
|
(rootnode, node4),
|
|
(node4, subnode3),
|
|
(node4, subnode4),
|
|
]
|
|
self.assert_sort(tuples)
|
|
|
|
def test_sort_two(self):
|
|
node1 = "node1"
|
|
node2 = "node2"
|
|
node3 = "node3"
|
|
node4 = "node4"
|
|
node5 = "node5"
|
|
node6 = "node6"
|
|
node7 = "node7"
|
|
tuples = [
|
|
(node1, node2),
|
|
(node3, node4),
|
|
(node4, node5),
|
|
(node5, node6),
|
|
(node6, node2),
|
|
]
|
|
self.assert_sort(tuples, [node7])
|
|
|
|
def test_sort_three(self):
|
|
node1 = "keywords"
|
|
node2 = "itemkeyowrds"
|
|
node3 = "items"
|
|
node4 = "hoho"
|
|
tuples = [
|
|
(node1, node2),
|
|
(node4, node1),
|
|
(node1, node3),
|
|
(node3, node2),
|
|
]
|
|
self.assert_sort(tuples)
|
|
|
|
def test_sort_deterministic_one(self):
|
|
node1 = "node1"
|
|
node2 = "node2"
|
|
node3 = "node3"
|
|
node4 = "node4"
|
|
node5 = "node5"
|
|
node6 = "node6"
|
|
allitems = [node6, node5, node4, node3, node2, node1]
|
|
tuples = [(node6, node5), (node2, node1)]
|
|
expected = [node6, node4, node3, node2, node5, node1]
|
|
self.assert_sort_deterministic(tuples, allitems, expected)
|
|
|
|
def test_sort_deterministic_two(self):
|
|
node1 = 1
|
|
node2 = 2
|
|
node3 = 3
|
|
node4 = 4
|
|
node5 = 5
|
|
node6 = 6
|
|
allitems = [node6, node5, node4, node3, node2, node1]
|
|
tuples = [(node6, node5), (node4, node3), (node2, node1)]
|
|
expected = [node6, node4, node2, node5, node3, node1]
|
|
self.assert_sort_deterministic(tuples, allitems, expected)
|
|
|
|
def test_raise_on_cycle_one(self):
|
|
node1 = "node1"
|
|
node2 = "node2"
|
|
node3 = "node3"
|
|
node4 = "node4"
|
|
node5 = "node5"
|
|
tuples = [
|
|
(node4, node5),
|
|
(node5, node4),
|
|
(node1, node2),
|
|
(node2, node3),
|
|
(node3, node1),
|
|
(node4, node1),
|
|
]
|
|
allitems = self._nodes_from_tuples(tuples)
|
|
|
|
try:
|
|
list(topological.sort(tuples, allitems))
|
|
assert False
|
|
except exc.CircularDependencyError as err:
|
|
eq_(err.cycles, set(["node1", "node3", "node2", "node5", "node4"]))
|
|
eq_(
|
|
err.edges,
|
|
set(
|
|
[
|
|
("node3", "node1"),
|
|
("node4", "node1"),
|
|
("node2", "node3"),
|
|
("node1", "node2"),
|
|
("node4", "node5"),
|
|
("node5", "node4"),
|
|
]
|
|
),
|
|
)
|
|
|
|
def test_raise_on_cycle_two(self):
|
|
|
|
# this condition was arising from ticket:362 and was not treated
|
|
# properly by topological sort
|
|
|
|
node1 = "node1"
|
|
node2 = "node2"
|
|
node3 = "node3"
|
|
node4 = "node4"
|
|
tuples = [
|
|
(node1, node2),
|
|
(node3, node1),
|
|
(node2, node4),
|
|
(node3, node2),
|
|
(node2, node3),
|
|
]
|
|
allitems = self._nodes_from_tuples(tuples)
|
|
|
|
try:
|
|
list(topological.sort(tuples, allitems))
|
|
assert False
|
|
except exc.CircularDependencyError as err:
|
|
eq_(err.cycles, set(["node1", "node3", "node2"]))
|
|
eq_(
|
|
err.edges,
|
|
set(
|
|
[
|
|
("node3", "node1"),
|
|
("node2", "node3"),
|
|
("node3", "node2"),
|
|
("node1", "node2"),
|
|
("node2", "node4"),
|
|
]
|
|
),
|
|
)
|
|
|
|
def test_raise_on_cycle_three(self):
|
|
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),
|
|
]
|
|
allitems = self._nodes_from_tuples(tuples)
|
|
assert_raises(
|
|
exc.CircularDependencyError,
|
|
list,
|
|
topological.sort(tuples, allitems),
|
|
)
|
|
|
|
# TODO: test find_cycles
|
|
|
|
def test_large_sort(self):
|
|
tuples = [(i, i + 1) for i in range(0, 1500, 2)]
|
|
self.assert_sort(tuples)
|
|
|
|
def test_ticket_1380(self):
|
|
|
|
# ticket:1380 regression: would raise a KeyError
|
|
|
|
tuples = [(id(i), i) for i in range(3)]
|
|
self.assert_sort(tuples)
|
|
|
|
def test_find_cycle_one(self):
|
|
node1 = "node1"
|
|
node2 = "node2"
|
|
node3 = "node3"
|
|
node4 = "node4"
|
|
tuples = [
|
|
(node1, node2),
|
|
(node3, node1),
|
|
(node2, node4),
|
|
(node3, node2),
|
|
(node2, node3),
|
|
]
|
|
eq_(
|
|
topological.find_cycles(tuples, self._nodes_from_tuples(tuples)),
|
|
set([node1, node2, node3]),
|
|
)
|
|
|
|
def test_find_multiple_cycles_one(self):
|
|
node1 = "node1"
|
|
node2 = "node2"
|
|
node3 = "node3"
|
|
node4 = "node4"
|
|
node5 = "node5"
|
|
node6 = "node6"
|
|
node7 = "node7"
|
|
node8 = "node8"
|
|
node9 = "node9"
|
|
tuples = [ # cycle 1 cycle 2 cycle 3 cycle 4, but only if cycle
|
|
# 1 nodes are present
|
|
(node1, node2),
|
|
(node2, node4),
|
|
(node4, node1),
|
|
(node9, node9),
|
|
(node7, node5),
|
|
(node5, node7),
|
|
(node1, node6),
|
|
(node6, node8),
|
|
(node8, node4),
|
|
(node3, node1),
|
|
(node3, node2),
|
|
]
|
|
allnodes = set(
|
|
[node1, node2, node3, node4, node5, node6, node7, node8, node9]
|
|
)
|
|
eq_(
|
|
topological.find_cycles(tuples, allnodes),
|
|
set(
|
|
[
|
|
"node8",
|
|
"node1",
|
|
"node2",
|
|
"node5",
|
|
"node4",
|
|
"node7",
|
|
"node6",
|
|
"node9",
|
|
]
|
|
),
|
|
)
|
|
|
|
def test_find_multiple_cycles_two(self):
|
|
node1 = "node1"
|
|
node2 = "node2"
|
|
node3 = "node3"
|
|
node4 = "node4"
|
|
node5 = "node5"
|
|
node6 = "node6"
|
|
tuples = [ # cycle 1 cycle 2
|
|
(node1, node2),
|
|
(node2, node4),
|
|
(node4, node1),
|
|
(node1, node6),
|
|
(node6, node2),
|
|
(node2, node4),
|
|
(node4, node1),
|
|
]
|
|
allnodes = set([node1, node2, node3, node4, node5, node6])
|
|
# node6 only became present here once [ticket:2282] was addressed.
|
|
eq_(
|
|
topological.find_cycles(tuples, allnodes),
|
|
set(["node1", "node2", "node4", "node6"]),
|
|
)
|
|
|
|
def test_find_multiple_cycles_three(self):
|
|
node1 = "node1"
|
|
node2 = "node2"
|
|
node3 = "node3"
|
|
node4 = "node4"
|
|
node5 = "node5"
|
|
node6 = "node6"
|
|
tuples = [ # cycle 1 cycle 2 cycle3 cycle4
|
|
(node1, node2),
|
|
(node2, node1),
|
|
(node2, node3),
|
|
(node3, node2),
|
|
(node2, node4),
|
|
(node4, node2),
|
|
(node2, node5),
|
|
(node5, node6),
|
|
(node6, node2),
|
|
]
|
|
allnodes = set([node1, node2, node3, node4, node5, node6])
|
|
eq_(topological.find_cycles(tuples, allnodes), allnodes)
|
|
|
|
def test_find_multiple_cycles_four(self):
|
|
tuples = [
|
|
("node6", "node2"),
|
|
("node15", "node19"),
|
|
("node19", "node2"),
|
|
("node4", "node10"),
|
|
("node15", "node13"),
|
|
("node17", "node11"),
|
|
("node1", "node19"),
|
|
("node15", "node8"),
|
|
("node6", "node20"),
|
|
("node14", "node11"),
|
|
("node6", "node14"),
|
|
("node11", "node2"),
|
|
("node10", "node20"),
|
|
("node1", "node11"),
|
|
("node20", "node19"),
|
|
("node4", "node20"),
|
|
("node15", "node20"),
|
|
("node9", "node19"),
|
|
("node11", "node10"),
|
|
("node11", "node19"),
|
|
("node13", "node6"),
|
|
("node3", "node15"),
|
|
("node9", "node11"),
|
|
("node4", "node17"),
|
|
("node2", "node20"),
|
|
("node19", "node10"),
|
|
("node8", "node4"),
|
|
("node11", "node3"),
|
|
("node6", "node1"),
|
|
]
|
|
allnodes = ["node%d" % i for i in range(1, 21)]
|
|
eq_(
|
|
topological.find_cycles(tuples, allnodes),
|
|
set(
|
|
[
|
|
"node11",
|
|
"node10",
|
|
"node13",
|
|
"node15",
|
|
"node14",
|
|
"node17",
|
|
"node19",
|
|
"node20",
|
|
"node8",
|
|
"node1",
|
|
"node3",
|
|
"node2",
|
|
"node4",
|
|
"node6",
|
|
]
|
|
),
|
|
)
|