MCPcopy
hub / github.com/sqlalchemy/sqlalchemy / find_cycles

Function find_cycles

lib/sqlalchemy/util/topological.py:77–116  ·  view source on GitHub ↗
(
    tuples: Iterable[Tuple[_T, _T]], allitems: Iterable[_T]
)

Source from the content-addressed store, hash-verified

75
76
77def find_cycles(
78 tuples: Iterable[Tuple[_T, _T]], allitems: Iterable[_T]
79) -> Set[_T]:
80 # adapted from:
81 # https://neopythonic.blogspot.com/2009/01/detecting-cycles-in-directed-graph.html
82
83 edges: DefaultDict[_T, Set[_T]] = util.defaultdict(set)
84 for parent, child in tuples:
85 edges[parent].add(child)
86 nodes_to_test = set(edges)
87
88 output = set()
89
90 # we'd like to find all nodes that are
91 # involved in cycles, so we do the full
92 # pass through the whole thing for each
93 # node in the original list.
94
95 # we can go just through parent edge nodes.
96 # if a node is only a child and never a parent,
97 # by definition it can't be part of a cycle. same
98 # if it's not in the edges at all.
99 for node in nodes_to_test:
100 stack = [node]
101 todo = nodes_to_test.difference(stack)
102 while stack:
103 top = stack[-1]
104 for node in edges[top]:
105 if node in stack:
106 cyc = stack[stack.index(node) :]
107 todo.difference_update(cyc)
108 output.update(cyc)
109
110 if node in todo:
111 stack.append(node)
112 todo.remove(node)
113 break
114 else:
115 stack.pop()
116 return output
117
118
119def _gen_edges(edges: DefaultDict[_T, Set[_T]]) -> Set[Tuple[_T, _T]]:

Callers 1

sort_as_subsetsFunction · 0.85

Calls 8

indexMethod · 0.80
addMethod · 0.45
differenceMethod · 0.45
difference_updateMethod · 0.45
updateMethod · 0.45
appendMethod · 0.45
removeMethod · 0.45
popMethod · 0.45

Tested by

no test coverage detected