@@ -11,6 +11,23 @@ class NodeType(Enum):
1111 TASK = 2
1212
1313
14+ class CycleFoundException (Exception ):
15+ """Raised when there is a cycle when drawing the call tree."""
16+
17+ def __init__ (self , cycles , id2name ):
18+ super ().__init__ ()
19+ self .cycles = cycles
20+ self .id2name = id2name
21+
22+ def __str__ (self ):
23+ for c in self .cycles :
24+ names = " → " .join (self .id2name .get (tid , hex (tid )) for tid in c )
25+ return (
26+ "ERROR: await-graph contains cycles – cannot print a tree!\n "
27+ f"cycle: { names } "
28+ )
29+
30+
1431# ─── indexing helpers ───────────────────────────────────────────
1532def _index (result ):
1633 id2name , awaits = {}, []
@@ -56,9 +73,9 @@ def _cor_node(parent_key, frame_name):
5673
5774
5875def _roots (id2label , children ):
59- roots = [n for n , lbl in id2label .items () if lbl == "Task-1" ]
60- if roots :
61- return roots
76+ # roots = [n for n, lbl in id2label.items() if lbl == "Task-1"]
77+ # if roots:
78+ # return roots
6279 all_children = {c for kids in children .values () for c in kids }
6380 return [n for n in id2label if n not in all_children ]
6481
@@ -80,7 +97,7 @@ def _find_cycles(graph):
8097 empty list if the graph is acyclic.
8198 """
8299 WHITE , GREY , BLACK = 0 , 1 , 2
83- color = { n : WHITE for n in graph }
100+ color = defaultdict ( lambda : WHITE )
84101 path , cycles = [], []
85102
86103 def dfs (v ):
@@ -108,6 +125,10 @@ def print_async_tree(result, task_emoji="(T)", cor_emoji="", printer=print):
108125 prefixing tasks with *task_emoji* and coroutine frames with *cor_emoji*.
109126 """
110127 id2name , awaits = _index (result )
128+ g = _task_graph (awaits )
129+ cycles = _find_cycles (g )
130+ if cycles :
131+ raise CycleFoundException (cycles , id2name )
111132 labels , children = _build_tree (id2name , awaits )
112133
113134 def pretty (node ):
@@ -166,20 +187,9 @@ def build_task_table(result):
166187 print (f"Error retrieving tasks: { e } " )
167188 sys .exit (1 )
168189
190+ print (tasks )
169191 if args .tree :
170192 # Print the async call tree
171- id2name , awaits = _index (tasks )
172- g = _task_graph (awaits )
173- cycles = _find_cycles (g )
174-
175- if cycles :
176- print ("ERROR: await-graph contains cycles – cannot print a tree!\n " )
177- for c in cycles :
178- # pretty-print task names instead of bare ids
179- names = " → " .join (id2name .get (tid , hex (tid )) for tid in c )
180- print (f" cycle: { names } " )
181- sys .exit (1 )
182-
183193 result = print_async_tree (tasks )
184194 for tree in result :
185195 print ("\n " .join (tree ))
0 commit comments