diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 56ea7ba44e2eac1..96b768beffb72cd 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -419,12 +419,18 @@ def create_future(self): """Create a Future object attached to the loop.""" return futures.Future(loop=self) - def create_task(self, coro, *, name=None): + def create_task(self, coro, used_wrap_await=False, name=None): """Schedule a coroutine object. Return a task object. """ - self._check_closed() + try: + self._check_closed() + except RuntimeError: + if used_wrap_await: + coro.close() + raise + if self._task_factory is None: task = tasks.Task(coro, loop=self, name=name) if task._source_traceback: diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py index d91fe8db2b02044..13244f7b9e7669b 100644 --- a/Lib/asyncio/events.py +++ b/Lib/asyncio/events.py @@ -274,7 +274,7 @@ def create_future(self): # Method scheduling a coroutine object: create a task. - def create_task(self, coro, *, name=None): + def create_task(self, coro, used_wrap_await=False, name=None): raise NotImplementedError # Methods for interacting with threads. diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 53eef84427be10c..b84e93103f14efd 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -328,7 +328,7 @@ def __wakeup(self, future): Task = _CTask = _asyncio.Task -def create_task(coro, *, name=None): +def create_task(coro, used_wrap_await=False, name=None): """Schedule the execution of a coroutine object in a spawn task. Return a Task object. @@ -612,10 +612,13 @@ def ensure_future(coro_or_future, *, loop=None): If the argument is a Future, it is returned directly. """ + if loop is None: + coro_or_future.close() return _ensure_future(coro_or_future, loop=loop) def _ensure_future(coro_or_future, *, loop=None): + wrap_await = False if futures.isfuture(coro_or_future): if loop is not None and loop is not futures._get_loop(coro_or_future): raise ValueError('The future belongs to a different loop than ' @@ -625,13 +628,14 @@ def _ensure_future(coro_or_future, *, loop=None): if not coroutines.iscoroutine(coro_or_future): if inspect.isawaitable(coro_or_future): coro_or_future = _wrap_awaitable(coro_or_future) + wrap_await = 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) + return loop.create_task(coro_or_future, used_wrap_await=wrap_await) @types.coroutine