| -- Return statement |
| -- ---------------- |
| |
| |
| [case testReturnValue] |
| import typing |
| def f() -> 'A': |
| return A() |
| def g() -> 'B': |
| return A() |
| class A: |
| pass |
| class B: |
| pass |
| [out] |
| main:5: error: Incompatible return value type (got "A", expected "B") |
| |
| [case testReturnSubtype] |
| import typing |
| def f() -> 'B': |
| return A() |
| def g() -> 'A': |
| return B() |
| class A: |
| pass |
| class B(A): |
| pass |
| [out] |
| main:3: error: Incompatible return value type (got "A", expected "B") |
| |
| [case testReturnWithoutAValue] |
| import typing |
| def f() -> 'A': |
| return |
| def g() -> None: |
| return |
| class A: |
| pass |
| [out] |
| main:3: error: Return value expected |
| |
| [case testReturnNoneInFunctionReturningNone] |
| import typing |
| def f() -> None: |
| return None |
| def g() -> None: |
| return f() |
| [out] |
| |
| [case testReturnInGenerator] |
| from typing import Generator |
| def f() -> Generator[int, None, str]: |
| yield 1 |
| return "foo" |
| [out] |
| |
| [case testEmptyReturnInGenerator] |
| from typing import Generator |
| def f() -> Generator[int, None, str]: |
| yield 1 |
| return # E: Return value expected |
| [out] |
| |
| [case testNoReturnInGenerator] |
| from typing import Generator |
| def f() -> Generator[int, None, str]: # E: Missing return statement |
| yield 1 |
| [out] |
| |
| [case testEmptyReturnInNoneTypedGenerator] |
| from typing import Generator |
| def f() -> Generator[int, None, None]: |
| yield 1 |
| return |
| [out] |
| |
| [case testNonEmptyReturnInNoneTypedGenerator] |
| from typing import Generator |
| def f() -> Generator[int, None, None]: |
| yield 1 |
| return 42 # E: No return value expected |
| [out] |
| |
| [case testReturnInIterator] |
| from typing import Iterator |
| def f() -> Iterator[int]: |
| yield 1 |
| return "foo" |
| [out] |
| |
| |
| -- If statement |
| -- ------------ |
| |
| |
| [case testIfStatement] |
| |
| a = None # type: A |
| a2 = None # type: A |
| a3 = None # type: A |
| b = None # type: bool |
| if a: |
| a = b # E: Incompatible types in assignment (expression has type "bool", variable has type "A") |
| elif a2: |
| a = b # E: Incompatible types in assignment (expression has type "bool", variable has type "A") |
| elif a3: |
| a = b # E: Incompatible types in assignment (expression has type "bool", variable has type "A") |
| else: |
| a = b # E: Incompatible types in assignment (expression has type "bool", variable has type "A") |
| if b: |
| pass |
| elif b: |
| pass |
| if b: |
| pass |
| |
| class A: pass |
| [builtins fixtures/bool.pyi] |
| |
| |
| -- Loops |
| -- ----- |
| |
| |
| [case testWhileStatement] |
| |
| a = None # type: A |
| b = None # type: bool |
| while a: |
| a = b # Fail |
| else: |
| a = b # Fail |
| while b: |
| b = b |
| |
| class A: pass |
| [builtins fixtures/bool.pyi] |
| [out] |
| main:5: error: Incompatible types in assignment (expression has type "bool", variable has type "A") |
| main:7: error: Incompatible types in assignment (expression has type "bool", variable has type "A") |
| |
| [case testForStatement] |
| |
| a = None # type: A |
| b = None # type: object |
| for a in [A()]: |
| a = b # Fail |
| else: |
| a = b # Fail |
| |
| class A: pass |
| [builtins fixtures/list.pyi] |
| [out] |
| main:5: error: Incompatible types in assignment (expression has type "object", variable has type "A") |
| main:7: error: Incompatible types in assignment (expression has type "object", variable has type "A") |
| |
| [case testBreakStatement] |
| import typing |
| while None: |
| break |
| [builtins fixtures/bool.pyi] |
| [out] |
| |
| [case testContinueStatement] |
| import typing |
| while None: |
| continue |
| [builtins fixtures/bool.pyi] |
| [out] |
| |
| [case testForStatementTypeComments] |
| |
| from typing import List, Union |
| x = [] # type: List[int] |
| |
| for y in x: # type: str # E: Incompatible types in assignment (expression has type "int", variable has type "str") |
| pass |
| |
| for z in x: # type: int |
| pass |
| |
| for w in x: # type: Union[int, str] |
| reveal_type(w) # N: Revealed type is 'Union[builtins.int, builtins.str]' |
| |
| for v in x: # type: int, int # E: Syntax error in type annotation # N: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn) |
| pass |
| [builtins fixtures/list.pyi] |
| |
| [case testForStatementMultipleTypeComments] |
| |
| from typing import List, Tuple |
| x = [] # type: List[Tuple[int, int]] |
| |
| for y in x: # type: int, int # E: Syntax error in type annotation # N: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn) |
| pass |
| |
| for z in x: # type: Tuple[int, int] |
| pass |
| |
| for w,v in x: # type: int, str # E: Incompatible types in assignment (expression has type "int", variable has type "str") |
| pass |
| |
| for a, b in x: # type: int, int, int # E: Incompatible number of tuple items |
| pass |
| [builtins fixtures/list.pyi] |
| |
| |
| -- Operator assignment |
| -- ------------------- |
| |
| |
| [case testPlusAssign] |
| |
| a, b, c = None, None, None # type: (A, B, C) |
| a += b # Fail |
| b += a # Fail |
| c += a # Fail |
| a += c |
| |
| class A: |
| def __add__(self, x: 'C') -> 'A': pass |
| |
| class B: |
| def __add__(self, x: A) -> 'C': pass |
| |
| class C: pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| main:3: error: Unsupported operand types for + ("A" and "B") |
| main:4: error: Incompatible types in assignment (expression has type "C", variable has type "B") |
| main:5: error: Unsupported left operand type for + ("C") |
| |
| [case testMinusAssign] |
| |
| a, b, c = None, None, None # type: (A, B, C) |
| a -= b # Fail |
| b -= a # Fail |
| c -= a # Fail |
| a -= c |
| |
| class A: |
| def __sub__(self, x: 'C') -> 'A': pass |
| |
| class B: |
| def __sub__(self, x: A) -> 'C': pass |
| |
| class C: pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| main:3: error: Unsupported operand types for - ("A" and "B") |
| main:4: error: Incompatible types in assignment (expression has type "C", variable has type "B") |
| main:5: error: Unsupported left operand type for - ("C") |
| |
| [case testMulAssign] |
| |
| a, c = None, None # type: (A, C) |
| a *= a # Fail |
| c *= a # Fail |
| a *= c |
| |
| class A: |
| def __mul__(self, x: 'C') -> 'A': pass |
| |
| class C: pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| main:3: error: Unsupported operand types for * ("A" and "A") |
| main:4: error: Unsupported left operand type for * ("C") |
| |
| [case testMatMulAssign] |
| a, c = None, None # type: (A, C) |
| a @= a # E: Unsupported operand types for @ ("A" and "A") |
| c @= a # E: Unsupported left operand type for @ ("C") |
| a @= c |
| |
| class A: |
| def __matmul__(self, x: 'C') -> 'A': pass |
| |
| class C: pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testDivAssign] |
| |
| a, c = None, None # type: (A, C) |
| a /= a # Fail |
| c /= a # Fail |
| a /= c |
| |
| class A: |
| def __truediv__(self, x: 'C') -> 'A': pass |
| |
| class C: pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| main:3: error: Unsupported operand types for / ("A" and "A") |
| main:4: error: Unsupported left operand type for / ("C") |
| |
| [case testPowAssign] |
| |
| a, c = None, None # type: (A, C) |
| a **= a # Fail |
| c **= a # Fail |
| a **= c |
| |
| class A: |
| def __pow__(self, x: 'C') -> 'A': pass |
| |
| class C: pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| main:3: error: Unsupported operand types for ** ("A" and "A") |
| main:4: error: Unsupported left operand type for ** ("C") |
| |
| [case testSubtypesInOperatorAssignment] |
| |
| a, b = None, None # type: (A, B) |
| b += b |
| b += a |
| a += b |
| |
| class A: |
| def __add__(self, x: 'A') -> 'B': pass |
| |
| class B(A): pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testAdditionalOperatorsInOpAssign] |
| |
| a, c = None, None # type: (A, C) |
| a &= a # Fail |
| a >>= a # Fail |
| a //= a # Fail |
| a &= c |
| a >>= c |
| a //= c |
| class A: |
| def __and__(self, x: 'C') -> 'A': pass |
| def __rshift__(self, x: 'C') -> 'A': pass |
| def __floordiv__(self, x: 'C') -> 'A': pass |
| class C: pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| main:3: error: Unsupported operand types for & ("A" and "A") |
| main:4: error: Unsupported operand types for >> ("A" and "A") |
| main:5: error: Unsupported operand types for // ("A" and "A") |
| |
| [case testInplaceOperatorMethods] |
| import typing |
| class A: |
| def __iadd__(self, x: int) -> 'A': pass |
| def __imul__(self, x: str) -> 'A': pass |
| def __imatmul__(self, x: str) -> 'A': pass |
| a = A() |
| a += 1 |
| a *= '' |
| a @= '' |
| a += '' # E: Argument 1 to "__iadd__" of "A" has incompatible type "str"; expected "int" |
| a *= 1 # E: Argument 1 to "__imul__" of "A" has incompatible type "int"; expected "str" |
| a @= 1 # E: Argument 1 to "__imatmul__" of "A" has incompatible type "int"; expected "str" |
| |
| [case testInplaceSetitem] |
| class A(object): |
| def __init__(self) -> None: |
| self.a = [1] |
| |
| def __iadd__(self, a): |
| # type: (int) -> A |
| self.a += [2] |
| return self |
| |
| a = A() |
| b = [a] |
| b[0] += 1 |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| |
| -- Assert statement |
| -- ---------------- |
| |
| |
| [case testAssert] |
| import typing |
| assert None + None # Fail |
| assert None |
| [out] |
| main:2: error: Unsupported left operand type for + ("None") |
| |
| |
| -- Exception handling |
| -- ------------------ |
| |
| |
| [case testRaiseStatement] |
| |
| e = None # type: BaseException |
| f = None # type: MyError |
| a = None # type: A |
| raise a # Fail |
| raise e |
| raise f |
| class A: pass |
| class MyError(BaseException): pass |
| [builtins fixtures/exception.pyi] |
| [out] |
| main:5: error: Exception must be derived from BaseException |
| |
| [case testRaiseClassobject] |
| import typing |
| class A: pass |
| class MyError(BaseException): pass |
| def f(): pass |
| raise BaseException |
| raise MyError |
| raise A # E: Exception must be derived from BaseException |
| raise object # E: Exception must be derived from BaseException |
| raise f # E: Exception must be derived from BaseException |
| [builtins fixtures/exception.pyi] |
| |
| [case testRaiseExceptionType] |
| import typing |
| x = None # type: typing.Type[BaseException] |
| raise x |
| [builtins fixtures/exception.pyi] |
| |
| [case testRaiseNonExceptionTypeFails] |
| import typing |
| x = int # type: typing.Type[int] |
| raise x # E: Exception must be derived from BaseException |
| [builtins fixtures/exception.pyi] |
| |
| [case testRaiseUnion] |
| import typing |
| x = None # type: typing.Union[BaseException, typing.Type[BaseException]] |
| raise x |
| [builtins fixtures/exception.pyi] |
| |
| [case testRaiseNonExceptionUnionFails] |
| import typing |
| x = None # type: typing.Union[BaseException, int] |
| raise x # E: Exception must be derived from BaseException |
| [builtins fixtures/exception.pyi] |
| |
| [case testRaiseFromStatement] |
| e = None # type: BaseException |
| f = None # type: MyError |
| a = None # type: A |
| x = None # type: BaseException |
| del x |
| raise e from a # E: Exception must be derived from BaseException |
| raise e from e |
| raise e from f |
| raise e from x # E: Trying to read deleted variable "x" |
| class A: pass |
| class MyError(BaseException): pass |
| [builtins fixtures/exception.pyi] |
| |
| [case testRaiseFromClassobject] |
| import typing |
| class A: pass |
| class MyError(BaseException): pass |
| def f(): pass |
| raise BaseException from BaseException |
| raise BaseException from MyError |
| raise BaseException from A # E: Exception must be derived from BaseException |
| raise BaseException from object # E: Exception must be derived from BaseException |
| raise BaseException from f # E: Exception must be derived from BaseException |
| [builtins fixtures/exception.pyi] |
| |
| [case testTryFinallyStatement] |
| import typing |
| try: |
| b = object() # type: A # Fail |
| finally: |
| c = object() # type: A # Fail |
| class A: pass |
| [out] |
| main:3: error: Incompatible types in assignment (expression has type "object", variable has type "A") |
| main:5: error: Incompatible types in assignment (expression has type "object", variable has type "A") |
| |
| [case testSimpleTryExcept] |
| |
| try: |
| pass |
| except BaseException as e: |
| a, o = None, None # type: (BaseException, object) |
| e = a |
| e = o # Fail |
| class A: pass |
| class B: pass |
| [builtins fixtures/exception.pyi] |
| [out] |
| main:7: error: Incompatible types in assignment (expression has type "object", variable has type "BaseException") |
| |
| [case testTypeErrorInBlock] |
| while object: |
| x = None # type: A |
| if int(): |
| x = object() # E: Incompatible types in assignment (expression has type "object", variable has type "A") |
| x = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| class A: pass |
| class B: pass |
| |
| [case testTypeErrorInvolvingBaseException] |
| |
| x, a = None, None # type: (BaseException, A) |
| if int(): |
| a = BaseException() # E: Incompatible types in assignment (expression has type "BaseException", variable has type "A") |
| if int(): |
| a = object() # E: Incompatible types in assignment (expression has type "object", variable has type "A") |
| if int(): |
| x = object() # E: Incompatible types in assignment (expression has type "object", variable has type "BaseException") |
| if int(): |
| x = A() # E: Incompatible types in assignment (expression has type "A", variable has type "BaseException") |
| if int(): |
| x = BaseException() |
| class A: pass |
| [builtins fixtures/exception.pyi] |
| |
| [case testSimpleTryExcept2] |
| import typing |
| try: |
| pass |
| except BaseException as e: |
| e = object() # Fail |
| e = BaseException() |
| [builtins fixtures/exception.pyi] |
| [out] |
| main:5: error: Incompatible types in assignment (expression has type "object", variable has type "BaseException") |
| |
| [case testBaseClassAsExceptionTypeInExcept] |
| import typing |
| try: |
| pass |
| except Err as e: |
| e = BaseException() # Fail |
| e = Err() |
| class Err(BaseException): pass |
| [builtins fixtures/exception.pyi] |
| [out] |
| main:5: error: Incompatible types in assignment (expression has type "BaseException", variable has type "Err") |
| |
| [case testMultipleExceptHandlers] |
| import typing |
| try: |
| pass |
| except BaseException as e: |
| pass |
| except Err as f: |
| f = BaseException() # Fail |
| f = Err() |
| class Err(BaseException): pass |
| [builtins fixtures/exception.pyi] |
| [out] |
| main:7: error: Incompatible types in assignment (expression has type "BaseException", variable has type "Err") |
| |
| [case testTryExceptStatement] |
| import typing |
| try: |
| a = B() # type: A # Fail |
| except BaseException as e: |
| e = A() # Fail |
| e = Err() |
| except Err as f: |
| f = BaseException() # Fail |
| f = Err() |
| class A: pass |
| class B: pass |
| class Err(BaseException): pass |
| [builtins fixtures/exception.pyi] |
| [out] |
| main:3: error: Incompatible types in assignment (expression has type "B", variable has type "A") |
| main:5: error: Incompatible types in assignment (expression has type "A", variable has type "BaseException") |
| main:8: error: Incompatible types in assignment (expression has type "BaseException", variable has type "Err") |
| |
| [case testTryExceptWithinFunction] |
| import typing |
| def f() -> None: |
| try: pass |
| except BaseException as e: |
| e = object() # Fail |
| e = BaseException() |
| except Err as f: |
| f = BaseException() # Fail |
| f = Err() |
| class Err(BaseException): pass |
| [builtins fixtures/exception.pyi] |
| [out] |
| main:5: error: Incompatible types in assignment (expression has type "object", variable has type "BaseException") |
| main:8: error: Incompatible types in assignment (expression has type "BaseException", variable has type "Err") |
| |
| [case testTryExceptFlow] |
| def f() -> None: |
| x = 1 |
| try: |
| pass |
| except: |
| raise |
| x + 'a' # E: Unsupported left operand type for + ("int") |
| [builtins fixtures/exception.pyi] |
| [out] |
| |
| [case testTryWithElse] |
| import typing |
| try: pass |
| except BaseException: pass |
| else: |
| object(None) # E: Too many arguments for "object" |
| [builtins fixtures/exception.pyi] |
| |
| [case testRedefinedFunctionInTryWithElse] |
| def f() -> None: pass |
| try: |
| pass |
| except BaseException: |
| f2 = f |
| else: |
| def f2() -> str: pass |
| try: |
| pass |
| except BaseException: |
| f3 = f |
| else: |
| def f3() -> None: pass |
| [builtins fixtures/exception.pyi] |
| [out] |
| main:7: error: Incompatible redefinition (redefinition with type "Callable[[], str]", original type "Callable[[], None]") |
| |
| [case testExceptWithoutType] |
| import typing |
| try: |
| -None # E: Unsupported operand type for unary - ("None") |
| except: |
| ~None # E: Unsupported operand type for ~ ("None") |
| [builtins fixtures/exception.pyi] |
| |
| [case testRaiseWithoutArgument] |
| import typing |
| try: |
| None |
| except: |
| raise |
| [builtins fixtures/exception.pyi] |
| |
| [case testExceptWithMultipleTypes] |
| import typing |
| class E1(BaseException): pass |
| class E2(E1): pass |
| try: |
| pass |
| except (E1, E2): pass |
| except (E1, object): pass # E: Exception type must be derived from BaseException |
| except (object, E2): pass # E: Exception type must be derived from BaseException |
| except (E1, (E2,)): pass # E: Exception type must be derived from BaseException |
| |
| except (E1, E2): pass |
| except ((E1, E2)): pass |
| except (((E1, E2))): pass |
| [builtins fixtures/exception.pyi] |
| |
| [case testExceptWithTypeType] |
| import typing |
| E = BaseException # type: typing.Type[BaseException] |
| |
| try: |
| pass |
| except E: |
| pass |
| [builtins fixtures/exception.pyi] |
| |
| [case testExceptWithMultipleTypes2] |
| import typing |
| class E1(BaseException): pass |
| class E2(E1): pass |
| try: |
| pass |
| except (E1, E2) as e1: |
| x = e1 # type: E1 |
| y = e1 # type: E2 # E: Incompatible types in assignment (expression has type "E1", variable has type "E2") |
| except (E2, E1) as e2: |
| a = e2 # type: E1 |
| b = e2 # type: E2 # E: Incompatible types in assignment (expression has type "E1", variable has type "E2") |
| except (E1, E2, int) as e3: # E: Exception type must be derived from BaseException |
| pass |
| [builtins fixtures/exception.pyi] |
| |
| [case testExceptWithMultipleTypes3] |
| import typing |
| class E1(BaseException): pass |
| class E1_1(E1): pass |
| class E1_2(E1): pass |
| try: pass |
| except (E1, E1_1, E1_2) as e1: |
| x = e1 # type: E1 |
| y = e1 # type: E1_1 # E: Incompatible types in assignment (expression has type "E1", variable has type "E1_1") |
| z = e1 # type: E1_2 # E: Incompatible types in assignment (expression has type "E1", variable has type "E1_2") |
| except (E1_1, E1_2) as e2: |
| a = e2 # type: E1 |
| b = e2 # type: E1_1 # E: Incompatible types in assignment (expression has type "Union[E1_1, E1_2]", variable has type "E1_1") |
| c = e2 # type: E1_2 # E: Incompatible types in assignment (expression has type "Union[E1_1, E1_2]", variable has type "E1_2") |
| [builtins fixtures/exception.pyi] |
| |
| [case testExceptWithMultipleTypes4] |
| from typing import Tuple, Type, Union |
| |
| class E1(BaseException): pass |
| class E2(BaseException): pass |
| class E3(BaseException): pass |
| |
| def variadic(exc: Tuple[Type[E1], ...]) -> None: |
| try: |
| pass |
| except exc as e: |
| reveal_type(e) # N: Revealed type is '__main__.E1' |
| |
| def union(exc: Union[Type[E1], Type[E2]]) -> None: |
| try: |
| pass |
| except exc as e: |
| reveal_type(e) # N: Revealed type is 'Union[__main__.E1, __main__.E2]' |
| |
| def tuple_in_union(exc: Union[Type[E1], Tuple[Type[E2], Type[E3]]]) -> None: |
| try: |
| pass |
| except exc as e: |
| reveal_type(e) # N: Revealed type is 'Union[__main__.E1, __main__.E2, __main__.E3]' |
| |
| def variadic_in_union(exc: Union[Type[E1], Tuple[Type[E2], ...]]) -> None: |
| try: |
| pass |
| except exc as e: |
| reveal_type(e) # N: Revealed type is 'Union[__main__.E1, __main__.E2]' |
| |
| def nested_union(exc: Union[Type[E1], Union[Type[E2], Type[E3]]]) -> None: |
| try: |
| pass |
| except exc as e: |
| reveal_type(e) # N: Revealed type is 'Union[__main__.E1, __main__.E2, __main__.E3]' |
| |
| def error_in_union(exc: Union[Type[E1], int]) -> None: |
| try: |
| pass |
| except exc as e: # E: Exception type must be derived from BaseException |
| pass |
| |
| def error_in_variadic(exc: Tuple[int, ...]) -> None: |
| try: |
| pass |
| except exc as e: # E: Exception type must be derived from BaseException |
| pass |
| |
| [builtins fixtures/tuple.pyi] |
| |
| [case testExceptWithAnyTypes] |
| from typing import Any |
| |
| E1 = None # type: Any |
| class E2(BaseException): pass |
| class NotBaseDerived: pass |
| |
| try: |
| pass |
| except BaseException as e1: |
| reveal_type(e1) # N: Revealed type is 'builtins.BaseException' |
| except (E1, BaseException) as e2: |
| reveal_type(e2) # N: Revealed type is 'Union[Any, builtins.BaseException]' |
| except (E1, E2) as e3: |
| reveal_type(e3) # N: Revealed type is 'Union[Any, __main__.E2]' |
| except (E1, E2, BaseException) as e4: |
| reveal_type(e4) # N: Revealed type is 'Union[Any, builtins.BaseException]' |
| |
| try: pass |
| except E1 as e1: |
| reveal_type(e1) # N: Revealed type is 'Any' |
| except E2 as e2: |
| reveal_type(e2) # N: Revealed type is '__main__.E2' |
| except NotBaseDerived as e3: # E: Exception type must be derived from BaseException |
| pass |
| except (NotBaseDerived, E1) as e4: # E: Exception type must be derived from BaseException |
| pass |
| except (NotBaseDerived, E2) as e5: # E: Exception type must be derived from BaseException |
| pass |
| except (NotBaseDerived, E1, E2) as e6: # E: Exception type must be derived from BaseException |
| pass |
| except (E1, E2, NotBaseDerived) as e6: # E: Exception type must be derived from BaseException |
| pass |
| [builtins fixtures/exception.pyi] |
| |
| [case testReuseTryExceptionVariable] |
| import typing |
| class E1(BaseException): pass |
| class E2(BaseException): pass |
| try: pass |
| except E1 as e: pass |
| try: pass |
| except E1 as e: pass |
| try: pass |
| except E2 as e: pass |
| e + 1 # E: Trying to read deleted variable "e" |
| e = E1() # E: Assignment to variable "e" outside except: block |
| [builtins fixtures/exception.pyi] |
| |
| [case testReuseDefinedTryExceptionVariable] |
| import typing |
| class E1(BaseException): pass |
| class E2(BaseException): pass |
| e = 1 |
| def f(): e # Prevent redefinition |
| e = 1 |
| try: pass |
| except E1 as e: pass |
| e = 1 # E: Assignment to variable "e" outside except: block |
| e = E1() # E: Assignment to variable "e" outside except: block |
| [builtins fixtures/exception.pyi] |
| |
| [case testExceptionVariableReuseInDeferredNode1] |
| def f(*a: BaseException) -> int: |
| x |
| try: pass |
| except BaseException as err: pass |
| try: pass |
| except BaseException as err: f(err) |
| return 0 |
| x = f() |
| [builtins fixtures/exception.pyi] |
| |
| [case testExceptionVariableReuseInDeferredNode2] |
| def f(*a: BaseException) -> int: |
| try: pass |
| except BaseException as err: pass |
| x |
| try: pass |
| except BaseException as err: f(err) |
| return 0 |
| x = f() |
| [builtins fixtures/exception.pyi] |
| |
| [case testExceptionVariableReuseInDeferredNode3] |
| def f(*a: BaseException) -> int: |
| try: pass |
| except BaseException as err: pass |
| try: pass |
| except BaseException as err: f(err) |
| x |
| return 0 |
| x = f() |
| [builtins fixtures/exception.pyi] |
| |
| [case testExceptionVariableReuseInDeferredNode4] |
| class EA(BaseException): |
| a = None # type: int |
| class EB(BaseException): |
| b = None # type: str |
| def f(*arg: BaseException) -> int: |
| x |
| try: pass |
| except EA as err: |
| f(err) |
| a = err.a |
| reveal_type(a) |
| try: pass |
| except EB as err: |
| f(err) |
| b = err.b |
| reveal_type(b) |
| return 0 |
| x = f() |
| [builtins fixtures/exception.pyi] |
| [out] |
| main:11: note: Revealed type is 'builtins.int' |
| main:16: note: Revealed type is 'builtins.str' |
| |
| [case testExceptionVariableReuseInDeferredNode5] |
| class EA(BaseException): |
| a = None # type: int |
| class EB(BaseException): |
| b = None # type: str |
| def f(*arg: BaseException) -> int: |
| try: pass |
| except EA as err: |
| f(err) |
| a = err.a |
| reveal_type(a) |
| x |
| try: pass |
| except EB as err: |
| f(err) |
| b = err.b |
| reveal_type(b) |
| return 0 |
| x = f() |
| [builtins fixtures/exception.pyi] |
| [out] |
| main:10: note: Revealed type is 'builtins.int' |
| main:16: note: Revealed type is 'builtins.str' |
| |
| [case testExceptionVariableReuseInDeferredNode6] |
| class EA(BaseException): |
| a = None # type: int |
| class EB(BaseException): |
| b = None # type: str |
| def f(*arg: BaseException) -> int: |
| try: pass |
| except EA as err: |
| f(err) |
| a = err.a |
| reveal_type(a) |
| try: pass |
| except EB as err: |
| f(err) |
| b = err.b |
| reveal_type(b) |
| x |
| return 0 |
| x = f() |
| [builtins fixtures/exception.pyi] |
| [out] |
| main:10: note: Revealed type is 'builtins.int' |
| main:15: note: Revealed type is 'builtins.str' |
| |
| [case testArbitraryExpressionAsExceptionType] |
| import typing |
| a = BaseException |
| try: pass |
| except a as b: |
| b = BaseException() |
| b = object() # E: Incompatible types in assignment (expression has type "object", variable has type "BaseException") |
| [builtins fixtures/exception.pyi] |
| |
| [case testInvalidExceptionCallable] |
| import typing |
| def exc() -> BaseException: pass |
| try: pass |
| except exc as e: pass # E: Exception type must be derived from BaseException |
| except BaseException() as b: pass # E: Exception type must be derived from BaseException |
| [builtins fixtures/exception.pyi] |
| |
| [case testTupleValueAsExceptionType] |
| import typing |
| def exc() -> BaseException: pass |
| class E1(BaseException): pass |
| class E1_1(E1): pass |
| class E1_2(E1): pass |
| |
| exs1 = (E1, E1_1, E1_2) |
| try: pass |
| except exs1 as e1: |
| x = e1 # type: E1 |
| y = e1 # type: E1_1 # E: Incompatible types in assignment (expression has type "E1", variable has type "E1_1") |
| z = e1 # type: E1_2 # E: Incompatible types in assignment (expression has type "E1", variable has type "E1_2") |
| |
| exs2 = (E1_1, E1_2) |
| try: pass |
| except exs2 as e2: |
| a = e2 # type: E1 |
| b = e2 # type: E1_1 # E: Incompatible types in assignment (expression has type "Union[E1_1, E1_2]", variable has type "E1_1") |
| c = e2 # type: E1_2 # E: Incompatible types in assignment (expression has type "Union[E1_1, E1_2]", variable has type "E1_2") |
| |
| exs3 = (E1, (E1_1, (E1_2,))) |
| try: pass |
| except exs3 as e3: pass # E: Exception type must be derived from BaseException |
| [builtins fixtures/exception.pyi] |
| |
| [case testInvalidTupleValueAsExceptionType] |
| import typing |
| def exc() -> BaseException: pass |
| class E1(BaseException): pass |
| class E2(E1): pass |
| |
| exs1 = (E1, E2, int) |
| try: pass |
| except exs1 as e: pass # E: Exception type must be derived from BaseException |
| [builtins fixtures/exception.pyi] |
| |
| [case testOverloadedExceptionType] |
| from foo import * |
| [file foo.pyi] |
| from typing import overload |
| class E(BaseException): |
| @overload |
| def __init__(self) -> None: pass |
| @overload |
| def __init__(self, x) -> None: pass |
| try: |
| pass |
| except E as e: |
| e = E() |
| e = BaseException() # E: Incompatible types in assignment (expression has type "BaseException", variable has type "E") |
| [builtins fixtures/exception.pyi] |
| |
| [case testExceptionWithAnyBaseClass] |
| from typing import Any |
| E = None # type: Any |
| class EE(E): pass |
| raise EE() |
| raise EE |
| [builtins fixtures/exception.pyi] |
| |
| [case testExceptionIsType] |
| from typing import Type |
| class B(BaseException): pass |
| def f(e: Type[B]): |
| try: pass |
| except e: pass |
| def g(e: Type[BaseException]): |
| try: pass |
| except e as err: |
| reveal_type(err) |
| def h(e: Type[int]): |
| try: pass |
| except e: pass |
| [builtins fixtures/exception.pyi] |
| [out] |
| main:9: note: Revealed type is 'builtins.BaseException' |
| main:12: error: Exception type must be derived from BaseException |
| |
| |
| -- Del statement |
| -- ------------- |
| |
| |
| [case testDelStmtWithIndex] |
| a, b = None, None # type: (A, B) |
| del b[a] |
| del b[b] # E: Argument 1 to "__delitem__" of "B" has incompatible type "B"; expected "A" |
| del a[a] # E: "A" has no attribute "__delitem__" |
| del a[b] # E: "A" has no attribute "__delitem__" |
| class B: |
| def __delitem__(self, index: 'A'): pass |
| class A: pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testDelStmtWithAttribute] |
| class A: |
| def f(self): pass |
| x = 0 |
| a = A() |
| del a.f |
| del a.x |
| del a.z # E: "A" has no attribute "z" |
| |
| [case testDelStatementWithTuple] |
| class A: |
| x = 0 |
| a = A() |
| del a.x, a.y # E: "A" has no attribute "y" |
| [builtins fixtures/tuple.pyi] |
| |
| |
| [case testDelStatementWithAssignmentSimple] |
| a = 1 |
| a + 1 |
| del a |
| a + 1 # E: Trying to read deleted variable "a" |
| [builtins fixtures/ops.pyi] |
| |
| [case testDelStatementWithAssignmentTuple] |
| a = 1 |
| b = 1 |
| del (a, b) |
| b + 1 # E: Trying to read deleted variable "b" |
| [builtins fixtures/ops.pyi] |
| |
| [case testDelStatementWithAssignmentList] |
| a = 1 |
| b = 1 |
| del [a, b] |
| b + 1 # E: Trying to read deleted variable "b" |
| [builtins fixtures/list.pyi] |
| |
| [case testDelStatementWithAssignmentClass] |
| class C: |
| a = 1 |
| |
| c = C() |
| c.a = 1 |
| c.a + 1 |
| del c.a |
| c.a + 1 |
| [builtins fixtures/ops.pyi] |
| |
| [case testDelStatementWithConditions] |
| x = 5 |
| del x |
| if x: ... # E: Trying to read deleted variable "x" |
| |
| def f(x): |
| return x |
| |
| if 0: ... |
| elif f(x): ... # E: Trying to read deleted variable "x" |
| |
| while x == 5: ... # E: Trying to read deleted variable "x" |
| |
| -- Yield statement |
| -- --------------- |
| |
| |
| [case testSimpleYield] |
| from typing import Iterator |
| def f() -> Iterator[int]: |
| yield 1 |
| yield '' # E: Incompatible types in "yield" (actual type "str", expected type "int") |
| [builtins fixtures/for.pyi] |
| [out] |
| |
| [case testYieldInFunctionReturningGenerator] |
| from typing import Generator |
| def f() -> Generator[int, None, None]: |
| yield 1 |
| [builtins fixtures/for.pyi] |
| [out] |
| |
| [case testYieldInFunctionReturningIterable] |
| from typing import Iterable |
| def f() -> Iterable[int]: |
| yield 1 |
| [builtins fixtures/for.pyi] |
| [out] |
| |
| [case testYieldInFunctionReturningObject] |
| def f() -> object: |
| yield 1 |
| [builtins fixtures/for.pyi] |
| [out] |
| |
| [case testYieldInFunctionReturningAny] |
| from typing import Any |
| def f() -> Any: |
| yield object() |
| [out] |
| |
| [case testYieldInFunctionReturningFunction] |
| from typing import Callable |
| def f() -> Callable[[], None]: # E: The return type of a generator function should be "Generator" or one of its supertypes |
| yield object() |
| [out] |
| |
| [case testYieldInDynamicallyTypedFunction] |
| import typing |
| def f(): |
| yield f |
| |
| [case testWithInvalidInstanceReturnType] |
| import typing |
| def f() -> int: # E: The return type of a generator function should be "Generator" or one of its supertypes |
| yield 1 |
| [builtins fixtures/for.pyi] |
| [out] |
| |
| [case testTypeInferenceContextAndYield] |
| from typing import List, Iterator |
| def f() -> 'Iterator[List[int]]': |
| yield [] |
| yield [object()] # E: List item 0 has incompatible type "object"; expected "int" |
| [builtins fixtures/for.pyi] |
| [out] |
| |
| [case testYieldAndReturnWithoutValue] |
| from typing import Iterator |
| def f() -> Iterator[int]: |
| yield 1 |
| return |
| [builtins fixtures/for.pyi] |
| |
| [case testYieldWithNoValue] |
| from typing import Iterator |
| def f() -> Iterator[None]: |
| yield |
| [builtins fixtures/for.pyi] |
| |
| [case testYieldWithNoValueWhenValueRequired] |
| from typing import Iterator |
| def f() -> Iterator[int]: |
| yield # E: Yield value expected |
| [builtins fixtures/for.pyi] |
| [out] |
| |
| [case testYieldWithExplicitNone] |
| from typing import Iterator |
| def f() -> Iterator[None]: |
| yield None |
| [builtins fixtures/for.pyi] |
| [out] |
| |
| |
| -- Yield from statement |
| -- -------------------- |
| -- |
| -- (It's not really a statement, but don't want to move the tests.) |
| |
| [case testSimpleYieldFromWithIterator] |
| from typing import Iterator |
| def g() -> Iterator[str]: |
| yield '42' |
| def h() -> Iterator[int]: |
| yield 42 |
| def f() -> Iterator[str]: |
| yield from g() |
| yield from h() # E: Incompatible types in "yield from" (actual type "int", expected type "str") |
| [out] |
| |
| [case testYieldFromAppliedToAny] |
| from typing import Any |
| def g() -> Any: |
| yield object() |
| def f() -> Any: |
| yield from g() |
| [out] |
| |
| [case testYieldFromInFunctionReturningFunction] |
| from typing import Iterator, Callable |
| def g() -> Iterator[int]: |
| yield 42 |
| def f() -> Callable[[], None]: # E: The return type of a generator function should be "Generator" or one of its supertypes |
| yield from g() |
| [out] |
| |
| [case testYieldFromNotIterableReturnType] |
| from typing import Iterator |
| def g() -> Iterator[int]: |
| yield 42 |
| def f() -> int: # E: The return type of a generator function should be "Generator" or one of its supertypes |
| yield from g() |
| [out] |
| |
| [case testYieldFromNotAppliedIterator] |
| from typing import Iterator |
| def g() -> int: |
| return 42 |
| def f() -> Iterator[int]: |
| yield from g() # E: "yield from" can't be applied to "int" |
| [out] |
| |
| [case testYieldFromCheckIncompatibleTypesTwoIterables] |
| from typing import List, Iterator |
| def g() -> Iterator[List[int]]: |
| yield [2, 3, 4] |
| def f() -> Iterator[List[int]]: |
| yield from g() |
| yield from [1, 2, 3] # E: Incompatible types in "yield from" (actual type "int", expected type "List[int]") |
| [builtins fixtures/for.pyi] |
| [out] |
| |
| [case testYieldFromNotAppliedToNothing] |
| def h(): |
| yield from # E: invalid syntax |
| [out] |
| |
| [case testYieldFromAndYieldTogether] |
| from typing import Iterator |
| def f() -> Iterator[str]: |
| yield "g1 ham" |
| yield from g() |
| yield "g1 eggs" |
| def g() -> Iterator[str]: |
| yield "g2 spam" |
| yield "g2 more spam" |
| [out] |
| |
| [case testYieldFromAny] |
| from typing import Iterator |
| def f(a): |
| b = yield from a |
| return b |
| [out] |
| |
| [case testYieldFromGenericCall] |
| from typing import Generator, TypeVar |
| T = TypeVar('T') |
| def f(a: T) -> Generator[int, str, T]: pass |
| def g() -> Generator[int, str, float]: |
| r = yield from f('') |
| reveal_type(r) # N: Revealed type is 'builtins.str*' |
| return 3.14 |
| |
| [case testYieldFromTupleStatement] |
| from typing import Generator |
| def g() -> Generator[int, None, None]: |
| yield from () |
| yield from (0, 1, 2) |
| yield from (0, "ERROR") # E: Incompatible types in "yield from" (actual type "object", expected type "int") |
| yield from ("ERROR",) # E: Incompatible types in "yield from" (actual type "str", expected type "int") |
| [builtins fixtures/tuple.pyi] |
| |
| -- With statement |
| -- -------------- |
| |
| |
| [case testSimpleWith] |
| import typing |
| class A: |
| def __enter__(self) -> None: pass |
| def __exit__(self, x, y, z) -> None: pass |
| with A(): |
| object(A) # E: Too many arguments for "object" |
| |
| [case testWithStmtAndInvalidExit] |
| import typing |
| class A: |
| def __enter__(self) -> None: pass |
| def __exit__(self, x, y) -> None: pass |
| with A(): # E: Too many arguments for "__exit__" of "A" |
| pass |
| |
| [case testWithStmtAndMissingExit] |
| import typing |
| class A: |
| def __enter__(self) -> None: pass |
| with A(): # E: "A" has no attribute "__exit__" |
| pass |
| |
| [case testWithStmtAndInvalidEnter] |
| import typing |
| class A: |
| def __enter__(self, x) -> None: pass |
| def __exit__(self, x, y, z) -> None: pass |
| with A(): # E: Too few arguments for "__enter__" of "A" |
| pass |
| |
| [case testWithStmtAndMissingEnter] |
| import typing |
| class A: |
| def __exit__(self, x, y, z) -> None: pass |
| with A(): # E: "A" has no attribute "__enter__" |
| pass |
| |
| [case testWithStmtAndMultipleExprs] |
| import typing |
| class A: |
| def __enter__(self) -> None: pass |
| def __exit__(self, x, y, z) -> None: pass |
| class B: |
| def __enter__(self) -> None: pass |
| with A(), B(): # E: "B" has no attribute "__exit__" |
| pass |
| with B(), A(): # E: "B" has no attribute "__exit__" |
| pass |
| |
| [case testWithStmtAndResult] |
| import typing |
| class B: pass |
| class A: |
| def __enter__(self) -> B: pass |
| def __exit__(self, x, y, z): pass |
| with A() as b: |
| b = B() |
| b = A() # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| |
| [case testWithStmtAndMultipleResults] |
| from typing import TypeVar, Generic |
| t = TypeVar('t') |
| class B: pass |
| class C: pass |
| class A(Generic[t]): |
| def __enter__(self) -> t: pass |
| def __exit__(self, x, y, z): pass |
| a_b = A() # type: A[B] |
| a_c = A() # type: A[C] |
| with a_b as b, a_c as c: |
| b = B() |
| c = C() |
| b = c # E: Incompatible types in assignment (expression has type "C", variable has type "B") |
| c = b # E: Incompatible types in assignment (expression has type "B", variable has type "C") |
| |
| [case testWithStmtAndComplexTarget] |
| from typing import Tuple |
| class A: |
| def __enter__(self) -> Tuple[int, str]: pass |
| def __exit__(self, x, y, z): pass |
| with A() as (a, b): |
| a = 1 |
| b = '' |
| a = b # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| [builtins fixtures/tuple.pyi] |
| |
| [case testWithStmtTypeComment] |
| |
| from typing import Union |
| class A: |
| def __enter__(self) -> int: pass |
| def __exit__(self, x, y, z): pass |
| |
| with A(): # type: int # E: Invalid type comment: "with" statement has no targets |
| pass |
| |
| with A() as a: # type: int |
| pass |
| |
| with A() as b: # type: str # E: Incompatible types in assignment (expression has type "int", variable has type "str") |
| pass |
| |
| with A() as c: # type: int, int # E: Syntax error in type annotation # N: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn) |
| pass |
| |
| with A() as d: # type: Union[int, str] |
| reveal_type(d) # N: Revealed type is 'Union[builtins.int, builtins.str]' |
| |
| [case testWithStmtTupleTypeComment] |
| |
| from typing import Tuple |
| class A: |
| def __enter__(self) -> Tuple[int, int]: pass |
| def __exit__(self, x, y, z): pass |
| |
| with A(): |
| pass |
| |
| with A() as a: # type: Tuple[int, int] |
| pass |
| |
| with A() as b: # type: Tuple[int, str] # E: Incompatible types in assignment (expression has type "Tuple[int, int]", variable has type "Tuple[int, str]") |
| pass |
| |
| with A() as (c, d): # type: int, int |
| pass |
| |
| with A() as (e, f): # type: Tuple[int, int] |
| pass |
| |
| with A() as (g, h): # type: int # E: Tuple type expected for multiple variables |
| pass |
| |
| with A() as (i, j): # type: int, int, str # E: Incompatible number of tuple items |
| pass |
| |
| with A() as (k, l): # type: int, str # E: Incompatible types in assignment (expression has type "int", variable has type "str") |
| pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testWithStmtComplexTypeComment] |
| |
| from typing import Tuple |
| class A: |
| def __enter__(self) -> Tuple[int, int]: pass |
| def __exit__(self, x, y, z): pass |
| |
| class B: |
| def __enter__(self) -> str: pass |
| def __exit__(self, x, y, z): pass |
| |
| with A() as a, A() as (b, c), B() as d: # type: Tuple[int, int], (int, int), str |
| pass |
| |
| with A() as e, A() as (f, g), B() as h: # type: Tuple[int, int], Tuple[int, int], str |
| pass |
| |
| with A() as i, A() as (j, k), B() as l: # type: (int, int), (int, int), str # E: Syntax error in type annotation # N: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn) |
| pass |
| |
| with A(), A(), B() as m, A() as n, B(), B() as o: # type: int, Tuple[int, int] # E: Incompatible number of types for "with" targets |
| pass |
| |
| with A(), B(), B() as p, A(), A(): # type: str |
| pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testWithStmtBoolExitReturnWithResultFalse] |
| from typing import Optional |
| |
| class InvalidReturn1: |
| def __exit__(self, x, y, z) -> bool: # E: "bool" is invalid as return type for "__exit__" that always returns False \ |
| # N: Use "typing_extensions.Literal[False]" as the return type or change it to "None" \ |
| # N: If return type of "__exit__" implies that it may return True, the context manager may swallow exceptions |
| return False |
| |
| class InvalidReturn2: |
| def __exit__(self, x, y, z) -> Optional[bool]: # E: "bool" is invalid as return type for "__exit__" that always returns False \ |
| # N: Use "typing_extensions.Literal[False]" as the return type or change it to "None" \ |
| # N: If return type of "__exit__" implies that it may return True, the context manager may swallow exceptions |
| if int(): |
| return False |
| else: |
| return False |
| |
| class InvalidReturn3: |
| def __exit__(self, x, y, z) -> bool: # E: "bool" is invalid as return type for "__exit__" that always returns False \ |
| # N: Use "typing_extensions.Literal[False]" as the return type or change it to "None" \ |
| # N: If return type of "__exit__" implies that it may return True, the context manager may swallow exceptions |
| def nested() -> bool: |
| return True |
| return False |
| [builtins fixtures/bool.pyi] |
| |
| [case testWithStmtBoolExitReturnOkay] |
| from typing_extensions import Literal |
| |
| class GoodReturn1: |
| def __exit__(self, x, y, z) -> bool: |
| if int(): |
| return True |
| else: |
| return False |
| |
| class GoodReturn2: |
| def __exit__(self, x, y, z) -> bool: |
| if int(): |
| return False |
| else: |
| return True |
| |
| class GoodReturn3: |
| def __exit__(self, x, y, z) -> bool: |
| return bool() |
| |
| class GoodReturn4: |
| def __exit__(self, x, y, z) -> None: |
| return |
| |
| class GoodReturn5: |
| def __exit__(self, x, y, z) -> None: |
| return None |
| |
| class GoodReturn6: |
| def exit(self, x, y, z) -> bool: |
| return False |
| |
| class GoodReturn7: |
| def exit(self, x, y, z) -> bool: |
| pass |
| |
| class MissingReturn: |
| def exit(self, x, y, z) -> bool: # E: Missing return statement |
| x = 0 |
| |
| class LiteralReturn: |
| def __exit__(self, x, y, z) -> Literal[False]: |
| return False |
| [builtins fixtures/bool.pyi] |
| |
| |
| [case testWithStmtBoolExitReturnInStub] |
| import stub |
| |
| [file stub.pyi] |
| from typing import Optional |
| |
| class C1: |
| def __exit__(self, x, y, z) -> bool: ... |
| |
| class C2: |
| def __exit__(self, x, y, z) -> bool: pass |
| |
| class C3: |
| def __exit__(self, x, y, z) -> Optional[bool]: pass |
| [builtins fixtures/bool.pyi] |
| |
| |
| -- Chained assignment |
| -- ------------------ |
| |
| |
| [case testChainedAssignment] |
| import typing |
| class A: pass |
| class B: pass |
| x = y = A() |
| if int(): |
| x = A() |
| if int(): |
| y = A() |
| if int(): |
| x = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| if int(): |
| y = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| |
| [case testChainedAssignment2] |
| import typing |
| def f() -> None: |
| x = 1 |
| y = 'x' |
| if int(): |
| x = y = 'x' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| x = y = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str") |
| [builtins fixtures/primitives.pyi] |
| [out] |
| |
| [case testChainedAssignmentWithType] |
| x = y = None # type: int |
| if int(): |
| x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| if int(): |
| y = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| if int(): |
| x = 1 |
| if int(): |
| y = 1 |
| |
| |
| -- Star assignment |
| -- --------------- |
| |
| |
| [case testAssignListToStarExpr] |
| from typing import List |
| bs, cs = None, None # type: List[A], List[B] |
| if int(): |
| *bs, b = bs |
| if int(): |
| *bs, c = cs # E: Incompatible types in assignment (expression has type "List[B]", variable has type "List[A]") |
| if int(): |
| *ns, c = cs |
| if int(): |
| nc = cs |
| |
| class A: pass |
| class B: pass |
| [builtins fixtures/list.pyi] |
| |
| |
| -- Type aliases |
| -- ------------ |
| |
| |
| [case testSimpleTypeAlias] |
| import typing |
| foo = int |
| def f(x: foo) -> None: pass |
| f(1) |
| f('x') # E: Argument 1 to "f" has incompatible type "str"; expected "int" |
| |
| [case testTypeAliasDefinedInAModule] |
| import typing |
| import m |
| def f(x: m.foo) -> None: pass |
| f(1) |
| f('x') # E: Argument 1 to "f" has incompatible type "str"; expected "int" |
| [file m.py] |
| import typing |
| foo = int |
| |
| [case testTypeAliasDefinedInAModule2] |
| import typing |
| from m import foo |
| def f(x: foo) -> None: pass |
| f(1) |
| f('x') # E: Argument 1 to "f" has incompatible type "str"; expected "int" |
| [file m.py] |
| import typing |
| foo = int |
| |
| |
| -- nonlocal and global |
| -- ------------------- |
| |
| |
| [case testTypeOfGlobalUsed] |
| import typing |
| g = A() |
| def f() -> None: |
| global g |
| g = B() |
| |
| class A(): pass |
| class B(): pass |
| [out] |
| main:5: error: Incompatible types in assignment (expression has type "B", variable has type "A") |
| |
| [case testTypeOfNonlocalUsed] |
| import typing |
| def f() -> None: |
| a = A() |
| def g() -> None: |
| nonlocal a |
| a = B() |
| |
| class A(): pass |
| class B(): pass |
| [out] |
| main:6: error: Incompatible types in assignment (expression has type "B", variable has type "A") |
| |
| [case testTypeOfOuterMostNonlocalUsed] |
| import typing |
| def f() -> None: |
| a = A() |
| def g() -> None: |
| a = B() |
| def h() -> None: |
| nonlocal a |
| a = A() |
| a = B() |
| |
| class A(): pass |
| class B(): pass |
| [out] |
| main:8: error: Incompatible types in assignment (expression has type "A", variable has type "B") |
| |
| [case testAugmentedAssignmentIntFloat] |
| weight0 = 65.5 |
| reveal_type(weight0) # N: Revealed type is 'builtins.float' |
| if int(): |
| weight0 = 65 |
| reveal_type(weight0) # N: Revealed type is 'builtins.int' |
| weight0 *= 'a' # E: Incompatible types in assignment (expression has type "str", variable has type "float") |
| weight0 *= 0.5 |
| reveal_type(weight0) # N: Revealed type is 'builtins.float' |
| weight0 *= object() # E: Unsupported operand types for * ("float" and "object") |
| reveal_type(weight0) # N: Revealed type is 'builtins.float' |
| |
| [builtins fixtures/float.pyi] |
| |
| [case testAugmentedAssignmentIntFloatMember] |
| class A: |
| def __init__(self) -> None: |
| self.weight0 = 65.5 |
| reveal_type(self.weight0) # N: Revealed type is 'builtins.float' |
| self.weight0 = 65 |
| reveal_type(self.weight0) # N: Revealed type is 'builtins.int' |
| self.weight0 *= 'a' # E: Incompatible types in assignment (expression has type "str", variable has type "float") |
| self.weight0 *= 0.5 |
| reveal_type(self.weight0) # N: Revealed type is 'builtins.float' |
| self.weight0 *= object() # E: Unsupported operand types for * ("float" and "object") |
| reveal_type(self.weight0) # N: Revealed type is 'builtins.float' |
| |
| [builtins fixtures/float.pyi] |
| |
| [case testAugmentedAssignmentIntFloatDict] |
| from typing import Dict |
| d = {'weight0': 65.5} |
| reveal_type(d['weight0']) # N: Revealed type is 'builtins.float*' |
| d['weight0'] = 65 |
| reveal_type(d['weight0']) # N: Revealed type is 'builtins.float*' |
| d['weight0'] *= 'a' # E: Unsupported operand types for * ("float" and "str") |
| d['weight0'] *= 0.5 |
| reveal_type(d['weight0']) # N: Revealed type is 'builtins.float*' |
| d['weight0'] *= object() # E: Unsupported operand types for * ("float" and "object") |
| reveal_type(d['weight0']) # N: Revealed type is 'builtins.float*' |
| |
| [builtins fixtures/floatdict.pyi] |
| |
| [case testForwardRefsInForStatementImplicit] |
| from typing import List, NamedTuple |
| lst: List[N] |
| |
| for i in lst: |
| reveal_type(i.x) # N: Revealed type is 'builtins.int' |
| a: str = i[0] # E: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| N = NamedTuple('N', [('x', int)]) |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testForwardRefsInForStatement] |
| from typing import List, NamedTuple |
| lst: List[M] |
| |
| for i in lst: # type: N |
| reveal_type(i.x) # N: Revealed type is 'builtins.int' |
| a: str = i[0] # E: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| N = NamedTuple('N', [('x', int)]) |
| class M(N): pass |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testForwardRefsInWithStatementImplicit] |
| from typing import ContextManager, Any |
| from mypy_extensions import TypedDict |
| cm: ContextManager[N] |
| |
| with cm as g: |
| a: int = g['x'] |
| |
| N = TypedDict('N', {'x': int}) |
| [builtins fixtures/dict.pyi] |
| [typing fixtures/typing-medium.pyi] |
| [out] |
| |
| [case testForwardRefsInWithStatement] |
| from typing import ContextManager, Any |
| from mypy_extensions import TypedDict |
| cm: ContextManager[Any] |
| |
| with cm as g: # type: N |
| a: str = g['x'] # E: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| N = TypedDict('N', {'x': int}) |
| [builtins fixtures/dict.pyi] |
| [typing fixtures/typing-medium.pyi] |
| [out] |
| |
| [case testGlobalWithoutInitialization] |
| |
| from typing import List |
| |
| def foo() -> None: |
| global bar |
| # TODO: Confusing error message |
| bar = [] # type: List[str] # E: Name 'bar' already defined (possibly by an import) |
| bar # E: Name 'bar' is not defined |
| |
| def foo2(): |
| global bar2 |
| bar2 = [] # type: List[str] |
| bar2 |
| [builtins fixtures/list.pyi] |