@@ -298,6 +298,68 @@ async def main(t1, t2):
298298 ]
299299 ])
300300
301+ async def test_stack_as_completed (self ):
302+ # gh-156523: as_completed() must record the awaiting task
303+ stack_for_inner = None
304+
305+ async def inner ():
306+ await asyncio .sleep (0 )
307+ nonlocal stack_for_inner
308+ stack_for_inner = capture_test_stack ()
309+
310+ async def main (t ):
311+ for f in asyncio .as_completed ([t ]):
312+ await f
313+
314+ t = asyncio .create_task (inner (), name = 'inner' )
315+ await main (t )
316+ self .assertFalse (t ._asyncio_awaited_by )
317+
318+ self .assertEqual (stack_for_inner [0 ], [
319+ 'T<inner>' ,
320+ ['s capture_test_stack' , 'a inner' ],
321+ [
322+ ['T<anon>' ,
323+ ['a get' , 'a _wait_for_one' , 'a main' ,
324+ 'a test_stack_as_completed' ],
325+ []
326+ ]
327+ ]
328+ ])
329+
330+ async def test_stack_as_completed_timeout (self ):
331+ # gh-156523: the awaiting task must be dropped when as_completed() times out
332+ stack_for_inner = None
333+
334+ async def inner ():
335+ nonlocal stack_for_inner
336+ stack_for_inner = capture_test_stack ()
337+ await asyncio .sleep (3600 )
338+
339+ async def main (t ):
340+ with self .assertRaises (TimeoutError ):
341+ for f in asyncio .as_completed ([t ], timeout = 0.01 ):
342+ await f
343+
344+ t = asyncio .create_task (inner (), name = 'inner' )
345+ await main (t )
346+ self .assertFalse (t ._asyncio_awaited_by )
347+ t .cancel ()
348+ with self .assertRaises (asyncio .CancelledError ):
349+ await t
350+
351+ self .assertEqual (stack_for_inner [0 ], [
352+ 'T<inner>' ,
353+ ['s capture_test_stack' , 'a inner' ],
354+ [
355+ ['T<anon>' ,
356+ ['a get' , 'a _wait_for_one' , 'a main' ,
357+ 'a test_stack_as_completed_timeout' ],
358+ []
359+ ]
360+ ]
361+ ])
362+
301363 async def test_stack_task (self ):
302364
303365 stack_for_inner = None
0 commit comments