mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
itertools: defer dropwhile predicate validation (#8504)
Store the `dropwhile` predicate as a Python object and call it while advancing the iterator. This defers callable validation until the predicate is first needed, matching CPython for empty input while preserving exception propagation during iteration. Remove the now-passing `test_dropwhile` expected-failure marker. Assisted-by: Codex:gpt-5.6-sol
This commit is contained in:
1 parent
7e6eaa8e3c
commit
1178841eab
2 files changed
+4
-6
No files matched your search
Vendored
-1
@@ -1260,7 +1260,6 @@ class TestBasicOps(unittest.TestCase):
|
||||
self.assertEqual(list(t), [1, 1, 1])
|
||||
self.assertRaises(StopIteration, next, t)
|
||||
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_dropwhile(self):
|
||||
data = [1, 3, 5, 20, 2, 4, 6, 8]
|
||||
self.assertEqual(list(dropwhile(underten, data)), [20, 2, 4, 6, 8])
|
||||
|
||||
@@ -10,7 +10,7 @@ mod decl {
|
||||
rc::PyRc,
|
||||
},
|
||||
convert::ToPyObject,
|
||||
function::{ArgCallable, FuncArgs, OptionalArg, OptionalOption, PosArgs},
|
||||
function::{FuncArgs, OptionalArg, OptionalOption, PosArgs},
|
||||
protocol::{PyIter, PyIterReturn, PyNumber},
|
||||
raise_if_stop,
|
||||
stdlib::sys,
|
||||
@@ -477,7 +477,7 @@ mod decl {
|
||||
#[pyclass(name = "dropwhile")]
|
||||
#[derive(Debug, PyPayload)]
|
||||
struct PyItertoolsDropwhile {
|
||||
predicate: ArgCallable,
|
||||
predicate: PyObjectRef,
|
||||
iterable: PyIter,
|
||||
start_flag: AtomicCell<bool>,
|
||||
}
|
||||
@@ -485,7 +485,7 @@ mod decl {
|
||||
#[derive(FromArgs)]
|
||||
struct DropwhileNewArgs {
|
||||
#[pyarg(positional)]
|
||||
predicate: ArgCallable,
|
||||
predicate: PyObjectRef,
|
||||
#[pyarg(positional)]
|
||||
iterable: PyIter,
|
||||
}
|
||||
@@ -522,8 +522,7 @@ mod decl {
|
||||
if !zelf.start_flag.load() {
|
||||
loop {
|
||||
let obj = raise_if_stop!(iterable.next(vm)?);
|
||||
let pred = predicate.clone();
|
||||
let pred_value = pred.invoke((obj.clone(),), vm)?;
|
||||
let pred_value = predicate.call((obj.clone(),), vm)?;
|
||||
if !pred_value.try_to_bool(vm)? {
|
||||
zelf.start_flag.store(true);
|
||||
return Ok(PyIterReturn::Return(obj));
|
||||
|
||||
Reference in new issue
Block a user