You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
False negative involving null checks on optional types #5423
Here is a minimal program demonstrating the problem:
foo = None
for _ in range(2):
if foo is not None:
print(1[2])
foo = 1
Expected behavior:
error: Value of type "int" is not indexable
Actual behavior:
mypy accepts the program as valid, when run with the --strict flag
This issue seems to be a problem with how mypy handles reassignment to None type variables, and static evaluation of conditionals. After line 1, foo has the type None according to mypy. Thus, mypy determines that the condition on line 3 will never hold, and thus doesn't do type checking for the body of the if statement. On line 5, foo's type changes to Optional[int]. This, however, will only be reflected in code that follows line 5.
Hm, indeed, the conditional binder still doesn't catch all the corner cases. But actually by preference would be to just show errors in unreachable code in the strict mode.
This bug is actually pretty bad, I think. It comes up not infrequently and has a pretty bad knock-on effect on mypyc, where it causes bizarre type errors of the form TypeError: None object expected
@msullivan
I left a comment in a very similar issue (a duplicate?) recently #7204 (comment). That "proposal" didn't get much traction however (although it seems to me the binder refactoring might me of smaller size than the semantic analyzer one, plus it can be split into few parts).
This might be easy to fix without a major refactoring. Maybe we only need to modify how is None / is not None checks behave when the type is a partial type.
in case anyone comes here for help:
i annotated a variable used in a loop under an if-statement with foo: Optional[float] = None where it previously was not.
after that the error went away.
I guess mypy assumed the type to be NoneType or something and that it could never be float.
(lesson for me here is; always try to annotate more, it'll not only help me but also mypy)
Activity
ilevkivskyi commentedon Aug 6, 2018
Hm, indeed, the conditional binder still doesn't catch all the corner cases. But actually by preference would be to just show errors in unreachable code in the strict mode.
msullivan commentedon Aug 9, 2019
This bug is actually pretty bad, I think. It comes up not infrequently and has a pretty bad knock-on effect on mypyc, where it causes bizarre type errors of the form
TypeError: None object expectedilevkivskyi commentedon Aug 9, 2019
@msullivan
I left a comment in a very similar issue (a duplicate?) recently #7204 (comment). That "proposal" didn't get much traction however (although it seems to me the binder refactoring might me of smaller size than the semantic analyzer one, plus it can be split into few parts).
JukkaL commentedon Aug 12, 2019
This might be easy to fix without a major refactoring. Maybe we only need to modify how
is None/is not Nonechecks behave when the type is a partial type.msullivan commentedon Aug 21, 2019
Hm, there are cases where this breaks mypyc without
is Nonechecks:Produce mypyc errors when encountering bug #5423
Produce mypyc errors when encountering bug #5423
Produce mypyc errors when encountering bug #5423 (#7482)
Apply variable expansion to default values
Apply variable expansion to default values (#204)
joshinils commentedon Aug 28, 2022
in case anyone comes here for help:
i annotated a variable used in a loop under an if-statement with
foo: Optional[float] = Nonewhere it previously was not.after that the error went away.
I guess mypy assumed the type to be NoneType or something and that it could never be float.
(lesson for me here is; always try to annotate more, it'll not only help me but also mypy)
Revisit the body of a loop if the number of partial types has changed.
Revisit the body of a loop if the number of partial types has changed. (