blob: d6041ccf1e6c1ac8d361a1f6a70665228a5784ca [file]
[case testForcedAssignment]
x = 1 # type: object
y = 1
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 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]
[out]
[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]
[out]
[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()
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]
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:
x = 1
if x:
x = 'a'
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 + (likely involving Union)
x = foo()
if bool():
continue
x = 'a'
x = 'a'
x + 'a'
[builtins fixtures/isinstancelist.pyi]
[out]
[case testUnionTryExcept]
class A: y = A()
class B(A): z = 1
x = A()
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()
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()
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()
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()
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()
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"
[out]
[case testUnionListIsinstance]
from typing import Union, List
class A: y = A()
class B(A): z = C()
class C: pass
class D(C): d = 1
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?
x + 1 # E: Unsupported operand types for + (likely involving Union)
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 + (likely involving Union)
[builtins fixtures/isinstancelist.pyi]
[out]
[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()
x = 1
x = x + 1
x = foo()
x = x + 1 # E: Unsupported operand types for + (likely involving Union)
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 + (likely involving Union)
z = h.pet.paws + 'a' # E: Unsupported operand types for + (likely involving Union)
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: Some element of union has no attribute "method3"
[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 + (likely involving Union)
foo()
[builtins fixtures/isinstancelist.pyi]
[out]
[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 + (likely involving Union)
x + [1] # E: Unsupported operand types for + (likely involving Union)
[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" and "str")
x + [1] # E: Unsupported operand types for + (likely involving Union)
[builtins fixtures/isinstancelist.pyi]
[case testIsInstanceThreeUnion3]
from typing import Union, List
while bool():
x = None # type: Union[int, str, List[int]]
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 + (likely involving Union)
[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 + (likely involving Union)
if isinstance(x, int):
break
x + 'a'
x = foo()
x + 'a' # E: Unsupported operand types for + (likely involving Union)
if isinstance(x, int):
break
x + 'a'
x = foo()
x + 'a' # E: Unsupported operand types for + (likely involving Union)
if isinstance(x, int):
break
x + 'a'
x + 'a' # E: Unsupported operand types for + (likely involving Union)
[builtins fixtures/isinstancelist.pyi]
[case testModifyRepeatedly]
from typing import Union
def foo() -> Union[int, str]: pass
x = foo()
x + 1 # E: Unsupported operand types for + (likely involving Union)
x + 'a' # E: Unsupported operand types for + (likely involving Union)
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 + (likely involving Union)
x + 'a' # E: Unsupported operand types for + (likely involving Union)
[builtins fixtures/isinstancelist.pyi]
[case testModifyLoop]
from typing import Union
def foo() -> Union[int, str]: pass
x = foo()
x + 1 # E: Unsupported operand types for + (likely involving Union)
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 + (likely involving Union)
x = 'a'
[builtins fixtures/isinstancelist.pyi]
[case testModifyLoop2]
from typing import Union
def foo() -> Union[int, str]: pass
x = foo()
x + 1 # E: Unsupported operand types for + (likely involving Union)
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 + (likely involving Union)
[builtins fixtures/isinstancelist.pyi]
[case testModifyLoop3]
from typing import Union
def foo() -> Union[int, str]: pass
x = foo()
x = 1
while bool():
x + 1
x = 'a'
break
else:
x + 1
x + 1 # E: Unsupported operand types for + (likely involving Union)
x = 1
for y in [1]:
x + 1
x = 'a'
break
else:
x + 1
x + 1 # E: Unsupported operand types for + (likely involving Union)
[builtins fixtures/isinstancelist.pyi]
[case testModifyLoopWhile4]
from typing import Union
def foo() -> Union[int, str]: pass
x = foo()
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 + (likely involving Union)
if bool():
x = 'a'
continue
else:
x + 1 # E: Unsupported operand types for + (likely involving Union)
x = 'a'
x + 'a'
[builtins fixtures/isinstancelist.pyi]
[case testModifyLoopFor4]
from typing import Union
def foo() -> Union[int, str]: pass
x = foo()
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 + (likely involving Union)
if bool():
x = 'a'
continue
else:
x + 1 # E: Unsupported operand types for + (likely involving Union)
x = 'a'
x + 'a'
[builtins fixtures/isinstancelist.pyi]
[case testModifyNestedLoop]
from typing import Union
def foo() -> Union[int, str]: pass
x = foo()
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 + (likely involving Union)
x = 1
while bool():
while bool():
break
else:
x = 'a'
break
else:
x + 1
x + 1 # E: Unsupported operand types for + (likely involving Union)
[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 + (some union)
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
#for i in [1]:
while bool():
if isinstance(x, int):
x + 1
else:
x.a # E: Some element of union has no attribute "a"
x = 'a'
[builtins fixtures/isinstancelist.pyi]
[out]
[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) # E: Revealed type is 'builtins.str'
reveal_type(x) # E: 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) # E: Revealed type is 'builtins.str'
reveal_type(x) # E: 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]
# flags: --fast-parser
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
[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]
[out]
[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) # E: Revealed type is 'builtins.int'
return x
[builtins fixtures/isinstance.pyi]
[out]
[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) # E: Revealed type is 'builtins.int'
return x
[builtins fixtures/isinstance.pyi]
[out]
[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 "int")
[builtins fixtures/isinstance.pyi]
[out]
[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 testIsinstanceOfSuperclass]
class A: pass
class B(A): pass
x = B()
if isinstance(x, A):
reveal_type(x) # E: Revealed type is '__main__.B'
if not isinstance(x, A):
reveal_type(x) # unreachable
x = A()
reveal_type(x) # E: 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) # E: 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]
[out]
[case testIsinstanceOfGenericClassRetainsParameters]
from typing import List, Union
def f(x: Union[List[int], str]) -> None:
if isinstance(x, list):
x[0]()
[builtins fixtures/isinstancelist.pyi]
[out]
main:4: error: "int" not callable
[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) # E: Revealed type is 'Union[__main__.B, __main__.C]'
f = x1.flag # type: int
else:
reveal_type(x1) # E: Revealed type is '__main__.A'
f = 0
x2 = A()
if isinstance(x2, A) or isinstance(x2, C):
reveal_type(x2) # E: Revealed type is '__main__.A'
f = x2.flag # E: "A" has no attribute "flag"
else:
# unreachable
1()
[builtins fixtures/isinstance.pyi]
[out]
[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) # E: Revealed type is 'builtins.list[builtins.int*]'
reveal_type(g) # E: Revealed type is 'typing.Iterator[builtins.int*]'
reveal_type(d) # E: 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]
[out]
[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) # E: Revealed type is '__main__.A'
[builtins fixtures/isinstance.pyi]
[out]