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

login
register
mail settings
Submitter phabricator
Date Aug. 16, 2017, 3:47 a.m.
Message ID <a412c6ce3319c5fa059cfcee82ef7a16@localhost.localdomain>
Download mbox | patch
Permalink /patch/23066/
State Not Applicable
Headers show

Comments

phabricator - Aug. 16, 2017, 3:47 a.m.
This revision was automatically updated to reflect the committed changes.
durin42 marked an inline comment as done.
Closed by commit rHGd390726b575d: py3: introduce a wrapper for __builtins__.{raw_,}input() (authored by durin42).

CHANGED PRIOR TO COMMIT
  https://phab.mercurial-scm.org/D299?vs=948&id=971#toc

REPOSITORY
  rHG Mercurial

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

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

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

CHANGE DETAILS




To: durin42, #hg-reviewers, yuja
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 encoding.strtolocal(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/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: