| -- 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() # E: No return value expected |
| [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 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] |
| |
| |
| -- 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 |
| [out] |
| main:3: error: Unsupported operand types for + ("A" and "B") |
| main:4: error: Result type of + incompatible in assignment |
| 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 |
| [out] |
| main:3: error: Unsupported operand types for - ("A" and "B") |
| main:4: error: Result type of - incompatible in assignment |
| 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 |
| [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 |
| |
| [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 |
| [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 |
| [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 |
| [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 |
| [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): |
| self.a = 0 |
| |
| def __iadd__(self, a): |
| # type: (int) -> A |
| self.a += 1 |
| 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 testRaiseFromStatement] |
| |
| e = None # type: BaseException |
| f = None # type: MyError |
| a = None # type: A |
| raise e from a # E: Exception must be derived from BaseException |
| raise e from e |
| raise e from f |
| 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 |
| x = object() |
| x = B() |
| class A: pass |
| class B: pass |
| [out] |
| main:4: error: Incompatible types in assignment (expression has type "object", variable has type "A") |
| main:5: error: Incompatible types in assignment (expression has type "B", variable has type "A") |
| |
| [case testTypeErrorInvolvingBaseException] |
| |
| x, a = None, None # type: (BaseException, A) |
| a = BaseException() # Fail |
| a = object() # Fail |
| x = object() # Fail |
| x = A() # Fail |
| x = BaseException() |
| class A: pass |
| [builtins fixtures/exception.pyi] |
| [out] |
| main:3: error: Incompatible types in assignment (expression has type "BaseException", variable has type "A") |
| main:4: 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 "BaseException") |
| main:6: error: Incompatible types in assignment (expression has type "A", variable has type "BaseException") |
| |
| [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 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 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) # E: Revealed type is 'builtins.BaseException' |
| except (E1, BaseException) as e2: |
| reveal_type(e2) # E: Revealed type is 'Any' |
| except (E1, E2) as e3: |
| reveal_type(e3) # E: Revealed type is 'Any' |
| except (E1, E2, BaseException) as e4: |
| reveal_type(e4) # E: Revealed type is 'Any' |
| |
| try: pass |
| except E1 as e1: |
| reveal_type(e1) # E: Revealed type is 'Any' |
| except E2 as e2: |
| reveal_type(e2) # E: 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 |
| 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) |
| 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) |
| 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 |
| 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) |
| x = f() |
| [builtins fixtures/exception.pyi] |
| [out] |
| main:11: error: Revealed type is 'builtins.int' |
| main:16: error: 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) |
| x = f() |
| [builtins fixtures/exception.pyi] |
| [out] |
| main:10: error: Revealed type is 'builtins.int' |
| main:16: error: 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 |
| x = f() |
| [builtins fixtures/exception.pyi] |
| [out] |
| main:10: error: Revealed type is 'builtins.int' |
| main:15: error: 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 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: error: 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 |
| |
| [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" |
| |
| |
| [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 testDelStatementWithAssignmentClass] |
| class C: |
| a = 1 |
| |
| c = C() |
| c.a = 1 |
| c.a + 1 |
| del c.a |
| c.a + 1 |
| [builtins fixtures/ops.pyi] |
| |
| -- 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" |
| [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 # E: Incompatible types in yield (actual type None, expected type None) |
| [builtins fixtures/for.pyi] |
| [out] |
| |
| |
| -- Yield from statement |
| -- -------------------- |
| |
| -- Iterables |
| -- ---------- |
| |
| [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] |
| |
| -- 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] |
| |
| |
| -- Chained assignment |
| -- ------------------ |
| |
| |
| [case testChainedAssignment] |
| import typing |
| class A: pass |
| class B: pass |
| x = y = A() |
| x = A() |
| y = A() |
| x = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| 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' |
| 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 |
| x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| y = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| x = 1 |
| y = 1 |
| |
| |
| -- Star assignment |
| -- --------------- |
| |
| |
| [case testAssignListToStarExpr] |
| from typing import List |
| bs, cs = None, None # type: List[A], List[B] |
| *bs, b = bs |
| *bs, c = cs # E: Incompatible types in assignment (expression has type List[B], variable has type List[A]) |
| *ns, c = cs |
| 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") |