False Positive of `reportUnnecessaryComparison` for Loop Variables
Describe the bug & Code or Screenshots
In the following code, the loop condition i != 10 is flagged by Pyright, while j != 10 is accepted, even though both loops implement the same logic (PP):
def test() -> bool: ...
i = 0
while i != 10: # Pyright: Condition will always evaluate to True since the types "Literal[0]" and "Literal[10]" have no overlap
if test():
continue
i += 1
j = 0
while j != 10:
if test():
continue
j += 1
VS Code extension or command-line Pylance version: 2025.4.100
Thanks for the bug report and the clean, simple repro case. I have some theories about the underlying cause, but I'll need to investigate further.
Another related—albeit somewhat contrived—example is shown below (PP):
i = 0
def work() -> None:
global i
print(i)
i += 1
while i != 10: # Pyright: Condition will always evaluate to True since the types "Literal[0]" and "Literal[10]" have no overlap
work()
Interestingly, I found that replacing i = 0 with i = int(0) resolves the issue.
The second example is working as intended, so I don't consider that a bug. Pyright performs type narrowing locally within an execution scope without regard for side effects that may occur in other execution scopes. Static type checkers cannot generally determine if and when code within other scopes may be executed. If you want your code to work well with static analyzers, avoid writing code that has side effects like this.