| [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] |