microsoft / pyright

Static Type Checker for Python
Other
13.12k stars 1.4k forks source link

Unbound|str for for-loop variable #8791

Closed PortalWalker closed 3 weeks ago

PortalWalker commented 3 weeks ago

Describe the bug Variable shows as possibly unbound when it is getting assigned inside a for-loop:

for data in ["foo", "bar"]:
    pass

The type of data in the above example shows as Unbound | str after the loop even though it is getting assigned to a string inside the for-loop and therefore can't be unbound.

Using in Python in Visual Studio Community 2022 and a link through that directed me to this github

erictraut commented 3 weeks ago

This is a duplicate issue.

Pyright is working as intended here, so I don't consider this a bug.

There is currently no way in the Python type system to represent an iterable type that is guaranteed to iterate at least once. Type checkers therefore must assume that iterables may produce zero results.

There have been some early thoughts about how the type system could be extended to provide additional information to a static type checker in this case, but they haven't gotten very far yet.

You have several ways to work around this:

  1. Don't use loop variables outside of the loop body.
  2. Initialize loop variables before the loop with a value.
  3. Disable the reportPossiblyUnboundVariable check in pyright, either globally for your project or on a per-file or per-line basis. Pyright specifically distinguishes between "possibly unbound" and "definitely unbound" variable usage to accommodate this.
PortalWalker commented 3 weeks ago

Understood. Thank you so much for your quick and thorough answer