changeset 45040:fd205a9c358a

procutil: factor out conditional creation of LineBufferedWrapper At the same time, document the logic and generalize it to work on all Python versions.
author Manuel Jacob <me@manueljacob.de>
date Sat, 04 Jul 2020 12:15:41 +0200
parents 2bfbd7d2c204
children 1053f878dd46
files mercurial/utils/procutil.py
diffstat 1 files changed, 13 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/utils/procutil.py	Thu Jul 02 04:37:18 2020 +0200
+++ b/mercurial/utils/procutil.py	Sat Jul 04 12:15:41 2020 +0200
@@ -67,6 +67,18 @@
 io.BufferedIOBase.register(LineBufferedWrapper)
 
 
+def make_line_buffered(stream):
+    if pycompat.ispy3 and not isinstance(stream, io.BufferedIOBase):
+        # On Python 3, buffered streams can be expected to subclass
+        # BufferedIOBase. This is definitively the case for the streams
+        # initialized by the interpreter. For unbuffered streams, we don't need
+        # to emulate line buffering.
+        return stream
+    if isinstance(stream, LineBufferedWrapper):
+        return stream
+    return LineBufferedWrapper(stream)
+
+
 # glibc determines buffering on first write to stdout - if we replace a TTY
 # destined stdout with a pipe destined stdout (e.g. pager), we want line
 # buffering (or unbuffered, on Windows)
@@ -77,10 +89,7 @@
     elif pycompat.ispy3:
         # On Python 3, buffered binary streams can't be set line-buffered.
         # Therefore we have a wrapper that implements line buffering.
-        if isinstance(stdout, io.BufferedIOBase) and not isinstance(
-            stdout, LineBufferedWrapper
-        ):
-            stdout = LineBufferedWrapper(stdout)
+        stdout = make_line_buffered(stdout)
     else:
         stdout = os.fdopen(stdout.fileno(), 'wb', 1)