[Python-Dev] subprocess, buffered files, pipes and broken pipe errors

Victor Stinner victor.stinner at gmail.com
Fri Mar 6 13:53:07 CET 2015


Hi,

=> I propose to ignore BrokenPipeError on Popen.__exit__(), what do you think?

A recent issue fixed subprocess.Popen.__exit__() to read the exit
status of the child process, even if stdin.close() raised a
BrokenPipeError:
http://bugs.python.org/issue21619

When I saw the issue, I was surprised that Popen.__exit__() doesn't
ignore BrokenPipeError.

Popen.communicate() is designed to handle corner cases and it ignores
BrokenPipeError.

Popen.__exit__() only returns when the process exited. The method
starts by closing all pipes. Usually the child process notices that
stdin was closed and exit (programs used as "pipes" like grep, cat,
wc, etc.).

The problem is that Popen uses a buffered writer for Popen.stdin with
a default buffer size of 8 KB. We may buffer some data and so
stdin.close() will call stdin.write(). If the child process exited or
closed stdin, the pipe is broken, and the write in the parent process
(stdin.close() in Popen.__exit__) will raise BrokenPipeError.

I propose to ignore BrokenPipeError in Popen.__exit__, as done in
communicate(), for convinience:
http://bugs.python.org/issue23570

Serhiy wants to keep BrokenPipeError, he wrote that file.close()
should not ignore write errors (read the issue for details).

I consider that BrokenPipeError on a pipe is different than a write
error on a regular file.

EPIPE and SIGPIPE are designed to notify that the pipe is closed and
that it's now inefficient to continue to write into this pipe.

Ignoring BrokenPipeError in Popen.__exit__() respects this constrain
because the method closes stdin and only returns when the process
exited. So the caller will not write anything into stdin anymore.

What do you think?

Victor


More information about the Python-Dev mailing list