Skip to content

Commit bad1257

Browse files
Issue #22777: Test pickling with all protocols.
1 parent 79b8173 commit bad1257

30 files changed

Lines changed: 725 additions & 645 deletions

Lib/ctypes/test/test_pickling.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ def __init__(self, *args, **kw):
1414
class Y(X):
1515
_fields_ = [("str", c_char_p)]
1616

17-
class PickleTest(unittest.TestCase):
17+
class PickleTest:
1818
def dumps(self, item):
19-
return pickle.dumps(item)
19+
return pickle.dumps(item, self.proto)
2020

2121
def loads(self, item):
2222
return pickle.loads(item)
@@ -67,17 +67,15 @@ def test_unpickable(self):
6767
self.assertRaises(ValueError, lambda: self.dumps(item))
6868

6969
def test_wchar(self):
70-
pickle.dumps(c_char(b"x"))
70+
self.dumps(c_char(b"x"))
7171
# Issue 5049
72-
pickle.dumps(c_wchar("x"))
72+
self.dumps(c_wchar("x"))
7373

74-
class PickleTest_1(PickleTest):
75-
def dumps(self, item):
76-
return pickle.dumps(item, 1)
77-
78-
class PickleTest_2(PickleTest):
79-
def dumps(self, item):
80-
return pickle.dumps(item, 2)
74+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
75+
name = 'PickleTest_%s' % proto
76+
globals()[name] = type(name,
77+
(PickleTest, unittest.TestCase),
78+
{'proto': proto})
8179

8280
if __name__ == "__main__":
8381
unittest.main()

Lib/test/audiotests.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ def check_params(self, f, nchannels, sampwidth, framerate, nframes,
4545
self.assertEqual(params.comptype, comptype)
4646
self.assertEqual(params.compname, compname)
4747

48-
dump = pickle.dumps(params)
49-
self.assertEqual(pickle.loads(dump), params)
48+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
49+
dump = pickle.dumps(params, proto)
50+
self.assertEqual(pickle.loads(dump), params)
5051

5152

5253
class AudioWriteTests(AudioTests):

Lib/test/datetimetester.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,11 +1682,12 @@ def test_pickling(self):
16821682

16831683
def test_more_pickling(self):
16841684
a = self.theclass(2003, 2, 7, 16, 48, 37, 444116)
1685-
s = pickle.dumps(a)
1686-
b = pickle.loads(s)
1687-
self.assertEqual(b.year, 2003)
1688-
self.assertEqual(b.month, 2)
1689-
self.assertEqual(b.day, 7)
1685+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1686+
s = pickle.dumps(a, proto)
1687+
b = pickle.loads(s)
1688+
self.assertEqual(b.year, 2003)
1689+
self.assertEqual(b.month, 2)
1690+
self.assertEqual(b.day, 7)
16901691

16911692
def test_pickling_subclass_datetime(self):
16921693
args = 6, 7, 23, 20, 59, 1, 64**2

Lib/test/seq_tests.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ def __eq__(self, other):
392392

393393
def test_pickle(self):
394394
lst = self.type2test([4, 5, 6, 7])
395-
lst2 = pickle.loads(pickle.dumps(lst))
396-
self.assertEqual(lst2, lst)
397-
self.assertNotEqual(id(lst2), id(lst))
395+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
396+
lst2 = pickle.loads(pickle.dumps(lst, proto))
397+
self.assertEqual(lst2, lst)
398+
self.assertNotEqual(id(lst2), id(lst))

Lib/test/test_array.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -285,17 +285,18 @@ def test_pickle_for_empty_array(self):
285285

286286
def test_iterator_pickle(self):
287287
data = array.array(self.typecode, self.example)
288-
orgit = iter(data)
289-
d = pickle.dumps(orgit)
290-
it = pickle.loads(d)
291-
self.assertEqual(type(orgit), type(it))
292-
self.assertEqual(list(it), list(data))
293-
294-
if len(data):
288+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
289+
orgit = iter(data)
290+
d = pickle.dumps(orgit, proto)
295291
it = pickle.loads(d)
296-
next(it)
297-
d = pickle.dumps(it)
298-
self.assertEqual(list(it), list(data)[1:])
292+
self.assertEqual(type(orgit), type(it))
293+
self.assertEqual(list(it), list(data))
294+
295+
if len(data):
296+
it = pickle.loads(d)
297+
next(it)
298+
d = pickle.dumps(it, proto)
299+
self.assertEqual(list(it), list(data)[1:])
299300

300301
def test_insert(self):
301302
a = array.array(self.typecode, self.example)

Lib/test/test_bool.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,10 +269,9 @@ def test_marshal(self):
269269

270270
def test_pickle(self):
271271
import pickle
272-
self.assertIs(pickle.loads(pickle.dumps(True)), True)
273-
self.assertIs(pickle.loads(pickle.dumps(False)), False)
274-
self.assertIs(pickle.loads(pickle.dumps(True, True)), True)
275-
self.assertIs(pickle.loads(pickle.dumps(False, True)), False)
272+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
273+
self.assertIs(pickle.loads(pickle.dumps(True, proto)), True)
274+
self.assertIs(pickle.loads(pickle.dumps(False, proto)), False)
276275

277276
def test_picklevalues(self):
278277
# Test for specific backwards-compatible pickle values

Lib/test/test_builtin.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ def map_char(arg):
121121

122122
class BuiltinTest(unittest.TestCase):
123123
# Helper to check picklability
124-
def check_iter_pickle(self, it, seq):
124+
def check_iter_pickle(self, it, seq, proto):
125125
itorg = it
126-
d = pickle.dumps(it)
126+
d = pickle.dumps(it, proto)
127127
it = pickle.loads(d)
128128
self.assertEqual(type(itorg), type(it))
129129
self.assertEqual(list(it), seq)
@@ -134,7 +134,7 @@ def check_iter_pickle(self, it, seq):
134134
next(it)
135135
except StopIteration:
136136
return
137-
d = pickle.dumps(it)
137+
d = pickle.dumps(it, proto)
138138
it = pickle.loads(d)
139139
self.assertEqual(list(it), seq[1:])
140140

@@ -636,9 +636,10 @@ def badfunc():
636636
self.assertRaises(TypeError, list, filter(42, (1, 2)))
637637

638638
def test_filter_pickle(self):
639-
f1 = filter(filter_char, "abcdeabcde")
640-
f2 = filter(filter_char, "abcdeabcde")
641-
self.check_iter_pickle(f1, list(f2))
639+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
640+
f1 = filter(filter_char, "abcdeabcde")
641+
f2 = filter(filter_char, "abcdeabcde")
642+
self.check_iter_pickle(f1, list(f2), proto)
642643

643644
def test_getattr(self):
644645
self.assertTrue(getattr(sys, 'stdout') is sys.stdout)
@@ -834,9 +835,10 @@ def badfunc(x):
834835
self.assertRaises(RuntimeError, list, map(badfunc, range(5)))
835836

836837
def test_map_pickle(self):
837-
m1 = map(map_char, "Is this the real life?")
838-
m2 = map(map_char, "Is this the real life?")
839-
self.check_iter_pickle(m1, list(m2))
838+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
839+
m1 = map(map_char, "Is this the real life?")
840+
m2 = map(map_char, "Is this the real life?")
841+
self.check_iter_pickle(m1, list(m2), proto)
840842

841843
def test_max(self):
842844
self.assertEqual(max('123123'), '3')
@@ -1433,8 +1435,9 @@ def test_zip_pickle(self):
14331435
a = (1, 2, 3)
14341436
b = (4, 5, 6)
14351437
t = [(1, 4), (2, 5), (3, 6)]
1436-
z1 = zip(a, b)
1437-
self.check_iter_pickle(z1, t)
1438+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1439+
z1 = zip(a, b)
1440+
self.check_iter_pickle(z1, t, proto)
14381441

14391442
def test_format(self):
14401443
# Test the basic machinery of the format() builtin. Don't test

Lib/test/test_bytes.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -555,22 +555,23 @@ def test_pickling(self):
555555
self.assertEqual(b, q)
556556

557557
def test_iterator_pickling(self):
558-
for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0":
559-
it = itorg = iter(self.type2test(b))
560-
data = list(self.type2test(b))
561-
d = pickle.dumps(it)
562-
it = pickle.loads(d)
563-
self.assertEqual(type(itorg), type(it))
564-
self.assertEqual(list(it), data)
565-
566-
it = pickle.loads(d)
567-
try:
568-
next(it)
569-
except StopIteration:
570-
continue
571-
d = pickle.dumps(it)
572-
it = pickle.loads(d)
573-
self.assertEqual(list(it), data[1:])
558+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
559+
for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0":
560+
it = itorg = iter(self.type2test(b))
561+
data = list(self.type2test(b))
562+
d = pickle.dumps(it, proto)
563+
it = pickle.loads(d)
564+
self.assertEqual(type(itorg), type(it))
565+
self.assertEqual(list(it), data)
566+
567+
it = pickle.loads(d)
568+
try:
569+
next(it)
570+
except StopIteration:
571+
continue
572+
d = pickle.dumps(it, proto)
573+
it = pickle.loads(d)
574+
self.assertEqual(list(it), data[1:])
574575

575576
def test_strip(self):
576577
b = self.type2test(b'mississippi')

Lib/test/test_bz2.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,9 @@ def testCompress4G(self, size):
646646
data = None
647647

648648
def testPickle(self):
649-
with self.assertRaises(TypeError):
650-
pickle.dumps(BZ2Compressor())
649+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
650+
with self.assertRaises(TypeError):
651+
pickle.dumps(BZ2Compressor(), proto)
651652

652653

653654
class BZ2DecompressorTest(BaseTest):
@@ -702,8 +703,9 @@ def testDecompress4G(self, size):
702703
decompressed = None
703704

704705
def testPickle(self):
705-
with self.assertRaises(TypeError):
706-
pickle.dumps(BZ2Decompressor())
706+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
707+
with self.assertRaises(TypeError):
708+
pickle.dumps(BZ2Decompressor(), proto)
707709

708710

709711
class CompressDecompressTest(BaseTest):

Lib/test/test_collections.py

Lines changed: 36 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,17 @@ def test_basics(self):
6363
for m1, m2 in zip(d.maps[1:], e.maps[1:]):
6464
self.assertIs(m1, m2)
6565

66-
for e in [pickle.loads(pickle.dumps(d)),
67-
copy.deepcopy(d),
66+
# check deep copies
67+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
68+
e = pickle.loads(pickle.dumps(d, proto))
69+
self.assertEqual(d, e)
70+
self.assertEqual(d.maps, e.maps)
71+
self.assertIsNot(d, e)
72+
for m1, m2 in zip(d.maps, e.maps):
73+
self.assertIsNot(m1, m2, e)
74+
for e in [copy.deepcopy(d),
6875
eval(repr(d))
69-
]: # check deep copies
76+
]:
7077
self.assertEqual(d, e)
7178
self.assertEqual(d.maps, e.maps)
7279
self.assertIsNot(d, e)
@@ -1110,28 +1117,21 @@ def test_copying(self):
11101117
# Check that counters are copyable, deepcopyable, picklable, and
11111118
#have a repr/eval round-trip
11121119
words = Counter('which witch had which witches wrist watch'.split())
1120+
def check(dup):
1121+
msg = "\ncopy: %s\nwords: %s" % (dup, words)
1122+
self.assertIsNot(dup, words, msg)
1123+
self.assertEqual(dup, words)
1124+
check(words.copy())
1125+
check(copy.copy(words))
1126+
check(copy.deepcopy(words))
1127+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1128+
with self.subTest(proto=proto):
1129+
check(pickle.loads(pickle.dumps(words, proto)))
1130+
check(eval(repr(words)))
11131131
update_test = Counter()
11141132
update_test.update(words)
1115-
for label, dup in [
1116-
('words.copy()', words.copy()),
1117-
('copy.copy(words)', copy.copy(words)),
1118-
('copy.deepcopy(words)', copy.deepcopy(words)),
1119-
('pickle.loads(pickle.dumps(words, 0))',
1120-
pickle.loads(pickle.dumps(words, 0))),
1121-
('pickle.loads(pickle.dumps(words, 1))',
1122-
pickle.loads(pickle.dumps(words, 1))),
1123-
('pickle.loads(pickle.dumps(words, 2))',
1124-
pickle.loads(pickle.dumps(words, 2))),
1125-
('pickle.loads(pickle.dumps(words, -1))',
1126-
pickle.loads(pickle.dumps(words, -1))),
1127-
('eval(repr(words))', eval(repr(words))),
1128-
('update_test', update_test),
1129-
('Counter(words)', Counter(words)),
1130-
]:
1131-
with self.subTest(label=label):
1132-
msg = "\ncopy: %s\nwords: %s" % (dup, words)
1133-
self.assertIsNot(dup, words, msg)
1134-
self.assertEqual(dup, words)
1133+
check(update_test)
1134+
check(Counter(words))
11351135

11361136
def test_copy_subclass(self):
11371137
class MyCounter(Counter):
@@ -1433,30 +1433,21 @@ def test_copying(self):
14331433
# and have a repr/eval round-trip
14341434
pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
14351435
od = OrderedDict(pairs)
1436+
def check(dup):
1437+
msg = "\ncopy: %s\nod: %s" % (dup, od)
1438+
self.assertIsNot(dup, od, msg)
1439+
self.assertEqual(dup, od)
1440+
check(od.copy())
1441+
check(copy.copy(od))
1442+
check(copy.deepcopy(od))
1443+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1444+
with self.subTest(proto=proto):
1445+
check(pickle.loads(pickle.dumps(od, proto)))
1446+
check(eval(repr(od)))
14361447
update_test = OrderedDict()
14371448
update_test.update(od)
1438-
for label, dup in [
1439-
('od.copy()', od.copy()),
1440-
('copy.copy(od)', copy.copy(od)),
1441-
('copy.deepcopy(od)', copy.deepcopy(od)),
1442-
('pickle.loads(pickle.dumps(od, 0))',
1443-
pickle.loads(pickle.dumps(od, 0))),
1444-
('pickle.loads(pickle.dumps(od, 1))',
1445-
pickle.loads(pickle.dumps(od, 1))),
1446-
('pickle.loads(pickle.dumps(od, 2))',
1447-
pickle.loads(pickle.dumps(od, 2))),
1448-
('pickle.loads(pickle.dumps(od, 3))',
1449-
pickle.loads(pickle.dumps(od, 3))),
1450-
('pickle.loads(pickle.dumps(od, -1))',
1451-
pickle.loads(pickle.dumps(od, -1))),
1452-
('eval(repr(od))', eval(repr(od))),
1453-
('update_test', update_test),
1454-
('OrderedDict(od)', OrderedDict(od)),
1455-
]:
1456-
with self.subTest(label=label):
1457-
msg = "\ncopy: %s\nod: %s" % (dup, od)
1458-
self.assertIsNot(dup, od, msg)
1459-
self.assertEqual(dup, od)
1449+
check(update_test)
1450+
check(OrderedDict(od))
14601451

14611452
def test_yaml_linkage(self):
14621453
# Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature.

0 commit comments

Comments
 (0)