12
12
import sys
13
13
import struct
14
14
import threading
15
+ import gc
16
+
15
17
maxsize = support .MAX_Py_ssize_t
16
18
minsize = - maxsize - 1
17
19
@@ -193,7 +195,6 @@ def test_chain_reducible(self):
193
195
self .assertRaises (TypeError , list , oper (chain (2 , 3 )))
194
196
for proto in range (pickle .HIGHEST_PROTOCOL + 1 ):
195
197
self .pickletest (proto , chain ('abc' , 'def' ), compare = list ('abcdef' ))
196
-
197
198
# TODO: RUSTPYTHON
198
199
@unittest .expectedFailure
199
200
def test_chain_setstate (self ):
@@ -208,7 +209,6 @@ def test_chain_setstate(self):
208
209
it = chain ()
209
210
it .__setstate__ ((iter (['abc' , 'def' ]), iter (['ghi' ])))
210
211
self .assertEqual (list (it ), ['ghi' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' ])
211
-
212
212
# TODO: RUSTPYTHON
213
213
@unittest .expectedFailure
214
214
def test_combinations (self ):
@@ -1053,6 +1053,25 @@ def run(r1, r2):
1053
1053
self .assertEqual (next (it ), (1 , 2 ))
1054
1054
self .assertRaises (RuntimeError , next , it )
1055
1055
1056
+ def test_pairwise (self ):
1057
+ self .assertEqual (list (pairwise ('' )), [])
1058
+ self .assertEqual (list (pairwise ('a' )), [])
1059
+ self .assertEqual (list (pairwise ('ab' )),
1060
+ [('a' , 'b' )]),
1061
+ self .assertEqual (list (pairwise ('abcde' )),
1062
+ [('a' , 'b' ), ('b' , 'c' ), ('c' , 'd' ), ('d' , 'e' )])
1063
+ self .assertEqual (list (pairwise (range (10_000 ))),
1064
+ list (zip (range (10_000 ), range (1 , 10_000 ))))
1065
+
1066
+ with self .assertRaises (TypeError ):
1067
+ pairwise () # too few arguments
1068
+ with self .assertRaises (TypeError ):
1069
+ pairwise ('abc' , 10 ) # too many arguments
1070
+ with self .assertRaises (TypeError ):
1071
+ pairwise (iterable = 'abc' ) # keyword arguments
1072
+ with self .assertRaises (TypeError ):
1073
+ pairwise (None ) # non-iterable argument
1074
+
1056
1075
def test_product (self ):
1057
1076
for args , result in [
1058
1077
([], [()]), # zero iterables
@@ -1609,6 +1628,51 @@ def test_StopIteration(self):
1609
1628
self .assertRaises (StopIteration , next , f (lambda x :x , []))
1610
1629
self .assertRaises (StopIteration , next , f (lambda x :x , StopNow ()))
1611
1630
1631
+ @support .cpython_only
1632
+ def test_combinations_result_gc (self ):
1633
+ # bpo-42536: combinations's tuple-reuse speed trick breaks the GC's
1634
+ # assumptions about what can be untracked. Make sure we re-track result
1635
+ # tuples whenever we reuse them.
1636
+ it = combinations ([None , []], 1 )
1637
+ next (it )
1638
+ gc .collect ()
1639
+ # That GC collection probably untracked the recycled internal result
1640
+ # tuple, which has the value (None,). Make sure it's re-tracked when
1641
+ # it's mutated and returned from __next__:
1642
+ self .assertTrue (gc .is_tracked (next (it )))
1643
+
1644
+ @support .cpython_only
1645
+ def test_combinations_with_replacement_result_gc (self ):
1646
+ # Ditto for combinations_with_replacement.
1647
+ it = combinations_with_replacement ([None , []], 1 )
1648
+ next (it )
1649
+ gc .collect ()
1650
+ self .assertTrue (gc .is_tracked (next (it )))
1651
+
1652
+ @support .cpython_only
1653
+ def test_permutations_result_gc (self ):
1654
+ # Ditto for permutations.
1655
+ it = permutations ([None , []], 1 )
1656
+ next (it )
1657
+ gc .collect ()
1658
+ self .assertTrue (gc .is_tracked (next (it )))
1659
+
1660
+ @support .cpython_only
1661
+ def test_product_result_gc (self ):
1662
+ # Ditto for product.
1663
+ it = product ([None , []])
1664
+ next (it )
1665
+ gc .collect ()
1666
+ self .assertTrue (gc .is_tracked (next (it )))
1667
+
1668
+ @support .cpython_only
1669
+ def test_zip_longest_result_gc (self ):
1670
+ # Ditto for zip_longest.
1671
+ it = zip_longest ([[]])
1672
+ gc .collect ()
1673
+ self .assertTrue (gc .is_tracked (next (it )))
1674
+
1675
+
1612
1676
class TestExamples (unittest .TestCase ):
1613
1677
1614
1678
def test_accumulate (self ):
@@ -1848,6 +1912,10 @@ def test_islice(self):
1848
1912
a = []
1849
1913
self .makecycle (islice ([a ]* 2 , None ), a )
1850
1914
1915
+ def test_pairwise (self ):
1916
+ a = []
1917
+ self .makecycle (pairwise ([a ]* 5 ), a )
1918
+
1851
1919
def test_permutations (self ):
1852
1920
a = []
1853
1921
self .makecycle (permutations ([1 ,2 ,a ,3 ], 3 ), a )
@@ -1946,6 +2014,7 @@ def L(seqn):
1946
2014
1947
2015
1948
2016
class TestVariousIteratorArgs (unittest .TestCase ):
2017
+
1949
2018
def test_accumulate (self ):
1950
2019
s = [1 ,2 ,3 ,4 ,5 ]
1951
2020
r = [1 ,3 ,6 ,10 ,15 ]
@@ -2055,6 +2124,17 @@ def test_islice(self):
2055
2124
self .assertRaises (TypeError , islice , N (s ), 10 )
2056
2125
self .assertRaises (ZeroDivisionError , list , islice (E (s ), 10 ))
2057
2126
2127
+ def test_pairwise (self ):
2128
+ for s in ("123" , "" , range (1000 ), ('do' , 1.2 ), range (2000 ,2200 ,5 )):
2129
+ for g in (G , I , Ig , S , L , R ):
2130
+ seq = list (g (s ))
2131
+ expected = list (zip (seq , seq [1 :]))
2132
+ actual = list (pairwise (g (s )))
2133
+ self .assertEqual (actual , expected )
2134
+ self .assertRaises (TypeError , pairwise , X (s ))
2135
+ self .assertRaises (TypeError , pairwise , N (s ))
2136
+ self .assertRaises (ZeroDivisionError , list , pairwise (E (s )))
2137
+
2058
2138
def test_starmap (self ):
2059
2139
for s in (range (10 ), range (0 ), range (100 ), (7 ,11 ), range (20 ,50 ,5 )):
2060
2140
for g in (G , I , Ig , S , L , R ):
@@ -2356,7 +2436,7 @@ def test_permutations_sizeof(self):
2356
2436
... "Count how many times the predicate is true"
2357
2437
... return sum(map(pred, iterable))
2358
2438
2359
- >>> def padnone (iterable):
2439
+ >>> def pad_none (iterable):
2360
2440
... "Returns the sequence elements and then returns None indefinitely"
2361
2441
... return chain(iterable, repeat(None))
2362
2442
@@ -2378,15 +2458,6 @@ def test_permutations_sizeof(self):
2378
2458
... else:
2379
2459
... return starmap(func, repeat(args, times))
2380
2460
2381
- >>> def pairwise(iterable):
2382
- ... "s -> (s0,s1), (s1,s2), (s2, s3), ..."
2383
- ... a, b = tee(iterable)
2384
- ... try:
2385
- ... next(b)
2386
- ... except StopIteration:
2387
- ... pass
2388
- ... return zip(a, b)
2389
-
2390
2461
>>> def grouper(n, iterable, fillvalue=None):
2391
2462
... "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
2392
2463
... args = [iter(iterable)] * n
@@ -2517,16 +2588,7 @@ def test_permutations_sizeof(self):
2517
2588
>>> take(5, map(int, repeatfunc(random.random)))
2518
2589
[0, 0, 0, 0, 0]
2519
2590
2520
- >>> list(pairwise('abcd'))
2521
- [('a', 'b'), ('b', 'c'), ('c', 'd')]
2522
-
2523
- >>> list(pairwise([]))
2524
- []
2525
-
2526
- >>> list(pairwise('a'))
2527
- []
2528
-
2529
- >>> list(islice(padnone('abc'), 0, 6))
2591
+ >>> list(islice(pad_none('abc'), 0, 6))
2530
2592
['a', 'b', 'c', None, None, None]
2531
2593
2532
2594
>>> list(ncycles('abc', 3))
0 commit comments