Hi, I tried to use subprocess.run(..., stdout=subprocess.PIPE, timeout=N) to run some test scripts with a given timeout. This works as expected with simple scripts. However if the script itself creates other children which write to stdout then `subprocess.run()` seems to wait for all of the children to finish. I've attached a minimal example. I looked into subprocess.py and `subprocess.run()` calls `process.communicate()` again without timeout when handling the TimeoutExpired exception which then in turn waits for the pipes to be closed by all children. If communicate() would check if the process is still alive while waiting for output and close the pipes once the process has finished the timeout feature should work as expected and descendants would get a SIGPIPE when writing to stdout/stderr.
This proposal sounds like a race condition. Closing the output pipe as a child exits means you risk missing recent output. On the other hand, if you don’t care about the output any more, close the pipe first and then wait for the child. Related discussions: Issue 30154: Similar problem, but the grandchild does not write any output Issue 26534: kill_group=True option for timeout Issue 31447: Windows-specific (?)
Closing in faviour of Issue 30154, which suggests documentation or adjusting the timeout implementation. There is also Issue 26534 proposing a new “kill_group” option when using the timeout feature.