Patchwork pycompat: try __bytes__() to convert object to bytestr

login
register
mail settings
Submitter Yuya Nishihara
Date May 24, 2017, 3:36 p.m.
Message ID <09a28b35aef55ffd4098.1495640206@mimosa>
Download mbox | patch
Permalink /patch/20879/
State Accepted
Headers show

Comments

Yuya Nishihara - May 24, 2017, 3:36 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1493866267 -32400
#      Thu May 04 11:51:07 2017 +0900
# Node ID 09a28b35aef55ffd4098fd37059850560bf5690a
# Parent  57d6c0c74b1bbc83e9a511a4a1fa8b57e2457046
pycompat: try __bytes__() to convert object to bytestr

It should be better than using __str__() unconditionally.
Augie Fackler - May 24, 2017, 8:31 p.m.
On Thu, May 25, 2017 at 12:36:46AM +0900, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara <yuya@tcha.org>
> # Date 1493866267 -32400
> #      Thu May 04 11:51:07 2017 +0900
> # Node ID 09a28b35aef55ffd4098fd37059850560bf5690a
> # Parent  57d6c0c74b1bbc83e9a511a4a1fa8b57e2457046
> pycompat: try __bytes__() to convert object to bytestr

queued, thanks

Patch

diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py
--- a/mercurial/pycompat.py
+++ b/mercurial/pycompat.py
@@ -87,6 +87,14 @@  if ispy3:
         >>> s = bytestr(b'foo')
         >>> assert s is bytestr(s)
 
+        __bytes__() should be called if provided:
+
+        >>> class bytesable(object):
+        ...     def __bytes__(self):
+        ...         return b'bytes'
+        >>> bytestr(bytesable())
+        b'bytes'
+
         There's no implicit conversion from non-ascii str as its encoding is
         unknown:
 
@@ -127,7 +135,8 @@  if ispy3:
         def __new__(cls, s=b''):
             if isinstance(s, bytestr):
                 return s
-            if not isinstance(s, (bytes, bytearray)):
+            if (not isinstance(s, (bytes, bytearray))
+                and not hasattr(s, u'__bytes__')):  # hasattr-py3-only
                 s = str(s).encode(u'ascii')
             return bytes.__new__(cls, s)