Skip to content

Commit d2cbfff

Browse files
ZackerySpytzserhiy-storchaka
authored andcommitted
bpo-25007: Add copy protocol support to zlib compressors and decompressors (pythonGH-7940)
1 parent fbd7172 commit d2cbfff

File tree

5 files changed

+183
-25
lines changed

5 files changed

+183
-25
lines changed

Doc/library/zlib.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,11 @@ Compression objects support the following methods:
231231
compress a set of data that share a common initial prefix.
232232

233233

234+
.. versionchanged:: 3.8
235+
Added :func:`copy.copy` and :func:`copy.deepcopy` support to compression
236+
objects.
237+
238+
234239
Decompression objects support the following methods and attributes:
235240

236241

@@ -298,6 +303,11 @@ Decompression objects support the following methods and attributes:
298303
seeks into the stream at a future point.
299304

300305

306+
.. versionchanged:: 3.8
307+
Added :func:`copy.copy` and :func:`copy.deepcopy` support to decompression
308+
objects.
309+
310+
301311
Information about the version of the zlib library in use is available through
302312
the following constants:
303313

Lib/test/test_zlib.py

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import unittest
22
from test import support
33
import binascii
4+
import copy
45
import pickle
56
import random
67
import sys
@@ -626,23 +627,24 @@ def test_compresscopy(self):
626627
# Test copying a compression object
627628
data0 = HAMLET_SCENE
628629
data1 = bytes(str(HAMLET_SCENE, "ascii").swapcase(), "ascii")
629-
c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
630-
bufs0 = []
631-
bufs0.append(c0.compress(data0))
630+
for func in lambda c: c.copy(), copy.copy, copy.deepcopy:
631+
c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
632+
bufs0 = []
633+
bufs0.append(c0.compress(data0))
632634

633-
c1 = c0.copy()
634-
bufs1 = bufs0[:]
635+
c1 = func(c0)
636+
bufs1 = bufs0[:]
635637

636-
bufs0.append(c0.compress(data0))
637-
bufs0.append(c0.flush())
638-
s0 = b''.join(bufs0)
638+
bufs0.append(c0.compress(data0))
639+
bufs0.append(c0.flush())
640+
s0 = b''.join(bufs0)
639641

640-
bufs1.append(c1.compress(data1))
641-
bufs1.append(c1.flush())
642-
s1 = b''.join(bufs1)
642+
bufs1.append(c1.compress(data1))
643+
bufs1.append(c1.flush())
644+
s1 = b''.join(bufs1)
643645

644-
self.assertEqual(zlib.decompress(s0),data0+data0)
645-
self.assertEqual(zlib.decompress(s1),data0+data1)
646+
self.assertEqual(zlib.decompress(s0),data0+data0)
647+
self.assertEqual(zlib.decompress(s1),data0+data1)
646648

647649
@requires_Compress_copy
648650
def test_badcompresscopy(self):
@@ -651,6 +653,8 @@ def test_badcompresscopy(self):
651653
c.compress(HAMLET_SCENE)
652654
c.flush()
653655
self.assertRaises(ValueError, c.copy)
656+
self.assertRaises(ValueError, copy.copy, c)
657+
self.assertRaises(ValueError, copy.deepcopy, c)
654658

655659
@requires_Decompress_copy
656660
def test_decompresscopy(self):
@@ -660,21 +664,22 @@ def test_decompresscopy(self):
660664
# Test type of return value
661665
self.assertIsInstance(comp, bytes)
662666

663-
d0 = zlib.decompressobj()
664-
bufs0 = []
665-
bufs0.append(d0.decompress(comp[:32]))
667+
for func in lambda c: c.copy(), copy.copy, copy.deepcopy:
668+
d0 = zlib.decompressobj()
669+
bufs0 = []
670+
bufs0.append(d0.decompress(comp[:32]))
666671

667-
d1 = d0.copy()
668-
bufs1 = bufs0[:]
672+
d1 = func(d0)
673+
bufs1 = bufs0[:]
669674

670-
bufs0.append(d0.decompress(comp[32:]))
671-
s0 = b''.join(bufs0)
675+
bufs0.append(d0.decompress(comp[32:]))
676+
s0 = b''.join(bufs0)
672677

673-
bufs1.append(d1.decompress(comp[32:]))
674-
s1 = b''.join(bufs1)
678+
bufs1.append(d1.decompress(comp[32:]))
679+
s1 = b''.join(bufs1)
675680

676-
self.assertEqual(s0,s1)
677-
self.assertEqual(s0,data)
681+
self.assertEqual(s0,s1)
682+
self.assertEqual(s0,data)
678683

679684
@requires_Decompress_copy
680685
def test_baddecompresscopy(self):
@@ -684,6 +689,8 @@ def test_baddecompresscopy(self):
684689
d.decompress(data)
685690
d.flush()
686691
self.assertRaises(ValueError, d.copy)
692+
self.assertRaises(ValueError, copy.copy, d)
693+
self.assertRaises(ValueError, copy.deepcopy, d)
687694

688695
def test_compresspickle(self):
689696
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add :func:`copy.copy` and :func:`copy.deepcopy` support to zlib compressors
2+
and decompressors. Patch by Zackery Spytz.

Modules/clinic/zlibmodule.c.h

Lines changed: 83 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/zlibmodule.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,32 @@ zlib_Compress_copy_impl(compobject *self)
984984
return NULL;
985985
}
986986

987+
/*[clinic input]
988+
zlib.Compress.__copy__
989+
[clinic start generated code]*/
990+
991+
static PyObject *
992+
zlib_Compress___copy___impl(compobject *self)
993+
/*[clinic end generated code: output=1875e6791975442e input=be97a05a788dfd83]*/
994+
{
995+
return zlib_Compress_copy_impl(self);
996+
}
997+
998+
/*[clinic input]
999+
zlib.Compress.__deepcopy__
1000+
1001+
memo: object
1002+
/
1003+
1004+
[clinic start generated code]*/
1005+
1006+
static PyObject *
1007+
zlib_Compress___deepcopy__(compobject *self, PyObject *memo)
1008+
/*[clinic end generated code: output=f47a2213282c9eb0 input=a9a8b0b40d83388e]*/
1009+
{
1010+
return zlib_Compress_copy_impl(self);
1011+
}
1012+
9871013
/*[clinic input]
9881014
zlib.Decompress.copy
9891015
@@ -1039,6 +1065,33 @@ zlib_Decompress_copy_impl(compobject *self)
10391065
Py_XDECREF(retval);
10401066
return NULL;
10411067
}
1068+
1069+
/*[clinic input]
1070+
zlib.Decompress.__copy__
1071+
[clinic start generated code]*/
1072+
1073+
static PyObject *
1074+
zlib_Decompress___copy___impl(compobject *self)
1075+
/*[clinic end generated code: output=80bae8bc43498ad4 input=efcb98b5472c13d2]*/
1076+
{
1077+
return zlib_Decompress_copy_impl(self);
1078+
}
1079+
1080+
/*[clinic input]
1081+
zlib.Decompress.__deepcopy__
1082+
1083+
memo: object
1084+
/
1085+
1086+
[clinic start generated code]*/
1087+
1088+
static PyObject *
1089+
zlib_Decompress___deepcopy__(compobject *self, PyObject *memo)
1090+
/*[clinic end generated code: output=1f77286ab490124b input=6e99bd0ac4b9cd8b]*/
1091+
{
1092+
return zlib_Decompress_copy_impl(self);
1093+
}
1094+
10421095
#endif
10431096

10441097
/*[clinic input]
@@ -1139,6 +1192,8 @@ static PyMethodDef comp_methods[] =
11391192
ZLIB_COMPRESS_COMPRESS_METHODDEF
11401193
ZLIB_COMPRESS_FLUSH_METHODDEF
11411194
ZLIB_COMPRESS_COPY_METHODDEF
1195+
ZLIB_COMPRESS___COPY___METHODDEF
1196+
ZLIB_COMPRESS___DEEPCOPY___METHODDEF
11421197
{NULL, NULL}
11431198
};
11441199

@@ -1147,6 +1202,8 @@ static PyMethodDef Decomp_methods[] =
11471202
ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF
11481203
ZLIB_DECOMPRESS_FLUSH_METHODDEF
11491204
ZLIB_DECOMPRESS_COPY_METHODDEF
1205+
ZLIB_DECOMPRESS___COPY___METHODDEF
1206+
ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF
11501207
{NULL, NULL}
11511208
};
11521209

0 commit comments

Comments
 (0)