summaryrefslogtreecommitdiff
path: root/Lib/test/test_itertools.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_itertools.py')
-rw-r--r--Lib/test/test_itertools.py65
1 files changed, 49 insertions, 16 deletions
diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py
index e054303ded..ea1f57caad 100644
--- a/Lib/test/test_itertools.py
+++ b/Lib/test/test_itertools.py
@@ -4,7 +4,6 @@ from itertools import *
import weakref
from decimal import Decimal
from fractions import Fraction
-import sys
import operator
import random
import copy
@@ -644,24 +643,58 @@ class TestBasicOps(unittest.TestCase):
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
self.pickletest(proto, cycle('abc'))
+ for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+ # test with partial consumed input iterable
+ it = iter('abcde')
+ c = cycle(it)
+ _ = [next(c) for i in range(2)] # consume 2 of 5 inputs
+ p = pickle.dumps(c, proto)
+ d = pickle.loads(p) # rebuild the cycle object
+ self.assertEqual(take(20, d), list('cdeabcdeabcdeabcdeab'))
+
+ # test with completely consumed input iterable
+ it = iter('abcde')
+ c = cycle(it)
+ _ = [next(c) for i in range(7)] # consume 7 of 5 inputs
+ p = pickle.dumps(c, proto)
+ d = pickle.loads(p) # rebuild the cycle object
+ self.assertEqual(take(20, d), list('cdeabcdeabcdeabcdeab'))
+
def test_cycle_setstate(self):
+ # Verify both modes for restoring state
+
+ # Mode 0 is efficient. It uses an incompletely consumed input
+ # iterator to build a cycle object and then passes in state with
+ # a list of previously consumed values. There is no data
+ # overlap between the two.
+ c = cycle('defg')
+ c.__setstate__((list('abc'), 0))
+ self.assertEqual(take(20, c), list('defgabcdefgabcdefgab'))
+
+ # Mode 1 is inefficient. It starts with a cycle object built
+ # from an iterator over the remaining elements in a partial
+ # cycle and then passes in state with all of the previously
+ # seen values (this overlaps values included in the iterator).
+ c = cycle('defg')
+ c.__setstate__((list('abcdefg'), 1))
+ self.assertEqual(take(20, c), list('defgabcdefgabcdefgab'))
+
+ # The first argument to setstate needs to be a tuple
+ with self.assertRaises(TypeError):
+ cycle('defg').__setstate__([list('abcdefg'), 0])
+
+ # The first argument in the setstate tuple must be a list
+ with self.assertRaises(TypeError):
+ c = cycle('defg')
+ c.__setstate__((tuple('defg'), 0))
+ take(20, c)
+
+ # The second argument in the setstate tuple must be an int
+ with self.assertRaises(TypeError):
+ cycle('defg').__setstate__((list('abcdefg'), 'x'))
+
self.assertRaises(TypeError, cycle('').__setstate__, ())
- self.assertRaises(TypeError, cycle('').__setstate__, [])
- self.assertRaises(TypeError, cycle('').__setstate__, 0)
self.assertRaises(TypeError, cycle('').__setstate__, ([],))
- self.assertRaises(TypeError, cycle('').__setstate__, ((), 0))
- it = cycle('abc')
- it.__setstate__((['de', 'fg'], 0))
- self.assertEqual(list(islice(it, 15)),
- ['a', 'b', 'c', 'de', 'fg',
- 'a', 'b', 'c', 'de', 'fg',
- 'a', 'b', 'c', 'de', 'fg'])
- it = cycle('abc')
- it.__setstate__((['de', 'fg'], 1))
- self.assertEqual(list(islice(it, 15)),
- ['a', 'b', 'c', 'de', 'fg',
- 'de', 'fg', 'de', 'fg', 'de',
- 'fg', 'de', 'fg', 'de', 'fg'])
def test_groupby(self):
# Check whether it accepts arguments correctly