Bug Report
--strict-equality-for-none gives a false-positive comparison-overlap error when checking if a global is None in a loop.
To Reproduce
# No playground link since playground doesn't support --strict-equality-for-none yet (https://github.com/ymyzk/mypy-playground/issues/1058). # flags: --strict-equality --strict-equality-for-none --local-partial-types --allow-redefinition-new x: int | None = None def f() -> None: for _ in range(1): reveal_type(x) # note: Revealed type is "builtins.int | None" if x is None: # error: Non-overlapping identity check (left operand type: "int", right operand type: "None") [comparison-overlap] raise RuntimeError()
Expected Behavior
No error.
Actual Behavior
$ mypy --strict-equality --strict-equality-for-none --local-partial-types --allow-redefinition-new eg.py eg.py:9: note: Revealed type is "builtins.int | None" eg.py:10: error: Non-overlapping identity check (left operand type: "int", right operand type: "None") [comparison-overlap] Found 1 error in 1 file (checked 1 source file)
Your Environment
Notes
This seems similar to #19328. Note that the error goes away if you remove the line for _ in range(1):.
But it's different from #19328 in some ways:
It seems to be specific to --strict-equality-for-none; the error goes away if you change None to str:
# flags: --strict-equality --strict-equality-for-none --local-partial-types --allow-redefinition-new x: int | str = "" def f() -> None: for _ in range(1): reveal_type(x) # note: Revealed type is "builtins.int | builtins.str" if x == "": # NO ERROR raise RuntimeError()
It seems to require multiple variable scopes: the error goes away if you remove the line def f() -> None:.
Unlike the snippet in --strict-equality too strict in iteratively visited code #19328, the variable is never mutated.
Fix `--strict-equality` for iteratively visited code (python#19635)
Activity
Fix `--strict-equality` for iteratively visited code (python#19635)