blob: 22595fc09db8e90fa5a39e9bc28c53c0dfa7b443 [file] [log] [blame]
Guido van Rossum8b48cf92001-04-21 13:33:54 +00001# Test iterators.
2
3import unittest
Barry Warsaw04f357c2002-07-23 19:04:11 +00004from test.test_support import run_unittest, TESTFN, unlink, have_unicode
Guido van Rossum8b48cf92001-04-21 13:33:54 +00005
6# Test result of triple loop (too big to inline)
7TRIPLETS = [(0, 0, 0), (0, 0, 1), (0, 0, 2),
8 (0, 1, 0), (0, 1, 1), (0, 1, 2),
9 (0, 2, 0), (0, 2, 1), (0, 2, 2),
10
11 (1, 0, 0), (1, 0, 1), (1, 0, 2),
12 (1, 1, 0), (1, 1, 1), (1, 1, 2),
13 (1, 2, 0), (1, 2, 1), (1, 2, 2),
14
15 (2, 0, 0), (2, 0, 1), (2, 0, 2),
16 (2, 1, 0), (2, 1, 1), (2, 1, 2),
17 (2, 2, 0), (2, 2, 1), (2, 2, 2)]
18
19# Helper classes
20
21class BasicIterClass:
22 def __init__(self, n):
23 self.n = n
24 self.i = 0
Georg Brandla18af4e2007-04-21 15:47:16 +000025 def __next__(self):
Guido van Rossum8b48cf92001-04-21 13:33:54 +000026 res = self.i
27 if res >= self.n:
28 raise StopIteration
29 self.i = res + 1
30 return res
31
32class IteratingSequenceClass:
33 def __init__(self, n):
34 self.n = n
35 def __iter__(self):
36 return BasicIterClass(self.n)
37
38class SequenceClass:
39 def __init__(self, n):
40 self.n = n
41 def __getitem__(self, i):
42 if 0 <= i < self.n:
43 return i
44 else:
45 raise IndexError
46
47# Main test suite
48
49class TestCase(unittest.TestCase):
50
51 # Helper to check that an iterator returns a given sequence
52 def check_iterator(self, it, seq):
53 res = []
54 while 1:
55 try:
Georg Brandla18af4e2007-04-21 15:47:16 +000056 val = next(it)
Guido van Rossum8b48cf92001-04-21 13:33:54 +000057 except StopIteration:
58 break
59 res.append(val)
60 self.assertEqual(res, seq)
61
62 # Helper to check that a for loop generates a given sequence
63 def check_for_loop(self, expr, seq):
64 res = []
65 for val in expr:
66 res.append(val)
67 self.assertEqual(res, seq)
68
69 # Test basic use of iter() function
70 def test_iter_basic(self):
Guido van Rossum805365e2007-05-07 22:24:25 +000071 self.check_iterator(iter(range(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +000072
73 # Test that iter(iter(x)) is the same as iter(x)
74 def test_iter_idempotency(self):
Guido van Rossum805365e2007-05-07 22:24:25 +000075 seq = list(range(10))
Guido van Rossum8b48cf92001-04-21 13:33:54 +000076 it = iter(seq)
77 it2 = iter(it)
78 self.assert_(it is it2)
79
80 # Test that for loops over iterators work
81 def test_iter_for_loop(self):
Guido van Rossum805365e2007-05-07 22:24:25 +000082 self.check_for_loop(iter(range(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +000083
84 # Test several independent iterators over the same list
85 def test_iter_independence(self):
86 seq = range(3)
87 res = []
88 for i in iter(seq):
89 for j in iter(seq):
90 for k in iter(seq):
91 res.append((i, j, k))
92 self.assertEqual(res, TRIPLETS)
93
94 # Test triple list comprehension using iterators
95 def test_nested_comprehensions_iter(self):
96 seq = range(3)
97 res = [(i, j, k)
98 for i in iter(seq) for j in iter(seq) for k in iter(seq)]
99 self.assertEqual(res, TRIPLETS)
100
101 # Test triple list comprehension without iterators
102 def test_nested_comprehensions_for(self):
103 seq = range(3)
104 res = [(i, j, k) for i in seq for j in seq for k in seq]
105 self.assertEqual(res, TRIPLETS)
106
107 # Test a class with __iter__ in a for loop
108 def test_iter_class_for(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000109 self.check_for_loop(IteratingSequenceClass(10), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000110
111 # Test a class with __iter__ with explicit iter()
112 def test_iter_class_iter(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000113 self.check_iterator(iter(IteratingSequenceClass(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000114
115 # Test for loop on a sequence class without __iter__
116 def test_seq_class_for(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000117 self.check_for_loop(SequenceClass(10), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000118
119 # Test iter() on a sequence class without __iter__
120 def test_seq_class_iter(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000121 self.check_iterator(iter(SequenceClass(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000122
123 # Test two-argument iter() with callable instance
124 def test_iter_callable(self):
125 class C:
126 def __init__(self):
127 self.i = 0
128 def __call__(self):
129 i = self.i
130 self.i = i + 1
131 if i > 100:
132 raise IndexError # Emergency stop
133 return i
Guido van Rossum805365e2007-05-07 22:24:25 +0000134 self.check_iterator(iter(C(), 10), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000135
136 # Test two-argument iter() with function
137 def test_iter_function(self):
138 def spam(state=[0]):
139 i = state[0]
140 state[0] = i+1
141 return i
Guido van Rossum805365e2007-05-07 22:24:25 +0000142 self.check_iterator(iter(spam, 10), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000143
144 # Test two-argument iter() with function that raises StopIteration
145 def test_iter_function_stop(self):
146 def spam(state=[0]):
147 i = state[0]
148 if i == 10:
149 raise StopIteration
150 state[0] = i+1
151 return i
Guido van Rossum805365e2007-05-07 22:24:25 +0000152 self.check_iterator(iter(spam, 20), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000153
154 # Test exception propagation through function iterator
155 def test_exception_function(self):
156 def spam(state=[0]):
157 i = state[0]
158 state[0] = i+1
159 if i == 10:
160 raise RuntimeError
161 return i
162 res = []
163 try:
164 for x in iter(spam, 20):
165 res.append(x)
166 except RuntimeError:
Guido van Rossum805365e2007-05-07 22:24:25 +0000167 self.assertEqual(res, list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000168 else:
169 self.fail("should have raised RuntimeError")
170
171 # Test exception propagation through sequence iterator
172 def test_exception_sequence(self):
173 class MySequenceClass(SequenceClass):
174 def __getitem__(self, i):
175 if i == 10:
176 raise RuntimeError
177 return SequenceClass.__getitem__(self, i)
178 res = []
179 try:
180 for x in MySequenceClass(20):
181 res.append(x)
182 except RuntimeError:
Guido van Rossum805365e2007-05-07 22:24:25 +0000183 self.assertEqual(res, list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000184 else:
185 self.fail("should have raised RuntimeError")
186
187 # Test for StopIteration from __getitem__
188 def test_stop_sequence(self):
189 class MySequenceClass(SequenceClass):
190 def __getitem__(self, i):
191 if i == 10:
192 raise StopIteration
193 return SequenceClass.__getitem__(self, i)
Guido van Rossum805365e2007-05-07 22:24:25 +0000194 self.check_for_loop(MySequenceClass(20), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000195
196 # Test a big range
197 def test_iter_big_range(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000198 self.check_for_loop(iter(range(10000)), list(range(10000)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000199
200 # Test an empty list
201 def test_iter_empty(self):
202 self.check_for_loop(iter([]), [])
203
204 # Test a tuple
205 def test_iter_tuple(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000206 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 +0000207
Guido van Rossum805365e2007-05-07 22:24:25 +0000208 # Test a range
209 def test_iter_range(self):
210 self.check_for_loop(iter(range(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000211
212 # Test a string
213 def test_iter_string(self):
214 self.check_for_loop(iter("abcde"), ["a", "b", "c", "d", "e"])
215
216 # Test a Unicode string
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000217 if have_unicode:
218 def test_iter_unicode(self):
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000219 self.check_for_loop(iter(str("abcde")),
220 [str("a"), str("b"), str("c"),
221 str("d"), str("e")])
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000222
223 # Test a directory
224 def test_iter_dict(self):
225 dict = {}
226 for i in range(10):
227 dict[i] = None
Brett Cannon0caf6d82007-02-22 04:49:03 +0000228 self.check_for_loop(dict, list(dict.keys()))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000229
230 # Test a file
231 def test_iter_file(self):
232 f = open(TESTFN, "w")
233 try:
234 for i in range(5):
235 f.write("%d\n" % i)
236 finally:
237 f.close()
238 f = open(TESTFN, "r")
239 try:
240 self.check_for_loop(f, ["0\n", "1\n", "2\n", "3\n", "4\n"])
241 self.check_for_loop(f, [])
242 finally:
243 f.close()
244 try:
245 unlink(TESTFN)
246 except OSError:
247 pass
248
Tim Petersf553f892001-05-01 20:45:31 +0000249 # Test list()'s use of iterators.
250 def test_builtin_list(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000251 self.assertEqual(list(SequenceClass(5)), list(range(5)))
Tim Petersf553f892001-05-01 20:45:31 +0000252 self.assertEqual(list(SequenceClass(0)), [])
253 self.assertEqual(list(()), [])
Tim Petersf553f892001-05-01 20:45:31 +0000254
255 d = {"one": 1, "two": 2, "three": 3}
Brett Cannon0caf6d82007-02-22 04:49:03 +0000256 self.assertEqual(list(d), list(d.keys()))
Tim Petersf553f892001-05-01 20:45:31 +0000257
258 self.assertRaises(TypeError, list, list)
259 self.assertRaises(TypeError, list, 42)
260
261 f = open(TESTFN, "w")
262 try:
263 for i in range(5):
264 f.write("%d\n" % i)
265 finally:
266 f.close()
267 f = open(TESTFN, "r")
268 try:
269 self.assertEqual(list(f), ["0\n", "1\n", "2\n", "3\n", "4\n"])
270 f.seek(0, 0)
Guido van Rossum8ee52432002-08-06 17:14:04 +0000271 self.assertEqual(list(f),
Tim Petersf553f892001-05-01 20:45:31 +0000272 ["0\n", "1\n", "2\n", "3\n", "4\n"])
273 finally:
274 f.close()
275 try:
276 unlink(TESTFN)
277 except OSError:
278 pass
279
Tim Peters6912d4d2001-05-05 03:56:37 +0000280 # Test tuples()'s use of iterators.
281 def test_builtin_tuple(self):
282 self.assertEqual(tuple(SequenceClass(5)), (0, 1, 2, 3, 4))
283 self.assertEqual(tuple(SequenceClass(0)), ())
284 self.assertEqual(tuple([]), ())
285 self.assertEqual(tuple(()), ())
286 self.assertEqual(tuple("abc"), ("a", "b", "c"))
287
288 d = {"one": 1, "two": 2, "three": 3}
289 self.assertEqual(tuple(d), tuple(d.keys()))
290
291 self.assertRaises(TypeError, tuple, list)
292 self.assertRaises(TypeError, tuple, 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(tuple(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(tuple(f),
Tim Peters6912d4d2001-05-05 03:56:37 +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 Peters0e57abf2001-05-02 07:39:38 +0000313 # Test filter()'s use of iterators.
314 def test_builtin_filter(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000315 self.assertEqual(filter(None, SequenceClass(5)), list(range(1, 5)))
Tim Peters0e57abf2001-05-02 07:39:38 +0000316 self.assertEqual(filter(None, SequenceClass(0)), [])
317 self.assertEqual(filter(None, ()), ())
318 self.assertEqual(filter(None, "abc"), "abc")
319
320 d = {"one": 1, "two": 2, "three": 3}
Brett Cannon0caf6d82007-02-22 04:49:03 +0000321 self.assertEqual(filter(None, d), list(d.keys()))
Tim Peters0e57abf2001-05-02 07:39:38 +0000322
323 self.assertRaises(TypeError, filter, None, list)
324 self.assertRaises(TypeError, filter, None, 42)
325
326 class Boolean:
327 def __init__(self, truth):
328 self.truth = truth
Jack Diederich4dafcc42006-11-28 19:15:13 +0000329 def __bool__(self):
Tim Peters0e57abf2001-05-02 07:39:38 +0000330 return self.truth
Jack Diederich4dafcc42006-11-28 19:15:13 +0000331 bTrue = Boolean(True)
332 bFalse = Boolean(False)
Tim Peters0e57abf2001-05-02 07:39:38 +0000333
334 class Seq:
335 def __init__(self, *args):
336 self.vals = args
337 def __iter__(self):
338 class SeqIter:
339 def __init__(self, vals):
340 self.vals = vals
341 self.i = 0
342 def __iter__(self):
343 return self
Georg Brandla18af4e2007-04-21 15:47:16 +0000344 def __next__(self):
Tim Peters0e57abf2001-05-02 07:39:38 +0000345 i = self.i
346 self.i = i + 1
347 if i < len(self.vals):
348 return self.vals[i]
349 else:
350 raise StopIteration
351 return SeqIter(self.vals)
352
Tim Peterscae330e2002-12-23 16:50:58 +0000353 seq = Seq(*([bTrue, bFalse] * 25))
354 self.assertEqual(filter(lambda x: not x, seq), [bFalse]*25)
355 self.assertEqual(filter(lambda x: not x, iter(seq)), [bFalse]*25)
Tim Peters0e57abf2001-05-02 07:39:38 +0000356
Tim Petersc3074532001-05-03 07:00:32 +0000357 # Test max() and min()'s use of iterators.
358 def test_builtin_max_min(self):
359 self.assertEqual(max(SequenceClass(5)), 4)
360 self.assertEqual(min(SequenceClass(5)), 0)
361 self.assertEqual(max(8, -1), 8)
362 self.assertEqual(min(8, -1), -1)
363
364 d = {"one": 1, "two": 2, "three": 3}
365 self.assertEqual(max(d), "two")
366 self.assertEqual(min(d), "one")
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000367 self.assertEqual(max(d.values()), 3)
368 self.assertEqual(min(iter(d.values())), 1)
Tim Petersc3074532001-05-03 07:00:32 +0000369
Tim Petersc3074532001-05-03 07:00:32 +0000370 f = open(TESTFN, "w")
371 try:
372 f.write("medium line\n")
373 f.write("xtra large line\n")
374 f.write("itty-bitty line\n")
375 finally:
376 f.close()
377 f = open(TESTFN, "r")
378 try:
379 self.assertEqual(min(f), "itty-bitty line\n")
380 f.seek(0, 0)
381 self.assertEqual(max(f), "xtra large line\n")
382 finally:
383 f.close()
384 try:
385 unlink(TESTFN)
386 except OSError:
387 pass
388
Tim Peters4e9afdc2001-05-03 23:54:49 +0000389 # Test map()'s use of iterators.
390 def test_builtin_map(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000391 self.assertEqual(map(None, SequenceClass(5)), list(range(5)))
392 self.assertEqual(map(lambda x: x+1, SequenceClass(5)), list(range(1, 6)))
Tim Peters4e9afdc2001-05-03 23:54:49 +0000393
394 d = {"one": 1, "two": 2, "three": 3}
Brett Cannon0caf6d82007-02-22 04:49:03 +0000395 self.assertEqual(map(None, d), list(d.keys()))
396 self.assertEqual(map(lambda k, d=d: (k, d[k]), d), list(d.items()))
397 dkeys = list(d.keys())
Tim Peters4e9afdc2001-05-03 23:54:49 +0000398 expected = [(i < len(d) and dkeys[i] or None,
399 i,
400 i < len(d) and dkeys[i] or None)
401 for i in range(5)]
402 self.assertEqual(map(None, d,
403 SequenceClass(5),
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000404 iter(d.keys())),
Tim Peters8bc10b02001-05-03 23:58:47 +0000405 expected)
Tim Peters4e9afdc2001-05-03 23:54:49 +0000406
407 f = open(TESTFN, "w")
408 try:
409 for i in range(10):
410 f.write("xy" * i + "\n") # line i has len 2*i+1
411 finally:
412 f.close()
413 f = open(TESTFN, "r")
414 try:
Guido van Rossum805365e2007-05-07 22:24:25 +0000415 self.assertEqual(map(len, f), list(range(1, 21, 2)))
Tim Peters4e9afdc2001-05-03 23:54:49 +0000416 finally:
417 f.close()
418 try:
419 unlink(TESTFN)
420 except OSError:
421 pass
422
Tim Peters8572b4f2001-05-06 01:05:02 +0000423 # Test zip()'s use of iterators.
424 def test_builtin_zip(self):
Guido van Rossum801f0d72006-08-24 19:48:10 +0000425 self.assertEqual(list(zip()), [])
426 self.assertEqual(list(zip(*[])), [])
427 self.assertEqual(list(zip(*[(1, 2), 'ab'])), [(1, 'a'), (2, 'b')])
Raymond Hettingereaef6152003-08-02 07:42:57 +0000428
Tim Peters8572b4f2001-05-06 01:05:02 +0000429 self.assertRaises(TypeError, zip, None)
430 self.assertRaises(TypeError, zip, range(10), 42)
431 self.assertRaises(TypeError, zip, range(10), zip)
432
Guido van Rossum801f0d72006-08-24 19:48:10 +0000433 self.assertEqual(list(zip(IteratingSequenceClass(3))),
Tim Peters8572b4f2001-05-06 01:05:02 +0000434 [(0,), (1,), (2,)])
Guido van Rossum801f0d72006-08-24 19:48:10 +0000435 self.assertEqual(list(zip(SequenceClass(3))),
Tim Peters8572b4f2001-05-06 01:05:02 +0000436 [(0,), (1,), (2,)])
437
438 d = {"one": 1, "two": 2, "three": 3}
Brett Cannon0caf6d82007-02-22 04:49:03 +0000439 self.assertEqual(list(d.items()), list(zip(d, d.values())))
Tim Peters8572b4f2001-05-06 01:05:02 +0000440
441 # Generate all ints starting at constructor arg.
442 class IntsFrom:
443 def __init__(self, start):
444 self.i = start
445
446 def __iter__(self):
447 return self
448
Georg Brandla18af4e2007-04-21 15:47:16 +0000449 def __next__(self):
Tim Peters8572b4f2001-05-06 01:05:02 +0000450 i = self.i
451 self.i = i+1
452 return i
453
454 f = open(TESTFN, "w")
455 try:
456 f.write("a\n" "bbb\n" "cc\n")
457 finally:
458 f.close()
459 f = open(TESTFN, "r")
460 try:
Guido van Rossum801f0d72006-08-24 19:48:10 +0000461 self.assertEqual(list(zip(IntsFrom(0), f, IntsFrom(-100))),
Tim Peters8572b4f2001-05-06 01:05:02 +0000462 [(0, "a\n", -100),
463 (1, "bbb\n", -99),
464 (2, "cc\n", -98)])
465 finally:
466 f.close()
467 try:
468 unlink(TESTFN)
469 except OSError:
470 pass
471
Guido van Rossum805365e2007-05-07 22:24:25 +0000472 self.assertEqual(list(zip(range(5))), [(i,) for i in range(5)])
Tim Peters67d687a2002-04-29 21:27:32 +0000473
474 # Classes that lie about their lengths.
475 class NoGuessLen5:
476 def __getitem__(self, i):
477 if i >= 5:
478 raise IndexError
479 return i
480
481 class Guess3Len5(NoGuessLen5):
482 def __len__(self):
483 return 3
484
485 class Guess30Len5(NoGuessLen5):
486 def __len__(self):
487 return 30
488
Guido van Rossum801f0d72006-08-24 19:48:10 +0000489 def lzip(*args):
490 return list(zip(*args))
491
Tim Peters67d687a2002-04-29 21:27:32 +0000492 self.assertEqual(len(Guess3Len5()), 3)
493 self.assertEqual(len(Guess30Len5()), 30)
Guido van Rossum801f0d72006-08-24 19:48:10 +0000494 self.assertEqual(lzip(NoGuessLen5()), lzip(range(5)))
495 self.assertEqual(lzip(Guess3Len5()), lzip(range(5)))
496 self.assertEqual(lzip(Guess30Len5()), lzip(range(5)))
Tim Peters67d687a2002-04-29 21:27:32 +0000497
498 expected = [(i, i) for i in range(5)]
499 for x in NoGuessLen5(), Guess3Len5(), Guess30Len5():
500 for y in NoGuessLen5(), Guess3Len5(), Guess30Len5():
Guido van Rossum801f0d72006-08-24 19:48:10 +0000501 self.assertEqual(lzip(x, y), expected)
Tim Peters67d687a2002-04-29 21:27:32 +0000502
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000503 # This test case will be removed if we don't have Unicode
Tim Peters2cfe3682001-05-05 05:36:48 +0000504 def test_unicode_join_endcase(self):
505
506 # This class inserts a Unicode object into its argument's natural
507 # iteration, in the 3rd position.
508 class OhPhooey:
509 def __init__(self, seq):
510 self.it = iter(seq)
511 self.i = 0
512
513 def __iter__(self):
514 return self
515
Georg Brandla18af4e2007-04-21 15:47:16 +0000516 def __next__(self):
Tim Peters2cfe3682001-05-05 05:36:48 +0000517 i = self.i
518 self.i = i+1
519 if i == 2:
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000520 return str("fooled you!")
Georg Brandla18af4e2007-04-21 15:47:16 +0000521 return next(self.it)
Tim Peters2cfe3682001-05-05 05:36:48 +0000522
523 f = open(TESTFN, "w")
524 try:
525 f.write("a\n" + "b\n" + "c\n")
526 finally:
527 f.close()
528
529 f = open(TESTFN, "r")
530 # Nasty: string.join(s) can't know whether unicode.join() is needed
531 # until it's seen all of s's elements. But in this case, f's
532 # iterator cannot be restarted. So what we're testing here is
533 # whether string.join() can manage to remember everything it's seen
534 # and pass that on to unicode.join().
535 try:
536 got = " - ".join(OhPhooey(f))
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000537 self.assertEqual(got, str("a\n - b\n - fooled you! - c\n"))
Tim Peters2cfe3682001-05-05 05:36:48 +0000538 finally:
539 f.close()
540 try:
541 unlink(TESTFN)
542 except OSError:
543 pass
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000544 if not have_unicode:
545 def test_unicode_join_endcase(self): pass
Tim Peters2cfe3682001-05-05 05:36:48 +0000546
Tim Petersde9725f2001-05-05 10:06:17 +0000547 # Test iterators with 'x in y' and 'x not in y'.
548 def test_in_and_not_in(self):
Tim Peterscb8d3682001-05-05 21:05:01 +0000549 for sc5 in IteratingSequenceClass(5), SequenceClass(5):
550 for i in range(5):
551 self.assert_(i in sc5)
552 for i in "abc", -1, 5, 42.42, (3, 4), [], {1: 1}, 3-12j, sc5:
553 self.assert_(i not in sc5)
Tim Petersde9725f2001-05-05 10:06:17 +0000554
555 self.assertRaises(TypeError, lambda: 3 in 12)
556 self.assertRaises(TypeError, lambda: 3 not in map)
557
558 d = {"one": 1, "two": 2, "three": 3, 1j: 2j}
559 for k in d:
560 self.assert_(k in d)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000561 self.assert_(k not in d.values())
Tim Petersde9725f2001-05-05 10:06:17 +0000562 for v in d.values():
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000563 self.assert_(v in d.values())
Tim Petersde9725f2001-05-05 10:06:17 +0000564 self.assert_(v not in d)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000565 for k, v in d.items():
566 self.assert_((k, v) in d.items())
567 self.assert_((v, k) not in d.items())
Tim Petersde9725f2001-05-05 10:06:17 +0000568
569 f = open(TESTFN, "w")
570 try:
571 f.write("a\n" "b\n" "c\n")
572 finally:
573 f.close()
574 f = open(TESTFN, "r")
575 try:
576 for chunk in "abc":
577 f.seek(0, 0)
578 self.assert_(chunk not in f)
579 f.seek(0, 0)
580 self.assert_((chunk + "\n") in f)
581 finally:
582 f.close()
583 try:
584 unlink(TESTFN)
585 except OSError:
586 pass
587
Tim Peters75f8e352001-05-05 11:33:43 +0000588 # Test iterators with operator.countOf (PySequence_Count).
589 def test_countOf(self):
590 from operator import countOf
591 self.assertEqual(countOf([1,2,2,3,2,5], 2), 3)
592 self.assertEqual(countOf((1,2,2,3,2,5), 2), 3)
593 self.assertEqual(countOf("122325", "2"), 3)
594 self.assertEqual(countOf("122325", "6"), 0)
595
596 self.assertRaises(TypeError, countOf, 42, 1)
597 self.assertRaises(TypeError, countOf, countOf, countOf)
598
599 d = {"one": 3, "two": 3, "three": 3, 1j: 2j}
600 for k in d:
601 self.assertEqual(countOf(d, k), 1)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000602 self.assertEqual(countOf(d.values(), 3), 3)
603 self.assertEqual(countOf(d.values(), 2j), 1)
604 self.assertEqual(countOf(d.values(), 1j), 0)
Tim Peters75f8e352001-05-05 11:33:43 +0000605
606 f = open(TESTFN, "w")
607 try:
608 f.write("a\n" "b\n" "c\n" "b\n")
609 finally:
610 f.close()
611 f = open(TESTFN, "r")
612 try:
613 for letter, count in ("a", 1), ("b", 2), ("c", 1), ("d", 0):
614 f.seek(0, 0)
615 self.assertEqual(countOf(f, letter + "\n"), count)
616 finally:
617 f.close()
618 try:
619 unlink(TESTFN)
620 except OSError:
621 pass
622
Tim Peters16a77ad2001-09-08 04:00:12 +0000623 # Test iterators with operator.indexOf (PySequence_Index).
624 def test_indexOf(self):
625 from operator import indexOf
626 self.assertEqual(indexOf([1,2,2,3,2,5], 1), 0)
627 self.assertEqual(indexOf((1,2,2,3,2,5), 2), 1)
628 self.assertEqual(indexOf((1,2,2,3,2,5), 3), 3)
629 self.assertEqual(indexOf((1,2,2,3,2,5), 5), 5)
630 self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 0)
631 self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 6)
632
633 self.assertEqual(indexOf("122325", "2"), 1)
634 self.assertEqual(indexOf("122325", "5"), 5)
635 self.assertRaises(ValueError, indexOf, "122325", "6")
636
637 self.assertRaises(TypeError, indexOf, 42, 1)
638 self.assertRaises(TypeError, indexOf, indexOf, indexOf)
639
640 f = open(TESTFN, "w")
641 try:
642 f.write("a\n" "b\n" "c\n" "d\n" "e\n")
643 finally:
644 f.close()
645 f = open(TESTFN, "r")
646 try:
647 fiter = iter(f)
648 self.assertEqual(indexOf(fiter, "b\n"), 1)
649 self.assertEqual(indexOf(fiter, "d\n"), 1)
650 self.assertEqual(indexOf(fiter, "e\n"), 0)
651 self.assertRaises(ValueError, indexOf, fiter, "a\n")
652 finally:
653 f.close()
654 try:
655 unlink(TESTFN)
656 except OSError:
657 pass
658
659 iclass = IteratingSequenceClass(3)
660 for i in range(3):
661 self.assertEqual(indexOf(iclass, i), i)
662 self.assertRaises(ValueError, indexOf, iclass, -1)
663
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000664 # Test iterators with file.writelines().
665 def test_writelines(self):
Alex Martelli01c77c62006-08-24 02:58:11 +0000666 f = open(TESTFN, "w")
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000667
668 try:
669 self.assertRaises(TypeError, f.writelines, None)
670 self.assertRaises(TypeError, f.writelines, 42)
Tim Peters527e64f2001-10-04 05:36:56 +0000671
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000672 f.writelines(["1\n", "2\n"])
673 f.writelines(("3\n", "4\n"))
674 f.writelines({'5\n': None})
675 f.writelines({})
676
677 # Try a big chunk too.
678 class Iterator:
679 def __init__(self, start, finish):
680 self.start = start
681 self.finish = finish
682 self.i = self.start
683
Georg Brandla18af4e2007-04-21 15:47:16 +0000684 def __next__(self):
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000685 if self.i >= self.finish:
686 raise StopIteration
687 result = str(self.i) + '\n'
688 self.i += 1
689 return result
690
691 def __iter__(self):
692 return self
693
694 class Whatever:
695 def __init__(self, start, finish):
696 self.start = start
697 self.finish = finish
698
699 def __iter__(self):
700 return Iterator(self.start, self.finish)
Tim Peters527e64f2001-10-04 05:36:56 +0000701
702 f.writelines(Whatever(6, 6+2000))
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000703 f.close()
704
Alex Martelli01c77c62006-08-24 02:58:11 +0000705 f = open(TESTFN)
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000706 expected = [str(i) + "\n" for i in range(1, 2006)]
707 self.assertEqual(list(f), expected)
Tim Peters527e64f2001-10-04 05:36:56 +0000708
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000709 finally:
710 f.close()
711 try:
712 unlink(TESTFN)
713 except OSError:
714 pass
715
716
Tim Petersd6d010b2001-06-21 02:49:55 +0000717 # Test iterators on RHS of unpacking assignments.
718 def test_unpack_iter(self):
719 a, b = 1, 2
720 self.assertEqual((a, b), (1, 2))
721
722 a, b, c = IteratingSequenceClass(3)
723 self.assertEqual((a, b, c), (0, 1, 2))
724
725 try: # too many values
726 a, b = IteratingSequenceClass(3)
727 except ValueError:
728 pass
729 else:
730 self.fail("should have raised ValueError")
731
732 try: # not enough values
733 a, b, c = IteratingSequenceClass(2)
734 except ValueError:
735 pass
736 else:
737 self.fail("should have raised ValueError")
738
739 try: # not iterable
740 a, b, c = len
741 except TypeError:
742 pass
743 else:
744 self.fail("should have raised TypeError")
745
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000746 a, b, c = {1: 42, 2: 42, 3: 42}.values()
Tim Petersd6d010b2001-06-21 02:49:55 +0000747 self.assertEqual((a, b, c), (42, 42, 42))
748
749 f = open(TESTFN, "w")
750 lines = ("a\n", "bb\n", "ccc\n")
751 try:
752 for line in lines:
753 f.write(line)
754 finally:
755 f.close()
756 f = open(TESTFN, "r")
757 try:
758 a, b, c = f
759 self.assertEqual((a, b, c), lines)
760 finally:
761 f.close()
762 try:
763 unlink(TESTFN)
764 except OSError:
765 pass
766
767 (a, b), (c,) = IteratingSequenceClass(2), {42: 24}
768 self.assertEqual((a, b, c), (0, 1, 42))
769
Guido van Rossumbb8f59a2001-12-03 19:33:25 +0000770 # Test reference count behavior
771
772 class C(object):
773 count = 0
774 def __new__(cls):
775 cls.count += 1
776 return object.__new__(cls)
777 def __del__(self):
778 cls = self.__class__
779 assert cls.count > 0
780 cls.count -= 1
781 x = C()
782 self.assertEqual(C.count, 1)
783 del x
784 self.assertEqual(C.count, 0)
785 l = [C(), C(), C()]
786 self.assertEqual(C.count, 3)
787 try:
788 a, b = iter(l)
789 except ValueError:
790 pass
791 del l
792 self.assertEqual(C.count, 0)
Fred Drake2e2be372001-09-20 21:33:42 +0000793
Guido van Rossum674eae62002-07-16 21:48:11 +0000794
795 # Make sure StopIteration is a "sink state".
796 # This tests various things that weren't sink states in Python 2.2.1,
797 # plus various things that always were fine.
798
799 def test_sinkstate_list(self):
800 # This used to fail
Guido van Rossum805365e2007-05-07 22:24:25 +0000801 a = list(range(5))
Guido van Rossum674eae62002-07-16 21:48:11 +0000802 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000803 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000804 a.extend(range(5, 10))
805 self.assertEqual(list(b), [])
806
807 def test_sinkstate_tuple(self):
808 a = (0, 1, 2, 3, 4)
809 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000810 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000811 self.assertEqual(list(b), [])
812
813 def test_sinkstate_string(self):
814 a = "abcde"
815 b = iter(a)
816 self.assertEqual(list(b), ['a', 'b', 'c', 'd', 'e'])
817 self.assertEqual(list(b), [])
818
819 def test_sinkstate_sequence(self):
820 # This used to fail
821 a = SequenceClass(5)
822 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000823 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000824 a.n = 10
825 self.assertEqual(list(b), [])
826
827 def test_sinkstate_callable(self):
828 # This used to fail
829 def spam(state=[0]):
830 i = state[0]
831 state[0] = i+1
832 if i == 10:
833 raise AssertionError, "shouldn't have gotten this far"
834 return i
835 b = iter(spam, 5)
Guido van Rossum805365e2007-05-07 22:24:25 +0000836 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000837 self.assertEqual(list(b), [])
838
839 def test_sinkstate_dict(self):
840 # XXX For a more thorough test, see towards the end of:
841 # http://mail.python.org/pipermail/python-dev/2002-July/026512.html
842 a = {1:1, 2:2, 0:0, 4:4, 3:3}
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000843 for b in iter(a), a.keys(), a.items(), a.values():
Guido van Rossum674eae62002-07-16 21:48:11 +0000844 b = iter(a)
845 self.assertEqual(len(list(b)), 5)
846 self.assertEqual(list(b), [])
847
848 def test_sinkstate_yield(self):
849 def gen():
850 for i in range(5):
851 yield i
852 b = gen()
Guido van Rossum805365e2007-05-07 22:24:25 +0000853 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000854 self.assertEqual(list(b), [])
855
856 def test_sinkstate_range(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000857 a = range(5)
Guido van Rossum674eae62002-07-16 21:48:11 +0000858 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000859 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000860 self.assertEqual(list(b), [])
861
862 def test_sinkstate_enumerate(self):
863 a = range(5)
864 e = enumerate(a)
865 b = iter(e)
Guido van Rossum801f0d72006-08-24 19:48:10 +0000866 self.assertEqual(list(b), list(zip(range(5), range(5))))
Guido van Rossum674eae62002-07-16 21:48:11 +0000867 self.assertEqual(list(b), [])
868
869
Fred Drake2e2be372001-09-20 21:33:42 +0000870def test_main():
871 run_unittest(TestCase)
872
873
874if __name__ == "__main__":
875 test_main()