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