blob: a91670b4a11fba6902b13747d73bec906815782f [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
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +03006from test.support import check_free_after_iterating
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00007import pickle
8import collections.abc
Guido van Rossum8b48cf92001-04-21 13:33:54 +00009
10# Test result of triple loop (too big to inline)
11TRIPLETS = [(0, 0, 0), (0, 0, 1), (0, 0, 2),
12 (0, 1, 0), (0, 1, 1), (0, 1, 2),
13 (0, 2, 0), (0, 2, 1), (0, 2, 2),
14
15 (1, 0, 0), (1, 0, 1), (1, 0, 2),
16 (1, 1, 0), (1, 1, 1), (1, 1, 2),
17 (1, 2, 0), (1, 2, 1), (1, 2, 2),
18
19 (2, 0, 0), (2, 0, 1), (2, 0, 2),
20 (2, 1, 0), (2, 1, 1), (2, 1, 2),
21 (2, 2, 0), (2, 2, 1), (2, 2, 2)]
22
23# Helper classes
24
25class BasicIterClass:
26 def __init__(self, n):
27 self.n = n
28 self.i = 0
Georg Brandla18af4e2007-04-21 15:47:16 +000029 def __next__(self):
Guido van Rossum8b48cf92001-04-21 13:33:54 +000030 res = self.i
31 if res >= self.n:
32 raise StopIteration
33 self.i = res + 1
34 return res
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +000035 def __iter__(self):
36 return self
Guido van Rossum8b48cf92001-04-21 13:33:54 +000037
38class IteratingSequenceClass:
39 def __init__(self, n):
40 self.n = n
41 def __iter__(self):
42 return BasicIterClass(self.n)
43
44class SequenceClass:
45 def __init__(self, n):
46 self.n = n
47 def __getitem__(self, i):
48 if 0 <= i < self.n:
49 return i
50 else:
51 raise IndexError
52
Serhiy Storchaka4faf5c52015-05-21 20:50:25 +030053class UnlimitedSequenceClass:
54 def __getitem__(self, i):
55 return i
56
Guido van Rossum8b48cf92001-04-21 13:33:54 +000057# Main test suite
58
59class TestCase(unittest.TestCase):
60
61 # Helper to check that an iterator returns a given sequence
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +000062 def check_iterator(self, it, seq, pickle=True):
63 if pickle:
64 self.check_pickle(it, seq)
Guido van Rossum8b48cf92001-04-21 13:33:54 +000065 res = []
66 while 1:
67 try:
Georg Brandla18af4e2007-04-21 15:47:16 +000068 val = next(it)
Guido van Rossum8b48cf92001-04-21 13:33:54 +000069 except StopIteration:
70 break
71 res.append(val)
72 self.assertEqual(res, seq)
73
74 # Helper to check that a for loop generates a given sequence
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +000075 def check_for_loop(self, expr, seq, pickle=True):
76 if pickle:
77 self.check_pickle(iter(expr), seq)
Guido van Rossum8b48cf92001-04-21 13:33:54 +000078 res = []
79 for val in expr:
80 res.append(val)
81 self.assertEqual(res, seq)
82
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +000083 # Helper to check picklability
84 def check_pickle(self, itorg, seq):
Serhiy Storchakabad12572014-12-15 14:03:42 +020085 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
86 d = pickle.dumps(itorg, proto)
87 it = pickle.loads(d)
88 # Cannot assert type equality because dict iterators unpickle as list
89 # iterators.
90 # self.assertEqual(type(itorg), type(it))
91 self.assertTrue(isinstance(it, collections.abc.Iterator))
92 self.assertEqual(list(it), seq)
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +000093
Serhiy Storchakabad12572014-12-15 14:03:42 +020094 it = pickle.loads(d)
95 try:
96 next(it)
97 except StopIteration:
98 continue
99 d = pickle.dumps(it, proto)
100 it = pickle.loads(d)
101 self.assertEqual(list(it), seq[1:])
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000102
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000103 # Test basic use of iter() function
104 def test_iter_basic(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000105 self.check_iterator(iter(range(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000106
107 # Test that iter(iter(x)) is the same as iter(x)
108 def test_iter_idempotency(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000109 seq = list(range(10))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000110 it = iter(seq)
111 it2 = iter(it)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000112 self.assertTrue(it is it2)
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000113
114 # Test that for loops over iterators work
115 def test_iter_for_loop(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000116 self.check_for_loop(iter(range(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000117
118 # Test several independent iterators over the same list
119 def test_iter_independence(self):
120 seq = range(3)
121 res = []
122 for i in iter(seq):
123 for j in iter(seq):
124 for k in iter(seq):
125 res.append((i, j, k))
126 self.assertEqual(res, TRIPLETS)
127
128 # Test triple list comprehension using iterators
129 def test_nested_comprehensions_iter(self):
130 seq = range(3)
131 res = [(i, j, k)
132 for i in iter(seq) for j in iter(seq) for k in iter(seq)]
133 self.assertEqual(res, TRIPLETS)
134
135 # Test triple list comprehension without iterators
136 def test_nested_comprehensions_for(self):
137 seq = range(3)
138 res = [(i, j, k) for i in seq for j in seq for k in seq]
139 self.assertEqual(res, TRIPLETS)
140
141 # Test a class with __iter__ in a for loop
142 def test_iter_class_for(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000143 self.check_for_loop(IteratingSequenceClass(10), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000144
145 # Test a class with __iter__ with explicit iter()
146 def test_iter_class_iter(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000147 self.check_iterator(iter(IteratingSequenceClass(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000148
149 # Test for loop on a sequence class without __iter__
150 def test_seq_class_for(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000151 self.check_for_loop(SequenceClass(10), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000152
153 # Test iter() on a sequence class without __iter__
154 def test_seq_class_iter(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000155 self.check_iterator(iter(SequenceClass(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000156
Serhiy Storchakaaabafe72016-03-06 14:10:24 +0200157 def test_mutating_seq_class_iter_pickle(self):
158 orig = SequenceClass(5)
159 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
160 # initial iterator
161 itorig = iter(orig)
162 d = pickle.dumps((itorig, orig), proto)
163 it, seq = pickle.loads(d)
164 seq.n = 7
165 self.assertIs(type(it), type(itorig))
166 self.assertEqual(list(it), list(range(7)))
167
168 # running iterator
169 next(itorig)
170 d = pickle.dumps((itorig, orig), proto)
171 it, seq = pickle.loads(d)
172 seq.n = 7
173 self.assertIs(type(it), type(itorig))
174 self.assertEqual(list(it), list(range(1, 7)))
175
176 # empty iterator
177 for i in range(1, 5):
178 next(itorig)
179 d = pickle.dumps((itorig, orig), proto)
180 it, seq = pickle.loads(d)
181 seq.n = 7
182 self.assertIs(type(it), type(itorig))
183 self.assertEqual(list(it), list(range(5, 7)))
184
185 # exhausted iterator
186 self.assertRaises(StopIteration, next, itorig)
187 d = pickle.dumps((itorig, orig), proto)
188 it, seq = pickle.loads(d)
189 seq.n = 7
190 self.assertTrue(isinstance(it, collections.abc.Iterator))
191 self.assertEqual(list(it), [])
192
Serhiy Storchaka8dc2ec12016-03-30 21:01:26 +0300193 def test_mutating_seq_class_exhausted_iter(self):
194 a = SequenceClass(5)
195 exhit = iter(a)
196 empit = iter(a)
197 for x in exhit: # exhaust the iterator
198 next(empit) # not exhausted
199 a.n = 7
200 self.assertEqual(list(exhit), [])
201 self.assertEqual(list(empit), [5, 6])
202 self.assertEqual(list(a), [0, 1, 2, 3, 4, 5, 6])
203
Amaury Forgeot d'Arcf343e012009-01-12 23:58:21 +0000204 # Test a new_style class with __iter__ but no next() method
205 def test_new_style_iter_class(self):
206 class IterClass(object):
207 def __iter__(self):
208 return self
209 self.assertRaises(TypeError, iter, IterClass())
210
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000211 # Test two-argument iter() with callable instance
212 def test_iter_callable(self):
213 class C:
214 def __init__(self):
215 self.i = 0
216 def __call__(self):
217 i = self.i
218 self.i = i + 1
219 if i > 100:
220 raise IndexError # Emergency stop
221 return i
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000222 self.check_iterator(iter(C(), 10), list(range(10)), pickle=False)
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000223
224 # Test two-argument iter() with function
225 def test_iter_function(self):
226 def spam(state=[0]):
227 i = state[0]
228 state[0] = i+1
229 return i
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000230 self.check_iterator(iter(spam, 10), list(range(10)), pickle=False)
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000231
232 # Test two-argument iter() with function that raises StopIteration
233 def test_iter_function_stop(self):
234 def spam(state=[0]):
235 i = state[0]
236 if i == 10:
237 raise StopIteration
238 state[0] = i+1
239 return i
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000240 self.check_iterator(iter(spam, 20), list(range(10)), pickle=False)
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000241
242 # Test exception propagation through function iterator
243 def test_exception_function(self):
244 def spam(state=[0]):
245 i = state[0]
246 state[0] = i+1
247 if i == 10:
248 raise RuntimeError
249 return i
250 res = []
251 try:
252 for x in iter(spam, 20):
253 res.append(x)
254 except RuntimeError:
Guido van Rossum805365e2007-05-07 22:24:25 +0000255 self.assertEqual(res, list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000256 else:
257 self.fail("should have raised RuntimeError")
258
259 # Test exception propagation through sequence iterator
260 def test_exception_sequence(self):
261 class MySequenceClass(SequenceClass):
262 def __getitem__(self, i):
263 if i == 10:
264 raise RuntimeError
265 return SequenceClass.__getitem__(self, i)
266 res = []
267 try:
268 for x in MySequenceClass(20):
269 res.append(x)
270 except RuntimeError:
Guido van Rossum805365e2007-05-07 22:24:25 +0000271 self.assertEqual(res, list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000272 else:
273 self.fail("should have raised RuntimeError")
274
275 # Test for StopIteration from __getitem__
276 def test_stop_sequence(self):
277 class MySequenceClass(SequenceClass):
278 def __getitem__(self, i):
279 if i == 10:
280 raise StopIteration
281 return SequenceClass.__getitem__(self, i)
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000282 self.check_for_loop(MySequenceClass(20), list(range(10)), pickle=False)
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000283
284 # Test a big range
285 def test_iter_big_range(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000286 self.check_for_loop(iter(range(10000)), list(range(10000)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000287
288 # Test an empty list
289 def test_iter_empty(self):
290 self.check_for_loop(iter([]), [])
291
292 # Test a tuple
293 def test_iter_tuple(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000294 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 +0000295
Guido van Rossum805365e2007-05-07 22:24:25 +0000296 # Test a range
297 def test_iter_range(self):
298 self.check_for_loop(iter(range(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000299
300 # Test a string
301 def test_iter_string(self):
302 self.check_for_loop(iter("abcde"), ["a", "b", "c", "d", "e"])
303
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000304 # Test a directory
305 def test_iter_dict(self):
306 dict = {}
307 for i in range(10):
308 dict[i] = None
Brett Cannon0caf6d82007-02-22 04:49:03 +0000309 self.check_for_loop(dict, list(dict.keys()))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000310
311 # Test a file
312 def test_iter_file(self):
313 f = open(TESTFN, "w")
314 try:
315 for i in range(5):
316 f.write("%d\n" % i)
317 finally:
318 f.close()
319 f = open(TESTFN, "r")
320 try:
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000321 self.check_for_loop(f, ["0\n", "1\n", "2\n", "3\n", "4\n"], pickle=False)
322 self.check_for_loop(f, [], pickle=False)
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000323 finally:
324 f.close()
325 try:
326 unlink(TESTFN)
327 except OSError:
328 pass
329
Tim Petersf553f892001-05-01 20:45:31 +0000330 # Test list()'s use of iterators.
331 def test_builtin_list(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000332 self.assertEqual(list(SequenceClass(5)), list(range(5)))
Tim Petersf553f892001-05-01 20:45:31 +0000333 self.assertEqual(list(SequenceClass(0)), [])
334 self.assertEqual(list(()), [])
Tim Petersf553f892001-05-01 20:45:31 +0000335
336 d = {"one": 1, "two": 2, "three": 3}
Brett Cannon0caf6d82007-02-22 04:49:03 +0000337 self.assertEqual(list(d), list(d.keys()))
Tim Petersf553f892001-05-01 20:45:31 +0000338
339 self.assertRaises(TypeError, list, list)
340 self.assertRaises(TypeError, list, 42)
341
342 f = open(TESTFN, "w")
343 try:
344 for i in range(5):
345 f.write("%d\n" % i)
346 finally:
347 f.close()
348 f = open(TESTFN, "r")
349 try:
350 self.assertEqual(list(f), ["0\n", "1\n", "2\n", "3\n", "4\n"])
351 f.seek(0, 0)
Guido van Rossum8ee52432002-08-06 17:14:04 +0000352 self.assertEqual(list(f),
Tim Petersf553f892001-05-01 20:45:31 +0000353 ["0\n", "1\n", "2\n", "3\n", "4\n"])
354 finally:
355 f.close()
356 try:
357 unlink(TESTFN)
358 except OSError:
359 pass
360
Tim Peters6912d4d2001-05-05 03:56:37 +0000361 # Test tuples()'s use of iterators.
362 def test_builtin_tuple(self):
363 self.assertEqual(tuple(SequenceClass(5)), (0, 1, 2, 3, 4))
364 self.assertEqual(tuple(SequenceClass(0)), ())
365 self.assertEqual(tuple([]), ())
366 self.assertEqual(tuple(()), ())
367 self.assertEqual(tuple("abc"), ("a", "b", "c"))
368
369 d = {"one": 1, "two": 2, "three": 3}
370 self.assertEqual(tuple(d), tuple(d.keys()))
371
372 self.assertRaises(TypeError, tuple, list)
373 self.assertRaises(TypeError, tuple, 42)
374
375 f = open(TESTFN, "w")
376 try:
377 for i in range(5):
378 f.write("%d\n" % i)
379 finally:
380 f.close()
381 f = open(TESTFN, "r")
382 try:
383 self.assertEqual(tuple(f), ("0\n", "1\n", "2\n", "3\n", "4\n"))
384 f.seek(0, 0)
Guido van Rossum8ee52432002-08-06 17:14:04 +0000385 self.assertEqual(tuple(f),
Tim Peters6912d4d2001-05-05 03:56:37 +0000386 ("0\n", "1\n", "2\n", "3\n", "4\n"))
387 finally:
388 f.close()
389 try:
390 unlink(TESTFN)
391 except OSError:
392 pass
393
Tim Peters0e57abf2001-05-02 07:39:38 +0000394 # Test filter()'s use of iterators.
395 def test_builtin_filter(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000396 self.assertEqual(list(filter(None, SequenceClass(5))),
397 list(range(1, 5)))
398 self.assertEqual(list(filter(None, SequenceClass(0))), [])
399 self.assertEqual(list(filter(None, ())), [])
400 self.assertEqual(list(filter(None, "abc")), ["a", "b", "c"])
Tim Peters0e57abf2001-05-02 07:39:38 +0000401
402 d = {"one": 1, "two": 2, "three": 3}
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000403 self.assertEqual(list(filter(None, d)), list(d.keys()))
Tim Peters0e57abf2001-05-02 07:39:38 +0000404
405 self.assertRaises(TypeError, filter, None, list)
406 self.assertRaises(TypeError, filter, None, 42)
407
408 class Boolean:
409 def __init__(self, truth):
410 self.truth = truth
Jack Diederich4dafcc42006-11-28 19:15:13 +0000411 def __bool__(self):
Tim Peters0e57abf2001-05-02 07:39:38 +0000412 return self.truth
Jack Diederich4dafcc42006-11-28 19:15:13 +0000413 bTrue = Boolean(True)
414 bFalse = Boolean(False)
Tim Peters0e57abf2001-05-02 07:39:38 +0000415
416 class Seq:
417 def __init__(self, *args):
418 self.vals = args
419 def __iter__(self):
420 class SeqIter:
421 def __init__(self, vals):
422 self.vals = vals
423 self.i = 0
424 def __iter__(self):
425 return self
Georg Brandla18af4e2007-04-21 15:47:16 +0000426 def __next__(self):
Tim Peters0e57abf2001-05-02 07:39:38 +0000427 i = self.i
428 self.i = i + 1
429 if i < len(self.vals):
430 return self.vals[i]
431 else:
432 raise StopIteration
433 return SeqIter(self.vals)
434
Tim Peterscae330e2002-12-23 16:50:58 +0000435 seq = Seq(*([bTrue, bFalse] * 25))
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000436 self.assertEqual(list(filter(lambda x: not x, seq)), [bFalse]*25)
437 self.assertEqual(list(filter(lambda x: not x, iter(seq))), [bFalse]*25)
Tim Peters0e57abf2001-05-02 07:39:38 +0000438
Tim Petersc3074532001-05-03 07:00:32 +0000439 # Test max() and min()'s use of iterators.
440 def test_builtin_max_min(self):
441 self.assertEqual(max(SequenceClass(5)), 4)
442 self.assertEqual(min(SequenceClass(5)), 0)
443 self.assertEqual(max(8, -1), 8)
444 self.assertEqual(min(8, -1), -1)
445
446 d = {"one": 1, "two": 2, "three": 3}
447 self.assertEqual(max(d), "two")
448 self.assertEqual(min(d), "one")
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000449 self.assertEqual(max(d.values()), 3)
450 self.assertEqual(min(iter(d.values())), 1)
Tim Petersc3074532001-05-03 07:00:32 +0000451
Tim Petersc3074532001-05-03 07:00:32 +0000452 f = open(TESTFN, "w")
453 try:
454 f.write("medium line\n")
455 f.write("xtra large line\n")
456 f.write("itty-bitty line\n")
457 finally:
458 f.close()
459 f = open(TESTFN, "r")
460 try:
461 self.assertEqual(min(f), "itty-bitty line\n")
462 f.seek(0, 0)
463 self.assertEqual(max(f), "xtra large line\n")
464 finally:
465 f.close()
466 try:
467 unlink(TESTFN)
468 except OSError:
469 pass
470
Tim Peters4e9afdc2001-05-03 23:54:49 +0000471 # Test map()'s use of iterators.
472 def test_builtin_map(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000473 self.assertEqual(list(map(lambda x: x+1, SequenceClass(5))),
474 list(range(1, 6)))
Tim Peters4e9afdc2001-05-03 23:54:49 +0000475
476 d = {"one": 1, "two": 2, "three": 3}
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000477 self.assertEqual(list(map(lambda k, d=d: (k, d[k]), d)),
478 list(d.items()))
Brett Cannon0caf6d82007-02-22 04:49:03 +0000479 dkeys = list(d.keys())
Tim Peters4e9afdc2001-05-03 23:54:49 +0000480 expected = [(i < len(d) and dkeys[i] or None,
481 i,
482 i < len(d) and dkeys[i] or None)
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000483 for i in range(3)]
Tim Peters4e9afdc2001-05-03 23:54:49 +0000484
485 f = open(TESTFN, "w")
486 try:
487 for i in range(10):
488 f.write("xy" * i + "\n") # line i has len 2*i+1
489 finally:
490 f.close()
491 f = open(TESTFN, "r")
492 try:
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000493 self.assertEqual(list(map(len, f)), list(range(1, 21, 2)))
Tim Peters4e9afdc2001-05-03 23:54:49 +0000494 finally:
495 f.close()
496 try:
497 unlink(TESTFN)
498 except OSError:
499 pass
500
Tim Peters8572b4f2001-05-06 01:05:02 +0000501 # Test zip()'s use of iterators.
502 def test_builtin_zip(self):
Guido van Rossum801f0d72006-08-24 19:48:10 +0000503 self.assertEqual(list(zip()), [])
504 self.assertEqual(list(zip(*[])), [])
505 self.assertEqual(list(zip(*[(1, 2), 'ab'])), [(1, 'a'), (2, 'b')])
Raymond Hettingereaef6152003-08-02 07:42:57 +0000506
Tim Peters8572b4f2001-05-06 01:05:02 +0000507 self.assertRaises(TypeError, zip, None)
508 self.assertRaises(TypeError, zip, range(10), 42)
509 self.assertRaises(TypeError, zip, range(10), zip)
510
Guido van Rossum801f0d72006-08-24 19:48:10 +0000511 self.assertEqual(list(zip(IteratingSequenceClass(3))),
Tim Peters8572b4f2001-05-06 01:05:02 +0000512 [(0,), (1,), (2,)])
Guido van Rossum801f0d72006-08-24 19:48:10 +0000513 self.assertEqual(list(zip(SequenceClass(3))),
Tim Peters8572b4f2001-05-06 01:05:02 +0000514 [(0,), (1,), (2,)])
515
516 d = {"one": 1, "two": 2, "three": 3}
Brett Cannon0caf6d82007-02-22 04:49:03 +0000517 self.assertEqual(list(d.items()), list(zip(d, d.values())))
Tim Peters8572b4f2001-05-06 01:05:02 +0000518
519 # Generate all ints starting at constructor arg.
520 class IntsFrom:
521 def __init__(self, start):
522 self.i = start
523
524 def __iter__(self):
525 return self
526
Georg Brandla18af4e2007-04-21 15:47:16 +0000527 def __next__(self):
Tim Peters8572b4f2001-05-06 01:05:02 +0000528 i = self.i
529 self.i = i+1
530 return i
531
532 f = open(TESTFN, "w")
533 try:
534 f.write("a\n" "bbb\n" "cc\n")
535 finally:
536 f.close()
537 f = open(TESTFN, "r")
538 try:
Guido van Rossum801f0d72006-08-24 19:48:10 +0000539 self.assertEqual(list(zip(IntsFrom(0), f, IntsFrom(-100))),
Tim Peters8572b4f2001-05-06 01:05:02 +0000540 [(0, "a\n", -100),
541 (1, "bbb\n", -99),
542 (2, "cc\n", -98)])
543 finally:
544 f.close()
545 try:
546 unlink(TESTFN)
547 except OSError:
548 pass
549
Guido van Rossum805365e2007-05-07 22:24:25 +0000550 self.assertEqual(list(zip(range(5))), [(i,) for i in range(5)])
Tim Peters67d687a2002-04-29 21:27:32 +0000551
552 # Classes that lie about their lengths.
553 class NoGuessLen5:
554 def __getitem__(self, i):
555 if i >= 5:
556 raise IndexError
557 return i
558
559 class Guess3Len5(NoGuessLen5):
560 def __len__(self):
561 return 3
562
563 class Guess30Len5(NoGuessLen5):
564 def __len__(self):
565 return 30
566
Guido van Rossum801f0d72006-08-24 19:48:10 +0000567 def lzip(*args):
568 return list(zip(*args))
569
Tim Peters67d687a2002-04-29 21:27:32 +0000570 self.assertEqual(len(Guess3Len5()), 3)
571 self.assertEqual(len(Guess30Len5()), 30)
Guido van Rossum801f0d72006-08-24 19:48:10 +0000572 self.assertEqual(lzip(NoGuessLen5()), lzip(range(5)))
573 self.assertEqual(lzip(Guess3Len5()), lzip(range(5)))
574 self.assertEqual(lzip(Guess30Len5()), lzip(range(5)))
Tim Peters67d687a2002-04-29 21:27:32 +0000575
576 expected = [(i, i) for i in range(5)]
577 for x in NoGuessLen5(), Guess3Len5(), Guess30Len5():
578 for y in NoGuessLen5(), Guess3Len5(), Guess30Len5():
Guido van Rossum801f0d72006-08-24 19:48:10 +0000579 self.assertEqual(lzip(x, y), expected)
Tim Peters67d687a2002-04-29 21:27:32 +0000580
Tim Peters2cfe3682001-05-05 05:36:48 +0000581 def test_unicode_join_endcase(self):
582
583 # This class inserts a Unicode object into its argument's natural
584 # iteration, in the 3rd position.
585 class OhPhooey:
586 def __init__(self, seq):
587 self.it = iter(seq)
588 self.i = 0
589
590 def __iter__(self):
591 return self
592
Georg Brandla18af4e2007-04-21 15:47:16 +0000593 def __next__(self):
Tim Peters2cfe3682001-05-05 05:36:48 +0000594 i = self.i
595 self.i = i+1
596 if i == 2:
Walter Dörwald1f5947b2007-05-22 16:52:54 +0000597 return "fooled you!"
Georg Brandla18af4e2007-04-21 15:47:16 +0000598 return next(self.it)
Tim Peters2cfe3682001-05-05 05:36:48 +0000599
600 f = open(TESTFN, "w")
601 try:
602 f.write("a\n" + "b\n" + "c\n")
603 finally:
604 f.close()
605
606 f = open(TESTFN, "r")
607 # Nasty: string.join(s) can't know whether unicode.join() is needed
608 # until it's seen all of s's elements. But in this case, f's
609 # iterator cannot be restarted. So what we're testing here is
610 # whether string.join() can manage to remember everything it's seen
611 # and pass that on to unicode.join().
612 try:
613 got = " - ".join(OhPhooey(f))
Walter Dörwald5de48bd2007-06-11 21:38:39 +0000614 self.assertEqual(got, "a\n - b\n - fooled you! - c\n")
Tim Peters2cfe3682001-05-05 05:36:48 +0000615 finally:
616 f.close()
617 try:
618 unlink(TESTFN)
619 except OSError:
620 pass
621
Tim Petersde9725f2001-05-05 10:06:17 +0000622 # Test iterators with 'x in y' and 'x not in y'.
623 def test_in_and_not_in(self):
Tim Peterscb8d3682001-05-05 21:05:01 +0000624 for sc5 in IteratingSequenceClass(5), SequenceClass(5):
625 for i in range(5):
Benjamin Peterson577473f2010-01-19 00:09:57 +0000626 self.assertIn(i, sc5)
Tim Peterscb8d3682001-05-05 21:05:01 +0000627 for i in "abc", -1, 5, 42.42, (3, 4), [], {1: 1}, 3-12j, sc5:
Benjamin Peterson577473f2010-01-19 00:09:57 +0000628 self.assertNotIn(i, sc5)
Tim Petersde9725f2001-05-05 10:06:17 +0000629
630 self.assertRaises(TypeError, lambda: 3 in 12)
631 self.assertRaises(TypeError, lambda: 3 not in map)
632
633 d = {"one": 1, "two": 2, "three": 3, 1j: 2j}
634 for k in d:
Benjamin Peterson577473f2010-01-19 00:09:57 +0000635 self.assertIn(k, d)
636 self.assertNotIn(k, d.values())
Tim Petersde9725f2001-05-05 10:06:17 +0000637 for v in d.values():
Benjamin Peterson577473f2010-01-19 00:09:57 +0000638 self.assertIn(v, d.values())
639 self.assertNotIn(v, d)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000640 for k, v in d.items():
Benjamin Peterson577473f2010-01-19 00:09:57 +0000641 self.assertIn((k, v), d.items())
642 self.assertNotIn((v, k), d.items())
Tim Petersde9725f2001-05-05 10:06:17 +0000643
644 f = open(TESTFN, "w")
645 try:
646 f.write("a\n" "b\n" "c\n")
647 finally:
648 f.close()
649 f = open(TESTFN, "r")
650 try:
651 for chunk in "abc":
652 f.seek(0, 0)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000653 self.assertNotIn(chunk, f)
Tim Petersde9725f2001-05-05 10:06:17 +0000654 f.seek(0, 0)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000655 self.assertIn((chunk + "\n"), f)
Tim Petersde9725f2001-05-05 10:06:17 +0000656 finally:
657 f.close()
658 try:
659 unlink(TESTFN)
660 except OSError:
661 pass
662
Tim Peters75f8e352001-05-05 11:33:43 +0000663 # Test iterators with operator.countOf (PySequence_Count).
664 def test_countOf(self):
665 from operator import countOf
666 self.assertEqual(countOf([1,2,2,3,2,5], 2), 3)
667 self.assertEqual(countOf((1,2,2,3,2,5), 2), 3)
668 self.assertEqual(countOf("122325", "2"), 3)
669 self.assertEqual(countOf("122325", "6"), 0)
670
671 self.assertRaises(TypeError, countOf, 42, 1)
672 self.assertRaises(TypeError, countOf, countOf, countOf)
673
674 d = {"one": 3, "two": 3, "three": 3, 1j: 2j}
675 for k in d:
676 self.assertEqual(countOf(d, k), 1)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000677 self.assertEqual(countOf(d.values(), 3), 3)
678 self.assertEqual(countOf(d.values(), 2j), 1)
679 self.assertEqual(countOf(d.values(), 1j), 0)
Tim Peters75f8e352001-05-05 11:33:43 +0000680
681 f = open(TESTFN, "w")
682 try:
683 f.write("a\n" "b\n" "c\n" "b\n")
684 finally:
685 f.close()
686 f = open(TESTFN, "r")
687 try:
688 for letter, count in ("a", 1), ("b", 2), ("c", 1), ("d", 0):
689 f.seek(0, 0)
690 self.assertEqual(countOf(f, letter + "\n"), count)
691 finally:
692 f.close()
693 try:
694 unlink(TESTFN)
695 except OSError:
696 pass
697
Tim Peters16a77ad2001-09-08 04:00:12 +0000698 # Test iterators with operator.indexOf (PySequence_Index).
699 def test_indexOf(self):
700 from operator import indexOf
701 self.assertEqual(indexOf([1,2,2,3,2,5], 1), 0)
702 self.assertEqual(indexOf((1,2,2,3,2,5), 2), 1)
703 self.assertEqual(indexOf((1,2,2,3,2,5), 3), 3)
704 self.assertEqual(indexOf((1,2,2,3,2,5), 5), 5)
705 self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 0)
706 self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 6)
707
708 self.assertEqual(indexOf("122325", "2"), 1)
709 self.assertEqual(indexOf("122325", "5"), 5)
710 self.assertRaises(ValueError, indexOf, "122325", "6")
711
712 self.assertRaises(TypeError, indexOf, 42, 1)
713 self.assertRaises(TypeError, indexOf, indexOf, indexOf)
714
715 f = open(TESTFN, "w")
716 try:
717 f.write("a\n" "b\n" "c\n" "d\n" "e\n")
718 finally:
719 f.close()
720 f = open(TESTFN, "r")
721 try:
722 fiter = iter(f)
723 self.assertEqual(indexOf(fiter, "b\n"), 1)
724 self.assertEqual(indexOf(fiter, "d\n"), 1)
725 self.assertEqual(indexOf(fiter, "e\n"), 0)
726 self.assertRaises(ValueError, indexOf, fiter, "a\n")
727 finally:
728 f.close()
729 try:
730 unlink(TESTFN)
731 except OSError:
732 pass
733
734 iclass = IteratingSequenceClass(3)
735 for i in range(3):
736 self.assertEqual(indexOf(iclass, i), i)
737 self.assertRaises(ValueError, indexOf, iclass, -1)
738
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000739 # Test iterators with file.writelines().
740 def test_writelines(self):
Alex Martelli01c77c62006-08-24 02:58:11 +0000741 f = open(TESTFN, "w")
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000742
743 try:
744 self.assertRaises(TypeError, f.writelines, None)
745 self.assertRaises(TypeError, f.writelines, 42)
Tim Peters527e64f2001-10-04 05:36:56 +0000746
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000747 f.writelines(["1\n", "2\n"])
748 f.writelines(("3\n", "4\n"))
749 f.writelines({'5\n': None})
750 f.writelines({})
751
752 # Try a big chunk too.
753 class Iterator:
754 def __init__(self, start, finish):
755 self.start = start
756 self.finish = finish
757 self.i = self.start
758
Georg Brandla18af4e2007-04-21 15:47:16 +0000759 def __next__(self):
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000760 if self.i >= self.finish:
761 raise StopIteration
762 result = str(self.i) + '\n'
763 self.i += 1
764 return result
765
766 def __iter__(self):
767 return self
768
769 class Whatever:
770 def __init__(self, start, finish):
771 self.start = start
772 self.finish = finish
773
774 def __iter__(self):
775 return Iterator(self.start, self.finish)
Tim Peters527e64f2001-10-04 05:36:56 +0000776
777 f.writelines(Whatever(6, 6+2000))
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000778 f.close()
779
Alex Martelli01c77c62006-08-24 02:58:11 +0000780 f = open(TESTFN)
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000781 expected = [str(i) + "\n" for i in range(1, 2006)]
782 self.assertEqual(list(f), expected)
Tim Peters527e64f2001-10-04 05:36:56 +0000783
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000784 finally:
785 f.close()
786 try:
787 unlink(TESTFN)
788 except OSError:
789 pass
790
791
Tim Petersd6d010b2001-06-21 02:49:55 +0000792 # Test iterators on RHS of unpacking assignments.
793 def test_unpack_iter(self):
794 a, b = 1, 2
795 self.assertEqual((a, b), (1, 2))
796
797 a, b, c = IteratingSequenceClass(3)
798 self.assertEqual((a, b, c), (0, 1, 2))
799
800 try: # too many values
801 a, b = IteratingSequenceClass(3)
802 except ValueError:
803 pass
804 else:
805 self.fail("should have raised ValueError")
806
807 try: # not enough values
808 a, b, c = IteratingSequenceClass(2)
809 except ValueError:
810 pass
811 else:
812 self.fail("should have raised ValueError")
813
814 try: # not iterable
815 a, b, c = len
816 except TypeError:
817 pass
818 else:
819 self.fail("should have raised TypeError")
820
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000821 a, b, c = {1: 42, 2: 42, 3: 42}.values()
Tim Petersd6d010b2001-06-21 02:49:55 +0000822 self.assertEqual((a, b, c), (42, 42, 42))
823
824 f = open(TESTFN, "w")
825 lines = ("a\n", "bb\n", "ccc\n")
826 try:
827 for line in lines:
828 f.write(line)
829 finally:
830 f.close()
831 f = open(TESTFN, "r")
832 try:
833 a, b, c = f
834 self.assertEqual((a, b, c), lines)
835 finally:
836 f.close()
837 try:
838 unlink(TESTFN)
839 except OSError:
840 pass
841
842 (a, b), (c,) = IteratingSequenceClass(2), {42: 24}
843 self.assertEqual((a, b, c), (0, 1, 42))
844
Guido van Rossumbb8f59a2001-12-03 19:33:25 +0000845
Benjamin Peterson945c5792010-06-22 20:34:34 +0000846 @cpython_only
847 def test_ref_counting_behavior(self):
Guido van Rossumbb8f59a2001-12-03 19:33:25 +0000848 class C(object):
849 count = 0
850 def __new__(cls):
851 cls.count += 1
852 return object.__new__(cls)
853 def __del__(self):
854 cls = self.__class__
855 assert cls.count > 0
856 cls.count -= 1
857 x = C()
858 self.assertEqual(C.count, 1)
859 del x
860 self.assertEqual(C.count, 0)
861 l = [C(), C(), C()]
862 self.assertEqual(C.count, 3)
863 try:
864 a, b = iter(l)
865 except ValueError:
866 pass
867 del l
868 self.assertEqual(C.count, 0)
Fred Drake2e2be372001-09-20 21:33:42 +0000869
Guido van Rossum674eae62002-07-16 21:48:11 +0000870
871 # Make sure StopIteration is a "sink state".
872 # This tests various things that weren't sink states in Python 2.2.1,
873 # plus various things that always were fine.
874
875 def test_sinkstate_list(self):
876 # This used to fail
Guido van Rossum805365e2007-05-07 22:24:25 +0000877 a = list(range(5))
Guido van Rossum674eae62002-07-16 21:48:11 +0000878 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000879 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000880 a.extend(range(5, 10))
881 self.assertEqual(list(b), [])
882
883 def test_sinkstate_tuple(self):
884 a = (0, 1, 2, 3, 4)
885 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000886 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000887 self.assertEqual(list(b), [])
888
889 def test_sinkstate_string(self):
890 a = "abcde"
891 b = iter(a)
892 self.assertEqual(list(b), ['a', 'b', 'c', 'd', 'e'])
893 self.assertEqual(list(b), [])
894
895 def test_sinkstate_sequence(self):
896 # This used to fail
897 a = SequenceClass(5)
898 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000899 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000900 a.n = 10
901 self.assertEqual(list(b), [])
902
903 def test_sinkstate_callable(self):
904 # This used to fail
905 def spam(state=[0]):
906 i = state[0]
907 state[0] = i+1
908 if i == 10:
Collin Winter3add4d72007-08-29 23:37:32 +0000909 raise AssertionError("shouldn't have gotten this far")
Guido van Rossum674eae62002-07-16 21:48:11 +0000910 return i
911 b = iter(spam, 5)
Guido van Rossum805365e2007-05-07 22:24:25 +0000912 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000913 self.assertEqual(list(b), [])
914
915 def test_sinkstate_dict(self):
916 # XXX For a more thorough test, see towards the end of:
917 # http://mail.python.org/pipermail/python-dev/2002-July/026512.html
918 a = {1:1, 2:2, 0:0, 4:4, 3:3}
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000919 for b in iter(a), a.keys(), a.items(), a.values():
Guido van Rossum674eae62002-07-16 21:48:11 +0000920 b = iter(a)
921 self.assertEqual(len(list(b)), 5)
922 self.assertEqual(list(b), [])
923
924 def test_sinkstate_yield(self):
925 def gen():
926 for i in range(5):
927 yield i
928 b = gen()
Guido van Rossum805365e2007-05-07 22:24:25 +0000929 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000930 self.assertEqual(list(b), [])
931
932 def test_sinkstate_range(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000933 a = range(5)
Guido van Rossum674eae62002-07-16 21:48:11 +0000934 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000935 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000936 self.assertEqual(list(b), [])
937
938 def test_sinkstate_enumerate(self):
939 a = range(5)
940 e = enumerate(a)
941 b = iter(e)
Guido van Rossum801f0d72006-08-24 19:48:10 +0000942 self.assertEqual(list(b), list(zip(range(5), range(5))))
Guido van Rossum674eae62002-07-16 21:48:11 +0000943 self.assertEqual(list(b), [])
944
Amaury Forgeot d'Arcf343e012009-01-12 23:58:21 +0000945 def test_3720(self):
946 # Avoid a crash, when an iterator deletes its next() method.
947 class BadIterator(object):
948 def __iter__(self):
949 return self
950 def __next__(self):
951 del BadIterator.__next__
952 return 1
953
954 try:
955 for i in BadIterator() :
956 pass
957 except TypeError:
958 pass
959
Ezio Melotti739e1792012-11-18 23:16:02 +0200960 def test_extending_list_with_iterator_does_not_segfault(self):
961 # The code to extend a list with an iterator has a fair
962 # amount of nontrivial logic in terms of guessing how
963 # much memory to allocate in advance, "stealing" refs,
964 # and then shrinking at the end. This is a basic smoke
965 # test for that scenario.
966 def gen():
967 for i in range(500):
968 yield i
969 lst = [0] * 500
970 for i in range(240):
971 lst.pop(0)
972 lst.extend(gen())
973 self.assertEqual(len(lst), 760)
974
Serhiy Storchaka4faf5c52015-05-21 20:50:25 +0300975 @cpython_only
976 def test_iter_overflow(self):
977 # Test for the issue 22939
978 it = iter(UnlimitedSequenceClass())
979 # Manually set `it_index` to PY_SSIZE_T_MAX-2 without a loop
980 it.__setstate__(sys.maxsize - 2)
981 self.assertEqual(next(it), sys.maxsize - 2)
982 self.assertEqual(next(it), sys.maxsize - 1)
983 with self.assertRaises(OverflowError):
984 next(it)
985 # Check that Overflow error is always raised
986 with self.assertRaises(OverflowError):
987 next(it)
988
989 def test_iter_neg_setstate(self):
990 it = iter(UnlimitedSequenceClass())
991 it.__setstate__(-42)
992 self.assertEqual(next(it), 0)
993 self.assertEqual(next(it), 1)
994
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +0300995 def test_free_after_iterating(self):
996 check_free_after_iterating(self, iter, SequenceClass, (0,))
997
Guido van Rossum674eae62002-07-16 21:48:11 +0000998
Fred Drake2e2be372001-09-20 21:33:42 +0000999def test_main():
1000 run_unittest(TestCase)
1001
1002
1003if __name__ == "__main__":
1004 test_main()