mirror of
https://github.com/python/cpython
synced 2024-09-30 14:24:27 +00:00
bpo-26552: Fixed case where failing asyncio.ensure_future
did not close the coroutine (#30288)
This commit is contained in:
parent
36f538c809
commit
24cc6411ad
|
@ -621,17 +621,23 @@ def _ensure_future(coro_or_future, *, loop=None):
|
||||||
raise ValueError('The future belongs to a different loop than '
|
raise ValueError('The future belongs to a different loop than '
|
||||||
'the one specified as the loop argument')
|
'the one specified as the loop argument')
|
||||||
return coro_or_future
|
return coro_or_future
|
||||||
|
called_wrap_awaitable = False
|
||||||
if not coroutines.iscoroutine(coro_or_future):
|
if not coroutines.iscoroutine(coro_or_future):
|
||||||
if inspect.isawaitable(coro_or_future):
|
if inspect.isawaitable(coro_or_future):
|
||||||
coro_or_future = _wrap_awaitable(coro_or_future)
|
coro_or_future = _wrap_awaitable(coro_or_future)
|
||||||
|
called_wrap_awaitable = True
|
||||||
else:
|
else:
|
||||||
raise TypeError('An asyncio.Future, a coroutine or an awaitable '
|
raise TypeError('An asyncio.Future, a coroutine or an awaitable '
|
||||||
'is required')
|
'is required')
|
||||||
|
|
||||||
if loop is None:
|
if loop is None:
|
||||||
loop = events._get_event_loop(stacklevel=4)
|
loop = events._get_event_loop(stacklevel=4)
|
||||||
|
try:
|
||||||
return loop.create_task(coro_or_future)
|
return loop.create_task(coro_or_future)
|
||||||
|
except RuntimeError:
|
||||||
|
if not called_wrap_awaitable:
|
||||||
|
coro_or_future.close()
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
@types.coroutine
|
@types.coroutine
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
from test.support.script_helper import assert_python_ok
|
from test.support.script_helper import assert_python_ok
|
||||||
from test.support import os_helper
|
from test.support import os_helper
|
||||||
from test.support import socket_helper
|
from test.support import socket_helper
|
||||||
|
import warnings
|
||||||
|
|
||||||
MOCK_ANY = mock.ANY
|
MOCK_ANY = mock.ANY
|
||||||
|
|
||||||
|
@ -796,6 +796,17 @@ def create_task(self, coro):
|
||||||
task._log_destroy_pending = False
|
task._log_destroy_pending = False
|
||||||
coro.close()
|
coro.close()
|
||||||
|
|
||||||
|
def test_create_task_error_closes_coro(self):
|
||||||
|
async def test():
|
||||||
|
pass
|
||||||
|
loop = asyncio.new_event_loop()
|
||||||
|
loop.close()
|
||||||
|
with warnings.catch_warnings(record=True) as w:
|
||||||
|
with self.assertRaises(RuntimeError):
|
||||||
|
asyncio.ensure_future(test(), loop=loop)
|
||||||
|
self.assertEqual(len(w), 0)
|
||||||
|
|
||||||
|
|
||||||
def test_create_named_task_with_default_factory(self):
|
def test_create_named_task_with_default_factory(self):
|
||||||
async def test():
|
async def test():
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fixed case where failing :func:`asyncio.ensure_future` did not close the coroutine. Patch by Kumar Aditya.
|
Loading…
Reference in a new issue