Patchwork [03,of,11] ui: use latin-1 as "fat bytes" to preserve EOL behavior on py3

login
register
mail settings
Submitter Augie Fackler
Date March 26, 2017, 10:36 p.m.
Message ID <25355685cfaced26214c.1490567797@imladris.local>
Download mbox | patch
Permalink /patch/19702/
State Accepted
Headers show

Comments

Augie Fackler - March 26, 2017, 10:36 p.m.
# HG changeset patch
# User Augie Fackler <raf@durin42.com>
# Date 1490562355 14400
#      Sun Mar 26 17:05:55 2017 -0400
# Node ID 25355685cfaced26214c1fb89d191c3705dc52c7
# Parent  28149aad82cb12522f1ba50b0bb184d1f960a9c9
ui: use latin-1 as "fat bytes" to preserve EOL behavior on py3

This avoids the encoding issues present in the last patch which would
have led to problems in the future. Thanks to Yuya for the idea.

Patch

diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -1212,8 +1212,16 @@  class ui(object):
                                       suffix=extra['suffix'], text=True,
                                       dir=rdir)
         try:
-            f = os.fdopen(fd, pycompat.sysstr("w"))
-            f.write(encoding.strfromlocal(text))
+            if pycompat.ispy3:
+                # We use latin-1 as "fat bytes" so that we still get
+                # free EOL conversion on Python 3, but we avoid
+                # encode/decode problems.
+                f = os.fdopen(fd, pycompat.sysstr("w"),
+                              encoding=pycompat.sysstr("latin-1"))
+                f.write(text.decode("latin-1"))
+            else:
+                f = os.fdopen(fd, pycompat.sysstr("w"))
+                f.write(text)
             f.close()
 
             environ = {'HGUSER': user}
@@ -1235,8 +1243,14 @@  class ui(object):
                         onerr=error.Abort, errprefix=_("edit failed"),
                         blockedtag='editor')
 
-            f = open(name)
-            t = encoding.strtolocal(f.read())
+            if pycompat.ispy3:
+                # See above about "fat bytes" and latin-1.
+                f = open(name, pycompat.sysstr("r"),
+                         encoding=pycompat.sysstr("latin-1"))
+                t = f.read().encode("latin-1")
+            else:
+                f = open(name, pycompat.sysstr("r"))
+                t = f.read()
             f.close()
         finally:
             os.unlink(name)