blob: abc408f86935de1048481a40e531fd6171f2c152 [file] [log] [blame]
Guido van Rossum8b48cf92001-04-21 13:33:54 +00001# Test iterators.
2
Serhiy Storchaka4faf5c52015-05-21 20:50:25 +03003import sys
Guido van Rossum8b48cf92001-04-21 13:33:54 +00004import unittest
Benjamin Peterson945c5792010-06-22 20:34:34 +00005from test.support import run_unittest, TESTFN, unlink, cpython_only
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00006import pickle
7import collections.abc
Guido van Rossum8b48cf92001-04-21 13:33:54 +00008
9# Test result of triple loop (too big to inline)
10TRIPLETS = [(0, 0, 0), (0, 0, 1), (0, 0, 2),
11 (0, 1, 0), (0, 1, 1), (0, 1, 2),
12 (0, 2, 0), (0, 2, 1), (0, 2, 2),
13
14 (1, 0, 0), (1, 0, 1), (1, 0, 2),
15 (1, 1, 0), (1, 1, 1), (1, 1, 2),
16 (1, 2, 0), (1, 2, 1), (1, 2, 2),
17
18 (2, 0, 0), (2, 0, 1), (2, 0, 2),
19 (2, 1, 0), (2, 1, 1), (2, 1, 2),
20 (2, 2, 0), (2, 2, 1), (2, 2, 2)]
21
22# Helper classes
23
24class BasicIterClass:
25 def __init__(self, n):
26 self.n = n
27 self.i = 0
Georg Brandla18af4e2007-04-21 15:47:16 +000028 def __next__(self):
Guido van Rossum8b48cf92001-04-21 13:33:54 +000029 res = self.i
30 if res >= self.n:
31 raise StopIteration
32 self.i = res + 1
33 return res
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +000034 def __iter__(self):
35 return self
Guido van Rossum8b48cf92001-04-21 13:33:54 +000036
37class IteratingSequenceClass:
38 def __init__(self, n):
39 self.n = n
40 def __iter__(self):
41 return BasicIterClass(self.n)
42
43class SequenceClass:
44 def __init__(self, n):
45 self.n = n
46 def __getitem__(self, i):
47 if 0 <= i < self.n:
48 return i
49 else:
50 raise IndexError
51
Serhiy Storchaka4faf5c52015-05-21 20:50:25 +030052class UnlimitedSequenceClass:
53 def __getitem__(self, i):
54 return i
55
Guido van Rossum8b48cf92001-04-21 13:33:54 +000056# Main test suite
57
58class TestCase(unittest.TestCase):
59
60 # Helper to check that an iterator returns a given sequence
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +000061 def check_iterator(self, it, seq, pickle=True):
62 if pickle:
63 self.check_pickle(it, seq)
Guido van Rossum8b48cf92001-04-21 13:33:54 +000064 res = []
65 while 1:
66 try:
Georg Brandla18af4e2007-04-21 15:47:16 +000067 val = next(it)
Guido van Rossum8b48cf92001-04-21 13:33:54 +000068 except StopIteration:
69 break
70 res.append(val)
71 self.assertEqual(res, seq)
72
73 # Helper to check that a for loop generates a given sequence
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +000074 def check_for_loop(self, expr, seq, pickle=True):
75 if pickle:
76 self.check_pickle(iter(expr), seq)
Guido van Rossum8b48cf92001-04-21 13:33:54 +000077 res = []
78 for val in expr:
79 res.append(val)
80 self.assertEqual(res, seq)
81
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +000082 # Helper to check picklability
83 def check_pickle(self, itorg, seq):
Serhiy Storchakabad12572014-12-15 14:03:42 +020084 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
85 d = pickle.dumps(itorg, proto)
86 it = pickle.loads(d)
87 # Cannot assert type equality because dict iterators unpickle as list
88 # iterators.
89 # self.assertEqual(type(itorg), type(it))
90 self.assertTrue(isinstance(it, collections.abc.Iterator))
91 self.assertEqual(list(it), seq)
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +000092
Serhiy Storchakabad12572014-12-15 14:03:42 +020093 it = pickle.loads(d)
94 try:
95 next(it)
96 except StopIteration:
97 continue
98 d = pickle.dumps(it, proto)
99 it = pickle.loads(d)
100 self.assertEqual(list(it), seq[1:])
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000101
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000102 # Test basic use of iter() function
103 def test_iter_basic(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000104 self.check_iterator(iter(range(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000105
106 # Test that iter(iter(x)) is the same as iter(x)
107 def test_iter_idempotency(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000108 seq = list(range(10))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000109 it = iter(seq)
110 it2 = iter(it)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000111 self.assertTrue(it is it2)
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000112
113 # Test that for loops over iterators work
114 def test_iter_for_loop(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000115 self.check_for_loop(iter(range(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000116
117 # Test several independent iterators over the same list
118 def test_iter_independence(self):
119 seq = range(3)
120 res = []
121 for i in iter(seq):
122 for j in iter(seq):
123 for k in iter(seq):
124 res.append((i, j, k))
125 self.assertEqual(res, TRIPLETS)
126
127 # Test triple list comprehension using iterators
128 def test_nested_comprehensions_iter(self):
129 seq = range(3)
130 res = [(i, j, k)
131 for i in iter(seq) for j in iter(seq) for k in iter(seq)]
132 self.assertEqual(res, TRIPLETS)
133
134 # Test triple list comprehension without iterators
135 def test_nested_comprehensions_for(self):
136 seq = range(3)
137 res = [(i, j, k) for i in seq for j in seq for k in seq]
138 self.assertEqual(res, TRIPLETS)
139
140 # Test a class with __iter__ in a for loop
141 def test_iter_class_for(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000142 self.check_for_loop(IteratingSequenceClass(10), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000143
144 # Test a class with __iter__ with explicit iter()
145 def test_iter_class_iter(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000146 self.check_iterator(iter(IteratingSequenceClass(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000147
148 # Test for loop on a sequence class without __iter__
149 def test_seq_class_for(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000150 self.check_for_loop(SequenceClass(10), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000151
152 # Test iter() on a sequence class without __iter__
153 def test_seq_class_iter(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000154 self.check_iterator(iter(SequenceClass(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000155
Amaury Forgeot d'Arcf343e012009-01-12 23:58:21 +0000156 # Test a new_style class with __iter__ but no next() method
157 def test_new_style_iter_class(self):
158 class IterClass(object):
159 def __iter__(self):
160 return self
161 self.assertRaises(TypeError, iter, IterClass())
162
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000163 # Test two-argument iter() with callable instance
164 def test_iter_callable(self):
165 class C:
166 def __init__(self):
167 self.i = 0
168 def __call__(self):
169 i = self.i
170 self.i = i + 1
171 if i > 100:
172 raise IndexError # Emergency stop
173 return i
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000174 self.check_iterator(iter(C(), 10), list(range(10)), pickle=False)
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000175
176 # Test two-argument iter() with function
177 def test_iter_function(self):
178 def spam(state=[0]):
179 i = state[0]
180 state[0] = i+1
181 return i
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000182 self.check_iterator(iter(spam, 10), list(range(10)), pickle=False)
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000183
184 # Test two-argument iter() with function that raises StopIteration
185 def test_iter_function_stop(self):
186 def spam(state=[0]):
187 i = state[0]
188 if i == 10:
189 raise StopIteration
190 state[0] = i+1
191 return i
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000192 self.check_iterator(iter(spam, 20), list(range(10)), pickle=False)
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000193
194 # Test exception propagation through function iterator
195 def test_exception_function(self):
196 def spam(state=[0]):
197 i = state[0]
198 state[0] = i+1
199 if i == 10:
200 raise RuntimeError
201 return i
202 res = []
203 try:
204 for x in iter(spam, 20):
205 res.append(x)
206 except RuntimeError:
Guido van Rossum805365e2007-05-07 22:24:25 +0000207 self.assertEqual(res, list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000208 else:
209 self.fail("should have raised RuntimeError")
210
211 # Test exception propagation through sequence iterator
212 def test_exception_sequence(self):
213 class MySequenceClass(SequenceClass):
214 def __getitem__(self, i):
215 if i == 10:
216 raise RuntimeError
217 return SequenceClass.__getitem__(self, i)
218 res = []
219 try:
220 for x in MySequenceClass(20):
221 res.append(x)
222 except RuntimeError:
Guido van Rossum805365e2007-05-07 22:24:25 +0000223 self.assertEqual(res, list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000224 else:
225 self.fail("should have raised RuntimeError")
226
227 # Test for StopIteration from __getitem__
228 def test_stop_sequence(self):
229 class MySequenceClass(SequenceClass):
230 def __getitem__(self, i):
231 if i == 10:
232 raise StopIteration
233 return SequenceClass.__getitem__(self, i)
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000234 self.check_for_loop(MySequenceClass(20), list(range(10)), pickle=False)
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000235
236 # Test a big range
237 def test_iter_big_range(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000238 self.check_for_loop(iter(range(10000)), list(range(10000)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000239
240 # Test an empty list
241 def test_iter_empty(self):
242 self.check_for_loop(iter([]), [])
243
244 # Test a tuple
245 def test_iter_tuple(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000246 self.check_for_loop(iter((0,1,2,3,4,5,6,7,8,9)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000247
Guido van Rossum805365e2007-05-07 22:24:25 +0000248 # Test a range
249 def test_iter_range(self):
250 self.check_for_loop(iter(range(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000251
252 # Test a string
253 def test_iter_string(self):
254 self.check_for_loop(iter("abcde"), ["a", "b", "c", "d", "e"])
255
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000256 # Test a directory
257 def test_iter_dict(self):
258 dict = {}
259 for i in range(10):
260 dict[i] = None
Brett Cannon0caf6d82007-02-22 04:49:03 +0000261 self.check_for_loop(dict, list(dict.keys()))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000262
263 # Test a file
264 def test_iter_file(self):
265 f = open(TESTFN, "w")
266 try:
267 for i in range(5):
268 f.write("%d\n" % i)
269 finally:
270 f.close()
271 f = open(TESTFN, "r")
272 try:
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000273 self.check_for_loop(f, ["0\n", "1\n", "2\n", "3\n", "4\n"], pickle=False)
274 self.check_for_loop(f, [], pickle=False)
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000275 finally:
276 f.close()
277 try:
278 unlink(TESTFN)
279 except OSError:
280 pass
281
Tim Petersf553f892001-05-01 20:45:31 +0000282 # Test list()'s use of iterators.
283 def test_builtin_list(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000284 self.assertEqual(list(SequenceClass(5)), list(range(5)))
Tim Petersf553f892001-05-01 20:45:31 +0000285 self.assertEqual(list(SequenceClass(0)), [])
286 self.assertEqual(list(()), [])
Tim Petersf553f892001-05-01 20:45:31 +0000287
288 d = {"one": 1, "two": 2, "three": 3}
Brett Cannon0caf6d82007-02-22 04:49:03 +0000289 self.assertEqual(list(d), list(d.keys()))
Tim Petersf553f892001-05-01 20:45:31 +0000290
291 self.assertRaises(TypeError, list, list)
292 self.assertRaises(TypeError, list, 42)
293
294 f = open(TESTFN, "w")
295 try:
296 for i in range(5):
297 f.write("%d\n" % i)
298 finally:
299 f.close()
300 f = open(TESTFN, "r")
301 try:
302 self.assertEqual(list(f), ["0\n", "1\n", "2\n", "3\n", "4\n"])
303 f.seek(0, 0)
Guido van Rossum8ee52432002-08-06 17:14:04 +0000304 self.assertEqual(list(f),
Tim Petersf553f892001-05-01 20:45:31 +0000305 ["0\n", "1\n", "2\n", "3\n", "4\n"])
306 finally:
307 f.close()
308 try:
309 unlink(TESTFN)
310 except OSError:
311 pass
312
Tim Peters6912d4d2001-05-05 03:56:37 +0000313 # Test tuples()'s use of iterators.
314 def test_builtin_tuple(self):
315 self.assertEqual(tuple(SequenceClass(5)), (0, 1, 2, 3, 4))
316 self.assertEqual(tuple(SequenceClass(0)), ())
317 self.assertEqual(tuple([]), ())
318 self.assertEqual(tuple(()), ())
319 self.assertEqual(tuple("abc"), ("a", "b", "c"))
320
321 d = {"one": 1, "two": 2, "three": 3}
322 self.assertEqual(tuple(d), tuple(d.keys()))
323
324 self.assertRaises(TypeError, tuple, list)
325 self.assertRaises(TypeError, tuple, 42)
326
327 f = open(TESTFN, "w")
328 try:
329 for i in range(5):
330 f.write("%d\n" % i)
331 finally:
332 f.close()
333 f = open(TESTFN, "r")
334 try:
335 self.assertEqual(tuple(f), ("0\n", "1\n", "2\n", "3\n", "4\n"))
336 f.seek(0, 0)
Guido van Rossum8ee52432002-08-06 17:14:04 +0000337 self.assertEqual(tuple(f),
Tim Peters6912d4d2001-05-05 03:56:37 +0000338 ("0\n", "1\n", "2\n", "3\n", "4\n"))
339 finally:
340 f.close()
341 try:
342 unlink(TESTFN)
343 except OSError:
344 pass
345
Tim Peters0e57abf2001-05-02 07:39:38 +0000346 # Test filter()'s use of iterators.
347 def test_builtin_filter(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000348 self.assertEqual(list(filter(None, SequenceClass(5))),
349 list(range(1, 5)))
350 self.assertEqual(list(filter(None, SequenceClass(0))), [])
351 self.assertEqual(list(filter(None, ())), [])
352 self.assertEqual(list(filter(None, "abc")), ["a", "b", "c"])
Tim Peters0e57abf2001-05-02 07:39:38 +0000353
354 d = {"one": 1, "two": 2, "three": 3}
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000355 self.assertEqual(list(filter(None, d)), list(d.keys()))
Tim Peters0e57abf2001-05-02 07:39:38 +0000356
357 self.assertRaises(TypeError, filter, None, list)
358 self.assertRaises(TypeError, filter, None, 42)
359
360 class Boolean:
361 def __init__(self, truth):
362 self.truth = truth
Jack Diederich4dafcc42006-11-28 19:15:13 +0000363 def __bool__(self):
Tim Peters0e57abf2001-05-02 07:39:38 +0000364 return self.truth
Jack Diederich4dafcc42006-11-28 19:15:13 +0000365 bTrue = Boolean(True)
366 bFalse = Boolean(False)
Tim Peters0e57abf2001-05-02 07:39:38 +0000367
368 class Seq:
369 def __init__(self, *args):
370 self.vals = args
371 def __iter__(self):
372 class SeqIter:
373 def __init__(self, vals):
374 self.vals = vals
375 self.i = 0
376 def __iter__(self):
377 return self
Georg Brandla18af4e2007-04-21 15:47:16 +0000378 def __next__(self):
Tim Peters0e57abf2001-05-02 07:39:38 +0000379 i = self.i
380 self.i = i + 1
381 if i < len(self.vals):
382 return self.vals[i]
383 else:
384 raise StopIteration
385 return SeqIter(self.vals)
386
Tim Peterscae330e2002-12-23 16:50:58 +0000387 seq = Seq(*([bTrue, bFalse] * 25))
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000388 self.assertEqual(list(filter(lambda x: not x, seq)), [bFalse]*25)
389 self.assertEqual(list(filter(lambda x: not x, iter(seq))), [bFalse]*25)
Tim Peters0e57abf2001-05-02 07:39:38 +0000390
Tim Petersc3074532001-05-03 07:00:32 +0000391 # Test max() and min()'s use of iterators.
392 def test_builtin_max_min(self):
393 self.assertEqual(max(SequenceClass(5)), 4)
394 self.assertEqual(min(SequenceClass(5)), 0)
395 self.assertEqual(max(8, -1), 8)
396 self.assertEqual(min(8, -1), -1)
397
398 d = {"one": 1, "two": 2, "three": 3}
399 self.assertEqual(max(d), "two")
400 self.assertEqual(min(d), "one")
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000401 self.assertEqual(max(d.values()), 3)
402 self.assertEqual(min(iter(d.values())), 1)
Tim Petersc3074532001-05-03 07:00:32 +0000403
Tim Petersc3074532001-05-03 07:00:32 +0000404 f = open(TESTFN, "w")
405 try:
406 f.write("medium line\n")
407 f.write("xtra large line\n")
408 f.write("itty-bitty line\n")
409 finally:
410 f.close()
411 f = open(TESTFN, "r")
412 try:
413 self.assertEqual(min(f), "itty-bitty line\n")
414 f.seek(0, 0)
415 self.assertEqual(max(f), "xtra large line\n")
416 finally:
417 f.close()
418 try:
419 unlink(TESTFN)
420 except OSError:
421 pass
422
Tim Peters4e9afdc2001-05-03 23:54:49 +0000423 # Test map()'s use of iterators.
424 def test_builtin_map(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000425 self.assertEqual(list(map(lambda x: x+1, SequenceClass(5))),
426 list(range(1, 6)))
Tim Peters4e9afdc2001-05-03 23:54:49 +0000427
428 d = {"one": 1, "two": 2, "three": 3}
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000429 self.assertEqual(list(map(lambda k, d=d: (k, d[k]), d)),
430 list(d.items()))
Brett Cannon0caf6d82007-02-22 04:49:03 +0000431 dkeys = list(d.keys())
Tim Peters4e9afdc2001-05-03 23:54:49 +0000432 expected = [(i < len(d) and dkeys[i] or None,
433 i,
434 i < len(d) and dkeys[i] or None)
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000435 for i in range(3)]
Tim Peters4e9afdc2001-05-03 23:54:49 +0000436
437 f = open(TESTFN, "w")
438 try:
439 for i in range(10):
440 f.write("xy" * i + "\n") # line i has len 2*i+1
441 finally:
442 f.close()
443 f = open(TESTFN, "r")
444 try:
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000445 self.assertEqual(list(map(len, f)), list(range(1, 21, 2)))
Tim Peters4e9afdc2001-05-03 23:54:49 +0000446 finally:
447 f.close()
448 try:
449 unlink(TESTFN)
450 except OSError:
451 pass
452
Tim Peters8572b4f2001-05-06 01:05:02 +0000453 # Test zip()'s use of iterators.
454 def test_builtin_zip(self):
Guido van Rossum801f0d72006-08-24 19:48:10 +0000455 self.assertEqual(list(zip()), [])
456 self.assertEqual(list(zip(*[])), [])
457 self.assertEqual(list(zip(*[(1, 2), 'ab'])), [(1, 'a'), (2, 'b')])
Raymond Hettingereaef6152003-08-02 07:42:57 +0000458
Tim Peters8572b4f2001-05-06 01:05:02 +0000459 self.assertRaises(TypeError, zip, None)
460 self.assertRaises(TypeError, zip, range(10), 42)
461 self.assertRaises(TypeError, zip, range(10), zip)
462
Guido van Rossum801f0d72006-08-24 19:48:10 +0000463 self.assertEqual(list(zip(IteratingSequenceClass(3))),
Tim Peters8572b4f2001-05-06 01:05:02 +0000464 [(0,), (1,), (2,)])
Guido van Rossum801f0d72006-08-24 19:48:10 +0000465 self.assertEqual(list(zip(SequenceClass(3))),
Tim Peters8572b4f2001-05-06 01:05:02 +0000466 [(0,), (1,), (2,)])
467
468 d = {"one": 1, "two": 2, "three": 3}
Brett Cannon0caf6d82007-02-22 04:49:03 +0000469 self.assertEqual(list(d.items()), list(zip(d, d.values())))
Tim Peters8572b4f2001-05-06 01:05:02 +0000470
471 # Generate all ints starting at constructor arg.
472 class IntsFrom:
473 def __init__(self, start):
474 self.i = start
475
476 def __iter__(self):
477 return self
478
Georg Brandla18af4e2007-04-21 15:47:16 +0000479 def __next__(self):
Tim Peters8572b4f2001-05-06 01:05:02 +0000480 i = self.i
481 self.i = i+1
482 return i
483
484 f = open(TESTFN, "w")
485 try:
486 f.write("a\n" "bbb\n" "cc\n")
487 finally:
488 f.close()
489 f = open(TESTFN, "r")
490 try:
Guido van Rossum801f0d72006-08-24 19:48:10 +0000491 self.assertEqual(list(zip(IntsFrom(0), f, IntsFrom(-100))),
Tim Peters8572b4f2001-05-06 01:05:02 +0000492 [(0, "a\n", -100),
493 (1, "bbb\n", -99),
494 (2, "cc\n", -98)])
495 finally:
496 f.close()
497 try:
498 unlink(TESTFN)
499 except OSError:
500 pass
501
Guido van Rossum805365e2007-05-07 22:24:25 +0000502 self.assertEqual(list(zip(range(5))), [(i,) for i in range(5)])
Tim Peters67d687a2002-04-29 21:27:32 +0000503
504 # Classes that lie about their lengths.
505 class NoGuessLen5:
506 def __getitem__(self, i):
507 if i >= 5:
508 raise IndexError
509 return i
510
511 class Guess3Len5(NoGuessLen5):
512 def __len__(self):
513 return 3
514
515 class Guess30Len5(NoGuessLen5):
516 def __len__(self):
517 return 30
518
Guido van Rossum801f0d72006-08-24 19:48:10 +0000519 def lzip(*args):
520 return list(zip(*args))
521
Tim Peters67d687a2002-04-29 21:27:32 +0000522 self.assertEqual(len(Guess3Len5()), 3)
523 self.assertEqual(len(Guess30Len5()), 30)
Guido van Rossum801f0d72006-08-24 19:48:10 +0000524 self.assertEqual(lzip(NoGuessLen5()), lzip(range(5)))
525 self.assertEqual(lzip(Guess3Len5()), lzip(range(5)))
526 self.assertEqual(lzip(Guess30Len5()), lzip(range(5)))
Tim Peters67d687a2002-04-29 21:27:32 +0000527
528 expected = [(i, i) for i in range(5)]
529 for x in NoGuessLen5(), Guess3Len5(), Guess30Len5():
530 for y in NoGuessLen5(), Guess3Len5(), Guess30Len5():
Guido van Rossum801f0d72006-08-24 19:48:10 +0000531 self.assertEqual(lzip(x, y), expected)
Tim Peters67d687a2002-04-29 21:27:32 +0000532
Tim Peters2cfe3682001-05-05 05:36:48 +0000533 def test_unicode_join_endcase(self):
534
535 # This class inserts a Unicode object into its argument's natural
536 # iteration, in the 3rd position.
537 class OhPhooey:
538 def __init__(self, seq):
539 self.it = iter(seq)
540 self.i = 0
541
542 def __iter__(self):
543 return self
544
Georg Brandla18af4e2007-04-21 15:47:16 +0000545 def __next__(self):
Tim Peters2cfe3682001-05-05 05:36:48 +0000546 i = self.i
547 self.i = i+1
548 if i == 2:
Walter Dörwald1f5947b2007-05-22 16:52:54 +0000549 return "fooled you!"
Georg Brandla18af4e2007-04-21 15:47:16 +0000550 return next(self.it)
Tim Peters2cfe3682001-05-05 05:36:48 +0000551
552 f = open(TESTFN, "w")
553 try:
554 f.write("a\n" + "b\n" + "c\n")
555 finally:
556 f.close()
557
558 f = open(TESTFN, "r")
559 # Nasty: string.join(s) can't know whether unicode.join() is needed
560 # until it's seen all of s's elements. But in this case, f's
561 # iterator cannot be restarted. So what we're testing here is
562 # whether string.join() can manage to remember everything it's seen
563 # and pass that on to unicode.join().
564 try:
565 got = " - ".join(OhPhooey(f))
Walter Dörwald5de48bd2007-06-11 21:38:39 +0000566 self.assertEqual(got, "a\n - b\n - fooled you! - c\n")
Tim Peters2cfe3682001-05-05 05:36:48 +0000567 finally:
568 f.close()
569 try:
570 unlink(TESTFN)
571 except OSError:
572 pass
573
Tim Petersde9725f2001-05-05 10:06:17 +0000574 # Test iterators with 'x in y' and 'x not in y'.
575 def test_in_and_not_in(self):
Tim Peterscb8d3682001-05-05 21:05:01 +0000576 for sc5 in IteratingSequenceClass(5), SequenceClass(5):
577 for i in range(5):
Benjamin Peterson577473f2010-01-19 00:09:57 +0000578 self.assertIn(i, sc5)
Tim Peterscb8d3682001-05-05 21:05:01 +0000579 for i in "abc", -1, 5, 42.42, (3, 4), [], {1: 1}, 3-12j, sc5:
Benjamin Peterson577473f2010-01-19 00:09:57 +0000580 self.assertNotIn(i, sc5)
Tim Petersde9725f2001-05-05 10:06:17 +0000581
582 self.assertRaises(TypeError, lambda: 3 in 12)
583 self.assertRaises(TypeError, lambda: 3 not in map)
584
585 d = {"one": 1, "two": 2, "three": 3, 1j: 2j}
586 for k in d:
Benjamin Peterson577473f2010-01-19 00:09:57 +0000587 self.assertIn(k, d)
588 self.assertNotIn(k, d.values())
Tim Petersde9725f2001-05-05 10:06:17 +0000589 for v in d.values():
Benjamin Peterson577473f2010-01-19 00:09:57 +0000590 self.assertIn(v, d.values())
591 self.assertNotIn(v, d)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000592 for k, v in d.items():
Benjamin Peterson577473f2010-01-19 00:09:57 +0000593 self.assertIn((k, v), d.items())
594 self.assertNotIn((v, k), d.items())
Tim Petersde9725f2001-05-05 10:06:17 +0000595
596 f = open(TESTFN, "w")
597 try:
598 f.write("a\n" "b\n" "c\n")
599 finally:
600 f.close()
601 f = open(TESTFN, "r")
602 try:
603 for chunk in "abc":
604 f.seek(0, 0)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000605 self.assertNotIn(chunk, f)
Tim Petersde9725f2001-05-05 10:06:17 +0000606 f.seek(0, 0)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000607 self.assertIn((chunk + "\n"), f)
Tim Petersde9725f2001-05-05 10:06:17 +0000608 finally:
609 f.close()
610 try:
611 unlink(TESTFN)
612 except OSError:
613 pass
614
Tim Peters75f8e352001-05-05 11:33:43 +0000615 # Test iterators with operator.countOf (PySequence_Count).
616 def test_countOf(self):
617 from operator import countOf
618 self.assertEqual(countOf([1,2,2,3,2,5], 2), 3)
619 self.assertEqual(countOf((1,2,2,3,2,5), 2), 3)
620 self.assertEqual(countOf("122325", "2"), 3)
621 self.assertEqual(countOf("122325", "6"), 0)
622
623 self.assertRaises(TypeError, countOf, 42, 1)
624 self.assertRaises(TypeError, countOf, countOf, countOf)
625
626 d = {"one": 3, "two": 3, "three": 3, 1j: 2j}
627 for k in d:
628 self.assertEqual(countOf(d, k), 1)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000629 self.assertEqual(countOf(d.values(), 3), 3)
630 self.assertEqual(countOf(d.values(), 2j), 1)
631 self.assertEqual(countOf(d.values(), 1j), 0)
Tim Peters75f8e352001-05-05 11:33:43 +0000632
633 f = open(TESTFN, "w")
634 try:
635 f.write("a\n" "b\n" "c\n" "b\n")
636 finally:
637 f.close()
638 f = open(TESTFN, "r")
639 try:
640 for letter, count in ("a", 1), ("b", 2), ("c", 1), ("d", 0):
641 f.seek(0, 0)
642 self.assertEqual(countOf(f, letter + "\n"), count)
643 finally:
644 f.close()
645 try:
646 unlink(TESTFN)
647 except OSError:
648 pass
649
Tim Peters16a77ad2001-09-08 04:00:12 +0000650 # Test iterators with operator.indexOf (PySequence_Index).
651 def test_indexOf(self):
652 from operator import indexOf
653 self.assertEqual(indexOf([1,2,2,3,2,5], 1), 0)
654 self.assertEqual(indexOf((1,2,2,3,2,5), 2), 1)
655 self.assertEqual(indexOf((1,2,2,3,2,5), 3), 3)
656 self.assertEqual(indexOf((1,2,2,3,2,5), 5), 5)
657 self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 0)
658 self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 6)
659
660 self.assertEqual(indexOf("122325", "2"), 1)
661 self.assertEqual(indexOf("122325", "5"), 5)
662 self.assertRaises(ValueError, indexOf, "122325", "6")
663
664 self.assertRaises(TypeError, indexOf, 42, 1)
665 self.assertRaises(TypeError, indexOf, indexOf, indexOf)
666
667 f = open(TESTFN, "w")
668 try:
669 f.write("a\n" "b\n" "c\n" "d\n" "e\n")
670 finally:
671 f.close()
672 f = open(TESTFN, "r")
673 try:
674 fiter = iter(f)
675 self.assertEqual(indexOf(fiter, "b\n"), 1)
676 self.assertEqual(indexOf(fiter, "d\n"), 1)
677 self.assertEqual(indexOf(fiter, "e\n"), 0)
678 self.assertRaises(ValueError, indexOf, fiter, "a\n")
679 finally:
680 f.close()
681 try:
682 unlink(TESTFN)
683 except OSError:
684 pass
685
686 iclass = IteratingSequenceClass(3)
687 for i in range(3):
688 self.assertEqual(indexOf(iclass, i), i)
689 self.assertRaises(ValueError, indexOf, iclass, -1)
690
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000691 # Test iterators with file.writelines().
692 def test_writelines(self):
Alex Martelli01c77c62006-08-24 02:58:11 +0000693 f = open(TESTFN, "w")
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000694
695 try:
696 self.assertRaises(TypeError, f.writelines, None)
697 self.assertRaises(TypeError, f.writelines, 42)
Tim Peters527e64f2001-10-04 05:36:56 +0000698
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000699 f.writelines(["1\n", "2\n"])
700 f.writelines(("3\n", "4\n"))
701 f.writelines({'5\n': None})
702 f.writelines({})
703
704 # Try a big chunk too.
705 class Iterator:
706 def __init__(self, start, finish):
707 self.start = start
708 self.finish = finish
709 self.i = self.start
710
Georg Brandla18af4e2007-04-21 15:47:16 +0000711 def __next__(self):
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000712 if self.i >= self.finish:
713 raise StopIteration
714 result = str(self.i) + '\n'
715 self.i += 1
716 return result
717
718 def __iter__(self):
719 return self
720
721 class Whatever:
722 def __init__(self, start, finish):
723 self.start = start
724 self.finish = finish
725
726 def __iter__(self):
727 return Iterator(self.start, self.finish)
Tim Peters527e64f2001-10-04 05:36:56 +0000728
729 f.writelines(Whatever(6, 6+2000))
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000730 f.close()
731
Alex Martelli01c77c62006-08-24 02:58:11 +0000732 f = open(TESTFN)
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000733 expected = [str(i) + "\n" for i in range(1, 2006)]
734 self.assertEqual(list(f), expected)
Tim Peters527e64f2001-10-04 05:36:56 +0000735
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000736 finally:
737 f.close()
738 try:
739 unlink(TESTFN)
740 except OSError:
741 pass
742
743
Tim Petersd6d010b2001-06-21 02:49:55 +0000744 # Test iterators on RHS of unpacking assignments.
745 def test_unpack_iter(self):
746 a, b = 1, 2
747 self.assertEqual((a, b), (1, 2))
748
749 a, b, c = IteratingSequenceClass(3)
750 self.assertEqual((a, b, c), (0, 1, 2))
751
752 try: # too many values
753 a, b = IteratingSequenceClass(3)
754 except ValueError:
755 pass
756 else:
757 self.fail("should have raised ValueError")
758
759 try: # not enough values
760 a, b, c = IteratingSequenceClass(2)
761 except ValueError:
762 pass
763 else:
764 self.fail("should have raised ValueError")
765
766 try: # not iterable
767 a, b, c = len
768 except TypeError:
769 pass
770 else:
771 self.fail("should have raised TypeError")
772
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000773 a, b, c = {1: 42, 2: 42, 3: 42}.values()
Tim Petersd6d010b2001-06-21 02:49:55 +0000774 self.assertEqual((a, b, c), (42, 42, 42))
775
776 f = open(TESTFN, "w")
777 lines = ("a\n", "bb\n", "ccc\n")
778 try:
779 for line in lines:
780 f.write(line)
781 finally:
782 f.close()
783 f = open(TESTFN, "r")
784 try:
785 a, b, c = f
786 self.assertEqual((a, b, c), lines)
787 finally:
788 f.close()
789 try:
790 unlink(TESTFN)
791 except OSError:
792 pass
793
794 (a, b), (c,) = IteratingSequenceClass(2), {42: 24}
795 self.assertEqual((a, b, c), (0, 1, 42))
796
Guido van Rossumbb8f59a2001-12-03 19:33:25 +0000797
Benjamin Peterson945c5792010-06-22 20:34:34 +0000798 @cpython_only
799 def test_ref_counting_behavior(self):
Guido van Rossumbb8f59a2001-12-03 19:33:25 +0000800 class C(object):
801 count = 0
802 def __new__(cls):
803 cls.count += 1
804 return object.__new__(cls)
805 def __del__(self):
806 cls = self.__class__
807 assert cls.count > 0
808 cls.count -= 1
809 x = C()
810 self.assertEqual(C.count, 1)
811 del x
812 self.assertEqual(C.count, 0)
813 l = [C(), C(), C()]
814 self.assertEqual(C.count, 3)
815 try:
816 a, b = iter(l)
817 except ValueError:
818 pass
819 del l
820 self.assertEqual(C.count, 0)
Fred Drake2e2be372001-09-20 21:33:42 +0000821
Guido van Rossum674eae62002-07-16 21:48:11 +0000822
823 # Make sure StopIteration is a "sink state".
824 # This tests various things that weren't sink states in Python 2.2.1,
825 # plus various things that always were fine.
826
827 def test_sinkstate_list(self):
828 # This used to fail
Guido van Rossum805365e2007-05-07 22:24:25 +0000829 a = list(range(5))
Guido van Rossum674eae62002-07-16 21:48:11 +0000830 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000831 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000832 a.extend(range(5, 10))
833 self.assertEqual(list(b), [])
834
835 def test_sinkstate_tuple(self):
836 a = (0, 1, 2, 3, 4)
837 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000838 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000839 self.assertEqual(list(b), [])
840
841 def test_sinkstate_string(self):
842 a = "abcde"
843 b = iter(a)
844 self.assertEqual(list(b), ['a', 'b', 'c', 'd', 'e'])
845 self.assertEqual(list(b), [])
846
847 def test_sinkstate_sequence(self):
848 # This used to fail
849 a = SequenceClass(5)
850 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000851 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000852 a.n = 10
853 self.assertEqual(list(b), [])
854
855 def test_sinkstate_callable(self):
856 # This used to fail
857 def spam(state=[0]):
858 i = state[0]
859 state[0] = i+1
860 if i == 10:
Collin Winter3add4d72007-08-29 23:37:32 +0000861 raise AssertionError("shouldn't have gotten this far")
Guido van Rossum674eae62002-07-16 21:48:11 +0000862 return i
863 b = iter(spam, 5)
Guido van Rossum805365e2007-05-07 22:24:25 +0000864 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000865 self.assertEqual(list(b), [])
866
867 def test_sinkstate_dict(self):
868 # XXX For a more thorough test, see towards the end of:
869 # http://mail.python.org/pipermail/python-dev/2002-July/026512.html
870 a = {1:1, 2:2, 0:0, 4:4, 3:3}
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000871 for b in iter(a), a.keys(), a.items(), a.values():
Guido van Rossum674eae62002-07-16 21:48:11 +0000872 b = iter(a)
873 self.assertEqual(len(list(b)), 5)
874 self.assertEqual(list(b), [])
875
876 def test_sinkstate_yield(self):
877 def gen():
878 for i in range(5):
879 yield i
880 b = gen()
Guido van Rossum805365e2007-05-07 22:24:25 +0000881 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000882 self.assertEqual(list(b), [])
883
884 def test_sinkstate_range(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000885 a = range(5)
Guido van Rossum674eae62002-07-16 21:48:11 +0000886 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000887 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000888 self.assertEqual(list(b), [])
889
890 def test_sinkstate_enumerate(self):
891 a = range(5)
892 e = enumerate(a)
893 b = iter(e)
Guido van Rossum801f0d72006-08-24 19:48:10 +0000894 self.assertEqual(list(b), list(zip(range(5), range(5))))
Guido van Rossum674eae62002-07-16 21:48:11 +0000895 self.assertEqual(list(b), [])
896
Amaury Forgeot d'Arcf343e012009-01-12 23:58:21 +0000897 def test_3720(self):
898 # Avoid a crash, when an iterator deletes its next() method.
899 class BadIterator(object):
900 def __iter__(self):
901 return self
902 def __next__(self):
903 del BadIterator.__next__
904 return 1
905
906 try:
907 for i in BadIterator() :
908 pass
909 except TypeError:
910 pass
911
Ezio Melotti739e1792012-11-18 23:16:02 +0200912 def test_extending_list_with_iterator_does_not_segfault(self):
913 # The code to extend a list with an iterator has a fair
914 # amount of nontrivial logic in terms of guessing how
915 # much memory to allocate in advance, "stealing" refs,
916 # and then shrinking at the end. This is a basic smoke
917 # test for that scenario.
918 def gen():
919 for i in range(500):
920 yield i
921 lst = [0] * 500
922 for i in range(240):
923 lst.pop(0)
924 lst.extend(gen())
925 self.assertEqual(len(lst), 760)
926
Serhiy Storchaka4faf5c52015-05-21 20:50:25 +0300927 @cpython_only
928 def test_iter_overflow(self):
929 # Test for the issue 22939
930 it = iter(UnlimitedSequenceClass())
931 # Manually set `it_index` to PY_SSIZE_T_MAX-2 without a loop
932 it.__setstate__(sys.maxsize - 2)
933 self.assertEqual(next(it), sys.maxsize - 2)
934 self.assertEqual(next(it), sys.maxsize - 1)
935 with self.assertRaises(OverflowError):
936 next(it)
937 # Check that Overflow error is always raised
938 with self.assertRaises(OverflowError):
939 next(it)
940
941 def test_iter_neg_setstate(self):
942 it = iter(UnlimitedSequenceClass())
943 it.__setstate__(-42)
944 self.assertEqual(next(it), 0)
945 self.assertEqual(next(it), 1)
946
Guido van Rossum674eae62002-07-16 21:48:11 +0000947
Fred Drake2e2be372001-09-20 21:33:42 +0000948def test_main():
949 run_unittest(TestCase)
950
951
952if __name__ == "__main__":
953 test_main()