Skip to content

Implement itertools.zip_longest #1604

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

Merged
merged 3 commits into from
Dec 1, 2019
Merged

Implement itertools.zip_longest #1604

merged 3 commits into from
Dec 1, 2019

Conversation

Space0726
Copy link
Contributor

@Space0726 Space0726 commented Nov 22, 2019

This pull request implements itertools.zip_longest in Python standard library, related with #1361.

Copy link
Member

@coolreader18 coolreader18 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've got a few small nitpicks, but overall this looks very good! If you could fix those up this will be good to merge.

for idx in 0..self.iterators.len() {
next_obj = match call_next(vm, &self.iterators[idx]) {
Ok(obj) => obj,
Err(_) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to check if the error here is a StopIteration or not and handle it accordingly (if it isn't StopIteration we just want to pass it on):

Err(err) => {
    if !objtype::isinstance(&err, &vm.ctx.exceptions.stop_iteration) {
        return Err(err);
    }
    numactive -= 1;
    // ...
}

struct PyItertoolsZiplongest {
iterators: Vec<PyObjectRef>,
fillvalue: PyObjectRef,
numactive: RefCell<usize>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can just be a Cell<usize>. Cell is better for primitive data types that can just be copied. Then, later, you can just do let numactive = self.numactive.get(); and self.numactive.set(new_numactive);

let mut numactive = self.numactive.clone().into_inner();

for idx in 0..self.iterators.len() {
next_obj = match call_next(vm, &self.iterators[idx]) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need to have next_obj be mutable and declared outside the loop? I think you could just do let next_obj = match call_next ....

@Space0726
Copy link
Contributor Author

@coolreader18 Thank you for your detailed review! I learned a lot from this review.

Copy link
Member

@coolreader18 coolreader18 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few more little things I didn't notice in the first review. Thanks for sticking with me!

Err(new_stop_iteration(vm))
} else {
let mut result: Vec<PyObjectRef> = Vec::new();
let mut numactive = self.numactive.get();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does self.numactive actually need to be a Cell? It doesn't look like you set it anywhere, but I'm not sure if it should be set at some point or if it doesn't need to be.

let mut result: Vec<PyObjectRef> = Vec::new();
let mut numactive = self.numactive.get();

for idx in 0..self.iterators.len() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can make this for iter in &self.iterators { ... }

@coolreader18
Copy link
Member

Thanks for contributing!

@coolreader18 coolreader18 dismissed their stale review December 1, 2019 04:51

Changes made

@coolreader18 coolreader18 merged commit ec011f5 into RustPython:master Dec 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants