blob: 2b62699b5166be0d63e75eb123fa24753c45603f [file] [log] [blame] [edit]
[case testForcedAssignment]
x = 1 # type: object
y = 1
def f(): x, y # Prevent independent redefinition
y = x # E: Incompatible types in assignment (expression has type "object", variable has type "int")
x = 2
y = x
[case testJoinAny]
from typing import List, Any
x = None # type: List[Any]
def foo() -> List[int]: pass
def bar() -> List[str]: pass
if bool():
x = foo()
else:
x = bar()
x * 2
[builtins fixtures/list.pyi]
[case testGeneratorExpressionTypes]
class A: y = 1
x = [A()]
y = [x]
z = [1,2]
z = [a.y for b in y for a in b]
[builtins fixtures/list.pyi]
[case testIsinstanceNestedTuple]
from typing import Union, List, Tuple, Dict
def f(x: Union[int, str, List]) -> None:
if isinstance(x, (str, (int,))):
reveal_type(x) # N: Revealed type is 'Union[builtins.int, builtins.str]'
x[1] # E: Value of type "Union[int, str]" is not indexable
else:
reveal_type(x) # N: Revealed type is 'builtins.list[Any]'
x[1]
reveal_type(x) # N: Revealed type is 'Union[builtins.int, builtins.str, builtins.list[Any]]'
if isinstance(x, (str, (list,))):
reveal_type(x) # N: Revealed type is 'Union[builtins.str, builtins.list[Any]]'
x[1]
reveal_type(x) # N: Revealed type is 'Union[builtins.int, builtins.str, builtins.list[Any]]'
[builtins fixtures/isinstancelist.pyi]
[case testClassAttributeInitialization-skip]
class A:
x = None # type: int
def __init__(self) -> None:
self.y = None # type: int
z = self.x
w = self.y
[case testAssignmentSubtypes-skip]
from typing import Union
def foo(x: Union[str, int]):
if isinstance(x, int):
x = 'a'
x + 'a' # Works in the current code
z = x # We probably want this to be of type str.
y = [x] # But what type should this be?
y[0] + 'a' # (1) Should this work?
y + [1] # (2) Or this?
z = 1 # Also, is this valid?
x = None # type: int
y = [x]
[builtins fixtures/isinstancelist.pyi]
[case testFunctionDefaultArgs]
class A: pass
class B(A): y = 1
x = A()
def foo(x: A = B()):
x.y # E: "A" has no attribute "y"
[builtins fixtures/isinstance.pyi]
[case testIsinstanceFancyConditionals]
class A: pass
class B(A):
y = 1
x = A()
if isinstance(x, B):
x.y
while isinstance(x, B):
x.y
while isinstance(x, B):
x.y
x = B()
[builtins fixtures/isinstance.pyi]
[case testSubtypingWithAny]
class A:
y = 1
class B(A):
z = 1
def foo(): pass
x = A()
if int():
x = B()
x.z
x = foo()
x.z # E: "A" has no attribute "z"
x.y
[case testSingleMultiAssignment-skip]
x = 'a'
(x, ) = ('a',)
[case testUnionMultiAssignment]
from typing import Union
x = None # type: Union[int, str]
if int():
x = 1
x = 'a'
x + 1 # E: Unsupported operand types for + ("str" and "int")
x = 1
(x, y) = ('a', 1)
x + 1 # E: Unsupported operand types for + ("str" and "int")
[builtins fixtures/isinstancelist.pyi]
[case testUnionIfZigzag]
from typing import Union
def f(x: Union[int, str]) -> None:
if 1: # Without this, the assignment below could create a new variable "x" of type "int"
x = 1
if x:
x = 'a'
x = 1
x + 1
x + 1
[builtins fixtures/isinstancelist.pyi]
[case testTwoLoopsUnion]
from typing import Union
def foo() -> Union[int, str]: pass
def bar() -> None:
x = foo()
if isinstance(x, int):
return
while bool():
x + 'a'
while bool():
x = foo()
if bool():
return
x = 'a'
x + 'a'
[builtins fixtures/isinstancelist.pyi]
[case testComplicatedBlocks]
from typing import Union
def foo() -> Union[int, str]: pass
def bar() -> None:
x = foo()
if isinstance(x, int):
return
while bool():
x + 'a'
while bool():
x = foo()
if bool():
return
x = 'a'
x + 'a'
x = foo()
if isinstance(x, int):
return
while bool():
x + 'a'
while bool():
x + 'a' # E: Unsupported operand types for + ("int" and "str") \
# N: Left operand is of type "Union[int, str]"
x = foo()
if bool():
continue
x = 'a'
x = 'a'
x + 'a'
[builtins fixtures/isinstancelist.pyi]
[case testUnionTryExcept]
class A:
y = A()
class B(A):
z = 1
x = A()
def f(): x # Prevent redefinition of x
x = B()
x.z
try:
x.z
x = A()
x = B()
x.z
except:
pass
x.z # E: "A" has no attribute "z"
[case testUnionTryExcept2]
class A:
y = A()
class B(A):
z = 1
x = A()
try:
x.z # E: "A" has no attribute "z"
x = A()
x = B()
x.z
except:
x.z # E: "A" has no attribute "z"
x = B()
x.z
else:
x = B()
x.z
[case testUnionTryExcept3]
class A:
y = A()
class B(A):
z = 1
x = A()
def f(): x # Prevent redefinition of x
x = B()
try:
raise BaseException()
x = A()
except:
pass
x.z
x = B()
try:
x = A()
raise BaseException()
except:
pass
x.z # E: "A" has no attribute "z"
x = B()
try:
pass
except:
x = A()
raise BaseException()
x.z
try:
x = A()
except:
pass
x.z # E: "A" has no attribute "z"
x = B()
try:
pass
except:
x = A()
x.z # E: "A" has no attribute "z"
[builtins fixtures/exception.pyi]
[case testUnionTryExcept4]
class A: pass
class B(A):
z = 1
x = A()
while bool():
try:
x.z # E: "A" has no attribute "z"
x = A()
except:
x = B()
else:
x = B()
x.z
[builtins fixtures/exception.pyi]
[case testUnionTryFinally]
class A: pass
class B(A):
b = 1
x = A()
def f(): x # Prevent redefinition
x = B()
try:
x = A()
x.b # E: "A" has no attribute "b"
x = B()
finally:
x.b # E: "A" has no attribute "b"
x.b
[case testUnionTryFinally2]
class A: pass
class B(A):
b = 1
x = A()
def f(): x # Prevent redefinition
x = B()
try:
x = A()
x = B()
except:
pass
finally:
pass
x.b # E: "A" has no attribute "b"
[case testUnionTryFinally3]
class A: pass
class B(A):
b = 1
x = A()
def f(): x # Prevent redefinition
x = B()
try:
x = A()
x = B()
except:
pass
finally:
x = B()
x.b
[case testUnionTryFinally4]
class A: pass
class B(A):
b = 1
while 2:
x = A()
def f(): x # Prevents redefinition
x = B()
try:
x = A()
x = B()
except:
pass
finally:
x.b # E: "A" has no attribute "b"
if not isinstance(x, B):
break
x.b
[builtins fixtures/isinstancelist.pyi]
[case testUnionTryFinally5]
class A: pass
class B(A):
b = 1
while 2:
x = A()
try:
x = A()
x = B()
finally:
x.b # E: "A" has no attribute "b"
break
x.b
x.b
[case testUnionTryFinally6]
class A: pass
class B(A):
b = 1
def f() -> int:
x = B() # type: A
try:
x = B()
except:
x = A()
# An exception could occur here
x = B()
finally:
return x.b # E: "A" has no attribute "b"
[case testUnionListIsinstance]
from typing import Union, List
def f(x: Union[List[int], List[str], int]) -> None:
if isinstance(x, list):
a = x[0]
if isinstance(a, int):
a + 1
a + 'x' # E: Unsupported operand types for + ("int" and "str")
# type of a?
reveal_type(x) # N: Revealed type is 'Union[builtins.list[builtins.int], builtins.list[builtins.str]]'
x + 1 # E: Unsupported operand types for + ("List[int]" and "int") \
# E: Unsupported operand types for + ("List[str]" and "int") \
# N: Left operand is of type "Union[List[int], List[str]]"
else:
x[0] # E: Value of type "int" is not indexable
x + 1
x[0] # E: Value of type "Union[List[int], List[str], int]" is not indexable
x + 1 # E: Unsupported operand types for + ("List[int]" and "int") \
# E: Unsupported operand types for + ("List[str]" and "int") \
# N: Left operand is of type "Union[List[int], List[str], int]"
[builtins fixtures/isinstancelist.pyi]
[case testUnionListIsinstance2]
from typing import Union, List
class A:
a = 1
class B: pass
class C: pass
def g(x: Union[A, B]) -> A: pass
def h(x: C) -> A: pass
def f(x: Union[A, B, C]) -> None:
if isinstance(x, C):
x = h(x)
else:
x = g(x)
x.a
[builtins fixtures/isinstancelist.pyi]
[case testUnionStrictDefnBasic]
from typing import Union
def foo() -> Union[int, str]: pass
x = foo()
if int():
x = 1
x = x + 1
x = foo()
x = x + 1 # E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[int, str]"
if isinstance(x, str):
x = x + 1 # E: Unsupported operand types for + ("str" and "int")
x = 1
x = x + 1
[builtins fixtures/isinstancelist.pyi]
[case testSubtypeRedefinitionBasic]
from typing import Union
class A: pass
class B(A):
y = 1
x = A()
x.y # E: "A" has no attribute "y"
x = B()
x.y # OK: x is known to be a B
[builtins fixtures/isinstancelist.pyi]
[case testIsInstanceBasic]
from typing import Union
x = None # type: Union[int, str]
if isinstance(x, str):
x = x + 1 # E: Unsupported operand types for + ("str" and "int")
x = x + 'a'
else:
x = x + 'a' # E: Unsupported operand types for + ("int" and "str")
x = x + 1
[builtins fixtures/isinstancelist.pyi]
[case testIsInstanceIndexing]
from typing import Union
x = None # type: Union[int, str]
j = [x]
if isinstance(j[0], str):
j[0] = j[0] + 'a'
j[0] = j[0] + 1 # E: Unsupported operand types for + ("str" and "int")
else:
j[0] = j[0] + 'a' # E: Unsupported operand types for + ("int" and "str")
j[0] = j[0] + 1
[builtins fixtures/isinstancelist.pyi]
[case testIsInstanceSubClassMember]
from typing import Union
class Animal: pass
class Dog(Animal):
paws = 4 # type: Union[int, str]
def bark(self): pass
class House:
pet = None # type: Animal
h = House()
h.pet = Dog()
while bool():
if isinstance(h.pet, Dog):
if isinstance(h.pet.paws, str):
x = h.pet.paws + 'a'
y = h.pet.paws + 1 # E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[int, str]"
z = h.pet.paws + 'a' # E: Unsupported operand types for + ("int" and "str") \
# N: Left operand is of type "Union[int, str]"
if isinstance(h.pet.paws, str):
x = h.pet.paws + 'a'
break
y = h.pet.paws + 1
z = h.pet.paws + 'a' # E: Unsupported operand types for + ("int" and "str")
[builtins fixtures/isinstancelist.pyi]
[case testIsInstanceSubClassReset]
class A:
pass
class B(A):
b = 1
class C:
a = A()
x = C()
x.a.b # E: "A" has no attribute "b"
if isinstance(x.a, B):
x.a.b
x = C()
x.a.b # E: "A" has no attribute "b"
[builtins fixtures/isinstance.pyi]
[case testIsinstanceTuple]
from typing import Union
class A: pass
class B:
def method2(self, arg: int):
return 123
class C:
def method2(self, arg: int):
return 456
def method3(self, arg: str):
return 'abc'
v = A() # type: Union[A, B, C]
if isinstance(v, (B, C)):
v.method2(123)
v.method3('xyz') # E: Item "B" of "Union[B, C]" has no attribute "method3"
[builtins fixtures/isinstance.pyi]
[case testIsinstanceNeverWidens]
from typing import Union
class A: pass
class B: pass
class C: pass
a = A() # type: A
assert isinstance(a, (A, B))
reveal_type(a) # N: Revealed type is '__main__.A'
b = A() # type: Union[A, B]
assert isinstance(b, (A, B, C))
reveal_type(b) # N: Revealed type is 'Union[__main__.A, __main__.B]'
[builtins fixtures/isinstance.pyi]
[case testMemberAssignmentChanges-skip]
from typing import Union
class Dog:
paws = 1 # type: Union[int, str]
pet = Dog()
pet.paws + 'a' # E: moo
pet.paws = 'a'
pet.paws + 'a'
pet.paws = 1
pet.paws + 1
[builtins fixtures/isinstancelist.pyi]
[case testIsInstanceSubClassMemberHard-skip]
from typing import Union
class Animal:
pass
class Dog(Animal):
paws = 4 # type: Union[int, str]
def bark(self): pass
class House:
pet = None # type: Animal
h = House()
h.pet = Dog()
if isinstance(h.pet, Dog):
if isinstance(h.pet.paws, str):
for i in [1]:
h.pet.paws + 'a'
if bool():
break
h.pet.paws = 1
h.pet.paws + 1
if isinstance(h.pet.paws, str):
h.pet.paws + 'a'
else:
h.pet.paws + 1
[builtins fixtures/isinstancelist.pyi]
[case testIsInstanceReturn]
from typing import Union
def foo() -> None:
x = 1 # type: Union[int, str]
if isinstance(x, int):
return
y = x + 'asdad'
def bar() -> None:
x = 1 # type: Union[int, str]
if isinstance(x, int):
return
else:
pass
y = x + 'asdad'
foo()
[builtins fixtures/isinstancelist.pyi]
[case testIsInstanceBadBreak]
from typing import Union
def foo() -> None:
x = None # type: Union[int, str]
if isinstance(x, int):
for z in [1,2]:
break
else:
pass
y = x + 'asdad' # E: Unsupported operand types for + ("int" and "str") \
# N: Left operand is of type "Union[int, str]"
foo()
[builtins fixtures/isinstancelist.pyi]
[case testIsInstanceThreeUnion]
from typing import Union, List
x = None # type: Union[int, str, List[int]]
while bool():
if isinstance(x, int):
x + 1
elif isinstance(x, str):
x + 'a'
else:
x + [1]
x + 'a' # E: Unsupported operand types for + ("int" and "str") \
# E: Unsupported operand types for + ("List[int]" and "str") \
# N: Left operand is of type "Union[int, str, List[int]]"
x + [1] # E: Unsupported operand types for + ("int" and "List[int]") \
# E: Unsupported operand types for + ("str" and "List[int]") \
# N: Left operand is of type "Union[int, str, List[int]]"
[builtins fixtures/isinstancelist.pyi]
[case testIsInstanceThreeUnion2]
from typing import Union, List
x = None # type: Union[int, str, List[int]]
while bool():
if isinstance(x, int):
x + 1
break
elif isinstance(x, str):
x + 'a'
break
x + [1]
x + 'a' # E: Unsupported operand types for + ("List[int]" and "str")
x + [1] # E: Unsupported operand types for + ("int" and "List[int]") \
# E: Unsupported operand types for + ("str" and "List[int]") \
# N: Left operand is of type "Union[int, str, List[int]]"
[builtins fixtures/isinstancelist.pyi]
[case testIsInstanceThreeUnion3]
from typing import Union, List
while bool():
x = None # type: Union[int, str, List[int]]
def f(): x # Prevent redefinition
x = 1
if isinstance(x, int):
x + 1
break
elif isinstance(x, str):
x + 'a'
break
x + [1] # These lines aren't reached because x was an int
x + 'a'
x + [1] # E: Unsupported operand types for + ("int" and "List[int]") \
# E: Unsupported operand types for + ("str" and "List[int]") \
# N: Left operand is of type "Union[int, str, List[int]]"
[builtins fixtures/isinstancelist.pyi]
[case testRemovingTypeRepeatedly]
from typing import Union
def foo() -> Union[int, str]: pass
for i in [1, 2]:
x = foo()
x + 'a' # E: Unsupported operand types for + ("int" and "str") \
# N: Left operand is of type "Union[int, str]"
if isinstance(x, int):
break
x + 'a'
x = foo()
x + 'a' # E: Unsupported operand types for + ("int" and "str") \
# N: Left operand is of type "Union[int, str]"
if isinstance(x, int):
break
x + 'a'
x = foo()
x + 'a' # E: Unsupported operand types for + ("int" and "str") \
# N: Left operand is of type "Union[int, str]"
if isinstance(x, int):
break
x + 'a'
x + 'a' # E: Unsupported operand types for + ("int" and "str") \
# N: Left operand is of type "Union[int, str]"
[builtins fixtures/isinstancelist.pyi]
[case testModifyRepeatedly]
from typing import Union
def foo() -> Union[int, str]: pass
x = foo()
def f(): x # Prevent redefinition
x + 1 # E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[int, str]"
x + 'a' # E: Unsupported operand types for + ("int" and "str") \
# N: Left operand is of type "Union[int, str]"
x = 1
x + 1
x + 'a' # E: Unsupported operand types for + ("int" and "str")
x = 'a'
x + 1 # E: Unsupported operand types for + ("str" and "int")
x + 'a'
x = foo()
x + 1 # E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[int, str]"
x + 'a' # E: Unsupported operand types for + ("int" and "str") \
# N: Left operand is of type "Union[int, str]"
[builtins fixtures/isinstancelist.pyi]
[case testModifyLoop]
from typing import Union
def foo() -> Union[int, str]: pass
x = foo()
def f(): x # Prevent redefinition
x + 1 # E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[int, str]"
x = 'a'
x + 1 # E: Unsupported operand types for + ("str" and "int")
x = 1
x + 1
while bool():
x + 1 # E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[int, str]"
x = 'a'
[builtins fixtures/isinstancelist.pyi]
[case testModifyLoop2]
from typing import Union
def foo() -> Union[int, str]: pass
x = foo()
def f(): x # Prevent redefinition
x + 1 # E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[int, str]"
x = 'a'
x + 1 # E: Unsupported operand types for + ("str" and "int")
x = 1
x + 1
for i in [1]:
x = 'a'
x + 1 # E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[int, str]"
[builtins fixtures/isinstancelist.pyi]
[case testModifyLoop3]
from typing import Union
def foo() -> Union[int, str]: pass
x = foo()
def f(): x # Prevent redefinition
x = 1
while bool():
x + 1
x = 'a'
break
else:
x + 1
x + 1 # E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[int, str]"
x = 1
for y in [1]:
x + 1
x = 'a'
break
else:
x + 1
x + 1 # E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[int, str]"
[builtins fixtures/isinstancelist.pyi]
[case testModifyLoopWhile4]
from typing import Union
def foo() -> Union[int, str]: pass
x = foo()
def f(): x # Prevent redefinition
x = 1
while bool():
x + 1
if bool():
x = 'a'
break
else:
x + 1
x = 'a'
x + 'a'
x = 1
while bool():
x + 1 # E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[int, str]"
if bool():
x = 'a'
continue
else:
x + 1 # E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[int, str]"
x = 'a'
x + 'a'
[builtins fixtures/isinstancelist.pyi]
[case testModifyLoopFor4]
from typing import Union
def foo() -> Union[int, str]: pass
x = foo()
def f(): x # Prevent redefinition
x = 1
for y in [1]:
x + 1
if bool():
x = 'a'
break
else:
x + 1
x = 'a'
x + 'a'
x = 1
for y in [1]:
x + 1 # E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[int, str]"
if bool():
x = 'a'
continue
else:
x + 1 # E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[int, str]"
x = 'a'
x + 'a'
[builtins fixtures/isinstancelist.pyi]
[case testModifyNestedLoop]
from typing import Union
def foo() -> Union[int, str]: pass
x = foo()
def f(): x # Prevent redefinition
x = 1
for y in [1]:
for z in [1]:
break
else:
x = 'a'
break
else:
x + 1
x + 1 # E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[int, str]"
x = 1
while bool():
while bool():
break
else:
x = 'a'
break
else:
x + 1
x + 1 # E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[int, str]"
[builtins fixtures/isinstancelist.pyi]
[case testModifyLoopLong]
from typing import Union
class A: a = 1
def foo() -> Union[int, str, A]: pass
def bar() -> None:
x = foo()
x + 1 # E: Unsupported left operand type for + ("A") \
# E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[int, str, A]"
if isinstance(x, A):
x.a
else:
if isinstance(x, int):
x + 1
x + 'a' # E: Unsupported operand types for + ("int" and "str")
else:
x + 'a'
x.a # E: "str" has no attribute "a"
x = A()
if isinstance(x, str):
x + 'a'
else:
while bool():
if isinstance(x, int):
x + 1
else:
x.a
break
while bool():
if isinstance(x, int):
x + 1
else:
x.a
continue
while bool():
if isinstance(x, int):
x + 1
else:
x.a # E: Item "str" of "Union[str, A]" has no attribute "a"
x = 'a'
[builtins fixtures/isinstancelist.pyi]
[case testWhileExitCondition1]
from typing import Union
x = 1 # type: Union[int, str]
while isinstance(x, int):
if bool():
continue
x = 'a'
else:
reveal_type(x) # N: Revealed type is 'builtins.str'
reveal_type(x) # N: Revealed type is 'builtins.str'
[builtins fixtures/isinstance.pyi]
[case testWhileExitCondition2]
from typing import Union
x = 1 # type: Union[int, str]
while isinstance(x, int):
if bool():
break
x = 'a'
else:
reveal_type(x) # N: Revealed type is 'builtins.str'
reveal_type(x) # N: Revealed type is 'Union[builtins.int, builtins.str]'
[builtins fixtures/isinstance.pyi]
[case testWhileLinkedList]
from typing import Union
LinkedList = Union['Cons', 'Nil']
class Nil: pass
class Cons:
tail = None # type: LinkedList
def last(x: LinkedList) -> Nil:
while isinstance(x, Cons):
x = x.tail
return x
[builtins fixtures/isinstance.pyi]
[case testReturnAndFlow]
def foo() -> int:
return 1 and 2
return 'a'
[case testCastIsinstance]
from typing import Union
def foo() -> Union[int, str]: pass
x = foo()
y = 1 # type: int
if isinstance(x, str):
x = y
x + 1
x + 'a' # E: Unsupported operand types for + ("int" and "str")
[builtins fixtures/isinstancelist.pyi]
[case testUnreachableCode]
x = 1 # type: int
while bool():
x = 'a' # E: Incompatible types in assignment (expression has type "str", variable has type "int")
break
x = 'a' # Note: no error because unreachable code
[builtins fixtures/isinstancelist.pyi]
[case testUnreachableCode2]
x = 1
while bool():
try:
pass
except:
continue
else:
continue
x + 'a'
[builtins fixtures/isinstance.pyi]
[case testUnreachableWhileTrue]
def f(x: int) -> None:
while True:
if x:
return
1()
[builtins fixtures/bool.pyi]
[case testUnreachableAssertFalse]
def f() -> None:
assert False
1()
[builtins fixtures/bool.pyi]
[case testUnreachableAssertFalse2]
def f() -> None:
# The old parser doesn't understand the syntax below
assert False, "hi"
1()
[builtins fixtures/bool.pyi]
[case testUnreachableReturnOrAssertFalse]
def f(x: int) -> int:
if x:
return x
else:
assert False
1()
[builtins fixtures/bool.pyi]
[case testUnreachableTryExcept]
def f() -> None:
try:
f()
return
except BaseException:
return
1()
[builtins fixtures/exception.pyi]
[case testUnreachableTryExceptElse]
def f() -> None:
try:
f()
except BaseException:
return
else:
return
1()
[builtins fixtures/exception.pyi]
[case testUnreachableTryReturnFinally1]
def f() -> None:
try:
return
finally:
pass
1()
[case testUnreachableTryReturnFinally2]
def f() -> None:
try:
pass
finally:
return
1()
[case testUnreachableTryReturnExceptRaise]
def f() -> None:
try:
return
except:
raise
1()
[case testUnreachableReturnLambda]
from typing import Callable
def g(t: Callable[[int], int]) -> int: pass
def f() -> int:
return g(lambda x: x)
1()
[case testIsinstanceAnd]
class A: pass
class B(A):
flag = 1
x = B() # type: A
if isinstance(x, B) and 1:
x.flag
[builtins fixtures/isinstancelist.pyi]
[case testIsinstanceShortcircuit]
class A:
pass
class B(A):
flag = 1
x = B() # type: A
if isinstance(x, B) and x.flag:
pass
if isinstance(x, B) or x.flag: # E: "A" has no attribute "flag"
pass
if not isinstance(x, B) or x.flag:
pass
if not isinstance(x, B) and x.flag: # E: "A" has no attribute "flag"
pass
[builtins fixtures/isinstancelist.pyi]
[case testIsinstanceExpression]
class A:
pass
class B(A):
flag = 1
x = B() # type: A
x.flag if isinstance(x, B) else 0
0 if not isinstance(x, B) else x.flag
0 if isinstance(x, B) else x.flag # E: "A" has no attribute "flag"
[builtins fixtures/isinstancelist.pyi]
[case testIsinstanceMultiAnd]
class A: pass
class B(A):
flag = 1
class C(A):
glaf = 1
x = B() # type: A
y = C() # type: A
if isinstance(x, B) and isinstance(y, C):
x.flag += 1
y.glaf += 1
x() # E: "B" not callable
y() # E: "C" not callable
else:
x() # E: "A" not callable
y() # E: "A" not callable
[builtins fixtures/isinstancelist.pyi]
[case testIsinstanceMultiAndSpecialCase]
class A: pass
class B(A):
flag = 1
class C(A):
glaf = 1
x = B() # type: A
y = C() # type: A
if isinstance(x, B) and isinstance(y, int):
1() # type checking skipped
if isinstance(y, int) and isinstance(x, B):
1() # type checking skipped
if isinstance(y, int) and y > 42:
1() # type checking skipped
[builtins fixtures/isinstancelist.pyi]
[case testReturnWithCallExprAndIsinstance]
from typing import Union
def f(x: Union[int, str]) -> None:
if not isinstance(x, int):
return foo()
x() # E: "int" not callable
def foo(): pass
[builtins fixtures/isinstancelist.pyi]
[case testIsinstanceOr1]
from typing import Optional
def f(a: bool, x: object) -> Optional[int]:
if a or not isinstance(x, int):
return None
reveal_type(x) # N: Revealed type is 'builtins.int'
return x
[builtins fixtures/isinstance.pyi]
[case testIsinstanceOr2]
from typing import Optional
def g(a: bool, x: object) -> Optional[int]:
if not isinstance(x, int) or a:
return None
reveal_type(x) # N: Revealed type is 'builtins.int'
return x
[builtins fixtures/isinstance.pyi]
[case testIsinstanceOr3]
from typing import Optional
def h(a: bool, x: object) -> Optional[int]:
if a or isinstance(x, int):
return None
return x # E: Incompatible return value type (got "object", expected "Optional[int]")
[builtins fixtures/isinstance.pyi]
[case testIsinstanceWithOverlappingUnionType]
from typing import Union
def f(x: Union[float, int]) -> None:
if isinstance(x, float):
pass
if not isinstance(x, int):
f(x)
[builtins fixtures/isinstance.pyi]
[case testIsinstanceWithOverlappingUnionType2]
from typing import Union
class A: pass
class B(A): pass
def f(x: Union[A, B]) -> None:
if isinstance(x, A):
pass
if not isinstance(x, B):
f(x)
[builtins fixtures/isinstance.pyi]
[case testIsinstanceWithOverlappingPromotionTypes-skip]
# Currently disabled: see https://github.com/python/mypy/issues/6180 for context
from typing import Union
class FloatLike: pass
class IntLike(FloatLike): pass
def f1(x: Union[float, int]) -> None:
# We ignore promotions in isinstance checks
if isinstance(x, float):
reveal_type(x) # N: Revealed type is 'builtins.float'
else:
reveal_type(x) # N: Revealed type is 'builtins.int'
def f2(x: Union[FloatLike, IntLike]) -> None:
# ...but not regular subtyping relationships
if isinstance(x, FloatLike):
reveal_type(x) # N: Revealed type is 'Union[__main__.FloatLike, __main__.IntLike]'
[builtins fixtures/isinstance.pyi]
[case testIsinstanceOfSuperclass]
class A: pass
class B(A): pass
x = B()
if isinstance(x, A):
reveal_type(x) # N: Revealed type is '__main__.B'
if not isinstance(x, A):
reveal_type(x) # unreachable
x = A()
reveal_type(x) # N: Revealed type is '__main__.B'
[builtins fixtures/isinstance.pyi]
[case testIsinstanceOfNonoverlapping]
class A: pass
class B: pass
x = B()
if isinstance(x, A):
reveal_type(x) # unreachable
else:
reveal_type(x) # N: Revealed type is '__main__.B'
reveal_type(x) # N: Revealed type is '__main__.B'
[builtins fixtures/isinstance.pyi]
[case testAssertIsinstance]
def f(x: object):
assert isinstance(x, int)
y = 0 # type: int
y = x
[builtins fixtures/isinstance.pyi]
[case testUnionAssertIsinstance]
from typing import Union
def f(x: Union[str, int]):
assert isinstance(x, int)
y = 0 # type: int
y = x
[builtins fixtures/isinstance.pyi]
[case testAnyAssertIsinstance]
from typing import Any
def f(x: Any):
assert isinstance(x, int) # this should narrow x to type int
x + "foo" # E: Unsupported operand types for + ("int" and "str")
[builtins fixtures/isinstance.pyi]
[case testIsinstanceOfGenericClassRetainsParameters]
from typing import List, Union
def f(x: Union[List[int], str]) -> None:
if isinstance(x, list):
x[0]() # E: "int" not callable
else:
reveal_type(x) # N: Revealed type is 'builtins.str'
reveal_type(x) # N: Revealed type is 'Union[builtins.list[builtins.int], builtins.str]'
[builtins fixtures/isinstancelist.pyi]
[case testIsinstanceOrIsinstance]
class A: pass
class B(A):
flag = 1
class C(A):
flag = 2
x1 = A()
if isinstance(x1, B) or isinstance(x1, C):
reveal_type(x1) # N: Revealed type is 'Union[__main__.B, __main__.C]'
f = x1.flag # type: int
else:
reveal_type(x1) # N: Revealed type is '__main__.A'
f = 0
reveal_type(x1) # N: Revealed type is '__main__.A'
x2 = A()
if isinstance(x2, A) or isinstance(x2, C):
reveal_type(x2) # N: Revealed type is '__main__.A'
f = x2.flag # E: "A" has no attribute "flag"
else:
# unreachable
1()
reveal_type(x2) # N: Revealed type is '__main__.A'
[builtins fixtures/isinstance.pyi]
[case testComprehensionIsInstance]
from typing import List, Union
a = [] # type: List[Union[int, str]]
l = [x for x in a if isinstance(x, int)]
g = (x for x in a if isinstance(x, int))
d = {0: x for x in a if isinstance(x, int)}
reveal_type(l) # N: Revealed type is 'builtins.list[builtins.int*]'
reveal_type(g) # N: Revealed type is 'typing.Generator[builtins.int*, None, None]'
reveal_type(d) # N: Revealed type is 'builtins.dict[builtins.int*, builtins.int*]'
[builtins fixtures/isinstancelist.pyi]
[case testIsinstanceInWrongOrderInBooleanOp]
class A:
m = 1
def f(x: object) -> None:
if x.m and isinstance(x, A) or False: # E: "object" has no attribute "m"
pass
[builtins fixtures/isinstance.pyi]
[case testIsinstanceAndOr]
class A:
a = None # type: A
def f(x: object) -> None:
b = isinstance(x, A) and x.a or A()
reveal_type(b) # N: Revealed type is '__main__.A'
[builtins fixtures/isinstance.pyi]
[case testIsInstanceWithUnknownType]
from typing import Union
def f(x: Union[int, str], typ: type) -> None:
if isinstance(x, (typ, int)):
x + 1 # E: Unsupported operand types for + ("str" and "int") \
# N: Left operand is of type "Union[int, str]"
reveal_type(x) # N: Revealed type is 'Union[builtins.int, builtins.str]'
else:
reveal_type(x) # N: Revealed type is 'builtins.str'
reveal_type(x) # N: Revealed type is 'Union[builtins.int, builtins.str]'
[builtins fixtures/isinstancelist.pyi]
[case testIsInstanceWithBoundedType]
from typing import Union, Type
class A: pass
def f(x: Union[int, A], a: Type[A]) -> None:
if isinstance(x, (a, int)):
reveal_type(x) # N: Revealed type is 'Union[builtins.int, __main__.A]'
else:
reveal_type(x) # N: Revealed type is '__main__.A'
reveal_type(x) # N: Revealed type is 'Union[builtins.int, __main__.A]'
[builtins fixtures/isinstancelist.pyi]
[case testIsInstanceWithEmtpy2ndArg]
from typing import Union
def f(x: Union[int, str]) -> None:
if isinstance(x, ()):
reveal_type(x) # N: Revealed type is 'Union[builtins.int, builtins.str]'
else:
reveal_type(x) # N: Revealed type is 'Union[builtins.int, builtins.str]'
[builtins fixtures/isinstancelist.pyi]
[case testIsInstanceWithTypeObject]
from typing import Union, Type
class A: pass
def f(x: Union[int, A], a: Type[A]) -> None:
if isinstance(x, a):
reveal_type(x) # N: Revealed type is '__main__.A'
elif isinstance(x, int):
reveal_type(x) # N: Revealed type is 'builtins.int'
else:
reveal_type(x) # N: Revealed type is '__main__.A'
reveal_type(x) # N: Revealed type is 'Union[builtins.int, __main__.A]'
[builtins fixtures/isinstancelist.pyi]
[case testIssubclassUnreachable]
from typing import Type, Sequence, Union
x: Type[str]
if issubclass(x, int):
reveal_type(x) # unreachable block
class X: pass
class Y(X): pass
class Z(X): pass
a: Union[Type[Y], Type[Z]]
if issubclass(a, X):
reveal_type(a) # N: Revealed type is 'Union[Type[__main__.Y], Type[__main__.Z]]'
else:
reveal_type(a) # unreachable block
[builtins fixtures/isinstancelist.pyi]
[case testIssubclasDestructuringUnions1]
from typing import Union, List, Tuple, Dict, Type
def f(x: Union[Type[int], Type[str], Type[List]]) -> None:
if issubclass(x, (str, (int,))):
reveal_type(x) # N: Revealed type is 'Union[Type[builtins.int], Type[builtins.str]]'
reveal_type(x()) # N: Revealed type is 'Union[builtins.int, builtins.str]'
x()[1] # E: Value of type "Union[int, str]" is not indexable
else:
reveal_type(x) # N: Revealed type is 'Type[builtins.list[Any]]'
reveal_type(x()) # N: Revealed type is 'builtins.list[Any]'
x()[1]
reveal_type(x) # N: Revealed type is 'Union[Type[builtins.int], Type[builtins.str], Type[builtins.list[Any]]]'
reveal_type(x()) # N: Revealed type is 'Union[builtins.int, builtins.str, builtins.list[Any]]'
if issubclass(x, (str, (list,))):
reveal_type(x) # N: Revealed type is 'Union[Type[builtins.str], Type[builtins.list[Any]]]'
reveal_type(x()) # N: Revealed type is 'Union[builtins.str, builtins.list[Any]]'
x()[1]
reveal_type(x) # N: Revealed type is 'Union[Type[builtins.int], Type[builtins.str], Type[builtins.list[Any]]]'
reveal_type(x()) # N: Revealed type is 'Union[builtins.int, builtins.str, builtins.list[Any]]'
[builtins fixtures/isinstancelist.pyi]
[case testIssubclasDestructuringUnions2]
from typing import Union, List, Tuple, Dict, Type
def f(x: Type[Union[int, str, List]]) -> None:
if issubclass(x, (str, (int,))):
reveal_type(x) # N: Revealed type is 'Union[Type[builtins.int], Type[builtins.str]]'
reveal_type(x()) # N: Revealed type is 'Union[builtins.int, builtins.str]'
x()[1] # E: Value of type "Union[int, str]" is not indexable
else:
reveal_type(x) # N: Revealed type is 'Type[builtins.list[Any]]'
reveal_type(x()) # N: Revealed type is 'builtins.list[Any]'
x()[1]
reveal_type(x) # N: Revealed type is 'Union[Type[builtins.int], Type[builtins.str], Type[builtins.list[Any]]]'
reveal_type(x()) # N: Revealed type is 'Union[builtins.int, builtins.str, builtins.list[Any]]'
if issubclass(x, (str, (list,))):
reveal_type(x) # N: Revealed type is 'Union[Type[builtins.str], Type[builtins.list[Any]]]'
reveal_type(x()) # N: Revealed type is 'Union[builtins.str, builtins.list[Any]]'
x()[1]
reveal_type(x) # N: Revealed type is 'Union[Type[builtins.int], Type[builtins.str], Type[builtins.list[Any]]]'
reveal_type(x()) # N: Revealed type is 'Union[builtins.int, builtins.str, builtins.list[Any]]'
[builtins fixtures/isinstancelist.pyi]
[case testIssubclasDestructuringUnions3]
from typing import Union, List, Tuple, Dict, Type
def f(x: Type[Union[int, str, List]]) -> None:
reveal_type(x) # N: Revealed type is 'Union[Type[builtins.int], Type[builtins.str], Type[builtins.list[Any]]]'
reveal_type(x()) # N: Revealed type is 'Union[builtins.int, builtins.str, builtins.list[Any]]'
if issubclass(x, (str, (int,))):
reveal_type(x) # N: Revealed type is 'Union[Type[builtins.int], Type[builtins.str]]'
reveal_type(x()) # N: Revealed type is 'Union[builtins.int, builtins.str]'
x()[1] # E: Value of type "Union[int, str]" is not indexable
else:
reveal_type(x) # N: Revealed type is 'Type[builtins.list[Any]]'
reveal_type(x()) # N: Revealed type is 'builtins.list[Any]'
x()[1]
reveal_type(x) # N: Revealed type is 'Union[Type[builtins.int], Type[builtins.str], Type[builtins.list[Any]]]'
reveal_type(x()) # N: Revealed type is 'Union[builtins.int, builtins.str, builtins.list[Any]]'
if issubclass(x, (str, (list,))):
reveal_type(x) # N: Revealed type is 'Union[Type[builtins.str], Type[builtins.list[Any]]]'
reveal_type(x()) # N: Revealed type is 'Union[builtins.str, builtins.list[Any]]'
x()[1]
reveal_type(x) # N: Revealed type is 'Union[Type[builtins.int], Type[builtins.str], Type[builtins.list[Any]]]'
reveal_type(x()) # N: Revealed type is 'Union[builtins.int, builtins.str, builtins.list[Any]]'
[builtins fixtures/isinstancelist.pyi]
[case testIssubclass]
from typing import Type, ClassVar
class Goblin:
level: int
class GoblinAmbusher(Goblin):
job: ClassVar[str] = 'Ranger'
def test_issubclass(cls: Type[Goblin]) -> None:
if issubclass(cls, GoblinAmbusher):
reveal_type(cls) # N: Revealed type is 'Type[__main__.GoblinAmbusher]'
cls.level
cls.job
ga = cls()
ga.level = 15
ga.job
ga.job = "Warrior" # E: Cannot assign to class variable "job" via instance
else:
reveal_type(cls) # N: Revealed type is 'Type[__main__.Goblin]'
cls.level
cls.job # E: "Type[Goblin]" has no attribute "job"
g = cls()
g.level = 15
g.job # E: "Goblin" has no attribute "job"
[builtins fixtures/isinstancelist.pyi]
[case testIssubclassDeepHierarchy]
from typing import Type, ClassVar
class Mob: pass
class Goblin(Mob):
level: int
class GoblinAmbusher(Goblin):
job: ClassVar[str] = 'Ranger'
def test_issubclass(cls: Type[Mob]) -> None:
if issubclass(cls, Goblin):
reveal_type(cls) # N: Revealed type is 'Type[__main__.Goblin]'
cls.level
cls.job # E: "Type[Goblin]" has no attribute "job"
g = cls()
g.level = 15
g.job # E: "Goblin" has no attribute "job"
if issubclass(cls, GoblinAmbusher):
reveal_type(cls) # N: Revealed type is 'Type[__main__.GoblinAmbusher]'
cls.level
cls.job
g = cls()
g.level = 15
g.job
g.job = 'Warrior' # E: Cannot assign to class variable "job" via instance
else:
reveal_type(cls) # N: Revealed type is 'Type[__main__.Mob]'
cls.job # E: "Type[Mob]" has no attribute "job"
cls.level # E: "Type[Mob]" has no attribute "level"
m = cls()
m.level = 15 # E: "Mob" has no attribute "level"
m.job # E: "Mob" has no attribute "job"
if issubclass(cls, GoblinAmbusher):
reveal_type(cls) # N: Revealed type is 'Type[__main__.GoblinAmbusher]'
cls.job
cls.level
ga = cls()
ga.level = 15
ga.job
ga.job = 'Warrior' # E: Cannot assign to class variable "job" via instance
if issubclass(cls, GoblinAmbusher):
reveal_type(cls) # N: Revealed type is 'Type[__main__.GoblinAmbusher]'
cls.level
cls.job
ga = cls()
ga.level = 15
ga.job
ga.job = "Warrior" # E: Cannot assign to class variable "job" via instance
[builtins fixtures/isinstancelist.pyi]
[case testIssubclassTuple]
from typing import Type, ClassVar
class Mob: pass
class Goblin(Mob):
level: int
class GoblinAmbusher(Goblin):
job: ClassVar[str] = 'Ranger'
class GoblinDigger(Goblin):
job: ClassVar[str] = 'Thief'
def test_issubclass(cls: Type[Mob]) -> None:
if issubclass(cls, (Goblin, GoblinAmbusher)):
reveal_type(cls) # N: Revealed type is 'Type[__main__.Goblin]'
cls.level
cls.job # E: "Type[Goblin]" has no attribute "job"
g = cls()
g.level = 15
g.job # E: "Goblin" has no attribute "job"
if issubclass(cls, GoblinAmbusher):
cls.level
reveal_type(cls) # N: Revealed type is 'Type[__main__.GoblinAmbusher]'
cls.job
ga = cls()
ga.level = 15
ga.job
ga.job = "Warrior" # E: Cannot assign to class variable "job" via instance
else:
reveal_type(cls) # N: Revealed type is 'Type[__main__.Mob]'
cls.job # E: "Type[Mob]" has no attribute "job"
cls.level # E: "Type[Mob]" has no attribute "level"
m = cls()
m.level = 15 # E: "Mob" has no attribute "level"
m.job # E: "Mob" has no attribute "job"
if issubclass(cls, GoblinAmbusher):
reveal_type(cls) # N: Revealed type is 'Type[__main__.GoblinAmbusher]'
cls.job
cls.level
ga = cls()
ga.level = 15
ga.job
ga.job = "Warrior" # E: Cannot assign to class variable "job" via instance
if issubclass(cls, (GoblinDigger, GoblinAmbusher)):
reveal_type(cls) # N: Revealed type is 'Union[Type[__main__.GoblinDigger], Type[__main__.GoblinAmbusher]]'
cls.level
cls.job
g = cls()
g.level = 15
g.job
g.job = "Warrior" # E: Cannot assign to class variable "job" via instance
[builtins fixtures/isinstancelist.pyi]
[case testIssubclassBuiltins]
from typing import List, Type
class MyList(List): pass
class MyIntList(List[int]): pass
def f(cls: Type[object]) -> None:
if issubclass(cls, MyList):
reveal_type(cls) # N: Revealed type is 'Type[__main__.MyList]'
cls()[0]
else:
reveal_type(cls) # N: Revealed type is 'Type[builtins.object]'
cls()[0] # E: Value of type "object" is not indexable
if issubclass(cls, MyIntList):
reveal_type(cls) # N: Revealed type is 'Type[__main__.MyIntList]'
cls()[0] + 1
[builtins fixtures/isinstancelist.pyi]
[case testIsinstanceTypeArgs]
from typing import Iterable, TypeVar
x = 1
T = TypeVar('T')
isinstance(x, Iterable)
isinstance(x, Iterable[int]) # E: Parameterized generics cannot be used with class or instance checks
isinstance(x, Iterable[T]) # E: Parameterized generics cannot be used with class or instance checks
isinstance(x, (int, Iterable[int])) # E: Parameterized generics cannot be used with class or instance checks
isinstance(x, (int, (str, Iterable[int]))) # E: Parameterized generics cannot be used with class or instance checks
[builtins fixtures/isinstancelist.pyi]
[typing fixtures/typing-full.pyi]
[case testIsinstanceAnyAlias]
from typing import Any
A = Any
isinstance(object(), A) # E: Cannot use isinstance() with Any type
[builtins fixtures/isinstance.pyi]
[case testIsinstanceTypeArgsAliases]
from typing import Iterable, TypeVar
x = 1
T = TypeVar('T')
It = Iterable
It2 = Iterable[T]
isinstance(x, It[int]) # E: Parameterized generics cannot be used with class or instance checks
isinstance(x, It)
isinstance(x, It2[int]) # E: Parameterized generics cannot be used with class or instance checks
isinstance(x, It2) # E: Parameterized generics cannot be used with class or instance checks
[builtins fixtures/isinstance.pyi]
[typing fixtures/typing-full.pyi]
[case testIssubclassTypeArgs]
from typing import Iterable, TypeVar
x = int
T = TypeVar('T')
issubclass(x, Iterable)
issubclass(x, Iterable[int]) # E: Parameterized generics cannot be used with class or instance checks
issubclass(x, Iterable[T]) # E: Parameterized generics cannot be used with class or instance checks
issubclass(x, (int, Iterable[int])) # E: Parameterized generics cannot be used with class or instance checks
[builtins fixtures/isinstance.pyi]
[typing fixtures/typing-full.pyi]
[case testIsinstanceAndNarrowTypeVariable]
from typing import TypeVar
class A: pass
class B(A): pass
T = TypeVar('T', bound=A)
def f(x: T) -> None:
if isinstance(x, B):
reveal_type(x) # N: Revealed type is '__main__.B'
else:
reveal_type(x) # N: Revealed type is 'T`-1'
reveal_type(x) # N: Revealed type is 'T`-1'
[builtins fixtures/isinstance.pyi]
[case testIsinstanceAndTypeType]
from typing import Type
def f(x: Type[int]) -> None:
if isinstance(x, type):
reveal_type(x) # N: Revealed type is 'Type[builtins.int]'
else:
reveal_type(x) # Unreachable
reveal_type(x) # N: Revealed type is 'Type[builtins.int]'
[builtins fixtures/isinstance.pyi]
[case testIsinstanceVariableSubstitution]
T = (int, str)
U = (list, T)
x: object = None
if isinstance(x, T):
reveal_type(x) # N: Revealed type is 'Union[builtins.int, builtins.str]'
if isinstance(x, U):
reveal_type(x) # N: Revealed type is 'Union[builtins.list[Any], builtins.int, builtins.str]'
if isinstance(x, (set, (list, T))):
reveal_type(x) # N: Revealed type is 'Union[builtins.set[Any], builtins.list[Any], builtins.int, builtins.str]'
[builtins fixtures/isinstancelist.pyi]
[case testIsInstanceTooFewArgs]
isinstance() # E: Too few arguments for "isinstance"
x: object
if isinstance(): # E: Too few arguments for "isinstance"
x = 1
reveal_type(x) # N: Revealed type is 'builtins.int'
if isinstance(x): # E: Too few arguments for "isinstance"
x = 1
reveal_type(x) # N: Revealed type is 'builtins.int'
[builtins fixtures/isinstancelist.pyi]
[case testIsSubclassTooFewArgs]
from typing import Type
issubclass() # E: Too few arguments for "issubclass"
y: Type[object]
if issubclass(): # E: Too few arguments for "issubclass"
reveal_type(y) # N: Revealed type is 'Type[builtins.object]'
if issubclass(y): # E: Too few arguments for "issubclass"
reveal_type(y) # N: Revealed type is 'Type[builtins.object]'
[builtins fixtures/isinstancelist.pyi]
[case testIsInstanceTooManyArgs]
isinstance(1, 1, 1) # E: Too many arguments for "isinstance" \
# E: Argument 2 to "isinstance" has incompatible type "int"; expected "Union[type, Tuple[Any, ...]]"
x: object
if isinstance(x, str, 1): # E: Too many arguments for "isinstance"
reveal_type(x) # N: Revealed type is 'builtins.object'
x = 1
reveal_type(x) # N: Revealed type is 'builtins.int'
[builtins fixtures/isinstancelist.pyi]
[case testIsinstanceNarrowAny]
from typing import Any
def narrow_any_to_str_then_reassign_to_int() -> None:
v = 1 # type: Any
if isinstance(v, str):
reveal_type(v) # N: Revealed type is 'builtins.str'
v = 2
reveal_type(v) # N: Revealed type is 'Any'
[builtins fixtures/isinstance.pyi]
[case testNarrowTypeAfterInList]
# flags: --strict-optional
from typing import List, Optional
x: List[int]
y: Optional[int]
if y in x:
reveal_type(y) # N: Revealed type is 'builtins.int'
else:
reveal_type(y) # N: Revealed type is 'Union[builtins.int, None]'
if y not in x:
reveal_type(y) # N: Revealed type is 'Union[builtins.int, None]'
else:
reveal_type(y) # N: Revealed type is 'builtins.int'
[builtins fixtures/list.pyi]
[out]
[case testNarrowTypeAfterInListOfOptional]
# flags: --strict-optional
from typing import List, Optional
x: List[Optional[int]]
y: Optional[int]
if y not in x:
reveal_type(y) # N: Revealed type is 'Union[builtins.int, None]'
else:
reveal_type(y) # N: Revealed type is 'Union[builtins.int, None]'
[builtins fixtures/list.pyi]
[out]
[case testNarrowTypeAfterInListNonOverlapping]
# flags: --strict-optional
from typing import List, Optional
x: List[str]
y: Optional[int]
if y in x:
reveal_type(y) # N: Revealed type is 'Union[builtins.int, None]'
else:
reveal_type(y) # N: Revealed type is 'Union[builtins.int, None]'
[builtins fixtures/list.pyi]
[out]
[case testNarrowTypeAfterInListNested]
# flags: --strict-optional
from typing import List, Optional, Any
x: Optional[int]
lst: Optional[List[int]]
nested_any: List[List[Any]]
if lst in nested_any:
reveal_type(lst) # N: Revealed type is 'builtins.list[builtins.int]'
if x in nested_any:
reveal_type(x) # N: Revealed type is 'Union[builtins.int, None]'
[builtins fixtures/list.pyi]
[out]
[case testNarrowTypeAfterInTuple]
# flags: --strict-optional
from typing import Optional
class A: pass
class B(A): pass
class C(A): pass
y: Optional[B]
if y in (B(), C()):
reveal_type(y) # N: Revealed type is '__main__.B'
else:
reveal_type(y) # N: Revealed type is 'Union[__main__.B, None]'
[builtins fixtures/tuple.pyi]
[out]
[case testNarrowTypeAfterInNamedTuple]
# flags: --strict-optional
from typing import NamedTuple, Optional
class NT(NamedTuple):
x: int
y: int
nt: NT
y: Optional[int]
if y not in nt:
reveal_type(y) # N: Revealed type is 'Union[builtins.int, None]'
else:
reveal_type(y) # N: Revealed type is 'builtins.int'
[builtins fixtures/tuple.pyi]
[out]
[case testNarrowTypeAfterInDict]
# flags: --strict-optional
from typing import Dict, Optional
x: Dict[str, int]
y: Optional[str]
if y in x:
reveal_type(y) # N: Revealed type is 'builtins.str'
else:
reveal_type(y) # N: Revealed type is 'Union[builtins.str, None]'
if y not in x:
reveal_type(y) # N: Revealed type is 'Union[builtins.str, None]'
else:
reveal_type(y) # N: Revealed type is 'builtins.str'
[builtins fixtures/dict.pyi]
[out]
[case testNarrowTypeAfterInList_python2]
# flags: --strict-optional
from typing import List, Optional
x = [] # type: List[int]
y = None # type: Optional[int]
# TODO: Fix running tests on Python 2: "Iterator[int]" has no attribute "next"
if y in x: # type: ignore
reveal_type(y) # N: Revealed type is 'builtins.int'
else:
reveal_type(y) # N: Revealed type is 'Union[builtins.int, None]'
if y not in x: # type: ignore
reveal_type(y) # N: Revealed type is 'Union[builtins.int, None]'
else:
reveal_type(y) # N: Revealed type is 'builtins.int'
[builtins_py2 fixtures/python2.pyi]
[out]
[case testNarrowTypeAfterInNoAnyOrObject]
# flags: --strict-optional
from typing import Any, List, Optional
x: List[Any]
z: List[object]
y: Optional[int]
if y in x:
reveal_type(y) # N: Revealed type is 'Union[builtins.int, None]'
else:
reveal_type(y) # N: Revealed type is 'Union[builtins.int, None]'
if y not in z:
reveal_type(y) # N: Revealed type is 'Union[builtins.int, None]'
else:
reveal_type(y) # N: Revealed type is 'Union[builtins.int, None]'
[typing fixtures/typing-full.pyi]
[builtins fixtures/list.pyi]
[out]
[case testNarrowTypeAfterInUserDefined]
# flags: --strict-optional
from typing import Container, Optional
class C(Container[int]):
def __contains__(self, item: object) -> bool:
return item is 'surprise'
y: Optional[int]
# We never trust user defined types
if y in C():
reveal_type(y) # N: Revealed type is 'Union[builtins.int, None]'
else:
reveal_type(y) # N: Revealed type is 'Union[builtins.int, None]'
if y not in C():
reveal_type(y) # N: Revealed type is 'Union[builtins.int, None]'
else:
reveal_type(y) # N: Revealed type is 'Union[builtins.int, None]'
[typing fixtures/typing-full.pyi]
[builtins fixtures/list.pyi]
[out]
[case testNarrowTypeAfterInSet]
# flags: --strict-optional
from typing import Optional, Set
s: Set[str]
y: Optional[str]
if y in {'a', 'b', 'c'}:
reveal_type(y) # N: Revealed type is 'builtins.str'
else:
reveal_type(y) # N: Revealed type is 'Union[builtins.str, None]'
if y not in s:
reveal_type(y) # N: Revealed type is 'Union[builtins.str, None]'
else:
reveal_type(y) # N: Revealed type is 'builtins.str'
[builtins fixtures/set.pyi]
[out]
[case testNarrowTypeAfterInTypedDict]
# flags: --strict-optional
from typing import Optional
from mypy_extensions import TypedDict
class TD(TypedDict):
a: int
b: str
td: TD
def f() -> None:
x: Optional[str]
if x not in td:
return
reveal_type(x) # N: Revealed type is 'builtins.str'
[typing fixtures/typing-full.pyi]
[builtins fixtures/dict.pyi]
[out]
[case testIsinstanceWidensWithAnyArg]
from typing import Any
class A: ...
B: Any
x: A
x.foo() # E: "A" has no attribute "foo"
assert isinstance(x, B)
x.foo()
reveal_type(x) # N: Revealed type is 'Any'
[builtins fixtures/isinstance.pyi]
[case testIsinstanceWidensUnionWithAnyArg]
from typing import Any, Union
class A: ...
B: Any
x: Union[A, B]
reveal_type(x) # N: Revealed type is 'Union[__main__.A, Any]'
assert isinstance(x, B)
reveal_type(x) # N: Revealed type is 'Any'
[builtins fixtures/isinstance.pyi]
[case testIsinstanceIgnoredImport]
from typing import Union
from foo import A # type: ignore
def f(x: Union[A, str]) -> None:
x.method_only_in_a() # E: Item "str" of "Union[Any, str]" has no attribute "method_only_in_a"
if isinstance(x, A):
x.method_only_in_a()
[builtins fixtures/isinstance.pyi]
[case testIsinstanceIgnoredImportDualAny]
from typing import Any
from foo import Bad, OtherBad # type: ignore
x: Any
if isinstance(x, Bad):
reveal_type(x) # N: Revealed type is 'Any'
else:
reveal_type(x) # N: Revealed type is 'Any'
if isinstance(x, (Bad, OtherBad)):
reveal_type(x) # N: Revealed type is 'Any'
else:
reveal_type(x) # N: Revealed type is 'Any'
y: object
if isinstance(y, Bad):
reveal_type(y) # N: Revealed type is 'Any'
else:
reveal_type(y) # N: Revealed type is 'builtins.object'
class Ok: pass
z: Any
if isinstance(z, Ok):
reveal_type(z) # N: Revealed type is '__main__.Ok'
else:
reveal_type(z) # N: Revealed type is 'Any'
[builtins fixtures/isinstance.pyi]
[case testIsInstanceInitialNoneCheckSkipsImpossibleCasesNoStrictOptional]
# flags: --strict-optional
from typing import Optional, Union
class A: pass
def foo1(x: Union[A, str, None]) -> None:
if x is None:
reveal_type(x) # N: Revealed type is 'None'
elif isinstance(x, A):
reveal_type(x) # N: Revealed type is '__main__.A'
else:
reveal_type(x) # N: Revealed type is 'builtins.str'
def foo2(x: Optional[str]) -> None:
if x is None:
reveal_type(x) # N: Revealed type is 'None'
elif isinstance(x, A):
reveal_type(x)
else:
reveal_type(x) # N: Revealed type is 'builtins.str'
[builtins fixtures/isinstance.pyi]
[case testIsInstanceInitialNoneCheckSkipsImpossibleCasesInNoStrictOptional]
# flags: --no-strict-optional
from typing import Optional, Union
class A: pass
def foo1(x: Union[A, str, None]) -> None:
if x is None:
reveal_type(x) # N: Revealed type is 'None'
elif isinstance(x, A):
# Note that Union[None, A] == A in no-strict-optional
reveal_type(x) # N: Revealed type is '__main__.A'
else:
reveal_type(x) # N: Revealed type is 'builtins.str'
def foo2(x: Optional[str]) -> None:
if x is None:
reveal_type(x) # N: Revealed type is 'None'
elif isinstance(x, A):
# Mypy should, however, be able to skip impossible cases
reveal_type(x)
else:
reveal_type(x) # N: Revealed type is 'builtins.str'
[builtins fixtures/isinstance.pyi]
[case testNoneCheckDoesNotNarrowWhenUsingTypeVars]
# flags: --strict-optional
# Note: this test (and the following one) are testing checker.conditional_type_map:
# if you set the 'prohibit_none_typevar_overlap' keyword argument to False when calling
# 'is_overlapping_types', the binder will incorrectly infer that 'out' has a type of
# Union[T, None] after the if statement.
from typing import TypeVar
T = TypeVar('T')
def foo(x: T) -> T:
out = None
out = x
if out is None:
pass
return out
[builtins fixtures/isinstance.pyi]
[case testNoneCheckDoesNotNarrowWhenUsingTypeVarsNoStrictOptional]
# flags: --no-strict-optional
from typing import TypeVar
T = TypeVar('T')
def foo(x: T) -> T:
out = None
out = x
if out is None:
pass
return out
[builtins fixtures/isinstance.pyi]
[case testNoneAndGenericTypesOverlapNoStrictOptional]
# flags: --no-strict-optional
from typing import Union, Optional, List
# Note: this test is indirectly making sure meet.is_overlapping_types
# correctly ignores 'None' in unions.
def foo(x: Optional[List[str]]) -> None:
reveal_type(x) # N: Revealed type is 'Union[builtins.list[builtins.str], None]'
assert isinstance(x, list)
reveal_type(x) # N: Revealed type is 'builtins.list[builtins.str]'
def bar(x: Union[List[str], List[int], None]) -> None:
reveal_type(x) # N: Revealed type is 'Union[builtins.list[builtins.str], builtins.list[builtins.int], None]'
assert isinstance(x, list)
reveal_type(x) # N: Revealed type is 'Union[builtins.list[builtins.str], builtins.list[builtins.int]]'
[builtins fixtures/isinstancelist.pyi]
[case testNoneAndGenericTypesOverlapStrictOptional]
# flags: --strict-optional
from typing import Union, Optional, List
# This test is the same as the one above, except for strict-optional.
# It isn't testing anything explicitly and mostly exists for the sake
# of completeness.
def foo(x: Optional[List[str]]) -> None:
reveal_type(x) # N: Revealed type is 'Union[builtins.list[builtins.str], None]'
assert isinstance(x, list)
reveal_type(x) # N: Revealed type is 'builtins.list[builtins.str]'
def bar(x: Union[List[str], List[int], None]) -> None:
reveal_type(x) # N: Revealed type is 'Union[builtins.list[builtins.str], builtins.list[builtins.int], None]'
assert isinstance(x, list)
reveal_type(x) # N: Revealed type is 'Union[builtins.list[builtins.str], builtins.list[builtins.int]]'
[builtins fixtures/isinstancelist.pyi]
[case testIsInstanceWithStarExpression]
from typing import Union, List, Tuple
def f(var: Union[List[str], Tuple[str, str], str]) -> None:
reveal_type(var) # N: Revealed type is 'Union[builtins.list[builtins.str], Tuple[builtins.str, builtins.str], builtins.str]'
if isinstance(var, (list, *(str, int))):
reveal_type(var) # N: Revealed type is 'Union[builtins.list[builtins.str], builtins.str]'
[builtins fixtures/isinstancelist.pyi]
[case testIsInstanceWithStarExpressionAndVariable]
from typing import Union
def f(var: Union[int, str]) -> None:
reveal_type(var) # N: Revealed type is 'Union[builtins.int, builtins.str]'
some_types = (str, tuple)
another_type = list
if isinstance(var, (*some_types, another_type)):
reveal_type(var) # N: Revealed type is 'builtins.str'
[builtins fixtures/isinstancelist.pyi]
[case testIsInstanceWithWrongStarExpression]
var = 'some string'
if isinstance(var, *(str, int)): # E: Too many arguments for "isinstance"
pass
[builtins fixtures/isinstancelist.pyi]