blob: 6aceda23e9bd827dfeb10cf8dfde3861d05b77a2 [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 Storchaka18b711c2019-08-04 14:12:48 +03006from test.support import check_free_after_iterating, ALWAYS_EQ, NEVER_EQ
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
Serhiy Storchaka18b711c2019-08-04 14:12:48 +030044class IteratorProxyClass:
45 def __init__(self, i):
46 self.i = i
47 def __next__(self):
48 return next(self.i)
49 def __iter__(self):
50 return self
51
Guido van Rossum8b48cf92001-04-21 13:33:54 +000052class SequenceClass:
53 def __init__(self, n):
54 self.n = n
55 def __getitem__(self, i):
56 if 0 <= i < self.n:
57 return i
58 else:
59 raise IndexError
60
Serhiy Storchaka18b711c2019-08-04 14:12:48 +030061class SequenceProxyClass:
62 def __init__(self, s):
63 self.s = s
64 def __getitem__(self, i):
65 return self.s[i]
66
Serhiy Storchaka4faf5c52015-05-21 20:50:25 +030067class UnlimitedSequenceClass:
68 def __getitem__(self, i):
69 return i
70
Guido van Rossum97c1adf2016-08-18 09:22:23 -070071class DefaultIterClass:
72 pass
73
74class NoIterClass:
75 def __getitem__(self, i):
76 return i
77 __iter__ = None
78
Guido van Rossum8b48cf92001-04-21 13:33:54 +000079# Main test suite
80
81class TestCase(unittest.TestCase):
82
83 # Helper to check that an iterator returns a given sequence
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +000084 def check_iterator(self, it, seq, pickle=True):
85 if pickle:
86 self.check_pickle(it, seq)
Guido van Rossum8b48cf92001-04-21 13:33:54 +000087 res = []
88 while 1:
89 try:
Georg Brandla18af4e2007-04-21 15:47:16 +000090 val = next(it)
Guido van Rossum8b48cf92001-04-21 13:33:54 +000091 except StopIteration:
92 break
93 res.append(val)
94 self.assertEqual(res, seq)
95
96 # Helper to check that a for loop generates a given sequence
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +000097 def check_for_loop(self, expr, seq, pickle=True):
98 if pickle:
99 self.check_pickle(iter(expr), seq)
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000100 res = []
101 for val in expr:
102 res.append(val)
103 self.assertEqual(res, seq)
104
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000105 # Helper to check picklability
106 def check_pickle(self, itorg, seq):
Serhiy Storchakabad12572014-12-15 14:03:42 +0200107 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
108 d = pickle.dumps(itorg, proto)
109 it = pickle.loads(d)
110 # Cannot assert type equality because dict iterators unpickle as list
111 # iterators.
112 # self.assertEqual(type(itorg), type(it))
113 self.assertTrue(isinstance(it, collections.abc.Iterator))
114 self.assertEqual(list(it), seq)
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000115
Serhiy Storchakabad12572014-12-15 14:03:42 +0200116 it = pickle.loads(d)
117 try:
118 next(it)
119 except StopIteration:
120 continue
121 d = pickle.dumps(it, proto)
122 it = pickle.loads(d)
123 self.assertEqual(list(it), seq[1:])
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000124
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000125 # Test basic use of iter() function
126 def test_iter_basic(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000127 self.check_iterator(iter(range(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000128
129 # Test that iter(iter(x)) is the same as iter(x)
130 def test_iter_idempotency(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000131 seq = list(range(10))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000132 it = iter(seq)
133 it2 = iter(it)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000134 self.assertTrue(it is it2)
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000135
136 # Test that for loops over iterators work
137 def test_iter_for_loop(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000138 self.check_for_loop(iter(range(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000139
140 # Test several independent iterators over the same list
141 def test_iter_independence(self):
142 seq = range(3)
143 res = []
144 for i in iter(seq):
145 for j in iter(seq):
146 for k in iter(seq):
147 res.append((i, j, k))
148 self.assertEqual(res, TRIPLETS)
149
150 # Test triple list comprehension using iterators
151 def test_nested_comprehensions_iter(self):
152 seq = range(3)
153 res = [(i, j, k)
154 for i in iter(seq) for j in iter(seq) for k in iter(seq)]
155 self.assertEqual(res, TRIPLETS)
156
157 # Test triple list comprehension without iterators
158 def test_nested_comprehensions_for(self):
159 seq = range(3)
160 res = [(i, j, k) for i in seq for j in seq for k in seq]
161 self.assertEqual(res, TRIPLETS)
162
163 # Test a class with __iter__ in a for loop
164 def test_iter_class_for(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000165 self.check_for_loop(IteratingSequenceClass(10), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000166
167 # Test a class with __iter__ with explicit iter()
168 def test_iter_class_iter(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000169 self.check_iterator(iter(IteratingSequenceClass(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000170
171 # Test for loop on a sequence class without __iter__
172 def test_seq_class_for(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000173 self.check_for_loop(SequenceClass(10), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000174
175 # Test iter() on a sequence class without __iter__
176 def test_seq_class_iter(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000177 self.check_iterator(iter(SequenceClass(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000178
Serhiy Storchakaaabafe72016-03-06 14:10:24 +0200179 def test_mutating_seq_class_iter_pickle(self):
180 orig = SequenceClass(5)
181 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
182 # initial iterator
183 itorig = iter(orig)
184 d = pickle.dumps((itorig, orig), proto)
185 it, seq = pickle.loads(d)
186 seq.n = 7
187 self.assertIs(type(it), type(itorig))
188 self.assertEqual(list(it), list(range(7)))
189
190 # running iterator
191 next(itorig)
192 d = pickle.dumps((itorig, orig), proto)
193 it, seq = pickle.loads(d)
194 seq.n = 7
195 self.assertIs(type(it), type(itorig))
196 self.assertEqual(list(it), list(range(1, 7)))
197
198 # empty iterator
199 for i in range(1, 5):
200 next(itorig)
201 d = pickle.dumps((itorig, orig), proto)
202 it, seq = pickle.loads(d)
203 seq.n = 7
204 self.assertIs(type(it), type(itorig))
205 self.assertEqual(list(it), list(range(5, 7)))
206
207 # exhausted iterator
208 self.assertRaises(StopIteration, next, itorig)
209 d = pickle.dumps((itorig, orig), proto)
210 it, seq = pickle.loads(d)
211 seq.n = 7
212 self.assertTrue(isinstance(it, collections.abc.Iterator))
213 self.assertEqual(list(it), [])
214
Serhiy Storchaka8dc2ec12016-03-30 21:01:26 +0300215 def test_mutating_seq_class_exhausted_iter(self):
216 a = SequenceClass(5)
217 exhit = iter(a)
218 empit = iter(a)
219 for x in exhit: # exhaust the iterator
220 next(empit) # not exhausted
221 a.n = 7
222 self.assertEqual(list(exhit), [])
223 self.assertEqual(list(empit), [5, 6])
224 self.assertEqual(list(a), [0, 1, 2, 3, 4, 5, 6])
225
Amaury Forgeot d'Arcf343e012009-01-12 23:58:21 +0000226 # Test a new_style class with __iter__ but no next() method
227 def test_new_style_iter_class(self):
228 class IterClass(object):
229 def __iter__(self):
230 return self
231 self.assertRaises(TypeError, iter, IterClass())
232
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000233 # Test two-argument iter() with callable instance
234 def test_iter_callable(self):
235 class C:
236 def __init__(self):
237 self.i = 0
238 def __call__(self):
239 i = self.i
240 self.i = i + 1
241 if i > 100:
242 raise IndexError # Emergency stop
243 return i
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000244 self.check_iterator(iter(C(), 10), list(range(10)), pickle=False)
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000245
246 # Test two-argument iter() with function
247 def test_iter_function(self):
248 def spam(state=[0]):
249 i = state[0]
250 state[0] = i+1
251 return i
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000252 self.check_iterator(iter(spam, 10), list(range(10)), pickle=False)
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000253
254 # Test two-argument iter() with function that raises StopIteration
255 def test_iter_function_stop(self):
256 def spam(state=[0]):
257 i = state[0]
258 if i == 10:
259 raise StopIteration
260 state[0] = i+1
261 return i
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000262 self.check_iterator(iter(spam, 20), list(range(10)), pickle=False)
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000263
264 # Test exception propagation through function iterator
265 def test_exception_function(self):
266 def spam(state=[0]):
267 i = state[0]
268 state[0] = i+1
269 if i == 10:
270 raise RuntimeError
271 return i
272 res = []
273 try:
274 for x in iter(spam, 20):
275 res.append(x)
276 except RuntimeError:
Guido van Rossum805365e2007-05-07 22:24:25 +0000277 self.assertEqual(res, list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000278 else:
279 self.fail("should have raised RuntimeError")
280
281 # Test exception propagation through sequence iterator
282 def test_exception_sequence(self):
283 class MySequenceClass(SequenceClass):
284 def __getitem__(self, i):
285 if i == 10:
286 raise RuntimeError
287 return SequenceClass.__getitem__(self, i)
288 res = []
289 try:
290 for x in MySequenceClass(20):
291 res.append(x)
292 except RuntimeError:
Guido van Rossum805365e2007-05-07 22:24:25 +0000293 self.assertEqual(res, list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000294 else:
295 self.fail("should have raised RuntimeError")
296
297 # Test for StopIteration from __getitem__
298 def test_stop_sequence(self):
299 class MySequenceClass(SequenceClass):
300 def __getitem__(self, i):
301 if i == 10:
302 raise StopIteration
303 return SequenceClass.__getitem__(self, i)
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000304 self.check_for_loop(MySequenceClass(20), list(range(10)), pickle=False)
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000305
306 # Test a big range
307 def test_iter_big_range(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000308 self.check_for_loop(iter(range(10000)), list(range(10000)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000309
310 # Test an empty list
311 def test_iter_empty(self):
312 self.check_for_loop(iter([]), [])
313
314 # Test a tuple
315 def test_iter_tuple(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000316 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 +0000317
Guido van Rossum805365e2007-05-07 22:24:25 +0000318 # Test a range
319 def test_iter_range(self):
320 self.check_for_loop(iter(range(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000321
322 # Test a string
323 def test_iter_string(self):
324 self.check_for_loop(iter("abcde"), ["a", "b", "c", "d", "e"])
325
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000326 # Test a directory
327 def test_iter_dict(self):
328 dict = {}
329 for i in range(10):
330 dict[i] = None
Brett Cannon0caf6d82007-02-22 04:49:03 +0000331 self.check_for_loop(dict, list(dict.keys()))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000332
333 # Test a file
334 def test_iter_file(self):
335 f = open(TESTFN, "w")
336 try:
337 for i in range(5):
338 f.write("%d\n" % i)
339 finally:
340 f.close()
341 f = open(TESTFN, "r")
342 try:
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000343 self.check_for_loop(f, ["0\n", "1\n", "2\n", "3\n", "4\n"], pickle=False)
344 self.check_for_loop(f, [], pickle=False)
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000345 finally:
346 f.close()
347 try:
348 unlink(TESTFN)
349 except OSError:
350 pass
351
Tim Petersf553f892001-05-01 20:45:31 +0000352 # Test list()'s use of iterators.
353 def test_builtin_list(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000354 self.assertEqual(list(SequenceClass(5)), list(range(5)))
Tim Petersf553f892001-05-01 20:45:31 +0000355 self.assertEqual(list(SequenceClass(0)), [])
356 self.assertEqual(list(()), [])
Tim Petersf553f892001-05-01 20:45:31 +0000357
358 d = {"one": 1, "two": 2, "three": 3}
Brett Cannon0caf6d82007-02-22 04:49:03 +0000359 self.assertEqual(list(d), list(d.keys()))
Tim Petersf553f892001-05-01 20:45:31 +0000360
361 self.assertRaises(TypeError, list, list)
362 self.assertRaises(TypeError, list, 42)
363
364 f = open(TESTFN, "w")
365 try:
366 for i in range(5):
367 f.write("%d\n" % i)
368 finally:
369 f.close()
370 f = open(TESTFN, "r")
371 try:
372 self.assertEqual(list(f), ["0\n", "1\n", "2\n", "3\n", "4\n"])
373 f.seek(0, 0)
Guido van Rossum8ee52432002-08-06 17:14:04 +0000374 self.assertEqual(list(f),
Tim Petersf553f892001-05-01 20:45:31 +0000375 ["0\n", "1\n", "2\n", "3\n", "4\n"])
376 finally:
377 f.close()
378 try:
379 unlink(TESTFN)
380 except OSError:
381 pass
382
Tim Peters6912d4d2001-05-05 03:56:37 +0000383 # Test tuples()'s use of iterators.
384 def test_builtin_tuple(self):
385 self.assertEqual(tuple(SequenceClass(5)), (0, 1, 2, 3, 4))
386 self.assertEqual(tuple(SequenceClass(0)), ())
387 self.assertEqual(tuple([]), ())
388 self.assertEqual(tuple(()), ())
389 self.assertEqual(tuple("abc"), ("a", "b", "c"))
390
391 d = {"one": 1, "two": 2, "three": 3}
392 self.assertEqual(tuple(d), tuple(d.keys()))
393
394 self.assertRaises(TypeError, tuple, list)
395 self.assertRaises(TypeError, tuple, 42)
396
397 f = open(TESTFN, "w")
398 try:
399 for i in range(5):
400 f.write("%d\n" % i)
401 finally:
402 f.close()
403 f = open(TESTFN, "r")
404 try:
405 self.assertEqual(tuple(f), ("0\n", "1\n", "2\n", "3\n", "4\n"))
406 f.seek(0, 0)
Guido van Rossum8ee52432002-08-06 17:14:04 +0000407 self.assertEqual(tuple(f),
Tim Peters6912d4d2001-05-05 03:56:37 +0000408 ("0\n", "1\n", "2\n", "3\n", "4\n"))
409 finally:
410 f.close()
411 try:
412 unlink(TESTFN)
413 except OSError:
414 pass
415
Tim Peters0e57abf2001-05-02 07:39:38 +0000416 # Test filter()'s use of iterators.
417 def test_builtin_filter(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000418 self.assertEqual(list(filter(None, SequenceClass(5))),
419 list(range(1, 5)))
420 self.assertEqual(list(filter(None, SequenceClass(0))), [])
421 self.assertEqual(list(filter(None, ())), [])
422 self.assertEqual(list(filter(None, "abc")), ["a", "b", "c"])
Tim Peters0e57abf2001-05-02 07:39:38 +0000423
424 d = {"one": 1, "two": 2, "three": 3}
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000425 self.assertEqual(list(filter(None, d)), list(d.keys()))
Tim Peters0e57abf2001-05-02 07:39:38 +0000426
427 self.assertRaises(TypeError, filter, None, list)
428 self.assertRaises(TypeError, filter, None, 42)
429
430 class Boolean:
431 def __init__(self, truth):
432 self.truth = truth
Jack Diederich4dafcc42006-11-28 19:15:13 +0000433 def __bool__(self):
Tim Peters0e57abf2001-05-02 07:39:38 +0000434 return self.truth
Jack Diederich4dafcc42006-11-28 19:15:13 +0000435 bTrue = Boolean(True)
436 bFalse = Boolean(False)
Tim Peters0e57abf2001-05-02 07:39:38 +0000437
438 class Seq:
439 def __init__(self, *args):
440 self.vals = args
441 def __iter__(self):
442 class SeqIter:
443 def __init__(self, vals):
444 self.vals = vals
445 self.i = 0
446 def __iter__(self):
447 return self
Georg Brandla18af4e2007-04-21 15:47:16 +0000448 def __next__(self):
Tim Peters0e57abf2001-05-02 07:39:38 +0000449 i = self.i
450 self.i = i + 1
451 if i < len(self.vals):
452 return self.vals[i]
453 else:
454 raise StopIteration
455 return SeqIter(self.vals)
456
Tim Peterscae330e2002-12-23 16:50:58 +0000457 seq = Seq(*([bTrue, bFalse] * 25))
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000458 self.assertEqual(list(filter(lambda x: not x, seq)), [bFalse]*25)
459 self.assertEqual(list(filter(lambda x: not x, iter(seq))), [bFalse]*25)
Tim Peters0e57abf2001-05-02 07:39:38 +0000460
Tim Petersc3074532001-05-03 07:00:32 +0000461 # Test max() and min()'s use of iterators.
462 def test_builtin_max_min(self):
463 self.assertEqual(max(SequenceClass(5)), 4)
464 self.assertEqual(min(SequenceClass(5)), 0)
465 self.assertEqual(max(8, -1), 8)
466 self.assertEqual(min(8, -1), -1)
467
468 d = {"one": 1, "two": 2, "three": 3}
469 self.assertEqual(max(d), "two")
470 self.assertEqual(min(d), "one")
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000471 self.assertEqual(max(d.values()), 3)
472 self.assertEqual(min(iter(d.values())), 1)
Tim Petersc3074532001-05-03 07:00:32 +0000473
Tim Petersc3074532001-05-03 07:00:32 +0000474 f = open(TESTFN, "w")
475 try:
476 f.write("medium line\n")
477 f.write("xtra large line\n")
478 f.write("itty-bitty line\n")
479 finally:
480 f.close()
481 f = open(TESTFN, "r")
482 try:
483 self.assertEqual(min(f), "itty-bitty line\n")
484 f.seek(0, 0)
485 self.assertEqual(max(f), "xtra large line\n")
486 finally:
487 f.close()
488 try:
489 unlink(TESTFN)
490 except OSError:
491 pass
492
Tim Peters4e9afdc2001-05-03 23:54:49 +0000493 # Test map()'s use of iterators.
494 def test_builtin_map(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000495 self.assertEqual(list(map(lambda x: x+1, SequenceClass(5))),
496 list(range(1, 6)))
Tim Peters4e9afdc2001-05-03 23:54:49 +0000497
498 d = {"one": 1, "two": 2, "three": 3}
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000499 self.assertEqual(list(map(lambda k, d=d: (k, d[k]), d)),
500 list(d.items()))
Brett Cannon0caf6d82007-02-22 04:49:03 +0000501 dkeys = list(d.keys())
Tim Peters4e9afdc2001-05-03 23:54:49 +0000502 expected = [(i < len(d) and dkeys[i] or None,
503 i,
504 i < len(d) and dkeys[i] or None)
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000505 for i in range(3)]
Tim Peters4e9afdc2001-05-03 23:54:49 +0000506
507 f = open(TESTFN, "w")
508 try:
509 for i in range(10):
510 f.write("xy" * i + "\n") # line i has len 2*i+1
511 finally:
512 f.close()
513 f = open(TESTFN, "r")
514 try:
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000515 self.assertEqual(list(map(len, f)), list(range(1, 21, 2)))
Tim Peters4e9afdc2001-05-03 23:54:49 +0000516 finally:
517 f.close()
518 try:
519 unlink(TESTFN)
520 except OSError:
521 pass
522
Tim Peters8572b4f2001-05-06 01:05:02 +0000523 # Test zip()'s use of iterators.
524 def test_builtin_zip(self):
Guido van Rossum801f0d72006-08-24 19:48:10 +0000525 self.assertEqual(list(zip()), [])
526 self.assertEqual(list(zip(*[])), [])
527 self.assertEqual(list(zip(*[(1, 2), 'ab'])), [(1, 'a'), (2, 'b')])
Raymond Hettingereaef6152003-08-02 07:42:57 +0000528
Tim Peters8572b4f2001-05-06 01:05:02 +0000529 self.assertRaises(TypeError, zip, None)
530 self.assertRaises(TypeError, zip, range(10), 42)
531 self.assertRaises(TypeError, zip, range(10), zip)
532
Guido van Rossum801f0d72006-08-24 19:48:10 +0000533 self.assertEqual(list(zip(IteratingSequenceClass(3))),
Tim Peters8572b4f2001-05-06 01:05:02 +0000534 [(0,), (1,), (2,)])
Guido van Rossum801f0d72006-08-24 19:48:10 +0000535 self.assertEqual(list(zip(SequenceClass(3))),
Tim Peters8572b4f2001-05-06 01:05:02 +0000536 [(0,), (1,), (2,)])
537
538 d = {"one": 1, "two": 2, "three": 3}
Brett Cannon0caf6d82007-02-22 04:49:03 +0000539 self.assertEqual(list(d.items()), list(zip(d, d.values())))
Tim Peters8572b4f2001-05-06 01:05:02 +0000540
541 # Generate all ints starting at constructor arg.
542 class IntsFrom:
543 def __init__(self, start):
544 self.i = start
545
546 def __iter__(self):
547 return self
548
Georg Brandla18af4e2007-04-21 15:47:16 +0000549 def __next__(self):
Tim Peters8572b4f2001-05-06 01:05:02 +0000550 i = self.i
551 self.i = i+1
552 return i
553
554 f = open(TESTFN, "w")
555 try:
556 f.write("a\n" "bbb\n" "cc\n")
557 finally:
558 f.close()
559 f = open(TESTFN, "r")
560 try:
Guido van Rossum801f0d72006-08-24 19:48:10 +0000561 self.assertEqual(list(zip(IntsFrom(0), f, IntsFrom(-100))),
Tim Peters8572b4f2001-05-06 01:05:02 +0000562 [(0, "a\n", -100),
563 (1, "bbb\n", -99),
564 (2, "cc\n", -98)])
565 finally:
566 f.close()
567 try:
568 unlink(TESTFN)
569 except OSError:
570 pass
571
Guido van Rossum805365e2007-05-07 22:24:25 +0000572 self.assertEqual(list(zip(range(5))), [(i,) for i in range(5)])
Tim Peters67d687a2002-04-29 21:27:32 +0000573
574 # Classes that lie about their lengths.
575 class NoGuessLen5:
576 def __getitem__(self, i):
577 if i >= 5:
578 raise IndexError
579 return i
580
581 class Guess3Len5(NoGuessLen5):
582 def __len__(self):
583 return 3
584
585 class Guess30Len5(NoGuessLen5):
586 def __len__(self):
587 return 30
588
Guido van Rossum801f0d72006-08-24 19:48:10 +0000589 def lzip(*args):
590 return list(zip(*args))
591
Tim Peters67d687a2002-04-29 21:27:32 +0000592 self.assertEqual(len(Guess3Len5()), 3)
593 self.assertEqual(len(Guess30Len5()), 30)
Guido van Rossum801f0d72006-08-24 19:48:10 +0000594 self.assertEqual(lzip(NoGuessLen5()), lzip(range(5)))
595 self.assertEqual(lzip(Guess3Len5()), lzip(range(5)))
596 self.assertEqual(lzip(Guess30Len5()), lzip(range(5)))
Tim Peters67d687a2002-04-29 21:27:32 +0000597
598 expected = [(i, i) for i in range(5)]
599 for x in NoGuessLen5(), Guess3Len5(), Guess30Len5():
600 for y in NoGuessLen5(), Guess3Len5(), Guess30Len5():
Guido van Rossum801f0d72006-08-24 19:48:10 +0000601 self.assertEqual(lzip(x, y), expected)
Tim Peters67d687a2002-04-29 21:27:32 +0000602
Tim Peters2cfe3682001-05-05 05:36:48 +0000603 def test_unicode_join_endcase(self):
604
605 # This class inserts a Unicode object into its argument's natural
606 # iteration, in the 3rd position.
607 class OhPhooey:
608 def __init__(self, seq):
609 self.it = iter(seq)
610 self.i = 0
611
612 def __iter__(self):
613 return self
614
Georg Brandla18af4e2007-04-21 15:47:16 +0000615 def __next__(self):
Tim Peters2cfe3682001-05-05 05:36:48 +0000616 i = self.i
617 self.i = i+1
618 if i == 2:
Walter Dörwald1f5947b2007-05-22 16:52:54 +0000619 return "fooled you!"
Georg Brandla18af4e2007-04-21 15:47:16 +0000620 return next(self.it)
Tim Peters2cfe3682001-05-05 05:36:48 +0000621
622 f = open(TESTFN, "w")
623 try:
624 f.write("a\n" + "b\n" + "c\n")
625 finally:
626 f.close()
627
628 f = open(TESTFN, "r")
629 # Nasty: string.join(s) can't know whether unicode.join() is needed
630 # until it's seen all of s's elements. But in this case, f's
631 # iterator cannot be restarted. So what we're testing here is
632 # whether string.join() can manage to remember everything it's seen
633 # and pass that on to unicode.join().
634 try:
635 got = " - ".join(OhPhooey(f))
Walter Dörwald5de48bd2007-06-11 21:38:39 +0000636 self.assertEqual(got, "a\n - b\n - fooled you! - c\n")
Tim Peters2cfe3682001-05-05 05:36:48 +0000637 finally:
638 f.close()
639 try:
640 unlink(TESTFN)
641 except OSError:
642 pass
643
Tim Petersde9725f2001-05-05 10:06:17 +0000644 # Test iterators with 'x in y' and 'x not in y'.
645 def test_in_and_not_in(self):
Tim Peterscb8d3682001-05-05 21:05:01 +0000646 for sc5 in IteratingSequenceClass(5), SequenceClass(5):
647 for i in range(5):
Benjamin Peterson577473f2010-01-19 00:09:57 +0000648 self.assertIn(i, sc5)
Tim Peterscb8d3682001-05-05 21:05:01 +0000649 for i in "abc", -1, 5, 42.42, (3, 4), [], {1: 1}, 3-12j, sc5:
Benjamin Peterson577473f2010-01-19 00:09:57 +0000650 self.assertNotIn(i, sc5)
Tim Petersde9725f2001-05-05 10:06:17 +0000651
Serhiy Storchaka18b711c2019-08-04 14:12:48 +0300652 self.assertIn(ALWAYS_EQ, IteratorProxyClass(iter([1])))
653 self.assertIn(ALWAYS_EQ, SequenceProxyClass([1]))
654 self.assertNotIn(ALWAYS_EQ, IteratorProxyClass(iter([NEVER_EQ])))
655 self.assertNotIn(ALWAYS_EQ, SequenceProxyClass([NEVER_EQ]))
656 self.assertIn(NEVER_EQ, IteratorProxyClass(iter([ALWAYS_EQ])))
657 self.assertIn(NEVER_EQ, SequenceProxyClass([ALWAYS_EQ]))
658
Tim Petersde9725f2001-05-05 10:06:17 +0000659 self.assertRaises(TypeError, lambda: 3 in 12)
660 self.assertRaises(TypeError, lambda: 3 not in map)
661
662 d = {"one": 1, "two": 2, "three": 3, 1j: 2j}
663 for k in d:
Benjamin Peterson577473f2010-01-19 00:09:57 +0000664 self.assertIn(k, d)
665 self.assertNotIn(k, d.values())
Tim Petersde9725f2001-05-05 10:06:17 +0000666 for v in d.values():
Benjamin Peterson577473f2010-01-19 00:09:57 +0000667 self.assertIn(v, d.values())
668 self.assertNotIn(v, d)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000669 for k, v in d.items():
Benjamin Peterson577473f2010-01-19 00:09:57 +0000670 self.assertIn((k, v), d.items())
671 self.assertNotIn((v, k), d.items())
Tim Petersde9725f2001-05-05 10:06:17 +0000672
673 f = open(TESTFN, "w")
674 try:
675 f.write("a\n" "b\n" "c\n")
676 finally:
677 f.close()
678 f = open(TESTFN, "r")
679 try:
680 for chunk in "abc":
681 f.seek(0, 0)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000682 self.assertNotIn(chunk, f)
Tim Petersde9725f2001-05-05 10:06:17 +0000683 f.seek(0, 0)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000684 self.assertIn((chunk + "\n"), f)
Tim Petersde9725f2001-05-05 10:06:17 +0000685 finally:
686 f.close()
687 try:
688 unlink(TESTFN)
689 except OSError:
690 pass
691
Tim Peters75f8e352001-05-05 11:33:43 +0000692 # Test iterators with operator.countOf (PySequence_Count).
693 def test_countOf(self):
694 from operator import countOf
695 self.assertEqual(countOf([1,2,2,3,2,5], 2), 3)
696 self.assertEqual(countOf((1,2,2,3,2,5), 2), 3)
697 self.assertEqual(countOf("122325", "2"), 3)
698 self.assertEqual(countOf("122325", "6"), 0)
699
700 self.assertRaises(TypeError, countOf, 42, 1)
701 self.assertRaises(TypeError, countOf, countOf, countOf)
702
703 d = {"one": 3, "two": 3, "three": 3, 1j: 2j}
704 for k in d:
705 self.assertEqual(countOf(d, k), 1)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000706 self.assertEqual(countOf(d.values(), 3), 3)
707 self.assertEqual(countOf(d.values(), 2j), 1)
708 self.assertEqual(countOf(d.values(), 1j), 0)
Tim Peters75f8e352001-05-05 11:33:43 +0000709
710 f = open(TESTFN, "w")
711 try:
712 f.write("a\n" "b\n" "c\n" "b\n")
713 finally:
714 f.close()
715 f = open(TESTFN, "r")
716 try:
717 for letter, count in ("a", 1), ("b", 2), ("c", 1), ("d", 0):
718 f.seek(0, 0)
719 self.assertEqual(countOf(f, letter + "\n"), count)
720 finally:
721 f.close()
722 try:
723 unlink(TESTFN)
724 except OSError:
725 pass
726
Tim Peters16a77ad2001-09-08 04:00:12 +0000727 # Test iterators with operator.indexOf (PySequence_Index).
728 def test_indexOf(self):
729 from operator import indexOf
730 self.assertEqual(indexOf([1,2,2,3,2,5], 1), 0)
731 self.assertEqual(indexOf((1,2,2,3,2,5), 2), 1)
732 self.assertEqual(indexOf((1,2,2,3,2,5), 3), 3)
733 self.assertEqual(indexOf((1,2,2,3,2,5), 5), 5)
734 self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 0)
735 self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 6)
736
737 self.assertEqual(indexOf("122325", "2"), 1)
738 self.assertEqual(indexOf("122325", "5"), 5)
739 self.assertRaises(ValueError, indexOf, "122325", "6")
740
741 self.assertRaises(TypeError, indexOf, 42, 1)
742 self.assertRaises(TypeError, indexOf, indexOf, indexOf)
743
744 f = open(TESTFN, "w")
745 try:
746 f.write("a\n" "b\n" "c\n" "d\n" "e\n")
747 finally:
748 f.close()
749 f = open(TESTFN, "r")
750 try:
751 fiter = iter(f)
752 self.assertEqual(indexOf(fiter, "b\n"), 1)
753 self.assertEqual(indexOf(fiter, "d\n"), 1)
754 self.assertEqual(indexOf(fiter, "e\n"), 0)
755 self.assertRaises(ValueError, indexOf, fiter, "a\n")
756 finally:
757 f.close()
758 try:
759 unlink(TESTFN)
760 except OSError:
761 pass
762
763 iclass = IteratingSequenceClass(3)
764 for i in range(3):
765 self.assertEqual(indexOf(iclass, i), i)
766 self.assertRaises(ValueError, indexOf, iclass, -1)
767
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000768 # Test iterators with file.writelines().
769 def test_writelines(self):
Alex Martelli01c77c62006-08-24 02:58:11 +0000770 f = open(TESTFN, "w")
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000771
772 try:
773 self.assertRaises(TypeError, f.writelines, None)
774 self.assertRaises(TypeError, f.writelines, 42)
Tim Peters527e64f2001-10-04 05:36:56 +0000775
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000776 f.writelines(["1\n", "2\n"])
777 f.writelines(("3\n", "4\n"))
778 f.writelines({'5\n': None})
779 f.writelines({})
780
781 # Try a big chunk too.
782 class Iterator:
783 def __init__(self, start, finish):
784 self.start = start
785 self.finish = finish
786 self.i = self.start
787
Georg Brandla18af4e2007-04-21 15:47:16 +0000788 def __next__(self):
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000789 if self.i >= self.finish:
790 raise StopIteration
791 result = str(self.i) + '\n'
792 self.i += 1
793 return result
794
795 def __iter__(self):
796 return self
797
798 class Whatever:
799 def __init__(self, start, finish):
800 self.start = start
801 self.finish = finish
802
803 def __iter__(self):
804 return Iterator(self.start, self.finish)
Tim Peters527e64f2001-10-04 05:36:56 +0000805
806 f.writelines(Whatever(6, 6+2000))
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000807 f.close()
808
Alex Martelli01c77c62006-08-24 02:58:11 +0000809 f = open(TESTFN)
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000810 expected = [str(i) + "\n" for i in range(1, 2006)]
811 self.assertEqual(list(f), expected)
Tim Peters527e64f2001-10-04 05:36:56 +0000812
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000813 finally:
814 f.close()
815 try:
816 unlink(TESTFN)
817 except OSError:
818 pass
819
820
Tim Petersd6d010b2001-06-21 02:49:55 +0000821 # Test iterators on RHS of unpacking assignments.
822 def test_unpack_iter(self):
823 a, b = 1, 2
824 self.assertEqual((a, b), (1, 2))
825
826 a, b, c = IteratingSequenceClass(3)
827 self.assertEqual((a, b, c), (0, 1, 2))
828
829 try: # too many values
830 a, b = IteratingSequenceClass(3)
831 except ValueError:
832 pass
833 else:
834 self.fail("should have raised ValueError")
835
836 try: # not enough values
837 a, b, c = IteratingSequenceClass(2)
838 except ValueError:
839 pass
840 else:
841 self.fail("should have raised ValueError")
842
843 try: # not iterable
844 a, b, c = len
845 except TypeError:
846 pass
847 else:
848 self.fail("should have raised TypeError")
849
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000850 a, b, c = {1: 42, 2: 42, 3: 42}.values()
Tim Petersd6d010b2001-06-21 02:49:55 +0000851 self.assertEqual((a, b, c), (42, 42, 42))
852
853 f = open(TESTFN, "w")
854 lines = ("a\n", "bb\n", "ccc\n")
855 try:
856 for line in lines:
857 f.write(line)
858 finally:
859 f.close()
860 f = open(TESTFN, "r")
861 try:
862 a, b, c = f
863 self.assertEqual((a, b, c), lines)
864 finally:
865 f.close()
866 try:
867 unlink(TESTFN)
868 except OSError:
869 pass
870
871 (a, b), (c,) = IteratingSequenceClass(2), {42: 24}
872 self.assertEqual((a, b, c), (0, 1, 42))
873
Guido van Rossumbb8f59a2001-12-03 19:33:25 +0000874
Benjamin Peterson945c5792010-06-22 20:34:34 +0000875 @cpython_only
876 def test_ref_counting_behavior(self):
Guido van Rossumbb8f59a2001-12-03 19:33:25 +0000877 class C(object):
878 count = 0
879 def __new__(cls):
880 cls.count += 1
881 return object.__new__(cls)
882 def __del__(self):
883 cls = self.__class__
884 assert cls.count > 0
885 cls.count -= 1
886 x = C()
887 self.assertEqual(C.count, 1)
888 del x
889 self.assertEqual(C.count, 0)
890 l = [C(), C(), C()]
891 self.assertEqual(C.count, 3)
892 try:
893 a, b = iter(l)
894 except ValueError:
895 pass
896 del l
897 self.assertEqual(C.count, 0)
Fred Drake2e2be372001-09-20 21:33:42 +0000898
Guido van Rossum674eae62002-07-16 21:48:11 +0000899
900 # Make sure StopIteration is a "sink state".
901 # This tests various things that weren't sink states in Python 2.2.1,
902 # plus various things that always were fine.
903
904 def test_sinkstate_list(self):
905 # This used to fail
Guido van Rossum805365e2007-05-07 22:24:25 +0000906 a = list(range(5))
Guido van Rossum674eae62002-07-16 21:48:11 +0000907 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000908 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000909 a.extend(range(5, 10))
910 self.assertEqual(list(b), [])
911
912 def test_sinkstate_tuple(self):
913 a = (0, 1, 2, 3, 4)
914 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000915 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000916 self.assertEqual(list(b), [])
917
918 def test_sinkstate_string(self):
919 a = "abcde"
920 b = iter(a)
921 self.assertEqual(list(b), ['a', 'b', 'c', 'd', 'e'])
922 self.assertEqual(list(b), [])
923
924 def test_sinkstate_sequence(self):
925 # This used to fail
926 a = SequenceClass(5)
927 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000928 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000929 a.n = 10
930 self.assertEqual(list(b), [])
931
932 def test_sinkstate_callable(self):
933 # This used to fail
934 def spam(state=[0]):
935 i = state[0]
936 state[0] = i+1
937 if i == 10:
Collin Winter3add4d72007-08-29 23:37:32 +0000938 raise AssertionError("shouldn't have gotten this far")
Guido van Rossum674eae62002-07-16 21:48:11 +0000939 return i
940 b = iter(spam, 5)
Guido van Rossum805365e2007-05-07 22:24:25 +0000941 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000942 self.assertEqual(list(b), [])
943
944 def test_sinkstate_dict(self):
945 # XXX For a more thorough test, see towards the end of:
946 # http://mail.python.org/pipermail/python-dev/2002-July/026512.html
947 a = {1:1, 2:2, 0:0, 4:4, 3:3}
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000948 for b in iter(a), a.keys(), a.items(), a.values():
Guido van Rossum674eae62002-07-16 21:48:11 +0000949 b = iter(a)
950 self.assertEqual(len(list(b)), 5)
951 self.assertEqual(list(b), [])
952
953 def test_sinkstate_yield(self):
954 def gen():
955 for i in range(5):
956 yield i
957 b = gen()
Guido van Rossum805365e2007-05-07 22:24:25 +0000958 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000959 self.assertEqual(list(b), [])
960
961 def test_sinkstate_range(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000962 a = range(5)
Guido van Rossum674eae62002-07-16 21:48:11 +0000963 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000964 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000965 self.assertEqual(list(b), [])
966
967 def test_sinkstate_enumerate(self):
968 a = range(5)
969 e = enumerate(a)
970 b = iter(e)
Guido van Rossum801f0d72006-08-24 19:48:10 +0000971 self.assertEqual(list(b), list(zip(range(5), range(5))))
Guido van Rossum674eae62002-07-16 21:48:11 +0000972 self.assertEqual(list(b), [])
973
Amaury Forgeot d'Arcf343e012009-01-12 23:58:21 +0000974 def test_3720(self):
975 # Avoid a crash, when an iterator deletes its next() method.
976 class BadIterator(object):
977 def __iter__(self):
978 return self
979 def __next__(self):
980 del BadIterator.__next__
981 return 1
982
983 try:
984 for i in BadIterator() :
985 pass
986 except TypeError:
987 pass
988
Ezio Melotti739e1792012-11-18 23:16:02 +0200989 def test_extending_list_with_iterator_does_not_segfault(self):
990 # The code to extend a list with an iterator has a fair
991 # amount of nontrivial logic in terms of guessing how
992 # much memory to allocate in advance, "stealing" refs,
993 # and then shrinking at the end. This is a basic smoke
994 # test for that scenario.
995 def gen():
996 for i in range(500):
997 yield i
998 lst = [0] * 500
999 for i in range(240):
1000 lst.pop(0)
1001 lst.extend(gen())
1002 self.assertEqual(len(lst), 760)
1003
Serhiy Storchaka4faf5c52015-05-21 20:50:25 +03001004 @cpython_only
1005 def test_iter_overflow(self):
1006 # Test for the issue 22939
1007 it = iter(UnlimitedSequenceClass())
1008 # Manually set `it_index` to PY_SSIZE_T_MAX-2 without a loop
1009 it.__setstate__(sys.maxsize - 2)
1010 self.assertEqual(next(it), sys.maxsize - 2)
1011 self.assertEqual(next(it), sys.maxsize - 1)
1012 with self.assertRaises(OverflowError):
1013 next(it)
1014 # Check that Overflow error is always raised
1015 with self.assertRaises(OverflowError):
1016 next(it)
1017
1018 def test_iter_neg_setstate(self):
1019 it = iter(UnlimitedSequenceClass())
1020 it.__setstate__(-42)
1021 self.assertEqual(next(it), 0)
1022 self.assertEqual(next(it), 1)
1023
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +03001024 def test_free_after_iterating(self):
1025 check_free_after_iterating(self, iter, SequenceClass, (0,))
1026
Guido van Rossum97c1adf2016-08-18 09:22:23 -07001027 def test_error_iter(self):
1028 for typ in (DefaultIterClass, NoIterClass):
1029 self.assertRaises(TypeError, iter, typ())
1030
Guido van Rossum674eae62002-07-16 21:48:11 +00001031
Fred Drake2e2be372001-09-20 21:33:42 +00001032def test_main():
1033 run_unittest(TestCase)
1034
1035
1036if __name__ == "__main__":
1037 test_main()