Skip to content
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

PyAnyMethods::iter() is a footgun, should be called try_iter() #4550

Open
itamarst opened this issue Sep 12, 2024 · 3 comments · May be fixed by #4553
Open

PyAnyMethods::iter() is a footgun, should be called try_iter() #4550

itamarst opened this issue Sep 12, 2024 · 3 comments · May be fixed by #4553
Assignees

Comments

@itamarst
Copy link
Contributor

itamarst commented Sep 12, 2024

Bug Description

PyAnyMethods::iter() returns a PyResult<&Bound<PyIterator>>. And Result is an iterator. So it's very easy to accidentally iterate over it directly.

Steps to Reproduce

Consider the two seemingly identical functions:

fn iterate(s: Vec<&PyResult<Bound<PyAny>>>) {
    for obj in s.iter() {
        do_something(obj);
    }
}

fn iterate2(s: Bound<PySequence>) {
    for obj in s.iter() {
        do_something(obj);
    }
}

They seem identical, but iterate2() will iterate over the PyResult returned from PyAnyMethods::iter(), so it will always have a single item, the original sequence!

And yes, I just discovered this the hard way.

Your PyO3 version

0.22

Additional Info

I would suggest:

  1. Deprecating iter().
  2. Creating a new, identical function and calling it try_iter(). The new name will suggest that it returns a Result<> and therefore requires a ? or equivalent handler.
@itamarst itamarst added the bug label Sep 12, 2024
@itamarst itamarst changed the title PyAny::iter() is a footgun, should be called try_iter() PyAny::iter() is a footgun, should be called try_iter() Sep 12, 2024
@itamarst itamarst changed the title PyAny::iter() is a footgun, should be called try_iter() PySequence::iter() is a footgun, should be called try_iter() Sep 12, 2024
@itamarst itamarst changed the title PySequence::iter() is a footgun, should be called try_iter() PyAnyMethods::iter() is a footgun, should be called try_iter() Sep 12, 2024
@davidhewitt
Copy link
Member

I think this is a good idea. Either try_iter() or py_iter() seem ok to me. Would be open to hearing other maintainers' opinions on names.

@LilyFoote
Copy link
Contributor

I prefer try_iter - it has the important hint that iteration is fallible and the user should expect to handle a Result. py_iter tells us we're working with a Python object, but we already know that from the type of s.

LilyFoote added a commit to LilyFoote/pyo3 that referenced this issue Sep 13, 2024
@LilyFoote LilyFoote linked a pull request Sep 13, 2024 that will close this issue
@LilyFoote LilyFoote self-assigned this Sep 13, 2024
LilyFoote added a commit to LilyFoote/pyo3 that referenced this issue Sep 13, 2024
@Icxolu
Copy link
Contributor

Icxolu commented Sep 13, 2024

try_iter sounds good to me as well 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants