|
2 | 2 | import operator |
3 | 3 | import sys |
4 | 4 | import pickle |
| 5 | +import gc |
5 | 6 |
|
6 | 7 | from test import support |
7 | 8 |
|
@@ -127,13 +128,37 @@ def test_argumentcheck(self): |
127 | 128 | self.assertRaises(TypeError, self.enum, 'abc', 'a') # wrong type |
128 | 129 | self.assertRaises(TypeError, self.enum, 'abc', 2, 3) # too many arguments |
129 | 130 |
|
| 131 | + def test_kwargs(self): |
| 132 | + self.assertEqual(list(self.enum(iterable=Ig(self.seq))), self.res) |
| 133 | + expected = list(self.enum(Ig(self.seq), 0)) |
| 134 | + self.assertEqual(list(self.enum(iterable=Ig(self.seq), start=0)), |
| 135 | + expected) |
| 136 | + self.assertEqual(list(self.enum(start=0, iterable=Ig(self.seq))), |
| 137 | + expected) |
| 138 | + self.assertRaises(TypeError, self.enum, iterable=[], x=3) |
| 139 | + self.assertRaises(TypeError, self.enum, start=0, x=3) |
| 140 | + self.assertRaises(TypeError, self.enum, x=0, y=3) |
| 141 | + self.assertRaises(TypeError, self.enum, x=0) |
| 142 | + |
130 | 143 | @support.cpython_only |
131 | 144 | def test_tuple_reuse(self): |
132 | 145 | # Tests an implementation detail where tuple is reused |
133 | 146 | # whenever nothing else holds a reference to it |
134 | 147 | self.assertEqual(len(set(map(id, list(enumerate(self.seq))))), len(self.seq)) |
135 | 148 | self.assertEqual(len(set(map(id, enumerate(self.seq)))), min(1,len(self.seq))) |
136 | 149 |
|
| 150 | + @support.cpython_only |
| 151 | + def test_enumerate_result_gc(self): |
| 152 | + # bpo-42536: enumerate's tuple-reuse speed trick breaks the GC's |
| 153 | + # assumptions about what can be untracked. Make sure we re-track result |
| 154 | + # tuples whenever we reuse them. |
| 155 | + it = self.enum([[]]) |
| 156 | + gc.collect() |
| 157 | + # That GC collection probably untracked the recycled internal result |
| 158 | + # tuple, which is initialized to (None, None). Make sure it's re-tracked |
| 159 | + # when it's mutated and returned from __next__: |
| 160 | + self.assertTrue(gc.is_tracked(next(it))) |
| 161 | + |
137 | 162 | class MyEnum(enumerate): |
138 | 163 | pass |
139 | 164 |
|
@@ -253,14 +278,16 @@ def test_basicfunction(self): |
253 | 278 |
|
254 | 279 |
|
255 | 280 | class TestStart(EnumerateStartTestCase): |
| 281 | + def enum(self, iterable, start=11): |
| 282 | + return enumerate(iterable, start=start) |
256 | 283 |
|
257 | | - enum = lambda self, i: enumerate(i, start=11) |
258 | 284 | seq, res = 'abc', [(11, 'a'), (12, 'b'), (13, 'c')] |
259 | 285 |
|
260 | 286 |
|
261 | 287 | class TestLongStart(EnumerateStartTestCase): |
| 288 | + def enum(self, iterable, start=sys.maxsize + 1): |
| 289 | + return enumerate(iterable, start=start) |
262 | 290 |
|
263 | | - enum = lambda self, i: enumerate(i, start=sys.maxsize+1) |
264 | 291 | seq, res = 'abc', [(sys.maxsize+1,'a'), (sys.maxsize+2,'b'), |
265 | 292 | (sys.maxsize+3,'c')] |
266 | 293 |
|
|
0 commit comments