Skip to content

Commit 77732be

Browse files
bpo-30404: The -u option now makes the stdout and stderr streams totally unbuffered. (#1667)
1 parent 0b5e61d commit 77732be

File tree

4 files changed

+17
-12
lines changed

4 files changed

+17
-12
lines changed

Doc/using/cmdline.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,13 +303,13 @@ Miscellaneous options
303303

304304
.. cmdoption:: -u
305305

306-
Force the binary layer of the stdout and stderr streams (which is
307-
available as their ``buffer`` attribute) to be unbuffered. The text I/O
308-
layer will still be line-buffered if writing to the console, or
309-
block-buffered if redirected to a non-interactive file.
306+
Force the stdout and stderr streams to be unbuffered.
310307

311308
See also :envvar:`PYTHONUNBUFFERED`.
312309

310+
.. versionchanged:: 3.7
311+
The text layer of the stdout and stderr streams now is unbuffered.
312+
313313

314314
.. cmdoption:: -v
315315

Lib/test/test_cmd_line.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,13 +221,12 @@ def test_unbuffered_output(self):
221221
rc, out, err = assert_python_ok('-u', '-c', code)
222222
data = err if stream == 'stderr' else out
223223
self.assertEqual(data, b'x', "binary %s not unbuffered" % stream)
224-
# Text is line-buffered
225-
code = ("import os, sys; sys.%s.write('x\\n'); os._exit(0)"
224+
# Text is unbuffered
225+
code = ("import os, sys; sys.%s.write('x'); os._exit(0)"
226226
% stream)
227227
rc, out, err = assert_python_ok('-u', '-c', code)
228228
data = err if stream == 'stderr' else out
229-
self.assertEqual(data.strip(), b'x',
230-
"text %s not line-buffered" % stream)
229+
self.assertEqual(data, b'x', "text %s not unbuffered" % stream)
231230

232231
def test_unbuffered_input(self):
233232
# sys.stdin still works with '-u'
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The -u option now makes the stdout and stderr streams unbuffered rather than
2+
line-buffered.

Python/pylifecycle.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,7 +1498,7 @@ create_stdio(PyObject* io,
14981498
PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res;
14991499
const char* mode;
15001500
const char* newline;
1501-
PyObject *line_buffering;
1501+
PyObject *line_buffering, *write_through;
15021502
int buffering, isatty;
15031503
_Py_IDENTIFIER(open);
15041504
_Py_IDENTIFIER(isatty);
@@ -1555,7 +1555,11 @@ create_stdio(PyObject* io,
15551555
Py_DECREF(res);
15561556
if (isatty == -1)
15571557
goto error;
1558-
if (isatty || Py_UnbufferedStdioFlag)
1558+
if (Py_UnbufferedStdioFlag)
1559+
write_through = Py_True;
1560+
else
1561+
write_through = Py_False;
1562+
if (isatty && !Py_UnbufferedStdioFlag)
15591563
line_buffering = Py_True;
15601564
else
15611565
line_buffering = Py_False;
@@ -1574,9 +1578,9 @@ create_stdio(PyObject* io,
15741578
newline = "\n";
15751579
#endif
15761580

1577-
stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OsssO",
1581+
stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OsssOO",
15781582
buf, encoding, errors,
1579-
newline, line_buffering);
1583+
newline, line_buffering, write_through);
15801584
Py_CLEAR(buf);
15811585
if (stream == NULL)
15821586
goto error;

0 commit comments

Comments
 (0)