This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2011年01月20日 20:23 by dmalcolm, last changed 2022年04月11日 14:57 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| py3k-handle-EPIPE-for-short-lived-subprocesses-2011年01月20日-001.patch | dmalcolm, 2011年01月20日 20:23 | review | ||
| 10963.patch | rosslagerwall, 2011年03月31日 12:35 | review | ||
| Messages (11) | |||
|---|---|---|---|
| msg126643 - (view) | Author: Dave Malcolm (dmalcolm) (Python committer) | Date: 2011年01月20日 20:23 | |
If we start a short-lived process which finishes before we begin communicating with it (e.g. by crashing), we can receive a SIGPIPE due to the receiving process no longer existing. This becomes an EPIPE, which becomes an: OSError: [Errno 32] Broken pipe Arguably this is a bug; if the subprocess could crash, the user currently has to check for it by both monitoring the returncode _and_ catching OSError (then examining for this specific errno), which seems ugly to me. I'm attaching a patch for subprocess which handles this case, masking the OSError within the Popen implementation, so that you have to test for it within the returncode, in one place, rather than wrap every call with a try/except. It could be argued that this is incorrect, as it masks under-reads of stdin by the subprocess. However I believe a sanely-written subprocess ought to indicate success/failure back with its return code. This was originally filed downstream within the Red Hat bugzilla instance as: https://bugzilla.redhat.com/show_bug.cgi?id=667431 The handler part of the patch is based on a patch attached there by Federico Simoncelli; I don't know if he has signed a PSF contributor agreement, however the size of the patch is sufficiently small that I suspect it's not copyrightable, and I've somewhat rewritten it since; I wrote the unit test. |
|||
| msg126644 - (view) | Author: Antoine Pitrou (pitrou) * (Python committer) | Date: 2011年01月20日 20:26 | |
> It could be argued that this is incorrect, as it masks under-reads of > stdin by the subprocess. However I believe a sanely-written subprocess > ought to indicate success/failure back with its return code. It seems quite orthogonal. The subprocess could have terminated successfully while not all of the stdin bytes were consumed; EPIPE informs you of the latter. |
|||
| msg126934 - (view) | Author: Federico Simoncelli (simon3z) | Date: 2011年01月24日 17:08 | |
I agree they are orthogonal. The problem is that Popen.communicate doesn't support a way to ignore the exception and keep reading from stdout and sterr until the process dies. When the child closes the stdin its (error/debug/info) messages on stout/sterr will be lost. I am not just concerned about checking both the return-code and this exception, I am also worried about losing important information. |
|||
| msg126935 - (view) | Author: Antoine Pitrou (pitrou) * (Python committer) | Date: 2011年01月24日 17:11 | |
You are right, this is suboptimal. It would also be a behaviour change from currently, but it seems beneficial. |
|||
| msg132662 - (view) | Author: Ross Lagerwall (rosslagerwall) (Python committer) | Date: 2011年03月31日 12:35 | |
I'd argue that this is not a feature request but a bug. I did some testing of this issue and the problem is that EPIPE is only generated sometimes depending on the time the process takes to finish, the size of the data sent, the underlying mechanism used (select vs poll) and the whether anything happens between the starting of the process and the communicate() call. Here are some results (on my PC, I think some of these will vary on others): With poll: [sys.executable, 'c', 'pass']- no error ['dd', 'option=bad'] - varies between EPIPE and no error ['dd', 'option=bad'], sleep(1) - EPIPE With select: [sys.executable, 'c', 'pass']- EPIPE ['dd', 'option=bad'] - EPIPE ['dd', 'option=bad'], sleep(1) - EPIPE Only stdin (neither select or poll): [sys.executable, 'c', 'pass']- no error (error in 2.7) ['dd', 'option=bad'] - no error (error in 2.7) ['dd', 'option=bad'], sleep(1) - EPIPE (all of my tests appear to fail on Windows, they also generate EINVAL sometimes) I think it's best to remove all this inconsistency and fix it so that EPIPE is never generated and then backport it to 2.7, 3.1, 3.2. Attached is a patch which fixes it for poll, select, windows and adds two tests. |
|||
| msg132730 - (view) | Author: Ross Lagerwall (rosslagerwall) (Python committer) | Date: 2011年04月01日 06:34 | |
Marked #6457 as a duplicate. See #6457 for more discussion. |
|||
| msg132806 - (view) | Author: Antoine Pitrou (pitrou) * (Python committer) | Date: 2011年04月02日 17:50 | |
> I think it's best to remove all this inconsistency and fix it so that > EPIPE is never generated and then backport it to 2.7, 3.1, 3.2. > > Attached is a patch which fixes it for poll, select, windows and adds > two tests. The patch looks good to me. |
|||
| msg133031 - (view) | Author: Roundup Robot (python-dev) (Python triager) | Date: 2011年04月05日 14:10 | |
New changeset c10d55c51d81 by Ross Lagerwall in branch '2.7': Issue #10963: Ensure that subprocess.communicate() never raises EPIPE. http://hg.python.org/cpython/rev/c10d55c51d81 New changeset 158495d49f58 by Ross Lagerwall in branch '3.1': Issue #10963: Ensure that subprocess.communicate() never raises EPIPE. http://hg.python.org/cpython/rev/158495d49f58 |
|||
| msg133033 - (view) | Author: Ross Lagerwall (rosslagerwall) (Python committer) | Date: 2011年04月05日 14:14 | |
Committed, thanks. |
|||
| msg236951 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) | Date: 2015年03月01日 09:31 | |
self.stdout.close() also can fail with EPIPE or EINVAL if the stream is buffered (text streams are buffered). I.e. communicate() in text mode can loss the data. See also issue21619. |
|||
| msg260416 - (view) | Author: Martin Panter (martin.panter) * (Python committer) | Date: 2016年02月18日 00:14 | |
FTR Issue 26372 has been opened about Serhiy’s bug with stdin.close() raising EPIPE. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:57:11 | admin | set | github: 55172 |
| 2016年02月18日 00:14:03 | martin.panter | set | nosy:
+ martin.panter messages: + msg260416 |
| 2015年03月01日 09:31:25 | serhiy.storchaka | set | nosy:
+ serhiy.storchaka messages: + msg236951 |
| 2011年04月05日 14:14:29 | rosslagerwall | set | status: open -> closed type: enhancement -> behavior messages: + msg133033 assignee: rosslagerwall resolution: fixed stage: patch review -> resolved |
| 2011年04月05日 14:10:14 | python-dev | set | nosy:
+ python-dev messages: + msg133031 |
| 2011年04月02日 17:50:03 | pitrou | set | messages: + msg132806 |
| 2011年04月01日 06:34:01 | rosslagerwall | set | nosy:
+ amaury.forgeotdarc, dwalczak, mcrute, Yaniv.Aknin messages: + msg132730 |
| 2011年03月31日 12:35:19 | rosslagerwall | set | files:
+ 10963.patch nosy: + rosslagerwall messages: + msg132662 |
| 2011年01月24日 18:30:53 | giampaolo.rodola | set | nosy:
+ giampaolo.rodola |
| 2011年01月24日 17:11:30 | pitrou | set | nosy:
+ gregory.p.smith type: enhancement messages: + msg126935 |
| 2011年01月24日 17:08:01 | simon3z | set | nosy:
+ simon3z messages: + msg126934 |
| 2011年01月20日 20:26:56 | pitrou | set | nosy:
+ pitrou messages: + msg126644 |
| 2011年01月20日 20:23:29 | dmalcolm | create | |