]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-26552: Fixed case where failing `asyncio.ensure_future` did not close the corouti...
authorKumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
Fri, 28 Jan 2022 22:24:35 +0000 (03:54 +0530)
committerGitHub <noreply@github.com>
Fri, 28 Jan 2022 22:24:35 +0000 (14:24 -0800)
Lib/asyncio/tasks.py
Lib/test/test_asyncio/test_base_events.py
Misc/NEWS.d/next/Library/2021-12-29-13-42-55.bpo-26552.1BqeAn.rst [new file with mode: 0644]

index 445a9f51226ed7a5e706d01dae80079e3db4dedf..2bee5c050ded7d4672c0dc7aef3e9d6df04e295f 100644 (file)
@@ -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
index 17e8396cfe2ef1ffa3178acd6f4a251e4218aa72..c64e1623a039563e91667f5cd00a4836195a454c 100644 (file)
@@ -18,7 +18,7 @@ from test import support
 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
 
@@ -796,6 +796,17 @@ class BaseEventLoopTests(test_utils.TestCase):
         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 (file)
index 0000000..85b6a64
--- /dev/null
@@ -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