-
-
Notifications
You must be signed in to change notification settings - Fork 31.6k
subprocess bufsize=1 docs are misleading #65531
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
https://docs.python.org/3.3/library/subprocess.html says "bufsize will be supplied as the corresponding argument to the open() function when creating the stdin/stdout/stderr pipe file objects: ... 1 means line buffered" but it calls io.open with 'wb' and 'rb': http://hg.python.org/cpython/file/c9cb931b20f4/Lib/subprocess.py#l828 This puts the file in binary mode, and https://docs.python.org/3.3/library/functions.html#open says "1 to select line buffering (only usable in text mode)" Even with universal_newlines=True, the TextIOWrapper isn't passed line_buffering=True. There's actually no way to get line buffering any more. |
It looks like a bug in the subprocess module e.g., if child process does: sys.stdout.write(sys.stdin.readline())
sys.stdout.flush() and the parent: p.stdin.write(line) #NOTE: no flush
line = p.stdout.readline() then a deadlock may happen with bufsize=1 (because it is equivalent to bufsize=-1 in the current code) Surprisingly, it works if universal_newlines=True but only for C implementation of io i.e., if C extension is disabled: import io, _pyio
io.TextIOWrapper = _pyio.TextIOWrapper then it blocks forever even if universal_newlines=True with bufsize=1 that is clearly wrong (<-- bug) e.g., C implementation works because it sets
Python io implementation doesn't flush with only It doesn't deadlock if bufsize=0 whether universal_newlines=True or not. Note: Python 2.7 doesn't deadlock with bufsize=0 and bufsize=1 in this case as expected. What is not clear is whether it should work with universal_newline=False and bufsize=1: both current docs and Python 2.7 behaviour say that there should not be a deadlock. I've updated the docs to mention that bufsize=1 works only with Patch is uploaded. |
Related issue bpo-21396 |
Thanks for the report, diagnosis and patch! Your change looks good to me. I'll commit it soon. |
I've changed test_newlines to work also with Python io implementation. I've updated the patch. Note: tests use 10 seconds timeouts: I don't know how long it should take to read back a line from a subprocess so that the timeout would indicate a deadlock. |
Perhaps you can avoid the 10 s deadlock timeout and threading in your test by closing the underlying input pipe file descriptor (or raw file object), without flushing it. Also, it seems to me that “line_buffering=True” is redundant with “write_through=True”. I’m not super familiar with the new write-through mode though, so I could be wrong. Perhaps the change in “subprocess.py” may not be needed at least once bpo-21396 is fixed. |
Sorry, it seems I was wrong on the second point. Looking closer, it seems write-through mode only flushes the TextIOWrapper layer, not the underlying binary file object, whereas line-buffering mode flushes everything to the OS, so the extra line_buffering=True flag would be needed. |
yes, line_buffering=(bufsize == 1) is necessary to support the current Note: the current patch for issue bpo-21396 (making C and Python io do the
It is a good idea. There could be portability issues with the test: it I've uploaded a new patch with the updated tests. Please, review. |
On second thoughts maybe the idea of closing the input is not such a good idea in practice. Once you call os.close() on the file descriptor, that descriptor becomes unallocated, and I can’t see any way to prevent p.stdin.close(), Popen() context, destructors, etc from trying to close the file descriptor again. If the Python test suite is ever multithreaded (I’m not really familiar with it), that would be a real problem. In any case closing an unallocated file descriptor is a bad idea. Maybe the deadlocking version is more appropriate after all. |
to be clear: the test itself doesn't use threads, If the test were to run in the presence of multiple threads then I don't think tests are expected to run in the presence of multiple |
I've updated the patch to remove changes to test_universal_newlines |
I've asked about thread-safety of tests on python-dev mailing list: |
https://mail.python.org/pipermail/python-dev/2014-May/134541.html It seems the test may be left as is. Please, review the patch. |
I'm fairly sure this hasn't been fixed in tip so I think we're still waiting on patch review. Is there an update here? |
The latest patch looks good to me. |
New changeset 38867f90f1d9 by Antoine Pitrou in branch '3.4': New changeset 763d565e5840 by Antoine Pitrou in branch 'default': |
Pushed! Thank you! |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: