blob: 4197989888ff314adfc981915b5fa8aa396b48cb [file] [log] [blame]
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001import unittest
2from test import test_support
3from itertools import *
Raymond Hettingera9f60922004-10-17 16:40:14 +00004from weakref import proxy
Raymond Hettinger2012f172003-02-07 05:32:58 +00005import sys
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +00006import operator
Raymond Hettinger6a5b0272003-10-24 08:45:23 +00007import random
Kristján Valur Jónsson170eee92007-05-03 20:09:56 +00008maxsize = test_support.MAX_Py_ssize_t
9minsize = -maxsize-1
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +000010
11def onearg(x):
12 'Test function of one argument'
Raymond Hettingerf0fa1c02003-05-29 07:18:57 +000013 return 2*x
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +000014
15def errfunc(*args):
16 'Test function that raises an error'
17 raise ValueError
18
19def gen3():
20 'Non-restartable source sequence'
21 for i in (0, 1, 2):
22 yield i
23
24def isEven(x):
25 'Test predicate'
26 return x%2==0
27
Raymond Hettingerf0fa1c02003-05-29 07:18:57 +000028def isOdd(x):
29 'Test predicate'
30 return x%2==1
31
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +000032class StopNow:
33 'Class emulating an empty iterable.'
34 def __iter__(self):
35 return self
36 def next(self):
37 raise StopIteration
Raymond Hettinger96ef8112003-02-01 00:10:11 +000038
Raymond Hettinger02420702003-06-29 20:36:23 +000039def take(n, seq):
40 'Convenience function for partially consuming a long of infinite iterable'
41 return list(islice(seq, n))
Raymond Hettingerf0fa1c02003-05-29 07:18:57 +000042
Raymond Hettingerd553d852008-03-04 04:17:08 +000043def prod(iterable):
44 return reduce(operator.mul, iterable, 1)
45
Raymond Hettinger93e804d2008-02-26 23:40:50 +000046def fact(n):
47 'Factorial'
Raymond Hettingerd553d852008-03-04 04:17:08 +000048 return prod(range(1, n+1))
49
50def permutations(iterable, r=None):
51 # XXX use this until real permutations code is added
52 pool = tuple(iterable)
53 n = len(pool)
54 r = n if r is None else r
55 for indices in product(range(n), repeat=r):
56 if len(set(indices)) == r:
57 yield tuple(pool[i] for i in indices)
Raymond Hettinger93e804d2008-02-26 23:40:50 +000058
Raymond Hettinger96ef8112003-02-01 00:10:11 +000059class TestBasicOps(unittest.TestCase):
Raymond Hettinger61fe64d2003-02-23 04:40:07 +000060 def test_chain(self):
61 self.assertEqual(list(chain('abc', 'def')), list('abcdef'))
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +000062 self.assertEqual(list(chain('abc')), list('abc'))
63 self.assertEqual(list(chain('')), [])
Raymond Hettinger02420702003-06-29 20:36:23 +000064 self.assertEqual(take(4, chain('abc', 'def')), list('abcd'))
Raymond Hettinger05bf6332008-02-28 22:30:42 +000065 self.assertRaises(TypeError, list,chain(2, 3))
Raymond Hettinger61fe64d2003-02-23 04:40:07 +000066
Raymond Hettingerb4cbc982008-02-28 22:46:41 +000067 def test_chain_from_iterable(self):
68 self.assertEqual(list(chain.from_iterable(['abc', 'def'])), list('abcdef'))
69 self.assertEqual(list(chain.from_iterable(['abc'])), list('abc'))
70 self.assertEqual(list(chain.from_iterable([''])), [])
71 self.assertEqual(take(4, chain.from_iterable(['abc', 'def'])), list('abcd'))
72 self.assertRaises(TypeError, list, chain.from_iterable([2, 3]))
73
Raymond Hettinger93e804d2008-02-26 23:40:50 +000074 def test_combinations(self):
75 self.assertRaises(TypeError, combinations, 'abc') # missing r argument
76 self.assertRaises(TypeError, combinations, 'abc', 2, 1) # too many arguments
Raymond Hettingerd553d852008-03-04 04:17:08 +000077 self.assertRaises(TypeError, combinations, None) # pool is not iterable
Raymond Hettinger93e804d2008-02-26 23:40:50 +000078 self.assertRaises(ValueError, combinations, 'abc', -2) # r is negative
79 self.assertRaises(ValueError, combinations, 'abc', 32) # r is too big
80 self.assertEqual(list(combinations(range(4), 3)),
81 [(0,1,2), (0,1,3), (0,2,3), (1,2,3)])
Raymond Hettingerd553d852008-03-04 04:17:08 +000082
83 def combinations1(iterable, r):
84 'Pure python version shown in the docs'
85 pool = tuple(iterable)
86 n = len(pool)
87 indices = range(r)
88 yield tuple(pool[i] for i in indices)
89 while 1:
90 for i in reversed(range(r)):
91 if indices[i] != i + n - r:
92 break
93 else:
94 return
95 indices[i] += 1
96 for j in range(i+1, r):
97 indices[j] = indices[j-1] + 1
98 yield tuple(pool[i] for i in indices)
99
100 def combinations2(iterable, r):
101 'Pure python version shown in the docs'
102 pool = tuple(iterable)
103 n = len(pool)
104 for indices in permutations(range(n), r):
105 if sorted(indices) == list(indices):
106 yield tuple(pool[i] for i in indices)
107
108 for n in range(7):
Raymond Hettinger93e804d2008-02-26 23:40:50 +0000109 values = [5*x-12 for x in range(n)]
110 for r in range(n+1):
111 result = list(combinations(values, r))
112 self.assertEqual(len(result), fact(n) / fact(r) / fact(n-r)) # right number of combs
113 self.assertEqual(len(result), len(set(result))) # no repeats
114 self.assertEqual(result, sorted(result)) # lexicographic order
115 for c in result:
116 self.assertEqual(len(c), r) # r-length combinations
117 self.assertEqual(len(set(c)), r) # no duplicate elements
118 self.assertEqual(list(c), sorted(c)) # keep original ordering
119 self.assert_(all(e in values for e in c)) # elements taken from input iterable
Raymond Hettingerd553d852008-03-04 04:17:08 +0000120 self.assertEqual(result, list(combinations1(values, r))) # matches first pure python version
121 self.assertEqual(result, list(combinations2(values, r))) # matches first pure python version
122
123 # Test implementation detail: tuple re-use
124 self.assertEqual(len(set(map(id, combinations('abcde', 3)))), 1)
125 self.assertNotEqual(len(set(map(id, list(combinations('abcde', 3))))), 1)
126
127 def test_permutations(self):
128 self.assertRaises(TypeError, permutations) # too few arguments
129 self.assertRaises(TypeError, permutations, 'abc', 2, 1) # too many arguments
130## self.assertRaises(TypeError, permutations, None) # pool is not iterable
131## self.assertRaises(ValueError, permutations, 'abc', -2) # r is negative
132## self.assertRaises(ValueError, permutations, 'abc', 32) # r is too big
133 self.assertEqual(list(permutations(range(3), 2)),
134 [(0,1), (0,2), (1,0), (1,2), (2,0), (2,1)])
135
136 def permutations1(iterable, r=None):
137 'Pure python version shown in the docs'
138 pool = tuple(iterable)
139 n = len(pool)
140 r = n if r is None else r
141 indices = range(n)
142 cycles = range(n-r+1, n+1)[::-1]
143 yield tuple(pool[i] for i in indices[:r])
144 while n:
145 for i in reversed(range(r)):
146 cycles[i] -= 1
147 if cycles[i] == 0:
148 indices[i:] = indices[i+1:] + indices[i:i+1]
149 cycles[i] = n - i
150 else:
151 j = cycles[i]
152 indices[i], indices[-j] = indices[-j], indices[i]
153 yield tuple(pool[i] for i in indices[:r])
154 break
155 else:
156 return
157
158 def permutations2(iterable, r=None):
159 'Pure python version shown in the docs'
160 pool = tuple(iterable)
161 n = len(pool)
162 r = n if r is None else r
163 for indices in product(range(n), repeat=r):
164 if len(set(indices)) == r:
165 yield tuple(pool[i] for i in indices)
166
167 for n in range(7):
168 values = [5*x-12 for x in range(n)]
169 for r in range(n+1):
170 result = list(permutations(values, r))
171 self.assertEqual(len(result), fact(n) / fact(n-r)) # right number of perms
172 self.assertEqual(len(result), len(set(result))) # no repeats
173 self.assertEqual(result, sorted(result)) # lexicographic order
174 for p in result:
175 self.assertEqual(len(p), r) # r-length permutations
176 self.assertEqual(len(set(p)), r) # no duplicate elements
177 self.assert_(all(e in values for e in p)) # elements taken from input iterable
178 self.assertEqual(result, list(permutations1(values, r))) # matches first pure python version
179 self.assertEqual(result, list(permutations2(values, r))) # matches first pure python version
180 if r == n:
181 self.assertEqual(result, list(permutations(values, None))) # test r as None
182 self.assertEqual(result, list(permutations(values))) # test default r
183
184 # Test implementation detail: tuple re-use
185## self.assertEqual(len(set(map(id, permutations('abcde', 3)))), 1)
186 self.assertNotEqual(len(set(map(id, list(permutations('abcde', 3))))), 1)
Raymond Hettinger93e804d2008-02-26 23:40:50 +0000187
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000188 def test_count(self):
189 self.assertEqual(zip('abc',count()), [('a', 0), ('b', 1), ('c', 2)])
190 self.assertEqual(zip('abc',count(3)), [('a', 3), ('b', 4), ('c', 5)])
Raymond Hettinger02420702003-06-29 20:36:23 +0000191 self.assertEqual(take(2, zip('abc',count(3))), [('a', 3), ('b', 4)])
Raymond Hettinger50e90e22007-10-04 00:20:27 +0000192 self.assertEqual(take(2, zip('abc',count(-1))), [('a', -1), ('b', 0)])
193 self.assertEqual(take(2, zip('abc',count(-3))), [('a', -3), ('b', -2)])
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000194 self.assertRaises(TypeError, count, 2, 3)
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +0000195 self.assertRaises(TypeError, count, 'a')
Raymond Hettinger50e90e22007-10-04 00:20:27 +0000196 self.assertEqual(list(islice(count(maxsize-5), 10)), range(maxsize-5, maxsize+5))
197 self.assertEqual(list(islice(count(-maxsize-5), 10)), range(-maxsize-5, -maxsize+5))
Raymond Hettinger4cda01e2004-09-28 04:45:28 +0000198 c = count(3)
199 self.assertEqual(repr(c), 'count(3)')
200 c.next()
201 self.assertEqual(repr(c), 'count(4)')
Jack Diederich36234e82006-09-21 17:50:26 +0000202 c = count(-9)
203 self.assertEqual(repr(c), 'count(-9)')
204 c.next()
205 self.assertEqual(c.next(), -8)
Raymond Hettinger50e90e22007-10-04 00:20:27 +0000206 for i in (-sys.maxint-5, -sys.maxint+5 ,-10, -1, 0, 10, sys.maxint-5, sys.maxint+5):
Raymond Hettinger3a0de082007-10-12 17:53:11 +0000207 # Test repr (ignoring the L in longs)
208 r1 = repr(count(i)).replace('L', '')
209 r2 = 'count(%r)'.__mod__(i).replace('L', '')
210 self.assertEqual(r1, r2)
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000211
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000212 def test_cycle(self):
Raymond Hettinger02420702003-06-29 20:36:23 +0000213 self.assertEqual(take(10, cycle('abc')), list('abcabcabca'))
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000214 self.assertEqual(list(cycle('')), [])
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +0000215 self.assertRaises(TypeError, cycle)
216 self.assertRaises(TypeError, cycle, 5)
217 self.assertEqual(list(islice(cycle(gen3()),10)), [0,1,2,0,1,2,0,1,2,0])
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000218
Raymond Hettingerd25c1c62003-12-06 16:23:06 +0000219 def test_groupby(self):
220 # Check whether it accepts arguments correctly
221 self.assertEqual([], list(groupby([])))
222 self.assertEqual([], list(groupby([], key=id)))
223 self.assertRaises(TypeError, list, groupby('abc', []))
224 self.assertRaises(TypeError, groupby, None)
Raymond Hettinger4cda01e2004-09-28 04:45:28 +0000225 self.assertRaises(TypeError, groupby, 'abc', lambda x:x, 10)
Raymond Hettingerd25c1c62003-12-06 16:23:06 +0000226
227 # Check normal input
228 s = [(0, 10, 20), (0, 11,21), (0,12,21), (1,13,21), (1,14,22),
229 (2,15,22), (3,16,23), (3,17,23)]
230 dup = []
231 for k, g in groupby(s, lambda r:r[0]):
232 for elem in g:
233 self.assertEqual(k, elem[0])
234 dup.append(elem)
235 self.assertEqual(s, dup)
236
237 # Check nested case
238 dup = []
239 for k, g in groupby(s, lambda r:r[0]):
240 for ik, ig in groupby(g, lambda r:r[2]):
241 for elem in ig:
242 self.assertEqual(k, elem[0])
243 self.assertEqual(ik, elem[2])
244 dup.append(elem)
245 self.assertEqual(s, dup)
246
247 # Check case where inner iterator is not used
248 keys = [k for k, g in groupby(s, lambda r:r[0])]
249 expectedkeys = set([r[0] for r in s])
250 self.assertEqual(set(keys), expectedkeys)
251 self.assertEqual(len(keys), len(expectedkeys))
252
253 # Exercise pipes and filters style
254 s = 'abracadabra'
255 # sort s | uniq
Raymond Hettinger64958a12003-12-17 20:43:33 +0000256 r = [k for k, g in groupby(sorted(s))]
Raymond Hettingerd25c1c62003-12-06 16:23:06 +0000257 self.assertEqual(r, ['a', 'b', 'c', 'd', 'r'])
258 # sort s | uniq -d
Raymond Hettinger64958a12003-12-17 20:43:33 +0000259 r = [k for k, g in groupby(sorted(s)) if list(islice(g,1,2))]
Raymond Hettingerd25c1c62003-12-06 16:23:06 +0000260 self.assertEqual(r, ['a', 'b', 'r'])
261 # sort s | uniq -c
Raymond Hettinger64958a12003-12-17 20:43:33 +0000262 r = [(len(list(g)), k) for k, g in groupby(sorted(s))]
Raymond Hettingerd25c1c62003-12-06 16:23:06 +0000263 self.assertEqual(r, [(5, 'a'), (2, 'b'), (1, 'c'), (1, 'd'), (2, 'r')])
264 # sort s | uniq -c | sort -rn | head -3
Raymond Hettinger64958a12003-12-17 20:43:33 +0000265 r = sorted([(len(list(g)) , k) for k, g in groupby(sorted(s))], reverse=True)[:3]
Raymond Hettingerd25c1c62003-12-06 16:23:06 +0000266 self.assertEqual(r, [(5, 'a'), (2, 'r'), (2, 'b')])
267
268 # iter.next failure
269 class ExpectedError(Exception):
270 pass
271 def delayed_raise(n=0):
272 for i in range(n):
273 yield 'yo'
274 raise ExpectedError
275 def gulp(iterable, keyp=None, func=list):
276 return [func(g) for k, g in groupby(iterable, keyp)]
277
278 # iter.next failure on outer object
279 self.assertRaises(ExpectedError, gulp, delayed_raise(0))
280 # iter.next failure on inner object
281 self.assertRaises(ExpectedError, gulp, delayed_raise(1))
282
283 # __cmp__ failure
284 class DummyCmp:
285 def __cmp__(self, dst):
286 raise ExpectedError
287 s = [DummyCmp(), DummyCmp(), None]
288
289 # __cmp__ failure on outer object
290 self.assertRaises(ExpectedError, gulp, s, func=id)
291 # __cmp__ failure on inner object
292 self.assertRaises(ExpectedError, gulp, s)
293
294 # keyfunc failure
295 def keyfunc(obj):
296 if keyfunc.skip > 0:
297 keyfunc.skip -= 1
298 return obj
299 else:
300 raise ExpectedError
301
302 # keyfunc failure on outer object
303 keyfunc.skip = 0
304 self.assertRaises(ExpectedError, gulp, [None], keyfunc)
305 keyfunc.skip = 1
306 self.assertRaises(ExpectedError, gulp, [None, None], keyfunc)
307
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000308 def test_ifilter(self):
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000309 self.assertEqual(list(ifilter(isEven, range(6))), [0,2,4])
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000310 self.assertEqual(list(ifilter(None, [0,1,0,2,0])), [1,2])
Raymond Hettinger9d638372008-02-25 22:42:32 +0000311 self.assertEqual(list(ifilter(bool, [0,1,0,2,0])), [1,2])
Raymond Hettinger02420702003-06-29 20:36:23 +0000312 self.assertEqual(take(4, ifilter(isEven, count())), [0,2,4,6])
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000313 self.assertRaises(TypeError, ifilter)
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +0000314 self.assertRaises(TypeError, ifilter, lambda x:x)
315 self.assertRaises(TypeError, ifilter, lambda x:x, range(6), 7)
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000316 self.assertRaises(TypeError, ifilter, isEven, 3)
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +0000317 self.assertRaises(TypeError, ifilter(range(6), range(6)).next)
Raymond Hettinger60eca932003-02-09 06:40:58 +0000318
319 def test_ifilterfalse(self):
Raymond Hettinger60eca932003-02-09 06:40:58 +0000320 self.assertEqual(list(ifilterfalse(isEven, range(6))), [1,3,5])
321 self.assertEqual(list(ifilterfalse(None, [0,1,0,2,0])), [0,0,0])
Raymond Hettinger9d638372008-02-25 22:42:32 +0000322 self.assertEqual(list(ifilterfalse(bool, [0,1,0,2,0])), [0,0,0])
Raymond Hettinger02420702003-06-29 20:36:23 +0000323 self.assertEqual(take(4, ifilterfalse(isEven, count())), [1,3,5,7])
Raymond Hettinger60eca932003-02-09 06:40:58 +0000324 self.assertRaises(TypeError, ifilterfalse)
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +0000325 self.assertRaises(TypeError, ifilterfalse, lambda x:x)
326 self.assertRaises(TypeError, ifilterfalse, lambda x:x, range(6), 7)
Raymond Hettinger60eca932003-02-09 06:40:58 +0000327 self.assertRaises(TypeError, ifilterfalse, isEven, 3)
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +0000328 self.assertRaises(TypeError, ifilterfalse(range(6), range(6)).next)
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000329
330 def test_izip(self):
331 ans = [(x,y) for x, y in izip('abc',count())]
332 self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)])
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +0000333 self.assertEqual(list(izip('abc', range(6))), zip('abc', range(6)))
334 self.assertEqual(list(izip('abcdef', range(3))), zip('abcdef', range(3)))
Raymond Hettinger02420702003-06-29 20:36:23 +0000335 self.assertEqual(take(3,izip('abcdef', count())), zip('abcdef', range(3)))
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +0000336 self.assertEqual(list(izip('abcdef')), zip('abcdef'))
Raymond Hettingerb5a42082003-08-08 05:10:41 +0000337 self.assertEqual(list(izip()), zip())
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +0000338 self.assertRaises(TypeError, izip, 3)
339 self.assertRaises(TypeError, izip, range(3), 3)
340 # Check tuple re-use (implementation detail)
341 self.assertEqual([tuple(list(pair)) for pair in izip('abc', 'def')],
342 zip('abc', 'def'))
Raymond Hettingerf0fa1c02003-05-29 07:18:57 +0000343 self.assertEqual([pair for pair in izip('abc', 'def')],
344 zip('abc', 'def'))
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +0000345 ids = map(id, izip('abc', 'def'))
346 self.assertEqual(min(ids), max(ids))
Raymond Hettingerf0fa1c02003-05-29 07:18:57 +0000347 ids = map(id, list(izip('abc', 'def')))
348 self.assertEqual(len(dict.fromkeys(ids)), len(ids))
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000349
Raymond Hettingerd36862c2007-02-21 05:20:38 +0000350 def test_iziplongest(self):
351 for args in [
352 ['abc', range(6)],
353 [range(6), 'abc'],
354 [range(1000), range(2000,2100), range(3000,3050)],
355 [range(1000), range(0), range(3000,3050), range(1200), range(1500)],
356 [range(1000), range(0), range(3000,3050), range(1200), range(1500), range(0)],
357 ]:
358 target = map(None, *args)
359 self.assertEqual(list(izip_longest(*args)), target)
360 self.assertEqual(list(izip_longest(*args, **{})), target)
361 target = [tuple((e is None and 'X' or e) for e in t) for t in target] # Replace None fills with 'X'
362 self.assertEqual(list(izip_longest(*args, **dict(fillvalue='X'))), target)
Tim Petersea5962f2007-03-12 18:07:52 +0000363
Raymond Hettingerd36862c2007-02-21 05:20:38 +0000364 self.assertEqual(take(3,izip_longest('abcdef', count())), zip('abcdef', range(3))) # take 3 from infinite input
365
366 self.assertEqual(list(izip_longest()), zip())
367 self.assertEqual(list(izip_longest([])), zip([]))
368 self.assertEqual(list(izip_longest('abcdef')), zip('abcdef'))
Tim Petersea5962f2007-03-12 18:07:52 +0000369
Raymond Hettingerd36862c2007-02-21 05:20:38 +0000370 self.assertEqual(list(izip_longest('abc', 'defg', **{})), map(None, 'abc', 'defg')) # empty keyword dict
371 self.assertRaises(TypeError, izip_longest, 3)
372 self.assertRaises(TypeError, izip_longest, range(3), 3)
373
374 for stmt in [
375 "izip_longest('abc', fv=1)",
Tim Petersea5962f2007-03-12 18:07:52 +0000376 "izip_longest('abc', fillvalue=1, bogus_keyword=None)",
Raymond Hettingerd36862c2007-02-21 05:20:38 +0000377 ]:
378 try:
379 eval(stmt, globals(), locals())
380 except TypeError:
381 pass
382 else:
383 self.fail('Did not raise Type in: ' + stmt)
Tim Petersea5962f2007-03-12 18:07:52 +0000384
Raymond Hettingerd36862c2007-02-21 05:20:38 +0000385 # Check tuple re-use (implementation detail)
386 self.assertEqual([tuple(list(pair)) for pair in izip_longest('abc', 'def')],
387 zip('abc', 'def'))
388 self.assertEqual([pair for pair in izip_longest('abc', 'def')],
389 zip('abc', 'def'))
390 ids = map(id, izip_longest('abc', 'def'))
391 self.assertEqual(min(ids), max(ids))
392 ids = map(id, list(izip_longest('abc', 'def')))
393 self.assertEqual(len(dict.fromkeys(ids)), len(ids))
394
Raymond Hettinger50986cc2008-02-22 03:16:42 +0000395 def test_product(self):
396 for args, result in [
Raymond Hettingerd553d852008-03-04 04:17:08 +0000397 ([], [()]), # zero iterables
Raymond Hettinger50986cc2008-02-22 03:16:42 +0000398 (['ab'], [('a',), ('b',)]), # one iterable
399 ([range(2), range(3)], [(0,0), (0,1), (0,2), (1,0), (1,1), (1,2)]), # two iterables
400 ([range(0), range(2), range(3)], []), # first iterable with zero length
401 ([range(2), range(0), range(3)], []), # middle iterable with zero length
402 ([range(2), range(3), range(0)], []), # last iterable with zero length
403 ]:
404 self.assertEqual(list(product(*args)), result)
Raymond Hettinger08ff6822008-02-29 02:21:48 +0000405 for r in range(4):
406 self.assertEqual(list(product(*(args*r))),
407 list(product(*args, **dict(repeat=r))))
Raymond Hettinger50986cc2008-02-22 03:16:42 +0000408 self.assertEqual(len(list(product(*[range(7)]*6))), 7**6)
409 self.assertRaises(TypeError, product, range(6), None)
410 argtypes = ['', 'abc', '', xrange(0), xrange(4), dict(a=1, b=2, c=3),
411 set('abcdefg'), range(11), tuple(range(13))]
412 for i in range(100):
413 args = [random.choice(argtypes) for j in range(random.randrange(5))]
Raymond Hettingerd553d852008-03-04 04:17:08 +0000414 expected_len = prod(map(len, args))
415 self.assertEqual(len(list(product(*args))), expected_len)
Raymond Hettinger50986cc2008-02-22 03:16:42 +0000416 args = map(iter, args)
Raymond Hettingerd553d852008-03-04 04:17:08 +0000417 self.assertEqual(len(list(product(*args))), expected_len)
Raymond Hettinger50986cc2008-02-22 03:16:42 +0000418
Raymond Hettinger73d79632008-02-23 02:20:41 +0000419 # Test implementation detail: tuple re-use
420 self.assertEqual(len(set(map(id, product('abc', 'def')))), 1)
421 self.assertNotEqual(len(set(map(id, list(product('abc', 'def'))))), 1)
Raymond Hettinger50986cc2008-02-22 03:16:42 +0000422
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000423 def test_repeat(self):
424 self.assertEqual(zip(xrange(3),repeat('a')),
425 [(0, 'a'), (1, 'a'), (2, 'a')])
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000426 self.assertEqual(list(repeat('a', 3)), ['a', 'a', 'a'])
Raymond Hettinger02420702003-06-29 20:36:23 +0000427 self.assertEqual(take(3, repeat('a')), ['a', 'a', 'a'])
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +0000428 self.assertEqual(list(repeat('a', 0)), [])
429 self.assertEqual(list(repeat('a', -3)), [])
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000430 self.assertRaises(TypeError, repeat)
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +0000431 self.assertRaises(TypeError, repeat, None, 3, 4)
432 self.assertRaises(TypeError, repeat, None, 'a')
Raymond Hettinger4cda01e2004-09-28 04:45:28 +0000433 r = repeat(1+0j)
434 self.assertEqual(repr(r), 'repeat((1+0j))')
435 r = repeat(1+0j, 5)
436 self.assertEqual(repr(r), 'repeat((1+0j), 5)')
437 list(r)
438 self.assertEqual(repr(r), 'repeat((1+0j), 0)')
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000439
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000440 def test_imap(self):
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000441 self.assertEqual(list(imap(operator.pow, range(3), range(1,7))),
442 [0**1, 1**2, 2**3])
443 self.assertEqual(list(imap(None, 'abc', range(5))),
444 [('a',0),('b',1),('c',2)])
Raymond Hettinger02420702003-06-29 20:36:23 +0000445 self.assertEqual(list(imap(None, 'abc', count())),
446 [('a',0),('b',1),('c',2)])
447 self.assertEqual(take(2,imap(None, 'abc', count())),
448 [('a',0),('b',1)])
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +0000449 self.assertEqual(list(imap(operator.pow, [])), [])
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000450 self.assertRaises(TypeError, imap)
451 self.assertRaises(TypeError, imap, operator.neg)
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +0000452 self.assertRaises(TypeError, imap(10, range(5)).next)
453 self.assertRaises(ValueError, imap(errfunc, [4], [5]).next)
454 self.assertRaises(TypeError, imap(onearg, [4], [5]).next)
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000455
456 def test_starmap(self):
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000457 self.assertEqual(list(starmap(operator.pow, zip(range(3), range(1,7)))),
458 [0**1, 1**2, 2**3])
Raymond Hettinger02420702003-06-29 20:36:23 +0000459 self.assertEqual(take(3, starmap(operator.pow, izip(count(), count(1)))),
460 [0**1, 1**2, 2**3])
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +0000461 self.assertEqual(list(starmap(operator.pow, [])), [])
Raymond Hettinger47317092008-01-17 03:02:14 +0000462 self.assertEqual(list(starmap(operator.pow, [iter([4,5])])), [4**5])
463 self.assertRaises(TypeError, list, starmap(operator.pow, [None]))
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +0000464 self.assertRaises(TypeError, starmap)
465 self.assertRaises(TypeError, starmap, operator.pow, [(4,5)], 'extra')
466 self.assertRaises(TypeError, starmap(10, [(4,5)]).next)
467 self.assertRaises(ValueError, starmap(errfunc, [(4,5)]).next)
468 self.assertRaises(TypeError, starmap(onearg, [(4,5)]).next)
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000469
470 def test_islice(self):
471 for args in [ # islice(args) should agree with range(args)
472 (10, 20, 3),
473 (10, 3, 20),
474 (10, 20),
475 (10, 3),
476 (20,)
477 ]:
478 self.assertEqual(list(islice(xrange(100), *args)), range(*args))
479
480 for args, tgtargs in [ # Stop when seqn is exhausted
481 ((10, 110, 3), ((10, 100, 3))),
482 ((10, 110), ((10, 100))),
483 ((110,), (100,))
484 ]:
485 self.assertEqual(list(islice(xrange(100), *args)), range(*tgtargs))
486
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000487 # Test stop=None
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000488 self.assertEqual(list(islice(xrange(10), None)), range(10))
Raymond Hettingerb2594052004-12-05 09:25:51 +0000489 self.assertEqual(list(islice(xrange(10), None, None)), range(10))
490 self.assertEqual(list(islice(xrange(10), None, None, None)), range(10))
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000491 self.assertEqual(list(islice(xrange(10), 2, None)), range(2, 10))
492 self.assertEqual(list(islice(xrange(10), 1, None, 2)), range(1, 10, 2))
493
Raymond Hettingerfdf3bd62005-03-27 20:11:44 +0000494 # Test number of items consumed SF #1171417
495 it = iter(range(10))
496 self.assertEqual(list(islice(it, 3)), range(3))
497 self.assertEqual(list(it), range(3, 10))
498
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000499 # Test invalid arguments
Raymond Hettinger341deb72003-05-02 19:44:20 +0000500 self.assertRaises(TypeError, islice, xrange(10))
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000501 self.assertRaises(TypeError, islice, xrange(10), 1, 2, 3, 4)
502 self.assertRaises(ValueError, islice, xrange(10), -5, 10, 1)
503 self.assertRaises(ValueError, islice, xrange(10), 1, -5, -1)
504 self.assertRaises(ValueError, islice, xrange(10), 1, 10, -1)
505 self.assertRaises(ValueError, islice, xrange(10), 1, 10, 0)
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000506 self.assertRaises(ValueError, islice, xrange(10), 'a')
507 self.assertRaises(ValueError, islice, xrange(10), 'a', 1)
508 self.assertRaises(ValueError, islice, xrange(10), 1, 'a')
509 self.assertRaises(ValueError, islice, xrange(10), 'a', 1, 1)
510 self.assertRaises(ValueError, islice, xrange(10), 1, 'a', 1)
Kristján Valur Jónsson170eee92007-05-03 20:09:56 +0000511 self.assertEqual(len(list(islice(count(), 1, 10, maxsize))), 1)
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000512
513 def test_takewhile(self):
514 data = [1, 3, 5, 20, 2, 4, 6, 8]
515 underten = lambda x: x<10
516 self.assertEqual(list(takewhile(underten, data)), [1, 3, 5])
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +0000517 self.assertEqual(list(takewhile(underten, [])), [])
518 self.assertRaises(TypeError, takewhile)
519 self.assertRaises(TypeError, takewhile, operator.pow)
520 self.assertRaises(TypeError, takewhile, operator.pow, [(4,5)], 'extra')
521 self.assertRaises(TypeError, takewhile(10, [(4,5)]).next)
522 self.assertRaises(ValueError, takewhile(errfunc, [(4,5)]).next)
Raymond Hettinger4cda01e2004-09-28 04:45:28 +0000523 t = takewhile(bool, [1, 1, 1, 0, 0, 0])
524 self.assertEqual(list(t), [1, 1, 1])
525 self.assertRaises(StopIteration, t.next)
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000526
527 def test_dropwhile(self):
528 data = [1, 3, 5, 20, 2, 4, 6, 8]
529 underten = lambda x: x<10
530 self.assertEqual(list(dropwhile(underten, data)), [20, 2, 4, 6, 8])
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +0000531 self.assertEqual(list(dropwhile(underten, [])), [])
532 self.assertRaises(TypeError, dropwhile)
533 self.assertRaises(TypeError, dropwhile, operator.pow)
534 self.assertRaises(TypeError, dropwhile, operator.pow, [(4,5)], 'extra')
535 self.assertRaises(TypeError, dropwhile(10, [(4,5)]).next)
536 self.assertRaises(ValueError, dropwhile(errfunc, [(4,5)]).next)
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000537
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000538 def test_tee(self):
Raymond Hettingerad983e72003-11-12 14:32:26 +0000539 n = 200
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000540 def irange(n):
541 for i in xrange(n):
542 yield i
543
544 a, b = tee([]) # test empty iterator
545 self.assertEqual(list(a), [])
546 self.assertEqual(list(b), [])
547
548 a, b = tee(irange(n)) # test 100% interleaved
549 self.assertEqual(zip(a,b), zip(range(n),range(n)))
550
551 a, b = tee(irange(n)) # test 0% interleaved
552 self.assertEqual(list(a), range(n))
553 self.assertEqual(list(b), range(n))
554
555 a, b = tee(irange(n)) # test dealloc of leading iterator
Raymond Hettingerad983e72003-11-12 14:32:26 +0000556 for i in xrange(100):
557 self.assertEqual(a.next(), i)
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000558 del a
559 self.assertEqual(list(b), range(n))
560
561 a, b = tee(irange(n)) # test dealloc of trailing iterator
Raymond Hettingerad983e72003-11-12 14:32:26 +0000562 for i in xrange(100):
563 self.assertEqual(a.next(), i)
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000564 del b
Raymond Hettingerad983e72003-11-12 14:32:26 +0000565 self.assertEqual(list(a), range(100, n))
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000566
567 for j in xrange(5): # test randomly interleaved
568 order = [0]*n + [1]*n
569 random.shuffle(order)
570 lists = ([], [])
571 its = tee(irange(n))
572 for i in order:
573 value = its[i].next()
574 lists[i].append(value)
575 self.assertEqual(lists[0], range(n))
576 self.assertEqual(lists[1], range(n))
577
Raymond Hettingerad983e72003-11-12 14:32:26 +0000578 # test argument format checking
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000579 self.assertRaises(TypeError, tee)
580 self.assertRaises(TypeError, tee, 3)
581 self.assertRaises(TypeError, tee, [1,2], 'x')
Raymond Hettingerad983e72003-11-12 14:32:26 +0000582 self.assertRaises(TypeError, tee, [1,2], 3, 'x')
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000583
Raymond Hettingerad983e72003-11-12 14:32:26 +0000584 # tee object should be instantiable
585 a, b = tee('abc')
586 c = type(a)('def')
587 self.assertEqual(list(c), list('def'))
Raymond Hettingerf0c5aec2003-10-26 14:25:56 +0000588
Raymond Hettingerad983e72003-11-12 14:32:26 +0000589 # test long-lagged and multi-way split
590 a, b, c = tee(xrange(2000), 3)
591 for i in xrange(100):
592 self.assertEqual(a.next(), i)
593 self.assertEqual(list(b), range(2000))
594 self.assertEqual([c.next(), c.next()], range(2))
595 self.assertEqual(list(a), range(100,2000))
596 self.assertEqual(list(c), range(2,2000))
597
Raymond Hettinger4cda01e2004-09-28 04:45:28 +0000598 # test values of n
599 self.assertRaises(TypeError, tee, 'abc', 'invalid')
Neal Norwitz69e88972006-09-02 02:58:13 +0000600 self.assertRaises(ValueError, tee, [], -1)
Raymond Hettinger4cda01e2004-09-28 04:45:28 +0000601 for n in xrange(5):
602 result = tee('abc', n)
603 self.assertEqual(type(result), tuple)
604 self.assertEqual(len(result), n)
605 self.assertEqual(map(list, result), [list('abc')]*n)
606
Raymond Hettingerad983e72003-11-12 14:32:26 +0000607 # tee pass-through to copyable iterator
608 a, b = tee('abc')
609 c, d = tee(a)
610 self.assert_(a is c)
611
Raymond Hettinger4cda01e2004-09-28 04:45:28 +0000612 # test tee_new
613 t1, t2 = tee('abc')
614 tnew = type(t1)
615 self.assertRaises(TypeError, tnew)
616 self.assertRaises(TypeError, tnew, 10)
617 t3 = tnew(t1)
618 self.assert_(list(t1) == list(t2) == list(t3) == list('abc'))
Raymond Hettingerf0c5aec2003-10-26 14:25:56 +0000619
Raymond Hettingera9f60922004-10-17 16:40:14 +0000620 # test that tee objects are weak referencable
621 a, b = tee(xrange(10))
622 p = proxy(a)
623 self.assertEqual(getattr(p, '__class__'), type(b))
624 del a
625 self.assertRaises(ReferenceError, getattr, p, '__class__')
626
Raymond Hettinger8fd3f872003-05-02 22:38:07 +0000627 def test_StopIteration(self):
Raymond Hettingerb5a42082003-08-08 05:10:41 +0000628 self.assertRaises(StopIteration, izip().next)
629
Raymond Hettingerd25c1c62003-12-06 16:23:06 +0000630 for f in (chain, cycle, izip, groupby):
Raymond Hettinger8fd3f872003-05-02 22:38:07 +0000631 self.assertRaises(StopIteration, f([]).next)
632 self.assertRaises(StopIteration, f(StopNow()).next)
633
634 self.assertRaises(StopIteration, islice([], None).next)
635 self.assertRaises(StopIteration, islice(StopNow(), None).next)
636
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000637 p, q = tee([])
638 self.assertRaises(StopIteration, p.next)
639 self.assertRaises(StopIteration, q.next)
640 p, q = tee(StopNow())
641 self.assertRaises(StopIteration, p.next)
642 self.assertRaises(StopIteration, q.next)
643
Raymond Hettinger8fd3f872003-05-02 22:38:07 +0000644 self.assertRaises(StopIteration, repeat(None, 0).next)
645
646 for f in (ifilter, ifilterfalse, imap, takewhile, dropwhile, starmap):
647 self.assertRaises(StopIteration, f(lambda x:x, []).next)
648 self.assertRaises(StopIteration, f(lambda x:x, StopNow()).next)
649
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000650class TestGC(unittest.TestCase):
651
652 def makecycle(self, iterator, container):
653 container.append(iterator)
654 iterator.next()
655 del container, iterator
656
657 def test_chain(self):
658 a = []
659 self.makecycle(chain(a), a)
660
661 def test_cycle(self):
662 a = []
663 self.makecycle(cycle([a]*2), a)
664
Raymond Hettingerff5dc0e2004-09-29 11:40:50 +0000665 def test_dropwhile(self):
666 a = []
667 self.makecycle(dropwhile(bool, [0, a, a]), a)
668
669 def test_groupby(self):
670 a = []
671 self.makecycle(groupby([a]*2, lambda x:x), a)
672
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000673 def test_ifilter(self):
674 a = []
675 self.makecycle(ifilter(lambda x:True, [a]*2), a)
676
677 def test_ifilterfalse(self):
678 a = []
679 self.makecycle(ifilterfalse(lambda x:False, a), a)
680
681 def test_izip(self):
682 a = []
683 self.makecycle(izip([a]*2, [a]*3), a)
684
685 def test_imap(self):
686 a = []
687 self.makecycle(imap(lambda x:x, [a]*2), a)
688
689 def test_islice(self):
690 a = []
691 self.makecycle(islice([a]*2, None), a)
692
Raymond Hettingerff5dc0e2004-09-29 11:40:50 +0000693 def test_repeat(self):
694 a = []
695 self.makecycle(repeat(a), a)
696
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000697 def test_starmap(self):
698 a = []
699 self.makecycle(starmap(lambda *t: t, [(a,a)]*2), a)
700
Raymond Hettingerff5dc0e2004-09-29 11:40:50 +0000701 def test_takewhile(self):
702 a = []
703 self.makecycle(takewhile(bool, [1, 0, a, a]), a)
704
Raymond Hettingerf0fa1c02003-05-29 07:18:57 +0000705def R(seqn):
706 'Regular generator'
707 for i in seqn:
708 yield i
Raymond Hettinger8fd3f872003-05-02 22:38:07 +0000709
Raymond Hettingerf0fa1c02003-05-29 07:18:57 +0000710class G:
711 'Sequence using __getitem__'
712 def __init__(self, seqn):
713 self.seqn = seqn
714 def __getitem__(self, i):
715 return self.seqn[i]
716
717class I:
718 'Sequence using iterator protocol'
719 def __init__(self, seqn):
720 self.seqn = seqn
721 self.i = 0
722 def __iter__(self):
723 return self
724 def next(self):
725 if self.i >= len(self.seqn): raise StopIteration
726 v = self.seqn[self.i]
727 self.i += 1
728 return v
729
730class Ig:
731 'Sequence using iterator protocol defined with a generator'
732 def __init__(self, seqn):
733 self.seqn = seqn
734 self.i = 0
735 def __iter__(self):
736 for val in self.seqn:
737 yield val
738
739class X:
740 'Missing __getitem__ and __iter__'
741 def __init__(self, seqn):
742 self.seqn = seqn
743 self.i = 0
744 def next(self):
745 if self.i >= len(self.seqn): raise StopIteration
746 v = self.seqn[self.i]
747 self.i += 1
748 return v
749
750class N:
751 'Iterator missing next()'
752 def __init__(self, seqn):
753 self.seqn = seqn
754 self.i = 0
755 def __iter__(self):
756 return self
757
758class E:
759 'Test propagation of exceptions'
760 def __init__(self, seqn):
761 self.seqn = seqn
762 self.i = 0
763 def __iter__(self):
764 return self
765 def next(self):
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +0000766 3 // 0
Raymond Hettingerf0fa1c02003-05-29 07:18:57 +0000767
768class S:
769 'Test immediate stop'
770 def __init__(self, seqn):
771 pass
772 def __iter__(self):
773 return self
774 def next(self):
775 raise StopIteration
776
777def L(seqn):
778 'Test multiple tiers of iterators'
779 return chain(imap(lambda x:x, R(Ig(G(seqn)))))
780
781
782class TestVariousIteratorArgs(unittest.TestCase):
783
784 def test_chain(self):
785 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
786 for g in (G, I, Ig, S, L, R):
787 self.assertEqual(list(chain(g(s))), list(g(s)))
788 self.assertEqual(list(chain(g(s), g(s))), list(g(s))+list(g(s)))
Raymond Hettinger05bf6332008-02-28 22:30:42 +0000789 self.assertRaises(TypeError, list, chain(X(s)))
Raymond Hettingerf0fa1c02003-05-29 07:18:57 +0000790 self.assertRaises(TypeError, list, chain(N(s)))
791 self.assertRaises(ZeroDivisionError, list, chain(E(s)))
792
Raymond Hettinger50986cc2008-02-22 03:16:42 +0000793 def test_product(self):
794 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
795 self.assertRaises(TypeError, product, X(s))
796 self.assertRaises(TypeError, product, N(s))
797 self.assertRaises(ZeroDivisionError, product, E(s))
798
Raymond Hettingerf0fa1c02003-05-29 07:18:57 +0000799 def test_cycle(self):
800 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
801 for g in (G, I, Ig, S, L, R):
802 tgtlen = len(s) * 3
803 expected = list(g(s))*3
804 actual = list(islice(cycle(g(s)), tgtlen))
805 self.assertEqual(actual, expected)
806 self.assertRaises(TypeError, cycle, X(s))
807 self.assertRaises(TypeError, list, cycle(N(s)))
808 self.assertRaises(ZeroDivisionError, list, cycle(E(s)))
809
Raymond Hettingerd25c1c62003-12-06 16:23:06 +0000810 def test_groupby(self):
811 for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):
812 for g in (G, I, Ig, S, L, R):
813 self.assertEqual([k for k, sb in groupby(g(s))], list(g(s)))
814 self.assertRaises(TypeError, groupby, X(s))
815 self.assertRaises(TypeError, list, groupby(N(s)))
816 self.assertRaises(ZeroDivisionError, list, groupby(E(s)))
817
Raymond Hettingerf0fa1c02003-05-29 07:18:57 +0000818 def test_ifilter(self):
819 for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):
820 for g in (G, I, Ig, S, L, R):
821 self.assertEqual(list(ifilter(isEven, g(s))), filter(isEven, g(s)))
822 self.assertRaises(TypeError, ifilter, isEven, X(s))
823 self.assertRaises(TypeError, list, ifilter(isEven, N(s)))
824 self.assertRaises(ZeroDivisionError, list, ifilter(isEven, E(s)))
825
826 def test_ifilterfalse(self):
827 for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):
828 for g in (G, I, Ig, S, L, R):
829 self.assertEqual(list(ifilterfalse(isEven, g(s))), filter(isOdd, g(s)))
830 self.assertRaises(TypeError, ifilterfalse, isEven, X(s))
831 self.assertRaises(TypeError, list, ifilterfalse(isEven, N(s)))
832 self.assertRaises(ZeroDivisionError, list, ifilterfalse(isEven, E(s)))
833
834 def test_izip(self):
835 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
836 for g in (G, I, Ig, S, L, R):
837 self.assertEqual(list(izip(g(s))), zip(g(s)))
838 self.assertEqual(list(izip(g(s), g(s))), zip(g(s), g(s)))
839 self.assertRaises(TypeError, izip, X(s))
840 self.assertRaises(TypeError, list, izip(N(s)))
841 self.assertRaises(ZeroDivisionError, list, izip(E(s)))
842
Raymond Hettingerd36862c2007-02-21 05:20:38 +0000843 def test_iziplongest(self):
844 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
845 for g in (G, I, Ig, S, L, R):
846 self.assertEqual(list(izip_longest(g(s))), zip(g(s)))
847 self.assertEqual(list(izip_longest(g(s), g(s))), zip(g(s), g(s)))
848 self.assertRaises(TypeError, izip_longest, X(s))
849 self.assertRaises(TypeError, list, izip_longest(N(s)))
850 self.assertRaises(ZeroDivisionError, list, izip_longest(E(s)))
851
Raymond Hettingerf0fa1c02003-05-29 07:18:57 +0000852 def test_imap(self):
853 for s in (range(10), range(0), range(100), (7,11), xrange(20,50,5)):
854 for g in (G, I, Ig, S, L, R):
855 self.assertEqual(list(imap(onearg, g(s))), map(onearg, g(s)))
856 self.assertEqual(list(imap(operator.pow, g(s), g(s))), map(operator.pow, g(s), g(s)))
857 self.assertRaises(TypeError, imap, onearg, X(s))
858 self.assertRaises(TypeError, list, imap(onearg, N(s)))
859 self.assertRaises(ZeroDivisionError, list, imap(onearg, E(s)))
860
861 def test_islice(self):
862 for s in ("12345", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
863 for g in (G, I, Ig, S, L, R):
864 self.assertEqual(list(islice(g(s),1,None,2)), list(g(s))[1::2])
865 self.assertRaises(TypeError, islice, X(s), 10)
866 self.assertRaises(TypeError, list, islice(N(s), 10))
867 self.assertRaises(ZeroDivisionError, list, islice(E(s), 10))
868
869 def test_starmap(self):
870 for s in (range(10), range(0), range(100), (7,11), xrange(20,50,5)):
871 for g in (G, I, Ig, S, L, R):
872 ss = zip(s, s)
873 self.assertEqual(list(starmap(operator.pow, g(ss))), map(operator.pow, g(s), g(s)))
874 self.assertRaises(TypeError, starmap, operator.pow, X(ss))
875 self.assertRaises(TypeError, list, starmap(operator.pow, N(ss)))
876 self.assertRaises(ZeroDivisionError, list, starmap(operator.pow, E(ss)))
877
878 def test_takewhile(self):
879 for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):
880 for g in (G, I, Ig, S, L, R):
881 tgt = []
882 for elem in g(s):
883 if not isEven(elem): break
884 tgt.append(elem)
885 self.assertEqual(list(takewhile(isEven, g(s))), tgt)
886 self.assertRaises(TypeError, takewhile, isEven, X(s))
887 self.assertRaises(TypeError, list, takewhile(isEven, N(s)))
888 self.assertRaises(ZeroDivisionError, list, takewhile(isEven, E(s)))
889
890 def test_dropwhile(self):
891 for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):
892 for g in (G, I, Ig, S, L, R):
893 tgt = []
894 for elem in g(s):
895 if not tgt and isOdd(elem): continue
896 tgt.append(elem)
897 self.assertEqual(list(dropwhile(isOdd, g(s))), tgt)
898 self.assertRaises(TypeError, dropwhile, isOdd, X(s))
899 self.assertRaises(TypeError, list, dropwhile(isOdd, N(s)))
900 self.assertRaises(ZeroDivisionError, list, dropwhile(isOdd, E(s)))
901
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000902 def test_tee(self):
903 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
904 for g in (G, I, Ig, S, L, R):
905 it1, it2 = tee(g(s))
906 self.assertEqual(list(it1), list(g(s)))
907 self.assertEqual(list(it2), list(g(s)))
908 self.assertRaises(TypeError, tee, X(s))
909 self.assertRaises(TypeError, list, tee(N(s))[0])
910 self.assertRaises(ZeroDivisionError, list, tee(E(s))[0])
911
Raymond Hettinger5cab2e32004-02-10 09:25:40 +0000912class LengthTransparency(unittest.TestCase):
913
914 def test_repeat(self):
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000915 from test.test_iterlen import len
Raymond Hettinger5cab2e32004-02-10 09:25:40 +0000916 self.assertEqual(len(repeat(None, 50)), 50)
917 self.assertRaises(TypeError, len, repeat(None))
918
Raymond Hettingera56f6b62003-08-29 23:09:58 +0000919class RegressionTests(unittest.TestCase):
920
921 def test_sf_793826(self):
922 # Fix Armin Rigo's successful efforts to wreak havoc
923
924 def mutatingtuple(tuple1, f, tuple2):
925 # this builds a tuple t which is a copy of tuple1,
926 # then calls f(t), then mutates t to be equal to tuple2
927 # (needs len(tuple1) == len(tuple2)).
928 def g(value, first=[1]):
929 if first:
930 del first[:]
931 f(z.next())
932 return value
933 items = list(tuple2)
934 items[1:1] = list(tuple1)
935 gen = imap(g, items)
936 z = izip(*[gen]*len(tuple1))
937 z.next()
938
939 def f(t):
940 global T
941 T = t
942 first[:] = list(T)
943
944 first = []
945 mutatingtuple((1,2,3), f, (4,5,6))
946 second = list(T)
947 self.assertEqual(first, second)
948
Raymond Hettingerf0fa1c02003-05-29 07:18:57 +0000949
Raymond Hettinger9d7c8702004-05-08 19:49:42 +0000950 def test_sf_950057(self):
951 # Make sure that chain() and cycle() catch exceptions immediately
952 # rather than when shifting between input sources
953
954 def gen1():
955 hist.append(0)
956 yield 1
957 hist.append(1)
Tim Petersbeb7c0c2004-07-18 17:34:03 +0000958 raise AssertionError
Raymond Hettinger9d7c8702004-05-08 19:49:42 +0000959 hist.append(2)
960
961 def gen2(x):
962 hist.append(3)
963 yield 2
964 hist.append(4)
965 if x:
966 raise StopIteration
967
968 hist = []
969 self.assertRaises(AssertionError, list, chain(gen1(), gen2(False)))
970 self.assertEqual(hist, [0,1])
971
972 hist = []
973 self.assertRaises(AssertionError, list, chain(gen1(), gen2(True)))
974 self.assertEqual(hist, [0,1])
975
976 hist = []
977 self.assertRaises(AssertionError, list, cycle(gen1()))
978 self.assertEqual(hist, [0,1])
979
Georg Brandlb84c1372007-01-21 10:28:43 +0000980class SubclassWithKwargsTest(unittest.TestCase):
981 def test_keywords_in_subclass(self):
982 # count is not subclassable...
983 for cls in (repeat, izip, ifilter, ifilterfalse, chain, imap,
984 starmap, islice, takewhile, dropwhile, cycle):
985 class Subclass(cls):
986 def __init__(self, newarg=None, *args):
987 cls.__init__(self, *args)
988 try:
989 Subclass(newarg=1)
990 except TypeError, err:
991 # we expect type errors because of wrong argument count
992 self.failIf("does not take keyword arguments" in err.args[0])
993
994
Raymond Hettingerf0fa1c02003-05-29 07:18:57 +0000995libreftest = """ Doctest for examples in the library reference: libitertools.tex
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000996
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000997
998>>> amounts = [120.15, 764.05, 823.14]
999>>> for checknum, amount in izip(count(1200), amounts):
1000... print 'Check %d is for $%.2f' % (checknum, amount)
1001...
1002Check 1200 is for $120.15
1003Check 1201 is for $764.05
1004Check 1202 is for $823.14
1005
1006>>> import operator
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001007>>> for cube in imap(operator.pow, xrange(1,4), repeat(3)):
1008... print cube
1009...
10101
10118
101227
1013
1014>>> reportlines = ['EuroPython', 'Roster', '', 'alex', '', 'laura', '', 'martin', '', 'walter', '', 'samuele']
Raymond Hettinger3567a872003-06-28 05:44:36 +00001015>>> for name in islice(reportlines, 3, None, 2):
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001016... print name.title()
1017...
1018Alex
1019Laura
1020Martin
1021Walter
1022Samuele
1023
Raymond Hettingerd25c1c62003-12-06 16:23:06 +00001024>>> from operator import itemgetter
1025>>> d = dict(a=1, b=2, c=1, d=2, e=1, f=2, g=3)
Armin Rigoa3f09272006-05-28 19:13:17 +00001026>>> di = sorted(sorted(d.iteritems()), key=itemgetter(1))
Raymond Hettingerd25c1c62003-12-06 16:23:06 +00001027>>> for k, g in groupby(di, itemgetter(1)):
1028... print k, map(itemgetter(0), g)
1029...
10301 ['a', 'c', 'e']
10312 ['b', 'd', 'f']
10323 ['g']
1033
Raymond Hettinger734fb572004-01-20 20:04:40 +00001034# Find runs of consecutive numbers using groupby. The key to the solution
1035# is differencing with a range so that consecutive numbers all appear in
1036# same group.
1037>>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28]
1038>>> for k, g in groupby(enumerate(data), lambda (i,x):i-x):
1039... print map(operator.itemgetter(1), g)
1040...
1041[1]
1042[4, 5, 6]
1043[10]
1044[15, 16, 17, 18]
1045[22]
1046[25, 26, 27, 28]
1047
Raymond Hettingera098b332003-09-08 23:58:40 +00001048>>> def take(n, seq):
1049... return list(islice(seq, n))
1050
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001051>>> def enumerate(iterable):
1052... return izip(count(), iterable)
1053
1054>>> def tabulate(function):
1055... "Return function(0), function(1), ..."
1056... return imap(function, count())
1057
1058>>> def iteritems(mapping):
1059... return izip(mapping.iterkeys(), mapping.itervalues())
1060
1061>>> def nth(iterable, n):
1062... "Returns the nth item"
Raymond Hettinger60eca932003-02-09 06:40:58 +00001063... return list(islice(iterable, n, n+1))
1064
Raymond Hettingerf77d0332005-03-11 22:17:30 +00001065>>> def all(seq, pred=None):
1066... "Returns True if pred(x) is true for every element in the iterable"
Raymond Hettinger4533f1f2004-09-23 07:27:39 +00001067... for elem in ifilterfalse(pred, seq):
1068... return False
1069... return True
Raymond Hettinger60eca932003-02-09 06:40:58 +00001070
Raymond Hettingerf77d0332005-03-11 22:17:30 +00001071>>> def any(seq, pred=None):
1072... "Returns True if pred(x) is true for at least one element in the iterable"
Raymond Hettinger4533f1f2004-09-23 07:27:39 +00001073... for elem in ifilter(pred, seq):
1074... return True
1075... return False
Raymond Hettinger60eca932003-02-09 06:40:58 +00001076
Raymond Hettingerf77d0332005-03-11 22:17:30 +00001077>>> def no(seq, pred=None):
1078... "Returns True if pred(x) is false for every element in the iterable"
Raymond Hettinger4533f1f2004-09-23 07:27:39 +00001079... for elem in ifilter(pred, seq):
1080... return False
1081... return True
Raymond Hettinger77fe69b2003-08-08 04:33:19 +00001082
Raymond Hettingerf77d0332005-03-11 22:17:30 +00001083>>> def quantify(seq, pred=None):
1084... "Count how many times the predicate is true in the sequence"
Raymond Hettinger77fe69b2003-08-08 04:33:19 +00001085... return sum(imap(pred, seq))
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001086
Raymond Hettinger14ef54c2003-05-02 19:04:37 +00001087>>> def padnone(seq):
1088... "Returns the sequence elements and then returns None indefinitely"
1089... return chain(seq, repeat(None))
1090
1091>>> def ncycles(seq, n):
1092... "Returns the sequence elements n times"
1093... return chain(*repeat(seq, n))
1094
1095>>> def dotproduct(vec1, vec2):
1096... return sum(imap(operator.mul, vec1, vec2))
1097
Raymond Hettinger6a5b0272003-10-24 08:45:23 +00001098>>> def flatten(listOfLists):
1099... return list(chain(*listOfLists))
1100
1101>>> def repeatfunc(func, times=None, *args):
1102... "Repeat calls to func with specified arguments."
1103... " Example: repeatfunc(random.random)"
1104... if times is None:
1105... return starmap(func, repeat(args))
1106... else:
1107... return starmap(func, repeat(args, times))
1108
Raymond Hettingerd591f662003-10-26 15:34:50 +00001109>>> def pairwise(iterable):
1110... "s -> (s0,s1), (s1,s2), (s2, s3), ..."
1111... a, b = tee(iterable)
Raymond Hettingerad983e72003-11-12 14:32:26 +00001112... try:
1113... b.next()
1114... except StopIteration:
1115... pass
1116... return izip(a, b)
Raymond Hettinger14ef54c2003-05-02 19:04:37 +00001117
1118This is not part of the examples but it tests to make sure the definitions
1119perform as purported.
1120
Raymond Hettingera098b332003-09-08 23:58:40 +00001121>>> take(10, count())
1122[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1123
Raymond Hettinger14ef54c2003-05-02 19:04:37 +00001124>>> list(enumerate('abc'))
1125[(0, 'a'), (1, 'b'), (2, 'c')]
1126
1127>>> list(islice(tabulate(lambda x: 2*x), 4))
1128[0, 2, 4, 6]
1129
1130>>> nth('abcde', 3)
1131['d']
1132
Raymond Hettingerdbe3d282003-10-05 16:47:36 +00001133>>> all([2, 4, 6, 8], lambda x: x%2==0)
Raymond Hettinger14ef54c2003-05-02 19:04:37 +00001134True
1135
Raymond Hettingerdbe3d282003-10-05 16:47:36 +00001136>>> all([2, 3, 6, 8], lambda x: x%2==0)
Raymond Hettinger14ef54c2003-05-02 19:04:37 +00001137False
1138
Raymond Hettingerdbe3d282003-10-05 16:47:36 +00001139>>> any([2, 4, 6, 8], lambda x: x%2==0)
Raymond Hettinger14ef54c2003-05-02 19:04:37 +00001140True
1141
Raymond Hettingerdbe3d282003-10-05 16:47:36 +00001142>>> any([1, 3, 5, 9], lambda x: x%2==0,)
Raymond Hettinger14ef54c2003-05-02 19:04:37 +00001143False
1144
Raymond Hettingerdbe3d282003-10-05 16:47:36 +00001145>>> no([1, 3, 5, 9], lambda x: x%2==0)
Raymond Hettinger14ef54c2003-05-02 19:04:37 +00001146True
1147
Raymond Hettingerdbe3d282003-10-05 16:47:36 +00001148>>> no([1, 2, 5, 9], lambda x: x%2==0)
Raymond Hettinger14ef54c2003-05-02 19:04:37 +00001149False
1150
Raymond Hettingerdbe3d282003-10-05 16:47:36 +00001151>>> quantify(xrange(99), lambda x: x%2==0)
Raymond Hettingerb5a42082003-08-08 05:10:41 +0000115250
1153
Raymond Hettinger6a5b0272003-10-24 08:45:23 +00001154>>> a = [[1, 2, 3], [4, 5, 6]]
1155>>> flatten(a)
1156[1, 2, 3, 4, 5, 6]
1157
1158>>> list(repeatfunc(pow, 5, 2, 3))
1159[8, 8, 8, 8, 8]
1160
1161>>> import random
1162>>> take(5, imap(int, repeatfunc(random.random)))
1163[0, 0, 0, 0, 0]
1164
Raymond Hettingerd591f662003-10-26 15:34:50 +00001165>>> list(pairwise('abcd'))
1166[('a', 'b'), ('b', 'c'), ('c', 'd')]
Raymond Hettinger14ef54c2003-05-02 19:04:37 +00001167
Raymond Hettingerd591f662003-10-26 15:34:50 +00001168>>> list(pairwise([]))
1169[]
1170
1171>>> list(pairwise('a'))
Raymond Hettingerbefa37d2003-06-18 19:25:37 +00001172[]
1173
Raymond Hettinger14ef54c2003-05-02 19:04:37 +00001174>>> list(islice(padnone('abc'), 0, 6))
1175['a', 'b', 'c', None, None, None]
1176
1177>>> list(ncycles('abc', 3))
1178['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c']
1179
1180>>> dotproduct([1,2,3], [4,5,6])
118132
1182
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001183"""
1184
1185__test__ = {'libreftest' : libreftest}
1186
1187def test_main(verbose=None):
Raymond Hettingera56f6b62003-08-29 23:09:58 +00001188 test_classes = (TestBasicOps, TestVariousIteratorArgs, TestGC,
Georg Brandlb84c1372007-01-21 10:28:43 +00001189 RegressionTests, LengthTransparency,
1190 SubclassWithKwargsTest)
Raymond Hettingerf0fa1c02003-05-29 07:18:57 +00001191 test_support.run_unittest(*test_classes)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001192
1193 # verify reference counting
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001194 if verbose and hasattr(sys, "gettotalrefcount"):
Raymond Hettinger02420702003-06-29 20:36:23 +00001195 import gc
Raymond Hettinger8fd3f872003-05-02 22:38:07 +00001196 counts = [None] * 5
1197 for i in xrange(len(counts)):
Raymond Hettingerf0fa1c02003-05-29 07:18:57 +00001198 test_support.run_unittest(*test_classes)
Raymond Hettinger02420702003-06-29 20:36:23 +00001199 gc.collect()
Raymond Hettinger8fd3f872003-05-02 22:38:07 +00001200 counts[i] = sys.gettotalrefcount()
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001201 print counts
1202
Raymond Hettinger14ef54c2003-05-02 19:04:37 +00001203 # doctest the examples in the library reference
Raymond Hettinger929f06c2003-05-16 23:16:36 +00001204 test_support.run_doctest(sys.modules[__name__], verbose)
Raymond Hettinger14ef54c2003-05-02 19:04:37 +00001205
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001206if __name__ == "__main__":
1207 test_main(verbose=True)