[3.14] gh-103847: fix cancellation safety of asyncio.create_subprocess_exec (GH-140805) (#141446)

gh-103847: fix cancellation safety of `asyncio.create_subprocess_exec` (GH-140805)
(cherry picked from commit ef474cfafb)

Co-authored-by: Kumar Aditya <kumaraditya@python.org>
This commit is contained in:
Miss Islington (bot) 2025-11-13 12:33:04 +01:00 committed by GitHub
parent 42e0468209
commit 7e9400c3e6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 51 additions and 1 deletions

View file

@ -11,7 +11,7 @@
from asyncio import subprocess
from test.test_asyncio import utils as test_utils
from test import support
from test.support import os_helper
from test.support import os_helper, warnings_helper, gc_collect
if not support.has_subprocess_support:
raise unittest.SkipTest("test module requires subprocess")
@ -879,6 +879,44 @@ async def main():
self.loop.run_until_complete(main())
@warnings_helper.ignore_warnings(category=ResourceWarning)
def test_subprocess_read_pipe_cancelled(self):
async def main():
loop = asyncio.get_running_loop()
loop.connect_read_pipe = mock.AsyncMock(side_effect=asyncio.CancelledError)
with self.assertRaises(asyncio.CancelledError):
await asyncio.create_subprocess_exec(*PROGRAM_BLOCKED, stderr=asyncio.subprocess.PIPE)
asyncio.run(main())
gc_collect()
@warnings_helper.ignore_warnings(category=ResourceWarning)
def test_subprocess_write_pipe_cancelled(self):
async def main():
loop = asyncio.get_running_loop()
loop.connect_write_pipe = mock.AsyncMock(side_effect=asyncio.CancelledError)
with self.assertRaises(asyncio.CancelledError):
await asyncio.create_subprocess_exec(*PROGRAM_BLOCKED, stdin=asyncio.subprocess.PIPE)
asyncio.run(main())
gc_collect()
@warnings_helper.ignore_warnings(category=ResourceWarning)
def test_subprocess_read_write_pipe_cancelled(self):
async def main():
loop = asyncio.get_running_loop()
loop.connect_read_pipe = mock.AsyncMock(side_effect=asyncio.CancelledError)
loop.connect_write_pipe = mock.AsyncMock(side_effect=asyncio.CancelledError)
with self.assertRaises(asyncio.CancelledError):
await asyncio.create_subprocess_exec(
*PROGRAM_BLOCKED,
stdin=asyncio.subprocess.PIPE,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
asyncio.run(main())
gc_collect()
if sys.platform != 'win32':
# Unix