Author: Philip Jenvey <[email protected]>
Branch: py3k
Changeset: r62521:5de0aa2e8003
Date: 2013-03-19 17:01 -0700
http://bitbucket.org/pypy/pypy/changeset/5de0aa2e8003/
Log: Merged in xentac/pypy/py3k-struct (pull request #141)
Fix struct tests with for py3k
diff --git a/lib-python/3/test/test_struct.py b/lib-python/3/test/test_struct.py
--- a/lib-python/3/test/test_struct.py
+++ b/lib-python/3/test/test_struct.py
@@ -522,31 +522,32 @@
if IS32BIT:
def test_crasher(self):
- self.assertRaises(MemoryError, struct.pack, "357913941b", "a")
+ # Pypy catches the string error instead of calculating the entire
size
+ self.assertRaises((MemoryError, TypeError), struct.pack,
"357913941b", "a")
def test_trailing_counter(self):
store = array.array('b', b' '*100)
# format lists containing only count spec should result in an error
self.assertRaises(struct.error, struct.pack, '12345')
- self.assertRaises(struct.error, struct.unpack, '12345', '')
+ self.assertRaises(struct.error, struct.unpack, '12345', b'')
self.assertRaises(struct.error, struct.pack_into, '12345', store, 0)
self.assertRaises(struct.error, struct.unpack_from, '12345', store, 0)
# Format lists with trailing count spec should result in an error
- self.assertRaises(struct.error, struct.pack, 'c12345', 'x')
- self.assertRaises(struct.error, struct.unpack, 'c12345', 'x')
+ self.assertRaises(struct.error, struct.pack, 'c12345', b'x')
+ self.assertRaises(struct.error, struct.unpack, 'c12345', b'x')
self.assertRaises(struct.error, struct.pack_into, 'c12345', store, 0,
- 'x')
+ b'x')
self.assertRaises(struct.error, struct.unpack_from, 'c12345', store,
0)
# Mixed format tests
- self.assertRaises(struct.error, struct.pack, '14s42', 'spam and eggs')
+ self.assertRaises(struct.error, struct.pack, '14s42', b'spam and eggs')
self.assertRaises(struct.error, struct.unpack, '14s42',
- 'spam and eggs')
+ b'spam and eggs')
self.assertRaises(struct.error, struct.pack_into, '14s42', store, 0,
- 'spam and eggs')
+ b'spam and eggs')
self.assertRaises(struct.error, struct.unpack_from, '14s42', store, 0)
def test_Struct_reinitialization(self):
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
@@ -3,7 +3,6 @@
from rpython.rlib.rstring import StringBuilder
from rpython.rlib.rstruct.error import StructError
from rpython.rlib.rstruct.formatiterator import FormatIterator
-from rpython.rlib.rstruct.standardfmttable import PACK_ACCEPTS_BROKEN_INPUT
from pypy.interpreter.error import OperationError
@@ -45,68 +44,39 @@
self.args_index += 1
return w_obj
- if PACK_ACCEPTS_BROKEN_INPUT:
- # permissive version - accepts float arguments too
+ # accepts objects with __index__es
- def accept_int_arg(self):
- return self._accept_integral("int_w")
+ def accept_int_arg(self):
+ return self._accept_integral("int_w")
- def accept_uint_arg(self):
- return self._accept_integral("uint_w")
+ def accept_uint_arg(self):
+ return self._accept_integral("uint_w")
- def accept_longlong_arg(self):
- return self._accept_integral("r_longlong_w")
+ def accept_longlong_arg(self):
+ return self._accept_integral("r_longlong_w")
- def accept_ulonglong_arg(self):
- return self._accept_integral("r_ulonglong_w")
+ def accept_ulonglong_arg(self):
+ return self._accept_integral("r_ulonglong_w")
- @specialize.arg(1)
- def _accept_integral(self, meth):
- space = self.space
- w_obj = self.accept_obj_arg()
- if space.isinstance_w(w_obj, space.w_int):
- w_index = w_obj
- else:
- w_index = None
- w_index_method = space.lookup(w_obj, "__index__")
- if w_index_method is not None:
- try:
- w_index = space.index(w_obj)
- except OperationError, e:
- if not e.match(space, space.w_TypeError):
- raise
- pass
- if w_index is None:
- w_index = self._maybe_float(w_obj)
- return getattr(space, meth)(w_index)
-
- def _maybe_float(self, w_obj):
- space = self.space
- if space.is_true(space.isinstance(w_obj, space.w_float)):
- msg = "struct: integer argument expected, got float"
- else:
- msg = "integer argument expected, got non-integer"
- space.warn(space.wrap(msg), space.w_DeprecationWarning)
- return space.int(w_obj) # wrapped float -> wrapped int or long
-
- else:
- # strict version
-
- def accept_int_arg(self):
- w_obj = self.accept_obj_arg()
- return self.space.int_w(w_obj)
-
- def accept_uint_arg(self):
- w_obj = self.accept_obj_arg()
- return self.space.uint_w(w_obj)
-
- def accept_longlong_arg(self):
- w_obj = self.accept_obj_arg()
- return self.space.r_longlong_w(w_obj)
-
- def accept_ulonglong_arg(self):
- w_obj = self.accept_obj_arg()
- return self.space.r_ulonglong_w(w_obj)
+ @specialize.arg(1)
+ def _accept_integral(self, meth):
+ space = self.space
+ w_obj = self.accept_obj_arg()
+ if space.isinstance_w(w_obj, space.w_int):
+ w_index = w_obj
+ else:
+ w_index = None
+ w_index_method = space.lookup(w_obj, "__index__")
+ if w_index_method is not None:
+ try:
+ w_index = space.index(w_obj)
+ except OperationError, e:
+ if not e.match(space, space.w_TypeError):
+ raise
+ pass
+ if w_index is None:
+ raise StructError("required argument is not an integer")
+ return getattr(space, meth)(w_index)
def accept_bool_arg(self):
w_obj = self.accept_obj_arg()
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
@@ -7,7 +7,7 @@
class AppTestStruct(object):
- spaceconfig = dict(usemodules=['struct'])
+ spaceconfig = dict(usemodules=['struct', 'array'])
def setup_class(cls):
"""
@@ -61,17 +61,6 @@
assert self.struct.unpack("i", self.struct.pack("i", X()))[0] == 3
- def test_deprecation_warning(self):
- import warnings
- for code in 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q':
- with warnings.catch_warnings(record=True) as w:
- warnings.simplefilter("always")
- raises(TypeError, self.struct.pack, code, 3j)
- assert len(w) == 1
- assert str(w[0].message) == "integer argument expected, got
non-integer"
- assert w[0].category is DeprecationWarning
-
-
def test_pack_standard_little(self):
"""
Check packing with the '<' format specifier.
@@ -386,6 +375,81 @@
assert self.struct.unpack("ii", b) == (62, 12)
raises(self.struct.error, self.struct.unpack, "i", b)
+ def test_trailing_counter(self):
+ import array
+ store = array.array('b', b' '*100)
+
+ # format lists containing only count spec should result in an error
+ raises(self.struct.error, self.struct.pack, '12345')
+ raises(self.struct.error, self.struct.unpack, '12345', b'')
+ raises(self.struct.error, self.struct.pack_into, '12345', store, 0)
+ raises(self.struct.error, self.struct.unpack_from, '12345', store, 0)
+
+ # Format lists with trailing count spec should result in an error
+ raises(self.struct.error, self.struct.pack, 'c12345', b'x')
+ raises(self.struct.error, self.struct.unpack, 'c12345', b'x')
+ raises(self.struct.error, self.struct.pack_into, 'c12345', store, 0,
+ b'x')
+ raises(self.struct.error, self.struct.unpack_from, 'c12345', store,
+ 0)
+
+ # Mixed format tests
+ raises(self.struct.error, self.struct.pack, '14s42', b'spam and eggs')
+ raises(self.struct.error, self.struct.unpack, '14s42',
+ b'spam and eggs')
+ raises(self.struct.error, self.struct.pack_into, '14s42', store, 0,
+ b'spam and eggs')
+ raises(self.struct.error, self.struct.unpack_from, '14s42', store, 0)
+
+ def test_1530559(self):
+ # Native 'q' packing isn't available on systems that don't have the C
+ # long long type.
+ try:
+ self.struct.pack('q', 5)
+ except self.struct.error:
+ HAVE_LONG_LONG = False
+ else:
+ HAVE_LONG_LONG = True
+ integer_codes = ('b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q')
+ for byteorder in '', '@', '=', '<', '>', '!':
+ for code in integer_codes:
+ if (byteorder in ('', '@') and code in ('q', 'Q') and
+ not HAVE_LONG_LONG):
+ continue
+ format = byteorder + code
+ raises(self.struct.error, self.struct.pack, format, 1.0)
+ raises(self.struct.error, self.struct.pack, format, 1.5)
+ raises(self.struct.error, self.struct.pack, 'P', 1.0)
+ raises(self.struct.error, self.struct.pack, 'P', 1.5)
+
+ def test_integers(self):
+ # Native 'q' packing isn't available on systems that don't have the C
+ # long long type.
+ try:
+ self.struct.pack('q', 5)
+ except self.struct.error:
+ HAVE_LONG_LONG = False
+ else:
+ HAVE_LONG_LONG = True
+
+ integer_codes = ('b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q')
+ byteorders = '', '@', '=', '<', '>', '!'
+
+ def run_not_int_test(format):
+ class NotAnInt:
+ def __int__(self):
+ return 42
+ raises((TypeError, self.struct.error),
+ self.struct.pack, format,
+ NotAnInt())
+
+ for code in integer_codes:
+ for byteorder in byteorders:
+ if (byteorder in ('', '@') and code in ('q', 'Q') and
+ not HAVE_LONG_LONG):
+ continue
+ format = byteorder+code
+ t = run_not_int_test(format)
class AppTestStructBuffer(object):
spaceconfig = dict(usemodules=['struct', '__pypy__'])
diff --git a/rpython/rlib/rstruct/standardfmttable.py
b/rpython/rlib/rstruct/standardfmttable.py
--- a/rpython/rlib/rstruct/standardfmttable.py
+++ b/rpython/rlib/rstruct/standardfmttable.py
@@ -13,12 +13,6 @@
from rpython.rlib.rstruct.error import StructError, StructOverflowError
from rpython.rlib.unroll import unrolling_iterable
-# In the CPython struct module, pack() unconsistently accepts inputs
-# that are out-of-range or floats instead of ints. Should we emulate
-# this? Let's use a flag for now:
-
-PACK_ACCEPTS_BROKEN_INPUT = True
-
# ____________________________________________________________
def pack_pad(fmtiter, count):
@@ -100,10 +94,7 @@
return min, max, accept_method
def make_int_packer(size, signed, cpython_checks_range, _memo={}):
- if cpython_checks_range:
- check_range = True
- else:
- check_range = not PACK_ACCEPTS_BROKEN_INPUT
+ check_range = True
key = (size, signed, check_range)
try:
return _memo[key]
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit