Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(98)

Side by Side Diff: Lib/test/test_enumerate.py

Issue 602: range: lean and mean (Closed) SVN Base: http://svn.python.org/view/*checkout*/python/branches/py3k/
Patch Set: __len__ is back! Created 3 months, 3 weeks ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 import unittest 1 import unittest
2 import sys 2 import sys
3 3
4 from test import test_support 4 from test import test_support
5 5
6 class G: 6 class G:
7 'Sequence using __getitem__' 7 'Sequence using __getitem__'
8 def __init__(self, seqn): 8 def __init__(self, seqn):
9 self.seqn = seqn 9 self.seqn = seqn
10 def __getitem__(self, i): 10 def __getitem__(self, i):
11 return self.seqn[i] 11 return self.seqn[i]
12 12
13 class I: 13 class I:
14 'Sequence using iterator protocol' 14 'Sequence using iterator protocol'
15 def __init__(self, seqn): 15 def __init__(self, seqn):
16 self.seqn = seqn 16 self.seqn = seqn
17 self.i = 0 17 self.i = 0
18 def __iter__(self): 18 def __iter__(self):
19 return self 19 return self
20 def __next__(self): 20 def __next__(self):
21 if self.i >= len(self.seqn): raise StopIteration 21 if self.i >= len(self.seqn): raise StopIteration
22 v = self.seqn[self.i] 22 v = self.seqn[self.i]
23 self.i += 1 23 self.i += 1
24 return v 24 return v
25 25
26 class Ig: 26 class Ig:
27 'Sequence using iterator protocol defined with a generator' 27 'Sequence using iterator protocol defined with a generator'
28 def __init__(self, seqn): 28 def __init__(self, seqn):
29 self.seqn = seqn 29 self.seqn = seqn
30 self.i = 0 30 self.i = 0
31 def __iter__(self): 31 def __iter__(self):
32 for val in self.seqn: 32 for val in self.seqn:
33 yield val 33 yield val
34 34
35 class X: 35 class X:
36 'Missing __getitem__ and __iter__' 36 'Missing __getitem__ and __iter__'
37 def __init__(self, seqn): 37 def __init__(self, seqn):
38 self.seqn = seqn 38 self.seqn = seqn
39 self.i = 0 39 self.i = 0
40 def __next__(self): 40 def __next__(self):
41 if self.i >= len(self.seqn): raise StopIteration 41 if self.i >= len(self.seqn): raise StopIteration
42 v = self.seqn[self.i] 42 v = self.seqn[self.i]
43 self.i += 1 43 self.i += 1
44 return v 44 return v
45 45
46 class E: 46 class E:
47 'Test propagation of exceptions' 47 'Test propagation of exceptions'
48 def __init__(self, seqn): 48 def __init__(self, seqn):
49 self.seqn = seqn 49 self.seqn = seqn
50 self.i = 0 50 self.i = 0
51 def __iter__(self): 51 def __iter__(self):
52 return self 52 return self
53 def __next__(self): 53 def __next__(self):
54 3 // 0 54 3 // 0
55 55
56 class N: 56 class N:
57 'Iterator missing __next__()' 57 'Iterator missing __next__()'
58 def __init__(self, seqn): 58 def __init__(self, seqn):
59 self.seqn = seqn 59 self.seqn = seqn
60 self.i = 0 60 self.i = 0
61 def __iter__(self): 61 def __iter__(self):
62 return self 62 return self
63 63
64 class EnumerateTestCase(unittest.TestCase): 64 class EnumerateTestCase(unittest.TestCase):
65 65
66 enum = enumerate 66 enum = enumerate
67 seq, res = 'abc', [(0,'a'), (1,'b'), (2,'c')] 67 seq, res = 'abc', [(0,'a'), (1,'b'), (2,'c')]
68 68
69 def test_basicfunction(self): 69 def test_basicfunction(self):
70 self.assertEqual(type(self.enum(self.seq)), self.enum) 70 self.assertEqual(type(self.enum(self.seq)), self.enum)
71 e = self.enum(self.seq) 71 e = self.enum(self.seq)
72 self.assertEqual(iter(e), e) 72 self.assertEqual(iter(e), e)
73 self.assertEqual(list(self.enum(self.seq)), self.res) 73 self.assertEqual(list(self.enum(self.seq)), self.res)
74 self.enum.__doc__ 74 self.enum.__doc__
75 75
76 def test_getitemseqn(self): 76 def test_getitemseqn(self):
77 self.assertEqual(list(self.enum(G(self.seq))), self.res) 77 self.assertEqual(list(self.enum(G(self.seq))), self.res)
78 e = self.enum(G('')) 78 e = self.enum(G(''))
79 self.assertRaises(StopIteration, next, e) 79 self.assertRaises(StopIteration, next, e)
80 80
81 def test_iteratorseqn(self): 81 def test_iteratorseqn(self):
82 self.assertEqual(list(self.enum(I(self.seq))), self.res) 82 self.assertEqual(list(self.enum(I(self.seq))), self.res)
83 e = self.enum(I('')) 83 e = self.enum(I(''))
84 self.assertRaises(StopIteration, next, e) 84 self.assertRaises(StopIteration, next, e)
85 85
86 def test_iteratorgenerator(self): 86 def test_iteratorgenerator(self):
87 self.assertEqual(list(self.enum(Ig(self.seq))), self.res) 87 self.assertEqual(list(self.enum(Ig(self.seq))), self.res)
88 e = self.enum(Ig('')) 88 e = self.enum(Ig(''))
89 self.assertRaises(StopIteration, next, e) 89 self.assertRaises(StopIteration, next, e)
90 90
91 def test_noniterable(self): 91 def test_noniterable(self):
92 self.assertRaises(TypeError, self.enum, X(self.seq)) 92 self.assertRaises(TypeError, self.enum, X(self.seq))
93 93
94 def test_illformediterable(self): 94 def test_illformediterable(self):
95 self.assertRaises(TypeError, self.enum, N(self.seq)) 95 self.assertRaises(TypeError, self.enum, N(self.seq))
96 96
97 def test_exception_propagation(self): 97 def test_exception_propagation(self):
98 self.assertRaises(ZeroDivisionError, list, self.enum(E(self.seq))) 98 self.assertRaises(ZeroDivisionError, list, self.enum(E(self.seq)))
99 99
100 def test_argumentcheck(self): 100 def test_argumentcheck(self):
101 self.assertRaises(TypeError, self.enum) # no arguments 101 self.assertRaises(TypeError, self.enum) # no arguments
102 self.assertRaises(TypeError, self.enum, 1) # wrong type (not iterable) 102 self.assertRaises(TypeError, self.enum, 1) # wrong type (not iterable)
103 self.assertRaises(TypeError, self.enum, 'abc', 2) # too many arguments 103 self.assertRaises(TypeError, self.enum, 'abc', 2) # too many arguments
104 104
105 def test_tuple_reuse(self): 105 def test_tuple_reuse(self):
106 # Tests an implementation detail where tuple is reused 106 # Tests an implementation detail where tuple is reused
107 # whenever nothing else holds a reference to it 107 # whenever nothing else holds a reference to it
108 self.assertEqual(len(set(map(id, list(enumerate(self.seq))))), len(self. seq)) 108 self.assertEqual(len(set(map(id, list(enumerate(self.seq))))), len(self. seq))
109 self.assertEqual(len(set(map(id, enumerate(self.seq)))), min(1,len(self. seq))) 109 self.assertEqual(len(set(map(id, enumerate(self.seq)))), min(1,len(self. seq)))
110 110
111 class MyEnum(enumerate): 111 class MyEnum(enumerate):
112 pass 112 pass
113 113
114 class SubclassTestCase(EnumerateTestCase): 114 class SubclassTestCase(EnumerateTestCase):
115 115
116 enum = MyEnum 116 enum = MyEnum
117 117
118 class TestEmpty(EnumerateTestCase): 118 class TestEmpty(EnumerateTestCase):
119 119
120 seq, res = '', [] 120 seq, res = '', []
121 121
122 class TestBig(EnumerateTestCase): 122 class TestBig(EnumerateTestCase):
123 123
124 seq = range(10,20000,2) 124 seq = list(range(10,20000,2))
125 res = list(zip(range(20000), seq)) 125 res = list(zip(range(20000), seq))
126 126
127 class TestReversed(unittest.TestCase): 127 class TestReversed(unittest.TestCase):
128 128
129 def test_simple(self): 129 def test_simple(self):
130 class A: 130 class A:
131 def __getitem__(self, i): 131 def __getitem__(self, i):
132 if i < 5: 132 if i < 5:
133 return str(i) 133 return str(i)
134 raise StopIteration 134 raise StopIteration
135 def __len__(self): 135 def __len__(self):
136 return 5 136 return 5
137 for data in 'abc', range(5), tuple(enumerate('abc')), A(), range(1,17,5) : 137 for data in 'abc', range(5), tuple(enumerate('abc')), A(), range(1,17,5) :
138 self.assertEqual(list(data)[::-1], list(reversed(data))) 138 self.assertEqual(list(data)[::-1], list(reversed(data)))
139 self.assertRaises(TypeError, reversed, {}) 139 self.assertRaises(TypeError, reversed, {})
140 140
141 def test_range_optimization(self): 141 def test_range_optimization(self):
142 x = range(1) 142 x = range(1)
143 self.assertEqual(type(reversed(x)), type(iter(x))) 143 self.assertEqual(type(reversed(x)), type(iter(x)))
144 144
145 def test_len(self): 145 def test_len(self):
146 # This is an implementation detail, not an interface requirement 146 # This is an implementation detail, not an interface requirement
147 from test.test_iterlen import len 147 from test.test_iterlen import len
148 for s in ('hello', tuple('hello'), list('hello'), range(5)): 148 for s in ('hello', tuple('hello'), list('hello'), range(5)):
149 self.assertEqual(len(reversed(s)), len(s)) 149 self.assertEqual(len(reversed(s)), len(s))
150 r = reversed(s) 150 r = reversed(s)
151 list(r) 151 list(r)
152 self.assertEqual(len(r), 0) 152 self.assertEqual(len(r), 0)
153 class SeqWithWeirdLen: 153 class SeqWithWeirdLen:
154 called = False 154 called = False
155 def __len__(self): 155 def __len__(self):
156 if not self.called: 156 if not self.called:
157 self.called = True 157 self.called = True
158 return 10 158 return 10
159 raise ZeroDivisionError 159 raise ZeroDivisionError
160 def __getitem__(self, index): 160 def __getitem__(self, index):
161 return index 161 return index
162 r = reversed(SeqWithWeirdLen()) 162 r = reversed(SeqWithWeirdLen())
163 self.assertRaises(ZeroDivisionError, len, r) 163 self.assertRaises(ZeroDivisionError, len, r)
164 164
165 165
166 def test_gc(self): 166 def test_gc(self):
167 class Seq: 167 class Seq:
168 def __len__(self): 168 def __len__(self):
169 return 10 169 return 10
170 def __getitem__(self, index): 170 def __getitem__(self, index):
171 return index 171 return index
172 s = Seq() 172 s = Seq()
173 r = reversed(s) 173 r = reversed(s)
174 s.r = r 174 s.r = r
175 175
176 def test_args(self): 176 def test_args(self):
177 self.assertRaises(TypeError, reversed) 177 self.assertRaises(TypeError, reversed)
178 self.assertRaises(TypeError, reversed, [], 'extra') 178 self.assertRaises(TypeError, reversed, [], 'extra')
179 179
180 def test_bug1229429(self): 180 def test_bug1229429(self):
181 # this bug was never in reversed, it was in 181 # this bug was never in reversed, it was in
182 # PyObject_CallMethod, and reversed_new calls that sometimes. 182 # PyObject_CallMethod, and reversed_new calls that sometimes.
183 if not hasattr(sys, "getrefcount"): 183 if not hasattr(sys, "getrefcount"):
184 return 184 return
185 def f(): 185 def f():
186 pass 186 pass
187 r = f.__reversed__ = object() 187 r = f.__reversed__ = object()
188 rc = sys.getrefcount(r) 188 rc = sys.getrefcount(r)
189 for i in range(10): 189 for i in range(10):
190 try: 190 try:
191 reversed(f) 191 reversed(f)
192 except TypeError: 192 except TypeError:
193 pass 193 pass
194 else: 194 else:
195 self.fail("non-callable __reversed__ didn't raise!") 195 self.fail("non-callable __reversed__ didn't raise!")
196 self.assertEqual(rc, sys.getrefcount(r)) 196 self.assertEqual(rc, sys.getrefcount(r))
197 197
198 198
199 def test_main(verbose=None): 199 def test_main(verbose=None):
200 testclasses = (EnumerateTestCase, SubclassTestCase, TestEmpty, TestBig, 200 testclasses = (EnumerateTestCase, SubclassTestCase, TestEmpty, TestBig,
201 TestReversed) 201 TestReversed)
202 test_support.run_unittest(*testclasses) 202 test_support.run_unittest(*testclasses)
203 203
204 # verify reference counting 204 # verify reference counting
205 import sys 205 import sys
206 if verbose and hasattr(sys, "gettotalrefcount"): 206 if verbose and hasattr(sys, "gettotalrefcount"):
207 counts = [None] * 5 207 counts = [None] * 5
208 for i in range(len(counts)): 208 for i in range(len(counts)):
209 test_support.run_unittest(*testclasses) 209 test_support.run_unittest(*testclasses)
210 counts[i] = sys.gettotalrefcount() 210 counts[i] = sys.gettotalrefcount()
211 print(counts) 211 print(counts)
212 212
213 if __name__ == "__main__": 213 if __name__ == "__main__":
214 test_main(verbose=True) 214 test_main(verbose=True)
OLDNEW

Powered by Google App Engine
This is Rietveld r292