Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit de128e1

Browse files
Issue #26015: Added new tests for pickling iterators of mutable sequences.
2 parents 5608411 + aabafe7 commit de128e1

6 files changed

Lines changed: 216 additions & 50 deletions

File tree

Lib/test/test_array.py

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -284,19 +284,42 @@ def test_pickle_for_empty_array(self):
284284
self.assertEqual(type(a), type(b))
285285

286286
def test_iterator_pickle(self):
287-
data = array.array(self.typecode, self.example)
287+
orig = array.array(self.typecode, self.example)
288+
data = list(orig)
289+
data2 = data[::-1]
288290
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
289-
orgit = iter(data)
290-
d = pickle.dumps(orgit, proto)
291-
it = pickle.loads(d)
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:])
291+
# initial iterator
292+
itorig = iter(orig)
293+
d = pickle.dumps((itorig, orig), proto)
294+
it, a = pickle.loads(d)
295+
a.fromlist(data2)
296+
self.assertEqual(type(it), type(itorig))
297+
self.assertEqual(list(it), data + data2)
298+
299+
# running iterator
300+
next(itorig)
301+
d = pickle.dumps((itorig, orig), proto)
302+
it, a = pickle.loads(d)
303+
a.fromlist(data2)
304+
self.assertEqual(type(it), type(itorig))
305+
self.assertEqual(list(it), data[1:] + data2)
306+
307+
# empty iterator
308+
for i in range(1, len(data)):
309+
next(itorig)
310+
d = pickle.dumps((itorig, orig), proto)
311+
it, a = pickle.loads(d)
312+
a.fromlist(data2)
313+
self.assertEqual(type(it), type(itorig))
314+
self.assertEqual(list(it), data2)
315+
316+
# exhausted iterator
317+
self.assertRaises(StopIteration, next, itorig)
318+
d = pickle.dumps((itorig, orig), proto)
319+
it, a = pickle.loads(d)
320+
a.fromlist(data2)
321+
self.assertEqual(type(it), type(itorig))
322+
self.assertEqual(list(it), data2)
300323

301324
def test_insert(self):
302325
a = array.array(self.typecode, self.example)

Lib/test/test_bytes.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -609,10 +609,9 @@ def test_iterator_pickling(self):
609609
self.assertEqual(list(it), data)
610610

611611
it = pickle.loads(d)
612-
try:
613-
next(it)
614-
except StopIteration:
612+
if not b:
615613
continue
614+
next(it)
616615
d = pickle.dumps(it, proto)
617616
it = pickle.loads(d)
618617
self.assertEqual(list(it), data[1:])
@@ -1379,6 +1378,43 @@ def test_obsolete_write_lock(self):
13791378
from _testcapi import getbuffer_with_null_view
13801379
self.assertRaises(BufferError, getbuffer_with_null_view, bytearray())
13811380

1381+
def test_iterator_pickling2(self):
1382+
orig = bytearray(b'abc')
1383+
data = list(b'qwerty')
1384+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1385+
# initial iterator
1386+
itorig = iter(orig)
1387+
d = pickle.dumps((itorig, orig), proto)
1388+
it, b = pickle.loads(d)
1389+
b[:] = data
1390+
self.assertEqual(type(it), type(itorig))
1391+
self.assertEqual(list(it), data)
1392+
1393+
# running iterator
1394+
next(itorig)
1395+
d = pickle.dumps((itorig, orig), proto)
1396+
it, b = pickle.loads(d)
1397+
b[:] = data
1398+
self.assertEqual(type(it), type(itorig))
1399+
self.assertEqual(list(it), data[1:])
1400+
1401+
# empty iterator
1402+
for i in range(1, len(orig)):
1403+
next(itorig)
1404+
d = pickle.dumps((itorig, orig), proto)
1405+
it, b = pickle.loads(d)
1406+
b[:] = data
1407+
self.assertEqual(type(it), type(itorig))
1408+
self.assertEqual(list(it), data[len(orig):])
1409+
1410+
# exhausted iterator
1411+
self.assertRaises(StopIteration, next, itorig)
1412+
d = pickle.dumps((itorig, orig), proto)
1413+
it, b = pickle.loads(d)
1414+
b[:] = data
1415+
self.assertEqual(list(it), [])
1416+
1417+
13821418
class AssortedBytesTest(unittest.TestCase):
13831419
#
13841420
# Test various combinations of bytes and bytearray

Lib/test/test_deque.py

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -640,18 +640,45 @@ def test_pickle_recursive(self):
640640
self.assertEqual(e.maxlen, d.maxlen)
641641

642642
def test_iterator_pickle(self):
643-
data = deque(range(200))
643+
orig = deque(range(200))
644+
data = [i*1.01 for i in orig]
644645
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
645-
it = itorg = iter(data)
646-
d = pickle.dumps(it, proto)
647-
it = pickle.loads(d)
648-
self.assertEqual(type(itorg), type(it))
649-
self.assertEqual(list(it), list(data))
650-
651-
it = pickle.loads(d)
652-
next(it)
653-
d = pickle.dumps(it, proto)
654-
self.assertEqual(list(it), list(data)[1:])
646+
# initial iterator
647+
itorg = iter(orig)
648+
dump = pickle.dumps((itorg, orig), proto)
649+
it, d = pickle.loads(dump)
650+
for i, x in enumerate(data):
651+
d[i] = x
652+
self.assertEqual(type(it), type(itorg))
653+
self.assertEqual(list(it), data)
654+
655+
# running iterator
656+
next(itorg)
657+
dump = pickle.dumps((itorg, orig), proto)
658+
it, d = pickle.loads(dump)
659+
for i, x in enumerate(data):
660+
d[i] = x
661+
self.assertEqual(type(it), type(itorg))
662+
self.assertEqual(list(it), data[1:])
663+
664+
# empty iterator
665+
for i in range(1, len(data)):
666+
next(itorg)
667+
dump = pickle.dumps((itorg, orig), proto)
668+
it, d = pickle.loads(dump)
669+
for i, x in enumerate(data):
670+
d[i] = x
671+
self.assertEqual(type(it), type(itorg))
672+
self.assertEqual(list(it), [])
673+
674+
# exhausted iterator
675+
self.assertRaises(StopIteration, next, itorg)
676+
dump = pickle.dumps((itorg, orig), proto)
677+
it, d = pickle.loads(dump)
678+
for i, x in enumerate(data):
679+
d[i] = x
680+
self.assertEqual(type(it), type(itorg))
681+
self.assertEqual(list(it), [])
655682

656683
def test_deepcopy(self):
657684
mut = [10]

Lib/test/test_iter.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,42 @@ def test_seq_class_for(self):
153153
def test_seq_class_iter(self):
154154
self.check_iterator(iter(SequenceClass(10)), list(range(10)))
155155

156+
def test_mutating_seq_class_iter_pickle(self):
157+
orig = SequenceClass(5)
158+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
159+
# initial iterator
160+
itorig = iter(orig)
161+
d = pickle.dumps((itorig, orig), proto)
162+
it, seq = pickle.loads(d)
163+
seq.n = 7
164+
self.assertIs(type(it), type(itorig))
165+
self.assertEqual(list(it), list(range(7)))
166+
167+
# running iterator
168+
next(itorig)
169+
d = pickle.dumps((itorig, orig), proto)
170+
it, seq = pickle.loads(d)
171+
seq.n = 7
172+
self.assertIs(type(it), type(itorig))
173+
self.assertEqual(list(it), list(range(1, 7)))
174+
175+
# empty iterator
176+
for i in range(1, 5):
177+
next(itorig)
178+
d = pickle.dumps((itorig, orig), proto)
179+
it, seq = pickle.loads(d)
180+
seq.n = 7
181+
self.assertIs(type(it), type(itorig))
182+
self.assertEqual(list(it), list(range(5, 7)))
183+
184+
# exhausted iterator
185+
self.assertRaises(StopIteration, next, itorig)
186+
d = pickle.dumps((itorig, orig), proto)
187+
it, seq = pickle.loads(d)
188+
seq.n = 7
189+
self.assertTrue(isinstance(it, collections.abc.Iterator))
190+
self.assertEqual(list(it), [])
191+
156192
# Test a new_style class with __iter__ but no next() method
157193
def test_new_style_iter_class(self):
158194
class IterClass(object):

Lib/test/test_list.py

Lines changed: 66 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -72,34 +72,76 @@ def check(n):
7272
check(1000000)
7373

7474
def test_iterator_pickle(self):
75-
# Userlist iterators don't support pickling yet since
76-
# they are based on generators.
77-
data = self.type2test([4, 5, 6, 7])
75+
orig = self.type2test([4, 5, 6, 7])
76+
data = [10, 11, 12, 13, 14, 15]
7877
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
79-
it = itorg = iter(data)
80-
d = pickle.dumps(it, proto)
81-
it = pickle.loads(d)
82-
self.assertEqual(type(itorg), type(it))
83-
self.assertEqual(self.type2test(it), self.type2test(data))
84-
85-
it = pickle.loads(d)
86-
next(it)
87-
d = pickle.dumps(it, proto)
88-
self.assertEqual(self.type2test(it), self.type2test(data)[1:])
78+
# initial iterator
79+
itorig = iter(orig)
80+
d = pickle.dumps((itorig, orig), proto)
81+
it, a = pickle.loads(d)
82+
a[:] = data
83+
self.assertEqual(type(it), type(itorig))
84+
self.assertEqual(list(it), data)
85+
86+
# running iterator
87+
next(itorig)
88+
d = pickle.dumps((itorig, orig), proto)
89+
it, a = pickle.loads(d)
90+
a[:] = data
91+
self.assertEqual(type(it), type(itorig))
92+
self.assertEqual(list(it), data[1:])
93+
94+
# empty iterator
95+
for i in range(1, len(orig)):
96+
next(itorig)
97+
d = pickle.dumps((itorig, orig), proto)
98+
it, a = pickle.loads(d)
99+
a[:] = data
100+
self.assertEqual(type(it), type(itorig))
101+
self.assertEqual(list(it), data[len(orig):])
102+
103+
# exhausted iterator
104+
self.assertRaises(StopIteration, next, itorig)
105+
d = pickle.dumps((itorig, orig), proto)
106+
it, a = pickle.loads(d)
107+
a[:] = data
108+
self.assertEqual(list(it), [])
89109

90110
def test_reversed_pickle(self):
91-
data = self.type2test([4, 5, 6, 7])
111+
orig = self.type2test([4, 5, 6, 7])
112+
data = [10, 11, 12, 13, 14, 15]
92113
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
93-
it = itorg = reversed(data)
94-
d = pickle.dumps(it, proto)
95-
it = pickle.loads(d)
96-
self.assertEqual(type(itorg), type(it))
97-
self.assertEqual(self.type2test(it), self.type2test(reversed(data)))
98-
99-
it = pickle.loads(d)
100-
next(it)
101-
d = pickle.dumps(it, proto)
102-
self.assertEqual(self.type2test(it), self.type2test(reversed(data))[1:])
114+
# initial iterator
115+
itorig = reversed(orig)
116+
d = pickle.dumps((itorig, orig), proto)
117+
it, a = pickle.loads(d)
118+
a[:] = data
119+
self.assertEqual(type(it), type(itorig))
120+
self.assertEqual(list(it), data[len(orig)-1::-1])
121+
122+
# running iterator
123+
next(itorig)
124+
d = pickle.dumps((itorig, orig), proto)
125+
it, a = pickle.loads(d)
126+
a[:] = data
127+
self.assertEqual(type(it), type(itorig))
128+
self.assertEqual(list(it), data[len(orig)-2::-1])
129+
130+
# empty iterator
131+
for i in range(1, len(orig)):
132+
next(itorig)
133+
d = pickle.dumps((itorig, orig), proto)
134+
it, a = pickle.loads(d)
135+
a[:] = data
136+
self.assertEqual(type(it), type(itorig))
137+
self.assertEqual(list(it), [])
138+
139+
# exhausted iterator
140+
self.assertRaises(StopIteration, next, itorig)
141+
d = pickle.dumps((itorig, orig), proto)
142+
it, a = pickle.loads(d)
143+
a[:] = data
144+
self.assertEqual(list(it), [])
103145

104146
def test_no_comdat_folding(self):
105147
# Issue 8847: In the PGO build, the MSVC linker's COMDAT folding

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,8 @@ Documentation
749749
Tests
750750
-----
751751

752+
- Issue #26015: Added new tests for pickling iterators of mutable sequences.
753+
752754
- Issue #26325: Added test.support.check_no_resource_warning() to check that
753755
no ResourceWarning is emitted.
754756

0 commit comments

Comments
 (0)