@@ -1172,6 +1172,7 @@ def test_islice(self):
11721172 (10 , 20 , 3 ),
11731173 (10 , 3 , 20 ),
11741174 (10 , 20 ),
1175+ (10 , 10 ),
11751176 (10 , 3 ),
11761177 (20 ,)
11771178 ]:
@@ -1198,6 +1199,10 @@ def test_islice(self):
11981199 self .assertEqual (list (islice (it , 3 )), list (range (3 )))
11991200 self .assertEqual (list (it ), list (range (3 , 10 )))
12001201
1202+ it = iter (range (10 ))
1203+ self .assertEqual (list (islice (it , 3 , 3 )), [])
1204+ self .assertEqual (list (it ), list (range (3 , 10 )))
1205+
12011206 # Test invalid arguments
12021207 ra = range (10 )
12031208 self .assertRaises (TypeError , islice , ra )
@@ -1571,6 +1576,48 @@ def test_takewhile(self):
15711576 self .assertEqual (list (takewhile (lambda x : x < 5 , [1 ,4 ,6 ,4 ,1 ])), [1 ,4 ])
15721577
15731578
1579+ class TestPurePythonRoughEquivalents (unittest .TestCase ):
1580+
1581+ @staticmethod
1582+ def islice (iterable , * args ):
1583+ s = slice (* args )
1584+ start , stop , step = s .start or 0 , s .stop or sys .maxsize , s .step or 1
1585+ it = iter (range (start , stop , step ))
1586+ try :
1587+ nexti = next (it )
1588+ except StopIteration :
1589+ # Consume *iterable* up to the *start* position.
1590+ for i , element in zip (range (start ), iterable ):
1591+ pass
1592+ return
1593+ try :
1594+ for i , element in enumerate (iterable ):
1595+ if i == nexti :
1596+ yield element
1597+ nexti = next (it )
1598+ except StopIteration :
1599+ # Consume to *stop*.
1600+ for i , element in zip (range (i + 1 , stop ), iterable ):
1601+ pass
1602+
1603+ def test_islice_recipe (self ):
1604+ self .assertEqual (list (self .islice ('ABCDEFG' , 2 )), list ('AB' ))
1605+ self .assertEqual (list (self .islice ('ABCDEFG' , 2 , 4 )), list ('CD' ))
1606+ self .assertEqual (list (self .islice ('ABCDEFG' , 2 , None )), list ('CDEFG' ))
1607+ self .assertEqual (list (self .islice ('ABCDEFG' , 0 , None , 2 )), list ('ACEG' ))
1608+ # Test items consumed.
1609+ it = iter (range (10 ))
1610+ self .assertEqual (list (self .islice (it , 3 )), list (range (3 )))
1611+ self .assertEqual (list (it ), list (range (3 , 10 )))
1612+ it = iter (range (10 ))
1613+ self .assertEqual (list (self .islice (it , 3 , 3 )), [])
1614+ self .assertEqual (list (it ), list (range (3 , 10 )))
1615+ # Test that slice finishes in predictable state.
1616+ c = count ()
1617+ self .assertEqual (list (self .islice (c , 1 , 3 , 50 )), [1 ])
1618+ self .assertEqual (next (c ), 3 )
1619+
1620+
15741621class TestGC (unittest .TestCase ):
15751622
15761623 def makecycle (self , iterator , container ):
@@ -2125,6 +2172,17 @@ def test_permutations_sizeof(self):
21252172... "Return function(0), function(1), ..."
21262173... return map(function, count(start))
21272174
2175+ >>> import collections
2176+ >>> def consume(iterator, n=None):
2177+ ... "Advance the iterator n-steps ahead. If n is None, consume entirely."
2178+ ... # Use functions that consume iterators at C speed.
2179+ ... if n is None:
2180+ ... # feed the entire iterator into a zero-length deque
2181+ ... collections.deque(iterator, maxlen=0)
2182+ ... else:
2183+ ... # advance to the empty slice starting at position n
2184+ ... next(islice(iterator, n, n), None)
2185+
21282186>>> def nth(iterable, n, default=None):
21292187... "Returns the nth item or a default value"
21302188... return next(islice(iterable, n, None), default)
@@ -2265,6 +2323,14 @@ def test_permutations_sizeof(self):
22652323>>> list(islice(tabulate(lambda x: 2*x), 4))
22662324[0, 2, 4, 6]
22672325
2326+ >>> it = iter(range(10))
2327+ >>> consume(it, 3)
2328+ >>> next(it)
2329+ 3
2330+ >>> consume(it)
2331+ >>> next(it, 'Done')
2332+ 'Done'
2333+
22682334>>> nth('abcde', 3)
22692335'd'
22702336
@@ -2353,6 +2419,7 @@ def test_main(verbose=None):
23532419 test_classes = (TestBasicOps , TestVariousIteratorArgs , TestGC ,
23542420 RegressionTests , LengthTransparency ,
23552421 SubclassWithKwargsTest , TestExamples ,
2422+ TestPurePythonRoughEquivalents ,
23562423 SizeofTest )
23572424 support .run_unittest (* test_classes )
23582425
0 commit comments