PyXR

c:\python24\lib \ test \ test_iter.py



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
SourceForge.net Logo