Skip to content

Commit 1993fdf

Browse files
authored
Complain about inferring UninhabitedType for a variable (#4112)
These don't really make sense as variable types, most of the time. Also, don't turn them into partial None types, since UninhabitedType and None no longer have any correspondence.
1 parent b875205 commit 1993fdf

File tree

3 files changed

+18
-14
lines changed

3 files changed

+18
-14
lines changed

mypy/checker.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1890,7 +1890,7 @@ def infer_variable_type(self, name: Var, lvalue: Lvalue,
18901890
self.set_inferred_type(name, lvalue, init_type)
18911891

18921892
def infer_partial_type(self, name: Var, lvalue: Lvalue, init_type: Type) -> bool:
1893-
if isinstance(init_type, (NoneTyp, UninhabitedType)):
1893+
if isinstance(init_type, NoneTyp):
18941894
partial_type = PartialType(None, name, [init_type])
18951895
elif isinstance(init_type, Instance):
18961896
fullname = init_type.type.fullname()
@@ -3391,11 +3391,11 @@ def is_valid_inferred_type(typ: Type) -> bool:
33913391
invalid. When doing strict Optional checking, only None and types that are
33923392
incompletely defined (i.e. contain UninhabitedType) are invalid.
33933393
"""
3394-
if is_same_type(typ, NoneTyp()):
3395-
# With strict Optional checking, we *may* eventually infer NoneTyp, but
3396-
# we only do that if we can't infer a specific Optional type. This
3397-
# resolution happens in leave_partial_types when we pop a partial types
3398-
# scope.
3394+
if isinstance(typ, (NoneTyp, UninhabitedType)):
3395+
# With strict Optional checking, we *may* eventually infer NoneTyp when
3396+
# the initializer is None, but we only do that if we can't infer a
3397+
# specific Optional type. This resolution happens in
3398+
# leave_partial_types when we pop a partial types scope.
33993399
return False
34003400
return is_valid_inferred_type_component(typ)
34013401

test-data/unit/check-inference.test

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -413,14 +413,15 @@ def id(x: T) -> T:
413413
return x
414414
[out]
415415

416-
[case testUnderspecifiedInferenceResult-skip]
416+
[case testUnderspecifiedInferenceResult]
417417
from typing import TypeVar
418418
T = TypeVar('T')
419419
class A: pass
420420
a = None # type: A
421421

422422
def ff() -> None:
423423
x = f() # E: Need type annotation for variable
424+
reveal_type(x)
424425

425426
g(None) # Ok
426427
f() # Ok because not used to infer local variable type
@@ -874,9 +875,10 @@ for x in [A()]:
874875
b = x # E: Incompatible types in assignment (expression has type "A", variable has type "B")
875876
a = x
876877

877-
for y in []:
878-
a = y
879-
reveal_type(y) # E: Revealed type is 'builtins.None'
878+
for y in []: # E: Need type annotation for variable
879+
a = y # E: Cannot determine type of 'y'
880+
reveal_type(y) # E: Revealed type is 'Any' \
881+
# E: Cannot determine type of 'y'
880882

881883
class A: pass
882884
class B: pass
@@ -920,9 +922,11 @@ for x, y in [[A()]]:
920922
a = x
921923
a = y
922924

923-
for e, f in [[]]:
924-
reveal_type(e) # E: Revealed type is 'builtins.None'
925-
reveal_type(f) # E: Revealed type is 'builtins.None'
925+
for e, f in [[]]: # E: Need type annotation for variable
926+
reveal_type(e) # E: Revealed type is 'Any' \
927+
# E: Cannot determine type of 'e'
928+
reveal_type(f) # E: Revealed type is 'Any' \
929+
# E: Cannot determine type of 'f'
926930

927931
class A: pass
928932
class B: pass

test-data/unit/check-tuples.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ for x in t:
633633
[case testForLoopOverEmptyTuple]
634634
import typing
635635
t = ()
636-
for x in t: pass
636+
for x in t: pass # E: Need type annotation for variable
637637
[builtins fixtures/for.pyi]
638638

639639
[case testForLoopOverNoneValuedTuple]

0 commit comments

Comments
 (0)