mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Update test_enumerate.py from 3.13.5 (#6032)
This commit is contained in:
1 parent
96f47a415e
commit
b7336366cb
2 files changed
+36
-8
No files matched your search
Vendored
+29
-2
@@ -2,6 +2,7 @@ import unittest
|
||||
import operator
|
||||
import sys
|
||||
import pickle
|
||||
import gc
|
||||
|
||||
from test import support
|
||||
|
||||
@@ -127,6 +128,18 @@ class EnumerateTestCase(unittest.TestCase, PickleTest):
|
||||
self.assertRaises(TypeError, self.enum, 'abc', 'a') # wrong type
|
||||
self.assertRaises(TypeError, self.enum, 'abc', 2, 3) # too many arguments
|
||||
|
||||
def test_kwargs(self):
|
||||
self.assertEqual(list(self.enum(iterable=Ig(self.seq))), self.res)
|
||||
expected = list(self.enum(Ig(self.seq), 0))
|
||||
self.assertEqual(list(self.enum(iterable=Ig(self.seq), start=0)),
|
||||
expected)
|
||||
self.assertEqual(list(self.enum(start=0, iterable=Ig(self.seq))),
|
||||
expected)
|
||||
self.assertRaises(TypeError, self.enum, iterable=[], x=3)
|
||||
self.assertRaises(TypeError, self.enum, start=0, x=3)
|
||||
self.assertRaises(TypeError, self.enum, x=0, y=3)
|
||||
self.assertRaises(TypeError, self.enum, x=0)
|
||||
|
||||
@support.cpython_only
|
||||
def test_tuple_reuse(self):
|
||||
# Tests an implementation detail where tuple is reused
|
||||
@@ -134,6 +147,18 @@ class EnumerateTestCase(unittest.TestCase, PickleTest):
|
||||
self.assertEqual(len(set(map(id, list(enumerate(self.seq))))), len(self.seq))
|
||||
self.assertEqual(len(set(map(id, enumerate(self.seq)))), min(1,len(self.seq)))
|
||||
|
||||
@support.cpython_only
|
||||
def test_enumerate_result_gc(self):
|
||||
# bpo-42536: enumerate's tuple-reuse speed trick breaks the GC's
|
||||
# assumptions about what can be untracked. Make sure we re-track result
|
||||
# tuples whenever we reuse them.
|
||||
it = self.enum([[]])
|
||||
gc.collect()
|
||||
# That GC collection probably untracked the recycled internal result
|
||||
# tuple, which is initialized to (None, None). Make sure it's re-tracked
|
||||
# when it's mutated and returned from __next__:
|
||||
self.assertTrue(gc.is_tracked(next(it)))
|
||||
|
||||
class MyEnum(enumerate):
|
||||
pass
|
||||
|
||||
@@ -253,14 +278,16 @@ class EnumerateStartTestCase(EnumerateTestCase):
|
||||
|
||||
|
||||
class TestStart(EnumerateStartTestCase):
|
||||
def enum(self, iterable, start=11):
|
||||
return enumerate(iterable, start=start)
|
||||
|
||||
enum = lambda self, i: enumerate(i, start=11)
|
||||
seq, res = 'abc', [(11, 'a'), (12, 'b'), (13, 'c')]
|
||||
|
||||
|
||||
class TestLongStart(EnumerateStartTestCase):
|
||||
def enum(self, iterable, start=sys.maxsize + 1):
|
||||
return enumerate(iterable, start=start)
|
||||
|
||||
enum = lambda self, i: enumerate(i, start=sys.maxsize+1)
|
||||
seq, res = 'abc', [(sys.maxsize+1,'a'), (sys.maxsize+2,'b'),
|
||||
(sys.maxsize+3,'c')]
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ use num_traits::Zero;
|
||||
pub struct PyEnumerate {
|
||||
#[pytraverse(skip)]
|
||||
counter: PyRwLock<BigInt>,
|
||||
iterator: PyIter,
|
||||
iterable: PyIter,
|
||||
}
|
||||
|
||||
impl PyPayload for PyEnumerate {
|
||||
@@ -31,7 +31,8 @@ impl PyPayload for PyEnumerate {
|
||||
|
||||
#[derive(FromArgs)]
|
||||
pub struct EnumerateArgs {
|
||||
iterator: PyIter,
|
||||
#[pyarg(any)]
|
||||
iterable: PyIter,
|
||||
#[pyarg(any, optional)]
|
||||
start: OptionalArg<PyIntRef>,
|
||||
}
|
||||
@@ -41,13 +42,13 @@ impl Constructor for PyEnumerate {
|
||||
|
||||
fn py_new(
|
||||
cls: PyTypeRef,
|
||||
Self::Args { iterator, start }: Self::Args,
|
||||
Self::Args { iterable, start }: Self::Args,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
let counter = start.map_or_else(BigInt::zero, |start| start.as_bigint().clone());
|
||||
Self {
|
||||
counter: PyRwLock::new(counter),
|
||||
iterator,
|
||||
iterable,
|
||||
}
|
||||
.into_ref_with_type(vm, cls)
|
||||
.map(Into::into)
|
||||
@@ -68,7 +69,7 @@ impl Py<PyEnumerate> {
|
||||
fn __reduce__(&self) -> (PyTypeRef, (PyIter, BigInt)) {
|
||||
(
|
||||
self.class().to_owned(),
|
||||
(self.iterator.clone(), self.counter.read().clone()),
|
||||
(self.iterable.clone(), self.counter.read().clone()),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -77,7 +78,7 @@ impl SelfIter for PyEnumerate {}
|
||||
|
||||
impl IterNext for PyEnumerate {
|
||||
fn next(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyIterReturn> {
|
||||
let next_obj = raise_if_stop!(zelf.iterator.next(vm)?);
|
||||
let next_obj = raise_if_stop!(zelf.iterable.next(vm)?);
|
||||
let mut counter = zelf.counter.write();
|
||||
let position = counter.clone();
|
||||
*counter += 1;
|
||||
|
||||
Reference in new issue
Block a user