11import argparse
2+ from dataclasses import dataclass
23from collections import defaultdict
34from itertools import count
45from enum import Enum
@@ -11,21 +12,11 @@ class NodeType(Enum):
1112 TASK = 2
1213
1314
15+ @dataclass (frozen = True )
1416class CycleFoundException (Exception ):
1517 """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- )
18+ cycles : list [list [int ]]
19+ id2name : dict [int , str ]
2920
3021
3122# ─── indexing helpers ───────────────────────────────────────────
@@ -172,6 +163,14 @@ def build_task_table(result):
172163
173164 return table
174165
166+ def _print_cycle_exception (exception : CycleFoundException ):
167+ print ("ERROR: await-graph contains cycles – cannot print a tree!" , file = sys .stderr )
168+ print ("" , file = sys .stderr )
169+ for c in exception .cycles :
170+ inames = " → " .join (exception .id2name .get (tid , hex (tid )) for tid in c )
171+ print (f"cycle: { inames } " , file = sys .stderr )
172+
173+
175174
176175if __name__ == "__main__" :
177176 parser = argparse .ArgumentParser (description = "Show Python async tasks in a process" )
@@ -184,13 +183,19 @@ def build_task_table(result):
184183 try :
185184 tasks = get_all_awaited_by (args .pid )
186185 except RuntimeError as e :
186+ while e .__cause__ is not None :
187+ e = e .__cause__
187188 print (f"Error retrieving tasks: { e } " )
188189 sys .exit (1 )
189190
190- print (tasks )
191191 if args .tree :
192192 # Print the async call tree
193- result = print_async_tree (tasks )
193+ try :
194+ result = print_async_tree (tasks )
195+ except CycleFoundException as e :
196+ _print_cycle_exception (e )
197+ sys .exit (1 )
198+
194199 for tree in result :
195200 print ("\n " .join (tree ))
196201 else :
0 commit comments