Skip to content

Commit 18fdf85

Browse files
authored
Fix itertools.pairwise (#5884)
* Fix pairwise hangs * Don't skip failing tests;) * Drop lock of read, not write
1 parent fa7af0e commit 18fdf85

File tree

2 files changed

+14
-7
lines changed

2 files changed

+14
-7
lines changed

Lib/test/test_itertools.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,8 +1182,6 @@ def test_pairwise(self):
11821182
with self.assertRaises(TypeError):
11831183
pairwise(None) # non-iterable argument
11841184

1185-
# TODO: RUSTPYTHON
1186-
@unittest.skip("TODO: RUSTPYTHON, hangs")
11871185
def test_pairwise_reenter(self):
11881186
def check(reenter_at, expected):
11891187
class I:
@@ -1234,8 +1232,6 @@ def __next__(self):
12341232
([5], [6]),
12351233
])
12361234

1237-
# TODO: RUSTPYTHON
1238-
@unittest.skip("TODO: RUSTPYTHON, hangs")
12391235
def test_pairwise_reenter2(self):
12401236
def check(maxcount, expected):
12411237
class I:

vm/src/stdlib/itertools.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,7 +1943,7 @@ mod decl {
19431943
type Args = PyIter;
19441944

19451945
fn py_new(cls: PyTypeRef, iterator: Self::Args, vm: &VirtualMachine) -> PyResult {
1946-
PyItertoolsPairwise {
1946+
Self {
19471947
iterator,
19481948
old: PyRwLock::new(None),
19491949
}
@@ -1959,18 +1959,29 @@ mod decl {
19591959

19601960
impl IterNext for PyItertoolsPairwise {
19611961
fn next(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyIterReturn> {
1962-
let old = match zelf.old.read().clone() {
1962+
let old_clone = {
1963+
let guard = zelf.old.read();
1964+
guard.clone()
1965+
};
1966+
let old = match old_clone {
19631967
None => match zelf.iterator.next(vm)? {
1964-
PyIterReturn::Return(obj) => obj,
1968+
PyIterReturn::Return(obj) => {
1969+
// Needed for when we reenter
1970+
*zelf.old.write() = Some(obj.clone());
1971+
obj
1972+
}
19651973
PyIterReturn::StopIteration(v) => return Ok(PyIterReturn::StopIteration(v)),
19661974
},
19671975
Some(obj) => obj,
19681976
};
1977+
19691978
let new = match zelf.iterator.next(vm)? {
19701979
PyIterReturn::Return(obj) => obj,
19711980
PyIterReturn::StopIteration(v) => return Ok(PyIterReturn::StopIteration(v)),
19721981
};
1982+
19731983
*zelf.old.write() = Some(new.clone());
1984+
19741985
Ok(PyIterReturn::Return(vm.new_tuple((old, new)).into()))
19751986
}
19761987
}

0 commit comments

Comments
 (0)