Issue #26015: Added new tests for pickling iterators of mutable sequences.
This commit is contained in:
parent
d55162517d
commit
aabafe7bc2
|
@ -284,19 +284,42 @@ class BaseTest:
|
||||||
self.assertEqual(type(a), type(b))
|
self.assertEqual(type(a), type(b))
|
||||||
|
|
||||||
def test_iterator_pickle(self):
|
def test_iterator_pickle(self):
|
||||||
data = array.array(self.typecode, self.example)
|
orig = array.array(self.typecode, self.example)
|
||||||
|
data = list(orig)
|
||||||
|
data2 = data[::-1]
|
||||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||||
orgit = iter(data)
|
# initial iterator
|
||||||
d = pickle.dumps(orgit, proto)
|
itorig = iter(orig)
|
||||||
it = pickle.loads(d)
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
self.assertEqual(type(orgit), type(it))
|
it, a = pickle.loads(d)
|
||||||
self.assertEqual(list(it), list(data))
|
a.fromlist(data2)
|
||||||
|
self.assertEqual(type(it), type(itorig))
|
||||||
|
self.assertEqual(list(it), data + data2)
|
||||||
|
|
||||||
if len(data):
|
# running iterator
|
||||||
it = pickle.loads(d)
|
next(itorig)
|
||||||
next(it)
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
d = pickle.dumps(it, proto)
|
it, a = pickle.loads(d)
|
||||||
self.assertEqual(list(it), list(data)[1:])
|
a.fromlist(data2)
|
||||||
|
self.assertEqual(type(it), type(itorig))
|
||||||
|
self.assertEqual(list(it), data[1:] + data2)
|
||||||
|
|
||||||
|
# empty iterator
|
||||||
|
for i in range(1, len(data)):
|
||||||
|
next(itorig)
|
||||||
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
|
it, a = pickle.loads(d)
|
||||||
|
a.fromlist(data2)
|
||||||
|
self.assertEqual(type(it), type(itorig))
|
||||||
|
self.assertEqual(list(it), data2)
|
||||||
|
|
||||||
|
# exhausted iterator
|
||||||
|
self.assertRaises(StopIteration, next, itorig)
|
||||||
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
|
it, a = pickle.loads(d)
|
||||||
|
a.fromlist(data2)
|
||||||
|
self.assertEqual(type(it), type(itorig))
|
||||||
|
self.assertEqual(list(it), data2)
|
||||||
|
|
||||||
def test_insert(self):
|
def test_insert(self):
|
||||||
a = array.array(self.typecode, self.example)
|
a = array.array(self.typecode, self.example)
|
||||||
|
|
|
@ -595,10 +595,9 @@ class BaseBytesTest:
|
||||||
self.assertEqual(list(it), data)
|
self.assertEqual(list(it), data)
|
||||||
|
|
||||||
it = pickle.loads(d)
|
it = pickle.loads(d)
|
||||||
try:
|
if not b:
|
||||||
next(it)
|
|
||||||
except StopIteration:
|
|
||||||
continue
|
continue
|
||||||
|
next(it)
|
||||||
d = pickle.dumps(it, proto)
|
d = pickle.dumps(it, proto)
|
||||||
it = pickle.loads(d)
|
it = pickle.loads(d)
|
||||||
self.assertEqual(list(it), data[1:])
|
self.assertEqual(list(it), data[1:])
|
||||||
|
@ -1284,6 +1283,43 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase):
|
||||||
from _testcapi import getbuffer_with_null_view
|
from _testcapi import getbuffer_with_null_view
|
||||||
self.assertRaises(BufferError, getbuffer_with_null_view, bytearray())
|
self.assertRaises(BufferError, getbuffer_with_null_view, bytearray())
|
||||||
|
|
||||||
|
def test_iterator_pickling2(self):
|
||||||
|
orig = bytearray(b'abc')
|
||||||
|
data = list(b'qwerty')
|
||||||
|
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||||
|
# initial iterator
|
||||||
|
itorig = iter(orig)
|
||||||
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
|
it, b = pickle.loads(d)
|
||||||
|
b[:] = data
|
||||||
|
self.assertEqual(type(it), type(itorig))
|
||||||
|
self.assertEqual(list(it), data)
|
||||||
|
|
||||||
|
# running iterator
|
||||||
|
next(itorig)
|
||||||
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
|
it, b = pickle.loads(d)
|
||||||
|
b[:] = data
|
||||||
|
self.assertEqual(type(it), type(itorig))
|
||||||
|
self.assertEqual(list(it), data[1:])
|
||||||
|
|
||||||
|
# empty iterator
|
||||||
|
for i in range(1, len(orig)):
|
||||||
|
next(itorig)
|
||||||
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
|
it, b = pickle.loads(d)
|
||||||
|
b[:] = data
|
||||||
|
self.assertEqual(type(it), type(itorig))
|
||||||
|
self.assertEqual(list(it), data[len(orig):])
|
||||||
|
|
||||||
|
# exhausted iterator
|
||||||
|
self.assertRaises(StopIteration, next, itorig)
|
||||||
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
|
it, b = pickle.loads(d)
|
||||||
|
b[:] = data
|
||||||
|
self.assertEqual(list(it), [])
|
||||||
|
|
||||||
|
|
||||||
class AssortedBytesTest(unittest.TestCase):
|
class AssortedBytesTest(unittest.TestCase):
|
||||||
#
|
#
|
||||||
# Test various combinations of bytes and bytearray
|
# Test various combinations of bytes and bytearray
|
||||||
|
|
|
@ -638,18 +638,45 @@ class TestBasic(unittest.TestCase):
|
||||||
## self.assertEqual(id(e), id(e[-1]))
|
## self.assertEqual(id(e), id(e[-1]))
|
||||||
|
|
||||||
def test_iterator_pickle(self):
|
def test_iterator_pickle(self):
|
||||||
data = deque(range(200))
|
orig = deque(range(200))
|
||||||
|
data = [i*1.01 for i in orig]
|
||||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||||
it = itorg = iter(data)
|
# initial iterator
|
||||||
d = pickle.dumps(it, proto)
|
itorg = iter(orig)
|
||||||
it = pickle.loads(d)
|
dump = pickle.dumps((itorg, orig), proto)
|
||||||
self.assertEqual(type(itorg), type(it))
|
it, d = pickle.loads(dump)
|
||||||
self.assertEqual(list(it), list(data))
|
for i, x in enumerate(data):
|
||||||
|
d[i] = x
|
||||||
|
self.assertEqual(type(it), type(itorg))
|
||||||
|
self.assertEqual(list(it), data)
|
||||||
|
|
||||||
it = pickle.loads(d)
|
# running iterator
|
||||||
next(it)
|
next(itorg)
|
||||||
d = pickle.dumps(it, proto)
|
dump = pickle.dumps((itorg, orig), proto)
|
||||||
self.assertEqual(list(it), list(data)[1:])
|
it, d = pickle.loads(dump)
|
||||||
|
for i, x in enumerate(data):
|
||||||
|
d[i] = x
|
||||||
|
self.assertEqual(type(it), type(itorg))
|
||||||
|
self.assertEqual(list(it), data[1:])
|
||||||
|
|
||||||
|
# empty iterator
|
||||||
|
for i in range(1, len(data)):
|
||||||
|
next(itorg)
|
||||||
|
dump = pickle.dumps((itorg, orig), proto)
|
||||||
|
it, d = pickle.loads(dump)
|
||||||
|
for i, x in enumerate(data):
|
||||||
|
d[i] = x
|
||||||
|
self.assertEqual(type(it), type(itorg))
|
||||||
|
self.assertEqual(list(it), [])
|
||||||
|
|
||||||
|
# exhausted iterator
|
||||||
|
self.assertRaises(StopIteration, next, itorg)
|
||||||
|
dump = pickle.dumps((itorg, orig), proto)
|
||||||
|
it, d = pickle.loads(dump)
|
||||||
|
for i, x in enumerate(data):
|
||||||
|
d[i] = x
|
||||||
|
self.assertEqual(type(it), type(itorg))
|
||||||
|
self.assertEqual(list(it), [])
|
||||||
|
|
||||||
def test_deepcopy(self):
|
def test_deepcopy(self):
|
||||||
mut = [10]
|
mut = [10]
|
||||||
|
|
|
@ -153,6 +153,42 @@ class TestCase(unittest.TestCase):
|
||||||
def test_seq_class_iter(self):
|
def test_seq_class_iter(self):
|
||||||
self.check_iterator(iter(SequenceClass(10)), list(range(10)))
|
self.check_iterator(iter(SequenceClass(10)), list(range(10)))
|
||||||
|
|
||||||
|
def test_mutating_seq_class_iter_pickle(self):
|
||||||
|
orig = SequenceClass(5)
|
||||||
|
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||||
|
# initial iterator
|
||||||
|
itorig = iter(orig)
|
||||||
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
|
it, seq = pickle.loads(d)
|
||||||
|
seq.n = 7
|
||||||
|
self.assertIs(type(it), type(itorig))
|
||||||
|
self.assertEqual(list(it), list(range(7)))
|
||||||
|
|
||||||
|
# running iterator
|
||||||
|
next(itorig)
|
||||||
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
|
it, seq = pickle.loads(d)
|
||||||
|
seq.n = 7
|
||||||
|
self.assertIs(type(it), type(itorig))
|
||||||
|
self.assertEqual(list(it), list(range(1, 7)))
|
||||||
|
|
||||||
|
# empty iterator
|
||||||
|
for i in range(1, 5):
|
||||||
|
next(itorig)
|
||||||
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
|
it, seq = pickle.loads(d)
|
||||||
|
seq.n = 7
|
||||||
|
self.assertIs(type(it), type(itorig))
|
||||||
|
self.assertEqual(list(it), list(range(5, 7)))
|
||||||
|
|
||||||
|
# exhausted iterator
|
||||||
|
self.assertRaises(StopIteration, next, itorig)
|
||||||
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
|
it, seq = pickle.loads(d)
|
||||||
|
seq.n = 7
|
||||||
|
self.assertTrue(isinstance(it, collections.abc.Iterator))
|
||||||
|
self.assertEqual(list(it), [])
|
||||||
|
|
||||||
# Test a new_style class with __iter__ but no next() method
|
# Test a new_style class with __iter__ but no next() method
|
||||||
def test_new_style_iter_class(self):
|
def test_new_style_iter_class(self):
|
||||||
class IterClass(object):
|
class IterClass(object):
|
||||||
|
|
|
@ -72,34 +72,76 @@ class ListTest(list_tests.CommonTest):
|
||||||
check(1000000)
|
check(1000000)
|
||||||
|
|
||||||
def test_iterator_pickle(self):
|
def test_iterator_pickle(self):
|
||||||
# Userlist iterators don't support pickling yet since
|
orig = self.type2test([4, 5, 6, 7])
|
||||||
# they are based on generators.
|
data = [10, 11, 12, 13, 14, 15]
|
||||||
data = self.type2test([4, 5, 6, 7])
|
|
||||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||||
it = itorg = iter(data)
|
# initial iterator
|
||||||
d = pickle.dumps(it, proto)
|
itorig = iter(orig)
|
||||||
it = pickle.loads(d)
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
self.assertEqual(type(itorg), type(it))
|
it, a = pickle.loads(d)
|
||||||
self.assertEqual(self.type2test(it), self.type2test(data))
|
a[:] = data
|
||||||
|
self.assertEqual(type(it), type(itorig))
|
||||||
|
self.assertEqual(list(it), data)
|
||||||
|
|
||||||
it = pickle.loads(d)
|
# running iterator
|
||||||
next(it)
|
next(itorig)
|
||||||
d = pickle.dumps(it, proto)
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
self.assertEqual(self.type2test(it), self.type2test(data)[1:])
|
it, a = pickle.loads(d)
|
||||||
|
a[:] = data
|
||||||
|
self.assertEqual(type(it), type(itorig))
|
||||||
|
self.assertEqual(list(it), data[1:])
|
||||||
|
|
||||||
|
# empty iterator
|
||||||
|
for i in range(1, len(orig)):
|
||||||
|
next(itorig)
|
||||||
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
|
it, a = pickle.loads(d)
|
||||||
|
a[:] = data
|
||||||
|
self.assertEqual(type(it), type(itorig))
|
||||||
|
self.assertEqual(list(it), data[len(orig):])
|
||||||
|
|
||||||
|
# exhausted iterator
|
||||||
|
self.assertRaises(StopIteration, next, itorig)
|
||||||
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
|
it, a = pickle.loads(d)
|
||||||
|
a[:] = data
|
||||||
|
self.assertEqual(list(it), [])
|
||||||
|
|
||||||
def test_reversed_pickle(self):
|
def test_reversed_pickle(self):
|
||||||
data = self.type2test([4, 5, 6, 7])
|
orig = self.type2test([4, 5, 6, 7])
|
||||||
|
data = [10, 11, 12, 13, 14, 15]
|
||||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||||
it = itorg = reversed(data)
|
# initial iterator
|
||||||
d = pickle.dumps(it, proto)
|
itorig = reversed(orig)
|
||||||
it = pickle.loads(d)
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
self.assertEqual(type(itorg), type(it))
|
it, a = pickle.loads(d)
|
||||||
self.assertEqual(self.type2test(it), self.type2test(reversed(data)))
|
a[:] = data
|
||||||
|
self.assertEqual(type(it), type(itorig))
|
||||||
|
self.assertEqual(list(it), data[len(orig)-1::-1])
|
||||||
|
|
||||||
it = pickle.loads(d)
|
# running iterator
|
||||||
next(it)
|
next(itorig)
|
||||||
d = pickle.dumps(it, proto)
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
self.assertEqual(self.type2test(it), self.type2test(reversed(data))[1:])
|
it, a = pickle.loads(d)
|
||||||
|
a[:] = data
|
||||||
|
self.assertEqual(type(it), type(itorig))
|
||||||
|
self.assertEqual(list(it), data[len(orig)-2::-1])
|
||||||
|
|
||||||
|
# empty iterator
|
||||||
|
for i in range(1, len(orig)):
|
||||||
|
next(itorig)
|
||||||
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
|
it, a = pickle.loads(d)
|
||||||
|
a[:] = data
|
||||||
|
self.assertEqual(type(it), type(itorig))
|
||||||
|
self.assertEqual(list(it), [])
|
||||||
|
|
||||||
|
# exhausted iterator
|
||||||
|
self.assertRaises(StopIteration, next, itorig)
|
||||||
|
d = pickle.dumps((itorig, orig), proto)
|
||||||
|
it, a = pickle.loads(d)
|
||||||
|
a[:] = data
|
||||||
|
self.assertEqual(list(it), [])
|
||||||
|
|
||||||
def test_no_comdat_folding(self):
|
def test_no_comdat_folding(self):
|
||||||
# Issue 8847: In the PGO build, the MSVC linker's COMDAT folding
|
# Issue 8847: In the PGO build, the MSVC linker's COMDAT folding
|
||||||
|
|
|
@ -274,6 +274,8 @@ Documentation
|
||||||
Tests
|
Tests
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
- Issue #26015: Added new tests for pickling iterators of mutable sequences.
|
||||||
|
|
||||||
- Issue #26325: Added test.support.check_no_resource_warning() to check that
|
- Issue #26325: Added test.support.check_no_resource_warning() to check that
|
||||||
no ResourceWarning is emitted.
|
no ResourceWarning is emitted.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue