Author martin.panter
Recipients Arfrever, dmalcolm, martin.panter, pitrou, python-dev, rosslagerwall, serhiy.storchaka, vstinner
Date 2015-03-02.02:19:18
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1425262760.47.0.577046900189.issue21619@psf.upfronthosting.co.za>
In-reply-to
Content
It seems two different issues have popped up:

## 1. Windows behaviour ##

Windows apparently doesn’t handle broken pipes consistently, sometimes raising an EINVAL error, and sometimes not raising any error. I don’t know if this is a problem with Python, or a quirk with Windows. (Just tried with Wine, and it always raises ENOSPC instead, but I guess that’s a Wine-specific quirk.)

Perhaps we can change the offending test case to the following, at least until someone can investigate and explain what is going on:

...
if mswindows:
    try:
        proc.__exit__(None, None, None)
    except OSError:  # Sometimes raises EINVAL, sometimes no error
        pass
else:
    self.assertRaises(BrokenPipeError, proc.__exit__, None, None, None)
...

## 2. Suppressing BrokenPipeError ##

I don’t have any strong opinions. I think in the past when writing to a process’s input raises BrokenPipeError, I have tended to skip the writing and go on to analyse the process’s output and/or exit status (the same as if writing succeeded).

Some arguments for raising BrokenPipeError (current behaviour):

* No change in behaviour
* Slightly simpler implementation
* Consistent with the way stdin.close() works
* Potentially more flexible if the user cares about handling a broken pipe specially.
* Exiting the context manager does not return any data, so no return value is lost by raising an exception. In contrast, one of the reasons communicate() was changed to sometimes suppress the exception is so that the captured output is returned and not lost.

Arguments for suppressing BrokenPipeError:

* Consistent with the way communicate() is meant to work, according to Issue 10963.
* Probably more useful in normal use cases
* User can always explicitly call stdin.close() if they really want to handle the BrokenPipeError
* Avoid possible confusion and hiding a more important exception, if one was already raised inside the context manager, for example if a subprocess crash was detected, or if stdin.write() already raised its own BrokenPipeError.

Replying to Victor: “the process always exit after __exit__?”:

__exit__ is meant to call wait(), so it only returns when the subprocess exits. It could potentially still be running despite closing its input pipe. This issue was originally about making sure __exit__ called wait() in all cases.
History
Date User Action Args
2015-03-02 02:19:20martin.pantersetrecipients: + martin.panter, pitrou, vstinner, Arfrever, dmalcolm, rosslagerwall, python-dev, serhiy.storchaka
2015-03-02 02:19:20martin.pantersetmessageid: <1425262760.47.0.577046900189.issue21619@psf.upfronthosting.co.za>
2015-03-02 02:19:20martin.panterlinkissue21619 messages
2015-03-02 02:19:18martin.pantercreate