bpo-25007: Add copy protocol support to zlib compressors and decompressors (GH-7940)

This commit is contained in:
Zackery Spytz 2018-06-27 12:04:51 -06:00 committed by Serhiy Storchaka
parent fbd7172325
commit d2cbfffc84
5 changed files with 183 additions and 25 deletions

View File

@ -231,6 +231,11 @@ Compression objects support the following methods:
compress a set of data that share a common initial prefix.
.. versionchanged:: 3.8
Added :func:`copy.copy` and :func:`copy.deepcopy` support to compression
objects.
Decompression objects support the following methods and attributes:
@ -298,6 +303,11 @@ Decompression objects support the following methods and attributes:
seeks into the stream at a future point.
.. versionchanged:: 3.8
Added :func:`copy.copy` and :func:`copy.deepcopy` support to decompression
objects.
Information about the version of the zlib library in use is available through
the following constants:

View File

@ -1,6 +1,7 @@
import unittest
from test import support
import binascii
import copy
import pickle
import random
import sys
@ -626,23 +627,24 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
# Test copying a compression object
data0 = HAMLET_SCENE
data1 = bytes(str(HAMLET_SCENE, "ascii").swapcase(), "ascii")
c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
bufs0 = []
bufs0.append(c0.compress(data0))
for func in lambda c: c.copy(), copy.copy, copy.deepcopy:
c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
bufs0 = []
bufs0.append(c0.compress(data0))
c1 = c0.copy()
bufs1 = bufs0[:]
c1 = func(c0)
bufs1 = bufs0[:]
bufs0.append(c0.compress(data0))
bufs0.append(c0.flush())
s0 = b''.join(bufs0)
bufs0.append(c0.compress(data0))
bufs0.append(c0.flush())
s0 = b''.join(bufs0)
bufs1.append(c1.compress(data1))
bufs1.append(c1.flush())
s1 = b''.join(bufs1)
bufs1.append(c1.compress(data1))
bufs1.append(c1.flush())
s1 = b''.join(bufs1)
self.assertEqual(zlib.decompress(s0),data0+data0)
self.assertEqual(zlib.decompress(s1),data0+data1)
self.assertEqual(zlib.decompress(s0),data0+data0)
self.assertEqual(zlib.decompress(s1),data0+data1)
@requires_Compress_copy
def test_badcompresscopy(self):
@ -651,6 +653,8 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
c.compress(HAMLET_SCENE)
c.flush()
self.assertRaises(ValueError, c.copy)
self.assertRaises(ValueError, copy.copy, c)
self.assertRaises(ValueError, copy.deepcopy, c)
@requires_Decompress_copy
def test_decompresscopy(self):
@ -660,21 +664,22 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
# Test type of return value
self.assertIsInstance(comp, bytes)
d0 = zlib.decompressobj()
bufs0 = []
bufs0.append(d0.decompress(comp[:32]))
for func in lambda c: c.copy(), copy.copy, copy.deepcopy:
d0 = zlib.decompressobj()
bufs0 = []
bufs0.append(d0.decompress(comp[:32]))
d1 = d0.copy()
bufs1 = bufs0[:]
d1 = func(d0)
bufs1 = bufs0[:]
bufs0.append(d0.decompress(comp[32:]))
s0 = b''.join(bufs0)
bufs0.append(d0.decompress(comp[32:]))
s0 = b''.join(bufs0)
bufs1.append(d1.decompress(comp[32:]))
s1 = b''.join(bufs1)
bufs1.append(d1.decompress(comp[32:]))
s1 = b''.join(bufs1)
self.assertEqual(s0,s1)
self.assertEqual(s0,data)
self.assertEqual(s0,s1)
self.assertEqual(s0,data)
@requires_Decompress_copy
def test_baddecompresscopy(self):
@ -684,6 +689,8 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
d.decompress(data)
d.flush()
self.assertRaises(ValueError, d.copy)
self.assertRaises(ValueError, copy.copy, d)
self.assertRaises(ValueError, copy.deepcopy, d)
def test_compresspickle(self):
for proto in range(pickle.HIGHEST_PROTOCOL + 1):

View File

@ -0,0 +1,2 @@
Add :func:`copy.copy` and :func:`copy.deepcopy` support to zlib compressors
and decompressors. Patch by Zackery Spytz.

View File

@ -335,6 +335,39 @@ zlib_Compress_copy(compobject *self, PyObject *Py_UNUSED(ignored))
#if defined(HAVE_ZLIB_COPY)
PyDoc_STRVAR(zlib_Compress___copy____doc__,
"__copy__($self, /)\n"
"--\n"
"\n");
#define ZLIB_COMPRESS___COPY___METHODDEF \
{"__copy__", (PyCFunction)zlib_Compress___copy__, METH_NOARGS, zlib_Compress___copy____doc__},
static PyObject *
zlib_Compress___copy___impl(compobject *self);
static PyObject *
zlib_Compress___copy__(compobject *self, PyObject *Py_UNUSED(ignored))
{
return zlib_Compress___copy___impl(self);
}
#endif /* defined(HAVE_ZLIB_COPY) */
#if defined(HAVE_ZLIB_COPY)
PyDoc_STRVAR(zlib_Compress___deepcopy____doc__,
"__deepcopy__($self, memo, /)\n"
"--\n"
"\n");
#define ZLIB_COMPRESS___DEEPCOPY___METHODDEF \
{"__deepcopy__", (PyCFunction)zlib_Compress___deepcopy__, METH_O, zlib_Compress___deepcopy____doc__},
#endif /* defined(HAVE_ZLIB_COPY) */
#if defined(HAVE_ZLIB_COPY)
PyDoc_STRVAR(zlib_Decompress_copy__doc__,
"copy($self, /)\n"
"--\n"
@ -355,6 +388,39 @@ zlib_Decompress_copy(compobject *self, PyObject *Py_UNUSED(ignored))
#endif /* defined(HAVE_ZLIB_COPY) */
#if defined(HAVE_ZLIB_COPY)
PyDoc_STRVAR(zlib_Decompress___copy____doc__,
"__copy__($self, /)\n"
"--\n"
"\n");
#define ZLIB_DECOMPRESS___COPY___METHODDEF \
{"__copy__", (PyCFunction)zlib_Decompress___copy__, METH_NOARGS, zlib_Decompress___copy____doc__},
static PyObject *
zlib_Decompress___copy___impl(compobject *self);
static PyObject *
zlib_Decompress___copy__(compobject *self, PyObject *Py_UNUSED(ignored))
{
return zlib_Decompress___copy___impl(self);
}
#endif /* defined(HAVE_ZLIB_COPY) */
#if defined(HAVE_ZLIB_COPY)
PyDoc_STRVAR(zlib_Decompress___deepcopy____doc__,
"__deepcopy__($self, memo, /)\n"
"--\n"
"\n");
#define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF \
{"__deepcopy__", (PyCFunction)zlib_Decompress___deepcopy__, METH_O, zlib_Decompress___deepcopy____doc__},
#endif /* defined(HAVE_ZLIB_COPY) */
PyDoc_STRVAR(zlib_Decompress_flush__doc__,
"flush($self, length=zlib.DEF_BUF_SIZE, /)\n"
"--\n"
@ -468,7 +534,23 @@ exit:
#define ZLIB_COMPRESS_COPY_METHODDEF
#endif /* !defined(ZLIB_COMPRESS_COPY_METHODDEF) */
#ifndef ZLIB_COMPRESS___COPY___METHODDEF
#define ZLIB_COMPRESS___COPY___METHODDEF
#endif /* !defined(ZLIB_COMPRESS___COPY___METHODDEF) */
#ifndef ZLIB_COMPRESS___DEEPCOPY___METHODDEF
#define ZLIB_COMPRESS___DEEPCOPY___METHODDEF
#endif /* !defined(ZLIB_COMPRESS___DEEPCOPY___METHODDEF) */
#ifndef ZLIB_DECOMPRESS_COPY_METHODDEF
#define ZLIB_DECOMPRESS_COPY_METHODDEF
#endif /* !defined(ZLIB_DECOMPRESS_COPY_METHODDEF) */
/*[clinic end generated code: output=43dd29b8977765f9 input=a9049054013a1b77]*/
#ifndef ZLIB_DECOMPRESS___COPY___METHODDEF
#define ZLIB_DECOMPRESS___COPY___METHODDEF
#endif /* !defined(ZLIB_DECOMPRESS___COPY___METHODDEF) */
#ifndef ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF
#define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF
#endif /* !defined(ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF) */
/*[clinic end generated code: output=d46c646770146ade input=a9049054013a1b77]*/

View File

@ -984,6 +984,32 @@ error:
return NULL;
}
/*[clinic input]
zlib.Compress.__copy__
[clinic start generated code]*/
static PyObject *
zlib_Compress___copy___impl(compobject *self)
/*[clinic end generated code: output=1875e6791975442e input=be97a05a788dfd83]*/
{
return zlib_Compress_copy_impl(self);
}
/*[clinic input]
zlib.Compress.__deepcopy__
memo: object
/
[clinic start generated code]*/
static PyObject *
zlib_Compress___deepcopy__(compobject *self, PyObject *memo)
/*[clinic end generated code: output=f47a2213282c9eb0 input=a9a8b0b40d83388e]*/
{
return zlib_Compress_copy_impl(self);
}
/*[clinic input]
zlib.Decompress.copy
@ -1039,6 +1065,33 @@ error:
Py_XDECREF(retval);
return NULL;
}
/*[clinic input]
zlib.Decompress.__copy__
[clinic start generated code]*/
static PyObject *
zlib_Decompress___copy___impl(compobject *self)
/*[clinic end generated code: output=80bae8bc43498ad4 input=efcb98b5472c13d2]*/
{
return zlib_Decompress_copy_impl(self);
}
/*[clinic input]
zlib.Decompress.__deepcopy__
memo: object
/
[clinic start generated code]*/
static PyObject *
zlib_Decompress___deepcopy__(compobject *self, PyObject *memo)
/*[clinic end generated code: output=1f77286ab490124b input=6e99bd0ac4b9cd8b]*/
{
return zlib_Decompress_copy_impl(self);
}
#endif
/*[clinic input]
@ -1139,6 +1192,8 @@ static PyMethodDef comp_methods[] =
ZLIB_COMPRESS_COMPRESS_METHODDEF
ZLIB_COMPRESS_FLUSH_METHODDEF
ZLIB_COMPRESS_COPY_METHODDEF
ZLIB_COMPRESS___COPY___METHODDEF
ZLIB_COMPRESS___DEEPCOPY___METHODDEF
{NULL, NULL}
};
@ -1147,6 +1202,8 @@ static PyMethodDef Decomp_methods[] =
ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF
ZLIB_DECOMPRESS_FLUSH_METHODDEF
ZLIB_DECOMPRESS_COPY_METHODDEF
ZLIB_DECOMPRESS___COPY___METHODDEF
ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF
{NULL, NULL}
};