From 7500655a6883d4eb448ab1b727a188d5e00e3468 Mon Sep 17 00:00:00 2001 From: "Yves.Duprat" Date: Fri, 21 Aug 2026 00:21:01 +0200 Subject: [PATCH 1/3] Initial commit - Update `Task.__step` , - Update `_asyncio` module on the corresponding function, - Add a `test_step_dont_swallow_systemexit` test in `test_task.py` file. --- Lib/asyncio/tasks.py | 6 +++++- Lib/test/test_asyncio/test_tasks.py | 19 +++++++++++++++++++ Modules/_asynciomodule.c | 9 +++++++-- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 7889d4793a5dec3..524be6224dc1552 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -268,7 +268,11 @@ def __step(self, exc=None): raise exceptions.InvalidStateError( f'__step(): already done: {self!r}, {exc!r}') if self._must_cancel: - if not isinstance(exc, exceptions.CancelledError): + if not isinstance(exc, (exceptions.CancelledError, + # gh-108549: do not swallow these + # 2 exceptions + SystemExit, KeyboardInterrupt) + ): exc = self._make_cancelled_error() self._must_cancel = False self._fut_waiter = None diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 9c111da8c27f162..8d11238fbd4449a 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -1891,6 +1891,25 @@ async def notmuch(): self.loop.run_until_complete(task), 'ko') + def test_step_dont_swallow_systemexit(self): + # gh-108549: do not swallow + # KeybordInterrupt too. + async def sub_task(): + raise SystemExit + + async def gather(): + try: + await asyncio.gather(sub_task(),) + except SystemExit: + pass + + t = self.new_task(self.loop, gather()) + with self.assertRaises(SystemExit): + self.loop.run_until_complete(t) + t.cancel() + self.loop.run_until_complete(t) + self.assertTrue(t.done()) + def test_step_result_future(self): # If coroutine returns future, task waits on this future. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 41384b388142ccc..03ea94a6c3ded36 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -3067,8 +3067,13 @@ task_step_impl(asyncio_state *state, TaskObj *task, PyObject *exc) if (task->task_must_cancel) { assert(exc != Py_None); - if (!exc || !PyErr_GivenExceptionMatches(exc, state->asyncio_CancelledError)) { - /* exc was not a CancelledError */ + if (!exc || + (!PyErr_GivenExceptionMatches(exc, state->asyncio_CancelledError) && + !PyErr_GivenExceptionMatches(exc, PyExc_KeyboardInterrupt) && + !PyErr_GivenExceptionMatches(exc, PyExc_SystemExit)) + ) { + /* exc was not a CancelledError, + neither SystemExit or KeyboardInterrupt (see gh-108549 )*/ exc = create_cancelled_error(state, (FutureObj*)task); if (!exc) { From d66b44f80a18a41a88d48438b714bac1ed1c46ff Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 24 Aug 2026 14:28:56 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2026-08-24-14-28-47.gh-issue-108549.XZ34WD.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2026-08-24-14-28-47.gh-issue-108549.XZ34WD.rst diff --git a/Misc/NEWS.d/next/Library/2026-08-24-14-28-47.gh-issue-108549.XZ34WD.rst b/Misc/NEWS.d/next/Library/2026-08-24-14-28-47.gh-issue-108549.XZ34WD.rst new file mode 100644 index 000000000000000..8d18a14d33a5e40 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-08-24-14-28-47.gh-issue-108549.XZ34WD.rst @@ -0,0 +1 @@ +In ``asyncio.Task.__step``, do not cancel the current task when a ``SystemExit``(or a ``KeyboardInterrupt``) exception was just raised. From a89d0d5c02edee7770359fab43fcf5df43284262 Mon Sep 17 00:00:00 2001 From: "Yves.Duprat" Date: Mon, 24 Aug 2026 16:42:30 +0200 Subject: [PATCH 3/3] Fix nits in news file. --- .../next/Library/2026-08-24-14-28-47.gh-issue-108549.XZ34WD.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2026-08-24-14-28-47.gh-issue-108549.XZ34WD.rst b/Misc/NEWS.d/next/Library/2026-08-24-14-28-47.gh-issue-108549.XZ34WD.rst index 8d18a14d33a5e40..c97425a91921f54 100644 --- a/Misc/NEWS.d/next/Library/2026-08-24-14-28-47.gh-issue-108549.XZ34WD.rst +++ b/Misc/NEWS.d/next/Library/2026-08-24-14-28-47.gh-issue-108549.XZ34WD.rst @@ -1 +1 @@ -In ``asyncio.Task.__step``, do not cancel the current task when a ``SystemExit``(or a ``KeyboardInterrupt``) exception was just raised. +In ``asyncio.Task.__step``, do not cancel the current task when a ``SystemExit`` (or a ``KeyboardInterrupt``) exception was just raised.