Repository navigation
asyncio.create_subprocess_shell does not consistently result in negative returncode on signal termination #138234
Description
Activity
- addedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Aug 29, 2025 - addedstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
on Aug 29, 2025 When using
create_subprocess_shell,proc.returncodeis 130 after sendingSIGINT.
When usingcreate_subprocess_exec, the return code is -2 as expected (terminated bySIGINT).The current documentation says:
A negative value -N indicates that the child was terminated by signal N (POSIX only).
This is accurate for
create_subprocess_exec, where the child process is executed directly.
But forcreate_subprocess_shell, the child is wrapped by /bin/sh, and the observed return code comes from the shell’s exit status rules (e.g. 128+N for termination by signal N).
So in this case, the return code follows Bash Exit Status
(or the corresponding shell), not the -N convention.Should the documentation clarify this difference between
create_subprocess_exec(direct POSIX behavior) andcreate_subprocess_shell(shell exit status)?Should the documentation clarify this difference between
create_subprocess_exec(direct POSIX behavior) andcreate_subprocess_shell(shell exit status)?I think the documentation should accurately describe the behavior of the functions, that's the point of having documentation.
Regarding the behavior of
create_subprocess_shell, I get that forwarding the exit status of the shell is the simplest way of implementingreturncode. Unfortunately, that makes it inconvenient for users of the interface to do anything useful with thereturncode, since they would have to know about all possible shells which might be used and their respective conventions. It might not be realistic, or even desirable, to change the implementation to have consistent behavior on all (POSIX) platforms. If the current behavior is kept, there should be a clear indication that the shell's exit code is used, and that this code depends on which shell is used.Regardless of what is done wrt
create_subprocess_shell, the documentationcreate_subprocess_execshould be clarified to state whether signal termination always results in a negativereturncodeindicating which signal caused termination. At the moment, an implementation which sometimes returns negative values as described when a signal terminates the process, but other times returns non-negative values for signal termination is allowed by the docs. I don't think this should ever happen, but from reading the docs I don't know if it could. If it actually can happen, it certainly should to be noted in the documentation.- added a commit that references this issue
on Mar 21, 2026
Metadata
Metadata
Assignees
Labels
Projects
- StatusShow more project fieldsDone
Bug report
Bug description:
The docs for
returncodestate the following:which does not technically require, but strongly suggest that processes terminated by signals will have a negative
returncodecorresponding to the signal. On some platforms (observed on Arch Linux and macOS, both using Python 3.13.7), this does indeed seem to be the case. On others it is not. The observed counterexample is Ubuntu using Python 3.12.3. There,returncodeseems to be set to 128 + signal value. Technically, this does not violate the documented behavior, but it is very surprising. If that is intended behavior, the docs deserve a clear warning. My preference would be to mandate negativereturncodes upon termination by signal in the docs and to adapt the code on non-conformant platforms accordingly.Interestingly,
asyncio.create_subprocess_exechas the expected behavior of consistently negativereturncodes on the tested platforms, which increases my suspicion that there is indeed undesired behavior involved.sigint.sh:I created a repo to show the differences in GitHub's CI: https://github.com/danielrainer/python_signal_returncode_repro/actions/runs/17310888203
CPython versions tested on:
3.13, 3.12
Operating systems tested on:
Linux, macOS
Linked PRs
shell=True(GH-138536) #146254shell=True(GH-138536) #146255