[pypy-commit] pypy fix-struct-unpack-Q: make sure that we return an int even when we use 'q' on 32bit
antocuni
pypy.commits at gmail.com
Mon Oct 31 10:31:15 EDT 2016
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: fix-struct-unpack-Q
Changeset: r87999:08ad056ff621
Date: 2016-10-31 15:29 +0100
http://bitbucket.org/pypy/pypy/changeset/08ad056ff621/
Log: make sure that we return an int even when we use 'q' 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,4 +1,5 @@
-from rpython.rlib.rarithmetic import r_uint, r_ulonglong, maxint, intmask
+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
@@ -149,13 +150,15 @@
@specialize.argtype(1)
def appendobj(self, value):
- if isinstance(value, r_uint) or isinstance(value, 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)
+ # 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)
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,9 +431,9 @@
def test_overflow(self):
raises(self.struct.error, self.struct.pack, 'i', 1<<65)
- def test_unpack_unsigned(self):
+ def test_unpack_fits_into_int(self):
import sys
- for fmt in 'ILQ':
+ 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)
More information about the pypy-commit
mailing list