| -- Test cases for the type checker related to functions, function types and |
| -- calls. |
| |
| -- See also check-varargs.test. |
| |
| |
| -- Callable type basics |
| -- -------------------- |
| |
| |
| [case testCallingVariableWithFunctionType] |
| from typing import Callable |
| f = None # type: Callable[[A], B] |
| a, b = None, None # type: (A, B) |
| if int(): |
| a = f(a) # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| if int(): |
| b = f(b) # E: Argument 1 has incompatible type "B"; expected "A" |
| if int(): |
| b = f() # E: Too few arguments |
| if int(): |
| b = f(a, a) # E: Too many arguments |
| if int(): |
| b = f(a) |
| |
| class A: pass |
| class B: pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testKeywordOnlyArgumentOrderInsensitivity] |
| import typing |
| |
| class A(object): |
| def f(self, *, a: int, b: str) -> None: pass |
| |
| class B(A): |
| def f(self, *, b: str, a: int) -> None: pass |
| |
| class C(A): |
| def f(self, *, b: int, a: str) -> None: pass # Fail |
| [out] |
| main:10: error: Signature of "f" incompatible with supertype "A" |
| main:10: note: Superclass: |
| main:10: note: def f(self, *, a: int, b: str) -> None |
| main:10: note: Subclass: |
| main:10: note: def f(self, *, b: int, a: str) -> None |
| |
| [case testPositionalOverridingArgumentNameInsensitivity] |
| import typing |
| |
| class A(object): |
| def f(self, a: int, b: str) -> None: pass |
| |
| class B(A): |
| def f(self, b: str, a: int) -> None: pass # E: Argument 1 of "f" is incompatible with supertype "A"; supertype defines the argument type as "int" \ |
| # N: This violates the Liskov substitution principle \ |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides \ |
| # E: Argument 2 of "f" is incompatible with supertype "A"; supertype defines the argument type as "str" |
| |
| class C(A): |
| def f(self, foo: int, bar: str) -> None: pass |
| |
| |
| [case testPositionalOverridingArgumentNamesCheckedWhenMismatchingPos] |
| import typing |
| |
| class A(object): |
| def f(self, a: int, b: str) -> None: pass |
| |
| class B(A): |
| def f(self, b: int, a: str) -> None: pass # Fail |
| [out] |
| main:7: error: Signature of "f" incompatible with supertype "A" |
| main:7: note: Superclass: |
| main:7: note: def f(self, a: int, b: str) -> None |
| main:7: note: Subclass: |
| main:7: note: def f(self, b: int, a: str) -> None |
| |
| [case testSubtypingFunctionTypes] |
| from typing import Callable |
| |
| class A: pass |
| class B(A): pass |
| |
| f = None # type: Callable[[B], A] |
| g = None # type: Callable[[A], A] # subtype of f |
| h = None # type: Callable[[B], B] # subtype of f |
| if int(): |
| g = h # E: Incompatible types in assignment (expression has type "Callable[[B], B]", variable has type "Callable[[A], A]") |
| if int(): |
| h = f # E: Incompatible types in assignment (expression has type "Callable[[B], A]", variable has type "Callable[[B], B]") |
| if int(): |
| h = g # E: Incompatible types in assignment (expression has type "Callable[[A], A]", variable has type "Callable[[B], B]") |
| if int(): |
| g = f # E: Incompatible types in assignment (expression has type "Callable[[B], A]", variable has type "Callable[[A], A]") |
| if int(): |
| f = g |
| if int(): |
| f = h |
| if int(): |
| f = f |
| if int(): |
| g = g |
| if int(): |
| h = h |
| |
| [case testSubtypingFunctionsDoubleCorrespondence] |
| |
| def l(x) -> None: ... |
| def r(__, *, x) -> None: ... |
| r = l # E: Incompatible types in assignment (expression has type "Callable[[Any], None]", variable has type "Callable[[Any, NamedArg(Any, 'x')], None]") |
| |
| [case testSubtypingFunctionsRequiredLeftArgNotPresent] |
| |
| def l(x, y) -> None: ... |
| def r(x) -> None: ... |
| r = l # E: Incompatible types in assignment (expression has type "Callable[[Any, Any], None]", variable has type "Callable[[Any], None]") |
| |
| [case testSubtypingFunctionsImplicitNames] |
| from typing import Any |
| |
| def f(a, b): pass |
| def g(c: Any, d: Any) -> Any: pass |
| |
| ff = f |
| gg = g |
| |
| gg = f |
| ff = g |
| |
| [case testSubtypingFunctionsDefaultsNames] |
| from typing import Callable |
| |
| def f(a: int, b: str) -> None: pass |
| f_nonames = None # type: Callable[[int, str], None] |
| def g(a: int, b: str = "") -> None: pass |
| def h(aa: int, b: str = "") -> None: pass |
| |
| ff_nonames = f_nonames |
| ff = f |
| gg = g |
| hh = h |
| |
| if int(): |
| ff = gg |
| if int(): |
| ff_nonames = ff |
| if int(): |
| ff_nonames = f_nonames # reset |
| if int(): |
| ff = ff_nonames # E: Incompatible types in assignment (expression has type "Callable[[int, str], None]", variable has type "Callable[[Arg(int, 'a'), Arg(str, 'b')], None]") |
| if int(): |
| ff = f # reset |
| if int(): |
| gg = ff # E: Incompatible types in assignment (expression has type "Callable[[Arg(int, 'a'), Arg(str, 'b')], None]", variable has type "Callable[[Arg(int, 'a'), DefaultArg(str, 'b')], None]") |
| if int(): |
| gg = hh # E: Incompatible types in assignment (expression has type "Callable[[Arg(int, 'aa'), DefaultArg(str, 'b')], None]", variable has type "Callable[[Arg(int, 'a'), DefaultArg(str, 'b')], None]") |
| |
| [case testSubtypingFunctionsArgsKwargs] |
| from typing import Any, Callable |
| |
| def everything(*args: Any, **kwargs: Any) -> None: pass |
| everywhere = None # type: Callable[..., None] |
| |
| def specific_1(a: int, b: str) -> None: pass |
| def specific_2(a: int, *, b: str) -> None: pass |
| |
| ss_1 = specific_1 |
| ss_2 = specific_2 |
| ee_def = everything |
| ee_var = everywhere |
| |
| if int(): |
| ss_1 = ee_def |
| if int(): |
| ss_1 = specific_1 |
| if int(): |
| ss_2 = ee_def |
| if int(): |
| ss_2 = specific_2 |
| if int(): |
| ee_def = everywhere |
| if int(): |
| ee_def = everything |
| if int(): |
| ee_var = everything |
| if int(): |
| ee_var = everywhere |
| |
| if int(): |
| ee_var = specific_1 # The difference between Callable[..., blah] and one with a *args: Any, **kwargs: Any is that the ... goes loosely both ways. |
| if int(): |
| ee_def = specific_1 # E: Incompatible types in assignment (expression has type "Callable[[int, str], None]", variable has type "Callable[[VarArg(Any), KwArg(Any)], None]") |
| |
| [builtins fixtures/dict.pyi] |
| |
| [case testSubtypingFunctionsDecorated] |
| from typing import Any |
| |
| # untyped decorator |
| def deco(f): pass |
| |
| class A: |
| @deco |
| def f(self) -> Any: |
| pass |
| |
| class B(A): |
| @deco |
| def f(self) -> Any: |
| pass |
| |
| [builtins fixtures/list.pyi] |
| |
| |
| [case testLackOfNames] |
| def f(__a: int, __b: str) -> None: pass |
| def g(a: int, b: str) -> None: pass |
| |
| ff = f |
| gg = g |
| |
| if int(): |
| ff = g |
| if int(): |
| gg = f # E: Incompatible types in assignment (expression has type "Callable[[int, str], None]", variable has type "Callable[[Arg(int, 'a'), Arg(str, 'b')], None]") |
| |
| [case testLackOfNamesFastparse] |
| def f(__a: int, __b: str) -> None: pass |
| def g(a: int, b: str) -> None: pass |
| |
| ff = f |
| gg = g |
| |
| if int(): |
| ff = g |
| if int(): |
| gg = f # E: Incompatible types in assignment (expression has type "Callable[[int, str], None]", variable has type "Callable[[Arg(int, 'a'), Arg(str, 'b')], None]") |
| |
| [case testFunctionTypeCompatibilityWithOtherTypes] |
| from typing import Callable |
| f = None # type: Callable[[], None] |
| a, o = None, None # type: (A, object) |
| if int(): |
| a = f # E: Incompatible types in assignment (expression has type "Callable[[], None]", variable has type "A") |
| if int(): |
| f = a # E: Incompatible types in assignment (expression has type "A", variable has type "Callable[[], None]") |
| if int(): |
| f = o # E: Incompatible types in assignment (expression has type "object", variable has type "Callable[[], None]") |
| if int(): |
| f = f() # E: Function does not return a value |
| |
| if int(): |
| f = f |
| if int(): |
| f = None |
| if int(): |
| o = f |
| |
| class A: pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testReturnEmptyTuple] |
| from typing import Tuple |
| def f(x): # type: (int) -> () # E: Syntax error in type annotation \ |
| # N: Suggestion: Use Tuple[()] instead of () for an empty tuple, or None for a function without a return value |
| pass |
| |
| def g(x: int) -> Tuple[()]: |
| pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testFunctionSubtypingWithVoid] |
| from typing import Callable |
| f = None # type: Callable[[], None] |
| g = None # type: Callable[[], object] |
| if int(): |
| f = g # E: Incompatible types in assignment (expression has type "Callable[[], object]", variable has type "Callable[[], None]") |
| if int(): |
| g = f # OK |
| |
| if int(): |
| f = f |
| if int(): |
| g = g |
| |
| [case testFunctionSubtypingWithMultipleArgs] |
| from typing import Callable |
| f = None # type: Callable[[A, A], None] |
| g = None # type: Callable[[A, B], None] |
| h = None # type: Callable[[B, B], None] |
| if int(): |
| f = g # E: Incompatible types in assignment (expression has type "Callable[[A, B], None]", variable has type "Callable[[A, A], None]") |
| if int(): |
| f = h # E: Incompatible types in assignment (expression has type "Callable[[B, B], None]", variable has type "Callable[[A, A], None]") |
| if int(): |
| g = h # E: Incompatible types in assignment (expression has type "Callable[[B, B], None]", variable has type "Callable[[A, B], None]") |
| if int(): |
| g = f |
| if int(): |
| h = f |
| if int(): |
| h = g |
| if int(): |
| f = f |
| if int(): |
| g = g |
| if int(): |
| h = h |
| |
| class A: pass |
| class B(A): pass |
| |
| [case testFunctionTypesWithDifferentArgumentCounts] |
| from typing import Callable |
| f = None # type: Callable[[], None] |
| g = None # type: Callable[[A], None] |
| h = None # type: Callable[[A, A], None] |
| |
| if int(): |
| f = g # E: Incompatible types in assignment (expression has type "Callable[[A], None]", variable has type "Callable[[], None]") |
| if int(): |
| f = h # E: Incompatible types in assignment (expression has type "Callable[[A, A], None]", variable has type "Callable[[], None]") |
| if int(): |
| h = f # E: Incompatible types in assignment (expression has type "Callable[[], None]", variable has type "Callable[[A, A], None]") |
| if int(): |
| h = g # E: Incompatible types in assignment (expression has type "Callable[[A], None]", variable has type "Callable[[A, A], None]") |
| |
| if int(): |
| f = f |
| if int(): |
| g = g |
| if int(): |
| h = h |
| |
| class A: pass |
| [out] |
| |
| [case testCompatibilityOfSimpleTypeObjectWithStdType] |
| t = None # type: type |
| a = None # type: A |
| |
| if int(): |
| a = A # E: Incompatible types in assignment (expression has type "Type[A]", variable has type "A") |
| if int(): |
| t = f # E: Incompatible types in assignment (expression has type "Callable[[], None]", variable has type "type") |
| if int(): |
| t = A |
| |
| class A: |
| def __init__(self, a: 'A') -> None: pass |
| |
| def f() -> None: pass |
| |
| [case testFunctionTypesWithOverloads] |
| from foo import * |
| [file foo.pyi] |
| from typing import Callable, overload |
| f = None # type: Callable[[AA], A] |
| g = None # type: Callable[[B], B] |
| h = None # type: Callable[[A], AA] |
| |
| if int(): |
| h = i # E: Incompatible types in assignment (expression has type overloaded function, variable has type "Callable[[A], AA]") |
| if int(): |
| f = j |
| |
| if int(): |
| f = i |
| if int(): |
| g = i |
| if int(): |
| g = j |
| |
| class A: pass |
| class AA(A): pass |
| |
| class B: pass |
| |
| @overload |
| def i(x: AA) -> A: |
| pass |
| @overload |
| def i(x: B) -> B: |
| pass |
| |
| @overload |
| def j(x: B) -> B: |
| pass |
| @overload |
| def j(x: A) -> AA: |
| pass |
| |
| [case testOverloadWithThreeItems] |
| from foo import * |
| [file foo.pyi] |
| from typing import Callable, overload |
| g1 = None # type: Callable[[A], A] |
| g2 = None # type: Callable[[B], B] |
| g3 = None # type: Callable[[C], C] |
| g4 = None # type: Callable[[A], B] |
| a, b, c = None, None, None # type: (A, B, C) |
| |
| if int(): |
| b = f(a) # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| if int(): |
| a = f(b) # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| if int(): |
| b = f(c) # E: Incompatible types in assignment (expression has type "C", variable has type "B") |
| if int(): |
| g4 = f # E: Incompatible types in assignment (expression has type overloaded function, variable has type "Callable[[A], B]") |
| |
| if int(): |
| g1 = f |
| if int(): |
| g2 = f |
| if int(): |
| g3 = f |
| if int(): |
| a = f(a) |
| if int(): |
| b = f(b) |
| if int(): |
| c = f(c) |
| |
| class A: pass |
| class B: pass |
| class C: pass |
| |
| @overload |
| def f(x: A) -> A: pass |
| @overload |
| def f(x: B) -> B: pass |
| @overload |
| def f(x: C) -> C: pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testInferConstraintsUnequalLengths] |
| from typing import Any, Callable, List |
| def f(fields: List[Callable[[Any], Any]]): pass |
| class C: pass |
| f([C]) # E: List item 0 has incompatible type "Type[C]"; expected "Callable[[Any], Any]" |
| class D: |
| def __init__(self, a, b): pass |
| f([D]) # E: List item 0 has incompatible type "Type[D]"; expected "Callable[[Any], Any]" |
| [builtins fixtures/list.pyi] |
| |
| [case testSubtypingTypeTypeAsCallable] |
| from typing import Callable, Type |
| class A: pass |
| x = None # type: Callable[..., A] |
| y = None # type: Type[A] |
| x = y |
| |
| [case testSubtypingCallableAsTypeType] |
| from typing import Callable, Type |
| class A: pass |
| x = None # type: Callable[..., A] |
| y = None # type: Type[A] |
| if int(): |
| y = x # E: Incompatible types in assignment (expression has type "Callable[..., A]", variable has type "Type[A]") |
| |
| -- Default argument values |
| -- ----------------------- |
| |
| |
| [case testCallingFunctionsWithDefaultArgumentValues] |
| |
| a, b = None, None # type: (A, B) |
| if int(): |
| a = f() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| if int(): |
| b = f(b) # E: Argument 1 to "f" has incompatible type "B"; expected "Optional[A]" |
| if int(): |
| b = f(a, a) # E: Too many arguments for "f" |
| |
| if int(): |
| b = f() |
| if int(): |
| b = f(a) |
| if int(): |
| b = f(AA()) |
| |
| def f(x: 'A' = None) -> 'B': pass |
| |
| class A: pass |
| class AA(A): pass |
| class B: pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testDefaultArgumentExpressions] |
| import typing |
| def f(x: 'A' = A()) -> None: |
| b = x # type: B # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| a = x # type: A |
| |
| class B: pass |
| class A: pass |
| [out] |
| |
| [case testDefaultArgumentExpressions2] |
| import typing |
| def f(x: 'A' = B()) -> None: # E: Incompatible default for argument "x" (default has type "B", argument has type "A") |
| b = x # type: B # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| a = x # type: A |
| |
| class B: pass |
| class A: pass |
| |
| [case testDefaultArgumentExpressionsGeneric] |
| from typing import TypeVar |
| T = TypeVar('T', bound='A') |
| def f(x: T = B()) -> None: # E: Incompatible default for argument "x" (default has type "B", argument has type "T") |
| b = x # type: B # E: Incompatible types in assignment (expression has type "T", variable has type "B") |
| a = x # type: A |
| |
| class B: pass |
| class A: pass |
| |
| [case testDefaultArgumentExpressionsPython2] |
| # flags: --python-version 2.7 |
| from typing import Tuple |
| def f(x = B()): # E: Incompatible default for argument "x" (default has type "B", argument has type "A") |
| # type: (A) -> None |
| b = x # type: B # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| a = x # type: A |
| |
| class B: pass |
| class A: pass |
| |
| [case testDefaultTupleArgumentExpressionsPython2] |
| # flags: --python-version 2.7 |
| from typing import Tuple |
| def f((x, y) = (A(), B())): # E: Incompatible default for tuple argument 1 (default has type "Tuple[A, B]", argument has type "Tuple[B, B]") |
| # type: (Tuple[B, B]) -> None |
| b = x # type: B |
| a = x # type: A # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| def g(a, (x, y) = (A(),)): # E: Incompatible default for tuple argument 2 (default has type "Tuple[A]", argument has type "Tuple[B, B]") |
| # type: (int, Tuple[B, B]) -> None |
| pass |
| def h((x, y) = (A(), B(), A())): # E: Incompatible default for tuple argument 1 (default has type "Tuple[A, B, A]", argument has type "Tuple[B, B]") |
| # type: (Tuple[B, B]) -> None |
| pass |
| |
| class B: pass |
| class A: pass |
| |
| [case testDefaultArgumentsWithSubtypes] |
| import typing |
| def f(x: 'B' = A()) -> None: # E: Incompatible default for argument "x" (default has type "A", argument has type "B") |
| pass |
| def g(x: 'A' = B()) -> None: |
| pass |
| |
| class A: pass |
| class B(A): pass |
| [out] |
| |
| [case testMultipleDefaultArgumentExpressions] |
| import typing |
| def f(x: 'A' = B(), y: 'B' = B()) -> None: # E: Incompatible default for argument "x" (default has type "B", argument has type "A") |
| pass |
| def h(x: 'A' = A(), y: 'B' = B()) -> None: |
| pass |
| |
| class A: pass |
| class B: pass |
| [out] |
| |
| [case testMultipleDefaultArgumentExpressions2] |
| import typing |
| def g(x: 'A' = A(), y: 'B' = A()) -> None: # E: Incompatible default for argument "y" (default has type "A", argument has type "B") |
| pass |
| |
| class A: pass |
| class B: pass |
| [out] |
| |
| [case testDefaultArgumentsAndSignatureAsComment] |
| import typing |
| def f(x = 1): # type: (int) -> str |
| pass |
| f() |
| f(1) |
| f('') # E: Argument 1 to "f" has incompatible type "str"; expected "int" |
| |
| [case testMethodDefaultArgumentsAndSignatureAsComment] |
| import typing |
| class A: |
| def f(self, x = 1): # type: (int) -> str |
| pass |
| A().f() |
| A().f(1) |
| A().f('') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int" |
| |
| |
| -- Access to method defined as a data attribute |
| -- -------------------------------------------- |
| |
| |
| [case testMethodAsDataAttribute] |
| from typing import Any, Callable |
| class B: pass |
| x = None # type: Any |
| class A: |
| f = x # type: Callable[[A], None] |
| g = x # type: Callable[[A, B], None] |
| a = None # type: A |
| a.f() |
| a.g(B()) |
| a.f(a) # E: Too many arguments |
| a.g() # E: Too few arguments |
| |
| [case testMethodWithInvalidMethodAsDataAttribute] |
| from typing import Any, Callable |
| class B: pass |
| x = None # type: Any |
| class A: |
| f = x # type: Callable[[], None] |
| g = x # type: Callable[[B], None] |
| a = None # type: A |
| a.f() # E: Attribute function "f" with type "Callable[[], None]" does not accept self argument |
| a.g() # E: Invalid self argument "A" to attribute function "g" with type "Callable[[B], None]" |
| |
| [case testMethodWithDynamicallyTypedMethodAsDataAttribute] |
| from typing import Any, Callable |
| class B: pass |
| x = None # type: Any |
| class A: |
| f = x # type: Callable[[Any], Any] |
| a = None # type: A |
| a.f() |
| a.f(a) # E: Too many arguments |
| |
| [case testOverloadedMethodAsDataAttribute] |
| from foo import * |
| [file foo.pyi] |
| from typing import overload |
| class B: pass |
| class A: |
| @overload |
| def f(self) -> None: pass |
| @overload |
| def f(self, b: B) -> None: pass |
| g = f |
| a = None # type: A |
| a.g() |
| a.g(B()) |
| a.g(a) # E: No overload variant matches argument type "A" \ |
| # N: Possible overload variants: \ |
| # N: def f(self) -> None \ |
| # N: def f(self, b: B) -> None |
| |
| [case testMethodAsDataAttributeInferredFromDynamicallyTypedMethod] |
| |
| class A: |
| def f(self, x): pass |
| g = f |
| a = None # type: A |
| a.g(object()) |
| a.g(a, a) # E: Too many arguments |
| a.g() # E: Too few arguments |
| |
| [case testMethodAsDataAttributeInGenericClass] |
| from typing import TypeVar, Generic |
| t = TypeVar('t') |
| class B: pass |
| class A(Generic[t]): |
| def f(self, x: t) -> None: pass |
| g = f |
| a = None # type: A[B] |
| a.g(B()) |
| a.g(a) # E: Argument 1 has incompatible type "A[B]"; expected "B" |
| |
| [case testInvalidMethodAsDataAttributeInGenericClass] |
| from typing import Any, TypeVar, Generic, Callable |
| t = TypeVar('t') |
| class B: pass |
| class C: pass |
| x = None # type: Any |
| class A(Generic[t]): |
| f = x # type: Callable[[A[B]], None] |
| ab = None # type: A[B] |
| ac = None # type: A[C] |
| ab.f() |
| ac.f() # E: Invalid self argument "A[C]" to attribute function "f" with type "Callable[[A[B]], None]" |
| |
| [case testPartiallyTypedSelfInMethodDataAttribute] |
| from typing import Any, TypeVar, Generic, Callable |
| t = TypeVar('t') |
| class B: pass |
| class C: pass |
| x = None # type: Any |
| class A(Generic[t]): |
| f = x # type: Callable[[A], None] |
| ab = None # type: A[B] |
| ac = None # type: A[C] |
| ab.f() |
| ac.f() |
| |
| [case testCallableDataAttribute] |
| from typing import Callable |
| class A: |
| g = None # type: Callable[[A], None] |
| def __init__(self, f: Callable[[], None]) -> None: |
| self.f = f |
| a = A(None) |
| a.f() |
| a.g() |
| a.f(a) # E: Too many arguments |
| a.g(a) # E: Too many arguments |
| |
| |
| -- Nested functions |
| -- ---------------- |
| |
| |
| [case testSimpleNestedFunction] |
| import typing |
| def f(a: 'A') -> None: |
| def g(b: 'B') -> None: |
| if int(): |
| b = a \ |
| # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| aa = a # type: A # ok |
| b = B() |
| g(a) # E: Argument 1 to "g" has incompatible type "A"; expected "B" |
| g(B()) |
| class A: pass |
| class B: pass |
| |
| [case testReturnAndNestedFunction] |
| import typing |
| def f() -> 'A': |
| def g() -> 'B': |
| return A() # fail |
| return B() |
| return B() # fail |
| return A() |
| class A: pass |
| class B: pass |
| [out] |
| main:4: error: Incompatible return value type (got "A", expected "B") |
| main:6: error: Incompatible return value type (got "B", expected "A") |
| |
| [case testDynamicallyTypedNestedFunction] |
| import typing |
| def f(x: object) -> None: |
| def g(y): |
| pass |
| g() # E: Missing positional argument "y" in call to "g" |
| g(x) |
| [out] |
| |
| [case testNestedFunctionInMethod] |
| import typing |
| class A: |
| def f(self) -> None: |
| def g(x: int) -> None: |
| y = x # type: int |
| a = x # type: A # fail |
| g(2) |
| g(A()) # fail |
| [out] |
| main:6: error: Incompatible types in assignment (expression has type "int", variable has type "A") |
| main:8: error: Argument 1 to "g" has incompatible type "A"; expected "int" |
| |
| [case testNestedFunctionInMethodWithTooFewArgumentsInTypeComment] |
| class A: |
| def f(self): |
| # type: () -> None |
| def g(x): # E: Type signature has too few arguments |
| # type: () -> None |
| pass |
| |
| [case testDeepNestedFunctionWithTooFewArgumentsInTypeComment] |
| class A: |
| def f(self): |
| # type: () -> None |
| class B: |
| def g(self): |
| # type: () -> None |
| def h(x): # E: Type signature has too few arguments |
| # type: () -> None |
| pass |
| |
| [case testDeepNestedMethodInTypeComment] |
| class A: |
| def f(self): |
| # type: () -> None |
| class B: |
| class C: |
| def g(self): |
| # type: () -> None |
| pass |
| |
| [case testMutuallyRecursiveNestedFunctions] |
| def f() -> None: |
| def g() -> None: |
| h(1) |
| h('') # E |
| def h(x: int) -> None: |
| g() |
| g(1) # E |
| [out] |
| main:4: error: Argument 1 to "h" has incompatible type "str"; expected "int" |
| main:7: error: Too many arguments for "g" |
| |
| [case testMutuallyRecursiveDecoratedFunctions] |
| from typing import Callable, Any |
| def dec(f) -> Callable[..., Any]: pass |
| def f() -> None: |
| @dec |
| def g() -> None: |
| h() |
| h.x # E |
| @dec |
| def h(x: int) -> None: |
| g(1) |
| g.x # E |
| [out] |
| main:7: error: "Callable[..., Any]" has no attribute "x" |
| main:11: error: "Callable[..., Any]" has no attribute "x" |
| |
| [case testNestedGenericFunctions] |
| from typing import TypeVar |
| T = TypeVar('T') |
| U = TypeVar('U') |
| |
| def outer(x: T) -> T: |
| def inner(y: U) -> T: ... |
| return inner(1) |
| |
| |
| -- Casts |
| -- ----- |
| |
| |
| [case testCastsToAndFromFunctionTypes] |
| from typing import TypeVar, Callable, Any, cast |
| t = TypeVar('t') |
| def f(x: t, |
| f1: Callable[[], None], |
| f2: Callable[[Any], None], o: object) -> None: |
| x = cast(t, f1) |
| f1 = cast(Callable[[], None], x) |
| f1 = cast(Callable[[], None], f2) |
| f1 = cast(Callable[[], None], o) |
| |
| |
| -- Function decorators |
| -- ------------------- |
| |
| |
| [case testTrivialStaticallyTypedFunctionDecorator] |
| from typing import TypeVar |
| t = TypeVar('t') |
| def dec(f: t) -> t: |
| return f |
| @dec |
| def f(x: int) -> None: pass |
| f(1) |
| f('x') # E: Argument 1 to "f" has incompatible type "str"; expected "int" |
| |
| [case testTrivialStaticallyTypedMethodDecorator] |
| from typing import TypeVar |
| t = TypeVar('t') |
| def dec(f: t) -> t: |
| return f |
| class A: |
| @dec |
| def f(self, x: int) -> None: pass |
| A().f(1) |
| A().f('') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int" |
| class B: pass |
| |
| [case testTrivialDecoratedNestedFunction] |
| from typing import TypeVar |
| t = TypeVar('t') |
| def dec(f: t) -> t: |
| return f |
| def g() -> None: |
| @dec |
| def f(x: int) -> None: pass |
| f(1) |
| f('') # E: Argument 1 to "f" has incompatible type "str"; expected "int" |
| [out] |
| |
| [case testCheckingDecoratedFunction] |
| import typing |
| def dec(f): pass |
| @dec |
| def f(x: 'A') -> None: |
| a = x # type: A |
| if int(): |
| x = object() # E: Incompatible types in assignment (expression has type "object", variable has type "A") |
| class A: pass |
| [out] |
| |
| [case testDecoratorThatSwitchesType] |
| from typing import Callable |
| def dec(x) -> Callable[[], None]: pass |
| @dec |
| def f(y): pass |
| f() |
| f(None) # E: Too many arguments for "f" |
| |
| [case testDecoratorThatSwitchesTypeWithMethod] |
| from typing import Any, Callable |
| def dec(x) -> Callable[[Any], None]: pass |
| class A: |
| @dec |
| def f(self, a, b, c): pass |
| a = None # type: A |
| a.f() |
| a.f(None) # E: Too many arguments for "f" of "A" |
| |
| [case testNestedDecorators] |
| from typing import Any, Callable |
| def dec1(f: Callable[[Any], None]) -> Callable[[], None]: pass |
| def dec2(f: Callable[[Any, Any], None]) -> Callable[[Any], None]: pass |
| @dec1 |
| @dec2 |
| def f(x, y): pass |
| f() |
| f(None) # E: Too many arguments for "f" |
| |
| [case testInvalidDecorator1] |
| from typing import Any, Callable |
| def dec1(f: Callable[[Any], None]) -> Callable[[], None]: pass |
| def dec2(f: Callable[[Any, Any], None]) -> Callable[[Any], None]: pass |
| @dec1 # E: Argument 1 to "dec2" has incompatible type "Callable[[Any], Any]"; expected "Callable[[Any, Any], None]" |
| @dec2 |
| def f(x): pass |
| |
| [case testInvalidDecorator2] |
| from typing import Any, Callable |
| def dec1(f: Callable[[Any, Any], None]) -> Callable[[], None]: pass |
| def dec2(f: Callable[[Any, Any], None]) -> Callable[[Any], None]: pass |
| @dec1 # E: Argument 1 to "dec1" has incompatible type "Callable[[Any], None]"; expected "Callable[[Any, Any], None]" |
| @dec2 |
| def f(x, y): pass |
| |
| [case testNoTypeCheckDecoratorOnMethod1] |
| from typing import no_type_check |
| |
| @no_type_check |
| def foo(x: 'bar', y: {'x': 4}) -> 42: |
| 1 + 'x' |
| [typing fixtures/typing-medium.pyi] |
| |
| [case testNoTypeCheckDecoratorOnMethod2] |
| import typing |
| |
| @typing.no_type_check |
| def foo(x: 's', y: {'x': 4}) -> 42: |
| 1 + 'x' |
| |
| @typing.no_type_check |
| def bar() -> None: |
| 1 + 'x' |
| [typing fixtures/typing-medium.pyi] |
| |
| [case testCallingNoTypeCheckFunction] |
| import typing |
| |
| @typing.no_type_check |
| def foo(x: {1:2}) -> [1]: |
| 1 + 'x' |
| |
| foo() |
| foo(1, 'b') |
| [typing fixtures/typing-medium.pyi] |
| |
| [case testCallingNoTypeCheckFunction2] |
| import typing |
| |
| def f() -> None: |
| foo() |
| |
| @typing.no_type_check |
| def foo(x: {1:2}) -> [1]: |
| 1 + 'x' |
| [typing fixtures/typing-medium.pyi] |
| |
| [case testNoTypeCheckDecoratorSemanticError] |
| import typing |
| |
| @typing.no_type_check |
| def foo(x: {1:2}) -> [1]: |
| x = y |
| [typing fixtures/typing-medium.pyi] |
| |
| |
| -- Forward references to decorated functions |
| -- ----------------------------------------- |
| |
| |
| [case testForwardReferenceToDynamicallyTypedDecorator] |
| def f(self) -> None: |
| g() |
| g(1) |
| |
| def dec(f): |
| return f |
| |
| @dec |
| def g(): |
| pass |
| |
| [case testForwardReferenceToDecoratorWithAnyReturn] |
| from typing import Any |
| |
| def f(self) -> None: |
| g() |
| g(1) |
| |
| def dec(f) -> Any: |
| return f |
| |
| @dec |
| def g(): |
| pass |
| |
| [case testForwardReferenceToDecoratorWithIdentityMapping] |
| from typing import TypeVar |
| |
| def f(self) -> None: |
| g() |
| g(1) # E: Too many arguments for "g" |
| h(1).x # E: "str" has no attribute "x" |
| h('') # E: Argument 1 to "h" has incompatible type "str"; expected "int" |
| |
| T = TypeVar('T') |
| def dec(f: T) -> T: |
| return f |
| |
| @dec |
| def g(): pass |
| @dec |
| def h(x: int) -> str: pass |
| [out] |
| |
| [case testForwardReferenceToDynamicallyTypedDecoratedMethod] |
| def f(self) -> None: |
| A().f(1).y |
| A().f() |
| |
| class A: |
| @dec |
| def f(self, x): pass |
| |
| def dec(f): return f |
| [builtins fixtures/staticmethod.pyi] |
| |
| [case testForwardReferenceToStaticallyTypedDecoratedMethod] |
| from typing import TypeVar |
| |
| def f(self) -> None: |
| A().f(1).y # E: "str" has no attribute "y" |
| A().f('') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int" |
| |
| class A: |
| @dec |
| def f(self, a: int) -> str: return '' |
| |
| T = TypeVar('T') |
| def dec(f: T) -> T: return f |
| [builtins fixtures/staticmethod.pyi] |
| [out] |
| |
| [case testForwardReferenceToDynamicallyTypedProperty] |
| def f(self) -> None: |
| A().x.y |
| |
| class A: |
| @property |
| def x(self): pass |
| [builtins fixtures/property.pyi] |
| |
| [case testForwardReferenceToStaticallyTypedProperty] |
| def f(self) -> None: |
| A().x.y # E: "int" has no attribute "y" |
| |
| class A: |
| @property |
| def x(self) -> int: return 1 |
| [builtins fixtures/property.pyi] |
| [out] |
| |
| [case testForwardReferenceToDynamicallyTypedStaticMethod] |
| def f(self) -> None: |
| A.x(1).y |
| A.x() # E: Missing positional argument "x" in call to "x" |
| |
| class A: |
| @staticmethod |
| def x(x): pass |
| [builtins fixtures/staticmethod.pyi] |
| [out] |
| |
| [case testForwardReferenceToStaticallyTypedStaticMethod] |
| def f(self) -> None: |
| A.x(1).y # E: "str" has no attribute "y" |
| A.x('') # E: Argument 1 to "x" of "A" has incompatible type "str"; expected "int" |
| |
| class A: |
| @staticmethod |
| def x(a: int) -> str: return '' |
| [builtins fixtures/staticmethod.pyi] |
| [out] |
| |
| [case testForwardReferenceToDynamicallyTypedClassMethod] |
| def f(self) -> None: |
| A.x(1).y |
| A.x() # E: Missing positional argument "a" in call to "x" |
| |
| class A: |
| @classmethod |
| def x(cls, a): pass |
| [builtins fixtures/classmethod.pyi] |
| [out] |
| |
| [case testForwardReferenceToStaticallyTypedClassMethod] |
| def f(self) -> None: |
| A.x(1).y # E: "str" has no attribute "y" |
| A.x('') # E: Argument 1 to "x" of "A" has incompatible type "str"; expected "int" |
| |
| class A: |
| @classmethod |
| def x(cls, x: int) -> str: return '' |
| [builtins fixtures/classmethod.pyi] |
| [out] |
| |
| [case testForwardReferenceToDecoratedFunctionUsingMemberExpr] |
| import m |
| |
| def f(self) -> None: |
| g(1).x # E: "str" has no attribute "x" |
| |
| @m.dec |
| def g(x: int) -> str: pass |
| [file m.py] |
| from typing import TypeVar |
| T = TypeVar('T') |
| def dec(f: T) -> T: |
| return f |
| [out] |
| |
| [case testForwardReferenceToFunctionWithMultipleDecorators] |
| def f(self) -> None: |
| g() |
| g(1) |
| |
| def dec(f): |
| return f |
| |
| @dec |
| @dec2 |
| def g(): |
| pass |
| |
| def dec2(f): |
| return f |
| |
| [case testForwardReferenceToDynamicallyTypedDecoratedStaticMethod] |
| def f(self) -> None: |
| A().f(1).y |
| A().f() |
| A().g(1).y |
| A().g() |
| |
| class A: |
| @dec |
| @staticmethod |
| def f(self, x): pass |
| @staticmethod |
| @dec |
| def g(self, x): pass |
| |
| def dec(f): return f |
| [builtins fixtures/staticmethod.pyi] |
| |
| [case testForwardRefereceToDecoratedFunctionWithCallExpressionDecorator] |
| def f(self) -> None: |
| g() |
| g(1) |
| |
| @dec(1) |
| def g(): pass |
| |
| def dec(f): pass |
| |
| |
| -- Decorator functions in import cycles |
| -- ------------------------------------ |
| |
| |
| [case testDecoratorWithIdentityTypeInImportCycle] |
| import a |
| |
| [file a.py] |
| import b |
| from d import dec |
| @dec |
| def f(x: int) -> None: pass |
| b.g(1) # E |
| |
| [file b.py] |
| import a |
| from d import dec |
| @dec |
| def g(x: str) -> None: pass |
| a.f('') |
| |
| [file d.py] |
| from typing import TypeVar |
| T = TypeVar('T') |
| def dec(f: T) -> T: return f |
| |
| [out] |
| tmp/b.py:5: error: Argument 1 to "f" has incompatible type "str"; expected "int" |
| tmp/a.py:5: error: Argument 1 to "g" has incompatible type "int"; expected "str" |
| |
| [case testDecoratorWithNoAnnotationInImportCycle] |
| import a |
| |
| [file a.py] |
| import b |
| from d import dec |
| @dec |
| def f(x: int) -> None: pass |
| b.g(1, z=4) |
| |
| [file b.py] |
| import a |
| from d import dec |
| @dec |
| def g(x: str) -> None: pass |
| a.f('', y=2) |
| |
| [file d.py] |
| def dec(f): return f |
| |
| [case testDecoratorWithFixedReturnTypeInImportCycle] |
| import a |
| |
| [file a.py] |
| import b |
| from d import dec |
| @dec |
| def f(x: int) -> str: pass |
| b.g(1)() |
| |
| [file b.py] |
| import a |
| from d import dec |
| @dec |
| def g(x: int) -> str: pass |
| a.f(1)() |
| |
| [file d.py] |
| from typing import Callable |
| def dec(f: Callable[[int], str]) -> Callable[[int], str]: return f |
| |
| [out] |
| tmp/b.py:5: error: "str" not callable |
| tmp/a.py:5: error: "str" not callable |
| |
| [case testDecoratorWithCallAndFixedReturnTypeInImportCycle] |
| import a |
| |
| [file a.py] |
| import b |
| from d import dec |
| @dec() |
| def f(x: int) -> str: pass |
| b.g(1)() |
| |
| [file b.py] |
| import a |
| from d import dec |
| @dec() |
| def g(x: int) -> str: pass |
| a.f(1)() |
| |
| [file d.py] |
| from typing import Callable |
| def dec() -> Callable[[Callable[[int], str]], Callable[[int], str]]: pass |
| |
| [out] |
| tmp/b.py:5: error: "str" not callable |
| tmp/a.py:5: error: "str" not callable |
| |
| [case testDecoratorWithCallAndFixedReturnTypeInImportCycleAndDecoratorArgs] |
| import a |
| |
| [file a.py] |
| import b |
| from d import dec |
| @dec(1) |
| def f(x: int) -> str: pass |
| b.g(1)() |
| |
| [file b.py] |
| import a |
| from d import dec |
| @dec(1) |
| def g(x: int) -> str: pass |
| a.f(1)() |
| |
| [file d.py] |
| from typing import Callable |
| def dec(x: str) -> Callable[[Callable[[int], str]], Callable[[int], str]]: pass |
| |
| [out] |
| tmp/b.py:3: error: Argument 1 to "dec" has incompatible type "int"; expected "str" |
| tmp/b.py:5: error: "str" not callable |
| tmp/a.py:3: error: Argument 1 to "dec" has incompatible type "int"; expected "str" |
| tmp/a.py:5: error: "str" not callable |
| |
| [case testUndefinedDecoratorInImportCycle] |
| # cmd: mypy -m foo.base |
| [file foo/__init__.py] |
| import foo.base |
| class Derived(foo.base.Base): |
| def method(self) -> None: pass |
| [file foo/base.py] |
| import foo |
| class Base: |
| @decorator |
| def method(self) -> None: pass |
| [out] |
| tmp/foo/base.py:3: error: Name "decorator" is not defined |
| |
| |
| -- Conditional function definition |
| -- ------------------------------- |
| |
| |
| [case testTypeCheckBodyOfConditionalFunction] |
| from typing import Any |
| x = None # type: Any |
| if x: |
| def f(x: int) -> None: |
| if int(): |
| x = 1 |
| x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| [out] |
| |
| [case testCallConditionalFunction] |
| from typing import Any |
| x = None # type: Any |
| if x: |
| def f(x: int) -> None: pass |
| f(1) |
| f('x') # E: Argument 1 to "f" has incompatible type "str"; expected "int" |
| f(1) |
| f('x') # E: Argument 1 to "f" has incompatible type "str"; expected "int" |
| |
| [case testConditionalFunctionDefinitionWithIfElse] |
| from typing import Any |
| x = None # type: Any |
| if x: |
| def f(x: int) -> None: |
| 'x' + x # fail |
| if int(): |
| x = 1 |
| else: |
| def f(x: int) -> None: |
| x + 'x' # fail |
| if int(): |
| x = 1 |
| f(1) |
| f('x') # fail |
| [builtins fixtures/primitives.pyi] |
| [out] |
| main:5: error: Unsupported operand types for + ("str" and "int") |
| main:10: error: Unsupported operand types for + ("int" and "str") |
| main:14: error: Argument 1 to "f" has incompatible type "str"; expected "int" |
| |
| [case testNestedConditionalFunctionDefinitionWithIfElse] |
| from typing import Any |
| x = None # type: Any |
| def top() -> None: |
| if x: |
| def f(x: int) -> None: |
| if int(): |
| x = 'x' # E: Incompatible types in assignment \ |
| (expression has type "str", variable has type "int") |
| x = 1 |
| else: |
| def f(x: int) -> None: |
| x + 'x' # E: Unsupported operand types for + ("int" and "str") |
| x = 1 |
| f(1) |
| f('x') # E: Argument 1 to "f" has incompatible type "str"; expected "int" |
| |
| [case testUnconditionalRedefinitionOfConditionalFunction] |
| from typing import Any |
| x = None # type: Any |
| if x: |
| def f(): pass |
| def f(): pass # E: Name "f" already defined on line 4 |
| |
| [case testIncompatibleConditionalFunctionDefinition] |
| from typing import Any |
| x = None # type: Any |
| if x: |
| def f(x: int) -> None: pass |
| else: |
| def f(x): pass # E: All conditional function variants must have identical signatures |
| |
| [case testIncompatibleConditionalFunctionDefinition2] |
| from typing import Any |
| x = None # type: Any |
| if x: |
| def f(x: int) -> None: pass |
| else: |
| def f(y: int) -> None: pass # E: All conditional function variants must have identical signatures |
| |
| [case testIncompatibleConditionalFunctionDefinition3] |
| from typing import Any |
| x = None # type: Any |
| if x: |
| def f(x: int) -> None: pass |
| else: |
| def f(x: int = 0) -> None: pass # E: All conditional function variants must have identical signatures |
| |
| [case testConditionalFunctionDefinitionUsingDecorator1] |
| from typing import Callable |
| |
| def dec(f) -> Callable[[int], None]: pass |
| |
| x = int() |
| if x: |
| @dec |
| def f(): pass |
| else: |
| def f(x: int) -> None: pass |
| |
| [case testConditionalFunctionDefinitionUsingDecorator2] |
| from typing import Callable |
| |
| def dec(f) -> Callable[[int], None]: pass |
| |
| x = int() |
| if x: |
| @dec |
| def f(): pass |
| else: |
| def f(x: str) -> None: pass # E: Incompatible redefinition (redefinition with type "Callable[[str], None]", original type "Callable[[int], None]") |
| |
| [case testConditionalFunctionDefinitionUsingDecorator3] |
| |
| from typing import Callable |
| |
| def dec(f) -> Callable[[int], None]: pass |
| |
| x = int() |
| if x: |
| def f(x: int) -> None: pass |
| else: |
| @dec |
| def f(): pass |
| |
| [case testConditionalFunctionDefinitionUsingDecorator4] |
| |
| from typing import Callable |
| |
| def dec(f) -> Callable[[int], None]: pass |
| |
| x = int() |
| if x: |
| def f(x: str) -> None: pass |
| else: |
| # TODO: Complain about incompatible redefinition |
| @dec |
| def f(): pass |
| |
| [case testConditionalRedefinitionOfAnUnconditionalFunctionDefinition1] |
| from typing import Any |
| def f(x: str) -> None: pass |
| x = None # type: Any |
| if x: |
| def f(x: int) -> None: pass # E: All conditional function variants must have identical signatures |
| |
| [case testConditionalRedefinitionOfAnUnconditionalFunctionDefinition2] |
| from typing import Any |
| def f(x: int) -> None: pass # N: "f" defined here |
| x = None # type: Any |
| if x: |
| def f(y: int) -> None: pass # E: All conditional function variants must have identical signatures |
| f(x=1) # The first definition takes precedence. |
| f(y=1) # E: Unexpected keyword argument "y" for "f" |
| |
| [case testRedefineFunctionDefinedAsVariable] |
| def g(): pass |
| f = g |
| if g(): |
| def f(): pass |
| f() |
| f(1) # E: Too many arguments |
| |
| [case testRedefineFunctionDefinedAsVariableInitializedToNone] |
| def g(): pass |
| f = None |
| if g(): |
| def f(): pass |
| f() |
| f(1) # E: Too many arguments for "f" |
| |
| [case testRedefineNestedFunctionDefinedAsVariableInitializedToNone] |
| def g() -> None: |
| f = None |
| if object(): |
| def f(x: int) -> None: pass |
| f() # E: Missing positional argument "x" in call to "f" |
| f(1) |
| f('') # E: Argument 1 to "f" has incompatible type "str"; expected "int" |
| [out] |
| |
| [case testRedefineFunctionDefinedAsVariableWithInvalidSignature] |
| def g(): pass |
| f = g |
| if g(): |
| def f(x): pass # E: Incompatible redefinition (redefinition with type "Callable[[Any], Any]", original type "Callable[[], Any]") |
| |
| [case testRedefineFunctionDefinedAsVariableWithVariance1] |
| class B: pass |
| class C(B): pass |
| def g(x: C) -> B: pass |
| f = g |
| if g(C()): |
| def f(x: C) -> C: pass |
| |
| [case testRedefineFunctionDefinedAsVariableWithVariance2] |
| class B: pass |
| class C(B): pass |
| def g(x: C) -> B: pass |
| f = g |
| if g(C()): |
| def f(x: B) -> B: pass |
| |
| [case testRedefineFunctionDefinedAsVariableInitializedToEmptyList] |
| f = [] # E: Need type annotation for "f" (hint: "f: List[<type>] = ...") |
| if object(): |
| def f(): pass # E: Incompatible redefinition |
| f() # E: "List[Any]" not callable |
| f(1) # E: "List[Any]" not callable |
| [builtins fixtures/list.pyi] |
| |
| [case testDefineConditionallyAsImportedAndDecorated] |
| from typing import Callable |
| |
| def dec(f: Callable[[], None]) -> Callable[[], None]: ... |
| |
| if int(): |
| from m import f |
| else: |
| @dec |
| def f(): |
| yield |
| [file m.py] |
| def f(): pass |
| |
| [case testDefineConditionallyAsImportedAndDecoratedWithInference] |
| if int(): |
| from m import f |
| else: |
| from contextlib import contextmanager |
| |
| @contextmanager |
| def f(): |
| yield |
| [file m.py] |
| from contextlib import contextmanager |
| |
| @contextmanager |
| def f(): |
| yield |
| [typing fixtures/typing-medium.pyi] |
| [builtins fixtures/tuple.pyi] |
| |
| |
| -- Conditional method definition |
| -- ----------------------------- |
| |
| |
| [case testTypeCheckBodyOfConditionalMethod] |
| from typing import Any |
| x = None # type: Any |
| class A: |
| if x: |
| def f(self, x: int) -> None: |
| if int(): |
| x = 1 |
| x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| [out] |
| |
| [case testCallConditionalMethodInClassBody] |
| from typing import Any |
| x = None # type: Any |
| class A: |
| if x: |
| def f(self, x: int) -> None: pass |
| f(x, 1) |
| f(x, 'x') # E: Argument 2 to "f" of "A" has incompatible type "str"; expected "int" |
| f(x, 1) |
| f(x, 'x') # E: Argument 2 to "f" of "A" has incompatible type "str"; expected "int" |
| [out] |
| |
| [case testCallConditionalMethodViaInstance] |
| from typing import Any |
| x = None # type: Any |
| class A: |
| if x: |
| def f(self, x: int) -> None: pass |
| A().f(1) |
| A().f('x') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int" |
| |
| [case testConditionalMethodDefinitionWithIfElse] |
| from typing import Any |
| x = None # type: Any |
| class A: |
| if x: |
| def f(self, x: int) -> None: |
| 'x' + x # fail |
| if int(): |
| x = 1 |
| else: |
| def f(self, x: int) -> None: |
| x + 'x' # fail |
| if int(): |
| x = 1 |
| A().f(1) |
| A().f('x') # fail |
| [builtins fixtures/primitives.pyi] |
| [out] |
| main:6: error: Unsupported operand types for + ("str" and "int") |
| main:11: error: Unsupported operand types for + ("int" and "str") |
| main:15: error: Argument 1 to "f" of "A" has incompatible type "str"; expected "int" |
| |
| [case testUnconditionalRedefinitionOfConditionalMethod] |
| from typing import Any |
| x = None # type: Any |
| class A: |
| if x: |
| def f(self): pass |
| def f(self): pass # E: Name "f" already defined on line 5 |
| |
| [case testIncompatibleConditionalMethodDefinition] |
| from typing import Any |
| x = None # type: Any |
| class A: |
| if x: |
| def f(self, x: int) -> None: pass |
| else: |
| def f(self, x): pass # E: All conditional function variants must have identical signatures |
| [out] |
| |
| [case testConditionalFunctionDefinitionInTry] |
| import typing |
| try: |
| def f(x: int) -> None: pass |
| except: |
| def g(x: str) -> None: pass |
| f(1) |
| f('x') # E: Argument 1 to "f" has incompatible type "str"; expected "int" |
| g('x') |
| g(1) # E: Argument 1 to "g" has incompatible type "int"; expected "str" |
| |
| [case testConditionalMethodDefinitionUsingDecorator] |
| from typing import Callable |
| |
| def dec(f) -> Callable[['A', int], None]: pass |
| |
| class A: |
| x = int() |
| if x: |
| @dec |
| def f(self): pass |
| else: |
| def f(self, x: int) -> None: pass |
| |
| |
| -- Callable with specific arg list |
| -- ------------------------------- |
| |
| |
| [case testCallableWithNamedArg] |
| from typing import Callable |
| from mypy_extensions import Arg |
| |
| def a(f: Callable[[Arg(int, 'x')], int]): |
| f(x=4) |
| f(5) |
| f(y=3) # E: Unexpected keyword argument "y" |
| |
| [builtins fixtures/dict.pyi] |
| |
| [case testCallableWithOptionalArg] |
| from typing import Callable |
| from mypy_extensions import DefaultArg |
| |
| def a(f: Callable[[DefaultArg(int, 'x')], int]): |
| f(x=4) |
| f(2) |
| f() |
| f(y=3) # E: Unexpected keyword argument "y" |
| f("foo") # E: Argument 1 has incompatible type "str"; expected "int" |
| [builtins fixtures/dict.pyi] |
| |
| [case testCallableWithNamedArgFromExpr] |
| from typing import Callable |
| from mypy_extensions import Arg |
| |
| F = Callable[[Arg(int, 'x')], int] |
| |
| def a(f: F): |
| f(x=4) |
| f(5) |
| f(y=3) # E: Unexpected keyword argument "y" |
| |
| [builtins fixtures/dict.pyi] |
| |
| [case testCallableWithOptionalArgFromExpr] |
| from typing import Callable |
| from mypy_extensions import DefaultArg |
| |
| F = Callable[[DefaultArg(int, 'x')], int] |
| def a(f: F): |
| f(x=4) |
| f(2) |
| f() |
| f(y=3) # E: Unexpected keyword argument "y" |
| f("foo") # E: Argument 1 has incompatible type "str"; expected "int" |
| [builtins fixtures/dict.pyi] |
| |
| [case testCallableParsingInInheritence] |
| |
| from collections import namedtuple |
| class C(namedtuple('t', 'x')): |
| pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testCallableParsingSameName] |
| from typing import Callable |
| |
| def Arg(x, y): pass |
| |
| F = Callable[[Arg(int, 'x')], int] # E: Invalid argument constructor "__main__.Arg" |
| |
| [case testCallableParsingFromExpr] |
| |
| from typing import Callable, List |
| from mypy_extensions import Arg, VarArg, KwArg |
| import mypy_extensions |
| |
| def WrongArg(x, y): return y |
| # Note that for this test, the 'Value of type "int" is not indexable' errors are silly, |
| # and a consequence of Callable being set to an int in the test stub. We can't set it to |
| # something else sensible, because other tests require the stub not have anything |
| # that looks like a function call. |
| F = Callable[[WrongArg(int, 'x')], int] # E: Invalid argument constructor "__main__.WrongArg" |
| G = Callable[[Arg(1, 'x')], int] # E: Invalid type: try using Literal[1] instead? |
| H = Callable[[VarArg(int, 'x')], int] # E: VarArg arguments should not have names |
| I = Callable[[VarArg(int)], int] # ok |
| J = Callable[[VarArg(), KwArg()], int] # ok |
| K = Callable[[VarArg(), int], int] # E: Required positional args may not appear after default, named or var args |
| L = Callable[[Arg(name='x', type=int)], int] # ok |
| # I have commented out the following test because I don't know how to expect the "defined here" note part of the error. |
| # M = Callable[[Arg(gnome='x', type=int)], int] E: Invalid type alias: expression is not a valid type E: Unexpected keyword argument "gnome" for "Arg" |
| N = Callable[[Arg(name=None, type=int)], int] # ok |
| O = Callable[[List[Arg(int)]], int] # E: Invalid type alias: expression is not a valid type # E: Value of type "int" is not indexable # E: Type expected within [...] # E: The type "Type[List[Any]]" is not generic and not indexable |
| P = Callable[[mypy_extensions.VarArg(int)], int] # ok |
| Q = Callable[[Arg(int, type=int)], int] # E: Invalid type alias: expression is not a valid type # E: Value of type "int" is not indexable # E: "Arg" gets multiple values for keyword argument "type" |
| R = Callable[[Arg(int, 'x', name='y')], int] # E: Invalid type alias: expression is not a valid type # E: Value of type "int" is not indexable # E: "Arg" gets multiple values for keyword argument "name" |
| |
| [builtins fixtures/dict.pyi] |
| |
| [case testCallableParsing] |
| from typing import Callable |
| from mypy_extensions import Arg, VarArg, KwArg |
| |
| def WrongArg(x, y): return y |
| |
| def b(f: Callable[[Arg(1, 'x')], int]): pass # Invalid type. Try using Literal[1] instead? |
| def d(f: Callable[[VarArg(int)], int]): pass # ok |
| def e(f: Callable[[VarArg(), KwArg()], int]): pass # ok |
| def g(f: Callable[[Arg(name='x', type=int)], int]): pass # ok |
| def h(f: Callable[[Arg(gnome='x', type=int)], int]): pass # E: Unexpected argument "gnome" for argument constructor |
| def i(f: Callable[[Arg(name=None, type=int)], int]): pass # ok |
| def j(f: Callable[[Arg(int, 'x', name='y')], int]): pass # E: "Arg" gets multiple values for keyword argument "name" |
| def k(f: Callable[[Arg(int, type=int)], int]): pass # E: "Arg" gets multiple values for keyword argument "type" |
| |
| [builtins fixtures/dict.pyi] |
| |
| [case testCallableTypeAnalysis] |
| from typing import Callable |
| from mypy_extensions import Arg, VarArg as VARG, KwArg |
| import mypy_extensions as ext |
| |
| def WrongArg(x, y): return y |
| def a(f: Callable[[WrongArg(int, 'x')], int]): pass # E: Invalid argument constructor "__main__.WrongArg" |
| def b(f: Callable[[BadArg(int, 'x')], int]): pass # E: Name "BadArg" is not defined |
| def d(f: Callable[[ext.VarArg(int)], int]): pass # ok |
| def e(f: Callable[[VARG(), ext.KwArg()], int]): pass # ok |
| def g(f: Callable[[ext.Arg(name='x', type=int)], int]): pass # ok |
| def i(f: Callable[[Arg(name=None, type=int)], int]): pass # ok |
| |
| def f1(*args) -> int: pass |
| def f2(*args, **kwargs) -> int: pass |
| |
| d(f1) |
| e(f2) |
| d(f2) |
| e(f1) # E: Argument 1 to "e" has incompatible type "Callable[[VarArg(Any)], int]"; expected "Callable[[VarArg(Any), KwArg(Any)], int]" |
| |
| [builtins fixtures/dict.pyi] |
| |
| [case testCallableWrongTypeType] |
| from typing import Callable |
| from mypy_extensions import Arg |
| def b(f: Callable[[Arg(1, 'x')], int]): pass # E: Invalid type: try using Literal[1] instead? |
| [builtins fixtures/dict.pyi] |
| |
| [case testCallableTooManyVarArg] |
| from typing import Callable |
| from mypy_extensions import VarArg |
| def c(f: Callable[[VarArg(int, 'x')], int]): pass # E: VarArg arguments should not have names |
| [builtins fixtures/dict.pyi] |
| |
| [case testCallableFastParseGood] |
| from typing import Callable |
| from mypy_extensions import VarArg, Arg, KwArg |
| def d(f: Callable[[VarArg(int)], int]): pass # ok |
| def e(f: Callable[[VarArg(), KwArg()], int]): pass # ok |
| def g(f: Callable[[Arg(name='x', type=int)], int]): pass # ok |
| def i(f: Callable[[Arg(name=None, type=int)], int]): pass # ok |
| [builtins fixtures/dict.pyi] |
| |
| [case testCallableFastParseBadArgArgName] |
| from typing import Callable |
| from mypy_extensions import Arg |
| def h(f: Callable[[Arg(gnome='x', type=int)], int]): pass # E: Unexpected argument "gnome" for argument constructor |
| [builtins fixtures/dict.pyi] |
| |
| [case testCallableKindsOrdering] |
| from typing import Callable, Any |
| from mypy_extensions import Arg, VarArg, KwArg, DefaultArg, NamedArg |
| |
| def f(f: Callable[[VarArg(), int], int]): pass # E: Required positional args may not appear after default, named or var args |
| def g(f: Callable[[VarArg(), VarArg()], int]): pass # E: Var args may not appear after named or var args |
| def h(f: Callable[[KwArg(), KwArg()], int]): pass # E: You may only have one **kwargs argument |
| def i(f: Callable[[DefaultArg(), int], int]): pass # E: Required positional args may not appear after default, named or var args |
| def j(f: Callable[[NamedArg(Any, 'x'), DefaultArg(int, 'y')], int]): pass # E: Positional default args may not appear after named or var args |
| def k(f: Callable[[KwArg(), NamedArg(Any, 'x')], int]): pass # E: A **kwargs argument must be the last argument |
| [builtins fixtures/dict.pyi] |
| |
| [case testCallableDuplicateNames] |
| from typing import Callable |
| from mypy_extensions import Arg, VarArg, KwArg, DefaultArg |
| |
| def f(f: Callable[[Arg(int, 'x'), int, Arg(int, 'x')], int]): pass # E: Duplicate argument "x" in Callable |
| |
| [builtins fixtures/dict.pyi] |
| |
| |
| [case testCallableWithKeywordOnlyArg] |
| from typing import Callable |
| from mypy_extensions import NamedArg |
| |
| def a(f: Callable[[NamedArg(int, 'x')], int]): |
| f(x=4) |
| f(2) # E: Too many positional arguments |
| f() # E: Missing named argument "x" |
| f(y=3) # E: Unexpected keyword argument "y" |
| f(x="foo") # E: Argument "x" has incompatible type "str"; expected "int" |
| [builtins fixtures/dict.pyi] |
| |
| [case testCallableWithKeywordOnlyOptionalArg] |
| from typing import Callable |
| from mypy_extensions import DefaultNamedArg |
| |
| def a(f: Callable[[DefaultNamedArg(int, 'x')], int]): |
| f(x=4) |
| f(2) # E: Too many positional arguments |
| f() |
| f(y=3) # E: Unexpected keyword argument "y" |
| f(x="foo") # E: Argument "x" has incompatible type "str"; expected "int" |
| [builtins fixtures/dict.pyi] |
| |
| [case testCallableWithKwargs] |
| from typing import Callable |
| from mypy_extensions import KwArg |
| |
| def a(f: Callable[[KwArg(int)], int]): |
| f(x=4) |
| f(2) # E: Too many arguments |
| f() |
| f(y=3) |
| f(x=4, y=3, z=10) |
| f(x="foo") # E: Argument "x" has incompatible type "str"; expected "int" |
| [builtins fixtures/dict.pyi] |
| |
| |
| [case testCallableWithVarArg] |
| from typing import Callable |
| from mypy_extensions import VarArg |
| |
| def a(f: Callable[[VarArg(int)], int]): |
| f(x=4) # E: Unexpected keyword argument "x" |
| f(2) |
| f() |
| f(3, 4, 5) |
| f("a") # E: Argument 1 has incompatible type "str"; expected "int" |
| [builtins fixtures/dict.pyi] |
| |
| [case testCallableArgKindSubtyping] |
| from typing import Callable |
| from mypy_extensions import Arg, DefaultArg |
| |
| int_str_fun = None # type: Callable[[int, str], str] |
| int_opt_str_fun = None # type: Callable[[int, DefaultArg(str, None)], str] |
| int_named_str_fun = None # type: Callable[[int, Arg(str, 's')], str] |
| |
| def isf(ii: int, ss: str) -> str: |
| return ss |
| |
| def iosf(i: int, s: str = "bar") -> str: |
| return s |
| |
| def isf_unnamed(__i: int, __s: str) -> str: |
| return __s |
| |
| int_str_fun = isf |
| int_str_fun = isf_unnamed |
| int_named_str_fun = isf_unnamed # E: Incompatible types in assignment (expression has type "Callable[[int, str], str]", variable has type "Callable[[int, Arg(str, 's')], str]") |
| int_opt_str_fun = iosf |
| int_str_fun = iosf |
| int_opt_str_fun = isf # E: Incompatible types in assignment (expression has type "Callable[[Arg(int, 'ii'), Arg(str, 'ss')], str]", variable has type "Callable[[int, DefaultArg(str)], str]") |
| |
| int_named_str_fun = isf # E: Incompatible types in assignment (expression has type "Callable[[Arg(int, 'ii'), Arg(str, 'ss')], str]", variable has type "Callable[[int, Arg(str, 's')], str]") |
| int_named_str_fun = iosf |
| |
| [builtins fixtures/dict.pyi] |
| |
| -- Callable[..., T] |
| -- ---------------- |
| |
| |
| [case testCallableWithArbitraryArgs] |
| from typing import Callable |
| def f(x: Callable[..., int]) -> None: |
| x() |
| x(1) |
| x(z=1) |
| x() + '' # E: Unsupported operand types for + ("int" and "str") |
| [out] |
| |
| [case testCallableWithArbitraryArgs2] |
| from typing import Callable |
| def f(x: Callable[..., int]) -> None: |
| x(*[1], **{'x': 2}) |
| [builtins fixtures/dict.pyi] |
| |
| [case testCastWithCallableAndArbitraryArgs] |
| from typing import Callable, cast |
| f = cast(Callable[..., int], None) |
| f(x=4) + '' # E: Unsupported operand types for + ("int" and "str") |
| |
| [case testCallableWithArbitraryArgsInErrorMessage] |
| from typing import Callable |
| def f(x: Callable[..., int]) -> None: |
| if int(): |
| x = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "Callable[..., int]") |
| [out] |
| |
| [case testCallableWithArbitraryArgsInGenericFunction] |
| from typing import Callable, TypeVar |
| T = TypeVar('T') |
| def f(x: Callable[..., T]) -> T: pass |
| def g(*x: int) -> str: pass |
| x = f(g) |
| x + 1 # E: Unsupported left operand type for + ("str") |
| [builtins fixtures/list.pyi] |
| |
| [case testCallableWithArbitraryArgsSubtyping] |
| from typing import Callable |
| def f(x: Callable[..., int]) -> None: pass |
| def g1(): pass |
| def g2(x, y) -> int: pass |
| def g3(*, y: str) -> int: pass |
| def g4(*, y: int) -> str: pass |
| f(g1) |
| f(g2) |
| f(g3) |
| f(g4) # E: Argument 1 to "f" has incompatible type "Callable[[NamedArg(int, 'y')], str]"; expected "Callable[..., int]" |
| |
| [case testCallableWithArbitraryArgsSubtypingWithGenericFunc] |
| from typing import Callable, TypeVar |
| T = TypeVar('T') |
| def f(x: Callable[..., int]) -> None: pass |
| def g1(x: T) -> int: pass |
| def g2(*x: T) -> int: pass |
| def g3(*x: T) -> T: pass |
| f(g1) |
| f(g2) |
| f(g3) |
| [builtins fixtures/tuple.pyi] |
| |
| -- (...) -> T |
| -- ---------------- |
| |
| [case testEllipsisWithArbitraryArgsOnBareFunction] |
| def f(x, y, z): # type: (...) -> None |
| pass |
| f(1, "hello", []) |
| f(x=1, y="hello", z=[]) |
| [builtins fixtures/dict.pyi] |
| |
| [case testEllipsisWithArbitraryArgsOnBareFunctionWithDefaults] |
| def f(x, y=1, z="hey"): # type: (...) -> None |
| pass |
| f(1, "hello", []) |
| f(x=1, y="hello", z=[]) |
| [builtins fixtures/dict.pyi] |
| |
| [case testEllipsisWithArbitraryArgsOnBareFunctionWithKwargs] |
| from typing import Dict |
| def f(x, **kwargs): # type: (...) -> None |
| success_dict_type = kwargs # type: Dict[str, str] |
| failure_dict_type = kwargs # type: Dict[int, str] # E: Incompatible types in assignment (expression has type "Dict[str, Any]", variable has type "Dict[int, str]") |
| f(1, thing_in_kwargs=["hey"]) |
| [builtins fixtures/dict.pyi] |
| [out] |
| |
| [case testEllipsisWithArbitraryArgsOnBareFunctionWithVarargs] |
| from typing import Tuple, Any |
| def f(x, *args): # type: (...) -> None |
| success_tuple_type = args # type: Tuple[Any, ...] |
| fail_tuple_type = args # type: None # E: Incompatible types in assignment (expression has type "Tuple[Any, ...]", variable has type "None") |
| f(1, "hello") |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testEllipsisWithArbitraryArgsOnInstanceMethod] |
| class A: |
| def f(self, x, y, z): # type: (...) -> None |
| pass |
| |
| [case testEllipsisWithArbitraryArgsOnClassMethod] |
| class A: |
| @classmethod |
| def f(cls, x, y, z): # type: (...) -> None |
| pass |
| [builtins fixtures/classmethod.pyi] |
| |
| [case testEllipsisWithArbitraryArgsOnStaticMethod] |
| class A: |
| @staticmethod |
| def f(x, y, z): # type: (...) -> None |
| pass |
| [builtins fixtures/staticmethod.pyi] |
| |
| [case testEllipsisWithSomethingAfterItFails] |
| def f(x, y, z): # type: (..., int) -> None |
| pass |
| [out] |
| main:1: error: Ellipses cannot accompany other argument types in function type signature |
| |
| [case testEllipsisWithSomethingBeforeItFails] |
| def f(x, y, z): # type: (int, ...) -> None |
| pass |
| [out] |
| main:1: error: Ellipses cannot accompany other argument types in function type signature |
| |
| [case testRejectCovariantArgument] |
| from typing import TypeVar, Generic |
| |
| t = TypeVar('t', covariant=True) |
| class A(Generic[t]): |
| def foo(self, x: t) -> None: |
| return None |
| [builtins fixtures/bool.pyi] |
| [out] |
| main:5: error: Cannot use a covariant type variable as a parameter |
| |
| [case testRejectCovariantArgumentSplitLine] |
| from typing import TypeVar, Generic |
| |
| t = TypeVar('t', covariant=True) |
| class A(Generic[t]): |
| def foo(self, |
| x: t) -> None: |
| return None |
| [builtins fixtures/bool.pyi] |
| [out] |
| main:6: error: Cannot use a covariant type variable as a parameter |
| |
| [case testRejectCovariantArgumentInLambda] |
| from typing import TypeVar, Generic, Callable |
| |
| t = TypeVar('t', covariant=True) |
| class Thing(Generic[t]): |
| def chain(self, func: Callable[[t], None]) -> None: pass |
| def end(self) -> None: |
| return self.chain( # Note that lambda args have no line numbers |
| lambda _: None) |
| [builtins fixtures/bool.pyi] |
| [out] |
| main:8: error: Cannot use a covariant type variable as a parameter |
| |
| [case testRejectCovariantArgumentInLambdaSplitLine] |
| from typing import TypeVar, Generic, Callable |
| |
| [case testRejectContravariantReturnType] |
| from typing import TypeVar, Generic |
| |
| t = TypeVar('t', contravariant=True) |
| class A(Generic[t]): |
| def foo(self) -> t: |
| return None |
| [builtins fixtures/bool.pyi] |
| [out] |
| main:5: error: Cannot use a contravariant type variable as return type |
| |
| [case testAcceptCovariantReturnType] |
| from typing import TypeVar, Generic |
| |
| t = TypeVar('t', covariant=True) |
| class A(Generic[t]): |
| def foo(self) -> t: |
| return None |
| [builtins fixtures/bool.pyi] |
| [case testAcceptContravariantArgument] |
| from typing import TypeVar, Generic |
| |
| t = TypeVar('t', contravariant=True) |
| class A(Generic[t]): |
| def foo(self, x: t) -> None: |
| return None |
| [builtins fixtures/bool.pyi] |
| |
| |
| -- Redefining functions |
| -- -------------------- |
| |
| |
| [case testRedefineFunction] |
| from typing import Any |
| def f(x) -> Any: pass |
| def g(x, y): pass |
| def h(x): pass |
| def j(y) -> Any: pass |
| f = h |
| f = j # E: Incompatible types in assignment (expression has type "Callable[[Arg(Any, 'y')], Any]", variable has type "Callable[[Arg(Any, 'x')], Any]") |
| f = g # E: Incompatible types in assignment (expression has type "Callable[[Any, Any], Any]", variable has type "Callable[[Any], Any]") |
| |
| [case testRedefineFunction2] |
| def f() -> None: pass |
| def f() -> None: pass # E: Name "f" already defined on line 1 |
| |
| |
| -- Special cases |
| -- ------------- |
| |
| |
| [case testFunctionDefinitionWithForStatement] |
| for _ in [1]: |
| def f(): pass |
| else: |
| def g(): pass |
| f() |
| g() |
| [builtins fixtures/list.pyi] |
| |
| [case testFunctionDefinitionWithWhileStatement] |
| while bool(): |
| def f(): pass |
| else: |
| def g(): pass |
| f() |
| g() |
| [builtins fixtures/bool.pyi] |
| |
| [case testBareCallable] |
| from typing import Callable, Any |
| |
| def foo(f: Callable) -> bool: |
| return f() |
| |
| def f1() -> bool: |
| return False |
| |
| foo(f1) |
| [builtins fixtures/bool.pyi] |
| |
| [case testFunctionNestedWithinWith] |
| from typing import Any |
| a = 1 # type: Any |
| with a: |
| def f() -> None: |
| pass |
| f(1) # E: Too many arguments for "f" |
| |
| |
| [case testNameForDecoratorMethod] |
| from typing import Callable |
| |
| class A: |
| def f(self) -> None: |
| # In particular, test that the error message contains "g" of "A". |
| self.g() # E: Too few arguments for "g" of "A" |
| self.g(1) |
| @dec |
| def g(self, x: str) -> None: pass |
| |
| def dec(f: Callable[[A, str], None]) -> Callable[[A, int], None]: pass |
| [out] |
| |
| [case testUnknownFunctionNotCallable] |
| def f() -> None: |
| pass |
| def g(x: int) -> None: |
| pass |
| h = f if bool() else g |
| reveal_type(h) # N: Revealed type is "builtins.function" |
| h(7) # E: Cannot call function of unknown type |
| [builtins fixtures/bool.pyi] |
| |
| [case testFunctionWithNameUnderscore] |
| def _(x: int) -> None: pass |
| |
| _(1) |
| _('x') # E: Argument 1 to "_" has incompatible type "str"; expected "int" |
| |
| -- Positional-only arguments |
| -- ------------------------- |
| |
| [case testPositionalOnlyArg] |
| def f(__a: int) -> None: pass |
| def g(__a__: int) -> None: pass |
| |
| f(1) |
| f(__a=1) # E: Unexpected keyword argument "__a" for "f" |
| |
| g(1) |
| # Argument names that also end with __ are not positional-only. |
| g(__a__=1) |
| |
| [builtins fixtures/bool.pyi] |
| [out] |
| main:1: note: "f" defined here |
| |
| [case testMagicMethodPositionalOnlyArg] |
| class A(object): |
| def __eq__(self, other) -> bool: return True # We are all equal. # N: "__eq__" of "A" defined here |
| |
| a = A() |
| a.__eq__(a) |
| a.__eq__(other=a) # E: Unexpected keyword argument "other" for "__eq__" of "A" |
| |
| [builtins fixtures/bool.pyi] |
| |
| [case testMagicMethodPositionalOnlyArgFastparse] |
| |
| |
| class A(object): |
| def __eq__(self, other) -> bool: return True # We are all equal. # N: "__eq__" of "A" defined here |
| |
| a = A() |
| a.__eq__(a) |
| a.__eq__(other=a) # E: Unexpected keyword argument "other" for "__eq__" of "A" |
| |
| [builtins fixtures/bool.pyi] |
| |
| [case testTupleArguments] |
| # flags: --python-version 2.7 |
| |
| def f(a, (b, c), d): pass |
| |
| [case testTupleArgumentsFastparse] |
| # flags: --python-version 2.7 |
| |
| def f(a, (b, c), d): pass |
| |
| -- Type variable shenanagins |
| -- ------------------------- |
| |
| [case testGenericFunctionTypeDecl] |
| from typing import Callable, TypeVar |
| |
| T = TypeVar('T') |
| |
| f: Callable[[T], T] |
| reveal_type(f) # N: Revealed type is "def [T] (T`-1) -> T`-1" |
| def g(__x: T) -> T: pass |
| f = g |
| reveal_type(f) # N: Revealed type is "def [T] (T`-1) -> T`-1" |
| i = f(3) |
| reveal_type(i) # N: Revealed type is "builtins.int" |
| |
| [case testFunctionReturningGenericFunction] |
| from typing import Callable, TypeVar |
| |
| T = TypeVar('T') |
| def deco() -> Callable[[T], T]: pass |
| reveal_type(deco) # N: Revealed type is "def () -> def [T] (T`-1) -> T`-1" |
| f = deco() |
| reveal_type(f) # N: Revealed type is "def [T] (T`-1) -> T`-1" |
| i = f(3) |
| reveal_type(i) # N: Revealed type is "builtins.int" |
| |
| [case testFunctionReturningGenericFunctionPartialBinding] |
| from typing import Callable, TypeVar |
| |
| T = TypeVar('T') |
| U = TypeVar('U') |
| |
| def deco(x: U) -> Callable[[T, U], T]: pass |
| reveal_type(deco) # N: Revealed type is "def [U] (x: U`-1) -> def [T] (T`-2, U`-1) -> T`-2" |
| f = deco("foo") |
| reveal_type(f) # N: Revealed type is "def [T] (T`-2, builtins.str) -> T`-2" |
| i = f(3, "eggs") |
| reveal_type(i) # N: Revealed type is "builtins.int" |
| |
| [case testFunctionReturningGenericFunctionTwoLevelBinding] |
| from typing import Callable, TypeVar |
| |
| T = TypeVar('T') |
| R = TypeVar('R') |
| def deco() -> Callable[[T], Callable[[T, R], R]]: pass |
| f = deco() |
| reveal_type(f) # N: Revealed type is "def [T] (T`-1) -> def [R] (T`-1, R`-2) -> R`-2" |
| g = f(3) |
| reveal_type(g) # N: Revealed type is "def [R] (builtins.int, R`-2) -> R`-2" |
| s = g(4, "foo") |
| reveal_type(s) # N: Revealed type is "builtins.str" |
| |
| [case testGenericFunctionReturnAsDecorator] |
| from typing import Callable, TypeVar |
| |
| T = TypeVar('T') |
| def deco(__i: int) -> Callable[[T], T]: pass |
| |
| @deco(3) |
| def lol(x: int) -> str: ... |
| |
| reveal_type(lol) # N: Revealed type is "def (x: builtins.int) -> builtins.str" |
| s = lol(4) |
| reveal_type(s) # N: Revealed type is "builtins.str" |
| |
| [case testGenericFunctionOnReturnTypeOnly] |
| from typing import TypeVar, List |
| |
| T = TypeVar('T') |
| |
| def make_list() -> List[T]: pass |
| |
| l: List[int] = make_list() |
| |
| bad = make_list() # E: Need type annotation for "bad" (hint: "bad: List[<type>] = ...") |
| [builtins fixtures/list.pyi] |
| |
| [case testAnonymousArgumentError] |
| def foo(__b: int, x: int, y: int) -> int: pass |
| foo(x=2, y=2) # E: Too few arguments for "foo" |
| foo(y=2) # E: Too few arguments for "foo" |
| |
| [case testMissingArgumentError] |
| def f(a, b, c, d=None) -> None: pass |
| f(1, 2, d=3) # E: Missing positional argument "c" in call to "f" |
| |
| [case testMissingArgumentErrorMoreThanOneOptional] |
| def f(a: int, b=None, c=None) -> None: pass |
| f(b=4) # E: Missing positional argument "a" in call to "f" |
| |
| [case testMissingArgumentsError] |
| def f(a, b, c, d=None) -> None: pass |
| f(1, d=3) # E: Missing positional arguments "b", "c" in call to "f" |
| |
| [case testReturnTypeLineNumberWithDecorator] |
| def dec(f): pass |
| |
| @dec |
| def test(a: str) -> (str,): # E: Syntax error in type annotation # N: Suggestion: Is there a spurious trailing comma? |
| return None |
| |
| [case testReturnTypeLineNumberNewLine] |
| def fn(a: str |
| ) -> badtype: # E: Name "badtype" is not defined |
| pass |
| |
| [case testArgumentTypeLineNumberWithDecorator] |
| def dec(f): pass |
| |
| @dec |
| def some_method(self: badtype): pass # E: Name "badtype" is not defined |
| |
| [case TestArgumentTypeLineNumberNewline] |
| def fn( |
| a: badtype) -> None: # E: Name "badtype" is not defined |
| pass |
| |
| [case testInferredTypeSubTypeOfReturnType] |
| from typing import Union, Dict, List |
| def f() -> List[Union[str, int]]: |
| x = ['a'] |
| return x # E: Incompatible return value type (got "List[str]", expected "List[Union[str, int]]") \ |
| # N: "List" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance \ |
| # N: Consider using "Sequence" instead, which is covariant \ |
| # N: Perhaps you need a type annotation for "x"? Suggestion: "List[Union[str, int]]" |
| |
| def g() -> Dict[str, Union[str, int]]: |
| x = {'a': 'a'} |
| return x # E: Incompatible return value type (got "Dict[str, str]", expected "Dict[str, Union[str, int]]") \ |
| # N: "Dict" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance \ |
| # N: Consider using "Mapping" instead, which is covariant in the value type \ |
| # N: Perhaps you need a type annotation for "x"? Suggestion: "Dict[str, Union[str, int]]" |
| |
| def h() -> Dict[Union[str, int], str]: |
| x = {'a': 'a'} |
| return x # E: Incompatible return value type (got "Dict[str, str]", expected "Dict[Union[str, int], str]") \ |
| # N: Perhaps you need a type annotation for "x"? Suggestion: "Dict[Union[str, int], str]" |
| |
| def i() -> List[Union[int, float]]: |
| x: List[int] = [1] |
| return x # E: Incompatible return value type (got "List[int]", expected "List[Union[int, float]]") \ |
| # N: "List" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance \ |
| # N: Consider using "Sequence" instead, which is covariant |
| |
| [builtins fixtures/dict.pyi] |
| |
| [case testInferredTypeNotSubTypeOfReturnType] |
| from typing import Union, List |
| def f() -> List[Union[int, float]]: |
| x = ['a'] |
| return x # E: Incompatible return value type (got "List[str]", expected "List[Union[int, float]]") |
| |
| def g() -> List[Union[str, int]]: |
| x = ('a', 2) |
| return x # E: Incompatible return value type (got "Tuple[str, int]", expected "List[Union[str, int]]") |
| |
| [builtins fixtures/list.pyi] |
| |
| [case testInferredTypeIsObjectMismatch] |
| from typing import Union, Dict, List |
| def f() -> Dict[str, Union[str, int]]: |
| x = {'a': 'a', 'b': 2} |
| return x # E: Incompatible return value type (got "Dict[str, object]", expected "Dict[str, Union[str, int]]") |
| |
| def g() -> Dict[str, Union[str, int]]: |
| x: Dict[str, Union[str, int]] = {'a': 'a', 'b': 2} |
| return x |
| |
| def h() -> List[Union[str, int]]: |
| x = ['a', 2] |
| return x # E: Incompatible return value type (got "List[object]", expected "List[Union[str, int]]") |
| |
| def i() -> List[Union[str, int]]: |
| x: List[Union[str, int]] = ['a', 2] |
| return x |
| |
| [builtins fixtures/dict.pyi] |
| |
| [case testLambdaSemanal] |
| f = lambda: xyz |
| [out] |
| main:1: error: Name "xyz" is not defined |
| |
| [case testLambdaTypeCheck] |
| f = lambda: 1 + '1' |
| [out] |
| main:1: error: Unsupported operand types for + ("int" and "str") |
| |
| [case testLambdaTypeInference] |
| f = lambda: 5 |
| reveal_type(f) |
| [out] |
| main:2: note: Revealed type is "def () -> builtins.int" |
| |
| [case testRevealLocalsFunction] |
| a = 1.0 |
| |
| class A: pass |
| |
| def f(a: int, b: int) -> int: |
| reveal_locals() |
| c = a + b |
| class C: pass |
| reveal_locals() |
| return c |
| |
| reveal_locals() |
| [out] |
| main:6: note: Revealed local types are: |
| main:6: note: a: builtins.int |
| main:6: note: b: builtins.int |
| main:9: note: Revealed local types are: |
| main:9: note: a: builtins.int |
| main:9: note: b: builtins.int |
| main:9: note: c: builtins.int |
| main:12: note: Revealed local types are: |
| main:12: note: a: builtins.float |
| |
| [case testNoComplainOverloadNone] |
| # flags: --no-strict-optional |
| from typing import overload, Optional |
| @overload |
| def bar(x: None) -> None: |
| ... |
| @overload |
| def bar(x: int) -> str: |
| ... |
| def bar(x: Optional[int]) -> Optional[str]: |
| if x is None: |
| return None |
| return "number" |
| |
| reveal_type(bar(None)) # N: Revealed type is "None" |
| [builtins fixtures/isinstance.pyi] |
| [out] |
| |
| [case testNoComplainOverloadNoneStrict] |
| # flags: --strict-optional |
| from typing import overload, Optional |
| @overload |
| def bar(x: None) -> None: |
| ... |
| @overload |
| def bar(x: int) -> str: |
| ... |
| def bar(x: Optional[int]) -> Optional[str]: |
| if x is None: |
| return None |
| return "number" |
| |
| reveal_type(bar(None)) # N: Revealed type is "None" |
| [builtins fixtures/isinstance.pyi] |
| [out] |
| |
| [case testNoComplainInferredNone] |
| # flags: --no-strict-optional |
| from typing import TypeVar, Optional |
| T = TypeVar('T') |
| def X(val: T) -> T: ... |
| x_in = None |
| def Y(x: Optional[str] = X(x_in)): ... |
| |
| xx: Optional[int] = X(x_in) |
| [out] |
| |
| [case testNoComplainInferredNoneStrict] |
| # flags: --strict-optional |
| from typing import TypeVar, Optional |
| T = TypeVar('T') |
| def X(val: T) -> T: ... |
| x_in = None |
| def Y(x: Optional[str] = X(x_in)): ... |
| |
| xx: Optional[int] = X(x_in) |
| [out] |
| |
| [case testNoComplainNoneReturnFromUntyped] |
| def foo() -> None: |
| pass |
| |
| def lol(): |
| x = foo() |
| |
| [case testConditionalImportFunction] |
| import p |
| [file p/__init__.py] |
| |
| if int(): |
| from p.a import f |
| elif int(): |
| from p.b import f |
| else: |
| from p.c import f |
| |
| [file p/a.py] |
| def f() -> int: ... |
| |
| [file p/b.py] |
| from p.d import f |
| |
| [file p/c.py] |
| def f() -> int: ... |
| |
| [file p/d.py] |
| import p |
| def f() -> int: ... |
| |
| [case testLambdaDefaultTypeErrors] |
| lambda a=nonsense: a # E: Name "nonsense" is not defined |
| lambda a=(1 + 'asdf'): a # E: Unsupported operand types for + ("int" and "str") |
| def f(x: int = i): # E: Name "i" is not defined |
| i = 42 |
| |
| [case testRevealTypeOfCallExpressionReturningNoneWorks] |
| def foo() -> None: |
| pass |
| |
| reveal_type(foo()) # N: Revealed type is "None" |
| |
| [case testAnyArgument] |
| def a(b: any): pass # E: Function "builtins.any" is not valid as a type \ |
| # N: Perhaps you meant "typing.Any" instead of "any"? |
| [builtins fixtures/any.pyi] |
| |
| [case testCallableArgument] |
| def a(b: callable): pass # E: Function "builtins.callable" is not valid as a type \ |
| # N: Perhaps you meant "typing.Callable" instead of "callable"? |
| [builtins fixtures/callable.pyi] |