[pypy-commit] pypy py3k: Fixes for the struct module

amauryfa noreply at buildbot.pypy.org
Wed Oct 19 01:43:25 CEST 2011


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py3k
Changeset: r48221:3b27b16f499d
Date: 2011-10-18 23:58 +0200
http://bitbucket.org/pypy/pypy/changeset/3b27b16f499d/

Log:	Fixes for the struct module

diff --git a/lib_pypy/struct.py b/lib_pypy/struct.py
--- a/lib_pypy/struct.py
+++ b/lib_pypy/struct.py
@@ -48,7 +48,7 @@
     pass
 error = StructError
 def unpack_int(data,index,size,le):
-    bytes = [ord(b) for b in data[index:index+size]]
+    bytes = [b for b in data[index:index+size]]
     if le == 'little':
         bytes.reverse()
     number = 0L
@@ -73,11 +73,11 @@
     x=number
     res=[]
     for i in range(size):
-        res.append(chr(x&0xff))
+        res.append(x&0xff)
         x >>= 8
     if le == 'big':
         res.reverse()
-    return ''.join(res)
+    return bytes(res)
 
 def pack_signed_int(number,size,le):
     if not isinstance(number, (int,long)):
@@ -96,7 +96,7 @@
     return pack_int(number,size,le)
 
 def pack_char(char,size,le):
-    return str(char)
+    return bytes(char)
 
 def isinf(x):
     return x != 0.0 and x / 2 == x
@@ -107,10 +107,10 @@
     unsigned = float_pack(x, size)
     result = []
     for i in range(8):
-        result.append(chr((unsigned >> (i * 8)) & 0xFF))
+        result.append((unsigned >> (i * 8)) & 0xFF)
     if le == "big":
         result.reverse()
-    return ''.join(result)
+    return bytes(result)
 
 def unpack_float(data, index, size, le):
     binary = [data[i] for i in range(index, index + 8)]
@@ -266,7 +266,7 @@
     try:
         formatdef,endianness = formatmode[fmt[0]]
         index = 1
-    except KeyError:
+    except (IndexError, KeyError):
         formatdef,endianness = formatmode['@']
         index = 0
     return formatdef,endianness,index
@@ -327,25 +327,25 @@
             num_s = num
 
         if cur == 'x':
-            result += ['\0'*num]
+            result += [b'\0'*num]
         elif cur == 's':
-            if isinstance(args[0], str):
+            if isinstance(args[0], bytes):
                 padding = num - len(args[0])
-                result += [args[0][:num] + '\0'*padding]
+                result += [args[0][:num] + b'\0'*padding]
                 args.pop(0)
             else:
                 raise StructError("arg for string format not a string")
         elif cur == 'p':
-            if isinstance(args[0], str):
+            if isinstance(args[0], bytes):
                 padding = num - len(args[0]) - 1
 
                 if padding > 0:
-                    result += [chr(len(args[0])) + args[0][:num-1] + '\0'*padding]
+                    result += [bytes([len(args[0])]) + args[0][:num-1] + b'\0'*padding]
                 else:
                     if num<255:
-                        result += [chr(num-1) + args[0][:num-1]]
+                        result += [bytes([num-1]) + args[0][:num-1]]
                     else:
-                        result += [chr(255) + args[0][:num-1]]
+                        result += [bytes([255]) + args[0][:num-1]]
                 args.pop(0)
             else:
                 raise StructError("arg for string format not a string")
@@ -360,7 +360,7 @@
         i += 1
     if len(args) != 0:
         raise StructError("too many arguments for pack format")
-    return ''.join(result)
+    return b''.join(result)
 
 def unpack(fmt,data):
     """unpack(fmt, string) -> (v1, v2, ...)
@@ -392,7 +392,7 @@
             result.append(data[j:j+num])
             j += num
         elif cur == 'p':
-            n=ord(data[j])
+            n=data[j]
             if n >= num:
                 n = num-1
             result.append(data[j+1:j+n+1])
diff --git a/pypy/module/struct/formatiterator.py b/pypy/module/struct/formatiterator.py
--- a/pypy/module/struct/formatiterator.py
+++ b/pypy/module/struct/formatiterator.py
@@ -116,7 +116,7 @@
 
     def accept_str_arg(self):
         w_obj = self.accept_obj_arg()
-        return self.space.str_w(w_obj)
+        return self.space.bytes_w(w_obj)
 
     def accept_unicode_arg(self):
         w_obj = self.accept_obj_arg()
@@ -163,4 +163,7 @@
 
     @specialize.argtype(1)
     def appendobj(self, value):
-        self.result_w.append(self.space.wrap(value))
+        if isinstance(value, str):
+            self.result_w.append(self.space.wrapbytes(value))
+        else:
+            self.result_w.append(self.space.wrap(value))
diff --git a/pypy/module/struct/interp_struct.py b/pypy/module/struct/interp_struct.py
--- a/pypy/module/struct/interp_struct.py
+++ b/pypy/module/struct/interp_struct.py
@@ -22,7 +22,7 @@
     except StructError, e:
         raise e.at_applevel(space)
     result = ''.join(fmtiter.result)
-    return space.wrap(result)
+    return space.wrapbytes(result)
 
 
 @unwrap_spec(format=str, input='bufferstr')
diff --git a/pypy/module/struct/test/test_struct.py b/pypy/module/struct/test/test_struct.py
--- a/pypy/module/struct/test/test_struct.py
+++ b/pypy/module/struct/test/test_struct.py
@@ -78,13 +78,13 @@
         Check packing with the '<' format specifier.
         """
         pack = self.struct.pack
-        assert pack("<i", 0x41424344) == 'DCBA'
-        assert pack("<i", -3) == '\xfd\xff\xff\xff'
-        assert pack("<i", -2147483648) == '\x00\x00\x00\x80'
-        assert pack("<I", 0x81424344) == 'DCB\x81'
-        assert pack("<q", 0x4142434445464748) == 'HGFEDCBA'
-        assert pack("<q", -0x41B2B3B4B5B6B7B8) == 'HHIJKLM\xbe'
-        assert pack("<Q", 0x8142434445464748) == 'HGFEDCB\x81'
+        assert pack("<i", 0x41424344) == b'DCBA'
+        assert pack("<i", -3) == b'\xfd\xff\xff\xff'
+        assert pack("<i", -2147483648) == b'\x00\x00\x00\x80'
+        assert pack("<I", 0x81424344) == b'DCB\x81'
+        assert pack("<q", 0x4142434445464748) == b'HGFEDCBA'
+        assert pack("<q", -0x41B2B3B4B5B6B7B8) == b'HHIJKLM\xbe'
+        assert pack("<Q", 0x8142434445464748) == b'HGFEDCB\x81'
 
 
     def test_unpack_standard_little(self):
@@ -92,13 +92,13 @@
         Check unpacking with the '<' format specifier.
         """
         unpack = self.struct.unpack
-        assert unpack("<i", 'DCBA') == (0x41424344,)
-        assert unpack("<i", '\xfd\xff\xff\xff') == (-3,)
-        assert unpack("<i", '\x00\x00\x00\x80') == (-2147483648,)
-        assert unpack("<I", 'DCB\x81') == (0x81424344,)
-        assert unpack("<q", 'HGFEDCBA') == (0x4142434445464748,)
-        assert unpack("<q", 'HHIJKLM\xbe') == (-0x41B2B3B4B5B6B7B8,)
-        assert unpack("<Q", 'HGFEDCB\x81') == (0x8142434445464748,)
+        assert unpack("<i", b'DCBA') == (0x41424344,)
+        assert unpack("<i", b'\xfd\xff\xff\xff') == (-3,)
+        assert unpack("<i", b'\x00\x00\x00\x80') == (-2147483648,)
+        assert unpack("<I", b'DCB\x81') == (0x81424344,)
+        assert unpack("<q", b'HGFEDCBA') == (0x4142434445464748,)
+        assert unpack("<q", b'HHIJKLM\xbe') == (-0x41B2B3B4B5B6B7B8,)
+        assert unpack("<Q", b'HGFEDCB\x81') == (0x8142434445464748,)
 
 
     def test_pack_standard_big(self):
@@ -106,13 +106,13 @@
         Check packing with the '>' format specifier.
         """
         pack = self.struct.pack
-        assert pack(">i", 0x41424344) == 'ABCD'
-        assert pack(">i", -3) == '\xff\xff\xff\xfd'
-        assert pack(">i", -2147483648) == '\x80\x00\x00\x00'
-        assert pack(">I", 0x81424344) == '\x81BCD'
-        assert pack(">q", 0x4142434445464748) == 'ABCDEFGH'
-        assert pack(">q", -0x41B2B3B4B5B6B7B8) == '\xbeMLKJIHH'
-        assert pack(">Q", 0x8142434445464748) == '\x81BCDEFGH'
+        assert pack(">i", 0x41424344) == b'ABCD'
+        assert pack(">i", -3) == b'\xff\xff\xff\xfd'
+        assert pack(">i", -2147483648) == b'\x80\x00\x00\x00'
+        assert pack(">I", 0x81424344) == b'\x81BCD'
+        assert pack(">q", 0x4142434445464748) == b'ABCDEFGH'
+        assert pack(">q", -0x41B2B3B4B5B6B7B8) == b'\xbeMLKJIHH'
+        assert pack(">Q", 0x8142434445464748) == b'\x81BCDEFGH'
 
 
     def test_unpack_standard_big(self):
@@ -120,13 +120,13 @@
         Check unpacking with the '>' format specifier.
         """
         unpack = self.struct.unpack
-        assert unpack(">i", 'ABCD') == (0x41424344,)
-        assert unpack(">i", '\xff\xff\xff\xfd') == (-3,)
-        assert unpack(">i", '\x80\x00\x00\x00') == (-2147483648,)
-        assert unpack(">I", '\x81BCD') == (0x81424344,)
-        assert unpack(">q", 'ABCDEFGH') == (0x4142434445464748,)
-        assert unpack(">q", '\xbeMLKJIHH') == (-0x41B2B3B4B5B6B7B8,)
-        assert unpack(">Q", '\x81BCDEFGH') == (0x8142434445464748,)
+        assert unpack(">i", b'ABCD') == (0x41424344,)
+        assert unpack(">i", b'\xff\xff\xff\xfd') == (-3,)
+        assert unpack(">i", b'\x80\x00\x00\x00') == (-2147483648,)
+        assert unpack(">I", b'\x81BCD') == (0x81424344,)
+        assert unpack(">q", b'ABCDEFGH') == (0x4142434445464748,)
+        assert unpack(">q", b'\xbeMLKJIHH') == (-0x41B2B3B4B5B6B7B8,)
+        assert unpack(">Q", b'\x81BCDEFGH') == (0x8142434445464748,)
 
 
     def test_calcsize_native(self):
@@ -168,13 +168,13 @@
         sizeofi = calcsize("i")
         res = pack("bi", -2, 5)
         assert len(res) == 2 * sizeofi
-        assert res[0] == '\xfe'
-        assert res[1:sizeofi] == '\x00' * (sizeofi-1)    # padding
+        assert res[0] == 0xfe
+        assert res[1:sizeofi] == b'\x00' * (sizeofi-1)    # padding
         if self.native_is_bigendian:
-            assert res[sizeofi:] == '\x00' * (sizeofi-1) + '\x05'
+            assert res[sizeofi:] == b'\x00' * (sizeofi-1) + b'\x05'
         else:
-            assert res[sizeofi:] == '\x05' + '\x00' * (sizeofi-1)
-        assert pack("q", -1) == '\xff' * calcsize("q")
+            assert res[sizeofi:] == b'\x05' + b'\x00' * (sizeofi-1)
+        assert pack("q", -1) == b'\xff' * calcsize("q")
 
 
     def test_unpack_native(self):
@@ -185,7 +185,7 @@
         pack = self.struct.pack
         unpack = self.struct.unpack
         assert unpack("bi", pack("bi", -2, 5)) == (-2, 5)
-        assert unpack("q", '\xff' * calcsize("q")) == (-1,)
+        assert unpack("q", b'\xff' * calcsize("q")) == (-1,)
 
 
     def test_string_format(self):
@@ -194,13 +194,13 @@
         """
         pack = self.struct.pack
         unpack = self.struct.unpack
-        assert pack("7s", "hello") == "hello\x00\x00"
-        assert pack("5s", "world") == "world"
-        assert pack("3s", "spam") == "spa"
-        assert pack("0s", "foo") == ""
-        assert unpack("7s", "hello\x00\x00") == ("hello\x00\x00",)
-        assert unpack("5s3s", "worldspa") == ("world", "spa")
-        assert unpack("0s", "") == ("",)
+        assert pack("7s", b"hello") == b"hello\x00\x00"
+        assert pack("5s", b"world") == b"world"
+        assert pack("3s", b"spam") == b"spa"
+        assert pack("0s", b"foo") == b""
+        assert unpack("7s", b"hello\x00\x00") == (b"hello\x00\x00",)
+        assert unpack("5s3s", b"worldspa") == (b"world", b"spa")
+        assert unpack("0s", b"") == (b"",)
 
 
     def test_pascal_format(self):
@@ -209,17 +209,17 @@
         """
         pack = self.struct.pack
         unpack = self.struct.unpack
-        longstring = str(range(70))     # this has 270 chars
-        longpacked300 = "\xff" + longstring + "\x00" * (299-len(longstring))
-        assert pack("8p", "hello") == "\x05hello\x00\x00"
-        assert pack("6p", "world") == "\x05world"
-        assert pack("4p", "spam") == "\x03spa"
-        assert pack("1p", "foo") == "\x00"
-        assert pack("10p", longstring) == "\x09" + longstring[:9]
+        longstring = bytes(range(135)) * 2    # this has 270 chars
+        longpacked300 = b"\xff" + longstring + b"\x00" * (299-len(longstring))
+        assert pack("8p", b"hello") == b"\x05hello\x00\x00"
+        assert pack("6p", b"world") == b"\x05world"
+        assert pack("4p", b"spam") == b"\x03spa"
+        assert pack("1p", b"foo") == b"\x00"
+        assert pack("10p", longstring) == b"\x09" + longstring[:9]
         assert pack("300p", longstring) == longpacked300
-        assert unpack("8p", "\x05helloxx") == ("hello",)
-        assert unpack("5p", "\x80abcd") == ("abcd",)
-        assert unpack("1p", "\x03") == ("",)
+        assert unpack("8p", b"\x05helloxx") == (b"hello",)
+        assert unpack("5p", b"\x80abcd") == (b"abcd",)
+        assert unpack("1p", b"\x03") == (b"",)
         assert unpack("300p", longpacked300) == (longstring[:255],)
 
 
@@ -229,10 +229,10 @@
         """
         pack = self.struct.pack
         unpack = self.struct.unpack
-        assert pack("c", "?") == "?"
-        assert pack("5c", "a", "\xc0", "\x00", "\n", "-") == "a\xc0\x00\n-"
-        assert unpack("c", "?") == ("?",)
-        assert unpack("5c", "a\xc0\x00\n-") == ("a", "\xc0", "\x00", "\n", "-")
+        assert pack("c", b"?") == b"?"
+        assert pack("5c", b"a", b"\xc0", b"\x00", b"\n", b"-") == b"a\xc0\x00\n-"
+        assert unpack("c", b"?") == (b"?",)
+        assert unpack("5c", b"a\xc0\x00\n-") == (b"a", b"\xc0", b"\x00", b"\n", b"-")
 
 
     def test_pad_format(self):
@@ -241,10 +241,10 @@
         """
         pack = self.struct.pack
         unpack = self.struct.unpack
-        assert pack("x") == "\x00"
-        assert pack("5x") == "\x00" * 5
-        assert unpack("x", "?") == ()
-        assert unpack("5x", "hello") == ()
+        assert pack("x") == b"\x00"
+        assert pack("5x") == b"\x00" * 5
+        assert unpack("x", b"?") == ()
+        assert unpack("5x", b"hello") == ()
 
 
     def test_native_floats(self):
@@ -270,28 +270,28 @@
         """
         pack = self.struct.pack
         unpack = self.struct.unpack
-        assert pack("!d", 12.5) == '@)\x00\x00\x00\x00\x00\x00'
-        assert pack("<d", -12.5) == '\x00\x00\x00\x00\x00\x00)\xc0'
-        assert unpack("!d", '\xc0)\x00\x00\x00\x00\x00\x00') == (-12.5,)
-        assert unpack("<d", '\x00\x00\x00\x00\x00\x00)@') == (12.5,)
-        assert pack("!f", -12.5) == '\xc1H\x00\x00'
-        assert pack("<f", 12.5) == '\x00\x00HA'
-        assert unpack("!f", 'AH\x00\x00') == (12.5,)
-        assert unpack("<f", '\x00\x00H\xc1') == (-12.5,)
+        assert pack("!d", 12.5) == b'@)\x00\x00\x00\x00\x00\x00'
+        assert pack("<d", -12.5) == b'\x00\x00\x00\x00\x00\x00)\xc0'
+        assert unpack("!d", b'\xc0)\x00\x00\x00\x00\x00\x00') == (-12.5,)
+        assert unpack("<d", b'\x00\x00\x00\x00\x00\x00)@') == (12.5,)
+        assert pack("!f", -12.5) == b'\xc1H\x00\x00'
+        assert pack("<f", 12.5) == b'\x00\x00HA'
+        assert unpack("!f", b'AH\x00\x00') == (12.5,)
+        assert unpack("<f", b'\x00\x00H\xc1') == (-12.5,)
         raises(OverflowError, pack, "<f", 10e100)
 
     def test_bool(self):
         pack = self.struct.pack
         unpack = self.struct.unpack
-        assert pack("!?", True) == '\x01'
-        assert pack(">?", True) == '\x01'
-        assert pack("!?", False) == '\x00'
-        assert pack(">?", False) == '\x00'
-        assert pack("@?", True) == '\x01'
-        assert pack("@?", False) == '\x00'
+        assert pack("!?", True) == b'\x01'
+        assert pack(">?", True) == b'\x01'
+        assert pack("!?", False) == b'\x00'
+        assert pack(">?", False) == b'\x00'
+        assert pack("@?", True) == b'\x01'
+        assert pack("@?", False) == b'\x00'
 
     def test_transitiveness(self):
-        c = 'a'
+        c = b'a'
         b = 1
         h = 255
         i = 65535
@@ -333,15 +333,15 @@
         raises(error, calcsize, "!P")   # bad char in struct format
         raises(error, pack, "ii", 15)   # struct format requires more arguments
         raises(error, pack, "i", 3, 4)  # too many arguments for struct format
-        raises(error, unpack, "ii", "?")# unpack str size too short for format
-        raises(error, unpack, "b", "??")# unpack str size too long for format
-        raises(error, pack, "c", "foo") # expected a string of length 1
+        raises(error, unpack, "ii", b"?")# unpack str size too short for format
+        raises(error, unpack, "b", b"??")# unpack str size too long for format
+        raises(error, pack, "c", b"foo") # expected a string of length 1
         try:
             pack("0p")                  # bad '0p' in struct format
         except error:                   # (but ignored on CPython)
             pass
         if '__pypy__' in sys.builtin_module_names:
-            raises(error, unpack, "0p", "")   # segfaults on CPython 2.5.2!
+            raises(error, unpack, "0p", b"")   # segfaults on CPython 2.5.2!
         raises(error, pack, "b", 150)   # argument out of range
         # XXX the accepted ranges still differs between PyPy and CPython
 
@@ -373,7 +373,7 @@
         if '__pypy__' not in sys.builtin_module_names:
             skip("PyPy extension")
         data = self.struct.pack("uuu", u'X', u'Y', u'Z')
-        assert data == str(buffer(u'XYZ'))
+        assert data == bytes(buffer(u'XYZ'))
         assert self.struct.unpack("uuu", data) == (u'X', u'Y', u'Z')
 
 
@@ -406,9 +406,9 @@
         b = self.bytebuffer(19)
         sz = self.struct.calcsize("ii")
         self.struct.pack_into("ii", b, 2, 17, 42)
-        assert b[:] == ('\x00' * 2 +
+        assert b[:] == (b'\x00' * 2 +
                         self.struct.pack("ii", 17, 42) +
-                        '\x00' * (19-sz-2))
+                        b'\x00' * (19-sz-2))
 
     def test_unpack_from(self):
         b = self.bytebuffer(19)


More information about the pypy-commit mailing list