| -- 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 "Callable[[Any, NamedArg(Any, 'x')], 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 "Callable[[Any, DefaultNamedArg(Any, 'x')], 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 "Callable[[Any, DefaultNamedArg(Any, 'x')], 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 "Callable[[Arg(Any, 'x'), VarArg(Any), KwArg(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 "Callable[[DefaultArg(Any)], None]", variable has type "Callable[[DefaultArg(Any, 'x'), VarArg(Any), KwArg(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 "Callable[[Arg(int, 'a'), Arg(str, 'b')], None]") | |
| if int(): | |
| ff = f # reset | |
| if int(): | |
| gg = ff # E: Incompatible types in assignment (expression has type "Callable[[Arg(int, 'a'), Arg(str, 'b')], None]", variable has type "Callable[[Arg(int, 'a'), DefaultArg(str, 'b')], None]") | |
| if int(): | |
| gg = hh # E: Incompatible types in assignment (expression has type "Callable[[Arg(int, 'aa'), DefaultArg(str, 'b')], None]", variable has type "Callable[[Arg(int, 'a'), DefaultArg(str, 'b')], None]") | |
| [case testSubtypingFunctionsArgsKwargs] | |
| from typing import Any, Callable | |
| def everything(*args: Any, **kwargs: Any) -> None: pass | |
| everywhere: 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 "Callable[[Arg(int, 'a'), Arg(str, 'b')], None]") | |
| [case testLackOfNamesFastparse] | |
| def f(__a: int, __b: str) -> None: pass | |
| def g(a: int, b: str) -> None: pass | |
| ff = f | |
| gg = g | |
| if int(): | |
| ff = g | |
| if int(): | |
| gg = f # E: Incompatible types in assignment (expression has type "Callable[[int, str], None]", variable has type "Callable[[Arg(int, 'a'), Arg(str, 'b')], None]") | |
| [case testFunctionTypeCompatibilityWithOtherTypes] | |
| # 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 "Optional[A]" | |
| if int(): | |
| b = f(a, a) # E: Too many arguments for "f" | |
| if int(): | |
| b = f() | |
| if int(): | |
| b = f(a) | |
| if int(): | |
| b = f(AA()) | |
| [builtins fixtures/tuple.pyi] | |
| [case testDefaultArgumentExpressions] | |
| 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 testDefaultArgumentExpressions2] | |
| import typing | |
| class B: pass | |
| class A: pass | |
| def f(x: 'A' = B()) -> None: # E: Incompatible default for argument "x" (default has type "B", argument has type "A") | |
| b = x # type: B # E: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| a = x # type: A | |
| [case testDefaultArgumentExpressionsGeneric] | |
| 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 argument "x" (default has type "B", argument has type "T") | |
| b = x # type: B # E: Incompatible types in assignment (expression has type "T", variable has type "B") | |
| a = x # type: A | |
| [case testDefaultArgumentsWithSubtypes] | |
| import typing | |
| class A: pass | |
| class B(A): pass | |
| def f(x: 'B' = A()) -> None: # E: Incompatible default for argument "x" (default has type "A", argument has type "B") | |
| pass | |
| def g(x: 'A' = B()) -> None: | |
| pass | |
| [out] | |
| [case testMultipleDefaultArgumentExpressions] | |
| import typing | |
| class A: pass | |
| class B: pass | |
| def f(x: 'A' = B(), y: 'B' = B()) -> None: # E: Incompatible default for argument "x" (default has type "B", argument has type "A") | |
| pass | |
| def h(x: 'A' = A(), y: 'B' = B()) -> None: | |
| pass | |
| [out] | |
| [case testMultipleDefaultArgumentExpressions2] | |
| import typing | |
| class A: pass | |
| class B: pass | |
| def g(x: 'A' = A(), y: 'B' = A()) -> None: # E: Incompatible default for argument "y" (default has type "A", argument 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" | |
| [case testNestedFunctionInMethodWithTooFewArgumentsInTypeComment] | |
| class A: | |
| def f(self): | |
| # type: () -> None | |
| def g(x): # E: Type signature has too few arguments | |
| # type: () -> None | |
| pass | |
| [case testDeepNestedFunctionWithTooFewArgumentsInTypeComment] | |
| class A: | |
| def f(self): | |
| # type: () -> None | |
| class B: | |
| def g(self): | |
| # type: () -> None | |
| def h(x): # E: Type signature has too few arguments | |
| # type: () -> None | |
| pass | |
| [case testDeepNestedMethodInTypeComment] | |
| class A: | |
| def f(self): | |
| # type: () -> None | |
| class B: | |
| class C: | |
| def g(self): | |
| # type: () -> None | |
| pass | |
| [case testMutuallyRecursiveNestedFunctions] | |
| def f() -> None: | |
| def g() -> None: | |
| h(1) | |
| h('') # E | |
| def h(x: int) -> None: | |
| g() | |
| g(1) # E | |
| [out] | |
| main:4: error: Argument 1 to "h" has incompatible type "str"; expected "int" | |
| main:7: error: Too many arguments for "g" | |
| [case testMutuallyRecursiveDecoratedFunctions] | |
| from typing import Callable, Any | |
| def dec(f) -> Callable[..., Any]: pass | |
| def f() -> None: | |
| @dec | |
| def g() -> None: | |
| h() | |
| h.x # E | |
| @dec | |
| def h(x: int) -> None: | |
| g(1) | |
| g.x # E | |
| [out] | |
| main:7: error: "Callable[..., Any]" has no attribute "x" | |
| main:11: error: "Callable[..., Any]" has no attribute "x" | |
| [case testNestedGenericFunctions] | |
| from typing import TypeVar | |
| T = TypeVar('T') | |
| U = TypeVar('U') | |
| def outer(x: T) -> T: | |
| def inner(y: U) -> T: ... | |
| return inner(1) | |
| -- Casts | |
| -- ----- | |
| [case testCastsToAndFromFunctionTypes] | |
| from typing import TypeVar, Callable, Any, cast | |
| t = TypeVar('t') | |
| def f(x: t, | |
| f1: Callable[[], None], | |
| f2: Callable[[Any], None], o: object) -> None: | |
| x = cast(t, f1) | |
| f1 = cast(Callable[[], None], x) | |
| f1 = cast(Callable[[], None], f2) | |
| f1 = cast(Callable[[], None], o) | |
| -- Function decorators | |
| -- ------------------- | |
| [case testTrivialStaticallyTypedFunctionDecorator] | |
| from typing import TypeVar | |
| t = TypeVar('t') | |
| def dec(f: t) -> t: | |
| return f | |
| @dec | |
| def f(x: int) -> None: pass | |
| f(1) | |
| f('x') # E: Argument 1 to "f" has incompatible type "str"; expected "int" | |
| [case testTrivialStaticallyTypedMethodDecorator] | |
| from typing import TypeVar | |
| t = TypeVar('t') | |
| def dec(f: t) -> t: | |
| return f | |
| class A: | |
| @dec | |
| def f(self, x: int) -> None: pass | |
| A().f(1) | |
| A().f('') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int" | |
| class B: pass | |
| [case testTrivialDecoratedNestedFunction] | |
| from typing import TypeVar | |
| t = TypeVar('t') | |
| def dec(f: t) -> t: | |
| return f | |
| def g() -> None: | |
| @dec | |
| def f(x: int) -> None: pass | |
| f(1) | |
| f('') # E: Argument 1 to "f" has incompatible type "str"; expected "int" | |
| [out] | |
| [case testCheckingDecoratedFunction] | |
| import typing | |
| def dec(f): pass | |
| @dec | |
| def f(x: 'A') -> None: | |
| a = x # type: A | |
| if int(): | |
| x = object() # E: Incompatible types in assignment (expression has type "object", variable has type "A") | |
| class A: pass | |
| [out] | |
| [case testDecoratorThatSwitchesType] | |
| from typing import Callable | |
| def dec(x) -> Callable[[], None]: pass | |
| @dec | |
| def f(y): pass | |
| f() | |
| f(None) # E: Too many arguments for "f" | |
| [case testDecoratorThatSwitchesTypeWithMethod] | |
| from typing import Any, Callable | |
| def dec(x) -> Callable[[Any], None]: pass | |
| class A: | |
| @dec | |
| def f(self, a, b, c): pass | |
| a: 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] | |
| -- Forward references to decorated functions | |
| -- ----------------------------------------- | |
| [case testForwardReferenceToDynamicallyTypedDecorator] | |
| def f(self) -> None: | |
| g() | |
| g(1) | |
| def dec(f): | |
| return f | |
| @dec | |
| def g(): | |
| pass | |
| [case testForwardReferenceToDecoratorWithAnyReturn] | |
| from typing import Any | |
| def f(self) -> None: | |
| g() | |
| g(1) | |
| def dec(f) -> Any: | |
| return f | |
| @dec | |
| def g(): | |
| pass | |
| [case testForwardReferenceToDecoratorWithIdentityMapping] | |
| from typing import TypeVar | |
| def f(self) -> None: | |
| g() | |
| g(1) # E: Too many arguments for "g" | |
| h(1).x # E: "str" has no attribute "x" | |
| h('') # E: Argument 1 to "h" has incompatible type "str"; expected "int" | |
| T = TypeVar('T') | |
| def dec(f: T) -> T: | |
| return f | |
| @dec | |
| def g(): pass | |
| @dec | |
| def h(x: int) -> str: pass | |
| [out] | |
| [case testForwardReferenceToDynamicallyTypedDecoratedMethod] | |
| def f(self) -> None: | |
| A().f(1).y | |
| A().f() | |
| class A: | |
| @dec | |
| def f(self, x): pass | |
| def dec(f): return f | |
| [builtins fixtures/staticmethod.pyi] | |
| [case testForwardReferenceToStaticallyTypedDecoratedMethod] | |
| from typing import TypeVar | |
| def f(self) -> None: | |
| A().f(1).y # E: "str" has no attribute "y" | |
| A().f('') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int" | |
| class A: | |
| @dec | |
| def f(self, a: int) -> str: return '' | |
| T = TypeVar('T') | |
| def dec(f: T) -> T: return f | |
| [builtins fixtures/staticmethod.pyi] | |
| [out] | |
| [case testForwardReferenceToDynamicallyTypedProperty] | |
| def f(self) -> None: | |
| A().x.y | |
| class A: | |
| @property | |
| def x(self): pass | |
| [builtins fixtures/property.pyi] | |
| [case testForwardReferenceToStaticallyTypedProperty] | |
| def f(self) -> None: | |
| A().x.y # E: "int" has no attribute "y" | |
| class A: | |
| @property | |
| def x(self) -> int: return 1 | |
| [builtins fixtures/property.pyi] | |
| [out] | |
| [case testForwardReferenceToDynamicallyTypedStaticMethod] | |
| def f(self) -> None: | |
| A.x(1).y | |
| A.x() # E: Missing positional argument "x" in call to "x" | |
| class A: | |
| @staticmethod | |
| def x(x): pass | |
| [builtins fixtures/staticmethod.pyi] | |
| [out] | |
| [case testForwardReferenceToStaticallyTypedStaticMethod] | |
| def f(self) -> None: | |
| A.x(1).y # E: "str" has no attribute "y" | |
| A.x('') # E: Argument 1 to "x" of "A" has incompatible type "str"; expected "int" | |
| class A: | |
| @staticmethod | |
| def x(a: int) -> str: return '' | |
| [builtins fixtures/staticmethod.pyi] | |
| [out] | |
| [case testForwardReferenceToDynamicallyTypedClassMethod] | |
| def f(self) -> None: | |
| A.x(1).y | |
| A.x() # E: Missing positional argument "a" in call to "x" | |
| class A: | |
| @classmethod | |
| def x(cls, a): pass | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testForwardReferenceToStaticallyTypedClassMethod] | |
| def f(self) -> None: | |
| A.x(1).y # E: "str" has no attribute "y" | |
| A.x('') # E: Argument 1 to "x" of "A" has incompatible type "str"; expected "int" | |
| class A: | |
| @classmethod | |
| def x(cls, x: int) -> str: return '' | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testForwardReferenceToDecoratedFunctionUsingMemberExpr] | |
| import m | |
| def f(self) -> None: | |
| g(1).x # E: "str" has no attribute "x" | |
| @m.dec | |
| def g(x: int) -> str: pass | |
| [file m.py] | |
| from typing import TypeVar | |
| T = TypeVar('T') | |
| def dec(f: T) -> T: | |
| return f | |
| [out] | |
| [case testForwardReferenceToFunctionWithMultipleDecorators] | |
| # 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 | |
| [file b.py] | |
| import a | |
| from d import dec | |
| @dec | |
| def g(x: str) -> None: pass | |
| a.f('') | |
| [file d.py] | |
| from typing import TypeVar | |
| T = TypeVar('T') | |
| def dec(f: T) -> T: return f | |
| [out] | |
| tmp/b.py:5: error: Argument 1 to "f" has incompatible type "str"; expected "int" | |
| tmp/a.py:5: error: Argument 1 to "g" has incompatible type "int"; expected "str" | |
| [case testDecoratorWithNoAnnotationInImportCycle] | |
| import a | |
| [file a.py] | |
| import b | |
| from d import dec | |
| @dec | |
| def f(x: int) -> None: pass | |
| b.g(1, z=4) | |
| [file b.py] | |
| import a | |
| from d import dec | |
| @dec | |
| def g(x: str) -> None: pass | |
| a.f('', y=2) | |
| [file d.py] | |
| def dec(f): return f | |
| [case testDecoratorWithFixedReturnTypeInImportCycle] | |
| import a | |
| [file a.py] | |
| import b | |
| from d import dec | |
| @dec | |
| def f(x: int) -> str: pass | |
| b.g(1)() | |
| [file b.py] | |
| import a | |
| from d import dec | |
| @dec | |
| def g(x: int) -> str: pass | |
| a.f(1)() | |
| [file d.py] | |
| from typing import Callable | |
| def dec(f: Callable[[int], str]) -> Callable[[int], str]: return f | |
| [out] | |
| tmp/b.py:5: error: "str" not callable | |
| tmp/a.py:5: error: "str" not callable | |
| [case testDecoratorWithCallAndFixedReturnTypeInImportCycle] | |
| import a | |
| [file a.py] | |
| import b | |
| from d import dec | |
| @dec() | |
| def f(x: int) -> str: pass | |
| b.g(1)() | |
| [file b.py] | |
| import a | |
| from d import dec | |
| @dec() | |
| def g(x: int) -> str: pass | |
| a.f(1)() | |
| [file d.py] | |
| from typing import Callable | |
| def dec() -> Callable[[Callable[[int], str]], Callable[[int], str]]: pass | |
| [out] | |
| tmp/b.py:5: error: "str" not callable | |
| tmp/a.py:5: error: "str" not callable | |
| [case testDecoratorWithCallAndFixedReturnTypeInImportCycleAndDecoratorArgs] | |
| import a | |
| [file a.py] | |
| import b | |
| from d import dec | |
| @dec(1) | |
| def f(x: int) -> str: pass | |
| b.g(1)() | |
| [file b.py] | |
| import a | |
| from d import dec | |
| @dec(1) | |
| def g(x: int) -> str: pass | |
| a.f(1)() | |
| [file d.py] | |
| from typing import Callable | |
| def dec(x: str) -> Callable[[Callable[[int], str]], Callable[[int], str]]: pass | |
| [out] | |
| tmp/b.py:3: error: Argument 1 to "dec" has incompatible type "int"; expected "str" | |
| tmp/b.py:5: error: "str" not callable | |
| tmp/a.py:3: error: Argument 1 to "dec" has incompatible type "int"; expected "str" | |
| tmp/a.py:5: error: "str" not callable | |
| [case testUndefinedDecoratorInImportCycle] | |
| # cmd: mypy -m foo.base | |
| [file foo/__init__.py] | |
| import foo.base | |
| class Derived(foo.base.Base): | |
| def method(self) -> None: pass | |
| [file foo/base.py] | |
| import foo | |
| class Base: | |
| @decorator | |
| def method(self) -> None: pass | |
| [out] | |
| tmp/foo/base.py:3: error: Name "decorator" is not defined | |
| -- Conditional function definition | |
| -- ------------------------------- | |
| [case testTypeCheckBodyOfConditionalFunction] | |
| from typing import Any | |
| x = None # type: Any | |
| if x: | |
| def f(x: int) -> None: | |
| if int(): | |
| x = 1 | |
| x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| [out] | |
| [case testCallConditionalFunction] | |
| from typing import Any | |
| x = None # type: Any | |
| if x: | |
| def f(x: int) -> None: pass | |
| f(1) | |
| f('x') # E: Argument 1 to "f" has incompatible type "str"; expected "int" | |
| f(1) | |
| f('x') # E: Argument 1 to "f" has incompatible type "str"; expected "int" | |
| [case testConditionalFunctionDefinitionWithIfElse] | |
| from typing import Any | |
| x = None # type: Any | |
| if x: | |
| def f(x: int) -> None: | |
| 'x' + x # fail | |
| if int(): | |
| x = 1 | |
| else: | |
| def f(x: int) -> None: | |
| x + 'x' # fail | |
| if int(): | |
| x = 1 | |
| f(1) | |
| f('x') # fail | |
| [builtins fixtures/primitives.pyi] | |
| [out] | |
| main:5: error: Unsupported operand types for + ("str" and "int") | |
| main:10: error: Unsupported operand types for + ("int" and "str") | |
| main:14: error: Argument 1 to "f" has incompatible type "str"; expected "int" | |
| [case testNestedConditionalFunctionDefinitionWithIfElse] | |
| from typing import Any | |
| x = None # type: Any | |
| def top() -> None: | |
| if x: | |
| def f(x: int) -> None: | |
| if int(): | |
| x = 'x' # E: Incompatible types in assignment \ | |
| (expression has type "str", variable has type "int") | |
| x = 1 | |
| else: | |
| def f(x: int) -> None: | |
| x + 'x' # E: Unsupported operand types for + ("int" and "str") | |
| x = 1 | |
| f(1) | |
| f('x') # E: Argument 1 to "f" has incompatible type "str"; expected "int" | |
| [case testUnconditionalRedefinitionOfConditionalFunction] | |
| from typing import Any | |
| x = None # type: Any | |
| if x: | |
| def f(): pass | |
| def f(): pass # E: Name "f" already defined on line 4 | |
| [case testIncompatibleConditionalFunctionDefinition] | |
| from typing import Any | |
| x = None # type: Any | |
| if x: | |
| def f(x: int) -> None: pass | |
| else: | |
| def f(x): pass # E: All conditional function variants must have identical signatures \ | |
| # 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: Union[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] | |
| def bar() -> None: | |
| if False: | |
| foo = 1 | |
| else: | |
| def foo(obj): ... | |
| def baz() -> None: | |
| if False: | |
| foo: int = 1 | |
| 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 # N: "f" defined here | |
| x = None # type: Any | |
| if x: | |
| def f(y: int) -> None: pass # E: All conditional function variants must have identical signatures \ | |
| # 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] | |
| # flags: --python-version 3.9 | |
| 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 argument "x" in Callable | |
| [builtins fixtures/dict.pyi] | |
| [case testCallableWithKeywordOnlyArg] | |
| from typing import Callable | |
| from mypy_extensions import NamedArg | |
| def a(f: Callable[[NamedArg(int, 'x')], int]): | |
| f(x=4) | |
| f(2) # E: Too many positional arguments | |
| f() # E: Missing named argument "x" | |
| f(y=3) # E: Unexpected keyword argument "y" | |
| f(x="foo") # E: Argument "x" has incompatible type "str"; expected "int" | |
| [builtins fixtures/dict.pyi] | |
| [case testCallableWithKeywordOnlyOptionalArg] | |
| from typing import Callable | |
| from mypy_extensions import DefaultNamedArg | |
| def a(f: Callable[[DefaultNamedArg(int, 'x')], int]): | |
| f(x=4) | |
| f(2) # E: Too many positional arguments | |
| f() | |
| f(y=3) # E: Unexpected keyword argument "y" | |
| f(x="foo") # E: Argument "x" has incompatible type "str"; expected "int" | |
| [builtins fixtures/dict.pyi] | |
| [case testCallableWithKwargs] | |
| from typing import Callable | |
| from mypy_extensions import KwArg | |
| def a(f: Callable[[KwArg(int)], int]): | |
| f(x=4) | |
| f(2) # E: Too many arguments | |
| f() | |
| f(y=3) | |
| f(x=4, y=3, z=10) | |
| f(x="foo") # E: Argument "x" has incompatible type "str"; expected "int" | |
| [builtins fixtures/dict.pyi] | |
| [case testCallableWithVarArg] | |
| from typing import Callable | |
| from mypy_extensions import VarArg | |
| def a(f: Callable[[VarArg(int)], int]): | |
| f(x=4) # E: Unexpected keyword argument "x" | |
| f(2) | |
| f() | |
| f(3, 4, 5) | |
| f("a") # E: Argument 1 has incompatible type "str"; expected "int" | |
| [builtins fixtures/dict.pyi] | |
| [case testCallableArgKindSubtyping] | |
| from typing import Callable | |
| from mypy_extensions import Arg, DefaultArg | |
| int_str_fun: 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 "Callable[[int, Arg(str, 's')], str]") | |
| int_opt_str_fun = iosf | |
| int_str_fun = iosf | |
| int_opt_str_fun = isf # E: Incompatible types in assignment (expression has type "Callable[[Arg(int, 'ii'), Arg(str, 'ss')], str]", variable has type "Callable[[int, DefaultArg(str)], str]") | |
| int_named_str_fun = isf # E: Incompatible types in assignment (expression has type "Callable[[Arg(int, 'ii'), Arg(str, 'ss')], str]", variable has type "Callable[[int, Arg(str, 's')], str]") | |
| int_named_str_fun = iosf | |
| [builtins fixtures/dict.pyi] | |
| -- Callable[..., T] | |
| -- ---------------- | |
| [case testCallableWithArbitraryArgs] | |
| from typing import Callable | |
| def f(x: Callable[..., int]) -> None: | |
| x() | |
| x(1) | |
| x(z=1) | |
| x() + '' # E: Unsupported operand types for + ("int" and "str") | |
| [out] | |
| [case testCallableWithArbitraryArgs2] | |
| from typing import Callable | |
| def f(x: Callable[..., int]) -> None: | |
| x(*[1], **{'x': 2}) | |
| [builtins fixtures/dict.pyi] | |
| [case testCastWithCallableAndArbitraryArgs] | |
| from typing import Callable, cast | |
| f = cast(Callable[..., int], None) | |
| f(x=4) + '' # E: Unsupported operand types for + ("int" and "str") | |
| [case testCallableWithArbitraryArgsInErrorMessage] | |
| from typing import Callable | |
| def f(x: Callable[..., int]) -> None: | |
| if int(): | |
| x = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "Callable[..., int]") | |
| [out] | |
| [case testCallableWithArbitraryArgsInGenericFunction] | |
| from typing import Callable, TypeVar | |
| T = TypeVar('T') | |
| def f(x: Callable[..., T]) -> T: pass | |
| def g(*x: int) -> str: pass | |
| x = f(g) | |
| x + 1 # E: Unsupported left operand type for + ("str") | |
| [builtins fixtures/list.pyi] | |
| [case testCallableWithArbitraryArgsSubtyping] | |
| from typing import Callable | |
| def f(x: Callable[..., int]) -> None: pass | |
| def g1(): pass | |
| def g2(x, y) -> int: pass | |
| def g3(*, y: str) -> int: pass | |
| def g4(*, y: int) -> str: pass | |
| f(g1) | |
| f(g2) | |
| f(g3) | |
| f(g4) # E: Argument 1 to "f" has incompatible type "Callable[[NamedArg(int, 'y')], str]"; expected "Callable[..., int]" | |
| [case testCallableWithArbitraryArgsSubtypingWithGenericFunc] | |
| from typing import Callable, TypeVar | |
| T = TypeVar('T') | |
| def f(x: Callable[..., int]) -> None: pass | |
| def g1(x: T) -> int: pass | |
| def g2(*x: T) -> int: pass | |
| def g3(*x: T) -> T: pass | |
| f(g1) | |
| f(g2) | |
| f(g3) | |
| [builtins fixtures/tuple.pyi] | |
| -- (...) -> T | |
| -- ---------------- | |
| [case testEllipsisWithArbitraryArgsOnBareFunction] | |
| def f(x, y, z): # type: (...) -> None | |
| pass | |
| f(1, "hello", []) | |
| f(x=1, y="hello", z=[]) | |
| [builtins fixtures/dict.pyi] | |
| [case testEllipsisWithArbitraryArgsOnBareFunctionWithDefaults] | |
| def f(x, y=1, z="hey"): # type: (...) -> None | |
| pass | |
| f(1, "hello", []) | |
| f(x=1, y="hello", z=[]) | |
| [builtins fixtures/dict.pyi] | |
| [case testEllipsisWithArbitraryArgsOnBareFunctionWithKwargs] | |
| from typing import Dict | |
| def f(x, **kwargs): # type: (...) -> None | |
| success_dict_type = kwargs # type: Dict[str, str] | |
| failure_dict_type = kwargs # type: Dict[int, str] # E: Incompatible types in assignment (expression has type "Dict[str, Any]", variable has type "Dict[int, str]") | |
| f(1, thing_in_kwargs=["hey"]) | |
| [builtins fixtures/dict.pyi] | |
| [out] | |
| [case testEllipsisWithArbitraryArgsOnBareFunctionWithVarargs] | |
| from typing import Tuple, Any | |
| def f(x, *args): # type: (...) -> None | |
| success_tuple_type = args # type: Tuple[Any, ...] | |
| fail_tuple_type = args # type: None # E: Incompatible types in assignment (expression has type "Tuple[Any, ...]", variable has type "None") | |
| f(1, "hello") | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| [case testEllipsisWithArbitraryArgsOnInstanceMethod] | |
| class A: | |
| def f(self, x, y, z): # type: (...) -> None | |
| pass | |
| [case testEllipsisWithArbitraryArgsOnClassMethod] | |
| class A: | |
| @classmethod | |
| def f(cls, x, y, z): # type: (...) -> None | |
| pass | |
| [builtins fixtures/classmethod.pyi] | |
| [case testEllipsisWithArbitraryArgsOnStaticMethod] | |
| class A: | |
| @staticmethod | |
| def f(x, y, z): # type: (...) -> None | |
| pass | |
| [builtins fixtures/staticmethod.pyi] | |
| [case testEllipsisWithSomethingAfterItFails] | |
| def f(x, y, z): # type: (..., int) -> None | |
| pass | |
| [out] | |
| main:1: error: Ellipses cannot accompany other argument types in function type signature | |
| [case testEllipsisWithSomethingBeforeItFails] | |
| def f(x, y, z): # type: (int, ...) -> None | |
| pass | |
| [out] | |
| main:1: error: Ellipses cannot accompany other argument types in function type signature | |
| [case testRejectCovariantArgument] | |
| from typing import TypeVar, Generic | |
| t = TypeVar('t', covariant=True) | |
| class A(Generic[t]): | |
| def foo(self, x: t) -> None: | |
| return None | |
| [builtins fixtures/bool.pyi] | |
| [out] | |
| main:5: error: Cannot use a covariant type variable as a parameter | |
| [case testRejectCovariantArgumentSplitLine] | |
| from typing import TypeVar, Generic | |
| t = TypeVar('t', covariant=True) | |
| class A(Generic[t]): | |
| def foo(self, | |
| x: t) -> None: | |
| return None | |
| [builtins fixtures/bool.pyi] | |
| [out] | |
| main:6: error: Cannot use a covariant type variable as a parameter | |
| [case testRejectCovariantArgumentInLambda] | |
| from typing import TypeVar, Generic, Callable | |
| t = TypeVar('t', covariant=True) | |
| class Thing(Generic[t]): | |
| def chain(self, func: Callable[[t], None]) -> None: pass | |
| def end(self) -> None: | |
| return self.chain( # Note that lambda args have no line numbers | |
| lambda _: None) | |
| [builtins fixtures/bool.pyi] | |
| [out] | |
| main:8: error: Cannot use a covariant type variable as a parameter | |
| [case testRejectCovariantArgumentInLambdaSplitLine] | |
| from typing import TypeVar, Generic, Callable | |
| [case testRejectContravariantReturnType] | |
| # 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 "Callable[[Arg(Any, 'y')], Any]", variable has type "Callable[[Arg(Any, 'x')], Any]") | |
| f = g # E: Incompatible types in assignment (expression has type "Callable[[Any, Any], Any]", variable has type "Callable[[Any], Any]") | |
| [case testRedefineFunction2] | |
| def f() -> None: pass | |
| def f() -> None: pass # E: Name "f" already defined on line 1 | |
| -- Special cases | |
| -- ------------- | |
| [case testFunctionDefinitionWithForStatement] | |
| for _ in [1]: | |
| def f(): pass | |
| else: | |
| def g(): pass | |
| f() | |
| g() | |
| [builtins fixtures/list.pyi] | |
| [case testFunctionDefinitionWithWhileStatement] | |
| while bool(): | |
| def f(): pass | |
| else: | |
| def g(): pass | |
| f() | |
| g() | |
| [builtins fixtures/bool.pyi] | |
| [case testBareCallable] | |
| from typing import Callable, Any | |
| def foo(f: Callable) -> bool: | |
| return f() | |
| def f1() -> bool: | |
| return False | |
| foo(f1) | |
| [builtins fixtures/bool.pyi] | |
| [case testFunctionNestedWithinWith] | |
| from typing import Any | |
| a = 1 # type: Any | |
| with a: | |
| def f() -> None: | |
| pass | |
| f(1) # E: Too many arguments for "f" | |
| [case testNameForDecoratorMethod] | |
| from typing import Callable | |
| class A: | |
| def f(self) -> None: | |
| # In particular, test that the error message contains "g" of "A". | |
| self.g() # E: Too few arguments for "g" of "A" | |
| self.g(1) | |
| @dec | |
| def g(self, x: str) -> None: pass | |
| def dec(f: Callable[[A, str], None]) -> Callable[[A, int], None]: pass | |
| [out] | |
| [case testUnknownFunctionNotCallable] | |
| 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 "Union[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] | |
| main:1: note: "f" defined here | |
| [case testMagicMethodPositionalOnlyArg] | |
| class A(object): | |
| def __eq__(self, other) -> bool: return True # We are all equal. # N: "__eq__" of "A" defined here | |
| a = A() | |
| a.__eq__(a) | |
| a.__eq__(other=a) # E: Unexpected keyword argument "other" for "__eq__" of "A" | |
| [builtins fixtures/bool.pyi] | |
| [case testMagicMethodPositionalOnlyArgFastparse] | |
| class A(object): | |
| def __eq__(self, other) -> bool: return True # We are all equal. # N: "__eq__" of "A" defined here | |
| a = A() | |
| a.__eq__(a) | |
| a.__eq__(other=a) # E: Unexpected keyword argument "other" for "__eq__" of "A" | |
| [builtins fixtures/bool.pyi] | |
| -- 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[Union[str, int]]") \ | |
| # N: "list" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance \ | |
| # N: Consider using "Sequence" instead, which is covariant \ | |
| # N: Perhaps you need a type annotation for "x"? Suggestion: "List[Union[str, int]]" | |
| def g() -> Dict[str, Union[str, int]]: | |
| x = {'a': 'a'} | |
| return x # E: Incompatible return value type (got "Dict[str, str]", expected "Dict[str, Union[str, int]]") \ | |
| # N: "dict" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance \ | |
| # N: Consider using "Mapping" instead, which is covariant in the value type \ | |
| # N: Perhaps you need a type annotation for "x"? Suggestion: "Dict[str, Union[str, int]]" | |
| def h() -> Dict[Union[str, int], str]: | |
| x = {'a': 'a'} | |
| return x # E: Incompatible return value type (got "Dict[str, str]", expected "Dict[Union[str, int], str]") \ | |
| # N: Perhaps you need a type annotation for "x"? Suggestion: "Dict[Union[str, int], str]" | |
| def i() -> List[Union[int, float]]: | |
| x: List[int] = [1] | |
| return x # E: Incompatible return value type (got "List[int]", expected "List[Union[int, float]]") \ | |
| # N: "list" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance \ | |
| # N: Consider using "Sequence" instead, which is covariant | |
| [builtins fixtures/dict.pyi] | |
| [case testInferredTypeNotSubTypeOfReturnType] | |
| from typing import Union, List | |
| def f() -> List[Union[int, float]]: | |
| x = ['a'] | |
| return x # E: Incompatible return value type (got "List[str]", expected "List[Union[int, float]]") | |
| def g() -> List[Union[str, int]]: | |
| x = ('a', 2) | |
| return x # E: Incompatible return value type (got "Tuple[str, int]", expected "List[Union[str, int]]") | |
| [builtins fixtures/list.pyi] | |
| [case testInferredTypeIsObjectMismatch] | |
| from typing import Union, Dict, List | |
| def f() -> Dict[str, Union[str, int]]: | |
| x = {'a': 'a', 'b': 2} | |
| return x # E: Incompatible return value type (got "Dict[str, object]", expected "Dict[str, Union[str, int]]") | |
| def g() -> Dict[str, Union[str, int]]: | |
| x: Dict[str, Union[str, int]] = {'a': 'a', 'b': 2} | |
| return x | |
| def h() -> List[Union[str, int]]: | |
| x = ['a', 2] | |
| return x # E: Incompatible return value type (got "List[object]", expected "List[Union[str, int]]") | |
| def i() -> List[Union[str, int]]: | |
| x: List[Union[str, int]] = ['a', 2] | |
| return x | |
| [builtins fixtures/dict.pyi] | |
| [case testLambdaSemanal] | |
| f = lambda: xyz | |
| [out] | |
| main:1: error: Name "xyz" is not defined | |
| [case testLambdaTypeCheck] | |
| f = lambda: 1 + '1' | |
| [out] | |
| main:1: error: Unsupported operand types for + ("int" and "str") | |
| [case testLambdaTypeInference] | |
| f = lambda: 5 | |
| reveal_type(f) | |
| [out] | |
| main:2: note: Revealed type is "def () -> builtins.int" | |
| [case testRevealLocalsFunction] | |
| a = 1.0 | |
| class A: pass | |
| def f(a: int, b: int) -> int: | |
| reveal_locals() | |
| c = a + b | |
| class C: pass | |
| reveal_locals() | |
| return c | |
| reveal_locals() | |
| [out] | |
| main:6: note: Revealed local types are: | |
| main:6: note: a: builtins.int | |
| main:6: note: b: builtins.int | |
| main:9: note: Revealed local types are: | |
| main:9: note: a: builtins.int | |
| main:9: note: b: builtins.int | |
| main:9: note: c: builtins.int | |
| main:12: note: Revealed local types are: | |
| main:12: note: a: builtins.float | |
| [case testNoComplainOverloadNone] | |
| # flags: --no-strict-optional | |
| from typing import overload, Optional | |
| @overload | |
| def bar(x: None) -> None: | |
| ... | |
| @overload | |
| def bar(x: int) -> str: | |
| ... | |
| def bar(x: Optional[int]) -> Optional[str]: | |
| if x is None: | |
| return None | |
| return "number" | |
| reveal_type(bar(None)) # N: Revealed type is "None" | |
| [builtins fixtures/isinstance.pyi] | |
| [out] | |
| [case testNoComplainOverloadNoneStrict] | |
| from typing import overload, Optional | |
| @overload | |
| def bar(x: None) -> None: | |
| ... | |
| @overload | |
| def bar(x: int) -> str: | |
| ... | |
| def bar(x: Optional[int]) -> Optional[str]: | |
| if x is None: | |
| return None | |
| return "number" | |
| reveal_type(bar(None)) # N: Revealed type is "None" | |
| [builtins fixtures/isinstance.pyi] | |
| [out] | |
| [case testNoComplainInferredNone] | |
| # flags: --no-strict-optional | |
| from typing import TypeVar, Optional | |
| T = TypeVar('T') | |
| def X(val: T) -> T: ... | |
| x_in = None | |
| def Y(x: Optional[str] = X(x_in)): ... | |
| xx: Optional[int] = X(x_in) | |
| [out] | |
| [case testNoComplainInferredNoneStrict] | |
| from typing import TypeVar, Optional | |
| T = TypeVar('T') | |
| def X(val: T) -> T: ... | |
| x_in = None | |
| def Y(x: Optional[str] = X(x_in)): ... | |
| xx: Optional[int] = X(x_in) | |
| [out] | |
| [case testNoComplainNoneReturnFromUntyped] | |
| def foo() -> None: | |
| pass | |
| def lol(): | |
| x = foo() | |
| [case testConditionalImportFunction] | |
| import p | |
| [file p/__init__.py] | |
| if int(): | |
| from p.a import f | |
| elif int(): | |
| from p.b import f | |
| else: | |
| from p.c import f | |
| [file p/a.py] | |
| def f() -> int: ... | |
| [file p/b.py] | |
| from p.d import f | |
| [file p/c.py] | |
| def f() -> int: ... | |
| [file p/d.py] | |
| import p | |
| def f() -> int: ... | |
| [case testLambdaDefaultTypeErrors] | |
| lambda a=(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 decorator is @f.setter | |
| @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] | |
| [out] | |
| [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] | |
| [out] | |
| [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) -> Union[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 "Union[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 () -> Union[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 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 "Callable[[Arg(int, 'b')], B]"; expected "Callable[[Arg(int, 'x')], 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 "Callable[[Arg(int, 'y')], Coroutine[Any, Any, None]]"; expected "Callable[[Arg(int, 'x')], 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 "Callable[[Arg(str, 'param')], 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[[Union[int, str]], None]"; expected "Callable[[Arg(int, 'x')], 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 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] |