Patchwork [3,of,6] procutil: factor out conditional creation of LineBufferedWrapper

login
register
mail settings
Submitter Manuel Jacob
Date July 5, 2020, 2:51 a.m.
Message ID <e5036c93535df6110089.1593917499@tmp.fritz.box>
Download mbox | patch
Permalink /patch/46620/
State Accepted
Headers show

Comments

Manuel Jacob - July 5, 2020, 2:51 a.m.
# HG changeset patch
# User Manuel Jacob <me@manueljacob.de>
# Date 1593857741 -7200
#      Sat Jul 04 12:15:41 2020 +0200
# Node ID e5036c93535df61100895be58ae8aabad5592328
# Parent  527b213d2d2416ce86bc17aac34851142dc37f77
# EXP-Topic stdio
procutil: factor out conditional creation of LineBufferedWrapper

At the same time, document the logic and generalize it to work on all Python
versions.
Yuya Nishihara - July 6, 2020, 11:19 a.m.
On Sun, 05 Jul 2020 04:51:39 +0200, Manuel Jacob wrote:
> # HG changeset patch
> # User Manuel Jacob <me@manueljacob.de>
> # Date 1593857741 -7200
> #      Sat Jul 04 12:15:41 2020 +0200
> # Node ID e5036c93535df61100895be58ae8aabad5592328
> # Parent  527b213d2d2416ce86bc17aac34851142dc37f77
> # EXP-Topic stdio
> procutil: factor out conditional creation of LineBufferedWrapper
> 
> At the same time, document the logic and generalize it to work on all Python
> versions.
> 
> diff --git a/mercurial/utils/procutil.py b/mercurial/utils/procutil.py
> --- a/mercurial/utils/procutil.py
> +++ b/mercurial/utils/procutil.py
> @@ -67,6 +67,18 @@
>  io.BufferedIOBase.register(LineBufferedWrapper)
>  
>  
> +def make_line_buffered(stream):
> +    if pycompat.ispy3 and not isinstance(stdout, io.BufferedIOBase):
                                            ^^^^^^
                                            s/stdout/stream/ ?

Patch

diff --git a/mercurial/utils/procutil.py b/mercurial/utils/procutil.py
--- a/mercurial/utils/procutil.py
+++ b/mercurial/utils/procutil.py
@@ -67,6 +67,18 @@ 
 io.BufferedIOBase.register(LineBufferedWrapper)
 
 
+def make_line_buffered(stream):
+    if pycompat.ispy3 and not isinstance(stdout, 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)