Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Doc/library/subprocess.rst
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,9 @@ Instances of the :class:`Popen` class have the following methods:

If the process does not terminate after *timeout* seconds, a
:exc:`TimeoutExpired` exception will be raised. Catching this exception and
retrying communication will not lose any output.
retrying communication will not lose any output. Supplying *input* to a
subsequent post-timeout :meth:`communicate` call is in undefined behavior
and may become an error in the future.

The child process is not killed if the timeout expires, so in order to
cleanup properly a well-behaved application should kill the child process and
Expand Down
2 changes: 1 addition & 1 deletion Lib/subprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -2105,7 +2105,7 @@ def _communicate(self, input, endtime, orig_timeout):
input_view = memoryview(self._input)

with _PopenSelector() as selector:
if self.stdin and input:
if self.stdin and not self.stdin.closed and self._input:
selector.register(self.stdin, selectors.EVENT_WRITE)
if self.stdout and not self.stdout.closed:
selector.register(self.stdout, selectors.EVENT_READ)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
When :meth:`subprocess.Popen.communicate` was called with *input* and a
*timeout* and is called for a second time after a
:exc:`~subprocess.TimeoutExpired` exception before the process has died, it
should no longer hang.
Loading