Skip to content

Commit f11deac

Browse files
authored
Merge pull request #2431 from AppDaemon/topo-sort
using graphlib.TopologicalSorter
2 parents 1a0ecfa + a8f5653 commit f11deac

File tree

1 file changed

+6
-45
lines changed

1 file changed

+6
-45
lines changed

appdaemon/dependency.py

Lines changed: 6 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import ast
22
import logging
3-
from collections.abc import Generator
3+
from collections.abc import Generator, Mapping
4+
from graphlib import TopologicalSorter
45
from pathlib import Path
56
from typing import Iterable
67

@@ -206,58 +207,18 @@ def find_all_dependents(
206207
return visited
207208

208209

209-
class CircularDependency(Exception):
210-
pass
211-
212-
213-
def topo_sort(graph: dict[str, set[str]]) -> list[str]:
210+
def topo_sort(graph: Mapping[str, set[str]]) -> list[str]:
214211
"""Topological sort
215212
216213
Args:
217214
graph (Mapping[str, set[str]]): Dependency graph
218215
219216
Raises:
220-
CircularDependency: Raised if a cycle is detected
217+
CycleError: Raised if a cycle is detected
221218
222219
Returns:
223220
list[str]: Ordered list of the nodes
224221
"""
225-
visited = list()
226-
stack = list()
227-
rec_stack = set() # Set to track nodes in the current recursion stack
228-
cycle_detected = False # Flag to indicate cycle detection
229-
230-
def _node_gen():
231-
for node, edges in graph.items():
232-
yield node
233-
if edges:
234-
yield from edges
235-
236-
nodes = set(_node_gen())
237-
238-
def visit(node: str):
239-
nonlocal cycle_detected
240-
if node in rec_stack:
241-
cycle_detected = True
242-
return
243-
elif node in visited:
244-
return
245-
246-
visited.append(node)
247-
rec_stack.add(node)
248-
249-
adjacent_nodes = graph.get(node) or set()
250-
for adj_node in adjacent_nodes:
251-
visit(adj_node)
252-
253-
rec_stack.remove(node)
254-
stack.append(node)
255-
256-
for node in nodes:
257-
if node not in visited:
258-
visit(node)
259-
if cycle_detected:
260-
deps = graph[node]
261-
raise CircularDependency(f"Visited {visited} already, but {node} depends on {deps}")
262222

263-
return stack
223+
ts = TopologicalSorter(graph)
224+
return list(ts.static_order())

0 commit comments

Comments
 (0)