0001 import unittest 0002 0003 from test import test_support 0004 0005 class G: 0006 'Sequence using __getitem__' 0007 def __init__(self, seqn): 0008 self.seqn = seqn 0009 def __getitem__(self, i): 0010 return self.seqn[i] 0011 0012 class I: 0013 'Sequence using iterator protocol' 0014 def __init__(self, seqn): 0015 self.seqn = seqn 0016 self.i = 0 0017 def __iter__(self): 0018 return self 0019 def next(self): 0020 if self.i >= len(self.seqn): raise StopIteration 0021 v = self.seqn[self.i] 0022 self.i += 1 0023 return v 0024 0025 class Ig: 0026 'Sequence using iterator protocol defined with a generator' 0027 def __init__(self, seqn): 0028 self.seqn = seqn 0029 self.i = 0 0030 def __iter__(self): 0031 for val in self.seqn: 0032 yield val 0033 0034 class X: 0035 'Missing __getitem__ and __iter__' 0036 def __init__(self, seqn): 0037 self.seqn = seqn 0038 self.i = 0 0039 def next(self): 0040 if self.i >= len(self.seqn): raise StopIteration 0041 v = self.seqn[self.i] 0042 self.i += 1 0043 return v 0044 0045 class E: 0046 'Test propagation of exceptions' 0047 def __init__(self, seqn): 0048 self.seqn = seqn 0049 self.i = 0 0050 def __iter__(self): 0051 return self 0052 def next(self): 0053 3 // 0 0054 0055 class N: 0056 'Iterator missing next()' 0057 def __init__(self, seqn): 0058 self.seqn = seqn 0059 self.i = 0 0060 def __iter__(self): 0061 return self 0062 0063 class EnumerateTestCase(unittest.TestCase): 0064 0065 enum = enumerate 0066 seq, res = 'abc', [(0,'a'), (1,'b'), (2,'c')] 0067 0068 def test_basicfunction(self): 0069 self.assertEqual(type(self.enum(self.seq)), self.enum) 0070 e = self.enum(self.seq) 0071 self.assertEqual(iter(e), e) 0072 self.assertEqual(list(self.enum(self.seq)), self.res) 0073 self.enum.__doc__ 0074 0075 def test_getitemseqn(self): 0076 self.assertEqual(list(self.enum(G(self.seq))), self.res) 0077 e = self.enum(G('')) 0078 self.assertRaises(StopIteration, e.next) 0079 0080 def test_iteratorseqn(self): 0081 self.assertEqual(list(self.enum(I(self.seq))), self.res) 0082 e = self.enum(I('')) 0083 self.assertRaises(StopIteration, e.next) 0084 0085 def test_iteratorgenerator(self): 0086 self.assertEqual(list(self.enum(Ig(self.seq))), self.res) 0087 e = self.enum(Ig('')) 0088 self.assertRaises(StopIteration, e.next) 0089 0090 def test_noniterable(self): 0091 self.assertRaises(TypeError, self.enum, X(self.seq)) 0092 0093 def test_illformediterable(self): 0094 self.assertRaises(TypeError, list, self.enum(N(self.seq))) 0095 0096 def test_exception_propagation(self): 0097 self.assertRaises(ZeroDivisionError, list, self.enum(E(self.seq))) 0098 0099 def test_argumentcheck(self): 0100 self.assertRaises(TypeError, self.enum) # no arguments 0101 self.assertRaises(TypeError, self.enum, 1) # wrong type (not iterable) 0102 self.assertRaises(TypeError, self.enum, 'abc', 2) # too many arguments 0103 0104 def test_tuple_reuse(self): 0105 # Tests an implementation detail where tuple is reused 0106 # whenever nothing else holds a reference to it 0107 self.assertEqual(len(set(map(id, list(enumerate(self.seq))))), len(self.seq)) 0108 self.assertEqual(len(set(map(id, enumerate(self.seq)))), min(1,len(self.seq))) 0109 0110 class MyEnum(enumerate): 0111 pass 0112 0113 class SubclassTestCase(EnumerateTestCase): 0114 0115 enum = MyEnum 0116 0117 class TestEmpty(EnumerateTestCase): 0118 0119 seq, res = '', [] 0120 0121 class TestBig(EnumerateTestCase): 0122 0123 seq = range(10,20000,2) 0124 res = zip(range(20000), seq) 0125 0126 class TestReversed(unittest.TestCase): 0127 0128 def test_simple(self): 0129 class A: 0130 def __getitem__(self, i): 0131 if i < 5: 0132 return str(i) 0133 raise StopIteration 0134 def __len__(self): 0135 return 5 0136 for data in 'abc', range(5), tuple(enumerate('abc')), A(), xrange(1,17,5): 0137 self.assertEqual(list(data)[::-1], list(reversed(data))) 0138 self.assertRaises(TypeError, reversed, {}) 0139 0140 def test_xrange_optimization(self): 0141 x = xrange(1) 0142 self.assertEqual(type(reversed(x)), type(iter(x))) 0143 0144 def test_len(self): 0145 # This is an implementation detail, not an interface requirement 0146 for s in ('hello', tuple('hello'), list('hello'), xrange(5)): 0147 self.assertEqual(len(reversed(s)), len(s)) 0148 r = reversed(s) 0149 list(r) 0150 self.assertEqual(len(r), 0) 0151 class SeqWithWeirdLen: 0152 called = False 0153 def __len__(self): 0154 if not self.called: 0155 self.called = True 0156 return 10 0157 raise ZeroDivisionError 0158 def __getitem__(self, index): 0159 return index 0160 r = reversed(SeqWithWeirdLen()) 0161 self.assertRaises(ZeroDivisionError, len, r) 0162 0163 0164 def test_gc(self): 0165 class Seq: 0166 def __len__(self): 0167 return 10 0168 def __getitem__(self, index): 0169 return index 0170 s = Seq() 0171 r = reversed(s) 0172 s.r = r 0173 0174 def test_args(self): 0175 self.assertRaises(TypeError, reversed) 0176 self.assertRaises(TypeError, reversed, [], 'extra') 0177 0178 def test_main(verbose=None): 0179 testclasses = (EnumerateTestCase, SubclassTestCase, TestEmpty, TestBig, 0180 TestReversed) 0181 test_support.run_unittest(*testclasses) 0182 0183 # verify reference counting 0184 import sys 0185 if verbose and hasattr(sys, "gettotalrefcount"): 0186 counts = [None] * 5 0187 for i in xrange(len(counts)): 0188 test_support.run_unittest(*testclasses) 0189 counts[i] = sys.gettotalrefcount() 0190 print counts 0191 0192 if __name__ == "__main__": 0193 test_main(verbose=True) 0194
Generated by PyXR 0.9.4