Skip to content

Commit 602f9bb

Browse files
authored
Merge pull request #100 from mgmacias95/GH-91048-tasks
Gh 91048 tasks
2 parents 9bd2a6f + 4cd011a commit 602f9bb

File tree

7 files changed

+429
-34
lines changed

7 files changed

+429
-34
lines changed

Lib/asyncio/tools.py

+26-16
Original file line numberDiff line numberDiff line change
@@ -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 ───────────────────────────────────────────
1532
def _index(result):
1633
id2name, awaits = {}, []
@@ -56,9 +73,9 @@ def _cor_node(parent_key, frame_name):
5673

5774

5875
def _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

Comments
 (0)