[pypy-commit] pypy fix-struct-unpack-Q: a failing test and the fix: on CPython, struct.unpack('Q', ...) tries hard to return an int, while PyPy always returned a long

antocuni pypy.commits at gmail.com
Thu Oct 27 12:09:21 EDT 2016


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: fix-struct-unpack-Q
Changeset: r87960:0fc23c94e459
Date: 2016-10-27 18:08 +0200
http://bitbucket.org/pypy/pypy/changeset/0fc23c94e459/

Log:	a failing test and the fix: on CPython, struct.unpack('Q',...) tries
	hard to return an int, while PyPy always returned a long

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
@@ -148,7 +148,18 @@
 
     @specialize.argtype(1)
     def appendobj(self, value):
-        self.result_w.append(self.space.wrap(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 value <= maxint:
+                w_value = self.space.wrap(intmask(value))
+            else:
+                w_value = self.space.wrap(value)
+        else:
+            w_value = self.space.wrap(value)
+        #
+        self.result_w.append(w_value)
 
     def get_pos(self):
         return self.pos
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,6 +431,17 @@
     def test_overflow(self):
         raises(self.struct.error, self.struct.pack, 'i', 1<<65)
 
+    def test_unpack_Q(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
+        #
+        buf = self.struct.pack('Q', sys.maxint+1)
+        obj, = self.struct.unpack('Q', buf)
+        assert obj == sys.maxint+1
+        assert type(obj) is long
 
 class AppTestStructBuffer(object):
     spaceconfig = dict(usemodules=['struct', '__pypy__'])


More information about the pypy-commit mailing list