[Python-checkins] bpo-26552: Fixed case where failing `asyncio.ensure_future` did not close the coroutine (#30288) (#31003)

gvanrossum webhook-mailer at python.org
Sat Jan 29 01:57:26 EST 2022


https://github.com/python/cpython/commit/a5451c96a14ac0c3ee7cef7b5c52ab1d783ec613
commit: a5451c96a14ac0c3ee7cef7b5c52ab1d783ec613
branch: 3.10
author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com>
committer: gvanrossum <gvanrossum at gmail.com>
date: 2022-01-28T22:57:18-08:00
summary:

bpo-26552: Fixed case where failing `asyncio.ensure_future` did not close the coroutine (#30288) (#31003)

files:
A Misc/NEWS.d/next/Library/2021-12-29-13-42-55.bpo-26552.1BqeAn.rst
M Lib/asyncio/tasks.py
M Lib/test/test_asyncio/test_base_events.py

diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py
index 445a9f51226ed..2bee5c050ded7 100644
--- a/Lib/asyncio/tasks.py
+++ b/Lib/asyncio/tasks.py
@@ -621,17 +621,23 @@ def _ensure_future(coro_or_future, *, loop=None):
             raise ValueError('The future belongs to a different loop than '
                             'the one specified as the loop argument')
         return coro_or_future
-
+    called_wrap_awaitable = False
     if not coroutines.iscoroutine(coro_or_future):
         if inspect.isawaitable(coro_or_future):
             coro_or_future = _wrap_awaitable(coro_or_future)
+            called_wrap_awaitable = True
         else:
             raise TypeError('An asyncio.Future, a coroutine or an awaitable '
                             'is required')
 
     if loop is None:
         loop = events._get_event_loop(stacklevel=4)
-    return loop.create_task(coro_or_future)
+    try:
+        return loop.create_task(coro_or_future)
+    except RuntimeError: 
+        if not called_wrap_awaitable:
+            coro_or_future.close()
+        raise
 
 
 @types.coroutine
diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py
index f7ef23e55090e..d77bf95a7b372 100644
--- a/Lib/test/test_asyncio/test_base_events.py
+++ b/Lib/test/test_asyncio/test_base_events.py
@@ -18,7 +18,7 @@
 from test.support.script_helper import assert_python_ok
 from test.support import os_helper
 from test.support import socket_helper
-
+import warnings
 
 MOCK_ANY = mock.ANY
 PY34 = sys.version_info >= (3, 4)
@@ -801,6 +801,17 @@ def create_task(self, coro):
         task._log_destroy_pending = False
         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):
         async def test():
             pass
diff --git a/Misc/NEWS.d/next/Library/2021-12-29-13-42-55.bpo-26552.1BqeAn.rst b/Misc/NEWS.d/next/Library/2021-12-29-13-42-55.bpo-26552.1BqeAn.rst
new file mode 100644
index 0000000000000..85b6a64ef53d1
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-12-29-13-42-55.bpo-26552.1BqeAn.rst
@@ -0,0 +1 @@
+Fixed case where failing :func:`asyncio.ensure_future` did not close the coroutine. Patch by Kumar Aditya.
\ No newline at end of file



More information about the Python-checkins mailing list