Author: Philip Jenvey <[email protected]>
Branch: py3k
Changeset: r59405:c376b798a56b
Date: 2012-12-11 11:58 -0800
http://bitbucket.org/pypy/pypy/changeset/c376b798a56b/

Log:    disallow plain ints to from_bytes and non-bytes results from
        __bytes__

diff --git a/pypy/objspace/std/longtype.py b/pypy/objspace/std/longtype.py
--- a/pypy/objspace/std/longtype.py
+++ b/pypy/objspace/std/longtype.py
@@ -115,7 +115,8 @@
 
 @unwrap_spec(byteorder=str, signed=bool)
 def descr_from_bytes(space, w_cls, w_obj, byteorder, signed=False):
-    bytes = space.bytes_w(space.call_function(space.w_bytes, w_obj))
+    from pypy.objspace.std.stringtype import makebytesdata_w
+    bytes = ''.join(makebytesdata_w(space, w_obj))
     try:
         bigint = rbigint.frombytes(bytes, byteorder=byteorder, signed=signed)
     except InvalidEndiannessError:
diff --git a/pypy/objspace/std/stringtype.py b/pypy/objspace/std/stringtype.py
--- a/pypy/objspace/std/stringtype.py
+++ b/pypy/objspace/std/stringtype.py
@@ -1,5 +1,5 @@
 from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
-from pypy.interpreter.error import OperationError
+from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.objspace.std.stdtypedef import StdTypeDef, SMM
 from pypy.objspace.std.register_all import register_all
 
@@ -282,6 +282,14 @@
     return makebytesdata_w(space, w_source)
 
 def makebytesdata_w(space, w_source):
+    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):
+            msg = "__bytes__ returned non-bytes (type '%s')"
+            raise operationerrfmt(space.w_TypeError, msg,
+                                  space.type(w_bytes).getname(space))
+        return [c for c in space.bytes_w(w_bytes)]
 
     # String-like argument
     try:
@@ -292,10 +300,10 @@
     else:
         return [c for c in string]
 
-    w_bytes_method = space.lookup(w_source, "__bytes__")
-    if w_bytes_method:
-        w_bytes = space.get_and_call_function(w_bytes_method, w_source)
-        w_source = w_bytes
+    if space.isinstance_w(w_source, space.w_unicode):
+        raise OperationError(
+            space.w_TypeError,
+            space.wrap("cannot convert unicode object to bytes"))
 
     # sequence of bytes
     data = []
diff --git a/pypy/objspace/std/test/test_longobject.py 
b/pypy/objspace/std/test/test_longobject.py
--- a/pypy/objspace/std/test/test_longobject.py
+++ b/pypy/objspace/std/test/test_longobject.py
@@ -305,6 +305,7 @@
         assert int.from_bytes(b'\x01\x00', 'big') == 256
         assert int.from_bytes(b'\x00\x80', 'little', signed=True) == -32768
         assert int.from_bytes([255, 0, 0], 'big', signed=True) == -65536
+        raises(TypeError, int.from_bytes, 0, 'big')
         raises(TypeError, int.from_bytes, '', 'big')
         raises(ValueError, int.from_bytes, b'c', 'foo')
 
diff --git a/pypy/objspace/std/test/test_stringobject.py 
b/pypy/objspace/std/test/test_stringobject.py
--- a/pypy/objspace/std/test/test_stringobject.py
+++ b/pypy/objspace/std/test/test_stringobject.py
@@ -715,6 +715,11 @@
                 return b'pyramid'
         assert bytes(X()) == b'pyramid'
 
+        class Z:
+            def __bytes__(self):
+                return [3, 4]
+        raises(TypeError, bytes, Z())
+
     def test_getnewargs(self):
         assert  b"foo".__getnewargs__() == (b"foo",)
 
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to