Patchwork D299: py3: introduce a wrapper for __builtins__.{raw_,}input()

login
register
mail settings
Submitter phabricator
Date Aug. 15, 2017, 8:50 p.m.
Message ID <552b6208175200997395c832bf471b4e@localhost.localdomain>
Download mbox | patch
Permalink /patch/23043/
State Not Applicable
Headers show

Comments

phabricator - Aug. 15, 2017, 8:50 p.m.
durin42 updated this revision to Diff 948.
durin42 edited the summary of this revision.
durin42 retitled this revision from "pycompat: introduce a wrapper for __builtins__.{raw_,}input()" to "py3: introduce a wrapper for __builtins__.{raw_,}input()".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D299?vs=801&id=948

REVISION DETAIL
  https://phab.mercurial-scm.org/D299

AFFECTED FILES
  hgext/hgk.py
  mercurial/encoding.py
  mercurial/pycompat.py
  mercurial/ui.py
  mercurial/util.py

CHANGE DETAILS




To: durin42, #hg-reviewers
Cc: yuja, mercurial-devel

Patch

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -172,6 +172,18 @@ 
 def safehasattr(thing, attr):
     return getattr(thing, attr, _notset) is not _notset
 
+def bytesinput(fin, fout, *args, **kwargs):
+    sin, sout = sys.stdin, sys.stdout
+    try:
+        if pycompat.ispy3:
+            sys.stdin, sys.stdout = encoding.strio(fin), encoding.strio(fout)
+            return pycompat.bytestr(input(*args, **kwargs))
+        else:
+            sys.stdin, sys.stdout = fin, fout
+            return raw_input(*args, **kwargs)
+    finally:
+        sys.stdin, sys.stdout = sin, sout
+
 def bitsfrom(container):
     bits = 0
     for bit in container:
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -1217,18 +1217,10 @@ 
         self.write(prompt, prompt=True)
         self.flush()
 
-        # instead of trying to emulate raw_input, swap (self.fin,
-        # self.fout) with (sys.stdin, sys.stdout)
-        oldin = sys.stdin
-        oldout = sys.stdout
-        sys.stdin = self.fin
-        sys.stdout = self.fout
         # prompt ' ' must exist; otherwise readline may delete entire line
         # - http://bugs.python.org/issue12833
         with self.timeblockedsection('stdio'):
-            line = raw_input(' ')
-        sys.stdin = oldin
-        sys.stdout = oldout
+            line = util.bytesinput(self.fin, self.fout, r' ')
 
         # When stdin is in binary mode on Windows, it can cause
         # raw_input() to emit an extra trailing carriage return
diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py
--- a/mercurial/pycompat.py
+++ b/mercurial/pycompat.py
@@ -304,6 +304,7 @@ 
     stdin = sys.stdin
     stdout = sys.stdout
     stderr = sys.stderr
+
     if getattr(sys, 'argv', None) is not None:
         sysargv = sys.argv
     sysplatform = sys.platform
diff --git a/mercurial/encoding.py b/mercurial/encoding.py
--- a/mercurial/encoding.py
+++ b/mercurial/encoding.py
@@ -8,6 +8,7 @@ 
 from __future__ import absolute_import
 
 import array
+import io
 import locale
 import os
 import unicodedata
@@ -573,3 +574,16 @@ 
             c = chr(ord(c.decode("utf-8")) & 0xff)
         r += c
     return r
+
+class strio(io.TextIOWrapper):
+    """Wrapper around TextIOWrapper that respects hg's encoding assumptions.
+
+    Also works around Python closing streams.
+    """
+
+    def __init__(self, buffer, **kwargs):
+        kwargs[r'encoding'] = encoding
+        super(strio, self).__init__(buffer, **kwargs)
+
+    def __del__(self):
+        """Override __del__ so it doesn't close the underlying stream."""
diff --git a/hgext/hgk.py b/hgext/hgk.py
--- a/hgext/hgk.py
+++ b/hgext/hgk.py
@@ -50,6 +50,7 @@ 
     patch,
     registrar,
     scmutil,
+    util,
 )
 
 cmdtable = {}
@@ -96,7 +97,7 @@ 
     while True:
         if opts['stdin']:
             try:
-                line = raw_input().split(' ')
+                line = util.bytesinput(ui.fin, ui.fout).split(' ')
                 node1 = line[0]
                 if len(line) > 1:
                     node2 = line[1]
@@ -177,7 +178,7 @@ 
     prefix = ""
     if opts['stdin']:
         try:
-            (type, r) = raw_input().split(' ')
+            (type, r) = util.bytesinput(ui.fin, ui.fout).split(' ')
             prefix = "    "
         except EOFError:
             return
@@ -195,7 +196,7 @@ 
         catcommit(ui, repo, n, prefix)
         if opts['stdin']:
             try:
-                (type, r) = raw_input().split(' ')
+                (type, r) = util.bytesinput(ui.fin, ui.fout).split(' ')
             except EOFError:
                 break
         else: