You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Make stdout and stderr truly unbuffered when using -u option #74589
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:
assignee=Noneclosed_at=<Date2017-10-04.17:26:10.442>created_at=<Date2017-05-19.15:52:05.216>labels= ['interpreter-core', 'type-feature', '3.7', 'expert-IO']
title='Make stdout and stderr truly unbuffered when using -u option'updated_at=<Date2017-10-13.12:16:36.996>user='https://github.com/serhiy-storchaka'
In Python 2 when run the interpreter with the -u option the stdout and stderr streams are unbuffered. In Python 3 they become just line-buffered. This is because initially there was no way to create unbuffered text streams. But since Python 3.3 TextIOWrapper supports unbuffered output binary stream and accepts the write_through argument which switch off its own buffering.
Proposed patch makes the stdout and stderr streams truly unbuffered when run with the -u option.
changed the title [-]Make stdout and stderr truly unbuffered when run with the -u option[/-][+]Make stdout and stderr truly unbuffered when using -u option[/+]on May 19, 2017
"If write_through is True, calls to write() are guaranteed not to be buffered: any data written on the TextIOWrapper object is immediately handled to its underlying binary buffer."
I didn't know write_through. It seems like it was introduced in Python 3.7: bpo-30526, commit 3c2817b.
While I hope that users of the -u options expect the slow-down, would it be possible to benchmark it?
For example, try to write setup.py content character by character to stdout using -u or not, into a TTY, into a pipe and/or a file. I'm curious if the line buffering vs really unbuffered has a significant impact on performances.
$ ./python -m timeit -s 'import sys' -s 'with open("setup.py") as f: s = f.readlines()''sys.stderr.writelines(s)'2>/dev/null
200 loops, best of 5: 1.07 msec per loop
$ ./python -u -m timeit -s 'import sys' -s 'with open("setup.py") as f: s = f.readlines()''sys.stderr.writelines(s)'2>/dev/null
Unpatched: 50 loops, best of 5: 5.89 msec per loop
Patched: 100 loops, best of 5: 3.32 msec per loop
Writing separate characters:
$ ./python -m timeit -s 'import sys' -s 'with open("setup.py") as f: s = list(f.read())''sys.stderr.writelines(s)'2>/dev/null
10 loops, best of 5: 30 msec per loop
$ ./python -u -m timeit -s 'import sys' -s 'with open("setup.py") as f: s = list(f.read())''sys.stderr.writelines(s)'2>/dev/null
Unpatched: 5 loops, best of 5: 49.2 msec per loop
Patched: 2 loops, best of 5: 137 msec per loop
Note that if output by lines, the patch speeds up the output! Actually the output is fast enough with buffering and without. The only slowdown is exposed when output by characters, but this is uncommon case. And if you output by characters (in case of drawing a progressbar or like), then perhaps you want the characters been displayed immediately, without buffering.
New changeset 77732be by Serhiy Storchaka in branch 'master': bpo-30404: The -u option now makes the stdout and stderr streams totally unbuffered. (bpo-1667) 77732be
Activity
serhiy-storchaka commentedon May 19, 2017
In Python 2 when run the interpreter with the -u option the stdout and stderr streams are unbuffered. In Python 3 they become just line-buffered. This is because initially there was no way to create unbuffered text streams. But since Python 3.3 TextIOWrapper supports unbuffered output binary stream and accepts the write_through argument which switch off its own buffering.
Proposed patch makes the stdout and stderr streams truly unbuffered when run with the -u option.
[-]Make stdout and stderr truly unbuffered when run with the -u option[/-][+]Make stdout and stderr truly unbuffered when using -u option[/+]vstinner commentedon Jun 19, 2017
Oh, I like #1667
"If write_through is True, calls to write() are guaranteed not to be buffered: any data written on the TextIOWrapper object is immediately handled to its underlying binary buffer."
I didn't know write_through. It seems like it was introduced in Python 3.7: bpo-30526, commit 3c2817b.
vstinner commentedon Jun 19, 2017
While I hope that users of the -u options expect the slow-down, would it be possible to benchmark it?
For example, try to write setup.py content character by character to stdout using -u or not, into a TTY, into a pipe and/or a file. I'm curious if the line buffering vs really unbuffered has a significant impact on performances.
serhiy-storchaka commentedon Jun 19, 2017
Writing separate lines:
Writing separate characters:
vstinner commentedon Jun 19, 2017
Hum. It has an huge impact on performances. Would it make sense to have two command line options to choose between unbuffered and line buffered?
The C setvbuf() function uses these constants:
serhiy-storchaka commentedon Jun 19, 2017
Note that if output by lines, the patch speeds up the output! Actually the output is fast enough with buffering and without. The only slowdown is exposed when output by characters, but this is uncommon case. And if you output by characters (in case of drawing a progressbar or like), then perhaps you want the characters been displayed immediately, without buffering.
See also bpo-13601.
serhiy-storchaka commentedon Oct 4, 2017
If there is a need in making redirected stdout line-buffered, a new option can be added in separate issue.
serhiy-storchaka commentedon Oct 4, 2017
New changeset 77732be by Serhiy Storchaka in branch 'master':
bpo-30404: The -u option now makes the stdout and stderr streams totally unbuffered. (bpo-1667)
77732be
berkerpeksag commentedon Oct 13, 2017
New changeset 7f58097 by Berker Peksag in branch 'master':
bpo-28647: Update -u documentation after bpo-30404 (GH-3961)
7f58097