summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/zlib.rst20
-rw-r--r--Lib/test/test_zlib.py33
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/clinic/zlibmodule.c.h22
-rw-r--r--Modules/zlibmodule.c8
5 files changed, 61 insertions, 25 deletions
diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst
index 846020c..3d742ab 100644
--- a/Doc/library/zlib.rst
+++ b/Doc/library/zlib.rst
@@ -129,7 +129,7 @@ The available exception and functions in this module are:
platforms, use ``crc32(data) & 0xffffffff``.
-.. function:: decompress(data[, wbits[, bufsize]])
+.. function:: decompress(data, wbits=MAX_WBITS, bufsize=DEF_BUF_SIZE)
Decompresses the bytes in *data*, returning a bytes object containing the
uncompressed data. The *wbits* parameter depends on
@@ -164,14 +164,16 @@ The available exception and functions in this module are:
When decompressing a stream, the window size must not be smaller
than the size originally used to compress the stream; using a too-small
value may result in an :exc:`error` exception. The default *wbits* value
- is 15, which corresponds to the largest window size and requires a zlib
- header and trailer to be included.
+ corresponds to the largest window size and requires a zlib header and
+ trailer to be included.
*bufsize* is the initial size of the buffer used to hold decompressed data. If
more space is required, the buffer size will be increased as needed, so you
don't have to get this value exactly right; tuning it will only save a few calls
- to :c:func:`malloc`. The default size is 16384.
+ to :c:func:`malloc`.
+ .. versionchanged:: 3.6
+ *wbits* and *bufsize* can be used as keyword arguments.
.. function:: decompressobj(wbits=15[, zdict])
@@ -257,7 +259,7 @@ Decompression objects support the following methods and attributes:
.. versionadded:: 3.3
-.. method:: Decompress.decompress(data[, max_length])
+.. method:: Decompress.decompress(data, max_length=0)
Decompress *data*, returning a bytes object containing the uncompressed data
corresponding to at least part of the data in *string*. This data should be
@@ -269,9 +271,11 @@ Decompression objects support the following methods and attributes:
no longer than *max_length*. This may mean that not all of the compressed input
can be processed; and unconsumed data will be stored in the attribute
:attr:`unconsumed_tail`. This bytestring must be passed to a subsequent call to
- :meth:`decompress` if decompression is to continue. If *max_length* is not
- supplied then the whole input is decompressed, and :attr:`unconsumed_tail` is
- empty.
+ :meth:`decompress` if decompression is to continue. If *max_length* is zero
+ then the whole input is decompressed, and :attr:`unconsumed_tail` is empty.
+
+ .. versionchanged:: 3.6
+ *max_length* can be used as a keyword argument.
.. method:: Decompress.flush([length])
diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py
index f9740f1..4d72d6f 100644
--- a/Lib/test/test_zlib.py
+++ b/Lib/test/test_zlib.py
@@ -169,6 +169,14 @@ class CompressTestCase(BaseCompressTestCase, unittest.TestCase):
self.assertEqual(zlib.decompress(x), HAMLET_SCENE)
with self.assertRaises(TypeError):
zlib.compress(data=HAMLET_SCENE, level=3)
+ self.assertEqual(zlib.decompress(x,
+ wbits=zlib.MAX_WBITS,
+ bufsize=zlib.DEF_BUF_SIZE),
+ HAMLET_SCENE)
+ with self.assertRaises(TypeError):
+ zlib.decompress(data=x,
+ wbits=zlib.MAX_WBITS,
+ bufsize=zlib.DEF_BUF_SIZE)
def test_speech128(self):
# compress more data
@@ -240,6 +248,27 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
self.assertIsInstance(dco.unconsumed_tail, bytes)
self.assertIsInstance(dco.unused_data, bytes)
+ def test_keywords(self):
+ level = 2
+ method = zlib.DEFLATED
+ wbits = -12
+ memLevel = 9
+ strategy = zlib.Z_FILTERED
+ co = zlib.compressobj(level=level,
+ method=method,
+ wbits=wbits,
+ memLevel=memLevel,
+ strategy=strategy,
+ zdict=b"")
+ do = zlib.decompressobj(wbits=wbits, zdict=b"")
+ with self.assertRaises(TypeError):
+ co.compress(data=HAMLET_SCENE)
+ with self.assertRaises(TypeError):
+ do.decompress(data=zlib.compress(HAMLET_SCENE))
+ x = co.compress(HAMLET_SCENE) + co.flush()
+ y = do.decompress(x, max_length=len(HAMLET_SCENE)) + do.flush()
+ self.assertEqual(HAMLET_SCENE, y)
+
def test_compressoptions(self):
# specify lots of options to compressobj()
level = 2
@@ -255,10 +284,6 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
y2 = dco.flush()
self.assertEqual(HAMLET_SCENE, y1 + y2)
- # keyword arguments should also be supported
- zlib.compressobj(level=level, method=method, wbits=wbits,
- memLevel=memLevel, strategy=strategy, zdict=b"")
-
def test_compressincremental(self):
# compress object in steps, decompress object as one-shot
data = HAMLET_SCENE * 128
diff --git a/Misc/NEWS b/Misc/NEWS
index a34289b..ea701fd 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ What's New in Python 3.6.0 alpha 4
Core and Builtins
-----------------
+- Issue #16764: Support keyword arguments to zlib.decompress(). Patch by
+ Xiang Zhang.
+
- Issue #27704: Optimized creating bytes and bytearray from byte-like objects
and iterables. Speed up to 3 times for short objects. Original patch by
Naoki Inada.
diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h
index e4e2c0d..172308a 100644
--- a/Modules/clinic/zlibmodule.c.h
+++ b/Modules/clinic/zlibmodule.c.h
@@ -44,7 +44,7 @@ exit:
}
PyDoc_STRVAR(zlib_decompress__doc__,
-"decompress($module, data, wbits=MAX_WBITS, bufsize=DEF_BUF_SIZE, /)\n"
+"decompress($module, data, /, wbits=MAX_WBITS, bufsize=DEF_BUF_SIZE)\n"
"--\n"
"\n"
"Returns a bytes object containing the uncompressed data.\n"
@@ -57,21 +57,23 @@ PyDoc_STRVAR(zlib_decompress__doc__,
" The initial output buffer size.");
#define ZLIB_DECOMPRESS_METHODDEF \
- {"decompress", (PyCFunction)zlib_decompress, METH_VARARGS, zlib_decompress__doc__},
+ {"decompress", (PyCFunction)zlib_decompress, METH_VARARGS|METH_KEYWORDS, zlib_decompress__doc__},
static PyObject *
zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits,
Py_ssize_t bufsize);
static PyObject *
-zlib_decompress(PyObject *module, PyObject *args)
+zlib_decompress(PyObject *module, PyObject *args, PyObject *kwargs)
{
PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"", "wbits", "bufsize", NULL};
+ static _PyArg_Parser _parser = {"y*|iO&:decompress", _keywords, 0};
Py_buffer data = {NULL, NULL};
int wbits = MAX_WBITS;
Py_ssize_t bufsize = DEF_BUF_SIZE;
- if (!PyArg_ParseTuple(args, "y*|iO&:decompress",
+ if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser,
&data, &wbits, ssize_t_converter, &bufsize)) {
goto exit;
}
@@ -228,7 +230,7 @@ exit:
}
PyDoc_STRVAR(zlib_Decompress_decompress__doc__,
-"decompress($self, data, max_length=0, /)\n"
+"decompress($self, data, /, max_length=0)\n"
"--\n"
"\n"
"Return a bytes object containing the decompressed version of the data.\n"
@@ -245,20 +247,22 @@ PyDoc_STRVAR(zlib_Decompress_decompress__doc__,
"Call the flush() method to clear these buffers.");
#define ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF \
- {"decompress", (PyCFunction)zlib_Decompress_decompress, METH_VARARGS, zlib_Decompress_decompress__doc__},
+ {"decompress", (PyCFunction)zlib_Decompress_decompress, METH_VARARGS|METH_KEYWORDS, zlib_Decompress_decompress__doc__},
static PyObject *
zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data,
Py_ssize_t max_length);
static PyObject *
-zlib_Decompress_decompress(compobject *self, PyObject *args)
+zlib_Decompress_decompress(compobject *self, PyObject *args, PyObject *kwargs)
{
PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"", "max_length", NULL};
+ static _PyArg_Parser _parser = {"y*|O&:decompress", _keywords, 0};
Py_buffer data = {NULL, NULL};
Py_ssize_t max_length = 0;
- if (!PyArg_ParseTuple(args, "y*|O&:decompress",
+ if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser,
&data, ssize_t_converter, &max_length)) {
goto exit;
}
@@ -463,4 +467,4 @@ exit:
#ifndef ZLIB_COMPRESS_COPY_METHODDEF
#define ZLIB_COMPRESS_COPY_METHODDEF
#endif /* !defined(ZLIB_COMPRESS_COPY_METHODDEF) */
-/*[clinic end generated code: output=1fed251c15a9bffa input=a9049054013a1b77]*/
+/*[clinic end generated code: output=48911ef429b65903 input=a9049054013a1b77]*/
diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c
index 491bc85..4cded31 100644
--- a/Modules/zlibmodule.c
+++ b/Modules/zlibmodule.c
@@ -318,11 +318,11 @@ zlib.decompress
data: Py_buffer
Compressed data.
+ /
wbits: int(c_default="MAX_WBITS") = MAX_WBITS
The window buffer size and container format.
bufsize: ssize_t(c_default="DEF_BUF_SIZE") = DEF_BUF_SIZE
The initial output buffer size.
- /
Returns a bytes object containing the uncompressed data.
[clinic start generated code]*/
@@ -330,7 +330,7 @@ Returns a bytes object containing the uncompressed data.
static PyObject *
zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits,
Py_ssize_t bufsize)
-/*[clinic end generated code: output=77c7e35111dc8c42 input=c13dd2c5696cd17f]*/
+/*[clinic end generated code: output=77c7e35111dc8c42 input=21960936208e9a5b]*/
{
PyObject *RetVal = NULL;
Byte *ibuf;
@@ -750,11 +750,11 @@ zlib.Decompress.decompress
data: Py_buffer
The binary data to decompress.
+ /
max_length: ssize_t = 0
The maximum allowable length of the decompressed data.
Unconsumed input data will be stored in
the unconsumed_tail attribute.
- /
Return a bytes object containing the decompressed version of the data.
@@ -766,7 +766,7 @@ Call the flush() method to clear these buffers.
static PyObject *
zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data,
Py_ssize_t max_length)
-/*[clinic end generated code: output=6e5173c74e710352 input=d6de9b53c4566b8a]*/
+/*[clinic end generated code: output=6e5173c74e710352 input=b85a212a012b770a]*/
{
int err = Z_OK;
Py_ssize_t ibuflen, obuflen = DEF_BUF_SIZE, hard_limit;