blob: 0ed2b4c5c1f761a4651a8fe7c72309fb71df29fc [file] [log] [blame]
Guido van Rossum7dab2422002-04-26 19:40:56 +00001import unittest
2
Barry Warsaw04f357c2002-07-23 19:04:11 +00003from test import test_support
Guido van Rossum7dab2422002-04-26 19:40:56 +00004
Guido van Rossum7dab2422002-04-26 19:40:56 +00005class G:
6 'Sequence using __getitem__'
7 def __init__(self, seqn):
8 self.seqn = seqn
9 def __getitem__(self, i):
10 return self.seqn[i]
11
12class I:
13 'Sequence using iterator protocol'
14 def __init__(self, seqn):
15 self.seqn = seqn
16 self.i = 0
17 def __iter__(self):
18 return self
19 def next(self):
20 if self.i >= len(self.seqn): raise StopIteration
21 v = self.seqn[self.i]
22 self.i += 1
23 return v
24
25class Ig:
26 'Sequence using iterator protocol defined with a generator'
27 def __init__(self, seqn):
28 self.seqn = seqn
29 self.i = 0
30 def __iter__(self):
31 for val in self.seqn:
32 yield val
33
34class X:
35 'Missing __getitem__ and __iter__'
36 def __init__(self, seqn):
37 self.seqn = seqn
38 self.i = 0
39 def next(self):
40 if self.i >= len(self.seqn): raise StopIteration
41 v = self.seqn[self.i]
42 self.i += 1
43 return v
44
45class E:
46 'Test propagation of exceptions'
47 def __init__(self, seqn):
48 self.seqn = seqn
49 self.i = 0
50 def __iter__(self):
51 return self
52 def next(self):
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +000053 3 // 0
Guido van Rossum7dab2422002-04-26 19:40:56 +000054
55class N:
56 'Iterator missing next()'
57 def __init__(self, seqn):
58 self.seqn = seqn
59 self.i = 0
60 def __iter__(self):
61 return self
62
63class EnumerateTestCase(unittest.TestCase):
64
65 enum = enumerate
Raymond Hettingere8b0f042003-05-28 14:05:34 +000066 seq, res = 'abc', [(0,'a'), (1,'b'), (2,'c')]
Guido van Rossum7dab2422002-04-26 19:40:56 +000067
68 def test_basicfunction(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000069 self.assertEqual(type(self.enum(self.seq)), self.enum)
70 e = self.enum(self.seq)
Guido van Rossum7dab2422002-04-26 19:40:56 +000071 self.assertEqual(iter(e), e)
Raymond Hettingere8b0f042003-05-28 14:05:34 +000072 self.assertEqual(list(self.enum(self.seq)), self.res)
Guido van Rossum7dab2422002-04-26 19:40:56 +000073 self.enum.__doc__
74
75 def test_getitemseqn(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000076 self.assertEqual(list(self.enum(G(self.seq))), self.res)
Guido van Rossum7dab2422002-04-26 19:40:56 +000077 e = self.enum(G(''))
78 self.assertRaises(StopIteration, e.next)
79
80 def test_iteratorseqn(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000081 self.assertEqual(list(self.enum(I(self.seq))), self.res)
Guido van Rossum7dab2422002-04-26 19:40:56 +000082 e = self.enum(I(''))
83 self.assertRaises(StopIteration, e.next)
84
85 def test_iteratorgenerator(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000086 self.assertEqual(list(self.enum(Ig(self.seq))), self.res)
Guido van Rossum7dab2422002-04-26 19:40:56 +000087 e = self.enum(Ig(''))
88 self.assertRaises(StopIteration, e.next)
89
90 def test_noniterable(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000091 self.assertRaises(TypeError, self.enum, X(self.seq))
Guido van Rossum7dab2422002-04-26 19:40:56 +000092
93 def test_illformediterable(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000094 self.assertRaises(TypeError, list, self.enum(N(self.seq)))
Guido van Rossum7dab2422002-04-26 19:40:56 +000095
96 def test_exception_propagation(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000097 self.assertRaises(ZeroDivisionError, list, self.enum(E(self.seq)))
98
99 def test_argumentcheck(self):
100 self.assertRaises(TypeError, self.enum) # no arguments
101 self.assertRaises(TypeError, self.enum, 1) # wrong type (not iterable)
102 self.assertRaises(TypeError, self.enum, 'abc', 2) # too many arguments
103
104 def test_tuple_reuse(self):
105 # Tests an implementation detail where tuple is reused
106 # whenever nothing else holds a reference to it
Raymond Hettingera690a992003-11-16 16:17:49 +0000107 self.assertEqual(len(set(map(id, list(enumerate(self.seq))))), len(self.seq))
108 self.assertEqual(len(set(map(id, enumerate(self.seq)))), min(1,len(self.seq)))
Guido van Rossum7dab2422002-04-26 19:40:56 +0000109
110class MyEnum(enumerate):
111 pass
112
113class SubclassTestCase(EnumerateTestCase):
114
115 enum = MyEnum
116
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000117class TestEmpty(EnumerateTestCase):
118
119 seq, res = '', []
120
121class TestBig(EnumerateTestCase):
122
123 seq = range(10,20000,2)
124 res = zip(range(20000), seq)
125
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000126class TestReversed(unittest.TestCase):
127
128 def test_simple(self):
129 class A:
130 def __getitem__(self, i):
131 if i < 5:
132 return str(i)
133 raise StopIteration
134 def __len__(self):
135 return 5
136 for data in 'abc', range(5), tuple(enumerate('abc')), A(), xrange(1,17,5):
137 self.assertEqual(list(data)[::-1], list(reversed(data)))
138 self.assertRaises(TypeError, reversed, {})
139
140 def test_xrange_optimization(self):
141 x = xrange(1)
142 self.assertEqual(type(reversed(x)), type(iter(x)))
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000143
Raymond Hettinger029dba52004-02-10 09:33:39 +0000144 def test_len(self):
Raymond Hettingerd2c36262004-03-10 08:32:47 +0000145 # This is an implementation detail, not an interface requirement
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000146 for s in ('hello', tuple('hello'), list('hello'), xrange(5)):
147 self.assertEqual(len(reversed(s)), len(s))
Raymond Hettingerff5dc0e2004-09-29 11:40:50 +0000148 r = reversed(s)
149 list(r)
150 self.assertEqual(len(r), 0)
151 class SeqWithWeirdLen:
152 called = False
153 def __len__(self):
154 if not self.called:
155 self.called = True
156 return 10
157 raise ZeroDivisionError
158 def __getitem__(self, index):
159 return index
160 r = reversed(SeqWithWeirdLen())
161 self.assertRaises(ZeroDivisionError, len, r)
162
163
164 def test_gc(self):
165 class Seq:
166 def __len__(self):
167 return 10
168 def __getitem__(self, index):
169 return index
170 s = Seq()
171 r = reversed(s)
172 s.r = r
173
174 def test_args(self):
175 self.assertRaises(TypeError, reversed)
176 self.assertRaises(TypeError, reversed, [], 'extra')
Raymond Hettinger029dba52004-02-10 09:33:39 +0000177
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000178def test_main(verbose=None):
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000179 testclasses = (EnumerateTestCase, SubclassTestCase, TestEmpty, TestBig,
180 TestReversed)
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000181 test_support.run_unittest(*testclasses)
182
183 # verify reference counting
184 import sys
185 if verbose and hasattr(sys, "gettotalrefcount"):
186 counts = [None] * 5
187 for i in xrange(len(counts)):
188 test_support.run_unittest(*testclasses)
189 counts[i] = sys.gettotalrefcount()
190 print counts
Guido van Rossum7dab2422002-04-26 19:40:56 +0000191
192if __name__ == "__main__":
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000193 test_main(verbose=True)