| -- 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: Callable[[A], B] | |
| a: A | |
| b: 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: Argument 1 of "f" is incompatible with supertype "A"; supertype defines the argument type as "str" | |
| main:10: note: This violates the Liskov substitution principle | |
| main:10: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides | |
| main:10: error: Argument 2 of "f" is incompatible with supertype "A"; supertype defines the argument type as "int" | |
| [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: Callable[[B], A] | |
| g: Callable[[A], A] # subtype of f | |
| h: 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, *, x) -> None: ... | |
| r = l # E: Incompatible types in assignment (expression has type "Callable[[Any], None]", variable has type "def r(Any, /, *, x: Any) -> None") | |
| [case testSubtypingFunctionsDoubleCorrespondenceNamedOptional] | |
| def l(x) -> None: ... | |
| def r(__x, *, x = 1) -> None: ... | |
| r = l # E: Incompatible types in assignment (expression has type "Callable[[Any], None]", variable has type "def r(Any, /, *, x: Any = ...) -> None") | |
| [case testSubtypingFunctionsDoubleCorrespondenceBothNamedOptional] | |
| def l(x = 1) -> None: ... | |
| def r(__x, *, x = 1) -> None: ... | |
| r = l # E: Incompatible types in assignment (expression has type "Callable[[Any], None]", variable has type "def r(Any, /, *, x: Any = ...) -> None") | |
| [case testSubtypingFunctionsTrivialSuffixRequired] | |
| def l(__x) -> None: ... | |
| def r(x, *args, **kwargs) -> None: ... | |
| r = l # E: Incompatible types in assignment (expression has type "Callable[[Any], None]", variable has type "def r(x: Any, *args: Any, **kwargs: Any) -> None") | |
| [builtins fixtures/dict.pyi] | |
| [case testSubtypingFunctionsTrivialSuffixOptional] | |
| def l(__x = 1) -> None: ... | |
| def r(x = 1, *args, **kwargs) -> None: ... | |
| r = l # E: Incompatible types in assignment (expression has type "def l(Any = ..., /) -> None", variable has type "def r(x: Any = ..., *args: Any, **kwargs: Any) -> None") | |
| [builtins fixtures/dict.pyi] | |
| [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: 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 "def f(a: int, b: str) -> None") | |
| if int(): | |
| ff = f # reset | |
| if int(): | |
| gg = ff # E: Incompatible types in assignment (expression has type "def f(a: int, b: str) -> None", variable has type "def g(a: int, b: str = ...) -> None") | |
| if int(): | |
| gg = hh # E: Incompatible types in assignment (expression has type "def h(aa: int, b: str = ...) -> None", variable has type "def g(a: int, b: str = ...) -> None") | |
| [case testSubtypingFunctionsArgsKwargs] | |
| from typing import Any, Callable | |
| def everything(*args: Any, **kwargs: Any) -> None: pass | |
| everywhere: 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 | |
| if int(): | |
| ee_def = specific_1 | |
| [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 "def g(a: int, b: str) -> 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 "def g(a: int, b: str) -> None") | |
| [case testFunctionTypeCompatibilityWithOtherTypes] | |
| # flags: --no-strict-optional | |
| 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 (it only ever returns None) | |
| 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: Callable[[], None] | |
| g: 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: Callable[[A, A], None] | |
| g: Callable[[A, B], None] | |
| h: 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: Callable[[], None] | |
| g: Callable[[A], None] | |
| h: 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] | |
| class A: | |
| def __init__(self, a: 'A') -> None: pass | |
| def f() -> None: pass | |
| t: type | |
| a: 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 | |
| [case testFunctionTypesWithOverloads] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import Callable, overload | |
| f: Callable[[AA], A] | |
| g: Callable[[B], B] | |
| h: 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: Callable[[A], A] | |
| g2: Callable[[B], B] | |
| g3: Callable[[C], C] | |
| g4: Callable[[A], B] | |
| a: A | |
| b: B | |
| c: 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: Callable[..., A] | |
| y: Type[A] | |
| x = y | |
| [case testSubtypingCallableAsTypeType] | |
| from typing import Callable, Type | |
| class A: pass | |
| x: Callable[..., A] | |
| y: 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] | |
| # flags: --implicit-optional --no-strict-optional | |
| class A: pass | |
| class AA(A): pass | |
| class B: pass | |
| def f(x: 'A' = None) -> 'B': pass | |
| 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 "A | None" | |
| 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()) | |
| [builtins fixtures/tuple.pyi] | |
| [case testDefaultParameterExpressions] | |
| import typing | |
| class B: pass | |
| class A: pass | |
| 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 | |
| [out] | |
| [case testDefaultParameterExpressions2] | |
| import typing | |
| class B: pass | |
| class A: pass | |
| def f(x: 'A' = B()) -> None: # E: Incompatible default for parameter "x" (default has type "B", parameter has type "A") | |
| b = x # type: B # E: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| a = x # type: A | |
| [case testDefaultParameterExpressionsGeneric] | |
| from typing import TypeVar | |
| T = TypeVar('T', bound='A') | |
| class B: pass | |
| class A: pass | |
| def f(x: T = B()) -> None: # E: Incompatible default for parameter "x" (default has type "B", parameter has type "T") | |
| b = x # type: B # E: Incompatible types in assignment (expression has type "T", variable has type "B") | |
| a = x # type: A | |
| [case testDefaultParametersWithSubtypes] | |
| import typing | |
| class A: pass | |
| class B(A): pass | |
| def f(x: 'B' = A()) -> None: # E: Incompatible default for parameter "x" (default has type "A", parameter has type "B") | |
| pass | |
| def g(x: 'A' = B()) -> None: | |
| pass | |
| [out] | |
| [case testMultipleDefaultParameterExpressions] | |
| import typing | |
| class A: pass | |
| class B: pass | |
| def f(x: 'A' = B(), y: 'B' = B()) -> None: # E: Incompatible default for parameter "x" (default has type "B", parameter has type "A") | |
| pass | |
| def h(x: 'A' = A(), y: 'B' = B()) -> None: | |
| pass | |
| [out] | |
| [case testMultipleDefaultParameterExpressions2] | |
| import typing | |
| class A: pass | |
| class B: pass | |
| def g(x: 'A' = A(), y: 'B' = A()) -> None: # E: Incompatible default for parameter "y" (default has type "A", parameter has type "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, ClassVar | |
| class B: pass | |
| x: Any | |
| class A: | |
| f = x # type: ClassVar[Callable[[A], None]] | |
| g = x # type: ClassVar[Callable[[A, B], None]] | |
| a: 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, ClassVar | |
| class B: pass | |
| x: Any | |
| class A: | |
| f = x # type: ClassVar[Callable[[], None]] | |
| g = x # type: ClassVar[Callable[[B], None]] | |
| a: 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, ClassVar | |
| class B: pass | |
| x: Any | |
| class A: | |
| f = x # type: ClassVar[Callable[[Any], Any]] | |
| a: A | |
| a.f() | |
| a.f(a) # E: Too many arguments | |
| [case testMethodWithInferredMethodAsDataAttribute] | |
| from typing import Any | |
| def m(self: "A") -> int: ... | |
| class A: | |
| n = m | |
| a = A() | |
| reveal_type(a.n()) # N: Revealed type is "builtins.int" | |
| reveal_type(A.n(a)) # N: Revealed type is "builtins.int" | |
| A.n() # E: Too few 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: 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: 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: 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, ClassVar | |
| t = TypeVar('t') | |
| class B: pass | |
| class C: pass | |
| x: Any | |
| class A(Generic[t]): | |
| f = x # type: ClassVar[Callable[[A[B]], None]] | |
| ab: A[B] | |
| ac: 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, ClassVar | |
| t = TypeVar('t') | |
| class B: pass | |
| class C: pass | |
| x: Any | |
| class A(Generic[t]): | |
| f = x # type: ClassVar[Callable[[A], None]] | |
| ab: A[B] | |
| ac: A[C] | |
| ab.f() | |
| ac.f() | |
| [case testCallableDataAttribute] | |
| from typing import Callable, ClassVar | |
| class A: | |
| g: ClassVar[Callable[[A], None]] | |
| def __init__(self, f: Callable[[], None]) -> None: | |
| self.f = f | |
| a = A(lambda: 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" | |
| -- Rejecting this is somewhat tricky in the new parser | |
| [case testNestedFunctionInMethodWithTooFewArgumentsInTypeComment_old_parser] | |
| class A: | |
| def f(self): | |
| # type: () -> None | |
| def g(x): # E: Type signature has too few parameters | |
| # type: () -> None | |
| pass | |
| [case testNestedFunctionInMethodCannotAccessEnclosingClassAttributes] | |
| class A: | |
| var: int | |
| import mod | |
| class B: ... | |
| def method(self) -> None: | |
| def f1(arg: object) -> None: | |
| arg.var # E: "object" has no attribute "var" | |
| arg.mod # E: "object" has no attribute "mod" | |
| arg.B # E: "object" has no attribute "B" | |
| [file mod.py] | |
| -- Rejecting this is somewhat tricky in the new parser | |
| [case testDeepNestedFunctionWithTooFewArgumentsInTypeComment_old_parser] | |
| class A: | |
| def f(self): | |
| # type: () -> None | |
| class B: | |
| def g(self): | |
| # type: () -> None | |
| def h(x): # E: Type signature has too few parameters | |
| # 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: 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 | |
| @dec2 # E: Argument 1 to "dec2" has incompatible type "Callable[[Any], Any]"; expected "Callable[[Any, Any], None]" | |
| def f(x): pass | |
| def faulty(c: Callable[[int], None]) -> Callable[[tuple[int, int]], None]: | |
| return lambda x: None | |
| @faulty # E: Argument 1 to "faulty" has incompatible type "Callable[[tuple[int, int]], None]"; expected "Callable[[int], None]" | |
| @faulty # E: Argument 1 to "faulty" has incompatible type "Callable[[str], None]"; expected "Callable[[int], None]" | |
| def g(x: str) -> None: | |
| return None | |
| [builtins fixtures/tuple.pyi] | |
| [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] | |
| [case testNoTypeCheckDecoratorNoUntypedDefs] | |
| # flags: --disallow-untyped-defs | |
| import typing | |
| @typing.no_type_check | |
| def foo(x: "foo") -> "bar": | |
| x: "whatever" | |
| [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" of "A" | |
| 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" of "A" | |
| 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] | |
| # flags: --disable-error-code=used-before-def | |
| 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] | |
| # flags: --disable-error-code=used-before-def | |
| 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: Argument 1 to "g" has incompatible type "int"; expected "str" | |
| [file b.py] | |
| import a | |
| from d import dec | |
| @dec | |
| def g(x: str) -> None: pass | |
| a.f('') # E: Argument 1 to "f" has incompatible type "str"; expected "int" | |
| [file d.py] | |
| from typing import TypeVar | |
| T = TypeVar('T') | |
| def dec(f: T) -> T: return f | |
| [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)() # E: "str" not callable | |
| [file b.py] | |
| import a | |
| from d import dec | |
| @dec | |
| def g(x: int) -> str: pass | |
| a.f(1)() # E: "str" not callable | |
| [file d.py] | |
| from typing import Callable | |
| def dec(f: Callable[[int], str]) -> Callable[[int], str]: return f | |
| [case testDecoratorWithCallAndFixedReturnTypeInImportCycle] | |
| import a | |
| [file a.py] | |
| import b | |
| from d import dec | |
| @dec() | |
| def f(x: int) -> str: pass | |
| b.g(1)() # E: "str" not callable | |
| [file b.py] | |
| import a | |
| from d import dec | |
| @dec() | |
| def g(x: int) -> str: pass | |
| a.f(1)() # E: "str" not callable | |
| [file d.py] | |
| from typing import Callable | |
| def dec() -> Callable[[Callable[[int], str]], Callable[[int], str]]: pass | |
| [case testDecoratorWithCallAndFixedReturnTypeInImportCycleAndDecoratorArgs] | |
| import a | |
| [file a.py] | |
| import b | |
| from d import dec | |
| @dec(1) # E: Argument 1 to "dec" has incompatible type "int"; expected "str" | |
| def f(x: int) -> str: pass | |
| b.g(1)() # E: "str" not callable | |
| [file b.py] | |
| import a | |
| from d import dec | |
| @dec(1) # E: Argument 1 to "dec" has incompatible type "int"; expected "str" | |
| def g(x: int) -> str: pass | |
| a.f(1)() # E: "str" not callable | |
| [file d.py] | |
| from typing import Callable | |
| def dec(x: str) -> Callable[[Callable[[int], str]], Callable[[int], str]]: pass | |
| [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 \ | |
| # N: Original: \ | |
| # N: def f(x: int) -> None \ | |
| # N: Redefinition: \ | |
| # N: def f(x: Any) -> Any | |
| [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 \ | |
| # N: Original: \ | |
| # N: def f(x: int) -> None \ | |
| # N: Redefinition: \ | |
| # N: def f(y: int) -> None | |
| [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 \ | |
| # N: Original: \ | |
| # N: def f(x: int) -> None \ | |
| # N: Redefinition: \ | |
| # N: def f(x: int = ...) -> None | |
| [case testIncompatibleConditionalFunctionDefinition4] | |
| from typing import Any, Union, TypeVar | |
| T1 = TypeVar('T1') | |
| T2 = TypeVar('T2', bound=Union[int, str]) | |
| x = None # type: Any | |
| if x: | |
| def f(x: T1) -> T1: pass | |
| else: | |
| def f(x: T2) -> T2: pass # E: All conditional function variants must have identical signatures \ | |
| # N: Original: \ | |
| # N: def [T1] f(x: T1) -> T1 \ | |
| # N: Redefinition: \ | |
| # N: def [T2: int | str] f(x: T2) -> T2 | |
| [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: | |
| @dec | |
| def f(): pass # E: All conditional function variants must have identical signatures \ | |
| # N: Original: \ | |
| # N: def f(x: str) -> None \ | |
| # N: Redefinition: \ | |
| # N: def f(int, /) -> None | |
| [case testConditionalFunctionDefinitionUnreachable] | |
| # flags: --warn-unreachable | |
| def bar() -> None: | |
| if False: | |
| foo = 1 # E: Statement is unreachable | |
| else: | |
| def foo(obj): ... | |
| def baz() -> None: | |
| if False: | |
| foo: int = 1 # E: Statement is unreachable | |
| else: | |
| def foo(obj): ... # E: Incompatible redefinition (redefinition with type "Callable[[Any], Any]", original type "int") | |
| [builtins fixtures/tuple.pyi] | |
| [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 \ | |
| # N: Original: \ | |
| # N: def f(x: str) -> None \ | |
| # N: Redefinition: \ | |
| # N: def f(x: int) -> None | |
| [case testConditionalRedefinitionOfAnUnconditionalFunctionDefinition2] | |
| from typing import Any | |
| def f(x: int) -> None: pass | |
| x = None # type: Any | |
| if x: | |
| def f(y: int) -> None: pass # E: All conditional function variants must have identical signatures \ | |
| # N: Original: \ | |
| # N: def f(x: int) -> None \ | |
| # N: Redefinition: \ | |
| # N: def f(y: int) -> None | |
| 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() -> None: 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 \ | |
| # N: Original: \ | |
| # N: def f(self: A, x: int) -> None \ | |
| # N: Redefinition: \ | |
| # N: def f(self: A, x: Any) -> Any | |
| [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 testCallableParsingInInheritance] | |
| 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 | |
| import types # Needed for type checking | |
| 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 [...] | |
| 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) | |
| [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 parameter "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: Callable[[int, str], str] | |
| int_opt_str_fun: Callable[[int, DefaultArg(str, None)], str] | |
| int_named_str_fun: 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 "def (int, /, s: str) -> str") | |
| int_opt_str_fun = iosf | |
| int_str_fun = iosf | |
| int_opt_str_fun = isf # E: Incompatible types in assignment (expression has type "def isf(ii: int, ss: str) -> str", variable has type "def (int, str = ..., /) -> str") | |
| int_named_str_fun = isf # E: Incompatible types in assignment (expression has type "def isf(ii: int, ss: str) -> str", variable has type "def (int, /, s: str) -> 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 "def g4(*, y: int) -> 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: Type signature has too few parameters | |
| [case testEllipsisWithSomethingBeforeItFails] | |
| def f(x, y, z): # type: (int, ...) -> None | |
| pass | |
| [out] | |
| main:1: error: Type signature has too few parameters | |
| [case testEllipsisWithSomethingAfterItFails2] | |
| def f(x, y): # type: (..., int) -> None | |
| pass | |
| [out] | |
| main:1: error: Unexpected "..." | |
| [case testEllipsisWithSomethingBeforeItFails2] | |
| def f(x, y): # type: (int, ...) -> None | |
| pass | |
| [out] | |
| main:1: error: Unexpected "..." | |
| [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 testAllowCovariantArgumentInLambda] | |
| 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( | |
| lambda _: None) | |
| [builtins fixtures/bool.pyi] | |
| [case testRejectContravariantReturnType] | |
| # flags: --no-strict-optional | |
| 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:6: error: Cannot use a contravariant type variable as return type | |
| [case testAcceptCovariantReturnType] | |
| # flags: --no-strict-optional | |
| 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 "def j(y: Any) -> Any", variable has type "def f(x: Any) -> 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] | |
| from typing import TypeVar | |
| def f() -> None: | |
| pass | |
| def g(x: int) -> None: | |
| pass | |
| h = f if bool() else g | |
| reveal_type(h) # N: Revealed type is "(def ()) | (def (x: builtins.int))" | |
| h(7) # E: Too many arguments for "f" | |
| T = TypeVar("T") | |
| def join(x: T, y: T) -> T: ... | |
| h2 = join(f, g) | |
| reveal_type(h2) # N: Revealed type is "builtins.function" | |
| h2(7) # E: Cannot call function of unknown type | |
| h3 = join(g, f) | |
| reveal_type(h3) # N: Revealed type is "builtins.function" | |
| h3(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] | |
| [case testMagicMethodPositionalOnlyArg] | |
| class A(object): | |
| def __eq__(self, other) -> bool: return True # We are all equal. | |
| 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. | |
| a = A() | |
| a.__eq__(a) | |
| a.__eq__(other=a) # E: Unexpected keyword argument "other" for "__eq__" of "A" | |
| [builtins fixtures/bool.pyi] | |
| -- Type variable shenanigans | |
| -- ------------------------- | |
| [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`1, builtins.str) -> T`1" | |
| 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`2) -> def [R] (T`2, R`1) -> R`1" | |
| g = f(3) | |
| reveal_type(g) # N: Revealed type is "def [R] (builtins.int, R`3) -> R`3" | |
| 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[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[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, 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, 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[str | int, str]") \ | |
| # N: Perhaps you need a type annotation for "x"? Suggestion: "dict[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[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[int | float]") | |
| def g() -> List[Union[str, int]]: | |
| x = ('a', 2) | |
| return x # E: Incompatible return value type (got "tuple[str, int]", expected "list[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, 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[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 testDeferredLambdaInOverload] | |
| from typing import Any, Callable, overload | |
| @overload | |
| def option(*, callback: Callable[[str], object] = ...) -> Any: ... | |
| @overload | |
| def option(*, callback: Callable[[int], object] = ...) -> Any: ... | |
| def option(**kwargs: object) -> None: pass | |
| def test() -> None: | |
| option(callback=lambda x: [y for y in x]) # OK | |
| x = C().x | |
| class C: | |
| def __init__(self) -> None: | |
| self.x = defer() | |
| def defer() -> int: ... | |
| [builtins fixtures/primitives.pyi] | |
| [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] | |
| 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) | |
| [case testNoComplainInferredNoneStrict] | |
| from typing import TypeVar, Optional | |
| T = TypeVar('T') | |
| def X(val: T) -> T: ... | |
| x_in = X(None) | |
| def Y(x: Optional[str] = X(x_in)): ... | |
| xx: Optional[int] = X(x_in) | |
| [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=(1 + 'asdf'): a # E: Unsupported operand types for + ("int" and "str") | |
| lambda a=nonsense: a # E: Name "nonsense" is not defined | |
| 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] | |
| [case testDecoratedProperty] | |
| from typing import TypeVar, Callable, final | |
| T = TypeVar("T") | |
| def dec(f: Callable[[T], int]) -> Callable[[T], str]: ... | |
| def dec2(f: T) -> T: ... | |
| class A: | |
| @property | |
| @dec | |
| def f(self) -> int: pass | |
| @property | |
| @dec2 | |
| def g(self) -> int: pass | |
| reveal_type(A().f) # N: Revealed type is "builtins.str" | |
| reveal_type(A().g) # N: Revealed type is "builtins.int" | |
| class B: | |
| @final | |
| @property | |
| @dec | |
| def f(self) -> int: pass | |
| reveal_type(B().f) # N: Revealed type is "builtins.str" | |
| class C: | |
| @property # E: Only instance methods can be decorated with @property | |
| @classmethod | |
| def f(cls) -> int: pass | |
| reveal_type(C().f) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/property.pyi] | |
| [out] | |
| [case testDecoratedPropertySetter] | |
| from typing import TypeVar, Callable, final | |
| T = TypeVar("T") | |
| def dec(f: T) -> T: ... | |
| class A: | |
| @property | |
| @dec | |
| def f(self) -> int: pass | |
| @f.setter | |
| @dec | |
| def f(self, v: int) -> None: pass | |
| reveal_type(A().f) # N: Revealed type is "builtins.int" | |
| class B: | |
| @property | |
| @dec | |
| def f(self) -> int: pass | |
| @dec # E: Only supported top decorators are "@f.setter" and "@f.deleter" | |
| @f.setter | |
| def f(self, v: int) -> None: pass | |
| class C: | |
| @dec # E: Decorators on top of @property are not supported | |
| @property | |
| def f(self) -> int: pass | |
| @f.setter | |
| @dec | |
| def f(self, v: int) -> None: pass | |
| [builtins fixtures/property.pyi] | |
| [case testInvalidArgCountForProperty] | |
| from typing import Callable, TypeVar | |
| T = TypeVar("T") | |
| def dec(f: Callable[[T], int]) -> Callable[[T, int], int]: ... | |
| class A: | |
| @property # E: Too many arguments for property | |
| def f(self, x) -> int: pass | |
| @property # E: Too many arguments for property | |
| @dec | |
| def e(self) -> int: pass | |
| @property | |
| def g() -> int: pass # E: Method must have at least one argument. Did you forget the "self" argument? | |
| @property | |
| def h(self, *args, **kwargs) -> int: pass # OK | |
| [builtins fixtures/property.pyi] | |
| [case testSubtypingUnionGenericBounds] | |
| from typing import Callable, TypeVar, Union, Sequence | |
| TI = TypeVar("TI", bound=int) | |
| TS = TypeVar("TS", bound=str) | |
| f: Callable[[Sequence[TI]], None] | |
| g: Callable[[Union[Sequence[TI], Sequence[TS]]], None] | |
| f = g | |
| [case testOverrideDecoratedProperty] | |
| class Base: | |
| @property | |
| def foo(self) -> int: ... | |
| class decorator: | |
| def __init__(self, fn): | |
| self.fn = fn | |
| def __call__(self, decorated_self) -> int: | |
| return self.fn(decorated_self) | |
| class Child(Base): | |
| @property | |
| @decorator | |
| def foo(self) -> int: | |
| return 42 | |
| reveal_type(Child().foo) # N: Revealed type is "builtins.int" | |
| Child().foo = 1 # E: Property "foo" defined in "Child" is read-only | |
| reveal_type(Child().foo) # N: Revealed type is "builtins.int" | |
| class BadChild1(Base): | |
| @decorator | |
| def foo(self) -> int: # E: Signature of "foo" incompatible with supertype "Base" \ | |
| # N: Superclass: \ | |
| # N: int \ | |
| # N: Subclass: \ | |
| # N: decorator | |
| return 42 | |
| class not_a_decorator: | |
| def __init__(self, fn): ... | |
| class BadChild2(Base): | |
| # Override error not shown as accessing 'foo' on BadChild2 returns Any. | |
| @property | |
| @not_a_decorator | |
| def foo(self) -> int: | |
| return 42 | |
| reveal_type(BadChild2().foo) # E: "not_a_decorator" not callable \ | |
| # N: Revealed type is "Any" | |
| [builtins fixtures/property.pyi] | |
| [case explicitOverride] | |
| # flags: --python-version 3.12 | |
| from typing import override | |
| class A: | |
| def f(self, x: int) -> str: pass | |
| @override | |
| def g(self, x: int) -> str: pass # E: Method "g" is marked as an override, but no base method was found with this name | |
| class B(A): | |
| @override | |
| def f(self, x: int) -> str: pass | |
| @override | |
| def g(self, x: int) -> str: pass | |
| class C(A): | |
| @override | |
| def f(self, x: str) -> str: 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 | |
| def g(self, x: int) -> str: pass | |
| class D(A): pass | |
| class E(D): pass | |
| class F(E): | |
| @override | |
| def f(self, x: int) -> str: pass | |
| [typing fixtures/typing-override.pyi] | |
| [case explicitOverrideStaticmethod] | |
| # flags: --python-version 3.12 | |
| from typing import override | |
| class A: | |
| @staticmethod | |
| def f(x: int) -> str: pass | |
| class B(A): | |
| @staticmethod | |
| @override | |
| def f(x: int) -> str: pass | |
| @override | |
| @staticmethod | |
| def g(x: int) -> str: pass # E: Method "g" is marked as an override, but no base method was found with this name | |
| class C(A): # inverted order of decorators | |
| @override | |
| @staticmethod | |
| def f(x: int) -> str: pass | |
| @override | |
| @staticmethod | |
| def g(x: int) -> str: pass # E: Method "g" is marked as an override, but no base method was found with this name | |
| class D(A): | |
| @staticmethod | |
| @override | |
| def f(x: str) -> str: 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 | |
| [typing fixtures/typing-override.pyi] | |
| [builtins fixtures/staticmethod.pyi] | |
| [case explicitOverrideClassmethod] | |
| # flags: --python-version 3.12 | |
| from typing import override | |
| class A: | |
| @classmethod | |
| def f(cls, x: int) -> str: pass | |
| class B(A): | |
| @classmethod | |
| @override | |
| def f(cls, x: int) -> str: pass | |
| @override | |
| @classmethod | |
| def g(cls, x: int) -> str: pass # E: Method "g" is marked as an override, but no base method was found with this name | |
| class C(A): # inverted order of decorators | |
| @override | |
| @classmethod | |
| def f(cls, x: int) -> str: pass | |
| @override | |
| @classmethod | |
| def g(cls, x: int) -> str: pass # E: Method "g" is marked as an override, but no base method was found with this name | |
| class D(A): | |
| @classmethod | |
| @override | |
| def f(cls, x: str) -> str: 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 | |
| [typing fixtures/typing-override.pyi] | |
| [builtins fixtures/classmethod.pyi] | |
| [case explicitOverrideProperty] | |
| # flags: --python-version 3.12 | |
| from typing import override | |
| class A: | |
| @property | |
| def f(self) -> str: pass | |
| class B(A): | |
| @property | |
| @override | |
| def f(self) -> str: pass | |
| @override | |
| @property | |
| def g(self) -> str: pass # E: Method "g" is marked as an override, but no base method was found with this name | |
| class C(A): # inverted order of decorators | |
| @override | |
| @property | |
| def f(self) -> str: pass | |
| @override | |
| @property | |
| def g(self) -> str: pass # E: Method "g" is marked as an override, but no base method was found with this name | |
| class D(A): | |
| @property | |
| @override | |
| def f(self) -> int: pass # E: Signature of "f" incompatible with supertype "A" \ | |
| # N: Superclass: \ | |
| # N: str \ | |
| # N: Subclass: \ | |
| # N: int | |
| [typing fixtures/typing-override.pyi] | |
| [builtins fixtures/property.pyi] | |
| [case explicitOverrideSettableProperty] | |
| # flags: --python-version 3.12 | |
| from typing import override | |
| class A: | |
| @property | |
| def f(self) -> str: pass | |
| @f.setter | |
| def f(self, value: str) -> None: pass | |
| class B(A): | |
| @property # E: Read-only property cannot override read-write property | |
| @override | |
| def f(self) -> str: pass | |
| class C(A): | |
| @override | |
| @property | |
| def f(self) -> str: pass | |
| @f.setter | |
| def f(self, value: str) -> None: pass | |
| class D(A): | |
| @override # E: Signature of "f" incompatible with supertype "A" \ | |
| # N: Superclass: \ | |
| # N: str \ | |
| # N: Subclass: \ | |
| # N: int | |
| @property | |
| def f(self) -> int: pass | |
| @f.setter | |
| def f(self, value: int) -> None: pass | |
| [typing fixtures/typing-override.pyi] | |
| [builtins fixtures/property.pyi] | |
| [case invalidExplicitOverride] | |
| # flags: --python-version 3.12 | |
| from typing import override | |
| @override # E: "override" used with a non-method | |
| def f(x: int) -> str: pass | |
| @override # this should probably throw an error but the signature from typeshed should ensure this already | |
| class A: pass | |
| def g() -> None: | |
| @override # E: "override" used with a non-method | |
| def h(b: bool) -> int: pass | |
| [typing fixtures/typing-override.pyi] | |
| [case explicitOverrideSpecialMethods] | |
| # flags: --python-version 3.12 | |
| from typing import override | |
| class A: | |
| def __init__(self, a: int) -> None: pass | |
| class B(A): | |
| @override | |
| def __init__(self, b: str) -> None: pass | |
| class C: | |
| @override | |
| def __init__(self, a: int) -> None: pass | |
| [typing fixtures/typing-override.pyi] | |
| [case explicitOverrideFromExtensions] | |
| from typing_extensions import override | |
| class A: | |
| def f(self, x: int) -> str: pass | |
| class B(A): | |
| @override | |
| def f2(self, x: int) -> str: pass # E: Method "f2" is marked as an override, but no base method was found with this name | |
| [builtins fixtures/tuple.pyi] | |
| [case explicitOverrideOverloads] | |
| # flags: --python-version 3.12 | |
| from typing import overload, override | |
| class A: | |
| def f(self, x: int) -> str: pass | |
| class B(A): | |
| @overload # E: Method "f2" is marked as an override, but no base method was found with this name | |
| def f2(self, x: int) -> str: pass | |
| @overload | |
| def f2(self, x: str) -> str: pass | |
| @override | |
| def f2(self, x: int | str) -> str: pass | |
| [typing fixtures/typing-override.pyi] | |
| [case explicitOverrideNotOnOverloadsImplementation] | |
| # flags: --python-version 3.12 | |
| from typing import overload, override | |
| class A: | |
| def f(self, x: int) -> str: pass | |
| class B(A): | |
| @overload # E: Method "f2" is marked as an override, but no base method was found with this name | |
| def f2(self, x: int) -> str: pass | |
| @override | |
| @overload | |
| def f2(self, x: str) -> str: pass | |
| def f2(self, x: int | str) -> str: pass | |
| class C(A): | |
| @overload | |
| def f(self, y: int) -> str: pass | |
| @override | |
| @overload | |
| def f(self, y: str) -> str: pass | |
| def f(self, y: int | str) -> str: pass | |
| [typing fixtures/typing-override.pyi] | |
| [case explicitOverrideOnMultipleOverloads] | |
| # flags: --python-version 3.12 | |
| from typing import overload, override | |
| class A: | |
| def f(self, x: int) -> str: pass | |
| class B(A): | |
| @override # E: Method "f2" is marked as an override, but no base method was found with this name | |
| @overload | |
| def f2(self, x: int) -> str: pass | |
| @override | |
| @overload | |
| def f2(self, x: str) -> str: pass | |
| def f2(self, x: int | str) -> str: pass | |
| class C(A): | |
| @overload | |
| def f(self, y: int) -> str: pass | |
| @override | |
| @overload | |
| def f(self, y: str) -> str: pass | |
| @override | |
| def f(self, y: int | str) -> str: pass | |
| [typing fixtures/typing-override.pyi] | |
| [case explicitOverrideCyclicDependency] | |
| # flags: --python-version 3.12 | |
| import b | |
| [file a.py] | |
| from typing import override | |
| import b | |
| import c | |
| class A(b.B): | |
| @override # This is fine | |
| @c.deco | |
| def meth(self) -> int: ... | |
| [file b.py] | |
| import a | |
| import c | |
| class B: | |
| @c.deco | |
| def meth(self) -> int: ... | |
| [file c.py] | |
| from typing import TypeVar, Tuple, Callable | |
| T = TypeVar('T') | |
| def deco(f: Callable[..., T]) -> Callable[..., Tuple[T, int]]: ... | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-override.pyi] | |
| [case requireExplicitOverrideMethod] | |
| # flags: --enable-error-code explicit-override --python-version 3.12 | |
| from typing import override | |
| class A: | |
| def f(self, x: int) -> str: pass | |
| class B(A): | |
| @override | |
| def f(self, y: int) -> str: pass | |
| class C(A): | |
| def f(self, y: int) -> str: pass # E: Method "f" is not using @override but is overriding a method in class "__main__.A" | |
| class D(B): | |
| def f(self, y: int) -> str: pass # E: Method "f" is not using @override but is overriding a method in class "__main__.B" | |
| [typing fixtures/typing-override.pyi] | |
| [case requireExplicitOverrideSpecialMethod] | |
| # flags: --enable-error-code explicit-override --python-version 3.12 | |
| from typing import Callable, Self, TypeVar, override, overload | |
| T = TypeVar('T') | |
| def some_decorator(f: Callable[..., T]) -> Callable[..., T]: ... | |
| # Don't require override decorator for __init__ and __new__ | |
| # See: https://github.com/python/typing/issues/1376 | |
| class A: | |
| def __init__(self) -> None: pass | |
| def __new__(cls) -> Self: pass | |
| class B(A): | |
| def __init__(self) -> None: pass | |
| def __new__(cls) -> Self: pass | |
| class C(A): | |
| @some_decorator | |
| def __init__(self) -> None: pass | |
| @some_decorator | |
| def __new__(cls) -> Self: pass | |
| class D(A): | |
| @overload | |
| def __init__(self, x: int) -> None: ... | |
| @overload | |
| def __init__(self, x: str) -> None: ... | |
| def __init__(self, x): pass | |
| @overload | |
| def __new__(cls, x: int) -> Self: pass | |
| @overload | |
| def __new__(cls, x: str) -> Self: pass | |
| def __new__(cls, x): pass | |
| [typing fixtures/typing-override.pyi] | |
| [case requireExplicitOverrideProperty] | |
| # flags: --enable-error-code explicit-override --python-version 3.12 | |
| from typing import override | |
| class A: | |
| @property | |
| def prop(self) -> int: pass | |
| class B(A): | |
| @override | |
| @property | |
| def prop(self) -> int: pass | |
| class C(A): | |
| @property | |
| def prop(self) -> int: pass # E: Method "prop" is not using @override but is overriding a method in class "__main__.A" | |
| [typing fixtures/typing-override.pyi] | |
| [builtins fixtures/property.pyi] | |
| [case requireExplicitOverrideOverload] | |
| # flags: --enable-error-code explicit-override --python-version 3.12 | |
| from typing import overload, override | |
| class A: | |
| @overload | |
| def f(self, x: int) -> str: ... | |
| @overload | |
| def f(self, x: str) -> str: ... | |
| def f(self, x): pass | |
| class B(A): | |
| @overload | |
| def f(self, y: int) -> str: ... | |
| @overload | |
| def f(self, y: str) -> str: ... | |
| @override | |
| def f(self, y): pass | |
| class C(A): | |
| @overload | |
| @override | |
| def f(self, y: int) -> str: ... | |
| @overload | |
| def f(self, y: str) -> str: ... | |
| def f(self, y): pass | |
| class D(A): | |
| @overload | |
| def f(self, y: int) -> str: ... | |
| @overload | |
| def f(self, y: str) -> str: ... | |
| def f(self, y): pass # E: Method "f" is not using @override but is overriding a method in class "__main__.A" | |
| [typing fixtures/typing-override.pyi] | |
| [case requireExplicitOverrideMultipleInheritance] | |
| # flags: --enable-error-code explicit-override --python-version 3.12 | |
| from typing import override | |
| class A: | |
| def f(self, x: int) -> str: pass | |
| class B: | |
| def f(self, y: int) -> str: pass | |
| class C(A, B): | |
| @override | |
| def f(self, z: int) -> str: pass | |
| class D(A, B): | |
| def f(self, z: int) -> str: pass # E: Method "f" is not using @override but is overriding a method in class "__main__.A" | |
| [typing fixtures/typing-override.pyi] | |
| [case testExplicitOverrideAllowedForPrivate] | |
| # flags: --enable-error-code explicit-override --python-version 3.12 | |
| class B: | |
| def __f(self, y: int) -> str: pass | |
| class C(B): | |
| def __f(self, y: int) -> str: pass # OK | |
| [typing fixtures/typing-override.pyi] | |
| [case testOverrideUntypedDef] | |
| # flags: --python-version 3.12 | |
| from typing import override | |
| class Parent: pass | |
| class Child(Parent): | |
| @override | |
| def foo(self, y): pass # E: Method "foo" is marked as an override, but no base method was found with this name | |
| [typing fixtures/typing-override.pyi] | |
| [case testOverrideOnUnknownBaseClass] | |
| # flags: --python-version 3.12 | |
| from typing import overload, override | |
| from unknown import UnknownParent # type: ignore[import-not-found] | |
| class UnknownChild(UnknownParent): | |
| @override | |
| def foo(self, y): pass # OK | |
| @override | |
| def bar(self, y: str) -> None: pass # OK | |
| @override | |
| @overload | |
| def baz(self, y: str) -> None: ... | |
| @override | |
| @overload | |
| def baz(self, y: int) -> None: ... | |
| def baz(self, y: str | int) -> None: ... | |
| [typing fixtures/typing-override.pyi] | |
| [case testCallableProperty] | |
| from typing import Callable | |
| class something_callable: | |
| def __call__(self, fn) -> str: ... | |
| def decorator(fn: Callable[..., int]) -> something_callable: ... | |
| class A: | |
| @property | |
| @decorator | |
| def f(self) -> int: ... | |
| reveal_type(A.f) # N: Revealed type is "__main__.something_callable" | |
| reveal_type(A().f) # N: Revealed type is "builtins.str" | |
| [builtins fixtures/property.pyi] | |
| [case testFinalOverrideOnUntypedDef] | |
| from typing import final | |
| class Base: | |
| @final | |
| def foo(self): | |
| pass | |
| class Derived(Base): | |
| def foo(self): # E: Cannot override final attribute "foo" (previously declared in base class "Base") | |
| pass | |
| [case testTypeVarIdClashPolymorphic] | |
| from typing import Callable, Generic, TypeVar | |
| A = TypeVar("A") | |
| B = TypeVar("B") | |
| class Gen(Generic[A]): ... | |
| def id_(x: A) -> A: ... | |
| def f(x: Gen[A], y: A) -> Gen[Gen[A]]: ... | |
| def g(x: Gen[A], id_: Callable[[B], B], f: Callable[[A, B], Gen[A]]) -> A: ... | |
| def test(x: Gen[Gen[A]]) -> Gen[A]: | |
| return g(x, id_, f) # Technically OK | |
| x: Gen[Gen[int]] | |
| reveal_type(g(x, id_, f)) # N: Revealed type is "__main__.Gen[builtins.int]" | |
| def h(x: A, y: A) -> A: ... | |
| def gn(id_: Callable[[B], B], step: Callable[[A, B], A]) -> A: ... | |
| def fn(x: A) -> A: | |
| return gn(id_, h) # Technically OK | |
| [case testTypeVarIdsNested] | |
| from typing import Callable, TypeVar | |
| A = TypeVar("A") | |
| B = TypeVar("B") | |
| def f(x: Callable[[A], A]) -> Callable[[B], B]: | |
| def g(x: B) -> B: ... | |
| return g | |
| reveal_type(f(f)) # N: Revealed type is "def [B] (B`1) -> B`1" | |
| reveal_type(f(f)(f)) # N: Revealed type is "def [A] (x: def (A`-1) -> A`-1) -> def [B] (B`-2) -> B`-2" | |
| [case testGenericUnionFunctionJoin] | |
| from typing import TypeVar, Union | |
| T = TypeVar("T") | |
| S = TypeVar("S") | |
| def f(x: T, y: S) -> Union[T, S]: ... | |
| def g(x: T, y: S) -> Union[T, S]: ... | |
| x = [f, g] | |
| reveal_type(x) # N: Revealed type is "builtins.list[def [T, S] (x: T`4, y: S`5) -> T`4 | S`5]" | |
| [builtins fixtures/list.pyi] | |
| [case testTypeVariableClashErrorMessage] | |
| from typing import TypeVar | |
| T = TypeVar("T") | |
| class C: # Note: Generic[T] missing | |
| def bad_idea(self, x: T) -> None: | |
| self.x = x | |
| def nope(self, x: T) -> None: | |
| self.x = x # E: Incompatible types in assignment (expression has type "T@nope", variable has type "T@bad_idea") | |
| [case testNoCrashOnBadCallablePropertyOverride] | |
| from typing import Callable, Union | |
| class C: ... | |
| class D: ... | |
| A = Callable[[C], None] | |
| B = Callable[[D], None] | |
| class Foo: | |
| @property | |
| def method(self) -> Callable[[int, Union[A, B]], None]: | |
| ... | |
| class Bar(Foo): | |
| @property | |
| def method(self) -> Callable[[int, A], None]: # E: Argument 2 of "method" is incompatible with supertype "Foo"; supertype defines the argument type as "Callable[[C], None] | Callable[[D], None]" \ | |
| # N: This violates the Liskov substitution principle \ | |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides | |
| ... | |
| [builtins fixtures/property.pyi] | |
| [case testNoCrashOnUnpackOverride] | |
| from typing import TypedDict, Unpack | |
| class Params(TypedDict): | |
| x: int | |
| y: str | |
| class Other(TypedDict): | |
| x: int | |
| y: int | |
| class B: | |
| def meth(self, **kwargs: Unpack[Params]) -> None: | |
| ... | |
| class C(B): | |
| def meth(self, **kwargs: Unpack[Other]) -> None: # E: Signature of "meth" incompatible with supertype "B" \ | |
| # N: Superclass: \ | |
| # N: def meth(*, x: int, y: str) -> None \ | |
| # N: Subclass: \ | |
| # N: def meth(*, x: int, y: int) -> None | |
| ... | |
| [builtins fixtures/dict.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testOverrideErrorLocationNamed] | |
| class B: | |
| def meth( | |
| self, *, | |
| x: int, | |
| y: str, | |
| ) -> None: | |
| ... | |
| class C(B): | |
| def meth( | |
| self, *, | |
| y: int, # E: Argument 1 of "meth" is incompatible with supertype "B"; supertype defines the argument type as "str" \ | |
| # N: This violates the Liskov substitution principle \ | |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides | |
| x: int, | |
| ) -> None: | |
| ... | |
| [builtins fixtures/tuple.pyi] | |
| [case testLambdaAlwaysAllowed] | |
| # flags: --disallow-untyped-calls | |
| from typing import Callable, Optional | |
| def func() -> Optional[str]: ... | |
| var: Optional[str] | |
| factory: Callable[[], Optional[str]] | |
| for factory in ( | |
| lambda: var, | |
| func, | |
| ): | |
| reveal_type(factory) # N: Revealed type is "def () -> builtins.str | None" | |
| var = factory() | |
| [builtins fixtures/tuple.pyi] | |
| [case testLambdaInDeferredDecoratorNoCrash] | |
| def foo(x): | |
| pass | |
| class Bar: | |
| def baz(self, x): | |
| pass | |
| class Qux(Bar): | |
| @foo(lambda x: None) | |
| def baz(self, x) -> None: | |
| pass | |
| [builtins fixtures/tuple.pyi] | |
| [case testGeneratorInDeferredDecoratorNoCrash] | |
| from typing import Protocol, TypeVar | |
| T = TypeVar("T", covariant=True) | |
| class SupportsNext(Protocol[T]): | |
| def __next__(self) -> T: ... | |
| def next(i: SupportsNext[T]) -> T: ... | |
| def foo(x): | |
| pass | |
| class Bar: | |
| def baz(self, x): | |
| pass | |
| class Qux(Bar): | |
| @next(f for f in [foo]) | |
| def baz(self, x) -> None: | |
| pass | |
| [builtins fixtures/tuple.pyi] | |
| [case testCallableJoinWithDefaults] | |
| from typing import Callable, TypeVar | |
| T = TypeVar("T") | |
| def join(t1: T, t2: T) -> T: ... | |
| def f1() -> None: ... | |
| def f2(i: int = 0) -> None: ... | |
| def f3(i: str = "") -> None: ... | |
| reveal_type(join(f1, f2)) # N: Revealed type is "def ()" | |
| reveal_type(join(f1, f3)) # N: Revealed type is "def ()" | |
| reveal_type(join(f2, f3)) # N: Revealed type is "builtins.function" # TODO: this could be better | |
| [builtins fixtures/tuple.pyi] | |
| [case testCallableJoinWithDefaultsMultiple] | |
| from typing import TypeVar | |
| T = TypeVar("T") | |
| def join(t1: T, t2: T, t3: T) -> T: ... | |
| def f_1(common, a=None): ... | |
| def f_any(*_, **__): ... | |
| def f_3(common, b=None, x=None): ... | |
| fdict = { | |
| "f_1": f_1, | |
| "f_any": f_any, | |
| "f_3": f_3, | |
| } | |
| reveal_type(fdict) # N: Revealed type is "builtins.dict[builtins.str, def (common: Any, a: Any =) -> Any]" | |
| reveal_type(join(f_1, f_any, f_3)) # N: Revealed type is "def (common: Any, a: Any =) -> Any" | |
| [builtins fixtures/tuple.pyi] | |
| [case testCallableJoinWithType] | |
| from __future__ import annotations | |
| class Exc: ... | |
| class AttributeErr(Exc): | |
| def __init__(self, *args: object) -> None: ... | |
| class FnfErr(Exc): ... | |
| x = [ | |
| FnfErr, | |
| AttributeErr, | |
| ] | |
| reveal_type(x) # N: Revealed type is "builtins.list[builtins.type]" | |
| [builtins fixtures/type.pyi] | |
| [case testDistinctFormatting] | |
| from typing import Awaitable, Callable, ParamSpec | |
| P = ParamSpec("P") | |
| class A: pass | |
| class B(A): pass | |
| def decorator(f: Callable[P, None]) -> Callable[[Callable[P, A]], None]: | |
| return lambda _: None | |
| def key(x: int) -> None: ... | |
| def fn_b(b: int) -> B: ... | |
| decorator(key)(fn_b) # E: Argument 1 has incompatible type "def fn_b(b: int) -> B"; expected "def (x: int) -> A" | |
| def decorator2(f: Callable[P, None]) -> Callable[ | |
| [Callable[P, Awaitable[None]]], | |
| Callable[P, Awaitable[None]], | |
| ]: | |
| return lambda f: f | |
| def key2(x: int) -> None: | |
| ... | |
| @decorator2(key2) # E: Argument 1 has incompatible type "def foo2(y: int) -> Coroutine[Any, Any, None]"; expected "def (x: int) -> Awaitable[None]" | |
| async def foo2(y: int) -> None: | |
| ... | |
| class Parent: | |
| def method_without(self) -> "Parent": ... | |
| def method_with(self, param: str) -> "Parent": ... | |
| class Child(Parent): | |
| method_without: Callable[[], "Child"] | |
| method_with: Callable[[str], "Child"] # E: Incompatible types in assignment (expression has type "Callable[[str], Child]", base class "Parent" defined the type as "def method_with(self, param: str) -> Parent") | |
| [builtins fixtures/tuple.pyi] | |
| [case testDistinctFormattingUnion] | |
| from typing import Callable, Union | |
| from mypy_extensions import Arg | |
| def f(x: Callable[[Arg(int, 'x')], None]) -> None: pass | |
| y: Callable[[Union[int, str]], None] | |
| f(y) # E: Argument 1 to "f" has incompatible type "Callable[[int | str], None]"; expected "def (x: int) -> None" | |
| [builtins fixtures/tuple.pyi] | |
| [case testAbstractOverloadsWithoutImplementationAllowed] | |
| from abc import abstractmethod | |
| from typing import overload, Union | |
| class Foo: | |
| @overload | |
| @abstractmethod | |
| def foo(self, value: int) -> int: | |
| ... | |
| @overload | |
| @abstractmethod | |
| def foo(self, value: str) -> str: | |
| ... | |
| class Bar(Foo): | |
| @overload | |
| def foo(self, value: int) -> int: | |
| ... | |
| @overload | |
| def foo(self, value: str) -> str: | |
| ... | |
| def foo(self, value: Union[int, str]) -> Union[int, str]: | |
| return super().foo(value) # E: Call to abstract method "foo" of "Foo" with trivial body via super() is unsafe | |
| [case fullNamesOfImportedBaseClassesDisplayed] | |
| from a import A | |
| class B(A): | |
| def f(self, x: str) -> None: # E: Argument 1 of "f" is incompatible with supertype "a.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 | |
| ... | |
| def g(self, x: str) -> None: # E: Signature of "g" incompatible with supertype "a.A" \ | |
| # N: Superclass: \ | |
| # N: def g(self) -> None \ | |
| # N: Subclass: \ | |
| # N: def g(self, x: str) -> None | |
| ... | |
| [file a.py] | |
| class A: | |
| def f(self, x: int) -> None: | |
| ... | |
| def g(self) -> None: | |
| ... | |
| [case testBoundMethodsAssignedInClassBody] | |
| from typing import Callable | |
| class A: | |
| def f(self, x: int) -> str: | |
| pass | |
| @classmethod | |
| def g(cls, x: int) -> str: | |
| pass | |
| @staticmethod | |
| def h(x: int) -> str: | |
| pass | |
| attr: Callable[[int], str] | |
| class C: | |
| x1 = A.f | |
| x2 = A.g | |
| x3 = A().f | |
| x4 = A().g | |
| x5 = A.h | |
| x6 = A().h | |
| x7 = A().attr | |
| reveal_type(C.x1) # N: Revealed type is "def (self: __main__.A, x: builtins.int) -> builtins.str" | |
| reveal_type(C.x2) # N: Revealed type is "def (x: builtins.int) -> builtins.str" | |
| reveal_type(C.x3) # N: Revealed type is "def (x: builtins.int) -> builtins.str" | |
| reveal_type(C.x4) # N: Revealed type is "def (x: builtins.int) -> builtins.str" | |
| reveal_type(C.x5) # N: Revealed type is "def (x: builtins.int) -> builtins.str" | |
| reveal_type(C.x6) # N: Revealed type is "def (x: builtins.int) -> builtins.str" | |
| reveal_type(C.x7) # N: Revealed type is "def (builtins.int) -> builtins.str" | |
| reveal_type(C().x1) # E: Invalid self argument "C" to attribute function "x1" with type "Callable[[A, int], str]" \ | |
| # N: Revealed type is "def (x: builtins.int) -> builtins.str" | |
| reveal_type(C().x2) # N: Revealed type is "def (x: builtins.int) -> builtins.str" | |
| reveal_type(C().x3) # N: Revealed type is "def (x: builtins.int) -> builtins.str" | |
| reveal_type(C().x4) # N: Revealed type is "def (x: builtins.int) -> builtins.str" | |
| reveal_type(C().x5) # N: Revealed type is "def (x: builtins.int) -> builtins.str" | |
| reveal_type(C().x6) # N: Revealed type is "def (x: builtins.int) -> builtins.str" | |
| reveal_type(C().x7) # E: Invalid self argument "C" to attribute function "x7" with type "Callable[[int], str]" \ | |
| # N: Revealed type is "def () -> builtins.str" | |
| [builtins fixtures/classmethod.pyi] | |
| [case testFunctionRedefinitionDeferred] | |
| from typing import Callable, TypeVar | |
| def outer() -> None: | |
| if bool(): | |
| def inner() -> str: ... | |
| else: | |
| def inner() -> int: ... # E: All conditional function variants must have identical signatures \ | |
| # N: Original: \ | |
| # N: def inner() -> str \ | |
| # N: Redefinition: \ | |
| # N: def inner() -> int | |
| x = defer() | |
| T = TypeVar("T") | |
| def deco(fn: Callable[[], T]) -> Callable[[], list[T]]: ... | |
| @deco | |
| def defer() -> int: ... | |
| [builtins fixtures/list.pyi] | |
| [case testCheckFunctionErrorContextDuplicateDeferred] | |
| # flags: --show-error-context | |
| from typing import Callable, TypeVar | |
| def a() -> None: | |
| def b() -> None: | |
| 1 + "" | |
| x = defer() | |
| T = TypeVar("T") | |
| def deco(fn: Callable[[], T]) -> Callable[[], list[T]]: ... | |
| @deco | |
| def defer() -> int: ... | |
| [out] | |
| main: note: In function "a": | |
| main:6: error: Unsupported operand types for + ("int" and "str") | |
| [case testNoExtraNoteForUnpacking] | |
| from typing import Protocol | |
| class P(Protocol): | |
| arg: int | |
| # Something that list and dict also have | |
| def __contains__(self, item: object) -> bool: ... | |
| def foo(x: P, y: P) -> None: ... | |
| args: list[object] | |
| foo(*args) # E: Argument 1 to "foo" has incompatible type "*list[object]"; expected "P" | |
| kwargs: dict[str, object] | |
| foo(**kwargs) # E: Argument 1 to "foo" has incompatible type "**dict[str, object]"; expected "P" | |
| [builtins fixtures/dict.pyi] | |
| [case testNoImplicitReturnErrorOnDeferral_no_empty] | |
| # flags: --no-warn-no-return | |
| def deferred() -> int: | |
| c: C | |
| x = 1 | |
| if int(): | |
| x = c.x | |
| reveal_type(x) # N: Revealed type is "builtins.int" | |
| return x | |
| class C: | |
| def __init__(self) -> None: | |
| self.x = defer() | |
| def defer() -> int: | |
| return 1 | |
| [case testNarrowingForDefaultInInnerFunction] | |
| from typing import Optional | |
| def outer(x: Optional[float]) -> None: | |
| if x is not None: | |
| def inner(y: float = x) -> None: ... # OK | |
| def bad(y: float = x) -> None: ... # E: Incompatible default for parameter "y" (default has type "float | None", parameter has type "float") | |
| [case testMissingPositionalArgShiftDetectedMiddle] | |
| def f(x: int, y: str, z: bytes, aa: int) -> None: ... | |
| f(1, b'x', 1) | |
| [builtins fixtures/primitives.pyi] | |
| [out] | |
| main:3: error: Missing positional argument "y" in call to "f" | |
| [case testMissingPositionalArgShiftDetectedFirst] | |
| def f(x: int, y: str, z: bytes, last: float) -> None: ... | |
| f("hello", b'x', 1.5) | |
| [builtins fixtures/primitives.pyi] | |
| [out] | |
| main:3: error: Missing positional argument "x" in call to "f" | |
| [case testMissingPositionalArgShiftDetectedManyArgs] | |
| def f(a: int, b: str, c: float, d: list[int], e: tuple[str, ...]) -> None: ... | |
| f(1, 1.5, [1, 2, 3], ("a", "b")) | |
| [builtins fixtures/list.pyi] | |
| [out] | |
| main:3: error: Missing positional argument "b" in call to "f" | |
| [case testMissingPositionalArgShiftDetectedLast] | |
| def f(x: int, y: str, z: bytes) -> None: ... | |
| f(1, "hello") | |
| [builtins fixtures/primitives.pyi] | |
| [out] | |
| main:3: error: Missing positional argument "z" in call to "f" | |
| [case testMissingPositionalArgNoShiftPattern] | |
| def f(x: int, y: str, z: bytes) -> None: ... | |
| f("wrong", 123) | |
| [builtins fixtures/primitives.pyi] | |
| [out] | |
| main:3: error: Missing positional argument "z" in call to "f" | |
| main:3: error: Argument 1 to "f" has incompatible type "str"; expected "int" | |
| main:3: error: Argument 2 to "f" has incompatible type "int"; expected "str" | |
| [case testMissingPositionalArgNoShiftPatternLast] | |
| def f(x: int, y: str, z: bytes) -> None: ... | |
| f(123, "wrong") | |
| [builtins fixtures/primitives.pyi] | |
| [out] | |
| main:3: error: Missing positional argument "z" in call to "f" | |
| [case testMissingPositionalArgNoShiftPatternNone] | |
| def f(x: int) -> None: ... | |
| f() | |
| [builtins fixtures/primitives.pyi] | |
| [out] | |
| main:3: error: Missing positional argument "x" in call to "f" | |
| [case testMissingPositionalArgMultipleMissing] | |
| def f(a: int, b: str, c: float, d: list[int]) -> None: ... | |
| f(1.5, [1, 2, 3]) | |
| [builtins fixtures/list.pyi] | |
| [out] | |
| main:3: error: Missing positional arguments "c", "d" in call to "f" | |
| main:3: error: Argument 1 to "f" has incompatible type "float"; expected "int" | |
| main:3: error: Argument 2 to "f" has incompatible type "list[int]"; expected "str" | |
| [case testMissingPositionalArgWithDefaults] | |
| def f(x: int, y: str, z: bytes = b'default') -> None: ... | |
| f("hello") | |
| [builtins fixtures/primitives.pyi] | |
| [out] | |
| main:3: error: Missing positional argument "y" in call to "f" | |
| main:3: error: Argument 1 to "f" has incompatible type "str"; expected "int" | |
| [case testMissingPositionalArgWithStarArgs] | |
| def f(x: int, y: str, z: bytes, *args: int) -> None: ... | |
| f("hello", b'x') | |
| [builtins fixtures/primitives.pyi] | |
| [out] | |
| main:3: error: Missing positional argument "z" in call to "f" | |
| main:3: error: Argument 1 to "f" has incompatible type "str"; expected "int" | |
| main:3: error: Argument 2 to "f" has incompatible type "bytes"; expected "str" | |
| [case testMissingPositionalArgNamesHigherN] | |
| # See https://github.com/python/mypy/issues/21427 | |
| def convert2(first: int, second: str) -> None: ... | |
| # Possibly omitted arg, but we still issue two errors because there is only one argument | |
| convert2("hello") # E: Missing positional argument "second" in call to "convert2" \ | |
| # E: Argument 1 to "convert2" has incompatible type "str"; expected "int" | |
| # Other cases | |
| convert2() # E: Missing positional arguments "first", "second" in call to "convert2" | |
| convert2("hello", 1) # E: Argument 1 to "convert2" has incompatible type "str"; expected "int" \ | |
| # E: Argument 2 to "convert2" has incompatible type "int"; expected "str" | |
| def convert3(first: int, second: str, third: float) -> None: ... | |
| # Possibly omitted arg, but we now only issue one error | |
| convert3("hello", 3.15) # E: Missing positional argument "first" in call to "convert3" | |
| # Other cases | |
| convert3("hello") # E: Missing positional arguments "second", "third" in call to "convert3" \ | |
| # E: Argument 1 to "convert3" has incompatible type "str"; expected "int" | |
| convert3(3.15, "hello") # E: Missing positional argument "third" in call to "convert3" \ | |
| # E: Argument 1 to "convert3" has incompatible type "float"; expected "int" | |
| def convert4(first: int, second: str, third: float, fourth: bytes) -> None: ... | |
| # Possibly omitted arg, but we now only issue one error | |
| convert4("hello", 3.15, b'') # E: Missing positional argument "first" in call to "convert4" | |
| # Other cases | |
| convert4("hello") # E: Missing positional arguments "second", "third", "fourth" in call to "convert4" \ | |
| # E: Argument 1 to "convert4" has incompatible type "str"; expected "int" | |
| convert4("hello", 3.15) # E: Missing positional arguments "third", "fourth" in call to "convert4" \ | |
| # E: Argument 1 to "convert4" has incompatible type "str"; expected "int" \ | |
| # E: Argument 2 to "convert4" has incompatible type "float"; expected "str" | |
| convert4(b'', "hello", 3.15) # E: Missing positional argument "fourth" in call to "convert4" \ | |
| # E: Argument 1 to "convert4" has incompatible type "bytes"; expected "int" | |
| [builtins fixtures/primitives.pyi] | |
| [case testGenericContextLambdaNoError] | |
| from lib import takes_lambda | |
| takes_lambda(lambda x: 1) | |
| [file lib.py] | |
| from typing import Any, Callable, TypeVar | |
| # extra spaces | |
| Ex = TypeVar("Ex", covariant=True) | |
| def takes_lambda(func: Callable[[Ex], Any]) -> None: | |
| pass |