0001 # Test iterators. 0002 0003 import unittest 0004 from test.test_support import run_unittest, TESTFN, unlink, have_unicode 0005 0006 # Test result of triple loop (too big to inline) 0007 TRIPLETS = [(0, 0, 0), (0, 0, 1), (0, 0, 2), 0008 (0, 1, 0), (0, 1, 1), (0, 1, 2), 0009 (0, 2, 0), (0, 2, 1), (0, 2, 2), 0010 0011 (1, 0, 0), (1, 0, 1), (1, 0, 2), 0012 (1, 1, 0), (1, 1, 1), (1, 1, 2), 0013 (1, 2, 0), (1, 2, 1), (1, 2, 2), 0014 0015 (2, 0, 0), (2, 0, 1), (2, 0, 2), 0016 (2, 1, 0), (2, 1, 1), (2, 1, 2), 0017 (2, 2, 0), (2, 2, 1), (2, 2, 2)] 0018 0019 # Helper classes 0020 0021 class BasicIterClass: 0022 def __init__(self, n): 0023 self.n = n 0024 self.i = 0 0025 def next(self): 0026 res = self.i 0027 if res >= self.n: 0028 raise StopIteration 0029 self.i = res + 1 0030 return res 0031 0032 class IteratingSequenceClass: 0033 def __init__(self, n): 0034 self.n = n 0035 def __iter__(self): 0036 return BasicIterClass(self.n) 0037 0038 class SequenceClass: 0039 def __init__(self, n): 0040 self.n = n 0041 def __getitem__(self, i): 0042 if 0 <= i < self.n: 0043 return i 0044 else: 0045 raise IndexError 0046 0047 # Main test suite 0048 0049 class TestCase(unittest.TestCase): 0050 0051 # Helper to check that an iterator returns a given sequence 0052 def check_iterator(self, it, seq): 0053 res = [] 0054 while 1: 0055 try: 0056 val = it.next() 0057 except StopIteration: 0058 break 0059 res.append(val) 0060 self.assertEqual(res, seq) 0061 0062 # Helper to check that a for loop generates a given sequence 0063 def check_for_loop(self, expr, seq): 0064 res = [] 0065 for val in expr: 0066 res.append(val) 0067 self.assertEqual(res, seq) 0068 0069 # Test basic use of iter() function 0070 def test_iter_basic(self): 0071 self.check_iterator(iter(range(10)), range(10)) 0072 0073 # Test that iter(iter(x)) is the same as iter(x) 0074 def test_iter_idempotency(self): 0075 seq = range(10) 0076 it = iter(seq) 0077 it2 = iter(it) 0078 self.assert_(it is it2) 0079 0080 # Test that for loops over iterators work 0081 def test_iter_for_loop(self): 0082 self.check_for_loop(iter(range(10)), range(10)) 0083 0084 # Test several independent iterators over the same list 0085 def test_iter_independence(self): 0086 seq = range(3) 0087 res = [] 0088 for i in iter(seq): 0089 for j in iter(seq): 0090 for k in iter(seq): 0091 res.append((i, j, k)) 0092 self.assertEqual(res, TRIPLETS) 0093 0094 # Test triple list comprehension using iterators 0095 def test_nested_comprehensions_iter(self): 0096 seq = range(3) 0097 res = [(i, j, k) 0098 for i in iter(seq) for j in iter(seq) for k in iter(seq)] 0099 self.assertEqual(res, TRIPLETS) 0100 0101 # Test triple list comprehension without iterators 0102 def test_nested_comprehensions_for(self): 0103 seq = range(3) 0104 res = [(i, j, k) for i in seq for j in seq for k in seq] 0105 self.assertEqual(res, TRIPLETS) 0106 0107 # Test a class with __iter__ in a for loop 0108 def test_iter_class_for(self): 0109 self.check_for_loop(IteratingSequenceClass(10), range(10)) 0110 0111 # Test a class with __iter__ with explicit iter() 0112 def test_iter_class_iter(self): 0113 self.check_iterator(iter(IteratingSequenceClass(10)), range(10)) 0114 0115 # Test for loop on a sequence class without __iter__ 0116 def test_seq_class_for(self): 0117 self.check_for_loop(SequenceClass(10), range(10)) 0118 0119 # Test iter() on a sequence class without __iter__ 0120 def test_seq_class_iter(self): 0121 self.check_iterator(iter(SequenceClass(10)), range(10)) 0122 0123 # Test two-argument iter() with callable instance 0124 def test_iter_callable(self): 0125 class C: 0126 def __init__(self): 0127 self.i = 0 0128 def __call__(self): 0129 i = self.i 0130 self.i = i + 1 0131 if i > 100: 0132 raise IndexError # Emergency stop 0133 return i 0134 self.check_iterator(iter(C(), 10), range(10)) 0135 0136 # Test two-argument iter() with function 0137 def test_iter_function(self): 0138 def spam(state=[0]): 0139 i = state[0] 0140 state[0] = i+1 0141 return i 0142 self.check_iterator(iter(spam, 10), range(10)) 0143 0144 # Test two-argument iter() with function that raises StopIteration 0145 def test_iter_function_stop(self): 0146 def spam(state=[0]): 0147 i = state[0] 0148 if i == 10: 0149 raise StopIteration 0150 state[0] = i+1 0151 return i 0152 self.check_iterator(iter(spam, 20), range(10)) 0153 0154 # Test exception propagation through function iterator 0155 def test_exception_function(self): 0156 def spam(state=[0]): 0157 i = state[0] 0158 state[0] = i+1 0159 if i == 10: 0160 raise RuntimeError 0161 return i 0162 res = [] 0163 try: 0164 for x in iter(spam, 20): 0165 res.append(x) 0166 except RuntimeError: 0167 self.assertEqual(res, range(10)) 0168 else: 0169 self.fail("should have raised RuntimeError") 0170 0171 # Test exception propagation through sequence iterator 0172 def test_exception_sequence(self): 0173 class MySequenceClass(SequenceClass): 0174 def __getitem__(self, i): 0175 if i == 10: 0176 raise RuntimeError 0177 return SequenceClass.__getitem__(self, i) 0178 res = [] 0179 try: 0180 for x in MySequenceClass(20): 0181 res.append(x) 0182 except RuntimeError: 0183 self.assertEqual(res, range(10)) 0184 else: 0185 self.fail("should have raised RuntimeError") 0186 0187 # Test for StopIteration from __getitem__ 0188 def test_stop_sequence(self): 0189 class MySequenceClass(SequenceClass): 0190 def __getitem__(self, i): 0191 if i == 10: 0192 raise StopIteration 0193 return SequenceClass.__getitem__(self, i) 0194 self.check_for_loop(MySequenceClass(20), range(10)) 0195 0196 # Test a big range 0197 def test_iter_big_range(self): 0198 self.check_for_loop(iter(range(10000)), range(10000)) 0199 0200 # Test an empty list 0201 def test_iter_empty(self): 0202 self.check_for_loop(iter([]), []) 0203 0204 # Test a tuple 0205 def test_iter_tuple(self): 0206 self.check_for_loop(iter((0,1,2,3,4,5,6,7,8,9)), range(10)) 0207 0208 # Test an xrange 0209 def test_iter_xrange(self): 0210 self.check_for_loop(iter(xrange(10)), range(10)) 0211 0212 # Test a string 0213 def test_iter_string(self): 0214 self.check_for_loop(iter("abcde"), ["a", "b", "c", "d", "e"]) 0215 0216 # Test a Unicode string 0217 if have_unicode: 0218 def test_iter_unicode(self): 0219 self.check_for_loop(iter(unicode("abcde")), 0220 [unicode("a"), unicode("b"), unicode("c"), 0221 unicode("d"), unicode("e")]) 0222 0223 # Test a directory 0224 def test_iter_dict(self): 0225 dict = {} 0226 for i in range(10): 0227 dict[i] = None 0228 self.check_for_loop(dict, dict.keys()) 0229 0230 # Test a file 0231 def test_iter_file(self): 0232 f = open(TESTFN, "w") 0233 try: 0234 for i in range(5): 0235 f.write("%d\n" % i) 0236 finally: 0237 f.close() 0238 f = open(TESTFN, "r") 0239 try: 0240 self.check_for_loop(f, ["0\n", "1\n", "2\n", "3\n", "4\n"]) 0241 self.check_for_loop(f, []) 0242 finally: 0243 f.close() 0244 try: 0245 unlink(TESTFN) 0246 except OSError: 0247 pass 0248 0249 # Test list()'s use of iterators. 0250 def test_builtin_list(self): 0251 self.assertEqual(list(SequenceClass(5)), range(5)) 0252 self.assertEqual(list(SequenceClass(0)), []) 0253 self.assertEqual(list(()), []) 0254 self.assertEqual(list(range(10, -1, -1)), range(10, -1, -1)) 0255 0256 d = {"one": 1, "two": 2, "three": 3} 0257 self.assertEqual(list(d), d.keys()) 0258 0259 self.assertRaises(TypeError, list, list) 0260 self.assertRaises(TypeError, list, 42) 0261 0262 f = open(TESTFN, "w") 0263 try: 0264 for i in range(5): 0265 f.write("%d\n" % i) 0266 finally: 0267 f.close() 0268 f = open(TESTFN, "r") 0269 try: 0270 self.assertEqual(list(f), ["0\n", "1\n", "2\n", "3\n", "4\n"]) 0271 f.seek(0, 0) 0272 self.assertEqual(list(f), 0273 ["0\n", "1\n", "2\n", "3\n", "4\n"]) 0274 finally: 0275 f.close() 0276 try: 0277 unlink(TESTFN) 0278 except OSError: 0279 pass 0280 0281 # Test tuples()'s use of iterators. 0282 def test_builtin_tuple(self): 0283 self.assertEqual(tuple(SequenceClass(5)), (0, 1, 2, 3, 4)) 0284 self.assertEqual(tuple(SequenceClass(0)), ()) 0285 self.assertEqual(tuple([]), ()) 0286 self.assertEqual(tuple(()), ()) 0287 self.assertEqual(tuple("abc"), ("a", "b", "c")) 0288 0289 d = {"one": 1, "two": 2, "three": 3} 0290 self.assertEqual(tuple(d), tuple(d.keys())) 0291 0292 self.assertRaises(TypeError, tuple, list) 0293 self.assertRaises(TypeError, tuple, 42) 0294 0295 f = open(TESTFN, "w") 0296 try: 0297 for i in range(5): 0298 f.write("%d\n" % i) 0299 finally: 0300 f.close() 0301 f = open(TESTFN, "r") 0302 try: 0303 self.assertEqual(tuple(f), ("0\n", "1\n", "2\n", "3\n", "4\n")) 0304 f.seek(0, 0) 0305 self.assertEqual(tuple(f), 0306 ("0\n", "1\n", "2\n", "3\n", "4\n")) 0307 finally: 0308 f.close() 0309 try: 0310 unlink(TESTFN) 0311 except OSError: 0312 pass 0313 0314 # Test filter()'s use of iterators. 0315 def test_builtin_filter(self): 0316 self.assertEqual(filter(None, SequenceClass(5)), range(1, 5)) 0317 self.assertEqual(filter(None, SequenceClass(0)), []) 0318 self.assertEqual(filter(None, ()), ()) 0319 self.assertEqual(filter(None, "abc"), "abc") 0320 0321 d = {"one": 1, "two": 2, "three": 3} 0322 self.assertEqual(filter(None, d), d.keys()) 0323 0324 self.assertRaises(TypeError, filter, None, list) 0325 self.assertRaises(TypeError, filter, None, 42) 0326 0327 class Boolean: 0328 def __init__(self, truth): 0329 self.truth = truth 0330 def __nonzero__(self): 0331 return self.truth 0332 bTrue = Boolean(1) 0333 bFalse = Boolean(0) 0334 0335 class Seq: 0336 def __init__(self, *args): 0337 self.vals = args 0338 def __iter__(self): 0339 class SeqIter: 0340 def __init__(self, vals): 0341 self.vals = vals 0342 self.i = 0 0343 def __iter__(self): 0344 return self 0345 def next(self): 0346 i = self.i 0347 self.i = i + 1 0348 if i < len(self.vals): 0349 return self.vals[i] 0350 else: 0351 raise StopIteration 0352 return SeqIter(self.vals) 0353 0354 seq = Seq(*([bTrue, bFalse] * 25)) 0355 self.assertEqual(filter(lambda x: not x, seq), [bFalse]*25) 0356 self.assertEqual(filter(lambda x: not x, iter(seq)), [bFalse]*25) 0357 0358 # Test max() and min()'s use of iterators. 0359 def test_builtin_max_min(self): 0360 self.assertEqual(max(SequenceClass(5)), 4) 0361 self.assertEqual(min(SequenceClass(5)), 0) 0362 self.assertEqual(max(8, -1), 8) 0363 self.assertEqual(min(8, -1), -1) 0364 0365 d = {"one": 1, "two": 2, "three": 3} 0366 self.assertEqual(max(d), "two") 0367 self.assertEqual(min(d), "one") 0368 self.assertEqual(max(d.itervalues()), 3) 0369 self.assertEqual(min(iter(d.itervalues())), 1) 0370 0371 f = open(TESTFN, "w") 0372 try: 0373 f.write("medium line\n") 0374 f.write("xtra large line\n") 0375 f.write("itty-bitty line\n") 0376 finally: 0377 f.close() 0378 f = open(TESTFN, "r") 0379 try: 0380 self.assertEqual(min(f), "itty-bitty line\n") 0381 f.seek(0, 0) 0382 self.assertEqual(max(f), "xtra large line\n") 0383 finally: 0384 f.close() 0385 try: 0386 unlink(TESTFN) 0387 except OSError: 0388 pass 0389 0390 # Test map()'s use of iterators. 0391 def test_builtin_map(self): 0392 self.assertEqual(map(None, SequenceClass(5)), range(5)) 0393 self.assertEqual(map(lambda x: x+1, SequenceClass(5)), range(1, 6)) 0394 0395 d = {"one": 1, "two": 2, "three": 3} 0396 self.assertEqual(map(None, d), d.keys()) 0397 self.assertEqual(map(lambda k, d=d: (k, d[k]), d), d.items()) 0398 dkeys = d.keys() 0399 expected = [(i < len(d) and dkeys[i] or None, 0400 i, 0401 i < len(d) and dkeys[i] or None) 0402 for i in range(5)] 0403 self.assertEqual(map(None, d, 0404 SequenceClass(5), 0405 iter(d.iterkeys())), 0406 expected) 0407 0408 f = open(TESTFN, "w") 0409 try: 0410 for i in range(10): 0411 f.write("xy" * i + "\n") # line i has len 2*i+1 0412 finally: 0413 f.close() 0414 f = open(TESTFN, "r") 0415 try: 0416 self.assertEqual(map(len, f), range(1, 21, 2)) 0417 finally: 0418 f.close() 0419 try: 0420 unlink(TESTFN) 0421 except OSError: 0422 pass 0423 0424 # Test zip()'s use of iterators. 0425 def test_builtin_zip(self): 0426 self.assertEqual(zip(), []) 0427 self.assertEqual(zip(*[]), []) 0428 self.assertEqual(zip(*[(1, 2), 'ab']), [(1, 'a'), (2, 'b')]) 0429 0430 self.assertRaises(TypeError, zip, None) 0431 self.assertRaises(TypeError, zip, range(10), 42) 0432 self.assertRaises(TypeError, zip, range(10), zip) 0433 0434 self.assertEqual(zip(IteratingSequenceClass(3)), 0435 [(0,), (1,), (2,)]) 0436 self.assertEqual(zip(SequenceClass(3)), 0437 [(0,), (1,), (2,)]) 0438 0439 d = {"one": 1, "two": 2, "three": 3} 0440 self.assertEqual(d.items(), zip(d, d.itervalues())) 0441 0442 # Generate all ints starting at constructor arg. 0443 class IntsFrom: 0444 def __init__(self, start): 0445 self.i = start 0446 0447 def __iter__(self): 0448 return self 0449 0450 def next(self): 0451 i = self.i 0452 self.i = i+1 0453 return i 0454 0455 f = open(TESTFN, "w") 0456 try: 0457 f.write("a\n" "bbb\n" "cc\n") 0458 finally: 0459 f.close() 0460 f = open(TESTFN, "r") 0461 try: 0462 self.assertEqual(zip(IntsFrom(0), f, IntsFrom(-100)), 0463 [(0, "a\n", -100), 0464 (1, "bbb\n", -99), 0465 (2, "cc\n", -98)]) 0466 finally: 0467 f.close() 0468 try: 0469 unlink(TESTFN) 0470 except OSError: 0471 pass 0472 0473 self.assertEqual(zip(xrange(5)), [(i,) for i in range(5)]) 0474 0475 # Classes that lie about their lengths. 0476 class NoGuessLen5: 0477 def __getitem__(self, i): 0478 if i >= 5: 0479 raise IndexError 0480 return i 0481 0482 class Guess3Len5(NoGuessLen5): 0483 def __len__(self): 0484 return 3 0485 0486 class Guess30Len5(NoGuessLen5): 0487 def __len__(self): 0488 return 30 0489 0490 self.assertEqual(len(Guess3Len5()), 3) 0491 self.assertEqual(len(Guess30Len5()), 30) 0492 self.assertEqual(zip(NoGuessLen5()), zip(range(5))) 0493 self.assertEqual(zip(Guess3Len5()), zip(range(5))) 0494 self.assertEqual(zip(Guess30Len5()), zip(range(5))) 0495 0496 expected = [(i, i) for i in range(5)] 0497 for x in NoGuessLen5(), Guess3Len5(), Guess30Len5(): 0498 for y in NoGuessLen5(), Guess3Len5(), Guess30Len5(): 0499 self.assertEqual(zip(x, y), expected) 0500 0501 # Test reduces()'s use of iterators. 0502 def test_builtin_reduce(self): 0503 from operator import add 0504 self.assertEqual(reduce(add, SequenceClass(5)), 10) 0505 self.assertEqual(reduce(add, SequenceClass(5), 42), 52) 0506 self.assertRaises(TypeError, reduce, add, SequenceClass(0)) 0507 self.assertEqual(reduce(add, SequenceClass(0), 42), 42) 0508 self.assertEqual(reduce(add, SequenceClass(1)), 0) 0509 self.assertEqual(reduce(add, SequenceClass(1), 42), 42) 0510 0511 d = {"one": 1, "two": 2, "three": 3} 0512 self.assertEqual(reduce(add, d), "".join(d.keys())) 0513 0514 # This test case will be removed if we don't have Unicode 0515 def test_unicode_join_endcase(self): 0516 0517 # This class inserts a Unicode object into its argument's natural 0518 # iteration, in the 3rd position. 0519 class OhPhooey: 0520 def __init__(self, seq): 0521 self.it = iter(seq) 0522 self.i = 0 0523 0524 def __iter__(self): 0525 return self 0526 0527 def next(self): 0528 i = self.i 0529 self.i = i+1 0530 if i == 2: 0531 return unicode("fooled you!") 0532 return self.it.next() 0533 0534 f = open(TESTFN, "w") 0535 try: 0536 f.write("a\n" + "b\n" + "c\n") 0537 finally: 0538 f.close() 0539 0540 f = open(TESTFN, "r") 0541 # Nasty: string.join(s) can't know whether unicode.join() is needed 0542 # until it's seen all of s's elements. But in this case, f's 0543 # iterator cannot be restarted. So what we're testing here is 0544 # whether string.join() can manage to remember everything it's seen 0545 # and pass that on to unicode.join(). 0546 try: 0547 got = " - ".join(OhPhooey(f)) 0548 self.assertEqual(got, unicode("a\n - b\n - fooled you! - c\n")) 0549 finally: 0550 f.close() 0551 try: 0552 unlink(TESTFN) 0553 except OSError: 0554 pass 0555 if not have_unicode: 0556 def test_unicode_join_endcase(self): pass 0557 0558 # Test iterators with 'x in y' and 'x not in y'. 0559 def test_in_and_not_in(self): 0560 for sc5 in IteratingSequenceClass(5), SequenceClass(5): 0561 for i in range(5): 0562 self.assert_(i in sc5) 0563 for i in "abc", -1, 5, 42.42, (3, 4), [], {1: 1}, 3-12j, sc5: 0564 self.assert_(i not in sc5) 0565 0566 self.assertRaises(TypeError, lambda: 3 in 12) 0567 self.assertRaises(TypeError, lambda: 3 not in map) 0568 0569 d = {"one": 1, "two": 2, "three": 3, 1j: 2j} 0570 for k in d: 0571 self.assert_(k in d) 0572 self.assert_(k not in d.itervalues()) 0573 for v in d.values(): 0574 self.assert_(v in d.itervalues()) 0575 self.assert_(v not in d) 0576 for k, v in d.iteritems(): 0577 self.assert_((k, v) in d.iteritems()) 0578 self.assert_((v, k) not in d.iteritems()) 0579 0580 f = open(TESTFN, "w") 0581 try: 0582 f.write("a\n" "b\n" "c\n") 0583 finally: 0584 f.close() 0585 f = open(TESTFN, "r") 0586 try: 0587 for chunk in "abc": 0588 f.seek(0, 0) 0589 self.assert_(chunk not in f) 0590 f.seek(0, 0) 0591 self.assert_((chunk + "\n") in f) 0592 finally: 0593 f.close() 0594 try: 0595 unlink(TESTFN) 0596 except OSError: 0597 pass 0598 0599 # Test iterators with operator.countOf (PySequence_Count). 0600 def test_countOf(self): 0601 from operator import countOf 0602 self.assertEqual(countOf([1,2,2,3,2,5], 2), 3) 0603 self.assertEqual(countOf((1,2,2,3,2,5), 2), 3) 0604 self.assertEqual(countOf("122325", "2"), 3) 0605 self.assertEqual(countOf("122325", "6"), 0) 0606 0607 self.assertRaises(TypeError, countOf, 42, 1) 0608 self.assertRaises(TypeError, countOf, countOf, countOf) 0609 0610 d = {"one": 3, "two": 3, "three": 3, 1j: 2j} 0611 for k in d: 0612 self.assertEqual(countOf(d, k), 1) 0613 self.assertEqual(countOf(d.itervalues(), 3), 3) 0614 self.assertEqual(countOf(d.itervalues(), 2j), 1) 0615 self.assertEqual(countOf(d.itervalues(), 1j), 0) 0616 0617 f = open(TESTFN, "w") 0618 try: 0619 f.write("a\n" "b\n" "c\n" "b\n") 0620 finally: 0621 f.close() 0622 f = open(TESTFN, "r") 0623 try: 0624 for letter, count in ("a", 1), ("b", 2), ("c", 1), ("d", 0): 0625 f.seek(0, 0) 0626 self.assertEqual(countOf(f, letter + "\n"), count) 0627 finally: 0628 f.close() 0629 try: 0630 unlink(TESTFN) 0631 except OSError: 0632 pass 0633 0634 # Test iterators with operator.indexOf (PySequence_Index). 0635 def test_indexOf(self): 0636 from operator import indexOf 0637 self.assertEqual(indexOf([1,2,2,3,2,5], 1), 0) 0638 self.assertEqual(indexOf((1,2,2,3,2,5), 2), 1) 0639 self.assertEqual(indexOf((1,2,2,3,2,5), 3), 3) 0640 self.assertEqual(indexOf((1,2,2,3,2,5), 5), 5) 0641 self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 0) 0642 self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 6) 0643 0644 self.assertEqual(indexOf("122325", "2"), 1) 0645 self.assertEqual(indexOf("122325", "5"), 5) 0646 self.assertRaises(ValueError, indexOf, "122325", "6") 0647 0648 self.assertRaises(TypeError, indexOf, 42, 1) 0649 self.assertRaises(TypeError, indexOf, indexOf, indexOf) 0650 0651 f = open(TESTFN, "w") 0652 try: 0653 f.write("a\n" "b\n" "c\n" "d\n" "e\n") 0654 finally: 0655 f.close() 0656 f = open(TESTFN, "r") 0657 try: 0658 fiter = iter(f) 0659 self.assertEqual(indexOf(fiter, "b\n"), 1) 0660 self.assertEqual(indexOf(fiter, "d\n"), 1) 0661 self.assertEqual(indexOf(fiter, "e\n"), 0) 0662 self.assertRaises(ValueError, indexOf, fiter, "a\n") 0663 finally: 0664 f.close() 0665 try: 0666 unlink(TESTFN) 0667 except OSError: 0668 pass 0669 0670 iclass = IteratingSequenceClass(3) 0671 for i in range(3): 0672 self.assertEqual(indexOf(iclass, i), i) 0673 self.assertRaises(ValueError, indexOf, iclass, -1) 0674 0675 # Test iterators with file.writelines(). 0676 def test_writelines(self): 0677 f = file(TESTFN, "w") 0678 0679 try: 0680 self.assertRaises(TypeError, f.writelines, None) 0681 self.assertRaises(TypeError, f.writelines, 42) 0682 0683 f.writelines(["1\n", "2\n"]) 0684 f.writelines(("3\n", "4\n")) 0685 f.writelines({'5\n': None}) 0686 f.writelines({}) 0687 0688 # Try a big chunk too. 0689 class Iterator: 0690 def __init__(self, start, finish): 0691 self.start = start 0692 self.finish = finish 0693 self.i = self.start 0694 0695 def next(self): 0696 if self.i >= self.finish: 0697 raise StopIteration 0698 result = str(self.i) + '\n' 0699 self.i += 1 0700 return result 0701 0702 def __iter__(self): 0703 return self 0704 0705 class Whatever: 0706 def __init__(self, start, finish): 0707 self.start = start 0708 self.finish = finish 0709 0710 def __iter__(self): 0711 return Iterator(self.start, self.finish) 0712 0713 f.writelines(Whatever(6, 6+2000)) 0714 f.close() 0715 0716 f = file(TESTFN) 0717 expected = [str(i) + "\n" for i in range(1, 2006)] 0718 self.assertEqual(list(f), expected) 0719 0720 finally: 0721 f.close() 0722 try: 0723 unlink(TESTFN) 0724 except OSError: 0725 pass 0726 0727 0728 # Test iterators on RHS of unpacking assignments. 0729 def test_unpack_iter(self): 0730 a, b = 1, 2 0731 self.assertEqual((a, b), (1, 2)) 0732 0733 a, b, c = IteratingSequenceClass(3) 0734 self.assertEqual((a, b, c), (0, 1, 2)) 0735 0736 try: # too many values 0737 a, b = IteratingSequenceClass(3) 0738 except ValueError: 0739 pass 0740 else: 0741 self.fail("should have raised ValueError") 0742 0743 try: # not enough values 0744 a, b, c = IteratingSequenceClass(2) 0745 except ValueError: 0746 pass 0747 else: 0748 self.fail("should have raised ValueError") 0749 0750 try: # not iterable 0751 a, b, c = len 0752 except TypeError: 0753 pass 0754 else: 0755 self.fail("should have raised TypeError") 0756 0757 a, b, c = {1: 42, 2: 42, 3: 42}.itervalues() 0758 self.assertEqual((a, b, c), (42, 42, 42)) 0759 0760 f = open(TESTFN, "w") 0761 lines = ("a\n", "bb\n", "ccc\n") 0762 try: 0763 for line in lines: 0764 f.write(line) 0765 finally: 0766 f.close() 0767 f = open(TESTFN, "r") 0768 try: 0769 a, b, c = f 0770 self.assertEqual((a, b, c), lines) 0771 finally: 0772 f.close() 0773 try: 0774 unlink(TESTFN) 0775 except OSError: 0776 pass 0777 0778 (a, b), (c,) = IteratingSequenceClass(2), {42: 24} 0779 self.assertEqual((a, b, c), (0, 1, 42)) 0780 0781 # Test reference count behavior 0782 0783 class C(object): 0784 count = 0 0785 def __new__(cls): 0786 cls.count += 1 0787 return object.__new__(cls) 0788 def __del__(self): 0789 cls = self.__class__ 0790 assert cls.count > 0 0791 cls.count -= 1 0792 x = C() 0793 self.assertEqual(C.count, 1) 0794 del x 0795 self.assertEqual(C.count, 0) 0796 l = [C(), C(), C()] 0797 self.assertEqual(C.count, 3) 0798 try: 0799 a, b = iter(l) 0800 except ValueError: 0801 pass 0802 del l 0803 self.assertEqual(C.count, 0) 0804 0805 0806 # Make sure StopIteration is a "sink state". 0807 # This tests various things that weren't sink states in Python 2.2.1, 0808 # plus various things that always were fine. 0809 0810 def test_sinkstate_list(self): 0811 # This used to fail 0812 a = range(5) 0813 b = iter(a) 0814 self.assertEqual(list(b), range(5)) 0815 a.extend(range(5, 10)) 0816 self.assertEqual(list(b), []) 0817 0818 def test_sinkstate_tuple(self): 0819 a = (0, 1, 2, 3, 4) 0820 b = iter(a) 0821 self.assertEqual(list(b), range(5)) 0822 self.assertEqual(list(b), []) 0823 0824 def test_sinkstate_string(self): 0825 a = "abcde" 0826 b = iter(a) 0827 self.assertEqual(list(b), ['a', 'b', 'c', 'd', 'e']) 0828 self.assertEqual(list(b), []) 0829 0830 def test_sinkstate_sequence(self): 0831 # This used to fail 0832 a = SequenceClass(5) 0833 b = iter(a) 0834 self.assertEqual(list(b), range(5)) 0835 a.n = 10 0836 self.assertEqual(list(b), []) 0837 0838 def test_sinkstate_callable(self): 0839 # This used to fail 0840 def spam(state=[0]): 0841 i = state[0] 0842 state[0] = i+1 0843 if i == 10: 0844 raise AssertionError, "shouldn't have gotten this far" 0845 return i 0846 b = iter(spam, 5) 0847 self.assertEqual(list(b), range(5)) 0848 self.assertEqual(list(b), []) 0849 0850 def test_sinkstate_dict(self): 0851 # XXX For a more thorough test, see towards the end of: 0852 # http://mail.python.org/pipermail/python-dev/2002-July/026512.html 0853 a = {1:1, 2:2, 0:0, 4:4, 3:3} 0854 for b in iter(a), a.iterkeys(), a.iteritems(), a.itervalues(): 0855 b = iter(a) 0856 self.assertEqual(len(list(b)), 5) 0857 self.assertEqual(list(b), []) 0858 0859 def test_sinkstate_yield(self): 0860 def gen(): 0861 for i in range(5): 0862 yield i 0863 b = gen() 0864 self.assertEqual(list(b), range(5)) 0865 self.assertEqual(list(b), []) 0866 0867 def test_sinkstate_range(self): 0868 a = xrange(5) 0869 b = iter(a) 0870 self.assertEqual(list(b), range(5)) 0871 self.assertEqual(list(b), []) 0872 0873 def test_sinkstate_enumerate(self): 0874 a = range(5) 0875 e = enumerate(a) 0876 b = iter(e) 0877 self.assertEqual(list(b), zip(range(5), range(5))) 0878 self.assertEqual(list(b), []) 0879 0880 0881 def test_main(): 0882 run_unittest(TestCase) 0883 0884 0885 if __name__ == "__main__": 0886 test_main() 0887
Generated by PyXR 0.9.4