[issue23570] Change "with subprocess.Popen():" (context manager) to ignore broken pipe error

STINNER Victor report at bugs.python.org
Tue Mar 3 12:41:44 CET 2015


STINNER Victor added the comment:

> Do you want to modify IOBase.__exit__ to ignore I/O errors in close()?

Nope. On files, you want to want to know if your data has been fully written. For a subprocess, it's different. You only expect best effort.

The BrokenPipeError exception is raised by Python when an OS function fails with EPIPE. This exception has the same purpose than the SIGPIPE signal: warn the application that it's now useless to send more data, the consumer will ignore it. By the way, since Python checks the result of *all* OS functions, SIGPIPE is simply ignored. SIGPIPE and EPIPE have the same purpose.

In the subprocess module, if we get BrokenPipeError, it means that the child process stopped reading from stdin (closed it or the process already exited).

Popen.communicate() must close stdin, so why would we pass BrokenPipeError to the caller? It's useless, we just stop writing and close the pipe.

Since Popen.__exit__() also closes stdin, I use the same rationale: it useless to pass BrokenPipeError to the caller. The caller expects that the process exited.

Anyway, we closed all pipes, it's not more possible to communicate with the child process. The following example displays "is proc stdin closed? True":
---
import subprocess, sys

args = [sys.executable, '-c', 'pass']
proc = subprocess.Popen(args, stdin=subprocess.PIPE)
try:
    with proc:
        proc.stdin.write(b'x' * (2**20))
except BrokenPipeError:
    pass
print("is proc stdin closed?", proc.stdin.closed)
---

See also: "Why does SIGPIPE exist?"
https://stackoverflow.com/questions/8369506/why-does-sigpipe-exist

----------
nosy: +neologix

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue23570>
_______________________________________


More information about the Python-bugs-list mailing list