Skip to content

Commit 24cc641

Browse files
bpo-26552: Fixed case where failing asyncio.ensure_future did not close the coroutine (#30288)
1 parent 36f538c commit 24cc641

File tree

3 files changed

+21
-3
lines changed

3 files changed

+21
-3
lines changed

Lib/asyncio/tasks.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,17 +621,23 @@ def _ensure_future(coro_or_future, *, loop=None):
621621
raise ValueError('The future belongs to a different loop than '
622622
'the one specified as the loop argument')
623623
return coro_or_future
624-
624+
called_wrap_awaitable = False
625625
if not coroutines.iscoroutine(coro_or_future):
626626
if inspect.isawaitable(coro_or_future):
627627
coro_or_future = _wrap_awaitable(coro_or_future)
628+
called_wrap_awaitable = True
628629
else:
629630
raise TypeError('An asyncio.Future, a coroutine or an awaitable '
630631
'is required')
631632

632633
if loop is None:
633634
loop = events._get_event_loop(stacklevel=4)
634-
return loop.create_task(coro_or_future)
635+
try:
636+
return loop.create_task(coro_or_future)
637+
except RuntimeError:
638+
if not called_wrap_awaitable:
639+
coro_or_future.close()
640+
raise
635641

636642

637643
@types.coroutine

Lib/test/test_asyncio/test_base_events.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from test.support.script_helper import assert_python_ok
1919
from test.support import os_helper
2020
from test.support import socket_helper
21-
21+
import warnings
2222

2323
MOCK_ANY = mock.ANY
2424

@@ -796,6 +796,17 @@ def create_task(self, coro):
796796
task._log_destroy_pending = False
797797
coro.close()
798798

799+
def test_create_task_error_closes_coro(self):
800+
async def test():
801+
pass
802+
loop = asyncio.new_event_loop()
803+
loop.close()
804+
with warnings.catch_warnings(record=True) as w:
805+
with self.assertRaises(RuntimeError):
806+
asyncio.ensure_future(test(), loop=loop)
807+
self.assertEqual(len(w), 0)
808+
809+
799810
def test_create_named_task_with_default_factory(self):
800811
async def test():
801812
pass
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed case where failing :func:`asyncio.ensure_future` did not close the coroutine. Patch by Kumar Aditya.

0 commit comments

Comments
 (0)