[pypy-commit] pypy fix-struct-unpack-Q: generalize the test and the fix: it's not only about Q, but about all the unsigned types; this also fix it on 32bit

antocuni pypy.commits at gmail.com
Fri Oct 28 12:38:01 EDT 2016


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: fix-struct-unpack-Q
Changeset: r87974:cced34dd6dde
Date: 2016-10-28 18:33 +0200
http://bitbucket.org/pypy/pypy/changeset/cced34dd6dde/

Log:	generalize the test and the fix: it's not only about Q, but about
	all the unsigned types; this also fix it on 32bit

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
@@ -1,3 +1,4 @@
+from rpython.rlib.rarithmetic import r_uint, r_ulonglong, maxint, intmask
 from rpython.rlib import jit
 from rpython.rlib.objectmodel import specialize
 from rpython.rlib.rstring import StringBuilder
@@ -148,15 +149,15 @@
 
     @specialize.argtype(1)
     def appendobj(self, value):
-        from rpython.rlib.rarithmetic import r_uint, maxint, intmask
-        if isinstance(value, r_uint):
-            # native-size uint: try to wrap it inside a native int if it fits,
-            # as CPython does
+        if isinstance(value, (r_uint, r_ulonglong)):
+            # unsigned int: space.wrap would wrap it inside a long, but
+            # CPython tries hard to return an int, if it fits
             if value <= maxint:
                 w_value = self.space.wrap(intmask(value))
             else:
                 w_value = self.space.wrap(value)
         else:
+            # generic type, just use space.wrap
             w_value = self.space.wrap(value)
         #
         self.result_w.append(w_value)
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
@@ -431,17 +431,20 @@
     def test_overflow(self):
         raises(self.struct.error, self.struct.pack, 'i', 1<<65)
 
-    def test_unpack_Q(self):
+    def test_unpack_unsigned(self):
         import sys
-        buf = self.struct.pack('Q', sys.maxint)
-        obj, = self.struct.unpack('Q', buf)
-        assert obj == sys.maxint
-        assert type(obj) is int
+        for fmt in 'ILQ':
+            # check that we return an int, if it fits
+            buf = self.struct.pack(fmt, 42)
+            val, = self.struct.unpack(fmt, buf)
+            assert val == 42
+            assert type(val) is int
         #
+        # check that we return a long, if it doesn't fit into an int
         buf = self.struct.pack('Q', sys.maxint+1)
-        obj, = self.struct.unpack('Q', buf)
-        assert obj == sys.maxint+1
-        assert type(obj) is long
+        val, = self.struct.unpack('Q', buf)
+        assert val == sys.maxint+1
+        assert type(val) is long
 
 class AppTestStructBuffer(object):
     spaceconfig = dict(usemodules=['struct', '__pypy__'])


More information about the pypy-commit mailing list