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

Reply via email to