diff options
-rw-r--r-- | Lib/asyncio/base_events.py | 6 | ||||
-rw-r--r-- | Lib/asyncio/futures.py | 2 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2022-09-30-15-56-20.gh-issue-96827.lzy1iw.rst | 1 |
3 files changed, 7 insertions, 2 deletions
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 9c9d98d..2df9dca 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -588,9 +588,11 @@ class BaseEventLoop(events.AbstractEventLoop): def _do_shutdown(self, future): try: self._default_executor.shutdown(wait=True) - self.call_soon_threadsafe(future.set_result, None) + if not self.is_closed(): + self.call_soon_threadsafe(future.set_result, None) except Exception as ex: - self.call_soon_threadsafe(future.set_exception, ex) + if not self.is_closed(): + self.call_soon_threadsafe(future.set_exception, ex) def _check_running(self): if self.is_running(): diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py index 4bd9629..39776e3 100644 --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -404,6 +404,8 @@ def _chain_future(source, destination): if dest_loop is None or dest_loop is source_loop: _set_state(destination, source) else: + if dest_loop.is_closed(): + return dest_loop.call_soon_threadsafe(_set_state, destination, source) destination.add_done_callback(_call_check_cancel) diff --git a/Misc/NEWS.d/next/Library/2022-09-30-15-56-20.gh-issue-96827.lzy1iw.rst b/Misc/NEWS.d/next/Library/2022-09-30-15-56-20.gh-issue-96827.lzy1iw.rst new file mode 100644 index 0000000..159ab32 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-09-30-15-56-20.gh-issue-96827.lzy1iw.rst @@ -0,0 +1 @@ +Avoid spurious tracebacks from :mod:`asyncio` when default executor cleanup is delayed until after the event loop is closed (e.g. as the result of a keyboard interrupt). |