Patchwork [04,of,10,py3] scmutil: convert exception to bytes in a Py3-friendly manner

login
register
mail settings
Submitter Augie Fackler
Date May 29, 2017, 2:32 p.m.
Message ID <6e1ab7424617c7c7afca.1496068346@imladris.local>
Download mbox | patch
Permalink /patch/21051/
State Accepted
Headers show

Comments

Augie Fackler - May 29, 2017, 2:32 p.m.
# HG changeset patch
# User Augie Fackler <raf@durin42.com>
# Date 1496000686 14400
#      Sun May 28 15:44:46 2017 -0400
# Node ID 6e1ab7424617c7c7afca7faab559507c5e816a9c
# Parent  f1ae981927af4d2d75e2a0bc58c733c9a90c085b
scmutil: convert exception to bytes in a Py3-friendly manner

As far as I can tell, the Abort instance might contain localized data,
so we need to str() then convert to bytes by hand.
Yuya Nishihara - May 30, 2017, 12:49 p.m.
On Mon, 29 May 2017 10:32:26 -0400, Augie Fackler wrote:
> # HG changeset patch
> # User Augie Fackler <raf@durin42.com>
> # Date 1496000686 14400
> #      Sun May 28 15:44:46 2017 -0400
> # Node ID 6e1ab7424617c7c7afca7faab559507c5e816a9c
> # Parent  f1ae981927af4d2d75e2a0bc58c733c9a90c085b
> scmutil: convert exception to bytes in a Py3-friendly manner
> 
> As far as I can tell, the Abort instance might contain localized data,
> so we need to str() then convert to bytes by hand.
> 
> diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
> --- a/mercurial/scmutil.py
> +++ b/mercurial/scmutil.py
> @@ -187,7 +187,10 @@ def callcatch(ui, func):
>              ui.warn(_("(%s)\n") % inst.hint)
>          return 1
>      except error.Abort as inst:
> -        ui.warn(_("abort: %s\n") % inst)
> +        msg = str(inst)
> +        if not isinstance(msg, bytes):
> +            msg = encoding.unitolocal(msg)
> +        ui.warn(_("abort: %s\n") % msg)

This works as follows on Python 3:

 1. str(inst) converts non-ascii bytes in b'\xXX' form
 2. escaped "b'...'" unicode is converted back to bytes

Perhaps we'll need to add __bytes__() to our exception classes.
Augie Fackler - May 31, 2017, 7:02 p.m.
> On May 30, 2017, at 08:49, Yuya Nishihara <yuya@tcha.org> wrote:
> 
> On Mon, 29 May 2017 10:32:26 -0400, Augie Fackler wrote:
>> # HG changeset patch
>> # User Augie Fackler <raf@durin42.com>
>> # Date 1496000686 14400
>> #      Sun May 28 15:44:46 2017 -0400
>> # Node ID 6e1ab7424617c7c7afca7faab559507c5e816a9c
>> # Parent  f1ae981927af4d2d75e2a0bc58c733c9a90c085b
>> scmutil: convert exception to bytes in a Py3-friendly manner
>> 
>> As far as I can tell, the Abort instance might contain localized data,
>> so we need to str() then convert to bytes by hand.
>> 
>> diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
>> --- a/mercurial/scmutil.py
>> +++ b/mercurial/scmutil.py
>> @@ -187,7 +187,10 @@ def callcatch(ui, func):
>>             ui.warn(_("(%s)\n") % inst.hint)
>>         return 1
>>     except error.Abort as inst:
>> -        ui.warn(_("abort: %s\n") % inst)
>> +        msg = str(inst)
>> +        if not isinstance(msg, bytes):
>> +            msg = encoding.unitolocal(msg)
>> +        ui.warn(_("abort: %s\n") % msg)
> 
> This works as follows on Python 3:
> 
> 1. str(inst) converts non-ascii bytes in b'\xXX' form
> 2. escaped "b'...'" unicode is converted back to bytes
> 
> Perhaps we'll need to add __bytes__() to our exception classes.

Indeed, I'd believe that. Should we proceed with this patch as-is and revisit the particular b'' repr ugly when we trip on it?

(I'm honestly not sure how we should proceed here.)

Patch

diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -187,7 +187,10 @@  def callcatch(ui, func):
             ui.warn(_("(%s)\n") % inst.hint)
         return 1
     except error.Abort as inst:
-        ui.warn(_("abort: %s\n") % inst)
+        msg = str(inst)
+        if not isinstance(msg, bytes):
+            msg = encoding.unitolocal(msg)
+        ui.warn(_("abort: %s\n") % msg)
         if inst.hint:
             ui.warn(_("(%s)\n") % inst.hint)
     except ImportError as inst: