mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Merge pull request #889 from adrian17/iter-class
Convert iterators to pyclass macros
This commit is contained in:
11 files changed
+125
-132
No files matched your search
+10
-12
@@ -7,7 +7,7 @@ use std::ops::{Deref, DerefMut};
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
use crate::function::OptionalArg;
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objint;
|
||||
@@ -84,11 +84,7 @@ pub fn init(context: &PyContext) {
|
||||
"upper" => context.new_rustfunc(PyByteArrayRef::upper)
|
||||
});
|
||||
|
||||
let bytearrayiterator_type = &context.bytearrayiterator_type;
|
||||
extend_class!(context, bytearrayiterator_type, {
|
||||
"__next__" => context.new_rustfunc(PyByteArrayIteratorRef::next),
|
||||
"__iter__" => context.new_rustfunc(PyByteArrayIteratorRef::iter),
|
||||
});
|
||||
PyByteArrayIterator::extend_class(context, &context.bytearrayiterator_type);
|
||||
}
|
||||
|
||||
fn bytearray_new(
|
||||
@@ -287,6 +283,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug)]
|
||||
pub struct PyByteArrayIterator {
|
||||
position: Cell<usize>,
|
||||
@@ -299,10 +296,10 @@ impl PyValue for PyByteArrayIterator {
|
||||
}
|
||||
}
|
||||
|
||||
type PyByteArrayIteratorRef = PyRef<PyByteArrayIterator>;
|
||||
|
||||
impl PyByteArrayIteratorRef {
|
||||
fn next(self, vm: &VirtualMachine) -> PyResult<u8> {
|
||||
#[pyimpl]
|
||||
impl PyByteArrayIterator {
|
||||
#[pymethod(name = "__next__")]
|
||||
fn next(&self, vm: &VirtualMachine) -> PyResult<u8> {
|
||||
if self.position.get() < self.bytearray.value.borrow().len() {
|
||||
let ret = self.bytearray.value.borrow()[self.position.get()];
|
||||
self.position.set(self.position.get() + 1);
|
||||
@@ -312,7 +309,8 @@ impl PyByteArrayIteratorRef {
|
||||
}
|
||||
}
|
||||
|
||||
fn iter(self, _vm: &VirtualMachine) -> Self {
|
||||
self
|
||||
#[pymethod(name = "__iter__")]
|
||||
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
|
||||
zelf
|
||||
}
|
||||
}
|
||||
+9
-11
@@ -64,11 +64,7 @@ pub fn init(context: &PyContext) {
|
||||
extend_class!(context, bytes_type, {
|
||||
"fromhex" => context.new_rustfunc(PyBytesRef::fromhex),
|
||||
});
|
||||
let bytesiterator_type = &context.bytesiterator_type;
|
||||
extend_class!(context, bytesiterator_type, {
|
||||
"__next__" => context.new_rustfunc(PyBytesIteratorRef::next),
|
||||
"__iter__" => context.new_rustfunc(PyBytesIteratorRef::iter),
|
||||
});
|
||||
PyBytesIterator::extend_class(context, &context.bytesiterator_type);
|
||||
}
|
||||
|
||||
#[pyimpl]
|
||||
@@ -271,6 +267,7 @@ impl PyBytesRef {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug)]
|
||||
pub struct PyBytesIterator {
|
||||
position: Cell<usize>,
|
||||
@@ -283,10 +280,10 @@ impl PyValue for PyBytesIterator {
|
||||
}
|
||||
}
|
||||
|
||||
type PyBytesIteratorRef = PyRef<PyBytesIterator>;
|
||||
|
||||
impl PyBytesIteratorRef {
|
||||
fn next(self, vm: &VirtualMachine) -> PyResult<u8> {
|
||||
#[pyimpl]
|
||||
impl PyBytesIterator {
|
||||
#[pymethod(name = "__next__")]
|
||||
fn next(&self, vm: &VirtualMachine) -> PyResult<u8> {
|
||||
if self.position.get() < self.bytes.inner.len() {
|
||||
let ret = self.bytes[self.position.get()];
|
||||
self.position.set(self.position.get() + 1);
|
||||
@@ -296,7 +293,8 @@ impl PyBytesIteratorRef {
|
||||
}
|
||||
}
|
||||
|
||||
fn iter(self, _vm: &VirtualMachine) -> Self {
|
||||
self
|
||||
#[pymethod(name = "__iter__")]
|
||||
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
|
||||
zelf
|
||||
}
|
||||
}
|
||||
@@ -5,13 +5,14 @@ use num_bigint::BigInt;
|
||||
use num_traits::Zero;
|
||||
|
||||
use crate::function::OptionalArg;
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objint::PyIntRef;
|
||||
use super::objiter;
|
||||
use super::objtype::PyClassRef;
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug)]
|
||||
pub struct PyEnumerate {
|
||||
counter: RefCell<BigInt>,
|
||||
@@ -44,8 +45,10 @@ fn enumerate_new(
|
||||
.into_ref_with_type(vm, cls)
|
||||
}
|
||||
|
||||
impl PyEnumerateRef {
|
||||
fn next(self, vm: &VirtualMachine) -> PyResult {
|
||||
#[pyimpl]
|
||||
impl PyEnumerate {
|
||||
#[pymethod(name = "__next__")]
|
||||
fn next(&self, vm: &VirtualMachine) -> PyResult {
|
||||
let iterator = &self.iterator;
|
||||
let counter = &self.counter;
|
||||
let next_obj = objiter::call_next(vm, iterator)?;
|
||||
@@ -58,16 +61,15 @@ impl PyEnumerateRef {
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn iter(self, _vm: &VirtualMachine) -> Self {
|
||||
self
|
||||
#[pymethod(name = "__iter__")]
|
||||
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
|
||||
zelf
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let enumerate_type = &context.enumerate_type;
|
||||
extend_class!(context, enumerate_type, {
|
||||
PyEnumerate::extend_class(context, &context.enumerate_type);
|
||||
extend_class!(context, &context.enumerate_type, {
|
||||
"__new__" => context.new_rustfunc(enumerate_new),
|
||||
"__next__" => context.new_rustfunc(PyEnumerateRef::next),
|
||||
"__iter__" => context.new_rustfunc(PyEnumerateRef::iter),
|
||||
});
|
||||
}
|
||||
+15
-16
@@ -1,4 +1,4 @@
|
||||
use crate::pyobject::{IdProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::pyobject::{IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::vm::VirtualMachine; // Required for arg_check! to use isinstance
|
||||
|
||||
use super::objbool;
|
||||
@@ -7,6 +7,11 @@ use crate::obj::objtype::PyClassRef;
|
||||
|
||||
pub type PyFilterRef = PyRef<PyFilter>;
|
||||
|
||||
/// filter(function or None, iterable) --> filter object
|
||||
///
|
||||
/// Return an iterator yielding those items of iterable for which function(item)
|
||||
/// is true. If function is None, return the items that are true.
|
||||
#[pyclass]
|
||||
#[derive(Debug)]
|
||||
pub struct PyFilter {
|
||||
predicate: PyObjectRef,
|
||||
@@ -34,8 +39,10 @@ fn filter_new(
|
||||
.into_ref_with_type(vm, cls)
|
||||
}
|
||||
|
||||
impl PyFilterRef {
|
||||
fn next(self, vm: &VirtualMachine) -> PyResult {
|
||||
#[pyimpl]
|
||||
impl PyFilter {
|
||||
#[pymethod(name = "__next__")]
|
||||
fn next(&self, vm: &VirtualMachine) -> PyResult {
|
||||
let predicate = &self.predicate;
|
||||
let iterator = &self.iterator;
|
||||
loop {
|
||||
@@ -53,23 +60,15 @@ impl PyFilterRef {
|
||||
}
|
||||
}
|
||||
|
||||
fn iter(self, _vm: &VirtualMachine) -> Self {
|
||||
self
|
||||
#[pymethod(name = "__iter__")]
|
||||
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
|
||||
zelf
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let filter_type = &context.filter_type;
|
||||
|
||||
let filter_doc =
|
||||
"filter(function or None, iterable) --> filter object\n\n\
|
||||
Return an iterator yielding those items of iterable for which function(item)\n\
|
||||
is true. If function is None, return the items that are true.";
|
||||
|
||||
extend_class!(context, filter_type, {
|
||||
PyFilter::extend_class(context, &context.filter_type);
|
||||
extend_class!(context, &context.filter_type, {
|
||||
"__new__" => context.new_rustfunc(filter_new),
|
||||
"__doc__" => context.new_str(filter_doc.to_string()),
|
||||
"__next__" => context.new_rustfunc(PyFilterRef::next),
|
||||
"__iter__" => context.new_rustfunc(PyFilterRef::iter),
|
||||
});
|
||||
}
|
||||
+12
-13
@@ -4,7 +4,9 @@
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::pyobject::{
|
||||
PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objtype;
|
||||
@@ -75,6 +77,7 @@ pub fn new_stop_iteration(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.new_exception(stop_iteration_type, "End of iterator".to_string())
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug)]
|
||||
pub struct PySequenceIterator {
|
||||
pub position: Cell<usize>,
|
||||
@@ -87,10 +90,10 @@ impl PyValue for PySequenceIterator {
|
||||
}
|
||||
}
|
||||
|
||||
type PySequenceIteratorRef = PyRef<PySequenceIterator>;
|
||||
|
||||
impl PySequenceIteratorRef {
|
||||
fn next(self, vm: &VirtualMachine) -> PyResult {
|
||||
#[pyimpl]
|
||||
impl PySequenceIterator {
|
||||
#[pymethod(name = "__next__")]
|
||||
fn next(&self, vm: &VirtualMachine) -> PyResult {
|
||||
let number = vm.ctx.new_int(self.position.get());
|
||||
match vm.call_method(&self.obj, "__getitem__", vec![number]) {
|
||||
Ok(val) => {
|
||||
@@ -105,16 +108,12 @@ impl PySequenceIteratorRef {
|
||||
}
|
||||
}
|
||||
|
||||
fn iter(self, _vm: &VirtualMachine) -> Self {
|
||||
self
|
||||
#[pymethod(name = "__iter__")]
|
||||
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
|
||||
zelf
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let iter_type = &context.iter_type;
|
||||
|
||||
extend_class!(context, iter_type, {
|
||||
"__next__" => context.new_rustfunc(PySequenceIteratorRef::next),
|
||||
"__iter__" => context.new_rustfunc(PySequenceIteratorRef::iter),
|
||||
});
|
||||
PySequenceIterator::extend_class(context, &context.iter_type);
|
||||
}
|
||||
+11
-12
@@ -8,7 +8,8 @@ use num_traits::{One, Signed, ToPrimitive, Zero};
|
||||
|
||||
use crate::function::{OptionalArg, PyFuncArgs};
|
||||
use crate::pyobject::{
|
||||
IdProtocol, PyContext, PyIterable, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
|
||||
IdProtocol, PyClassImpl, PyContext, PyIterable, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
TryFromObject,
|
||||
};
|
||||
use crate::vm::{ReprGuard, VirtualMachine};
|
||||
|
||||
@@ -776,6 +777,7 @@ fn list_sort(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug)]
|
||||
pub struct PyListIterator {
|
||||
pub position: Cell<usize>,
|
||||
@@ -788,10 +790,10 @@ impl PyValue for PyListIterator {
|
||||
}
|
||||
}
|
||||
|
||||
type PyListIteratorRef = PyRef<PyListIterator>;
|
||||
|
||||
impl PyListIteratorRef {
|
||||
fn next(self, vm: &VirtualMachine) -> PyResult {
|
||||
#[pyimpl]
|
||||
impl PyListIterator {
|
||||
#[pymethod(name = "__next__")]
|
||||
fn next(&self, vm: &VirtualMachine) -> PyResult {
|
||||
if self.position.get() < self.list.elements.borrow().len() {
|
||||
let ret = self.list.elements.borrow()[self.position.get()].clone();
|
||||
self.position.set(self.position.get() + 1);
|
||||
@@ -801,8 +803,9 @@ impl PyListIteratorRef {
|
||||
}
|
||||
}
|
||||
|
||||
fn iter(self, _vm: &VirtualMachine) -> Self {
|
||||
self
|
||||
#[pymethod(name = "__iter__")]
|
||||
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
|
||||
zelf
|
||||
}
|
||||
}
|
||||
|
||||
@@ -848,9 +851,5 @@ pub fn init(context: &PyContext) {
|
||||
"remove" => context.new_rustfunc(PyListRef::remove)
|
||||
});
|
||||
|
||||
let listiterator_type = &context.listiterator_type;
|
||||
extend_class!(context, listiterator_type, {
|
||||
"__next__" => context.new_rustfunc(PyListIteratorRef::next),
|
||||
"__iter__" => context.new_rustfunc(PyListIteratorRef::iter),
|
||||
});
|
||||
PyListIterator::extend_class(context, &context.listiterator_type);
|
||||
}
|
||||
+15
-15
@@ -1,10 +1,15 @@
|
||||
use crate::function::Args;
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objiter;
|
||||
use super::objtype::PyClassRef;
|
||||
|
||||
/// map(func, *iterables) --> map object
|
||||
///
|
||||
/// Make an iterator that computes the function using arguments from
|
||||
/// each of the iterables. Stops when the shortest iterable is exhausted.
|
||||
#[pyclass]
|
||||
#[derive(Debug)]
|
||||
pub struct PyMap {
|
||||
mapper: PyObjectRef,
|
||||
@@ -35,8 +40,10 @@ fn map_new(
|
||||
.into_ref_with_type(vm, cls.clone())
|
||||
}
|
||||
|
||||
impl PyMapRef {
|
||||
fn next(self, vm: &VirtualMachine) -> PyResult {
|
||||
#[pyimpl]
|
||||
impl PyMap {
|
||||
#[pymethod(name = "__next__")]
|
||||
fn next(&self, vm: &VirtualMachine) -> PyResult {
|
||||
let next_objs = self
|
||||
.iterators
|
||||
.iter()
|
||||
@@ -47,22 +54,15 @@ impl PyMapRef {
|
||||
vm.invoke(self.mapper.clone(), next_objs)
|
||||
}
|
||||
|
||||
fn iter(self, _vm: &VirtualMachine) -> Self {
|
||||
self
|
||||
#[pymethod(name = "__iter__")]
|
||||
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
|
||||
zelf
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let map_type = &context.map_type;
|
||||
|
||||
let map_doc = "map(func, *iterables) --> map object\n\n\
|
||||
Make an iterator that computes the function using arguments from\n\
|
||||
each of the iterables. Stops when the shortest iterable is exhausted.";
|
||||
|
||||
extend_class!(context, map_type, {
|
||||
PyMap::extend_class(context, &context.map_type);
|
||||
extend_class!(context, &context.map_type, {
|
||||
"__new__" => context.new_rustfunc(map_new),
|
||||
"__next__" => context.new_rustfunc(PyMapRef::next),
|
||||
"__iter__" => context.new_rustfunc(PyMapRef::iter),
|
||||
"__doc__" => context.new_str(map_doc.to_string())
|
||||
});
|
||||
}
|
||||
+10
-12
@@ -6,7 +6,7 @@ use num_traits::{One, Signed, Zero};
|
||||
|
||||
use crate::function::{OptionalArg, PyFuncArgs};
|
||||
use crate::pyobject::{
|
||||
PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
@@ -124,11 +124,7 @@ pub fn init(context: &PyContext) {
|
||||
"step" => context.new_property(PyRange::step),
|
||||
});
|
||||
|
||||
let rangeiterator_type = &context.rangeiterator_type;
|
||||
extend_class!(context, rangeiterator_type, {
|
||||
"__next__" => context.new_rustfunc(PyRangeIteratorRef::next),
|
||||
"__iter__" => context.new_rustfunc(PyRangeIteratorRef::iter),
|
||||
});
|
||||
PyRangeIterator::extend_class(context, &context.rangeiterator_type);
|
||||
}
|
||||
|
||||
type PyRangeRef = PyRef<PyRange>;
|
||||
@@ -341,6 +337,7 @@ fn range_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
Ok(range.into_object())
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug)]
|
||||
pub struct PyRangeIterator {
|
||||
position: Cell<usize>,
|
||||
@@ -353,10 +350,10 @@ impl PyValue for PyRangeIterator {
|
||||
}
|
||||
}
|
||||
|
||||
type PyRangeIteratorRef = PyRef<PyRangeIterator>;
|
||||
|
||||
impl PyRangeIteratorRef {
|
||||
fn next(self, vm: &VirtualMachine) -> PyResult<BigInt> {
|
||||
#[pyimpl]
|
||||
impl PyRangeIterator {
|
||||
#[pymethod(name = "__next__")]
|
||||
fn next(&self, vm: &VirtualMachine) -> PyResult<BigInt> {
|
||||
let position = BigInt::from(self.position.get());
|
||||
if let Some(int) = self.range.get(&position) {
|
||||
self.position.set(self.position.get() + 1);
|
||||
@@ -366,8 +363,9 @@ impl PyRangeIteratorRef {
|
||||
}
|
||||
}
|
||||
|
||||
fn iter(self, _vm: &VirtualMachine) -> Self {
|
||||
self
|
||||
#[pymethod(name = "__iter__")]
|
||||
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
|
||||
zelf
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-12
@@ -3,7 +3,7 @@ use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
use crate::function::OptionalArg;
|
||||
use crate::pyobject::{IdProtocol, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::pyobject::{IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::vm::{ReprGuard, VirtualMachine};
|
||||
|
||||
use super::objbool;
|
||||
@@ -224,6 +224,7 @@ fn tuple_new(
|
||||
PyTuple::from(elements).into_ref_with_type(vm, cls)
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug)]
|
||||
pub struct PyTupleIterator {
|
||||
position: Cell<usize>,
|
||||
@@ -236,10 +237,10 @@ impl PyValue for PyTupleIterator {
|
||||
}
|
||||
}
|
||||
|
||||
type PyTupleIteratorRef = PyRef<PyTupleIterator>;
|
||||
|
||||
impl PyTupleIteratorRef {
|
||||
fn next(self, vm: &VirtualMachine) -> PyResult {
|
||||
#[pyimpl]
|
||||
impl PyTupleIterator {
|
||||
#[pymethod(name = "__next__")]
|
||||
fn next(&self, vm: &VirtualMachine) -> PyResult {
|
||||
if self.position.get() < self.tuple.elements.borrow().len() {
|
||||
let ret = self.tuple.elements.borrow()[self.position.get()].clone();
|
||||
self.position.set(self.position.get() + 1);
|
||||
@@ -249,8 +250,9 @@ impl PyTupleIteratorRef {
|
||||
}
|
||||
}
|
||||
|
||||
fn iter(self, _vm: &VirtualMachine) -> Self {
|
||||
self
|
||||
#[pymethod(name = "__iter__")]
|
||||
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
|
||||
zelf
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,9 +284,5 @@ If the argument is a tuple, the return value is the same object.";
|
||||
"index" => context.new_rustfunc(PyTupleRef::index)
|
||||
});
|
||||
|
||||
let tupleiterator_type = &context.tupleiterator_type;
|
||||
extend_class!(context, tupleiterator_type, {
|
||||
"__next__" => context.new_rustfunc(PyTupleIteratorRef::next),
|
||||
"__iter__" => context.new_rustfunc(PyTupleIteratorRef::iter),
|
||||
});
|
||||
PyTupleIterator::extend_class(context, &context.tupleiterator_type);
|
||||
}
|
||||
+11
-9
@@ -1,5 +1,5 @@
|
||||
use crate::function::Args;
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objiter;
|
||||
@@ -7,6 +7,7 @@ use crate::obj::objtype::PyClassRef;
|
||||
|
||||
pub type PyZipRef = PyRef<PyZip>;
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug)]
|
||||
pub struct PyZip {
|
||||
iterators: Vec<PyObjectRef>,
|
||||
@@ -26,8 +27,10 @@ fn zip_new(cls: PyClassRef, iterables: Args, vm: &VirtualMachine) -> PyResult<Py
|
||||
PyZip { iterators }.into_ref_with_type(vm, cls)
|
||||
}
|
||||
|
||||
impl PyZipRef {
|
||||
fn next(self, vm: &VirtualMachine) -> PyResult {
|
||||
#[pyimpl]
|
||||
impl PyZip {
|
||||
#[pymethod(name = "__next__")]
|
||||
fn next(&self, vm: &VirtualMachine) -> PyResult {
|
||||
if self.iterators.is_empty() {
|
||||
Err(objiter::new_stop_iteration(vm))
|
||||
} else {
|
||||
@@ -41,16 +44,15 @@ impl PyZipRef {
|
||||
}
|
||||
}
|
||||
|
||||
fn iter(self, _vm: &VirtualMachine) -> Self {
|
||||
self
|
||||
#[pymethod(name = "__iter__")]
|
||||
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
|
||||
zelf
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let zip_type = &context.zip_type;
|
||||
extend_class!(context, zip_type, {
|
||||
PyZip::extend_class(context, &context.zip_type);
|
||||
extend_class!(context, &context.zip_type, {
|
||||
"__new__" => context.new_rustfunc(zip_new),
|
||||
"__next__" => context.new_rustfunc(PyZipRef::next),
|
||||
"__iter__" => context.new_rustfunc(PyZipRef::iter),
|
||||
});
|
||||
}
|
||||
+11
-11
@@ -15,7 +15,7 @@ use crate::obj::objiter;
|
||||
use crate::obj::objstr;
|
||||
use crate::obj::objstr::PyStringRef;
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
use crate::pyobject::{ItemProtocol, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::pyobject::{ItemProtocol, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
#[cfg(unix)]
|
||||
@@ -232,6 +232,7 @@ impl DirEntryRef {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug)]
|
||||
struct ScandirIterator {
|
||||
entries: RefCell<fs::ReadDir>,
|
||||
@@ -243,10 +244,10 @@ impl PyValue for ScandirIterator {
|
||||
}
|
||||
}
|
||||
|
||||
type ScandirIteratorRef = PyRef<ScandirIterator>;
|
||||
|
||||
impl ScandirIteratorRef {
|
||||
fn next(self, vm: &VirtualMachine) -> PyResult {
|
||||
#[pyimpl]
|
||||
impl ScandirIterator {
|
||||
#[pymethod(name = "__next__")]
|
||||
fn next(&self, vm: &VirtualMachine) -> PyResult {
|
||||
match self.entries.borrow_mut().next() {
|
||||
Some(entry) => match entry {
|
||||
Ok(entry) => Ok(DirEntry { entry }.into_ref(vm).into_object()),
|
||||
@@ -256,8 +257,9 @@ impl ScandirIteratorRef {
|
||||
}
|
||||
}
|
||||
|
||||
fn iter(self, _vm: &VirtualMachine) -> Self {
|
||||
self
|
||||
#[pymethod(name = "__iter__")]
|
||||
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
|
||||
zelf
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,10 +420,8 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
|
||||
let environ = _os_environ(vm);
|
||||
|
||||
let scandir_iter = py_class!(ctx, "ScandirIter", ctx.object(), {
|
||||
"__iter__" => ctx.new_rustfunc(ScandirIteratorRef::iter),
|
||||
"__next__" => ctx.new_rustfunc(ScandirIteratorRef::next),
|
||||
});
|
||||
let scandir_iter = ctx.new_class("ScandirIter", ctx.object());
|
||||
ScandirIterator::extend_class(ctx, &scandir_iter);
|
||||
|
||||
let dir_entry = py_class!(ctx, "DirEntry", ctx.object(), {
|
||||
"name" => ctx.new_property(DirEntryRef::name),
|
||||
|
||||
Reference in new issue
Block a user