Author: Antonio Cuni <[email protected]>
Branch:
Changeset: r88015:6b78c0c00c1c
Date: 2016-11-01 10:47 +0100
http://bitbucket.org/pypy/pypy/changeset/6b78c0c00c1c/
Log: merge branch fix-struct-unpack-Q: make sure that we return an int
whenever we can, instead of 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
@@ -1,3 +1,5 @@
+from rpython.rlib.rarithmetic import (r_uint, r_ulonglong, r_longlong,
+ maxint, intmask)
from rpython.rlib import jit
from rpython.rlib.objectmodel import specialize
from rpython.rlib.rstring import StringBuilder
@@ -148,7 +150,20 @@
@specialize.argtype(1)
def appendobj(self, value):
- self.result_w.append(self.space.wrap(value))
+ # CPython tries hard to return int objects whenever it can, but
+ # space.wrap returns a long if we pass a r_uint, r_ulonglong or
+ # r_longlong. So, we need special care in those cases.
+ is_unsigned = (isinstance(value, r_uint) or
+ isinstance(value, r_ulonglong))
+ if is_unsigned and value <= maxint:
+ w_value = self.space.wrap(intmask(value))
+ elif isinstance(value, r_longlong) and -maxint-1 <= value <= maxint:
+ w_value = self.space.wrap(intmask(value))
+ else:
+ # generic type, just use space.wrap
+ 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,20 @@
def test_overflow(self):
raises(self.struct.error, self.struct.pack, 'i', 1<<65)
+ def test_unpack_fits_into_int(self):
+ import sys
+ for fmt in 'ILQq':
+ # 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)
+ val, = self.struct.unpack('Q', buf)
+ assert val == sys.maxint+1
+ assert type(val) is long
class AppTestStructBuffer(object):
spaceconfig = dict(usemodules=['struct', '__pypy__'])
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit