blob: 095820b45fbfb1deee73344cc44725d891021731 [file] [log] [blame]
Guido van Rossum7dab2422002-04-26 19:40:56 +00001import unittest
Michael W. Hudson0edc7a02005-07-12 10:21:19 +00002import sys
Guido van Rossum7dab2422002-04-26 19:40:56 +00003
Benjamin Petersonee8712c2008-05-20 21:35:26 +00004from test import support
Guido van Rossum7dab2422002-04-26 19:40:56 +00005
Guido van Rossum7dab2422002-04-26 19:40:56 +00006class 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
13class 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
Georg Brandla18af4e2007-04-21 15:47:16 +000020 def __next__(self):
Guido van Rossum7dab2422002-04-26 19:40:56 +000021 if self.i >= len(self.seqn): raise StopIteration
22 v = self.seqn[self.i]
23 self.i += 1
24 return v
25
26class 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
35class X:
36 'Missing __getitem__ and __iter__'
37 def __init__(self, seqn):
38 self.seqn = seqn
39 self.i = 0
Georg Brandla18af4e2007-04-21 15:47:16 +000040 def __next__(self):
Guido van Rossum7dab2422002-04-26 19:40:56 +000041 if self.i >= len(self.seqn): raise StopIteration
42 v = self.seqn[self.i]
43 self.i += 1
44 return v
45
46class 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
Georg Brandla18af4e2007-04-21 15:47:16 +000053 def __next__(self):
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +000054 3 // 0
Guido van Rossum7dab2422002-04-26 19:40:56 +000055
56class N:
Georg Brandla18af4e2007-04-21 15:47:16 +000057 'Iterator missing __next__()'
Guido van Rossum7dab2422002-04-26 19:40:56 +000058 def __init__(self, seqn):
59 self.seqn = seqn
60 self.i = 0
61 def __iter__(self):
62 return self
63
64class EnumerateTestCase(unittest.TestCase):
65
66 enum = enumerate
Raymond Hettingere8b0f042003-05-28 14:05:34 +000067 seq, res = 'abc', [(0,'a'), (1,'b'), (2,'c')]
Guido van Rossum7dab2422002-04-26 19:40:56 +000068
69 def test_basicfunction(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000070 self.assertEqual(type(self.enum(self.seq)), self.enum)
71 e = self.enum(self.seq)
Guido van Rossum7dab2422002-04-26 19:40:56 +000072 self.assertEqual(iter(e), e)
Raymond Hettingere8b0f042003-05-28 14:05:34 +000073 self.assertEqual(list(self.enum(self.seq)), self.res)
Guido van Rossum7dab2422002-04-26 19:40:56 +000074 self.enum.__doc__
75
76 def test_getitemseqn(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000077 self.assertEqual(list(self.enum(G(self.seq))), self.res)
Guido van Rossum7dab2422002-04-26 19:40:56 +000078 e = self.enum(G(''))
Georg Brandla18af4e2007-04-21 15:47:16 +000079 self.assertRaises(StopIteration, next, e)
Guido van Rossum7dab2422002-04-26 19:40:56 +000080
81 def test_iteratorseqn(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000082 self.assertEqual(list(self.enum(I(self.seq))), self.res)
Guido van Rossum7dab2422002-04-26 19:40:56 +000083 e = self.enum(I(''))
Georg Brandla18af4e2007-04-21 15:47:16 +000084 self.assertRaises(StopIteration, next, e)
Guido van Rossum7dab2422002-04-26 19:40:56 +000085
86 def test_iteratorgenerator(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000087 self.assertEqual(list(self.enum(Ig(self.seq))), self.res)
Guido van Rossum7dab2422002-04-26 19:40:56 +000088 e = self.enum(Ig(''))
Georg Brandla18af4e2007-04-21 15:47:16 +000089 self.assertRaises(StopIteration, next, e)
Guido van Rossum7dab2422002-04-26 19:40:56 +000090
91 def test_noniterable(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000092 self.assertRaises(TypeError, self.enum, X(self.seq))
Guido van Rossum7dab2422002-04-26 19:40:56 +000093
94 def test_illformediterable(self):
Thomas Wouters1034dad2006-04-15 09:16:16 +000095 self.assertRaises(TypeError, self.enum, N(self.seq))
Guido van Rossum7dab2422002-04-26 19:40:56 +000096
97 def test_exception_propagation(self):
Raymond Hettingere8b0f042003-05-28 14:05:34 +000098 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)
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000103 self.assertRaises(TypeError, self.enum, 'abc', 'a') # wrong type
104 self.assertRaises(TypeError, self.enum, 'abc', 2, 3) # too many arguments
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000105
Benjamin Peterson4fd283a2010-06-25 23:24:35 +0000106 @support.cpython_only
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000107 def test_tuple_reuse(self):
108 # Tests an implementation detail where tuple is reused
109 # whenever nothing else holds a reference to it
Raymond Hettingera690a992003-11-16 16:17:49 +0000110 self.assertEqual(len(set(map(id, list(enumerate(self.seq))))), len(self.seq))
111 self.assertEqual(len(set(map(id, enumerate(self.seq)))), min(1,len(self.seq)))
Guido van Rossum7dab2422002-04-26 19:40:56 +0000112
113class MyEnum(enumerate):
114 pass
115
116class SubclassTestCase(EnumerateTestCase):
117
118 enum = MyEnum
119
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000120class TestEmpty(EnumerateTestCase):
121
122 seq, res = '', []
123
124class TestBig(EnumerateTestCase):
125
126 seq = range(10,20000,2)
Guido van Rossum801f0d72006-08-24 19:48:10 +0000127 res = list(zip(range(20000), seq))
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000128
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000129class TestReversed(unittest.TestCase):
130
131 def test_simple(self):
132 class A:
133 def __getitem__(self, i):
134 if i < 5:
135 return str(i)
136 raise StopIteration
137 def __len__(self):
138 return 5
Guido van Rossum805365e2007-05-07 22:24:25 +0000139 for data in 'abc', range(5), tuple(enumerate('abc')), A(), range(1,17,5):
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000140 self.assertEqual(list(data)[::-1], list(reversed(data)))
141 self.assertRaises(TypeError, reversed, {})
Alexandre Vassalottibee32532008-05-16 18:15:12 +0000142 # don't allow keyword arguments
143 self.assertRaises(TypeError, reversed, [], a=1)
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000144
Guido van Rossum805365e2007-05-07 22:24:25 +0000145 def test_range_optimization(self):
146 x = range(1)
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000147 self.assertEqual(type(reversed(x)), type(iter(x)))
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000148
Benjamin Peterson4fd283a2010-06-25 23:24:35 +0000149 @support.cpython_only
Raymond Hettinger029dba52004-02-10 09:33:39 +0000150 def test_len(self):
Raymond Hettingerd2c36262004-03-10 08:32:47 +0000151 # This is an implementation detail, not an interface requirement
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000152 from test.test_iterlen import len
Guido van Rossum805365e2007-05-07 22:24:25 +0000153 for s in ('hello', tuple('hello'), list('hello'), range(5)):
Raymond Hettingeref9bf402004-03-10 10:10:42 +0000154 self.assertEqual(len(reversed(s)), len(s))
Raymond Hettingerff5dc0e2004-09-29 11:40:50 +0000155 r = reversed(s)
156 list(r)
157 self.assertEqual(len(r), 0)
158 class SeqWithWeirdLen:
159 called = False
160 def __len__(self):
161 if not self.called:
162 self.called = True
163 return 10
164 raise ZeroDivisionError
165 def __getitem__(self, index):
166 return index
167 r = reversed(SeqWithWeirdLen())
168 self.assertRaises(ZeroDivisionError, len, r)
169
170
171 def test_gc(self):
172 class Seq:
173 def __len__(self):
174 return 10
175 def __getitem__(self, index):
176 return index
177 s = Seq()
178 r = reversed(s)
179 s.r = r
180
181 def test_args(self):
182 self.assertRaises(TypeError, reversed)
183 self.assertRaises(TypeError, reversed, [], 'extra')
Raymond Hettinger029dba52004-02-10 09:33:39 +0000184
Michael W. Hudson0edc7a02005-07-12 10:21:19 +0000185 def test_bug1229429(self):
186 # this bug was never in reversed, it was in
187 # PyObject_CallMethod, and reversed_new calls that sometimes.
188 if not hasattr(sys, "getrefcount"):
189 return
190 def f():
191 pass
192 r = f.__reversed__ = object()
193 rc = sys.getrefcount(r)
194 for i in range(10):
195 try:
196 reversed(f)
197 except TypeError:
198 pass
199 else:
200 self.fail("non-callable __reversed__ didn't raise!")
201 self.assertEqual(rc, sys.getrefcount(r))
Tim Petersf5f32b42005-07-17 23:16:17 +0000202
Mark Dickinsonfb3dc942010-05-25 19:06:24 +0000203 def test_objmethods(self):
204 # Objects must have __len__() and __getitem__() implemented.
205 class NoLen(object):
206 def __getitem__(self): return 1
207 nl = NoLen()
208 self.assertRaises(TypeError, reversed, nl)
209
210 class NoGetItem(object):
211 def __len__(self): return 2
212 ngi = NoGetItem()
213 self.assertRaises(TypeError, reversed, ngi)
214
Michael W. Hudson0edc7a02005-07-12 10:21:19 +0000215
Benjamin Peterson06507eb2010-05-08 16:51:16 +0000216class EnumerateStartTestCase(EnumerateTestCase):
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000217
Benjamin Peterson06507eb2010-05-08 16:51:16 +0000218 def test_basicfunction(self):
219 e = self.enum(self.seq)
220 self.assertEqual(iter(e), e)
221 self.assertEqual(list(self.enum(self.seq)), self.res)
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000222
223
Benjamin Peterson06507eb2010-05-08 16:51:16 +0000224class TestStart(EnumerateStartTestCase):
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000225
Benjamin Peterson06507eb2010-05-08 16:51:16 +0000226 enum = lambda self, i: enumerate(i, start=11)
227 seq, res = 'abc', [(11, 'a'), (12, 'b'), (13, 'c')]
228
229
230class TestLongStart(EnumerateStartTestCase):
231
232 enum = lambda self, i: enumerate(i, start=sys.maxsize+1)
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000233 seq, res = 'abc', [(sys.maxsize+1,'a'), (sys.maxsize+2,'b'),
234 (sys.maxsize+3,'c')]
235
236
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000237def test_main(verbose=None):
Benjamin Peterson06507eb2010-05-08 16:51:16 +0000238 support.run_unittest(__name__)
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000239
240 # verify reference counting
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000241 if verbose and hasattr(sys, "gettotalrefcount"):
242 counts = [None] * 5
Guido van Rossum805365e2007-05-07 22:24:25 +0000243 for i in range(len(counts)):
Mark Dickinsonf43c3d32010-05-25 19:46:20 +0000244 support.run_unittest(__name__)
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000245 counts[i] = sys.gettotalrefcount()
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000246 print(counts)
Guido van Rossum7dab2422002-04-26 19:40:56 +0000247
248if __name__ == "__main__":
Raymond Hettingere8b0f042003-05-28 14:05:34 +0000249 test_main(verbose=True)