-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add reversed iterator type. #2900
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,15 @@ | ||
| use crate::common::lock::PyRwLock; | ||
|
|
||
| use crossbeam_utils::atomic::AtomicCell; | ||
| use num_bigint::BigInt; | ||
| use num_traits::Zero; | ||
|
|
||
| use super::int::PyIntRef; | ||
| use super::pytype::PyTypeRef; | ||
| use crate::function::OptionalArg; | ||
| use crate::iterator; | ||
| use crate::slots::PyIter; | ||
| use crate::vm::VirtualMachine; | ||
| use crate::{iterator, ItemProtocol, TypeProtocol}; | ||
| use crate::{IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue}; | ||
|
|
||
| #[pyclass(module = false, name = "enumerate")] | ||
|
|
@@ -60,6 +61,52 @@ impl PyIter for PyEnumerate { | |
| } | ||
| } | ||
|
|
||
| #[pyclass(module = false, name = "reversed")] | ||
| #[derive(Debug)] | ||
| pub struct PyReverseSequenceIterator { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this belong to enuemerate rather than sequence? I feel like this iterator generate
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know. I don't know why CPython has them in the same file but it does. So I kept the same structure. |
||
| pub position: AtomicCell<isize>, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this isize rather than a usize?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Usually the reverse iterators keep an |
||
| pub obj: PyObjectRef, | ||
| } | ||
|
|
||
| impl PyValue for PyReverseSequenceIterator { | ||
| fn class(vm: &VirtualMachine) -> &PyTypeRef { | ||
| &vm.ctx.types.reverse_iter_type | ||
| } | ||
| } | ||
|
|
||
| #[pyimpl(with(PyIter))] | ||
| impl PyReverseSequenceIterator { | ||
| pub fn new(obj: PyObjectRef, len: isize) -> Self { | ||
| Self { | ||
| position: AtomicCell::new(len - 1), | ||
| obj, | ||
| } | ||
| } | ||
|
|
||
| #[pymethod(magic)] | ||
| fn length_hint(&self) -> PyResult<isize> { | ||
| Ok(self.position.load() + 1) | ||
| } | ||
| } | ||
|
|
||
| impl PyIter for PyReverseSequenceIterator { | ||
| fn next(zelf: &PyRef<Self>, vm: &VirtualMachine) -> PyResult { | ||
| let pos = zelf.position.fetch_sub(1); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what happens if this is called forever until negatively overflow?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm fixing all these methods in another pr. Currently I've just split these appart for now to make the changes a little smaller in size.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will you make another huge PR with the whole diff for a reference? I will also check the final result.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I could push the changes on this branch if it would make it easier for you.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think seperated small PR still have benefits. So another PR would be more convenient. It will be reusable after merging this one. For this PR, I thought I can compare other parts also, but after checking your answers about it, it doesn't look that's nessessary for now. |
||
| if pos >= 0 { | ||
| match zelf.obj.get_item(pos, vm) { | ||
| Err(ref e) if e.isinstance(&vm.ctx.exceptions.index_error) => { | ||
| Err(vm.new_stop_iteration()) | ||
| } | ||
| // also catches stop_iteration => stop_iteration | ||
| ret => ret, | ||
| } | ||
| } else { | ||
| Err(vm.new_stop_iteration()) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| pub fn init(context: &PyContext) { | ||
| PyEnumerate::extend_class(context, &context.types.enumerate_type); | ||
| PyReverseSequenceIterator::extend_class(context, &context.types.reverse_iter_type); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same level as the next line (Line 13)