https://github.com/python/cpython/commit/353e6d3eff1172bd7df9340436b55a505f850a06
commit: 353e6d3eff1172bd7df9340436b55a505f850a06
branch: main
author: Timofei Ivankov <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2026-07-28T06:59:49Z
summary:

gh-150866: Fix asyncio shutdown_asyncgens to report BaseException (#150867)

files:
A Misc/NEWS.d/next/Library/2026-06-03-18-41-42.gh-issue-150866.gXGyX-.rst
M Lib/asyncio/base_events.py
M Lib/test/test_asyncio/test_base_events.py

diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index 3836aaad326f62e..f26fba175b63cd7 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -590,7 +590,7 @@ async def shutdown_asyncgens(self):
             return_exceptions=True)
 
         for result, agen in zip(results, closing_agens):
-            if isinstance(result, Exception):
+            if isinstance(result, BaseException):
                 self.call_exception_handler({
                     'message': f'an error occurred during closing of '
                                f'asynchronous generator {agen!r}',
diff --git a/Lib/test/test_asyncio/test_base_events.py 
b/Lib/test/test_asyncio/test_base_events.py
index 1622f19f0213f3c..18afdca23163a1e 100644
--- a/Lib/test/test_asyncio/test_base_events.py
+++ b/Lib/test/test_asyncio/test_base_events.py
@@ -1042,6 +1042,60 @@ async def iter_one():
         asyncio.create_task(iter_one())
         return status
 
+    def test_shutdown_asyncgens_reports_base_exceptions(self):
+        # gh-150866: shutdown_asyncgens silently swallowed exceptions that
+        # don't inherit from Exception raised during aclose() because the
+        # check was isinstance(result, Exception), but CancelledError inherits
+        # from BaseException.
+        self.loop._process_events = mock.Mock()
+        self.loop._write_to_self = mock.Mock()
+
+        class MyBaseException(BaseException):
+            pass
+
+        async def agen_cancel():
+            try:
+                yield 1
+            finally:
+                raise asyncio.CancelledError("agen got cancelled during 
cleanup")
+
+        async def agen_base():
+            try:
+                yield 1
+            finally:
+                raise MyBaseException("base exc during cleanup")
+
+        async def agen_value_error():
+            try:
+                yield 1
+            finally:
+                raise ValueError("agen failed during cleanup")
+
+        caught = []
+
+        def handler(loop, context):
+            caught.append(context['exception'])
+
+        async def main():
+            loop = asyncio.get_running_loop()
+            loop.set_exception_handler(handler)
+
+            g1 = agen_cancel()
+            g2 = agen_base()
+            g3 = agen_value_error()
+            await g1.__anext__()
+            await g2.__anext__()
+            await g3.__anext__()
+
+            await loop.shutdown_asyncgens()
+
+        self.loop.run_until_complete(main())
+        self.assertEqual(len(caught), 3)
+        self.assertEqual(
+            {type(exc) for exc in caught},
+            {asyncio.CancelledError, MyBaseException, ValueError},
+        )
+
     def test_asyncgen_finalization_by_gc(self):
         # Async generators should be finalized when garbage collected.
         self.loop._process_events = mock.Mock()
diff --git 
a/Misc/NEWS.d/next/Library/2026-06-03-18-41-42.gh-issue-150866.gXGyX-.rst 
b/Misc/NEWS.d/next/Library/2026-06-03-18-41-42.gh-issue-150866.gXGyX-.rst
new file mode 100644
index 000000000000000..57af6e954384b10
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-06-03-18-41-42.gh-issue-150866.gXGyX-.rst
@@ -0,0 +1,2 @@
+Fix :meth:`asyncio.loop.shutdown_asyncgens` to report any
+:exc:`BaseException` raised during asynchronous generator cleanup.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to