]> 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>
Sat, 29 Jan 2022 06:57:18 +0000 (12:27 +0530)
committerGitHub <noreply@github.com>
Sat, 29 Jan 2022 06:57:18 +0000 (22:57 -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 f7ef23e55090ec9d867b361a24de79e3b36152f4..d77bf95a7b37254b37b2050660d75842bb7a318e 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
 PY34 = sys.version_info >= (3, 4)
@@ -801,6 +801,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