python-2.5.2/win32/Lib/test/test_enumerate.py
changeset 0 ae805ac0140d
equal deleted inserted replaced
-1:000000000000 0:ae805ac0140d
       
     1 import unittest
       
     2 import sys
       
     3 
       
     4 from test import test_support
       
     5 
       
     6 class G:
       
     7     'Sequence using __getitem__'
       
     8     def __init__(self, seqn):
       
     9         self.seqn = seqn
       
    10     def __getitem__(self, i):
       
    11         return self.seqn[i]
       
    12 
       
    13 class I:
       
    14     'Sequence using iterator protocol'
       
    15     def __init__(self, seqn):
       
    16         self.seqn = seqn
       
    17         self.i = 0
       
    18     def __iter__(self):
       
    19         return self
       
    20     def next(self):
       
    21         if self.i >= len(self.seqn): raise StopIteration
       
    22         v = self.seqn[self.i]
       
    23         self.i += 1
       
    24         return v
       
    25 
       
    26 class Ig:
       
    27     'Sequence using iterator protocol defined with a generator'
       
    28     def __init__(self, seqn):
       
    29         self.seqn = seqn
       
    30         self.i = 0
       
    31     def __iter__(self):
       
    32         for val in self.seqn:
       
    33             yield val
       
    34 
       
    35 class X:
       
    36     'Missing __getitem__ and __iter__'
       
    37     def __init__(self, seqn):
       
    38         self.seqn = seqn
       
    39         self.i = 0
       
    40     def next(self):
       
    41         if self.i >= len(self.seqn): raise StopIteration
       
    42         v = self.seqn[self.i]
       
    43         self.i += 1
       
    44         return v
       
    45 
       
    46 class E:
       
    47     'Test propagation of exceptions'
       
    48     def __init__(self, seqn):
       
    49         self.seqn = seqn
       
    50         self.i = 0
       
    51     def __iter__(self):
       
    52         return self
       
    53     def next(self):
       
    54         3 // 0
       
    55 
       
    56 class N:
       
    57     'Iterator missing next()'
       
    58     def __init__(self, seqn):
       
    59         self.seqn = seqn
       
    60         self.i = 0
       
    61     def __iter__(self):
       
    62         return self
       
    63 
       
    64 class EnumerateTestCase(unittest.TestCase):
       
    65 
       
    66     enum = enumerate
       
    67     seq, res = 'abc', [(0,'a'), (1,'b'), (2,'c')]
       
    68 
       
    69     def test_basicfunction(self):
       
    70         self.assertEqual(type(self.enum(self.seq)), self.enum)
       
    71         e = self.enum(self.seq)
       
    72         self.assertEqual(iter(e), e)
       
    73         self.assertEqual(list(self.enum(self.seq)), self.res)
       
    74         self.enum.__doc__
       
    75 
       
    76     def test_getitemseqn(self):
       
    77         self.assertEqual(list(self.enum(G(self.seq))), self.res)
       
    78         e = self.enum(G(''))
       
    79         self.assertRaises(StopIteration, e.next)
       
    80 
       
    81     def test_iteratorseqn(self):
       
    82         self.assertEqual(list(self.enum(I(self.seq))), self.res)
       
    83         e = self.enum(I(''))
       
    84         self.assertRaises(StopIteration, e.next)
       
    85 
       
    86     def test_iteratorgenerator(self):
       
    87         self.assertEqual(list(self.enum(Ig(self.seq))), self.res)
       
    88         e = self.enum(Ig(''))
       
    89         self.assertRaises(StopIteration, e.next)
       
    90 
       
    91     def test_noniterable(self):
       
    92         self.assertRaises(TypeError, self.enum, X(self.seq))
       
    93 
       
    94     def test_illformediterable(self):
       
    95         self.assertRaises(TypeError, list, self.enum(N(self.seq)))
       
    96 
       
    97     def test_exception_propagation(self):
       
    98         self.assertRaises(ZeroDivisionError, list, self.enum(E(self.seq)))
       
    99 
       
   100     def test_argumentcheck(self):
       
   101         self.assertRaises(TypeError, self.enum) # no arguments
       
   102         self.assertRaises(TypeError, self.enum, 1) # wrong type (not iterable)
       
   103         self.assertRaises(TypeError, self.enum, 'abc', 2) # too many arguments
       
   104 
       
   105     def test_tuple_reuse(self):
       
   106         # Tests an implementation detail where tuple is reused
       
   107         # whenever nothing else holds a reference to it
       
   108         self.assertEqual(len(set(map(id, list(enumerate(self.seq))))), len(self.seq))
       
   109         self.assertEqual(len(set(map(id, enumerate(self.seq)))), min(1,len(self.seq)))
       
   110 
       
   111 class MyEnum(enumerate):
       
   112     pass
       
   113 
       
   114 class SubclassTestCase(EnumerateTestCase):
       
   115 
       
   116     enum = MyEnum
       
   117 
       
   118 class TestEmpty(EnumerateTestCase):
       
   119 
       
   120     seq, res = '', []
       
   121 
       
   122 class TestBig(EnumerateTestCase):
       
   123 
       
   124     seq = range(10,20000,2)
       
   125     res = zip(range(20000), seq)
       
   126 
       
   127 class TestReversed(unittest.TestCase):
       
   128 
       
   129     def test_simple(self):
       
   130         class A:
       
   131             def __getitem__(self, i):
       
   132                 if i < 5:
       
   133                     return str(i)
       
   134                 raise StopIteration
       
   135             def __len__(self):
       
   136                 return 5
       
   137         for data in 'abc', range(5), tuple(enumerate('abc')), A(), xrange(1,17,5):
       
   138             self.assertEqual(list(data)[::-1], list(reversed(data)))
       
   139         self.assertRaises(TypeError, reversed, {})
       
   140 
       
   141     def test_xrange_optimization(self):
       
   142         x = xrange(1)
       
   143         self.assertEqual(type(reversed(x)), type(iter(x)))
       
   144 
       
   145     def test_len(self):
       
   146         # This is an implementation detail, not an interface requirement
       
   147         from test.test_iterlen import len
       
   148         for s in ('hello', tuple('hello'), list('hello'), xrange(5)):
       
   149             self.assertEqual(len(reversed(s)), len(s))
       
   150             r = reversed(s)
       
   151             list(r)
       
   152             self.assertEqual(len(r), 0)
       
   153         class SeqWithWeirdLen:
       
   154             called = False
       
   155             def __len__(self):
       
   156                 if not self.called:
       
   157                     self.called = True
       
   158                     return 10
       
   159                 raise ZeroDivisionError
       
   160             def __getitem__(self, index):
       
   161                 return index
       
   162         r = reversed(SeqWithWeirdLen())
       
   163         self.assertRaises(ZeroDivisionError, len, r)
       
   164 
       
   165 
       
   166     def test_gc(self):
       
   167         class Seq:
       
   168             def __len__(self):
       
   169                 return 10
       
   170             def __getitem__(self, index):
       
   171                 return index
       
   172         s = Seq()
       
   173         r = reversed(s)
       
   174         s.r = r
       
   175 
       
   176     def test_args(self):
       
   177         self.assertRaises(TypeError, reversed)
       
   178         self.assertRaises(TypeError, reversed, [], 'extra')
       
   179 
       
   180     def test_bug1229429(self):
       
   181         # this bug was never in reversed, it was in
       
   182         # PyObject_CallMethod, and reversed_new calls that sometimes.
       
   183         if not hasattr(sys, "getrefcount"):
       
   184             return
       
   185         def f():
       
   186             pass
       
   187         r = f.__reversed__ = object()
       
   188         rc = sys.getrefcount(r)
       
   189         for i in range(10):
       
   190             try:
       
   191                 reversed(f)
       
   192             except TypeError:
       
   193                 pass
       
   194             else:
       
   195                 self.fail("non-callable __reversed__ didn't raise!")
       
   196         self.assertEqual(rc, sys.getrefcount(r))
       
   197 
       
   198 
       
   199 def test_main(verbose=None):
       
   200     testclasses = (EnumerateTestCase, SubclassTestCase, TestEmpty, TestBig,
       
   201                    TestReversed)
       
   202     test_support.run_unittest(*testclasses)
       
   203 
       
   204     # verify reference counting
       
   205     import sys
       
   206     if verbose and hasattr(sys, "gettotalrefcount"):
       
   207         counts = [None] * 5
       
   208         for i in xrange(len(counts)):
       
   209             test_support.run_unittest(*testclasses)
       
   210             counts[i] = sys.gettotalrefcount()
       
   211         print counts
       
   212 
       
   213 if __name__ == "__main__":
       
   214     test_main(verbose=True)