Skip to content

Commit 5aa075c

Browse files
committed
Update test_enumerate.py from 3.13.5
1 parent 96f47a4 commit 5aa075c

File tree

2 files changed

+36
-8
lines changed

2 files changed

+36
-8
lines changed

Lib/test/test_enumerate.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import operator
33
import sys
44
import pickle
5+
import gc
56

67
from test import support
78

@@ -127,13 +128,37 @@ def test_argumentcheck(self):
127128
self.assertRaises(TypeError, self.enum, 'abc', 'a') # wrong type
128129
self.assertRaises(TypeError, self.enum, 'abc', 2, 3) # too many arguments
129130

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+
130143
@support.cpython_only
131144
def test_tuple_reuse(self):
132145
# Tests an implementation detail where tuple is reused
133146
# whenever nothing else holds a reference to it
134147
self.assertEqual(len(set(map(id, list(enumerate(self.seq))))), len(self.seq))
135148
self.assertEqual(len(set(map(id, enumerate(self.seq)))), min(1,len(self.seq)))
136149

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+
137162
class MyEnum(enumerate):
138163
pass
139164

@@ -253,14 +278,16 @@ def test_basicfunction(self):
253278

254279

255280
class TestStart(EnumerateStartTestCase):
281+
def enum(self, iterable, start=11):
282+
return enumerate(iterable, start=start)
256283

257-
enum = lambda self, i: enumerate(i, start=11)
258284
seq, res = 'abc', [(11, 'a'), (12, 'b'), (13, 'c')]
259285

260286

261287
class TestLongStart(EnumerateStartTestCase):
288+
def enum(self, iterable, start=sys.maxsize + 1):
289+
return enumerate(iterable, start=start)
262290

263-
enum = lambda self, i: enumerate(i, start=sys.maxsize+1)
264291
seq, res = 'abc', [(sys.maxsize+1,'a'), (sys.maxsize+2,'b'),
265292
(sys.maxsize+3,'c')]
266293

vm/src/builtins/enumerate.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use num_traits::Zero;
1919
pub struct PyEnumerate {
2020
#[pytraverse(skip)]
2121
counter: PyRwLock<BigInt>,
22-
iterator: PyIter,
22+
iterable: PyIter,
2323
}
2424

2525
impl PyPayload for PyEnumerate {
@@ -31,7 +31,8 @@ impl PyPayload for PyEnumerate {
3131

3232
#[derive(FromArgs)]
3333
pub struct EnumerateArgs {
34-
iterator: PyIter,
34+
#[pyarg(any)]
35+
iterable: PyIter,
3536
#[pyarg(any, optional)]
3637
start: OptionalArg<PyIntRef>,
3738
}
@@ -41,13 +42,13 @@ impl Constructor for PyEnumerate {
4142

4243
fn py_new(
4344
cls: PyTypeRef,
44-
Self::Args { iterator, start }: Self::Args,
45+
Self::Args { iterable, start }: Self::Args,
4546
vm: &VirtualMachine,
4647
) -> PyResult {
4748
let counter = start.map_or_else(BigInt::zero, |start| start.as_bigint().clone());
4849
Self {
4950
counter: PyRwLock::new(counter),
50-
iterator,
51+
iterable,
5152
}
5253
.into_ref_with_type(vm, cls)
5354
.map(Into::into)
@@ -68,7 +69,7 @@ impl Py<PyEnumerate> {
6869
fn __reduce__(&self) -> (PyTypeRef, (PyIter, BigInt)) {
6970
(
7071
self.class().to_owned(),
71-
(self.iterator.clone(), self.counter.read().clone()),
72+
(self.iterable.clone(), self.counter.read().clone()),
7273
)
7374
}
7475
}
@@ -77,7 +78,7 @@ impl SelfIter for PyEnumerate {}
7778

7879
impl IterNext for PyEnumerate {
7980
fn next(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyIterReturn> {
80-
let next_obj = raise_if_stop!(zelf.iterator.next(vm)?);
81+
let next_obj = raise_if_stop!(zelf.iterable.next(vm)?);
8182
let mut counter = zelf.counter.write();
8283
let position = counter.clone();
8384
*counter += 1;

0 commit comments

Comments
 (0)