summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/asyncio/base_events.py6
-rw-r--r--Lib/asyncio/futures.py2
-rw-r--r--Misc/NEWS.d/next/Library/2022-09-30-15-56-20.gh-issue-96827.lzy1iw.rst1
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).