]>
Commit | Line | Data |
---|---|---|
4710c53d | 1 | import unittest\r |
2 | from test import test_support\r | |
3 | from itertools import *\r | |
4 | from weakref import proxy\r | |
5 | from decimal import Decimal\r | |
6 | from fractions import Fraction\r | |
7 | import sys\r | |
8 | import operator\r | |
9 | import random\r | |
10 | import copy\r | |
11 | import pickle\r | |
12 | from functools import reduce\r | |
13 | maxsize = test_support.MAX_Py_ssize_t\r | |
14 | minsize = -maxsize-1\r | |
15 | \r | |
16 | def onearg(x):\r | |
17 | 'Test function of one argument'\r | |
18 | return 2*x\r | |
19 | \r | |
20 | def errfunc(*args):\r | |
21 | 'Test function that raises an error'\r | |
22 | raise ValueError\r | |
23 | \r | |
24 | def gen3():\r | |
25 | 'Non-restartable source sequence'\r | |
26 | for i in (0, 1, 2):\r | |
27 | yield i\r | |
28 | \r | |
29 | def isEven(x):\r | |
30 | 'Test predicate'\r | |
31 | return x%2==0\r | |
32 | \r | |
33 | def isOdd(x):\r | |
34 | 'Test predicate'\r | |
35 | return x%2==1\r | |
36 | \r | |
37 | class StopNow:\r | |
38 | 'Class emulating an empty iterable.'\r | |
39 | def __iter__(self):\r | |
40 | return self\r | |
41 | def next(self):\r | |
42 | raise StopIteration\r | |
43 | \r | |
44 | def take(n, seq):\r | |
45 | 'Convenience function for partially consuming a long of infinite iterable'\r | |
46 | return list(islice(seq, n))\r | |
47 | \r | |
48 | def prod(iterable):\r | |
49 | return reduce(operator.mul, iterable, 1)\r | |
50 | \r | |
51 | def fact(n):\r | |
52 | 'Factorial'\r | |
53 | return prod(range(1, n+1))\r | |
54 | \r | |
55 | class TestBasicOps(unittest.TestCase):\r | |
56 | def test_chain(self):\r | |
57 | \r | |
58 | def chain2(*iterables):\r | |
59 | 'Pure python version in the docs'\r | |
60 | for it in iterables:\r | |
61 | for element in it:\r | |
62 | yield element\r | |
63 | \r | |
64 | for c in (chain, chain2):\r | |
65 | self.assertEqual(list(c('abc', 'def')), list('abcdef'))\r | |
66 | self.assertEqual(list(c('abc')), list('abc'))\r | |
67 | self.assertEqual(list(c('')), [])\r | |
68 | self.assertEqual(take(4, c('abc', 'def')), list('abcd'))\r | |
69 | self.assertRaises(TypeError, list,c(2, 3))\r | |
70 | \r | |
71 | def test_chain_from_iterable(self):\r | |
72 | self.assertEqual(list(chain.from_iterable(['abc', 'def'])), list('abcdef'))\r | |
73 | self.assertEqual(list(chain.from_iterable(['abc'])), list('abc'))\r | |
74 | self.assertEqual(list(chain.from_iterable([''])), [])\r | |
75 | self.assertEqual(take(4, chain.from_iterable(['abc', 'def'])), list('abcd'))\r | |
76 | self.assertRaises(TypeError, list, chain.from_iterable([2, 3]))\r | |
77 | \r | |
78 | def test_combinations(self):\r | |
79 | self.assertRaises(TypeError, combinations, 'abc') # missing r argument\r | |
80 | self.assertRaises(TypeError, combinations, 'abc', 2, 1) # too many arguments\r | |
81 | self.assertRaises(TypeError, combinations, None) # pool is not iterable\r | |
82 | self.assertRaises(ValueError, combinations, 'abc', -2) # r is negative\r | |
83 | self.assertEqual(list(combinations('abc', 32)), []) # r > n\r | |
84 | self.assertEqual(list(combinations(range(4), 3)),\r | |
85 | [(0,1,2), (0,1,3), (0,2,3), (1,2,3)])\r | |
86 | \r | |
87 | def combinations1(iterable, r):\r | |
88 | 'Pure python version shown in the docs'\r | |
89 | pool = tuple(iterable)\r | |
90 | n = len(pool)\r | |
91 | if r > n:\r | |
92 | return\r | |
93 | indices = range(r)\r | |
94 | yield tuple(pool[i] for i in indices)\r | |
95 | while 1:\r | |
96 | for i in reversed(range(r)):\r | |
97 | if indices[i] != i + n - r:\r | |
98 | break\r | |
99 | else:\r | |
100 | return\r | |
101 | indices[i] += 1\r | |
102 | for j in range(i+1, r):\r | |
103 | indices[j] = indices[j-1] + 1\r | |
104 | yield tuple(pool[i] for i in indices)\r | |
105 | \r | |
106 | def combinations2(iterable, r):\r | |
107 | 'Pure python version shown in the docs'\r | |
108 | pool = tuple(iterable)\r | |
109 | n = len(pool)\r | |
110 | for indices in permutations(range(n), r):\r | |
111 | if sorted(indices) == list(indices):\r | |
112 | yield tuple(pool[i] for i in indices)\r | |
113 | \r | |
114 | def combinations3(iterable, r):\r | |
115 | 'Pure python version from cwr()'\r | |
116 | pool = tuple(iterable)\r | |
117 | n = len(pool)\r | |
118 | for indices in combinations_with_replacement(range(n), r):\r | |
119 | if len(set(indices)) == r:\r | |
120 | yield tuple(pool[i] for i in indices)\r | |
121 | \r | |
122 | for n in range(7):\r | |
123 | values = [5*x-12 for x in range(n)]\r | |
124 | for r in range(n+2):\r | |
125 | result = list(combinations(values, r))\r | |
126 | self.assertEqual(len(result), 0 if r>n else fact(n) // fact(r) // fact(n-r)) # right number of combs\r | |
127 | self.assertEqual(len(result), len(set(result))) # no repeats\r | |
128 | self.assertEqual(result, sorted(result)) # lexicographic order\r | |
129 | for c in result:\r | |
130 | self.assertEqual(len(c), r) # r-length combinations\r | |
131 | self.assertEqual(len(set(c)), r) # no duplicate elements\r | |
132 | self.assertEqual(list(c), sorted(c)) # keep original ordering\r | |
133 | self.assertTrue(all(e in values for e in c)) # elements taken from input iterable\r | |
134 | self.assertEqual(list(c),\r | |
135 | [e for e in values if e in c]) # comb is a subsequence of the input iterable\r | |
136 | self.assertEqual(result, list(combinations1(values, r))) # matches first pure python version\r | |
137 | self.assertEqual(result, list(combinations2(values, r))) # matches second pure python version\r | |
138 | self.assertEqual(result, list(combinations3(values, r))) # matches second pure python version\r | |
139 | \r | |
140 | # Test implementation detail: tuple re-use\r | |
141 | self.assertEqual(len(set(map(id, combinations('abcde', 3)))), 1)\r | |
142 | self.assertNotEqual(len(set(map(id, list(combinations('abcde', 3))))), 1)\r | |
143 | \r | |
144 | def test_combinations_with_replacement(self):\r | |
145 | cwr = combinations_with_replacement\r | |
146 | self.assertRaises(TypeError, cwr, 'abc') # missing r argument\r | |
147 | self.assertRaises(TypeError, cwr, 'abc', 2, 1) # too many arguments\r | |
148 | self.assertRaises(TypeError, cwr, None) # pool is not iterable\r | |
149 | self.assertRaises(ValueError, cwr, 'abc', -2) # r is negative\r | |
150 | self.assertEqual(list(cwr('ABC', 2)),\r | |
151 | [('A','A'), ('A','B'), ('A','C'), ('B','B'), ('B','C'), ('C','C')])\r | |
152 | \r | |
153 | def cwr1(iterable, r):\r | |
154 | 'Pure python version shown in the docs'\r | |
155 | # number items returned: (n+r-1)! / r! / (n-1)! when n>0\r | |
156 | pool = tuple(iterable)\r | |
157 | n = len(pool)\r | |
158 | if not n and r:\r | |
159 | return\r | |
160 | indices = [0] * r\r | |
161 | yield tuple(pool[i] for i in indices)\r | |
162 | while 1:\r | |
163 | for i in reversed(range(r)):\r | |
164 | if indices[i] != n - 1:\r | |
165 | break\r | |
166 | else:\r | |
167 | return\r | |
168 | indices[i:] = [indices[i] + 1] * (r - i)\r | |
169 | yield tuple(pool[i] for i in indices)\r | |
170 | \r | |
171 | def cwr2(iterable, r):\r | |
172 | 'Pure python version shown in the docs'\r | |
173 | pool = tuple(iterable)\r | |
174 | n = len(pool)\r | |
175 | for indices in product(range(n), repeat=r):\r | |
176 | if sorted(indices) == list(indices):\r | |
177 | yield tuple(pool[i] for i in indices)\r | |
178 | \r | |
179 | def numcombs(n, r):\r | |
180 | if not n:\r | |
181 | return 0 if r else 1\r | |
182 | return fact(n+r-1) // fact(r) // fact(n-1)\r | |
183 | \r | |
184 | for n in range(7):\r | |
185 | values = [5*x-12 for x in range(n)]\r | |
186 | for r in range(n+2):\r | |
187 | result = list(cwr(values, r))\r | |
188 | \r | |
189 | self.assertEqual(len(result), numcombs(n, r)) # right number of combs\r | |
190 | self.assertEqual(len(result), len(set(result))) # no repeats\r | |
191 | self.assertEqual(result, sorted(result)) # lexicographic order\r | |
192 | \r | |
193 | regular_combs = list(combinations(values, r)) # compare to combs without replacement\r | |
194 | if n == 0 or r <= 1:\r | |
195 | self.assertEqual(result, regular_combs) # cases that should be identical\r | |
196 | else:\r | |
197 | self.assertTrue(set(result) >= set(regular_combs)) # rest should be supersets of regular combs\r | |
198 | \r | |
199 | for c in result:\r | |
200 | self.assertEqual(len(c), r) # r-length combinations\r | |
201 | noruns = [k for k,v in groupby(c)] # combo without consecutive repeats\r | |
202 | self.assertEqual(len(noruns), len(set(noruns))) # no repeats other than consecutive\r | |
203 | self.assertEqual(list(c), sorted(c)) # keep original ordering\r | |
204 | self.assertTrue(all(e in values for e in c)) # elements taken from input iterable\r | |
205 | self.assertEqual(noruns,\r | |
206 | [e for e in values if e in c]) # comb is a subsequence of the input iterable\r | |
207 | self.assertEqual(result, list(cwr1(values, r))) # matches first pure python version\r | |
208 | self.assertEqual(result, list(cwr2(values, r))) # matches second pure python version\r | |
209 | \r | |
210 | # Test implementation detail: tuple re-use\r | |
211 | self.assertEqual(len(set(map(id, cwr('abcde', 3)))), 1)\r | |
212 | self.assertNotEqual(len(set(map(id, list(cwr('abcde', 3))))), 1)\r | |
213 | \r | |
214 | def test_permutations(self):\r | |
215 | self.assertRaises(TypeError, permutations) # too few arguments\r | |
216 | self.assertRaises(TypeError, permutations, 'abc', 2, 1) # too many arguments\r | |
217 | self.assertRaises(TypeError, permutations, None) # pool is not iterable\r | |
218 | self.assertRaises(ValueError, permutations, 'abc', -2) # r is negative\r | |
219 | self.assertEqual(list(permutations('abc', 32)), []) # r > n\r | |
220 | self.assertRaises(TypeError, permutations, 'abc', 's') # r is not an int or None\r | |
221 | self.assertEqual(list(permutations(range(3), 2)),\r | |
222 | [(0,1), (0,2), (1,0), (1,2), (2,0), (2,1)])\r | |
223 | \r | |
224 | def permutations1(iterable, r=None):\r | |
225 | 'Pure python version shown in the docs'\r | |
226 | pool = tuple(iterable)\r | |
227 | n = len(pool)\r | |
228 | r = n if r is None else r\r | |
229 | if r > n:\r | |
230 | return\r | |
231 | indices = range(n)\r | |
232 | cycles = range(n, n-r, -1)\r | |
233 | yield tuple(pool[i] for i in indices[:r])\r | |
234 | while n:\r | |
235 | for i in reversed(range(r)):\r | |
236 | cycles[i] -= 1\r | |
237 | if cycles[i] == 0:\r | |
238 | indices[i:] = indices[i+1:] + indices[i:i+1]\r | |
239 | cycles[i] = n - i\r | |
240 | else:\r | |
241 | j = cycles[i]\r | |
242 | indices[i], indices[-j] = indices[-j], indices[i]\r | |
243 | yield tuple(pool[i] for i in indices[:r])\r | |
244 | break\r | |
245 | else:\r | |
246 | return\r | |
247 | \r | |
248 | def permutations2(iterable, r=None):\r | |
249 | 'Pure python version shown in the docs'\r | |
250 | pool = tuple(iterable)\r | |
251 | n = len(pool)\r | |
252 | r = n if r is None else r\r | |
253 | for indices in product(range(n), repeat=r):\r | |
254 | if len(set(indices)) == r:\r | |
255 | yield tuple(pool[i] for i in indices)\r | |
256 | \r | |
257 | for n in range(7):\r | |
258 | values = [5*x-12 for x in range(n)]\r | |
259 | for r in range(n+2):\r | |
260 | result = list(permutations(values, r))\r | |
261 | self.assertEqual(len(result), 0 if r>n else fact(n) // fact(n-r)) # right number of perms\r | |
262 | self.assertEqual(len(result), len(set(result))) # no repeats\r | |
263 | self.assertEqual(result, sorted(result)) # lexicographic order\r | |
264 | for p in result:\r | |
265 | self.assertEqual(len(p), r) # r-length permutations\r | |
266 | self.assertEqual(len(set(p)), r) # no duplicate elements\r | |
267 | self.assertTrue(all(e in values for e in p)) # elements taken from input iterable\r | |
268 | self.assertEqual(result, list(permutations1(values, r))) # matches first pure python version\r | |
269 | self.assertEqual(result, list(permutations2(values, r))) # matches second pure python version\r | |
270 | if r == n:\r | |
271 | self.assertEqual(result, list(permutations(values, None))) # test r as None\r | |
272 | self.assertEqual(result, list(permutations(values))) # test default r\r | |
273 | \r | |
274 | # Test implementation detail: tuple re-use\r | |
275 | self.assertEqual(len(set(map(id, permutations('abcde', 3)))), 1)\r | |
276 | self.assertNotEqual(len(set(map(id, list(permutations('abcde', 3))))), 1)\r | |
277 | \r | |
278 | def test_combinatorics(self):\r | |
279 | # Test relationships between product(), permutations(),\r | |
280 | # combinations() and combinations_with_replacement().\r | |
281 | \r | |
282 | for n in range(6):\r | |
283 | s = 'ABCDEFG'[:n]\r | |
284 | for r in range(8):\r | |
285 | prod = list(product(s, repeat=r))\r | |
286 | cwr = list(combinations_with_replacement(s, r))\r | |
287 | perm = list(permutations(s, r))\r | |
288 | comb = list(combinations(s, r))\r | |
289 | \r | |
290 | # Check size\r | |
291 | self.assertEqual(len(prod), n**r)\r | |
292 | self.assertEqual(len(cwr), (fact(n+r-1) // fact(r) // fact(n-1)) if n else (not r))\r | |
293 | self.assertEqual(len(perm), 0 if r>n else fact(n) // fact(n-r))\r | |
294 | self.assertEqual(len(comb), 0 if r>n else fact(n) // fact(r) // fact(n-r))\r | |
295 | \r | |
296 | # Check lexicographic order without repeated tuples\r | |
297 | self.assertEqual(prod, sorted(set(prod)))\r | |
298 | self.assertEqual(cwr, sorted(set(cwr)))\r | |
299 | self.assertEqual(perm, sorted(set(perm)))\r | |
300 | self.assertEqual(comb, sorted(set(comb)))\r | |
301 | \r | |
302 | # Check interrelationships\r | |
303 | self.assertEqual(cwr, [t for t in prod if sorted(t)==list(t)]) # cwr: prods which are sorted\r | |
304 | self.assertEqual(perm, [t for t in prod if len(set(t))==r]) # perm: prods with no dups\r | |
305 | self.assertEqual(comb, [t for t in perm if sorted(t)==list(t)]) # comb: perms that are sorted\r | |
306 | self.assertEqual(comb, [t for t in cwr if len(set(t))==r]) # comb: cwrs without dups\r | |
307 | self.assertEqual(comb, filter(set(cwr).__contains__, perm)) # comb: perm that is a cwr\r | |
308 | self.assertEqual(comb, filter(set(perm).__contains__, cwr)) # comb: cwr that is a perm\r | |
309 | self.assertEqual(comb, sorted(set(cwr) & set(perm))) # comb: both a cwr and a perm\r | |
310 | \r | |
311 | def test_compress(self):\r | |
312 | self.assertEqual(list(compress(data='ABCDEF', selectors=[1,0,1,0,1,1])), list('ACEF'))\r | |
313 | self.assertEqual(list(compress('ABCDEF', [1,0,1,0,1,1])), list('ACEF'))\r | |
314 | self.assertEqual(list(compress('ABCDEF', [0,0,0,0,0,0])), list(''))\r | |
315 | self.assertEqual(list(compress('ABCDEF', [1,1,1,1,1,1])), list('ABCDEF'))\r | |
316 | self.assertEqual(list(compress('ABCDEF', [1,0,1])), list('AC'))\r | |
317 | self.assertEqual(list(compress('ABC', [0,1,1,1,1,1])), list('BC'))\r | |
318 | n = 10000\r | |
319 | data = chain.from_iterable(repeat(range(6), n))\r | |
320 | selectors = chain.from_iterable(repeat((0, 1)))\r | |
321 | self.assertEqual(list(compress(data, selectors)), [1,3,5] * n)\r | |
322 | self.assertRaises(TypeError, compress, None, range(6)) # 1st arg not iterable\r | |
323 | self.assertRaises(TypeError, compress, range(6), None) # 2nd arg not iterable\r | |
324 | self.assertRaises(TypeError, compress, range(6)) # too few args\r | |
325 | self.assertRaises(TypeError, compress, range(6), None) # too many args\r | |
326 | \r | |
327 | def test_count(self):\r | |
328 | self.assertEqual(zip('abc',count()), [('a', 0), ('b', 1), ('c', 2)])\r | |
329 | self.assertEqual(zip('abc',count(3)), [('a', 3), ('b', 4), ('c', 5)])\r | |
330 | self.assertEqual(take(2, zip('abc',count(3))), [('a', 3), ('b', 4)])\r | |
331 | self.assertEqual(take(2, zip('abc',count(-1))), [('a', -1), ('b', 0)])\r | |
332 | self.assertEqual(take(2, zip('abc',count(-3))), [('a', -3), ('b', -2)])\r | |
333 | self.assertRaises(TypeError, count, 2, 3, 4)\r | |
334 | self.assertRaises(TypeError, count, 'a')\r | |
335 | self.assertEqual(list(islice(count(maxsize-5), 10)), range(maxsize-5, maxsize+5))\r | |
336 | self.assertEqual(list(islice(count(-maxsize-5), 10)), range(-maxsize-5, -maxsize+5))\r | |
337 | c = count(3)\r | |
338 | self.assertEqual(repr(c), 'count(3)')\r | |
339 | c.next()\r | |
340 | self.assertEqual(repr(c), 'count(4)')\r | |
341 | c = count(-9)\r | |
342 | self.assertEqual(repr(c), 'count(-9)')\r | |
343 | c.next()\r | |
344 | self.assertEqual(repr(count(10.25)), 'count(10.25)')\r | |
345 | self.assertEqual(c.next(), -8)\r | |
346 | for i in (-sys.maxint-5, -sys.maxint+5 ,-10, -1, 0, 10, sys.maxint-5, sys.maxint+5):\r | |
347 | # Test repr (ignoring the L in longs)\r | |
348 | r1 = repr(count(i)).replace('L', '')\r | |
349 | r2 = 'count(%r)'.__mod__(i).replace('L', '')\r | |
350 | self.assertEqual(r1, r2)\r | |
351 | \r | |
352 | # check copy, deepcopy, pickle\r | |
353 | for value in -3, 3, sys.maxint-5, sys.maxint+5:\r | |
354 | c = count(value)\r | |
355 | self.assertEqual(next(copy.copy(c)), value)\r | |
356 | self.assertEqual(next(copy.deepcopy(c)), value)\r | |
357 | self.assertEqual(next(pickle.loads(pickle.dumps(c))), value)\r | |
358 | \r | |
359 | def test_count_with_stride(self):\r | |
360 | self.assertEqual(zip('abc',count(2,3)), [('a', 2), ('b', 5), ('c', 8)])\r | |
361 | self.assertEqual(zip('abc',count(start=2,step=3)),\r | |
362 | [('a', 2), ('b', 5), ('c', 8)])\r | |
363 | self.assertEqual(zip('abc',count(step=-1)),\r | |
364 | [('a', 0), ('b', -1), ('c', -2)])\r | |
365 | self.assertEqual(zip('abc',count(2,0)), [('a', 2), ('b', 2), ('c', 2)])\r | |
366 | self.assertEqual(zip('abc',count(2,1)), [('a', 2), ('b', 3), ('c', 4)])\r | |
367 | self.assertEqual(take(20, count(maxsize-15, 3)), take(20, range(maxsize-15, maxsize+100, 3)))\r | |
368 | self.assertEqual(take(20, count(-maxsize-15, 3)), take(20, range(-maxsize-15,-maxsize+100, 3)))\r | |
369 | self.assertEqual(take(3, count(2, 3.25-4j)), [2, 5.25-4j, 8.5-8j])\r | |
370 | self.assertEqual(take(3, count(Decimal('1.1'), Decimal('.1'))),\r | |
371 | [Decimal('1.1'), Decimal('1.2'), Decimal('1.3')])\r | |
372 | self.assertEqual(take(3, count(Fraction(2,3), Fraction(1,7))),\r | |
373 | [Fraction(2,3), Fraction(17,21), Fraction(20,21)])\r | |
374 | self.assertEqual(repr(take(3, count(10, 2.5))), repr([10, 12.5, 15.0]))\r | |
375 | c = count(3, 5)\r | |
376 | self.assertEqual(repr(c), 'count(3, 5)')\r | |
377 | c.next()\r | |
378 | self.assertEqual(repr(c), 'count(8, 5)')\r | |
379 | c = count(-9, 0)\r | |
380 | self.assertEqual(repr(c), 'count(-9, 0)')\r | |
381 | c.next()\r | |
382 | self.assertEqual(repr(c), 'count(-9, 0)')\r | |
383 | c = count(-9, -3)\r | |
384 | self.assertEqual(repr(c), 'count(-9, -3)')\r | |
385 | c.next()\r | |
386 | self.assertEqual(repr(c), 'count(-12, -3)')\r | |
387 | self.assertEqual(repr(c), 'count(-12, -3)')\r | |
388 | self.assertEqual(repr(count(10.5, 1.25)), 'count(10.5, 1.25)')\r | |
389 | self.assertEqual(repr(count(10.5, 1)), 'count(10.5)') # suppress step=1 when it's an int\r | |
390 | self.assertEqual(repr(count(10.5, 1.00)), 'count(10.5, 1.0)') # do show float values lilke 1.0\r | |
391 | for i in (-sys.maxint-5, -sys.maxint+5 ,-10, -1, 0, 10, sys.maxint-5, sys.maxint+5):\r | |
392 | for j in (-sys.maxint-5, -sys.maxint+5 ,-10, -1, 0, 1, 10, sys.maxint-5, sys.maxint+5):\r | |
393 | # Test repr (ignoring the L in longs)\r | |
394 | r1 = repr(count(i, j)).replace('L', '')\r | |
395 | if j == 1:\r | |
396 | r2 = ('count(%r)' % i).replace('L', '')\r | |
397 | else:\r | |
398 | r2 = ('count(%r, %r)' % (i, j)).replace('L', '')\r | |
399 | self.assertEqual(r1, r2)\r | |
400 | \r | |
401 | def test_cycle(self):\r | |
402 | self.assertEqual(take(10, cycle('abc')), list('abcabcabca'))\r | |
403 | self.assertEqual(list(cycle('')), [])\r | |
404 | self.assertRaises(TypeError, cycle)\r | |
405 | self.assertRaises(TypeError, cycle, 5)\r | |
406 | self.assertEqual(list(islice(cycle(gen3()),10)), [0,1,2,0,1,2,0,1,2,0])\r | |
407 | \r | |
408 | def test_groupby(self):\r | |
409 | # Check whether it accepts arguments correctly\r | |
410 | self.assertEqual([], list(groupby([])))\r | |
411 | self.assertEqual([], list(groupby([], key=id)))\r | |
412 | self.assertRaises(TypeError, list, groupby('abc', []))\r | |
413 | self.assertRaises(TypeError, groupby, None)\r | |
414 | self.assertRaises(TypeError, groupby, 'abc', lambda x:x, 10)\r | |
415 | \r | |
416 | # Check normal input\r | |
417 | s = [(0, 10, 20), (0, 11,21), (0,12,21), (1,13,21), (1,14,22),\r | |
418 | (2,15,22), (3,16,23), (3,17,23)]\r | |
419 | dup = []\r | |
420 | for k, g in groupby(s, lambda r:r[0]):\r | |
421 | for elem in g:\r | |
422 | self.assertEqual(k, elem[0])\r | |
423 | dup.append(elem)\r | |
424 | self.assertEqual(s, dup)\r | |
425 | \r | |
426 | # Check nested case\r | |
427 | dup = []\r | |
428 | for k, g in groupby(s, lambda r:r[0]):\r | |
429 | for ik, ig in groupby(g, lambda r:r[2]):\r | |
430 | for elem in ig:\r | |
431 | self.assertEqual(k, elem[0])\r | |
432 | self.assertEqual(ik, elem[2])\r | |
433 | dup.append(elem)\r | |
434 | self.assertEqual(s, dup)\r | |
435 | \r | |
436 | # Check case where inner iterator is not used\r | |
437 | keys = [k for k, g in groupby(s, lambda r:r[0])]\r | |
438 | expectedkeys = set([r[0] for r in s])\r | |
439 | self.assertEqual(set(keys), expectedkeys)\r | |
440 | self.assertEqual(len(keys), len(expectedkeys))\r | |
441 | \r | |
442 | # Exercise pipes and filters style\r | |
443 | s = 'abracadabra'\r | |
444 | # sort s | uniq\r | |
445 | r = [k for k, g in groupby(sorted(s))]\r | |
446 | self.assertEqual(r, ['a', 'b', 'c', 'd', 'r'])\r | |
447 | # sort s | uniq -d\r | |
448 | r = [k for k, g in groupby(sorted(s)) if list(islice(g,1,2))]\r | |
449 | self.assertEqual(r, ['a', 'b', 'r'])\r | |
450 | # sort s | uniq -c\r | |
451 | r = [(len(list(g)), k) for k, g in groupby(sorted(s))]\r | |
452 | self.assertEqual(r, [(5, 'a'), (2, 'b'), (1, 'c'), (1, 'd'), (2, 'r')])\r | |
453 | # sort s | uniq -c | sort -rn | head -3\r | |
454 | r = sorted([(len(list(g)) , k) for k, g in groupby(sorted(s))], reverse=True)[:3]\r | |
455 | self.assertEqual(r, [(5, 'a'), (2, 'r'), (2, 'b')])\r | |
456 | \r | |
457 | # iter.next failure\r | |
458 | class ExpectedError(Exception):\r | |
459 | pass\r | |
460 | def delayed_raise(n=0):\r | |
461 | for i in range(n):\r | |
462 | yield 'yo'\r | |
463 | raise ExpectedError\r | |
464 | def gulp(iterable, keyp=None, func=list):\r | |
465 | return [func(g) for k, g in groupby(iterable, keyp)]\r | |
466 | \r | |
467 | # iter.next failure on outer object\r | |
468 | self.assertRaises(ExpectedError, gulp, delayed_raise(0))\r | |
469 | # iter.next failure on inner object\r | |
470 | self.assertRaises(ExpectedError, gulp, delayed_raise(1))\r | |
471 | \r | |
472 | # __cmp__ failure\r | |
473 | class DummyCmp:\r | |
474 | def __cmp__(self, dst):\r | |
475 | raise ExpectedError\r | |
476 | s = [DummyCmp(), DummyCmp(), None]\r | |
477 | \r | |
478 | # __cmp__ failure on outer object\r | |
479 | self.assertRaises(ExpectedError, gulp, s, func=id)\r | |
480 | # __cmp__ failure on inner object\r | |
481 | self.assertRaises(ExpectedError, gulp, s)\r | |
482 | \r | |
483 | # keyfunc failure\r | |
484 | def keyfunc(obj):\r | |
485 | if keyfunc.skip > 0:\r | |
486 | keyfunc.skip -= 1\r | |
487 | return obj\r | |
488 | else:\r | |
489 | raise ExpectedError\r | |
490 | \r | |
491 | # keyfunc failure on outer object\r | |
492 | keyfunc.skip = 0\r | |
493 | self.assertRaises(ExpectedError, gulp, [None], keyfunc)\r | |
494 | keyfunc.skip = 1\r | |
495 | self.assertRaises(ExpectedError, gulp, [None, None], keyfunc)\r | |
496 | \r | |
497 | def test_ifilter(self):\r | |
498 | self.assertEqual(list(ifilter(isEven, range(6))), [0,2,4])\r | |
499 | self.assertEqual(list(ifilter(None, [0,1,0,2,0])), [1,2])\r | |
500 | self.assertEqual(list(ifilter(bool, [0,1,0,2,0])), [1,2])\r | |
501 | self.assertEqual(take(4, ifilter(isEven, count())), [0,2,4,6])\r | |
502 | self.assertRaises(TypeError, ifilter)\r | |
503 | self.assertRaises(TypeError, ifilter, lambda x:x)\r | |
504 | self.assertRaises(TypeError, ifilter, lambda x:x, range(6), 7)\r | |
505 | self.assertRaises(TypeError, ifilter, isEven, 3)\r | |
506 | self.assertRaises(TypeError, ifilter(range(6), range(6)).next)\r | |
507 | \r | |
508 | def test_ifilterfalse(self):\r | |
509 | self.assertEqual(list(ifilterfalse(isEven, range(6))), [1,3,5])\r | |
510 | self.assertEqual(list(ifilterfalse(None, [0,1,0,2,0])), [0,0,0])\r | |
511 | self.assertEqual(list(ifilterfalse(bool, [0,1,0,2,0])), [0,0,0])\r | |
512 | self.assertEqual(take(4, ifilterfalse(isEven, count())), [1,3,5,7])\r | |
513 | self.assertRaises(TypeError, ifilterfalse)\r | |
514 | self.assertRaises(TypeError, ifilterfalse, lambda x:x)\r | |
515 | self.assertRaises(TypeError, ifilterfalse, lambda x:x, range(6), 7)\r | |
516 | self.assertRaises(TypeError, ifilterfalse, isEven, 3)\r | |
517 | self.assertRaises(TypeError, ifilterfalse(range(6), range(6)).next)\r | |
518 | \r | |
519 | def test_izip(self):\r | |
520 | ans = [(x,y) for x, y in izip('abc',count())]\r | |
521 | self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)])\r | |
522 | self.assertEqual(list(izip('abc', range(6))), zip('abc', range(6)))\r | |
523 | self.assertEqual(list(izip('abcdef', range(3))), zip('abcdef', range(3)))\r | |
524 | self.assertEqual(take(3,izip('abcdef', count())), zip('abcdef', range(3)))\r | |
525 | self.assertEqual(list(izip('abcdef')), zip('abcdef'))\r | |
526 | self.assertEqual(list(izip()), zip())\r | |
527 | self.assertRaises(TypeError, izip, 3)\r | |
528 | self.assertRaises(TypeError, izip, range(3), 3)\r | |
529 | # Check tuple re-use (implementation detail)\r | |
530 | self.assertEqual([tuple(list(pair)) for pair in izip('abc', 'def')],\r | |
531 | zip('abc', 'def'))\r | |
532 | self.assertEqual([pair for pair in izip('abc', 'def')],\r | |
533 | zip('abc', 'def'))\r | |
534 | ids = map(id, izip('abc', 'def'))\r | |
535 | self.assertEqual(min(ids), max(ids))\r | |
536 | ids = map(id, list(izip('abc', 'def')))\r | |
537 | self.assertEqual(len(dict.fromkeys(ids)), len(ids))\r | |
538 | \r | |
539 | def test_iziplongest(self):\r | |
540 | for args in [\r | |
541 | ['abc', range(6)],\r | |
542 | [range(6), 'abc'],\r | |
543 | [range(1000), range(2000,2100), range(3000,3050)],\r | |
544 | [range(1000), range(0), range(3000,3050), range(1200), range(1500)],\r | |
545 | [range(1000), range(0), range(3000,3050), range(1200), range(1500), range(0)],\r | |
546 | ]:\r | |
547 | # target = map(None, *args) <- this raises a py3k warning\r | |
548 | # this is the replacement:\r | |
549 | target = [tuple([arg[i] if i < len(arg) else None for arg in args])\r | |
550 | for i in range(max(map(len, args)))]\r | |
551 | self.assertEqual(list(izip_longest(*args)), target)\r | |
552 | self.assertEqual(list(izip_longest(*args, **{})), target)\r | |
553 | target = [tuple((e is None and 'X' or e) for e in t) for t in target] # Replace None fills with 'X'\r | |
554 | self.assertEqual(list(izip_longest(*args, **dict(fillvalue='X'))), target)\r | |
555 | \r | |
556 | self.assertEqual(take(3,izip_longest('abcdef', count())), zip('abcdef', range(3))) # take 3 from infinite input\r | |
557 | \r | |
558 | self.assertEqual(list(izip_longest()), zip())\r | |
559 | self.assertEqual(list(izip_longest([])), zip([]))\r | |
560 | self.assertEqual(list(izip_longest('abcdef')), zip('abcdef'))\r | |
561 | \r | |
562 | self.assertEqual(list(izip_longest('abc', 'defg', **{})),\r | |
563 | zip(list('abc') + [None], 'defg')) # empty keyword dict\r | |
564 | self.assertRaises(TypeError, izip_longest, 3)\r | |
565 | self.assertRaises(TypeError, izip_longest, range(3), 3)\r | |
566 | \r | |
567 | for stmt in [\r | |
568 | "izip_longest('abc', fv=1)",\r | |
569 | "izip_longest('abc', fillvalue=1, bogus_keyword=None)",\r | |
570 | ]:\r | |
571 | try:\r | |
572 | eval(stmt, globals(), locals())\r | |
573 | except TypeError:\r | |
574 | pass\r | |
575 | else:\r | |
576 | self.fail('Did not raise Type in: ' + stmt)\r | |
577 | \r | |
578 | # Check tuple re-use (implementation detail)\r | |
579 | self.assertEqual([tuple(list(pair)) for pair in izip_longest('abc', 'def')],\r | |
580 | zip('abc', 'def'))\r | |
581 | self.assertEqual([pair for pair in izip_longest('abc', 'def')],\r | |
582 | zip('abc', 'def'))\r | |
583 | ids = map(id, izip_longest('abc', 'def'))\r | |
584 | self.assertEqual(min(ids), max(ids))\r | |
585 | ids = map(id, list(izip_longest('abc', 'def')))\r | |
586 | self.assertEqual(len(dict.fromkeys(ids)), len(ids))\r | |
587 | \r | |
588 | def test_bug_7244(self):\r | |
589 | \r | |
590 | class Repeater(object):\r | |
591 | # this class is similar to itertools.repeat\r | |
592 | def __init__(self, o, t, e):\r | |
593 | self.o = o\r | |
594 | self.t = int(t)\r | |
595 | self.e = e\r | |
596 | def __iter__(self): # its iterator is itself\r | |
597 | return self\r | |
598 | def next(self):\r | |
599 | if self.t > 0:\r | |
600 | self.t -= 1\r | |
601 | return self.o\r | |
602 | else:\r | |
603 | raise self.e\r | |
604 | \r | |
605 | # Formerly this code in would fail in debug mode\r | |
606 | # with Undetected Error and Stop Iteration\r | |
607 | r1 = Repeater(1, 3, StopIteration)\r | |
608 | r2 = Repeater(2, 4, StopIteration)\r | |
609 | def run(r1, r2):\r | |
610 | result = []\r | |
611 | for i, j in izip_longest(r1, r2, fillvalue=0):\r | |
612 | with test_support.captured_output('stdout'):\r | |
613 | print (i, j)\r | |
614 | result.append((i, j))\r | |
615 | return result\r | |
616 | self.assertEqual(run(r1, r2), [(1,2), (1,2), (1,2), (0,2)])\r | |
617 | \r | |
618 | # Formerly, the RuntimeError would be lost\r | |
619 | # and StopIteration would stop as expected\r | |
620 | r1 = Repeater(1, 3, RuntimeError)\r | |
621 | r2 = Repeater(2, 4, StopIteration)\r | |
622 | it = izip_longest(r1, r2, fillvalue=0)\r | |
623 | self.assertEqual(next(it), (1, 2))\r | |
624 | self.assertEqual(next(it), (1, 2))\r | |
625 | self.assertEqual(next(it), (1, 2))\r | |
626 | self.assertRaises(RuntimeError, next, it)\r | |
627 | \r | |
628 | def test_product(self):\r | |
629 | for args, result in [\r | |
630 | ([], [()]), # zero iterables\r | |
631 | (['ab'], [('a',), ('b',)]), # one iterable\r | |
632 | ([range(2), range(3)], [(0,0), (0,1), (0,2), (1,0), (1,1), (1,2)]), # two iterables\r | |
633 | ([range(0), range(2), range(3)], []), # first iterable with zero length\r | |
634 | ([range(2), range(0), range(3)], []), # middle iterable with zero length\r | |
635 | ([range(2), range(3), range(0)], []), # last iterable with zero length\r | |
636 | ]:\r | |
637 | self.assertEqual(list(product(*args)), result)\r | |
638 | for r in range(4):\r | |
639 | self.assertEqual(list(product(*(args*r))),\r | |
640 | list(product(*args, **dict(repeat=r))))\r | |
641 | self.assertEqual(len(list(product(*[range(7)]*6))), 7**6)\r | |
642 | self.assertRaises(TypeError, product, range(6), None)\r | |
643 | \r | |
644 | def product1(*args, **kwds):\r | |
645 | pools = map(tuple, args) * kwds.get('repeat', 1)\r | |
646 | n = len(pools)\r | |
647 | if n == 0:\r | |
648 | yield ()\r | |
649 | return\r | |
650 | if any(len(pool) == 0 for pool in pools):\r | |
651 | return\r | |
652 | indices = [0] * n\r | |
653 | yield tuple(pool[i] for pool, i in zip(pools, indices))\r | |
654 | while 1:\r | |
655 | for i in reversed(range(n)): # right to left\r | |
656 | if indices[i] == len(pools[i]) - 1:\r | |
657 | continue\r | |
658 | indices[i] += 1\r | |
659 | for j in range(i+1, n):\r | |
660 | indices[j] = 0\r | |
661 | yield tuple(pool[i] for pool, i in zip(pools, indices))\r | |
662 | break\r | |
663 | else:\r | |
664 | return\r | |
665 | \r | |
666 | def product2(*args, **kwds):\r | |
667 | 'Pure python version used in docs'\r | |
668 | pools = map(tuple, args) * kwds.get('repeat', 1)\r | |
669 | result = [[]]\r | |
670 | for pool in pools:\r | |
671 | result = [x+[y] for x in result for y in pool]\r | |
672 | for prod in result:\r | |
673 | yield tuple(prod)\r | |
674 | \r | |
675 | argtypes = ['', 'abc', '', xrange(0), xrange(4), dict(a=1, b=2, c=3),\r | |
676 | set('abcdefg'), range(11), tuple(range(13))]\r | |
677 | for i in range(100):\r | |
678 | args = [random.choice(argtypes) for j in range(random.randrange(5))]\r | |
679 | expected_len = prod(map(len, args))\r | |
680 | self.assertEqual(len(list(product(*args))), expected_len)\r | |
681 | self.assertEqual(list(product(*args)), list(product1(*args)))\r | |
682 | self.assertEqual(list(product(*args)), list(product2(*args)))\r | |
683 | args = map(iter, args)\r | |
684 | self.assertEqual(len(list(product(*args))), expected_len)\r | |
685 | \r | |
686 | # Test implementation detail: tuple re-use\r | |
687 | self.assertEqual(len(set(map(id, product('abc', 'def')))), 1)\r | |
688 | self.assertNotEqual(len(set(map(id, list(product('abc', 'def'))))), 1)\r | |
689 | \r | |
690 | def test_repeat(self):\r | |
691 | self.assertEqual(list(repeat(object='a', times=3)), ['a', 'a', 'a'])\r | |
692 | self.assertEqual(zip(xrange(3),repeat('a')),\r | |
693 | [(0, 'a'), (1, 'a'), (2, 'a')])\r | |
694 | self.assertEqual(list(repeat('a', 3)), ['a', 'a', 'a'])\r | |
695 | self.assertEqual(take(3, repeat('a')), ['a', 'a', 'a'])\r | |
696 | self.assertEqual(list(repeat('a', 0)), [])\r | |
697 | self.assertEqual(list(repeat('a', -3)), [])\r | |
698 | self.assertRaises(TypeError, repeat)\r | |
699 | self.assertRaises(TypeError, repeat, None, 3, 4)\r | |
700 | self.assertRaises(TypeError, repeat, None, 'a')\r | |
701 | r = repeat(1+0j)\r | |
702 | self.assertEqual(repr(r), 'repeat((1+0j))')\r | |
703 | r = repeat(1+0j, 5)\r | |
704 | self.assertEqual(repr(r), 'repeat((1+0j), 5)')\r | |
705 | list(r)\r | |
706 | self.assertEqual(repr(r), 'repeat((1+0j), 0)')\r | |
707 | \r | |
708 | def test_imap(self):\r | |
709 | self.assertEqual(list(imap(operator.pow, range(3), range(1,7))),\r | |
710 | [0**1, 1**2, 2**3])\r | |
711 | self.assertEqual(list(imap(None, 'abc', range(5))),\r | |
712 | [('a',0),('b',1),('c',2)])\r | |
713 | self.assertEqual(list(imap(None, 'abc', count())),\r | |
714 | [('a',0),('b',1),('c',2)])\r | |
715 | self.assertEqual(take(2,imap(None, 'abc', count())),\r | |
716 | [('a',0),('b',1)])\r | |
717 | self.assertEqual(list(imap(operator.pow, [])), [])\r | |
718 | self.assertRaises(TypeError, imap)\r | |
719 | self.assertRaises(TypeError, imap, operator.neg)\r | |
720 | self.assertRaises(TypeError, imap(10, range(5)).next)\r | |
721 | self.assertRaises(ValueError, imap(errfunc, [4], [5]).next)\r | |
722 | self.assertRaises(TypeError, imap(onearg, [4], [5]).next)\r | |
723 | \r | |
724 | def test_starmap(self):\r | |
725 | self.assertEqual(list(starmap(operator.pow, zip(range(3), range(1,7)))),\r | |
726 | [0**1, 1**2, 2**3])\r | |
727 | self.assertEqual(take(3, starmap(operator.pow, izip(count(), count(1)))),\r | |
728 | [0**1, 1**2, 2**3])\r | |
729 | self.assertEqual(list(starmap(operator.pow, [])), [])\r | |
730 | self.assertEqual(list(starmap(operator.pow, [iter([4,5])])), [4**5])\r | |
731 | self.assertRaises(TypeError, list, starmap(operator.pow, [None]))\r | |
732 | self.assertRaises(TypeError, starmap)\r | |
733 | self.assertRaises(TypeError, starmap, operator.pow, [(4,5)], 'extra')\r | |
734 | self.assertRaises(TypeError, starmap(10, [(4,5)]).next)\r | |
735 | self.assertRaises(ValueError, starmap(errfunc, [(4,5)]).next)\r | |
736 | self.assertRaises(TypeError, starmap(onearg, [(4,5)]).next)\r | |
737 | \r | |
738 | def test_islice(self):\r | |
739 | for args in [ # islice(args) should agree with range(args)\r | |
740 | (10, 20, 3),\r | |
741 | (10, 3, 20),\r | |
742 | (10, 20),\r | |
743 | (10, 3),\r | |
744 | (20,)\r | |
745 | ]:\r | |
746 | self.assertEqual(list(islice(xrange(100), *args)), range(*args))\r | |
747 | \r | |
748 | for args, tgtargs in [ # Stop when seqn is exhausted\r | |
749 | ((10, 110, 3), ((10, 100, 3))),\r | |
750 | ((10, 110), ((10, 100))),\r | |
751 | ((110,), (100,))\r | |
752 | ]:\r | |
753 | self.assertEqual(list(islice(xrange(100), *args)), range(*tgtargs))\r | |
754 | \r | |
755 | # Test stop=None\r | |
756 | self.assertEqual(list(islice(xrange(10), None)), range(10))\r | |
757 | self.assertEqual(list(islice(xrange(10), None, None)), range(10))\r | |
758 | self.assertEqual(list(islice(xrange(10), None, None, None)), range(10))\r | |
759 | self.assertEqual(list(islice(xrange(10), 2, None)), range(2, 10))\r | |
760 | self.assertEqual(list(islice(xrange(10), 1, None, 2)), range(1, 10, 2))\r | |
761 | \r | |
762 | # Test number of items consumed SF #1171417\r | |
763 | it = iter(range(10))\r | |
764 | self.assertEqual(list(islice(it, 3)), range(3))\r | |
765 | self.assertEqual(list(it), range(3, 10))\r | |
766 | \r | |
767 | # Test invalid arguments\r | |
768 | self.assertRaises(TypeError, islice, xrange(10))\r | |
769 | self.assertRaises(TypeError, islice, xrange(10), 1, 2, 3, 4)\r | |
770 | self.assertRaises(ValueError, islice, xrange(10), -5, 10, 1)\r | |
771 | self.assertRaises(ValueError, islice, xrange(10), 1, -5, -1)\r | |
772 | self.assertRaises(ValueError, islice, xrange(10), 1, 10, -1)\r | |
773 | self.assertRaises(ValueError, islice, xrange(10), 1, 10, 0)\r | |
774 | self.assertRaises(ValueError, islice, xrange(10), 'a')\r | |
775 | self.assertRaises(ValueError, islice, xrange(10), 'a', 1)\r | |
776 | self.assertRaises(ValueError, islice, xrange(10), 1, 'a')\r | |
777 | self.assertRaises(ValueError, islice, xrange(10), 'a', 1, 1)\r | |
778 | self.assertRaises(ValueError, islice, xrange(10), 1, 'a', 1)\r | |
779 | self.assertEqual(len(list(islice(count(), 1, 10, maxsize))), 1)\r | |
780 | \r | |
781 | # Issue #10323: Less islice in a predictable state\r | |
782 | c = count()\r | |
783 | self.assertEqual(list(islice(c, 1, 3, 50)), [1])\r | |
784 | self.assertEqual(next(c), 3)\r | |
785 | \r | |
786 | def test_takewhile(self):\r | |
787 | data = [1, 3, 5, 20, 2, 4, 6, 8]\r | |
788 | underten = lambda x: x<10\r | |
789 | self.assertEqual(list(takewhile(underten, data)), [1, 3, 5])\r | |
790 | self.assertEqual(list(takewhile(underten, [])), [])\r | |
791 | self.assertRaises(TypeError, takewhile)\r | |
792 | self.assertRaises(TypeError, takewhile, operator.pow)\r | |
793 | self.assertRaises(TypeError, takewhile, operator.pow, [(4,5)], 'extra')\r | |
794 | self.assertRaises(TypeError, takewhile(10, [(4,5)]).next)\r | |
795 | self.assertRaises(ValueError, takewhile(errfunc, [(4,5)]).next)\r | |
796 | t = takewhile(bool, [1, 1, 1, 0, 0, 0])\r | |
797 | self.assertEqual(list(t), [1, 1, 1])\r | |
798 | self.assertRaises(StopIteration, t.next)\r | |
799 | \r | |
800 | def test_dropwhile(self):\r | |
801 | data = [1, 3, 5, 20, 2, 4, 6, 8]\r | |
802 | underten = lambda x: x<10\r | |
803 | self.assertEqual(list(dropwhile(underten, data)), [20, 2, 4, 6, 8])\r | |
804 | self.assertEqual(list(dropwhile(underten, [])), [])\r | |
805 | self.assertRaises(TypeError, dropwhile)\r | |
806 | self.assertRaises(TypeError, dropwhile, operator.pow)\r | |
807 | self.assertRaises(TypeError, dropwhile, operator.pow, [(4,5)], 'extra')\r | |
808 | self.assertRaises(TypeError, dropwhile(10, [(4,5)]).next)\r | |
809 | self.assertRaises(ValueError, dropwhile(errfunc, [(4,5)]).next)\r | |
810 | \r | |
811 | def test_tee(self):\r | |
812 | n = 200\r | |
813 | def irange(n):\r | |
814 | for i in xrange(n):\r | |
815 | yield i\r | |
816 | \r | |
817 | a, b = tee([]) # test empty iterator\r | |
818 | self.assertEqual(list(a), [])\r | |
819 | self.assertEqual(list(b), [])\r | |
820 | \r | |
821 | a, b = tee(irange(n)) # test 100% interleaved\r | |
822 | self.assertEqual(zip(a,b), zip(range(n),range(n)))\r | |
823 | \r | |
824 | a, b = tee(irange(n)) # test 0% interleaved\r | |
825 | self.assertEqual(list(a), range(n))\r | |
826 | self.assertEqual(list(b), range(n))\r | |
827 | \r | |
828 | a, b = tee(irange(n)) # test dealloc of leading iterator\r | |
829 | for i in xrange(100):\r | |
830 | self.assertEqual(a.next(), i)\r | |
831 | del a\r | |
832 | self.assertEqual(list(b), range(n))\r | |
833 | \r | |
834 | a, b = tee(irange(n)) # test dealloc of trailing iterator\r | |
835 | for i in xrange(100):\r | |
836 | self.assertEqual(a.next(), i)\r | |
837 | del b\r | |
838 | self.assertEqual(list(a), range(100, n))\r | |
839 | \r | |
840 | for j in xrange(5): # test randomly interleaved\r | |
841 | order = [0]*n + [1]*n\r | |
842 | random.shuffle(order)\r | |
843 | lists = ([], [])\r | |
844 | its = tee(irange(n))\r | |
845 | for i in order:\r | |
846 | value = its[i].next()\r | |
847 | lists[i].append(value)\r | |
848 | self.assertEqual(lists[0], range(n))\r | |
849 | self.assertEqual(lists[1], range(n))\r | |
850 | \r | |
851 | # test argument format checking\r | |
852 | self.assertRaises(TypeError, tee)\r | |
853 | self.assertRaises(TypeError, tee, 3)\r | |
854 | self.assertRaises(TypeError, tee, [1,2], 'x')\r | |
855 | self.assertRaises(TypeError, tee, [1,2], 3, 'x')\r | |
856 | \r | |
857 | # tee object should be instantiable\r | |
858 | a, b = tee('abc')\r | |
859 | c = type(a)('def')\r | |
860 | self.assertEqual(list(c), list('def'))\r | |
861 | \r | |
862 | # test long-lagged and multi-way split\r | |
863 | a, b, c = tee(xrange(2000), 3)\r | |
864 | for i in xrange(100):\r | |
865 | self.assertEqual(a.next(), i)\r | |
866 | self.assertEqual(list(b), range(2000))\r | |
867 | self.assertEqual([c.next(), c.next()], range(2))\r | |
868 | self.assertEqual(list(a), range(100,2000))\r | |
869 | self.assertEqual(list(c), range(2,2000))\r | |
870 | \r | |
871 | # test values of n\r | |
872 | self.assertRaises(TypeError, tee, 'abc', 'invalid')\r | |
873 | self.assertRaises(ValueError, tee, [], -1)\r | |
874 | for n in xrange(5):\r | |
875 | result = tee('abc', n)\r | |
876 | self.assertEqual(type(result), tuple)\r | |
877 | self.assertEqual(len(result), n)\r | |
878 | self.assertEqual(map(list, result), [list('abc')]*n)\r | |
879 | \r | |
880 | # tee pass-through to copyable iterator\r | |
881 | a, b = tee('abc')\r | |
882 | c, d = tee(a)\r | |
883 | self.assertTrue(a is c)\r | |
884 | \r | |
885 | # test tee_new\r | |
886 | t1, t2 = tee('abc')\r | |
887 | tnew = type(t1)\r | |
888 | self.assertRaises(TypeError, tnew)\r | |
889 | self.assertRaises(TypeError, tnew, 10)\r | |
890 | t3 = tnew(t1)\r | |
891 | self.assertTrue(list(t1) == list(t2) == list(t3) == list('abc'))\r | |
892 | \r | |
893 | # test that tee objects are weak referencable\r | |
894 | a, b = tee(xrange(10))\r | |
895 | p = proxy(a)\r | |
896 | self.assertEqual(getattr(p, '__class__'), type(b))\r | |
897 | del a\r | |
898 | self.assertRaises(ReferenceError, getattr, p, '__class__')\r | |
899 | \r | |
900 | def test_StopIteration(self):\r | |
901 | self.assertRaises(StopIteration, izip().next)\r | |
902 | \r | |
903 | for f in (chain, cycle, izip, groupby):\r | |
904 | self.assertRaises(StopIteration, f([]).next)\r | |
905 | self.assertRaises(StopIteration, f(StopNow()).next)\r | |
906 | \r | |
907 | self.assertRaises(StopIteration, islice([], None).next)\r | |
908 | self.assertRaises(StopIteration, islice(StopNow(), None).next)\r | |
909 | \r | |
910 | p, q = tee([])\r | |
911 | self.assertRaises(StopIteration, p.next)\r | |
912 | self.assertRaises(StopIteration, q.next)\r | |
913 | p, q = tee(StopNow())\r | |
914 | self.assertRaises(StopIteration, p.next)\r | |
915 | self.assertRaises(StopIteration, q.next)\r | |
916 | \r | |
917 | self.assertRaises(StopIteration, repeat(None, 0).next)\r | |
918 | \r | |
919 | for f in (ifilter, ifilterfalse, imap, takewhile, dropwhile, starmap):\r | |
920 | self.assertRaises(StopIteration, f(lambda x:x, []).next)\r | |
921 | self.assertRaises(StopIteration, f(lambda x:x, StopNow()).next)\r | |
922 | \r | |
923 | class TestExamples(unittest.TestCase):\r | |
924 | \r | |
925 | def test_chain(self):\r | |
926 | self.assertEqual(''.join(chain('ABC', 'DEF')), 'ABCDEF')\r | |
927 | \r | |
928 | def test_chain_from_iterable(self):\r | |
929 | self.assertEqual(''.join(chain.from_iterable(['ABC', 'DEF'])), 'ABCDEF')\r | |
930 | \r | |
931 | def test_combinations(self):\r | |
932 | self.assertEqual(list(combinations('ABCD', 2)),\r | |
933 | [('A','B'), ('A','C'), ('A','D'), ('B','C'), ('B','D'), ('C','D')])\r | |
934 | self.assertEqual(list(combinations(range(4), 3)),\r | |
935 | [(0,1,2), (0,1,3), (0,2,3), (1,2,3)])\r | |
936 | \r | |
937 | def test_combinations_with_replacement(self):\r | |
938 | self.assertEqual(list(combinations_with_replacement('ABC', 2)),\r | |
939 | [('A','A'), ('A','B'), ('A','C'), ('B','B'), ('B','C'), ('C','C')])\r | |
940 | \r | |
941 | def test_compress(self):\r | |
942 | self.assertEqual(list(compress('ABCDEF', [1,0,1,0,1,1])), list('ACEF'))\r | |
943 | \r | |
944 | def test_count(self):\r | |
945 | self.assertEqual(list(islice(count(10), 5)), [10, 11, 12, 13, 14])\r | |
946 | \r | |
947 | def test_cycle(self):\r | |
948 | self.assertEqual(list(islice(cycle('ABCD'), 12)), list('ABCDABCDABCD'))\r | |
949 | \r | |
950 | def test_dropwhile(self):\r | |
951 | self.assertEqual(list(dropwhile(lambda x: x<5, [1,4,6,4,1])), [6,4,1])\r | |
952 | \r | |
953 | def test_groupby(self):\r | |
954 | self.assertEqual([k for k, g in groupby('AAAABBBCCDAABBB')],\r | |
955 | list('ABCDAB'))\r | |
956 | self.assertEqual([(list(g)) for k, g in groupby('AAAABBBCCD')],\r | |
957 | [list('AAAA'), list('BBB'), list('CC'), list('D')])\r | |
958 | \r | |
959 | def test_ifilter(self):\r | |
960 | self.assertEqual(list(ifilter(lambda x: x%2, range(10))), [1,3,5,7,9])\r | |
961 | \r | |
962 | def test_ifilterfalse(self):\r | |
963 | self.assertEqual(list(ifilterfalse(lambda x: x%2, range(10))), [0,2,4,6,8])\r | |
964 | \r | |
965 | def test_imap(self):\r | |
966 | self.assertEqual(list(imap(pow, (2,3,10), (5,2,3))), [32, 9, 1000])\r | |
967 | \r | |
968 | def test_islice(self):\r | |
969 | self.assertEqual(list(islice('ABCDEFG', 2)), list('AB'))\r | |
970 | self.assertEqual(list(islice('ABCDEFG', 2, 4)), list('CD'))\r | |
971 | self.assertEqual(list(islice('ABCDEFG', 2, None)), list('CDEFG'))\r | |
972 | self.assertEqual(list(islice('ABCDEFG', 0, None, 2)), list('ACEG'))\r | |
973 | \r | |
974 | def test_izip(self):\r | |
975 | self.assertEqual(list(izip('ABCD', 'xy')), [('A', 'x'), ('B', 'y')])\r | |
976 | \r | |
977 | def test_izip_longest(self):\r | |
978 | self.assertEqual(list(izip_longest('ABCD', 'xy', fillvalue='-')),\r | |
979 | [('A', 'x'), ('B', 'y'), ('C', '-'), ('D', '-')])\r | |
980 | \r | |
981 | def test_permutations(self):\r | |
982 | self.assertEqual(list(permutations('ABCD', 2)),\r | |
983 | map(tuple, 'AB AC AD BA BC BD CA CB CD DA DB DC'.split()))\r | |
984 | self.assertEqual(list(permutations(range(3))),\r | |
985 | [(0,1,2), (0,2,1), (1,0,2), (1,2,0), (2,0,1), (2,1,0)])\r | |
986 | \r | |
987 | def test_product(self):\r | |
988 | self.assertEqual(list(product('ABCD', 'xy')),\r | |
989 | map(tuple, 'Ax Ay Bx By Cx Cy Dx Dy'.split()))\r | |
990 | self.assertEqual(list(product(range(2), repeat=3)),\r | |
991 | [(0,0,0), (0,0,1), (0,1,0), (0,1,1),\r | |
992 | (1,0,0), (1,0,1), (1,1,0), (1,1,1)])\r | |
993 | \r | |
994 | def test_repeat(self):\r | |
995 | self.assertEqual(list(repeat(10, 3)), [10, 10, 10])\r | |
996 | \r | |
997 | def test_stapmap(self):\r | |
998 | self.assertEqual(list(starmap(pow, [(2,5), (3,2), (10,3)])),\r | |
999 | [32, 9, 1000])\r | |
1000 | \r | |
1001 | def test_takewhile(self):\r | |
1002 | self.assertEqual(list(takewhile(lambda x: x<5, [1,4,6,4,1])), [1,4])\r | |
1003 | \r | |
1004 | \r | |
1005 | class TestGC(unittest.TestCase):\r | |
1006 | \r | |
1007 | def makecycle(self, iterator, container):\r | |
1008 | container.append(iterator)\r | |
1009 | iterator.next()\r | |
1010 | del container, iterator\r | |
1011 | \r | |
1012 | def test_chain(self):\r | |
1013 | a = []\r | |
1014 | self.makecycle(chain(a), a)\r | |
1015 | \r | |
1016 | def test_chain_from_iterable(self):\r | |
1017 | a = []\r | |
1018 | self.makecycle(chain.from_iterable([a]), a)\r | |
1019 | \r | |
1020 | def test_combinations(self):\r | |
1021 | a = []\r | |
1022 | self.makecycle(combinations([1,2,a,3], 3), a)\r | |
1023 | \r | |
1024 | def test_combinations_with_replacement(self):\r | |
1025 | a = []\r | |
1026 | self.makecycle(combinations_with_replacement([1,2,a,3], 3), a)\r | |
1027 | \r | |
1028 | def test_compress(self):\r | |
1029 | a = []\r | |
1030 | self.makecycle(compress('ABCDEF', [1,0,1,0,1,0]), a)\r | |
1031 | \r | |
1032 | def test_count(self):\r | |
1033 | a = []\r | |
1034 | Int = type('Int', (int,), dict(x=a))\r | |
1035 | self.makecycle(count(Int(0), Int(1)), a)\r | |
1036 | \r | |
1037 | def test_cycle(self):\r | |
1038 | a = []\r | |
1039 | self.makecycle(cycle([a]*2), a)\r | |
1040 | \r | |
1041 | def test_dropwhile(self):\r | |
1042 | a = []\r | |
1043 | self.makecycle(dropwhile(bool, [0, a, a]), a)\r | |
1044 | \r | |
1045 | def test_groupby(self):\r | |
1046 | a = []\r | |
1047 | self.makecycle(groupby([a]*2, lambda x:x), a)\r | |
1048 | \r | |
1049 | def test_issue2246(self):\r | |
1050 | # Issue 2246 -- the _grouper iterator was not included in GC\r | |
1051 | n = 10\r | |
1052 | keyfunc = lambda x: x\r | |
1053 | for i, j in groupby(xrange(n), key=keyfunc):\r | |
1054 | keyfunc.__dict__.setdefault('x',[]).append(j)\r | |
1055 | \r | |
1056 | def test_ifilter(self):\r | |
1057 | a = []\r | |
1058 | self.makecycle(ifilter(lambda x:True, [a]*2), a)\r | |
1059 | \r | |
1060 | def test_ifilterfalse(self):\r | |
1061 | a = []\r | |
1062 | self.makecycle(ifilterfalse(lambda x:False, a), a)\r | |
1063 | \r | |
1064 | def test_izip(self):\r | |
1065 | a = []\r | |
1066 | self.makecycle(izip([a]*2, [a]*3), a)\r | |
1067 | \r | |
1068 | def test_izip_longest(self):\r | |
1069 | a = []\r | |
1070 | self.makecycle(izip_longest([a]*2, [a]*3), a)\r | |
1071 | b = [a, None]\r | |
1072 | self.makecycle(izip_longest([a]*2, [a]*3, fillvalue=b), a)\r | |
1073 | \r | |
1074 | def test_imap(self):\r | |
1075 | a = []\r | |
1076 | self.makecycle(imap(lambda x:x, [a]*2), a)\r | |
1077 | \r | |
1078 | def test_islice(self):\r | |
1079 | a = []\r | |
1080 | self.makecycle(islice([a]*2, None), a)\r | |
1081 | \r | |
1082 | def test_permutations(self):\r | |
1083 | a = []\r | |
1084 | self.makecycle(permutations([1,2,a,3], 3), a)\r | |
1085 | \r | |
1086 | def test_product(self):\r | |
1087 | a = []\r | |
1088 | self.makecycle(product([1,2,a,3], repeat=3), a)\r | |
1089 | \r | |
1090 | def test_repeat(self):\r | |
1091 | a = []\r | |
1092 | self.makecycle(repeat(a), a)\r | |
1093 | \r | |
1094 | def test_starmap(self):\r | |
1095 | a = []\r | |
1096 | self.makecycle(starmap(lambda *t: t, [(a,a)]*2), a)\r | |
1097 | \r | |
1098 | def test_takewhile(self):\r | |
1099 | a = []\r | |
1100 | self.makecycle(takewhile(bool, [1, 0, a, a]), a)\r | |
1101 | \r | |
1102 | def R(seqn):\r | |
1103 | 'Regular generator'\r | |
1104 | for i in seqn:\r | |
1105 | yield i\r | |
1106 | \r | |
1107 | class G:\r | |
1108 | 'Sequence using __getitem__'\r | |
1109 | def __init__(self, seqn):\r | |
1110 | self.seqn = seqn\r | |
1111 | def __getitem__(self, i):\r | |
1112 | return self.seqn[i]\r | |
1113 | \r | |
1114 | class I:\r | |
1115 | 'Sequence using iterator protocol'\r | |
1116 | def __init__(self, seqn):\r | |
1117 | self.seqn = seqn\r | |
1118 | self.i = 0\r | |
1119 | def __iter__(self):\r | |
1120 | return self\r | |
1121 | def next(self):\r | |
1122 | if self.i >= len(self.seqn): raise StopIteration\r | |
1123 | v = self.seqn[self.i]\r | |
1124 | self.i += 1\r | |
1125 | return v\r | |
1126 | \r | |
1127 | class Ig:\r | |
1128 | 'Sequence using iterator protocol defined with a generator'\r | |
1129 | def __init__(self, seqn):\r | |
1130 | self.seqn = seqn\r | |
1131 | self.i = 0\r | |
1132 | def __iter__(self):\r | |
1133 | for val in self.seqn:\r | |
1134 | yield val\r | |
1135 | \r | |
1136 | class X:\r | |
1137 | 'Missing __getitem__ and __iter__'\r | |
1138 | def __init__(self, seqn):\r | |
1139 | self.seqn = seqn\r | |
1140 | self.i = 0\r | |
1141 | def next(self):\r | |
1142 | if self.i >= len(self.seqn): raise StopIteration\r | |
1143 | v = self.seqn[self.i]\r | |
1144 | self.i += 1\r | |
1145 | return v\r | |
1146 | \r | |
1147 | class N:\r | |
1148 | 'Iterator missing next()'\r | |
1149 | def __init__(self, seqn):\r | |
1150 | self.seqn = seqn\r | |
1151 | self.i = 0\r | |
1152 | def __iter__(self):\r | |
1153 | return self\r | |
1154 | \r | |
1155 | class E:\r | |
1156 | 'Test propagation of exceptions'\r | |
1157 | def __init__(self, seqn):\r | |
1158 | self.seqn = seqn\r | |
1159 | self.i = 0\r | |
1160 | def __iter__(self):\r | |
1161 | return self\r | |
1162 | def next(self):\r | |
1163 | 3 // 0\r | |
1164 | \r | |
1165 | class S:\r | |
1166 | 'Test immediate stop'\r | |
1167 | def __init__(self, seqn):\r | |
1168 | pass\r | |
1169 | def __iter__(self):\r | |
1170 | return self\r | |
1171 | def next(self):\r | |
1172 | raise StopIteration\r | |
1173 | \r | |
1174 | def L(seqn):\r | |
1175 | 'Test multiple tiers of iterators'\r | |
1176 | return chain(imap(lambda x:x, R(Ig(G(seqn)))))\r | |
1177 | \r | |
1178 | \r | |
1179 | class TestVariousIteratorArgs(unittest.TestCase):\r | |
1180 | \r | |
1181 | def test_chain(self):\r | |
1182 | for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):\r | |
1183 | for g in (G, I, Ig, S, L, R):\r | |
1184 | self.assertEqual(list(chain(g(s))), list(g(s)))\r | |
1185 | self.assertEqual(list(chain(g(s), g(s))), list(g(s))+list(g(s)))\r | |
1186 | self.assertRaises(TypeError, list, chain(X(s)))\r | |
1187 | self.assertRaises(TypeError, list, chain(N(s)))\r | |
1188 | self.assertRaises(ZeroDivisionError, list, chain(E(s)))\r | |
1189 | \r | |
1190 | def test_compress(self):\r | |
1191 | for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):\r | |
1192 | n = len(s)\r | |
1193 | for g in (G, I, Ig, S, L, R):\r | |
1194 | self.assertEqual(list(compress(g(s), repeat(1))), list(g(s)))\r | |
1195 | self.assertRaises(TypeError, compress, X(s), repeat(1))\r | |
1196 | self.assertRaises(TypeError, list, compress(N(s), repeat(1)))\r | |
1197 | self.assertRaises(ZeroDivisionError, list, compress(E(s), repeat(1)))\r | |
1198 | \r | |
1199 | def test_product(self):\r | |
1200 | for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):\r | |
1201 | self.assertRaises(TypeError, product, X(s))\r | |
1202 | self.assertRaises(TypeError, product, N(s))\r | |
1203 | self.assertRaises(ZeroDivisionError, product, E(s))\r | |
1204 | \r | |
1205 | def test_cycle(self):\r | |
1206 | for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):\r | |
1207 | for g in (G, I, Ig, S, L, R):\r | |
1208 | tgtlen = len(s) * 3\r | |
1209 | expected = list(g(s))*3\r | |
1210 | actual = list(islice(cycle(g(s)), tgtlen))\r | |
1211 | self.assertEqual(actual, expected)\r | |
1212 | self.assertRaises(TypeError, cycle, X(s))\r | |
1213 | self.assertRaises(TypeError, list, cycle(N(s)))\r | |
1214 | self.assertRaises(ZeroDivisionError, list, cycle(E(s)))\r | |
1215 | \r | |
1216 | def test_groupby(self):\r | |
1217 | for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):\r | |
1218 | for g in (G, I, Ig, S, L, R):\r | |
1219 | self.assertEqual([k for k, sb in groupby(g(s))], list(g(s)))\r | |
1220 | self.assertRaises(TypeError, groupby, X(s))\r | |
1221 | self.assertRaises(TypeError, list, groupby(N(s)))\r | |
1222 | self.assertRaises(ZeroDivisionError, list, groupby(E(s)))\r | |
1223 | \r | |
1224 | def test_ifilter(self):\r | |
1225 | for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):\r | |
1226 | for g in (G, I, Ig, S, L, R):\r | |
1227 | self.assertEqual(list(ifilter(isEven, g(s))), filter(isEven, g(s)))\r | |
1228 | self.assertRaises(TypeError, ifilter, isEven, X(s))\r | |
1229 | self.assertRaises(TypeError, list, ifilter(isEven, N(s)))\r | |
1230 | self.assertRaises(ZeroDivisionError, list, ifilter(isEven, E(s)))\r | |
1231 | \r | |
1232 | def test_ifilterfalse(self):\r | |
1233 | for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):\r | |
1234 | for g in (G, I, Ig, S, L, R):\r | |
1235 | self.assertEqual(list(ifilterfalse(isEven, g(s))), filter(isOdd, g(s)))\r | |
1236 | self.assertRaises(TypeError, ifilterfalse, isEven, X(s))\r | |
1237 | self.assertRaises(TypeError, list, ifilterfalse(isEven, N(s)))\r | |
1238 | self.assertRaises(ZeroDivisionError, list, ifilterfalse(isEven, E(s)))\r | |
1239 | \r | |
1240 | def test_izip(self):\r | |
1241 | for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):\r | |
1242 | for g in (G, I, Ig, S, L, R):\r | |
1243 | self.assertEqual(list(izip(g(s))), zip(g(s)))\r | |
1244 | self.assertEqual(list(izip(g(s), g(s))), zip(g(s), g(s)))\r | |
1245 | self.assertRaises(TypeError, izip, X(s))\r | |
1246 | self.assertRaises(TypeError, list, izip(N(s)))\r | |
1247 | self.assertRaises(ZeroDivisionError, list, izip(E(s)))\r | |
1248 | \r | |
1249 | def test_iziplongest(self):\r | |
1250 | for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):\r | |
1251 | for g in (G, I, Ig, S, L, R):\r | |
1252 | self.assertEqual(list(izip_longest(g(s))), zip(g(s)))\r | |
1253 | self.assertEqual(list(izip_longest(g(s), g(s))), zip(g(s), g(s)))\r | |
1254 | self.assertRaises(TypeError, izip_longest, X(s))\r | |
1255 | self.assertRaises(TypeError, list, izip_longest(N(s)))\r | |
1256 | self.assertRaises(ZeroDivisionError, list, izip_longest(E(s)))\r | |
1257 | \r | |
1258 | def test_imap(self):\r | |
1259 | for s in (range(10), range(0), range(100), (7,11), xrange(20,50,5)):\r | |
1260 | for g in (G, I, Ig, S, L, R):\r | |
1261 | self.assertEqual(list(imap(onearg, g(s))), map(onearg, g(s)))\r | |
1262 | self.assertEqual(list(imap(operator.pow, g(s), g(s))), map(operator.pow, g(s), g(s)))\r | |
1263 | self.assertRaises(TypeError, imap, onearg, X(s))\r | |
1264 | self.assertRaises(TypeError, list, imap(onearg, N(s)))\r | |
1265 | self.assertRaises(ZeroDivisionError, list, imap(onearg, E(s)))\r | |
1266 | \r | |
1267 | def test_islice(self):\r | |
1268 | for s in ("12345", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):\r | |
1269 | for g in (G, I, Ig, S, L, R):\r | |
1270 | self.assertEqual(list(islice(g(s),1,None,2)), list(g(s))[1::2])\r | |
1271 | self.assertRaises(TypeError, islice, X(s), 10)\r | |
1272 | self.assertRaises(TypeError, list, islice(N(s), 10))\r | |
1273 | self.assertRaises(ZeroDivisionError, list, islice(E(s), 10))\r | |
1274 | \r | |
1275 | def test_starmap(self):\r | |
1276 | for s in (range(10), range(0), range(100), (7,11), xrange(20,50,5)):\r | |
1277 | for g in (G, I, Ig, S, L, R):\r | |
1278 | ss = zip(s, s)\r | |
1279 | self.assertEqual(list(starmap(operator.pow, g(ss))), map(operator.pow, g(s), g(s)))\r | |
1280 | self.assertRaises(TypeError, starmap, operator.pow, X(ss))\r | |
1281 | self.assertRaises(TypeError, list, starmap(operator.pow, N(ss)))\r | |
1282 | self.assertRaises(ZeroDivisionError, list, starmap(operator.pow, E(ss)))\r | |
1283 | \r | |
1284 | def test_takewhile(self):\r | |
1285 | for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):\r | |
1286 | for g in (G, I, Ig, S, L, R):\r | |
1287 | tgt = []\r | |
1288 | for elem in g(s):\r | |
1289 | if not isEven(elem): break\r | |
1290 | tgt.append(elem)\r | |
1291 | self.assertEqual(list(takewhile(isEven, g(s))), tgt)\r | |
1292 | self.assertRaises(TypeError, takewhile, isEven, X(s))\r | |
1293 | self.assertRaises(TypeError, list, takewhile(isEven, N(s)))\r | |
1294 | self.assertRaises(ZeroDivisionError, list, takewhile(isEven, E(s)))\r | |
1295 | \r | |
1296 | def test_dropwhile(self):\r | |
1297 | for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):\r | |
1298 | for g in (G, I, Ig, S, L, R):\r | |
1299 | tgt = []\r | |
1300 | for elem in g(s):\r | |
1301 | if not tgt and isOdd(elem): continue\r | |
1302 | tgt.append(elem)\r | |
1303 | self.assertEqual(list(dropwhile(isOdd, g(s))), tgt)\r | |
1304 | self.assertRaises(TypeError, dropwhile, isOdd, X(s))\r | |
1305 | self.assertRaises(TypeError, list, dropwhile(isOdd, N(s)))\r | |
1306 | self.assertRaises(ZeroDivisionError, list, dropwhile(isOdd, E(s)))\r | |
1307 | \r | |
1308 | def test_tee(self):\r | |
1309 | for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):\r | |
1310 | for g in (G, I, Ig, S, L, R):\r | |
1311 | it1, it2 = tee(g(s))\r | |
1312 | self.assertEqual(list(it1), list(g(s)))\r | |
1313 | self.assertEqual(list(it2), list(g(s)))\r | |
1314 | self.assertRaises(TypeError, tee, X(s))\r | |
1315 | self.assertRaises(TypeError, list, tee(N(s))[0])\r | |
1316 | self.assertRaises(ZeroDivisionError, list, tee(E(s))[0])\r | |
1317 | \r | |
1318 | class LengthTransparency(unittest.TestCase):\r | |
1319 | \r | |
1320 | def test_repeat(self):\r | |
1321 | from test.test_iterlen import len\r | |
1322 | self.assertEqual(len(repeat(None, 50)), 50)\r | |
1323 | self.assertRaises(TypeError, len, repeat(None))\r | |
1324 | \r | |
1325 | class RegressionTests(unittest.TestCase):\r | |
1326 | \r | |
1327 | def test_sf_793826(self):\r | |
1328 | # Fix Armin Rigo's successful efforts to wreak havoc\r | |
1329 | \r | |
1330 | def mutatingtuple(tuple1, f, tuple2):\r | |
1331 | # this builds a tuple t which is a copy of tuple1,\r | |
1332 | # then calls f(t), then mutates t to be equal to tuple2\r | |
1333 | # (needs len(tuple1) == len(tuple2)).\r | |
1334 | def g(value, first=[1]):\r | |
1335 | if first:\r | |
1336 | del first[:]\r | |
1337 | f(z.next())\r | |
1338 | return value\r | |
1339 | items = list(tuple2)\r | |
1340 | items[1:1] = list(tuple1)\r | |
1341 | gen = imap(g, items)\r | |
1342 | z = izip(*[gen]*len(tuple1))\r | |
1343 | z.next()\r | |
1344 | \r | |
1345 | def f(t):\r | |
1346 | global T\r | |
1347 | T = t\r | |
1348 | first[:] = list(T)\r | |
1349 | \r | |
1350 | first = []\r | |
1351 | mutatingtuple((1,2,3), f, (4,5,6))\r | |
1352 | second = list(T)\r | |
1353 | self.assertEqual(first, second)\r | |
1354 | \r | |
1355 | \r | |
1356 | def test_sf_950057(self):\r | |
1357 | # Make sure that chain() and cycle() catch exceptions immediately\r | |
1358 | # rather than when shifting between input sources\r | |
1359 | \r | |
1360 | def gen1():\r | |
1361 | hist.append(0)\r | |
1362 | yield 1\r | |
1363 | hist.append(1)\r | |
1364 | raise AssertionError\r | |
1365 | hist.append(2)\r | |
1366 | \r | |
1367 | def gen2(x):\r | |
1368 | hist.append(3)\r | |
1369 | yield 2\r | |
1370 | hist.append(4)\r | |
1371 | if x:\r | |
1372 | raise StopIteration\r | |
1373 | \r | |
1374 | hist = []\r | |
1375 | self.assertRaises(AssertionError, list, chain(gen1(), gen2(False)))\r | |
1376 | self.assertEqual(hist, [0,1])\r | |
1377 | \r | |
1378 | hist = []\r | |
1379 | self.assertRaises(AssertionError, list, chain(gen1(), gen2(True)))\r | |
1380 | self.assertEqual(hist, [0,1])\r | |
1381 | \r | |
1382 | hist = []\r | |
1383 | self.assertRaises(AssertionError, list, cycle(gen1()))\r | |
1384 | self.assertEqual(hist, [0,1])\r | |
1385 | \r | |
1386 | class SubclassWithKwargsTest(unittest.TestCase):\r | |
1387 | def test_keywords_in_subclass(self):\r | |
1388 | # count is not subclassable...\r | |
1389 | for cls in (repeat, izip, ifilter, ifilterfalse, chain, imap,\r | |
1390 | starmap, islice, takewhile, dropwhile, cycle, compress):\r | |
1391 | class Subclass(cls):\r | |
1392 | def __init__(self, newarg=None, *args):\r | |
1393 | cls.__init__(self, *args)\r | |
1394 | try:\r | |
1395 | Subclass(newarg=1)\r | |
1396 | except TypeError, err:\r | |
1397 | # we expect type errors because of wrong argument count\r | |
1398 | self.assertNotIn("does not take keyword arguments", err.args[0])\r | |
1399 | \r | |
1400 | \r | |
1401 | libreftest = """ Doctest for examples in the library reference: libitertools.tex\r | |
1402 | \r | |
1403 | \r | |
1404 | >>> amounts = [120.15, 764.05, 823.14]\r | |
1405 | >>> for checknum, amount in izip(count(1200), amounts):\r | |
1406 | ... print 'Check %d is for $%.2f' % (checknum, amount)\r | |
1407 | ...\r | |
1408 | Check 1200 is for $120.15\r | |
1409 | Check 1201 is for $764.05\r | |
1410 | Check 1202 is for $823.14\r | |
1411 | \r | |
1412 | >>> import operator\r | |
1413 | >>> for cube in imap(operator.pow, xrange(1,4), repeat(3)):\r | |
1414 | ... print cube\r | |
1415 | ...\r | |
1416 | 1\r | |
1417 | 8\r | |
1418 | 27\r | |
1419 | \r | |
1420 | >>> reportlines = ['EuroPython', 'Roster', '', 'alex', '', 'laura', '', 'martin', '', 'walter', '', 'samuele']\r | |
1421 | >>> for name in islice(reportlines, 3, None, 2):\r | |
1422 | ... print name.title()\r | |
1423 | ...\r | |
1424 | Alex\r | |
1425 | Laura\r | |
1426 | Martin\r | |
1427 | Walter\r | |
1428 | Samuele\r | |
1429 | \r | |
1430 | >>> from operator import itemgetter\r | |
1431 | >>> d = dict(a=1, b=2, c=1, d=2, e=1, f=2, g=3)\r | |
1432 | >>> di = sorted(sorted(d.iteritems()), key=itemgetter(1))\r | |
1433 | >>> for k, g in groupby(di, itemgetter(1)):\r | |
1434 | ... print k, map(itemgetter(0), g)\r | |
1435 | ...\r | |
1436 | 1 ['a', 'c', 'e']\r | |
1437 | 2 ['b', 'd', 'f']\r | |
1438 | 3 ['g']\r | |
1439 | \r | |
1440 | # Find runs of consecutive numbers using groupby. The key to the solution\r | |
1441 | # is differencing with a range so that consecutive numbers all appear in\r | |
1442 | # same group.\r | |
1443 | >>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28]\r | |
1444 | >>> for k, g in groupby(enumerate(data), lambda t:t[0]-t[1]):\r | |
1445 | ... print map(operator.itemgetter(1), g)\r | |
1446 | ...\r | |
1447 | [1]\r | |
1448 | [4, 5, 6]\r | |
1449 | [10]\r | |
1450 | [15, 16, 17, 18]\r | |
1451 | [22]\r | |
1452 | [25, 26, 27, 28]\r | |
1453 | \r | |
1454 | >>> def take(n, iterable):\r | |
1455 | ... "Return first n items of the iterable as a list"\r | |
1456 | ... return list(islice(iterable, n))\r | |
1457 | \r | |
1458 | >>> def enumerate(iterable, start=0):\r | |
1459 | ... return izip(count(start), iterable)\r | |
1460 | \r | |
1461 | >>> def tabulate(function, start=0):\r | |
1462 | ... "Return function(0), function(1), ..."\r | |
1463 | ... return imap(function, count(start))\r | |
1464 | \r | |
1465 | >>> def nth(iterable, n, default=None):\r | |
1466 | ... "Returns the nth item or a default value"\r | |
1467 | ... return next(islice(iterable, n, None), default)\r | |
1468 | \r | |
1469 | >>> def quantify(iterable, pred=bool):\r | |
1470 | ... "Count how many times the predicate is true"\r | |
1471 | ... return sum(imap(pred, iterable))\r | |
1472 | \r | |
1473 | >>> def padnone(iterable):\r | |
1474 | ... "Returns the sequence elements and then returns None indefinitely"\r | |
1475 | ... return chain(iterable, repeat(None))\r | |
1476 | \r | |
1477 | >>> def ncycles(iterable, n):\r | |
1478 | ... "Returns the sequence elements n times"\r | |
1479 | ... return chain(*repeat(iterable, n))\r | |
1480 | \r | |
1481 | >>> def dotproduct(vec1, vec2):\r | |
1482 | ... return sum(imap(operator.mul, vec1, vec2))\r | |
1483 | \r | |
1484 | >>> def flatten(listOfLists):\r | |
1485 | ... return list(chain.from_iterable(listOfLists))\r | |
1486 | \r | |
1487 | >>> def repeatfunc(func, times=None, *args):\r | |
1488 | ... "Repeat calls to func with specified arguments."\r | |
1489 | ... " Example: repeatfunc(random.random)"\r | |
1490 | ... if times is None:\r | |
1491 | ... return starmap(func, repeat(args))\r | |
1492 | ... else:\r | |
1493 | ... return starmap(func, repeat(args, times))\r | |
1494 | \r | |
1495 | >>> def pairwise(iterable):\r | |
1496 | ... "s -> (s0,s1), (s1,s2), (s2, s3), ..."\r | |
1497 | ... a, b = tee(iterable)\r | |
1498 | ... for elem in b:\r | |
1499 | ... break\r | |
1500 | ... return izip(a, b)\r | |
1501 | \r | |
1502 | >>> def grouper(n, iterable, fillvalue=None):\r | |
1503 | ... "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"\r | |
1504 | ... args = [iter(iterable)] * n\r | |
1505 | ... return izip_longest(fillvalue=fillvalue, *args)\r | |
1506 | \r | |
1507 | >>> def roundrobin(*iterables):\r | |
1508 | ... "roundrobin('ABC', 'D', 'EF') --> A D E B F C"\r | |
1509 | ... # Recipe credited to George Sakkis\r | |
1510 | ... pending = len(iterables)\r | |
1511 | ... nexts = cycle(iter(it).next for it in iterables)\r | |
1512 | ... while pending:\r | |
1513 | ... try:\r | |
1514 | ... for next in nexts:\r | |
1515 | ... yield next()\r | |
1516 | ... except StopIteration:\r | |
1517 | ... pending -= 1\r | |
1518 | ... nexts = cycle(islice(nexts, pending))\r | |
1519 | \r | |
1520 | >>> def powerset(iterable):\r | |
1521 | ... "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"\r | |
1522 | ... s = list(iterable)\r | |
1523 | ... return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))\r | |
1524 | \r | |
1525 | >>> def unique_everseen(iterable, key=None):\r | |
1526 | ... "List unique elements, preserving order. Remember all elements ever seen."\r | |
1527 | ... # unique_everseen('AAAABBBCCDAABBB') --> A B C D\r | |
1528 | ... # unique_everseen('ABBCcAD', str.lower) --> A B C D\r | |
1529 | ... seen = set()\r | |
1530 | ... seen_add = seen.add\r | |
1531 | ... if key is None:\r | |
1532 | ... for element in iterable:\r | |
1533 | ... if element not in seen:\r | |
1534 | ... seen_add(element)\r | |
1535 | ... yield element\r | |
1536 | ... else:\r | |
1537 | ... for element in iterable:\r | |
1538 | ... k = key(element)\r | |
1539 | ... if k not in seen:\r | |
1540 | ... seen_add(k)\r | |
1541 | ... yield element\r | |
1542 | \r | |
1543 | >>> def unique_justseen(iterable, key=None):\r | |
1544 | ... "List unique elements, preserving order. Remember only the element just seen."\r | |
1545 | ... # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B\r | |
1546 | ... # unique_justseen('ABBCcAD', str.lower) --> A B C A D\r | |
1547 | ... return imap(next, imap(itemgetter(1), groupby(iterable, key)))\r | |
1548 | \r | |
1549 | This is not part of the examples but it tests to make sure the definitions\r | |
1550 | perform as purported.\r | |
1551 | \r | |
1552 | >>> take(10, count())\r | |
1553 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\r | |
1554 | \r | |
1555 | >>> list(enumerate('abc'))\r | |
1556 | [(0, 'a'), (1, 'b'), (2, 'c')]\r | |
1557 | \r | |
1558 | >>> list(islice(tabulate(lambda x: 2*x), 4))\r | |
1559 | [0, 2, 4, 6]\r | |
1560 | \r | |
1561 | >>> nth('abcde', 3)\r | |
1562 | 'd'\r | |
1563 | \r | |
1564 | >>> nth('abcde', 9) is None\r | |
1565 | True\r | |
1566 | \r | |
1567 | >>> quantify(xrange(99), lambda x: x%2==0)\r | |
1568 | 50\r | |
1569 | \r | |
1570 | >>> a = [[1, 2, 3], [4, 5, 6]]\r | |
1571 | >>> flatten(a)\r | |
1572 | [1, 2, 3, 4, 5, 6]\r | |
1573 | \r | |
1574 | >>> list(repeatfunc(pow, 5, 2, 3))\r | |
1575 | [8, 8, 8, 8, 8]\r | |
1576 | \r | |
1577 | >>> import random\r | |
1578 | >>> take(5, imap(int, repeatfunc(random.random)))\r | |
1579 | [0, 0, 0, 0, 0]\r | |
1580 | \r | |
1581 | >>> list(pairwise('abcd'))\r | |
1582 | [('a', 'b'), ('b', 'c'), ('c', 'd')]\r | |
1583 | \r | |
1584 | >>> list(pairwise([]))\r | |
1585 | []\r | |
1586 | \r | |
1587 | >>> list(pairwise('a'))\r | |
1588 | []\r | |
1589 | \r | |
1590 | >>> list(islice(padnone('abc'), 0, 6))\r | |
1591 | ['a', 'b', 'c', None, None, None]\r | |
1592 | \r | |
1593 | >>> list(ncycles('abc', 3))\r | |
1594 | ['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c']\r | |
1595 | \r | |
1596 | >>> dotproduct([1,2,3], [4,5,6])\r | |
1597 | 32\r | |
1598 | \r | |
1599 | >>> list(grouper(3, 'abcdefg', 'x'))\r | |
1600 | [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'x', 'x')]\r | |
1601 | \r | |
1602 | >>> list(roundrobin('abc', 'd', 'ef'))\r | |
1603 | ['a', 'd', 'e', 'b', 'f', 'c']\r | |
1604 | \r | |
1605 | >>> list(powerset([1,2,3]))\r | |
1606 | [(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]\r | |
1607 | \r | |
1608 | >>> all(len(list(powerset(range(n)))) == 2**n for n in range(18))\r | |
1609 | True\r | |
1610 | \r | |
1611 | >>> list(powerset('abcde')) == sorted(sorted(set(powerset('abcde'))), key=len)\r | |
1612 | True\r | |
1613 | \r | |
1614 | >>> list(unique_everseen('AAAABBBCCDAABBB'))\r | |
1615 | ['A', 'B', 'C', 'D']\r | |
1616 | \r | |
1617 | >>> list(unique_everseen('ABBCcAD', str.lower))\r | |
1618 | ['A', 'B', 'C', 'D']\r | |
1619 | \r | |
1620 | >>> list(unique_justseen('AAAABBBCCDAABBB'))\r | |
1621 | ['A', 'B', 'C', 'D', 'A', 'B']\r | |
1622 | \r | |
1623 | >>> list(unique_justseen('ABBCcAD', str.lower))\r | |
1624 | ['A', 'B', 'C', 'A', 'D']\r | |
1625 | \r | |
1626 | """\r | |
1627 | \r | |
1628 | __test__ = {'libreftest' : libreftest}\r | |
1629 | \r | |
1630 | def test_main(verbose=None):\r | |
1631 | test_classes = (TestBasicOps, TestVariousIteratorArgs, TestGC,\r | |
1632 | RegressionTests, LengthTransparency,\r | |
1633 | SubclassWithKwargsTest, TestExamples)\r | |
1634 | test_support.run_unittest(*test_classes)\r | |
1635 | \r | |
1636 | # verify reference counting\r | |
1637 | if verbose and hasattr(sys, "gettotalrefcount"):\r | |
1638 | import gc\r | |
1639 | counts = [None] * 5\r | |
1640 | for i in xrange(len(counts)):\r | |
1641 | test_support.run_unittest(*test_classes)\r | |
1642 | gc.collect()\r | |
1643 | counts[i] = sys.gettotalrefcount()\r | |
1644 | print counts\r | |
1645 | \r | |
1646 | # doctest the examples in the library reference\r | |
1647 | test_support.run_doctest(sys.modules[__name__], verbose)\r | |
1648 | \r | |
1649 | if __name__ == "__main__":\r | |
1650 | test_main(verbose=True)\r |