Skip to content

Commit 91b87b3

Browse files
committed
gh-161178: Fix missing async generator frames in Task.print_stack()
1 parent bb9d26d commit 91b87b3

3 files changed

Lines changed: 41 additions & 1 deletion

File tree

‎Lib/asyncio/base_tasks.py‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,12 @@ def _task_get_stack(task, limit):
4242
elif hasattr(task._coro, 'ag_frame'):
4343
# case 3: async generators
4444
f = task._coro.ag_frame
45+
# gh-161178: async gens should not be missed
46+
elif not task.done() and hasattr(task._coro, 'aga_gen'):
47+
# case 4: pending async generator operations
48+
f = task._coro.aga_gen.ag_frame
4549
else:
46-
# case 4: unknown objects
50+
# case 5: unknown objects
4751
f = None
4852
if f is not None:
4953
while f is not None:

‎Lib/test/test_asyncio/test_tasks.py‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,40 @@ async def runner():
335335

336336
self.loop.run_until_complete(runner())
337337

338+
def test_get_stack_async_generator(self):
339+
# gh-161178
340+
async def gen():
341+
try:
342+
yield
343+
except ValueError:
344+
pass
345+
finally:
346+
await asyncio.sleep(0)
347+
yield
348+
349+
async def runner(method, args):
350+
agen = gen()
351+
await anext(agen)
352+
task = self.new_task(self.loop, getattr(agen, method)(*args))
353+
await asyncio.sleep(0)
354+
frame = agen.ag_frame
355+
stack = task.get_stack()
356+
await task
357+
try:
358+
self.assertEqual(stack, [frame])
359+
self.assertEqual(task.get_stack(), [])
360+
finally:
361+
await agen.aclose()
362+
363+
for method, args in (
364+
('__anext__', ()),
365+
('asend', (None,)),
366+
('athrow', (ValueError(),)),
367+
('aclose', ()),
368+
):
369+
with self.subTest(method=method):
370+
self.loop.run_until_complete(runner(method, args))
371+
338372
def test_task_repr(self):
339373
self.loop.set_debug(False)
340374

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix :meth:`asyncio.Task.print_stack` to include frames from async generator
2+
operations. Patch by Timofei Ivankov

0 commit comments

Comments
 (0)