Author: Manuel Jacob <m...@manueljacob.de>
Branch: py3.3
Changeset: r78497:db201c02e7fc
Date: 2015-07-05 08:40 +0200
http://bitbucket.org/pypy/pypy/changeset/db201c02e7fc/

Log:    Try __bytes__ before __index__ when converting an object to bytes.

diff --git a/pypy/objspace/std/bytesobject.py b/pypy/objspace/std/bytesobject.py
--- a/pypy/objspace/std/bytesobject.py
+++ b/pypy/objspace/std/bytesobject.py
@@ -683,6 +683,14 @@
             raise OperationError(space.w_TypeError, space.wrap(
                     "encoding or errors without string argument"))
         return []
+    # Some object with __bytes__ special method
+    w_bytes_method = space.lookup(w_source, "__bytes__")
+    if w_bytes_method is not None:
+        w_bytes = space.get_and_call_function(w_bytes_method, w_source)
+        if not space.isinstance_w(w_bytes, space.w_bytes):
+            raise oefmt(space.w_TypeError,
+                        "__bytes__ returned non-bytes (type '%T')", w_bytes)
+        return [c for c in space.bytes_w(w_bytes)]
     # Is it an integer?
     # Note that we're calling space.getindex_w() instead of space.int_w().
     try:
@@ -707,7 +715,7 @@
         w_source = encode_object(space, w_source, encoding, errors)
         # and continue with the encoded string
 
-    return makebytesdata_w(space, w_source)
+    return _convert_from_buffer_or_iterable(space, w_source)
 
 def makebytesdata_w(space, w_source):
     w_bytes_method = space.lookup(w_source, "__bytes__")
@@ -717,7 +725,9 @@
             raise oefmt(space.w_TypeError,
                         "__bytes__ returned non-bytes (type '%T')", w_bytes)
         return [c for c in space.bytes_w(w_bytes)]
+    return _convert_from_buffer_or_iterable(space, w_source)
 
+def _convert_from_buffer_or_iterable(space, w_source):
     # String-like argument
     try:
         buf = space.buffer_w(w_source, space.BUF_FULL_RO)
diff --git a/pypy/objspace/std/test/test_bytesobject.py 
b/pypy/objspace/std/test/test_bytesobject.py
--- a/pypy/objspace/std/test/test_bytesobject.py
+++ b/pypy/objspace/std/test/test_bytesobject.py
@@ -757,6 +757,14 @@
                 return 3
         raises(TypeError, bytes, WithInt())
 
+    def test_fromobject___bytes__(self):
+        class WithIndex:
+            def __bytes__(self):
+                return b'a'
+            def __index__(self):
+                return 3
+        assert bytes(WithIndex()) == b'a'
+
     def test_getnewargs(self):
         assert  b"foo".__getnewargs__() == (b"foo",)
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to