for the Windows console, this only applies when
:envvar:`PYTHONLEGACYWINDOWSSTDIO` is also set.
- * When interactive, ``stdout`` and ``stderr`` streams are line-buffered.
- Otherwise, they are block-buffered like regular text files. You can
- override this value with the :option:`-u` command-line option.
+ * When interactive, the ``stdout`` stream is line-buffered. Otherwise,
+ it is block-buffered like regular text files. The ``stderr`` stream
+ is line-buffered in both cases. You can make both streams unbuffered
+ by passing the :option:`-u` command-line option or setting the
+ :envvar:`PYTHONUNBUFFERED` environment variable.
+
+ .. versionchanged:: 3.9
+ Non-interactive ``stderr`` is now line-buffered instead of fully
+ buffered.
.. note::
import subprocess
import sys
import tempfile
+import textwrap
import unittest
from test import support
from test.support.script_helper import (
)
check_output(text)
+ def test_non_interactive_output_buffering(self):
+ code = textwrap.dedent("""
+ import sys
+ out = sys.stdout
+ print(out.isatty(), out.write_through, out.line_buffering)
+ err = sys.stderr
+ print(err.isatty(), err.write_through, err.line_buffering)
+ """)
+ args = [sys.executable, '-c', code]
+ proc = subprocess.run(args, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, text=True, check=True)
+ self.assertEqual(proc.stdout,
+ 'False False False\n'
+ 'False False True\n')
+
def test_unbuffered_output(self):
# Test expected operation of the '-u' switch
for stream in ('stdout', 'stderr'):
Nick Seidenman
Michael Seifert
Žiga Seilnacht
+Jendrik Seipp
Michael Selik
Yury Selivanov
Fred Sells
--- /dev/null
+By default, ``sys.stderr`` is line-buffered now, even if ``stderr`` is
+redirected to a file. You can still make ``sys.stderr`` unbuffered by
+passing the :option:`-u` command-line option or setting the
+:envvar:`PYTHONUNBUFFERED` environment variable.
+
+(Contributed by Jendrik Seipp in bpo-13601.)
write_through = Py_True;
else
write_through = Py_False;
- if (isatty && buffered_stdio)
+ if (buffered_stdio && (isatty || fd == fileno(stderr)))
line_buffering = Py_True;
else
line_buffering = Py_False;