This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Cannot cleanly kill a subprocess using high-level asyncio APIs
Type: behavior Stage: patch review
Components: asyncio Versions: Python 3.11
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Dennis Sweeney, asvetlov, kumaraditya, rabraham, skeggse, yselivanov
Priority: normal Keywords: patch

Created on 2021-04-19 02:47 by rabraham, last changed 2022-04-11 14:59 by admin.

Files
File name Uploaded Description Edit
kill_subprocess.py rabraham, 2021-04-19 02:47 Kill subprocess using the high-level asyncio subprocess APIs
Pull Requests
URL Status Linked Edit
PR 31611 closed kumaraditya, 2022-02-28 08:52
PR 32073 open kumaraditya, 2022-03-23 09:08
Messages (6)
msg391349 - (view) Author: Ronal Abraham (rabraham) Date: 2021-04-19 02:47
There doesn't appear to be a way to prematurely kill a subprocess using the high-level asyncio subprocess APIs (https://docs.python.org/3.9/library/asyncio-subprocess.html) without getting a traceback on exit.

On exit, the attached program writes the following to stderr:

$ python3.9 kill_subprocess.py

Exception ignored in: <function BaseSubprocessTransport.__del__ at 0x1065f0dc0>
Traceback (most recent call last):
    ...
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

If I uncomment `# process._transport.close()` or comment `asyncio.sleep(1)`, the walkback disappears. (I get the same behavior in python 3.8. I haven't tried other python versions.)
msg391350 - (view) Author: Ronal Abraham (rabraham) Date: 2021-04-19 02:50
Reproducing the program here:

    import asyncio
    
    async def test():
        process = await asyncio.create_subprocess_shell(
            "sleep 2 && echo done",
            stdout=asyncio.subprocess.PIPE,
        )
        await asyncio.sleep(1)
        process.kill()
        await process.wait()
        # process._transport.close()
    
    asyncio.run(test())

Can I use the high-level API to kill a subprocess cleanly without having to access the protected member process._transport? Seems like an oversight perhaps?
msg391369 - (view) Author: Dennis Sweeney (Dennis Sweeney) * (Python committer) Date: 2021-04-19 08:25
Running kill_subprocess.py on Windows 10, I get these results:

Python 3.7.2 (tags/v3.7.2:9a3ffc0492)
    - raises NotImplementedError in base_events.py, _make_subprocess_transport
Python 3.8.2 (tags/v3.8.2:7b3ab59)
    - Success
Python 3.9.0 (tags/v3.9.0:9cf6752)
    - Success
Python 3.10.0a6 (tags/v3.10.0a6:cc12888)
    - Success

What is your OS?
msg391379 - (view) Author: Ronal Abraham (rabraham) Date: 2021-04-19 13:54
I see this on MacOS and Linux, but I suspect any Unix-like system would have the same behavior.
msg399937 - (view) Author: Eli Skeggs (skeggse) Date: 2021-08-19 21:46
I'm also experiencing this, with virtually identical code, on macOS 10.15.7. The given fix (process._transport.close()) also works for me, so I'm just using that workaround for the time being.
msg415859 - (view) Author: Kumar Aditya (kumaraditya) * (Python triager) Date: 2022-03-23 08:32
@asvetlov Do you have any insight for this issue?
History
Date User Action Args
2022-04-11 14:59:44adminsetgithub: 88050
2022-03-23 09:08:45kumaradityasetpull_requests: + pull_request30160
2022-03-23 08:32:44kumaradityasetmessages: + msg415859
2022-02-28 08:52:48kumaradityasetkeywords: + patch
nosy: + kumaraditya

pull_requests: + pull_request29734
stage: patch review
2022-02-28 08:52:28kumaradityasetversions: + Python 3.11, - Python 3.8, Python 3.9
2021-08-19 21:46:10skeggsesetnosy: + skeggse
messages: + msg399937
2021-04-19 13:54:44rabrahamsetmessages: + msg391379
2021-04-19 08:25:20Dennis Sweeneysetnosy: + Dennis Sweeney
messages: + msg391369
2021-04-19 02:50:04rabrahamsetmessages: + msg391350
2021-04-19 02:47:38rabrahamcreate