Author: Brian Kearns <[email protected]>
Branch: stdlib-2.7.6
Changeset: r69632:00860b5ad1a8
Date: 2014-03-03 00:48 -0500
http://bitbucket.org/pypy/pypy/changeset/00860b5ad1a8/

Log:    more fixes for zlib

diff --git a/pypy/module/zlib/interp_zlib.py b/pypy/module/zlib/interp_zlib.py
--- a/pypy/module/zlib/interp_zlib.py
+++ b/pypy/module/zlib/interp_zlib.py
@@ -2,7 +2,7 @@
 from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.typedef import TypeDef, interp_attrproperty
-from pypy.interpreter.error import OperationError
+from pypy.interpreter.error import OperationError, oefmt
 from rpython.rlib.rarithmetic import intmask, r_uint
 from rpython.rlib.objectmodel import keepalive_until_here
 
@@ -87,7 +87,7 @@
     return space.wrap(result)
 
 
-@unwrap_spec(string='bufferstr', wbits=int, bufsize=int)
+@unwrap_spec(string='bufferstr', wbits="c_int", bufsize=int)
 def decompress(space, string, wbits=rzlib.MAX_WBITS, bufsize=0):
     """
     decompress(string[, wbits[, bufsize]]) -- Return decompressed string.
@@ -116,7 +116,6 @@
     stream = rzlib.null_stream
 
     def __init__(self, space):
-        self.space = space
         self._lock = space.allocate_lock()
 
     def lock(self):
@@ -146,7 +145,7 @@
             self.stream = rzlib.deflateInit(level, method, wbits,
                                             memLevel, strategy)
         except rzlib.RZlibError, e:
-            raise zlib_error(self.space, e.msg)
+            raise zlib_error(space, e.msg)
         except ValueError:
             raise OperationError(space.w_ValueError,
                                  space.wrap("Invalid initialization option"))
@@ -158,7 +157,7 @@
             self.stream = rzlib.null_stream
 
     @unwrap_spec(data='bufferstr')
-    def compress(self, data):
+    def compress(self, space, data):
         """
         compress(data) -- Return a string containing data compressed.
 
@@ -171,17 +170,17 @@
             self.lock()
             try:
                 if not self.stream:
-                    raise zlib_error(self.space,
+                    raise zlib_error(space,
                                      "compressor object already flushed")
                 result = rzlib.compress(self.stream, data)
             finally:
                 self.unlock()
         except rzlib.RZlibError, e:
-            raise zlib_error(self.space, e.msg)
-        return self.space.wrap(result)
+            raise zlib_error(space, e.msg)
+        return space.wrap(result)
 
     @unwrap_spec(mode="c_int")
-    def flush(self, mode=rzlib.Z_FINISH):
+    def flush(self, space, mode=rzlib.Z_FINISH):
         """
         flush( [mode] ) -- Return a string containing any remaining compressed
         data.
@@ -197,7 +196,7 @@
             self.lock()
             try:
                 if not self.stream:
-                    raise zlib_error(self.space,
+                    raise zlib_error(space,
                                      "compressor object already flushed")
                 result = rzlib.compress(self.stream, '', mode)
                 if mode == rzlib.Z_FINISH:    # release the data structures now
@@ -206,8 +205,8 @@
             finally:
                 self.unlock()
         except rzlib.RZlibError, e:
-            raise zlib_error(self.space, e.msg)
-        return self.space.wrap(result)
+            raise zlib_error(space, e.msg)
+        return space.wrap(result)
 
 
 @unwrap_spec(level=int, method=int, wbits=int, memLevel=int, strategy=int)
@@ -257,7 +256,7 @@
         try:
             self.stream = rzlib.inflateInit(wbits)
         except rzlib.RZlibError, e:
-            raise zlib_error(self.space, e.msg)
+            raise zlib_error(space, e.msg)
         except ValueError:
             raise OperationError(space.w_ValueError,
                                  space.wrap("Invalid initialization option"))
@@ -278,8 +277,8 @@
         else:
             self.unconsumed_tail = tail
 
-    @unwrap_spec(data='bufferstr', max_length=int)
-    def decompress(self, data, max_length=0):
+    @unwrap_spec(data='bufferstr', max_length="c_int")
+    def decompress(self, space, data, max_length=0):
         """
         decompress(data[, max_length]) -- Return a string containing the
         decompressed version of the data.
@@ -291,9 +290,8 @@
         if max_length == 0:
             max_length = sys.maxint
         elif max_length < 0:
-            raise OperationError(self.space.w_ValueError,
-                                 self.space.wrap("max_length must be "
-                                                 "greater than zero"))
+            raise oefmt(space.w_ValueError,
+                        "max_length must be greater than zero")
         try:
             self.lock()
             try:
@@ -301,35 +299,36 @@
             finally:
                 self.unlock()
         except rzlib.RZlibError, e:
-            raise zlib_error(self.space, e.msg)
+            raise zlib_error(space, e.msg)
 
         string, finished, unused_len = result
         self._save_unconsumed_input(data, finished, unused_len)
-        return self.space.wrap(string)
+        return space.wrap(string)
 
-    @unwrap_spec(mode="c_int")
-    def flush(self, mode=rzlib.Z_FINISH):
+    def flush(self, space, w_length=None):
         """
         flush( [length] ) -- This is kept for backward compatibility,
         because each call to decompress() immediately returns as much
         data as possible.
         """
-        if mode == rzlib.Z_NO_FLUSH:
-            return self.space.wrap("")
-
+        if w_length is not None:
+            length = space.c_int_w(w_length)
+            if length <= 0:
+                raise oefmt(space.w_ValueError,
+                            "length must be greater than zero")
         data = self.unconsumed_tail
         try:
             self.lock()
             try:
-                result = rzlib.decompress(self.stream, data, mode)
+                result = rzlib.decompress(self.stream, data, rzlib.Z_FINISH)
             finally:
                 self.unlock()
-        except rzlib.RZlibError, e:
-            raise zlib_error(self.space, e.msg)
-
-        string, finished, unused_len = result
-        self._save_unconsumed_input(data, finished, unused_len)
-        return self.space.wrap(string)
+        except rzlib.RZlibError:
+            string = ""
+        else:
+            string, finished, unused_len = result
+            self._save_unconsumed_input(data, finished, unused_len)
+        return space.wrap(string)
 
 
 @unwrap_spec(wbits=int)
diff --git a/pypy/module/zlib/test/test_zlib.py 
b/pypy/module/zlib/test/test_zlib.py
--- a/pypy/module/zlib/test/test_zlib.py
+++ b/pypy/module/zlib/test/test_zlib.py
@@ -33,14 +33,12 @@
         cls.w_expanded = cls.space.wrap(expanded)
         cls.w_compressed = cls.space.wrap(zlib.compress(expanded))
 
-
     def test_error(self):
         """
         zlib.error should be an exception class.
         """
         assert issubclass(self.zlib.error, Exception)
 
-
     def test_crc32(self):
         """
         When called with a string, zlib.crc32 should compute its CRC32 and
@@ -162,13 +160,46 @@
         raises(self.zlib.error, self.zlib.decompress, self.compressed[:-2])
         raises(self.zlib.error, self.zlib.decompress, 'foobar')
 
+    def test_bad_arguments(self):
+        import zlib
+        raises(ValueError, zlib.decompressobj().flush, 0)
+        raises(ValueError, zlib.decompressobj().flush, -1)
+        raises(TypeError, zlib.decompressobj().flush, None)
+        raises(OverflowError, zlib.decompressobj().flush, 2**31)
+        raises(ValueError, zlib.decompressobj().decompress, 'abc', -1)
+        raises(TypeError, zlib.decompressobj().decompress, 'abc', None)
+        raises(OverflowError, zlib.decompressobj().decompress, 'abc', 2**31)
+        raises(TypeError, self.zlib.decompress, self.compressed, None)
+        raises(OverflowError, self.zlib.decompress, self.compressed, 2**31)
+
+    def test_empty_flush(self):
+        import zlib
+        co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
+        assert co.flush()  # Returns a zlib header
+        dco = zlib.decompressobj()
+        assert dco.flush() == ""
+
+    def test_decompress_incomplete_stream(self):
+        import zlib
+        # This is 'foo', deflated
+        x = 'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E'
+        # For the record
+        assert zlib.decompress(x) == 'foo'
+        raises(zlib.error, zlib.decompress, x[:-5])
+        # Omitting the stream end works with decompressor objects
+        # (see issue #8672).
+        dco = zlib.decompressobj()
+        y = dco.decompress(x[:-5])
+        y += dco.flush()
+        assert y == 'foo'
+
     def test_unused_data(self):
         """
         Try to feed too much data to zlib.decompress().
         It should show up in the unused_data attribute.
         """
         d = self.zlib.decompressobj()
-        s = d.decompress(self.compressed + 'extrastuff')
+        s = d.decompress(self.compressed + 'extrastuff', 0)
         assert s == self.expanded
         assert d.unused_data == 'extrastuff'
         assert d.flush() == ''
@@ -232,6 +263,6 @@
         dco.decompress(data, 1)
         del data
         data = self.zlib.compress(input2)
-        assert dco.flush() == input1[1:]
+        assert dco.flush(1) == input1[1:]
         assert dco.unused_data == ''
         assert dco.unconsumed_tail == ''
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to