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

Mypy incorrectly requires __next__() on the iterable of a for loop (regression from 0.942). #16733

Open
md2468 opened this issue Jan 2, 2024 · 3 comments
Labels
bug mypy got something wrong

Comments

@md2468
Copy link

md2468 commented Jan 2, 2024

Bug Report

For loops in Python require only an iterable, for which an iterator is subsequently created. However, in the code below, Mypy incorrectly requires __next__ to be available on the iterable.

To Reproduce

from collections.abc import Iterable

xs: zip[tuple[object, ...]] | Iterable[object] = zip(*[[0], [0]])
for x in xs: pass

Actual Behavior

main.py:4: error: "Iterable[object]" has no attribute "__next__"  [attr-defined]

Your Environment

  • Mypy version used: 1.8.0.
  • Mypy command-line flags: None.
  • Mypy configuration options from mypy.ini (and other config files): None.
  • Python version used: 3.12.

This is a regression from version 0.942.
1.8.0 Playground
0.942 Playground

@md2468 md2468 added the bug mypy got something wrong label Jan 2, 2024
@graingert
Copy link
Contributor

I can repeat this on 0.800, so I think it's just that zip changed definition in typeshed after 0.942

https://mypy-play.net/?mypy=0.800&python=3.12&gist=94e05458b907384b70af1be75c60cfeb

@JamesParrott
Copy link

I can recreate this in v1.8.0 too. But interestingly there's no error with either type hint alone. The both annotations together with the | is causing the bug.

@hauntsaninja
Copy link
Collaborator

hauntsaninja commented Jan 4, 2024

Thanks for the issue!

It looks like mypy isn't handling the self type annotation on zip.__iter__ correctly. It loses track of the upper bound implied by the self type, so it gets the wrong return type when trying to resolve __iter__ in

iterator = echk.check_method_call_by_name("__iter__", iterable, [], [], context)[0]

This looked familiar to me and it turns out I have a relevant patch in #13221. That patch would indeed fix this case, but for reasons beyond my understanding that patch makes mypy pretty unhappy in general.

Maybe @ilevkivskyi has time to take a look, since he made #16184 which solved the issue #13221 was trying to solve, and also is generally awesome at fixing things.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

4 participants