python-2.5.2/win32/Lib/test/test_itertools.py
changeset 0 ae805ac0140d
equal deleted inserted replaced
-1:000000000000 0:ae805ac0140d
       
     1 import unittest
       
     2 from test import test_support
       
     3 from itertools import *
       
     4 from weakref import proxy
       
     5 import sys
       
     6 import operator
       
     7 import random
       
     8 maxsize = test_support.MAX_Py_ssize_t
       
     9 minsize = -maxsize-1
       
    10 
       
    11 def onearg(x):
       
    12     'Test function of one argument'
       
    13     return 2*x
       
    14 
       
    15 def errfunc(*args):
       
    16     'Test function that raises an error'
       
    17     raise ValueError
       
    18 
       
    19 def gen3():
       
    20     'Non-restartable source sequence'
       
    21     for i in (0, 1, 2):
       
    22         yield i
       
    23 
       
    24 def isEven(x):
       
    25     'Test predicate'
       
    26     return x%2==0
       
    27 
       
    28 def isOdd(x):
       
    29     'Test predicate'
       
    30     return x%2==1
       
    31 
       
    32 class StopNow:
       
    33     'Class emulating an empty iterable.'
       
    34     def __iter__(self):
       
    35         return self
       
    36     def next(self):
       
    37         raise StopIteration
       
    38 
       
    39 def take(n, seq):
       
    40     'Convenience function for partially consuming a long of infinite iterable'
       
    41     return list(islice(seq, n))
       
    42 
       
    43 class TestBasicOps(unittest.TestCase):
       
    44     def test_chain(self):
       
    45         self.assertEqual(list(chain('abc', 'def')), list('abcdef'))
       
    46         self.assertEqual(list(chain('abc')), list('abc'))
       
    47         self.assertEqual(list(chain('')), [])
       
    48         self.assertEqual(take(4, chain('abc', 'def')), list('abcd'))
       
    49         self.assertRaises(TypeError, chain, 2, 3)
       
    50 
       
    51     def test_count(self):
       
    52         self.assertEqual(zip('abc',count()), [('a', 0), ('b', 1), ('c', 2)])
       
    53         self.assertEqual(zip('abc',count(3)), [('a', 3), ('b', 4), ('c', 5)])
       
    54         self.assertEqual(take(2, zip('abc',count(3))), [('a', 3), ('b', 4)])
       
    55         self.assertRaises(TypeError, count, 2, 3)
       
    56         self.assertRaises(TypeError, count, 'a')
       
    57         self.assertRaises(OverflowError, list, islice(count(maxsize-5), 10))
       
    58         c = count(3)
       
    59         self.assertEqual(repr(c), 'count(3)')
       
    60         c.next()
       
    61         self.assertEqual(repr(c), 'count(4)')
       
    62         c = count(-9)
       
    63         self.assertEqual(repr(c), 'count(-9)')
       
    64         c.next()
       
    65         self.assertEqual(c.next(), -8)
       
    66 
       
    67     def test_cycle(self):
       
    68         self.assertEqual(take(10, cycle('abc')), list('abcabcabca'))
       
    69         self.assertEqual(list(cycle('')), [])
       
    70         self.assertRaises(TypeError, cycle)
       
    71         self.assertRaises(TypeError, cycle, 5)
       
    72         self.assertEqual(list(islice(cycle(gen3()),10)), [0,1,2,0,1,2,0,1,2,0])
       
    73 
       
    74     def test_groupby(self):
       
    75         # Check whether it accepts arguments correctly
       
    76         self.assertEqual([], list(groupby([])))
       
    77         self.assertEqual([], list(groupby([], key=id)))
       
    78         self.assertRaises(TypeError, list, groupby('abc', []))
       
    79         self.assertRaises(TypeError, groupby, None)
       
    80         self.assertRaises(TypeError, groupby, 'abc', lambda x:x, 10)
       
    81 
       
    82         # Check normal input
       
    83         s = [(0, 10, 20), (0, 11,21), (0,12,21), (1,13,21), (1,14,22),
       
    84              (2,15,22), (3,16,23), (3,17,23)]
       
    85         dup = []
       
    86         for k, g in groupby(s, lambda r:r[0]):
       
    87             for elem in g:
       
    88                 self.assertEqual(k, elem[0])
       
    89                 dup.append(elem)
       
    90         self.assertEqual(s, dup)
       
    91 
       
    92         # Check nested case
       
    93         dup = []
       
    94         for k, g in groupby(s, lambda r:r[0]):
       
    95             for ik, ig in groupby(g, lambda r:r[2]):
       
    96                 for elem in ig:
       
    97                     self.assertEqual(k, elem[0])
       
    98                     self.assertEqual(ik, elem[2])
       
    99                     dup.append(elem)
       
   100         self.assertEqual(s, dup)
       
   101 
       
   102         # Check case where inner iterator is not used
       
   103         keys = [k for k, g in groupby(s, lambda r:r[0])]
       
   104         expectedkeys = set([r[0] for r in s])
       
   105         self.assertEqual(set(keys), expectedkeys)
       
   106         self.assertEqual(len(keys), len(expectedkeys))
       
   107 
       
   108         # Exercise pipes and filters style
       
   109         s = 'abracadabra'
       
   110         # sort s | uniq
       
   111         r = [k for k, g in groupby(sorted(s))]
       
   112         self.assertEqual(r, ['a', 'b', 'c', 'd', 'r'])
       
   113         # sort s | uniq -d
       
   114         r = [k for k, g in groupby(sorted(s)) if list(islice(g,1,2))]
       
   115         self.assertEqual(r, ['a', 'b', 'r'])
       
   116         # sort s | uniq -c
       
   117         r = [(len(list(g)), k) for k, g in groupby(sorted(s))]
       
   118         self.assertEqual(r, [(5, 'a'), (2, 'b'), (1, 'c'), (1, 'd'), (2, 'r')])
       
   119         # sort s | uniq -c | sort -rn | head -3
       
   120         r = sorted([(len(list(g)) , k) for k, g in groupby(sorted(s))], reverse=True)[:3]
       
   121         self.assertEqual(r, [(5, 'a'), (2, 'r'), (2, 'b')])
       
   122 
       
   123         # iter.next failure
       
   124         class ExpectedError(Exception):
       
   125             pass
       
   126         def delayed_raise(n=0):
       
   127             for i in range(n):
       
   128                 yield 'yo'
       
   129             raise ExpectedError
       
   130         def gulp(iterable, keyp=None, func=list):
       
   131             return [func(g) for k, g in groupby(iterable, keyp)]
       
   132 
       
   133         # iter.next failure on outer object
       
   134         self.assertRaises(ExpectedError, gulp, delayed_raise(0))
       
   135         # iter.next failure on inner object
       
   136         self.assertRaises(ExpectedError, gulp, delayed_raise(1))
       
   137 
       
   138         # __cmp__ failure
       
   139         class DummyCmp:
       
   140             def __cmp__(self, dst):
       
   141                 raise ExpectedError
       
   142         s = [DummyCmp(), DummyCmp(), None]
       
   143 
       
   144         # __cmp__ failure on outer object
       
   145         self.assertRaises(ExpectedError, gulp, s, func=id)
       
   146         # __cmp__ failure on inner object
       
   147         self.assertRaises(ExpectedError, gulp, s)
       
   148 
       
   149         # keyfunc failure
       
   150         def keyfunc(obj):
       
   151             if keyfunc.skip > 0:
       
   152                 keyfunc.skip -= 1
       
   153                 return obj
       
   154             else:
       
   155                 raise ExpectedError
       
   156 
       
   157         # keyfunc failure on outer object
       
   158         keyfunc.skip = 0
       
   159         self.assertRaises(ExpectedError, gulp, [None], keyfunc)
       
   160         keyfunc.skip = 1
       
   161         self.assertRaises(ExpectedError, gulp, [None, None], keyfunc)
       
   162 
       
   163     def test_ifilter(self):
       
   164         self.assertEqual(list(ifilter(isEven, range(6))), [0,2,4])
       
   165         self.assertEqual(list(ifilter(None, [0,1,0,2,0])), [1,2])
       
   166         self.assertEqual(take(4, ifilter(isEven, count())), [0,2,4,6])
       
   167         self.assertRaises(TypeError, ifilter)
       
   168         self.assertRaises(TypeError, ifilter, lambda x:x)
       
   169         self.assertRaises(TypeError, ifilter, lambda x:x, range(6), 7)
       
   170         self.assertRaises(TypeError, ifilter, isEven, 3)
       
   171         self.assertRaises(TypeError, ifilter(range(6), range(6)).next)
       
   172 
       
   173     def test_ifilterfalse(self):
       
   174         self.assertEqual(list(ifilterfalse(isEven, range(6))), [1,3,5])
       
   175         self.assertEqual(list(ifilterfalse(None, [0,1,0,2,0])), [0,0,0])
       
   176         self.assertEqual(take(4, ifilterfalse(isEven, count())), [1,3,5,7])
       
   177         self.assertRaises(TypeError, ifilterfalse)
       
   178         self.assertRaises(TypeError, ifilterfalse, lambda x:x)
       
   179         self.assertRaises(TypeError, ifilterfalse, lambda x:x, range(6), 7)
       
   180         self.assertRaises(TypeError, ifilterfalse, isEven, 3)
       
   181         self.assertRaises(TypeError, ifilterfalse(range(6), range(6)).next)
       
   182 
       
   183     def test_izip(self):
       
   184         ans = [(x,y) for x, y in izip('abc',count())]
       
   185         self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)])
       
   186         self.assertEqual(list(izip('abc', range(6))), zip('abc', range(6)))
       
   187         self.assertEqual(list(izip('abcdef', range(3))), zip('abcdef', range(3)))
       
   188         self.assertEqual(take(3,izip('abcdef', count())), zip('abcdef', range(3)))
       
   189         self.assertEqual(list(izip('abcdef')), zip('abcdef'))
       
   190         self.assertEqual(list(izip()), zip())
       
   191         self.assertRaises(TypeError, izip, 3)
       
   192         self.assertRaises(TypeError, izip, range(3), 3)
       
   193         # Check tuple re-use (implementation detail)
       
   194         self.assertEqual([tuple(list(pair)) for pair in izip('abc', 'def')],
       
   195                          zip('abc', 'def'))
       
   196         self.assertEqual([pair for pair in izip('abc', 'def')],
       
   197                          zip('abc', 'def'))
       
   198         ids = map(id, izip('abc', 'def'))
       
   199         self.assertEqual(min(ids), max(ids))
       
   200         ids = map(id, list(izip('abc', 'def')))
       
   201         self.assertEqual(len(dict.fromkeys(ids)), len(ids))
       
   202 
       
   203     def test_repeat(self):
       
   204         self.assertEqual(zip(xrange(3),repeat('a')),
       
   205                          [(0, 'a'), (1, 'a'), (2, 'a')])
       
   206         self.assertEqual(list(repeat('a', 3)), ['a', 'a', 'a'])
       
   207         self.assertEqual(take(3, repeat('a')), ['a', 'a', 'a'])
       
   208         self.assertEqual(list(repeat('a', 0)), [])
       
   209         self.assertEqual(list(repeat('a', -3)), [])
       
   210         self.assertRaises(TypeError, repeat)
       
   211         self.assertRaises(TypeError, repeat, None, 3, 4)
       
   212         self.assertRaises(TypeError, repeat, None, 'a')
       
   213         r = repeat(1+0j)
       
   214         self.assertEqual(repr(r), 'repeat((1+0j))')
       
   215         r = repeat(1+0j, 5)
       
   216         self.assertEqual(repr(r), 'repeat((1+0j), 5)')
       
   217         list(r)
       
   218         self.assertEqual(repr(r), 'repeat((1+0j), 0)')
       
   219 
       
   220     def test_imap(self):
       
   221         self.assertEqual(list(imap(operator.pow, range(3), range(1,7))),
       
   222                          [0**1, 1**2, 2**3])
       
   223         self.assertEqual(list(imap(None, 'abc', range(5))),
       
   224                          [('a',0),('b',1),('c',2)])
       
   225         self.assertEqual(list(imap(None, 'abc', count())),
       
   226                          [('a',0),('b',1),('c',2)])
       
   227         self.assertEqual(take(2,imap(None, 'abc', count())),
       
   228                          [('a',0),('b',1)])
       
   229         self.assertEqual(list(imap(operator.pow, [])), [])
       
   230         self.assertRaises(TypeError, imap)
       
   231         self.assertRaises(TypeError, imap, operator.neg)
       
   232         self.assertRaises(TypeError, imap(10, range(5)).next)
       
   233         self.assertRaises(ValueError, imap(errfunc, [4], [5]).next)
       
   234         self.assertRaises(TypeError, imap(onearg, [4], [5]).next)
       
   235 
       
   236     def test_starmap(self):
       
   237         self.assertEqual(list(starmap(operator.pow, zip(range(3), range(1,7)))),
       
   238                          [0**1, 1**2, 2**3])
       
   239         self.assertEqual(take(3, starmap(operator.pow, izip(count(), count(1)))),
       
   240                          [0**1, 1**2, 2**3])
       
   241         self.assertEqual(list(starmap(operator.pow, [])), [])
       
   242         self.assertRaises(TypeError, list, starmap(operator.pow, [[4,5]]))
       
   243         self.assertRaises(TypeError, starmap)
       
   244         self.assertRaises(TypeError, starmap, operator.pow, [(4,5)], 'extra')
       
   245         self.assertRaises(TypeError, starmap(10, [(4,5)]).next)
       
   246         self.assertRaises(ValueError, starmap(errfunc, [(4,5)]).next)
       
   247         self.assertRaises(TypeError, starmap(onearg, [(4,5)]).next)
       
   248 
       
   249     def test_islice(self):
       
   250         for args in [          # islice(args) should agree with range(args)
       
   251                 (10, 20, 3),
       
   252                 (10, 3, 20),
       
   253                 (10, 20),
       
   254                 (10, 3),
       
   255                 (20,)
       
   256                 ]:
       
   257             self.assertEqual(list(islice(xrange(100), *args)), range(*args))
       
   258 
       
   259         for args, tgtargs in [  # Stop when seqn is exhausted
       
   260                 ((10, 110, 3), ((10, 100, 3))),
       
   261                 ((10, 110), ((10, 100))),
       
   262                 ((110,), (100,))
       
   263                 ]:
       
   264             self.assertEqual(list(islice(xrange(100), *args)), range(*tgtargs))
       
   265 
       
   266         # Test stop=None
       
   267         self.assertEqual(list(islice(xrange(10), None)), range(10))
       
   268         self.assertEqual(list(islice(xrange(10), None, None)), range(10))
       
   269         self.assertEqual(list(islice(xrange(10), None, None, None)), range(10))
       
   270         self.assertEqual(list(islice(xrange(10), 2, None)), range(2, 10))
       
   271         self.assertEqual(list(islice(xrange(10), 1, None, 2)), range(1, 10, 2))
       
   272 
       
   273         # Test number of items consumed     SF #1171417
       
   274         it = iter(range(10))
       
   275         self.assertEqual(list(islice(it, 3)), range(3))
       
   276         self.assertEqual(list(it), range(3, 10))
       
   277 
       
   278         # Test invalid arguments
       
   279         self.assertRaises(TypeError, islice, xrange(10))
       
   280         self.assertRaises(TypeError, islice, xrange(10), 1, 2, 3, 4)
       
   281         self.assertRaises(ValueError, islice, xrange(10), -5, 10, 1)
       
   282         self.assertRaises(ValueError, islice, xrange(10), 1, -5, -1)
       
   283         self.assertRaises(ValueError, islice, xrange(10), 1, 10, -1)
       
   284         self.assertRaises(ValueError, islice, xrange(10), 1, 10, 0)
       
   285         self.assertRaises(ValueError, islice, xrange(10), 'a')
       
   286         self.assertRaises(ValueError, islice, xrange(10), 'a', 1)
       
   287         self.assertRaises(ValueError, islice, xrange(10), 1, 'a')
       
   288         self.assertRaises(ValueError, islice, xrange(10), 'a', 1, 1)
       
   289         self.assertRaises(ValueError, islice, xrange(10), 1, 'a', 1)
       
   290         self.assertEqual(len(list(islice(count(), 1, 10, maxsize))), 1)
       
   291 
       
   292     def test_takewhile(self):
       
   293         data = [1, 3, 5, 20, 2, 4, 6, 8]
       
   294         underten = lambda x: x<10
       
   295         self.assertEqual(list(takewhile(underten, data)), [1, 3, 5])
       
   296         self.assertEqual(list(takewhile(underten, [])), [])
       
   297         self.assertRaises(TypeError, takewhile)
       
   298         self.assertRaises(TypeError, takewhile, operator.pow)
       
   299         self.assertRaises(TypeError, takewhile, operator.pow, [(4,5)], 'extra')
       
   300         self.assertRaises(TypeError, takewhile(10, [(4,5)]).next)
       
   301         self.assertRaises(ValueError, takewhile(errfunc, [(4,5)]).next)
       
   302         t = takewhile(bool, [1, 1, 1, 0, 0, 0])
       
   303         self.assertEqual(list(t), [1, 1, 1])
       
   304         self.assertRaises(StopIteration, t.next)
       
   305 
       
   306     def test_dropwhile(self):
       
   307         data = [1, 3, 5, 20, 2, 4, 6, 8]
       
   308         underten = lambda x: x<10
       
   309         self.assertEqual(list(dropwhile(underten, data)), [20, 2, 4, 6, 8])
       
   310         self.assertEqual(list(dropwhile(underten, [])), [])
       
   311         self.assertRaises(TypeError, dropwhile)
       
   312         self.assertRaises(TypeError, dropwhile, operator.pow)
       
   313         self.assertRaises(TypeError, dropwhile, operator.pow, [(4,5)], 'extra')
       
   314         self.assertRaises(TypeError, dropwhile(10, [(4,5)]).next)
       
   315         self.assertRaises(ValueError, dropwhile(errfunc, [(4,5)]).next)
       
   316 
       
   317     def test_tee(self):
       
   318         n = 200
       
   319         def irange(n):
       
   320             for i in xrange(n):
       
   321                 yield i
       
   322 
       
   323         a, b = tee([])        # test empty iterator
       
   324         self.assertEqual(list(a), [])
       
   325         self.assertEqual(list(b), [])
       
   326 
       
   327         a, b = tee(irange(n)) # test 100% interleaved
       
   328         self.assertEqual(zip(a,b), zip(range(n),range(n)))
       
   329 
       
   330         a, b = tee(irange(n)) # test 0% interleaved
       
   331         self.assertEqual(list(a), range(n))
       
   332         self.assertEqual(list(b), range(n))
       
   333 
       
   334         a, b = tee(irange(n)) # test dealloc of leading iterator
       
   335         for i in xrange(100):
       
   336             self.assertEqual(a.next(), i)
       
   337         del a
       
   338         self.assertEqual(list(b), range(n))
       
   339 
       
   340         a, b = tee(irange(n)) # test dealloc of trailing iterator
       
   341         for i in xrange(100):
       
   342             self.assertEqual(a.next(), i)
       
   343         del b
       
   344         self.assertEqual(list(a), range(100, n))
       
   345 
       
   346         for j in xrange(5):   # test randomly interleaved
       
   347             order = [0]*n + [1]*n
       
   348             random.shuffle(order)
       
   349             lists = ([], [])
       
   350             its = tee(irange(n))
       
   351             for i in order:
       
   352                 value = its[i].next()
       
   353                 lists[i].append(value)
       
   354             self.assertEqual(lists[0], range(n))
       
   355             self.assertEqual(lists[1], range(n))
       
   356 
       
   357         # test argument format checking
       
   358         self.assertRaises(TypeError, tee)
       
   359         self.assertRaises(TypeError, tee, 3)
       
   360         self.assertRaises(TypeError, tee, [1,2], 'x')
       
   361         self.assertRaises(TypeError, tee, [1,2], 3, 'x')
       
   362 
       
   363         # tee object should be instantiable
       
   364         a, b = tee('abc')
       
   365         c = type(a)('def')
       
   366         self.assertEqual(list(c), list('def'))
       
   367 
       
   368         # test long-lagged and multi-way split
       
   369         a, b, c = tee(xrange(2000), 3)
       
   370         for i in xrange(100):
       
   371             self.assertEqual(a.next(), i)
       
   372         self.assertEqual(list(b), range(2000))
       
   373         self.assertEqual([c.next(), c.next()], range(2))
       
   374         self.assertEqual(list(a), range(100,2000))
       
   375         self.assertEqual(list(c), range(2,2000))
       
   376 
       
   377         # test values of n
       
   378         self.assertRaises(TypeError, tee, 'abc', 'invalid')
       
   379         self.assertRaises(ValueError, tee, [], -1)
       
   380         for n in xrange(5):
       
   381             result = tee('abc', n)
       
   382             self.assertEqual(type(result), tuple)
       
   383             self.assertEqual(len(result), n)
       
   384             self.assertEqual(map(list, result), [list('abc')]*n)
       
   385 
       
   386         # tee pass-through to copyable iterator
       
   387         a, b = tee('abc')
       
   388         c, d = tee(a)
       
   389         self.assert_(a is c)
       
   390 
       
   391         # test tee_new
       
   392         t1, t2 = tee('abc')
       
   393         tnew = type(t1)
       
   394         self.assertRaises(TypeError, tnew)
       
   395         self.assertRaises(TypeError, tnew, 10)
       
   396         t3 = tnew(t1)
       
   397         self.assert_(list(t1) == list(t2) == list(t3) == list('abc'))
       
   398 
       
   399         # test that tee objects are weak referencable
       
   400         a, b = tee(xrange(10))
       
   401         p = proxy(a)
       
   402         self.assertEqual(getattr(p, '__class__'), type(b))
       
   403         del a
       
   404         self.assertRaises(ReferenceError, getattr, p, '__class__')
       
   405 
       
   406     def test_StopIteration(self):
       
   407         self.assertRaises(StopIteration, izip().next)
       
   408 
       
   409         for f in (chain, cycle, izip, groupby):
       
   410             self.assertRaises(StopIteration, f([]).next)
       
   411             self.assertRaises(StopIteration, f(StopNow()).next)
       
   412 
       
   413         self.assertRaises(StopIteration, islice([], None).next)
       
   414         self.assertRaises(StopIteration, islice(StopNow(), None).next)
       
   415 
       
   416         p, q = tee([])
       
   417         self.assertRaises(StopIteration, p.next)
       
   418         self.assertRaises(StopIteration, q.next)
       
   419         p, q = tee(StopNow())
       
   420         self.assertRaises(StopIteration, p.next)
       
   421         self.assertRaises(StopIteration, q.next)
       
   422 
       
   423         self.assertRaises(StopIteration, repeat(None, 0).next)
       
   424 
       
   425         for f in (ifilter, ifilterfalse, imap, takewhile, dropwhile, starmap):
       
   426             self.assertRaises(StopIteration, f(lambda x:x, []).next)
       
   427             self.assertRaises(StopIteration, f(lambda x:x, StopNow()).next)
       
   428 
       
   429 class TestGC(unittest.TestCase):
       
   430 
       
   431     def makecycle(self, iterator, container):
       
   432         container.append(iterator)
       
   433         iterator.next()
       
   434         del container, iterator
       
   435 
       
   436     def test_chain(self):
       
   437         a = []
       
   438         self.makecycle(chain(a), a)
       
   439 
       
   440     def test_cycle(self):
       
   441         a = []
       
   442         self.makecycle(cycle([a]*2), a)
       
   443 
       
   444     def test_dropwhile(self):
       
   445         a = []
       
   446         self.makecycle(dropwhile(bool, [0, a, a]), a)
       
   447 
       
   448     def test_groupby(self):
       
   449         a = []
       
   450         self.makecycle(groupby([a]*2, lambda x:x), a)
       
   451 
       
   452     def test_ifilter(self):
       
   453         a = []
       
   454         self.makecycle(ifilter(lambda x:True, [a]*2), a)
       
   455 
       
   456     def test_ifilterfalse(self):
       
   457         a = []
       
   458         self.makecycle(ifilterfalse(lambda x:False, a), a)
       
   459 
       
   460     def test_izip(self):
       
   461         a = []
       
   462         self.makecycle(izip([a]*2, [a]*3), a)
       
   463 
       
   464     def test_imap(self):
       
   465         a = []
       
   466         self.makecycle(imap(lambda x:x, [a]*2), a)
       
   467 
       
   468     def test_islice(self):
       
   469         a = []
       
   470         self.makecycle(islice([a]*2, None), a)
       
   471 
       
   472     def test_repeat(self):
       
   473         a = []
       
   474         self.makecycle(repeat(a), a)
       
   475 
       
   476     def test_starmap(self):
       
   477         a = []
       
   478         self.makecycle(starmap(lambda *t: t, [(a,a)]*2), a)
       
   479 
       
   480     def test_takewhile(self):
       
   481         a = []
       
   482         self.makecycle(takewhile(bool, [1, 0, a, a]), a)
       
   483 
       
   484 def R(seqn):
       
   485     'Regular generator'
       
   486     for i in seqn:
       
   487         yield i
       
   488 
       
   489 class G:
       
   490     'Sequence using __getitem__'
       
   491     def __init__(self, seqn):
       
   492         self.seqn = seqn
       
   493     def __getitem__(self, i):
       
   494         return self.seqn[i]
       
   495 
       
   496 class I:
       
   497     'Sequence using iterator protocol'
       
   498     def __init__(self, seqn):
       
   499         self.seqn = seqn
       
   500         self.i = 0
       
   501     def __iter__(self):
       
   502         return self
       
   503     def next(self):
       
   504         if self.i >= len(self.seqn): raise StopIteration
       
   505         v = self.seqn[self.i]
       
   506         self.i += 1
       
   507         return v
       
   508 
       
   509 class Ig:
       
   510     'Sequence using iterator protocol defined with a generator'
       
   511     def __init__(self, seqn):
       
   512         self.seqn = seqn
       
   513         self.i = 0
       
   514     def __iter__(self):
       
   515         for val in self.seqn:
       
   516             yield val
       
   517 
       
   518 class X:
       
   519     'Missing __getitem__ and __iter__'
       
   520     def __init__(self, seqn):
       
   521         self.seqn = seqn
       
   522         self.i = 0
       
   523     def next(self):
       
   524         if self.i >= len(self.seqn): raise StopIteration
       
   525         v = self.seqn[self.i]
       
   526         self.i += 1
       
   527         return v
       
   528 
       
   529 class N:
       
   530     'Iterator missing next()'
       
   531     def __init__(self, seqn):
       
   532         self.seqn = seqn
       
   533         self.i = 0
       
   534     def __iter__(self):
       
   535         return self
       
   536 
       
   537 class E:
       
   538     'Test propagation of exceptions'
       
   539     def __init__(self, seqn):
       
   540         self.seqn = seqn
       
   541         self.i = 0
       
   542     def __iter__(self):
       
   543         return self
       
   544     def next(self):
       
   545         3 // 0
       
   546 
       
   547 class S:
       
   548     'Test immediate stop'
       
   549     def __init__(self, seqn):
       
   550         pass
       
   551     def __iter__(self):
       
   552         return self
       
   553     def next(self):
       
   554         raise StopIteration
       
   555 
       
   556 def L(seqn):
       
   557     'Test multiple tiers of iterators'
       
   558     return chain(imap(lambda x:x, R(Ig(G(seqn)))))
       
   559 
       
   560 
       
   561 class TestVariousIteratorArgs(unittest.TestCase):
       
   562 
       
   563     def test_chain(self):
       
   564         for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
       
   565             for g in (G, I, Ig, S, L, R):
       
   566                 self.assertEqual(list(chain(g(s))), list(g(s)))
       
   567                 self.assertEqual(list(chain(g(s), g(s))), list(g(s))+list(g(s)))
       
   568             self.assertRaises(TypeError, chain, X(s))
       
   569             self.assertRaises(TypeError, list, chain(N(s)))
       
   570             self.assertRaises(ZeroDivisionError, list, chain(E(s)))
       
   571 
       
   572     def test_cycle(self):
       
   573         for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
       
   574             for g in (G, I, Ig, S, L, R):
       
   575                 tgtlen = len(s) * 3
       
   576                 expected = list(g(s))*3
       
   577                 actual = list(islice(cycle(g(s)), tgtlen))
       
   578                 self.assertEqual(actual, expected)
       
   579             self.assertRaises(TypeError, cycle, X(s))
       
   580             self.assertRaises(TypeError, list, cycle(N(s)))
       
   581             self.assertRaises(ZeroDivisionError, list, cycle(E(s)))
       
   582 
       
   583     def test_groupby(self):
       
   584         for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):
       
   585             for g in (G, I, Ig, S, L, R):
       
   586                 self.assertEqual([k for k, sb in groupby(g(s))], list(g(s)))
       
   587             self.assertRaises(TypeError, groupby, X(s))
       
   588             self.assertRaises(TypeError, list, groupby(N(s)))
       
   589             self.assertRaises(ZeroDivisionError, list, groupby(E(s)))
       
   590 
       
   591     def test_ifilter(self):
       
   592         for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):
       
   593             for g in (G, I, Ig, S, L, R):
       
   594                 self.assertEqual(list(ifilter(isEven, g(s))), filter(isEven, g(s)))
       
   595             self.assertRaises(TypeError, ifilter, isEven, X(s))
       
   596             self.assertRaises(TypeError, list, ifilter(isEven, N(s)))
       
   597             self.assertRaises(ZeroDivisionError, list, ifilter(isEven, E(s)))
       
   598 
       
   599     def test_ifilterfalse(self):
       
   600         for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):
       
   601             for g in (G, I, Ig, S, L, R):
       
   602                 self.assertEqual(list(ifilterfalse(isEven, g(s))), filter(isOdd, g(s)))
       
   603             self.assertRaises(TypeError, ifilterfalse, isEven, X(s))
       
   604             self.assertRaises(TypeError, list, ifilterfalse(isEven, N(s)))
       
   605             self.assertRaises(ZeroDivisionError, list, ifilterfalse(isEven, E(s)))
       
   606 
       
   607     def test_izip(self):
       
   608         for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
       
   609             for g in (G, I, Ig, S, L, R):
       
   610                 self.assertEqual(list(izip(g(s))), zip(g(s)))
       
   611                 self.assertEqual(list(izip(g(s), g(s))), zip(g(s), g(s)))
       
   612             self.assertRaises(TypeError, izip, X(s))
       
   613             self.assertRaises(TypeError, list, izip(N(s)))
       
   614             self.assertRaises(ZeroDivisionError, list, izip(E(s)))
       
   615 
       
   616     def test_imap(self):
       
   617         for s in (range(10), range(0), range(100), (7,11), xrange(20,50,5)):
       
   618             for g in (G, I, Ig, S, L, R):
       
   619                 self.assertEqual(list(imap(onearg, g(s))), map(onearg, g(s)))
       
   620                 self.assertEqual(list(imap(operator.pow, g(s), g(s))), map(operator.pow, g(s), g(s)))
       
   621             self.assertRaises(TypeError, imap, onearg, X(s))
       
   622             self.assertRaises(TypeError, list, imap(onearg, N(s)))
       
   623             self.assertRaises(ZeroDivisionError, list, imap(onearg, E(s)))
       
   624 
       
   625     def test_islice(self):
       
   626         for s in ("12345", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
       
   627             for g in (G, I, Ig, S, L, R):
       
   628                 self.assertEqual(list(islice(g(s),1,None,2)), list(g(s))[1::2])
       
   629             self.assertRaises(TypeError, islice, X(s), 10)
       
   630             self.assertRaises(TypeError, list, islice(N(s), 10))
       
   631             self.assertRaises(ZeroDivisionError, list, islice(E(s), 10))
       
   632 
       
   633     def test_starmap(self):
       
   634         for s in (range(10), range(0), range(100), (7,11), xrange(20,50,5)):
       
   635             for g in (G, I, Ig, S, L, R):
       
   636                 ss = zip(s, s)
       
   637                 self.assertEqual(list(starmap(operator.pow, g(ss))), map(operator.pow, g(s), g(s)))
       
   638             self.assertRaises(TypeError, starmap, operator.pow, X(ss))
       
   639             self.assertRaises(TypeError, list, starmap(operator.pow, N(ss)))
       
   640             self.assertRaises(ZeroDivisionError, list, starmap(operator.pow, E(ss)))
       
   641 
       
   642     def test_takewhile(self):
       
   643         for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):
       
   644             for g in (G, I, Ig, S, L, R):
       
   645                 tgt = []
       
   646                 for elem in g(s):
       
   647                     if not isEven(elem): break
       
   648                     tgt.append(elem)
       
   649                 self.assertEqual(list(takewhile(isEven, g(s))), tgt)
       
   650             self.assertRaises(TypeError, takewhile, isEven, X(s))
       
   651             self.assertRaises(TypeError, list, takewhile(isEven, N(s)))
       
   652             self.assertRaises(ZeroDivisionError, list, takewhile(isEven, E(s)))
       
   653 
       
   654     def test_dropwhile(self):
       
   655         for s in (range(10), range(0), range(1000), (7,11), xrange(2000,2200,5)):
       
   656             for g in (G, I, Ig, S, L, R):
       
   657                 tgt = []
       
   658                 for elem in g(s):
       
   659                     if not tgt and isOdd(elem): continue
       
   660                     tgt.append(elem)
       
   661                 self.assertEqual(list(dropwhile(isOdd, g(s))), tgt)
       
   662             self.assertRaises(TypeError, dropwhile, isOdd, X(s))
       
   663             self.assertRaises(TypeError, list, dropwhile(isOdd, N(s)))
       
   664             self.assertRaises(ZeroDivisionError, list, dropwhile(isOdd, E(s)))
       
   665 
       
   666     def test_tee(self):
       
   667         for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
       
   668             for g in (G, I, Ig, S, L, R):
       
   669                 it1, it2 = tee(g(s))
       
   670                 self.assertEqual(list(it1), list(g(s)))
       
   671                 self.assertEqual(list(it2), list(g(s)))
       
   672             self.assertRaises(TypeError, tee, X(s))
       
   673             self.assertRaises(TypeError, list, tee(N(s))[0])
       
   674             self.assertRaises(ZeroDivisionError, list, tee(E(s))[0])
       
   675 
       
   676 class LengthTransparency(unittest.TestCase):
       
   677 
       
   678     def test_repeat(self):
       
   679         from test.test_iterlen import len
       
   680         self.assertEqual(len(repeat(None, 50)), 50)
       
   681         self.assertRaises(TypeError, len, repeat(None))
       
   682 
       
   683 class RegressionTests(unittest.TestCase):
       
   684 
       
   685     def test_sf_793826(self):
       
   686         # Fix Armin Rigo's successful efforts to wreak havoc
       
   687 
       
   688         def mutatingtuple(tuple1, f, tuple2):
       
   689             # this builds a tuple t which is a copy of tuple1,
       
   690             # then calls f(t), then mutates t to be equal to tuple2
       
   691             # (needs len(tuple1) == len(tuple2)).
       
   692             def g(value, first=[1]):
       
   693                 if first:
       
   694                     del first[:]
       
   695                     f(z.next())
       
   696                 return value
       
   697             items = list(tuple2)
       
   698             items[1:1] = list(tuple1)
       
   699             gen = imap(g, items)
       
   700             z = izip(*[gen]*len(tuple1))
       
   701             z.next()
       
   702 
       
   703         def f(t):
       
   704             global T
       
   705             T = t
       
   706             first[:] = list(T)
       
   707 
       
   708         first = []
       
   709         mutatingtuple((1,2,3), f, (4,5,6))
       
   710         second = list(T)
       
   711         self.assertEqual(first, second)
       
   712 
       
   713 
       
   714     def test_sf_950057(self):
       
   715         # Make sure that chain() and cycle() catch exceptions immediately
       
   716         # rather than when shifting between input sources
       
   717 
       
   718         def gen1():
       
   719             hist.append(0)
       
   720             yield 1
       
   721             hist.append(1)
       
   722             raise AssertionError
       
   723             hist.append(2)
       
   724 
       
   725         def gen2(x):
       
   726             hist.append(3)
       
   727             yield 2
       
   728             hist.append(4)
       
   729             if x:
       
   730                 raise StopIteration
       
   731 
       
   732         hist = []
       
   733         self.assertRaises(AssertionError, list, chain(gen1(), gen2(False)))
       
   734         self.assertEqual(hist, [0,1])
       
   735 
       
   736         hist = []
       
   737         self.assertRaises(AssertionError, list, chain(gen1(), gen2(True)))
       
   738         self.assertEqual(hist, [0,1])
       
   739 
       
   740         hist = []
       
   741         self.assertRaises(AssertionError, list, cycle(gen1()))
       
   742         self.assertEqual(hist, [0,1])
       
   743 
       
   744 class SubclassWithKwargsTest(unittest.TestCase):
       
   745     def test_keywords_in_subclass(self):
       
   746         # count is not subclassable...
       
   747         for cls in (repeat, izip, ifilter, ifilterfalse, chain, imap,
       
   748                     starmap, islice, takewhile, dropwhile, cycle):
       
   749             class Subclass(cls):
       
   750                 def __init__(self, newarg=None, *args):
       
   751                     cls.__init__(self, *args)
       
   752             try:
       
   753                 Subclass(newarg=1)
       
   754             except TypeError, err:
       
   755                 # we expect type errors because of wrong argument count
       
   756                 self.failIf("does not take keyword arguments" in err.args[0])
       
   757 
       
   758 
       
   759 libreftest = """ Doctest for examples in the library reference: libitertools.tex
       
   760 
       
   761 
       
   762 >>> amounts = [120.15, 764.05, 823.14]
       
   763 >>> for checknum, amount in izip(count(1200), amounts):
       
   764 ...     print 'Check %d is for $%.2f' % (checknum, amount)
       
   765 ...
       
   766 Check 1200 is for $120.15
       
   767 Check 1201 is for $764.05
       
   768 Check 1202 is for $823.14
       
   769 
       
   770 >>> import operator
       
   771 >>> for cube in imap(operator.pow, xrange(1,4), repeat(3)):
       
   772 ...    print cube
       
   773 ...
       
   774 1
       
   775 8
       
   776 27
       
   777 
       
   778 >>> reportlines = ['EuroPython', 'Roster', '', 'alex', '', 'laura', '', 'martin', '', 'walter', '', 'samuele']
       
   779 >>> for name in islice(reportlines, 3, None, 2):
       
   780 ...    print name.title()
       
   781 ...
       
   782 Alex
       
   783 Laura
       
   784 Martin
       
   785 Walter
       
   786 Samuele
       
   787 
       
   788 >>> from operator import itemgetter
       
   789 >>> d = dict(a=1, b=2, c=1, d=2, e=1, f=2, g=3)
       
   790 >>> di = sorted(sorted(d.iteritems()), key=itemgetter(1))
       
   791 >>> for k, g in groupby(di, itemgetter(1)):
       
   792 ...     print k, map(itemgetter(0), g)
       
   793 ...
       
   794 1 ['a', 'c', 'e']
       
   795 2 ['b', 'd', 'f']
       
   796 3 ['g']
       
   797 
       
   798 # Find runs of consecutive numbers using groupby.  The key to the solution
       
   799 # is differencing with a range so that consecutive numbers all appear in
       
   800 # same group.
       
   801 >>> data = [ 1,  4,5,6, 10, 15,16,17,18, 22, 25,26,27,28]
       
   802 >>> for k, g in groupby(enumerate(data), lambda (i,x):i-x):
       
   803 ...     print map(operator.itemgetter(1), g)
       
   804 ...
       
   805 [1]
       
   806 [4, 5, 6]
       
   807 [10]
       
   808 [15, 16, 17, 18]
       
   809 [22]
       
   810 [25, 26, 27, 28]
       
   811 
       
   812 >>> def take(n, seq):
       
   813 ...     return list(islice(seq, n))
       
   814 
       
   815 >>> def enumerate(iterable):
       
   816 ...     return izip(count(), iterable)
       
   817 
       
   818 >>> def tabulate(function):
       
   819 ...     "Return function(0), function(1), ..."
       
   820 ...     return imap(function, count())
       
   821 
       
   822 >>> def iteritems(mapping):
       
   823 ...     return izip(mapping.iterkeys(), mapping.itervalues())
       
   824 
       
   825 >>> def nth(iterable, n):
       
   826 ...     "Returns the nth item"
       
   827 ...     return list(islice(iterable, n, n+1))
       
   828 
       
   829 >>> def all(seq, pred=None):
       
   830 ...     "Returns True if pred(x) is true for every element in the iterable"
       
   831 ...     for elem in ifilterfalse(pred, seq):
       
   832 ...         return False
       
   833 ...     return True
       
   834 
       
   835 >>> def any(seq, pred=None):
       
   836 ...     "Returns True if pred(x) is true for at least one element in the iterable"
       
   837 ...     for elem in ifilter(pred, seq):
       
   838 ...         return True
       
   839 ...     return False
       
   840 
       
   841 >>> def no(seq, pred=None):
       
   842 ...     "Returns True if pred(x) is false for every element in the iterable"
       
   843 ...     for elem in ifilter(pred, seq):
       
   844 ...         return False
       
   845 ...     return True
       
   846 
       
   847 >>> def quantify(seq, pred=None):
       
   848 ...     "Count how many times the predicate is true in the sequence"
       
   849 ...     return sum(imap(pred, seq))
       
   850 
       
   851 >>> def padnone(seq):
       
   852 ...     "Returns the sequence elements and then returns None indefinitely"
       
   853 ...     return chain(seq, repeat(None))
       
   854 
       
   855 >>> def ncycles(seq, n):
       
   856 ...     "Returns the sequence elements n times"
       
   857 ...     return chain(*repeat(seq, n))
       
   858 
       
   859 >>> def dotproduct(vec1, vec2):
       
   860 ...     return sum(imap(operator.mul, vec1, vec2))
       
   861 
       
   862 >>> def flatten(listOfLists):
       
   863 ...     return list(chain(*listOfLists))
       
   864 
       
   865 >>> def repeatfunc(func, times=None, *args):
       
   866 ...     "Repeat calls to func with specified arguments."
       
   867 ...     "   Example:  repeatfunc(random.random)"
       
   868 ...     if times is None:
       
   869 ...         return starmap(func, repeat(args))
       
   870 ...     else:
       
   871 ...         return starmap(func, repeat(args, times))
       
   872 
       
   873 >>> def pairwise(iterable):
       
   874 ...     "s -> (s0,s1), (s1,s2), (s2, s3), ..."
       
   875 ...     a, b = tee(iterable)
       
   876 ...     try:
       
   877 ...         b.next()
       
   878 ...     except StopIteration:
       
   879 ...         pass
       
   880 ...     return izip(a, b)
       
   881 
       
   882 This is not part of the examples but it tests to make sure the definitions
       
   883 perform as purported.
       
   884 
       
   885 >>> take(10, count())
       
   886 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
       
   887 
       
   888 >>> list(enumerate('abc'))
       
   889 [(0, 'a'), (1, 'b'), (2, 'c')]
       
   890 
       
   891 >>> list(islice(tabulate(lambda x: 2*x), 4))
       
   892 [0, 2, 4, 6]
       
   893 
       
   894 >>> nth('abcde', 3)
       
   895 ['d']
       
   896 
       
   897 >>> all([2, 4, 6, 8], lambda x: x%2==0)
       
   898 True
       
   899 
       
   900 >>> all([2, 3, 6, 8], lambda x: x%2==0)
       
   901 False
       
   902 
       
   903 >>> any([2, 4, 6, 8], lambda x: x%2==0)
       
   904 True
       
   905 
       
   906 >>> any([1, 3, 5, 9], lambda x: x%2==0,)
       
   907 False
       
   908 
       
   909 >>> no([1, 3, 5, 9], lambda x: x%2==0)
       
   910 True
       
   911 
       
   912 >>> no([1, 2, 5, 9], lambda x: x%2==0)
       
   913 False
       
   914 
       
   915 >>> quantify(xrange(99), lambda x: x%2==0)
       
   916 50
       
   917 
       
   918 >>> a = [[1, 2, 3], [4, 5, 6]]
       
   919 >>> flatten(a)
       
   920 [1, 2, 3, 4, 5, 6]
       
   921 
       
   922 >>> list(repeatfunc(pow, 5, 2, 3))
       
   923 [8, 8, 8, 8, 8]
       
   924 
       
   925 >>> import random
       
   926 >>> take(5, imap(int, repeatfunc(random.random)))
       
   927 [0, 0, 0, 0, 0]
       
   928 
       
   929 >>> list(pairwise('abcd'))
       
   930 [('a', 'b'), ('b', 'c'), ('c', 'd')]
       
   931 
       
   932 >>> list(pairwise([]))
       
   933 []
       
   934 
       
   935 >>> list(pairwise('a'))
       
   936 []
       
   937 
       
   938 >>> list(islice(padnone('abc'), 0, 6))
       
   939 ['a', 'b', 'c', None, None, None]
       
   940 
       
   941 >>> list(ncycles('abc', 3))
       
   942 ['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c']
       
   943 
       
   944 >>> dotproduct([1,2,3], [4,5,6])
       
   945 32
       
   946 
       
   947 """
       
   948 
       
   949 __test__ = {'libreftest' : libreftest}
       
   950 
       
   951 def test_main(verbose=None):
       
   952     test_classes = (TestBasicOps, TestVariousIteratorArgs, TestGC,
       
   953                     RegressionTests, LengthTransparency,
       
   954                     SubclassWithKwargsTest)
       
   955     test_support.run_unittest(*test_classes)
       
   956 
       
   957     # verify reference counting
       
   958     if verbose and hasattr(sys, "gettotalrefcount"):
       
   959         import gc
       
   960         counts = [None] * 5
       
   961         for i in xrange(len(counts)):
       
   962             test_support.run_unittest(*test_classes)
       
   963             gc.collect()
       
   964             counts[i] = sys.gettotalrefcount()
       
   965         print counts
       
   966 
       
   967     # doctest the examples in the library reference
       
   968     test_support.run_doctest(sys.modules[__name__], verbose)
       
   969 
       
   970 if __name__ == "__main__":
       
   971     test_main(verbose=True)