blob: 31a61688eeeeb316c453a1219893a9a97d27df4d [file]
-- 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)
a = f(a) # E: Incompatible types in assignment (expression has type "B", variable has type "A")
b = f(b) # E: Argument 1 has incompatible type "B"; expected "A"
b = f() # E: Too few arguments
b = f(a, a) # E: Too many arguments
b = f(a)
class A: pass
class B: pass
[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 # E: Signature of "f" incompatible with supertype "A"
[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" incompatible with supertype "A" # E: Argument 2 of "f" incompatible with supertype "A"
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 # E: Signature of "f" incompatible with supertype "A"
[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
g = h # E: Incompatible types in assignment (expression has type Callable[[B], B], variable has type Callable[[A], A])
h = f # E: Incompatible types in assignment (expression has type Callable[[B], A], variable has type Callable[[B], B])
h = g # E: Incompatible types in assignment (expression has type Callable[[A], A], variable has type Callable[[B], B])
g = f # E: Incompatible types in assignment (expression has type Callable[[B], A], variable has type Callable[[A], A])
f = g
f = h
f = f
g = g
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('x', Any)], 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]
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
ff = gg
ff_nonames = ff
ff_nonames = f_nonames # reset
ff = ff_nonames # E: Incompatible types in assignment (expression has type Callable[[int, str], None], variable has type Callable[[Arg('a', int), Arg('b', str)], None])
ff = f # reset
gg = ff # E: Incompatible types in assignment (expression has type Callable[[Arg('a', int), Arg('b', str)], None], variable has type Callable[[Arg('a', int), DefaultArg('b', str)], None])
gg = hh # E: Incompatible types in assignment (expression has type Callable[[Arg('aa', int), DefaultArg('b', str)], None], variable has type Callable[[Arg('a', int), DefaultArg('b', str)], 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
ss_1 = ee_def
ss_1 = specific_1
ss_2 = ee_def
ss_2 = specific_2
ee_def = everywhere
ee_def = everything
ee_var = everything
ee_var = everywhere
ee_var = specific_1 # The difference between Callable[..., blah] and one with a *args: Any, **kwargs: Any is that the ... goes loosely both ways.
ee_def = specific_1 # E: Incompatible types in assignment (expression has type Callable[[int, str], None], variable has type Callable[[StarArg(Any), KwArg(Any)], None])
[builtins fixtures/dict.pyi]
[case testLackOfNames]
def f(__a: int, __b: str) -> None: pass
def g(a: int, b: str) -> None: pass
ff = f
gg = g
ff = g
gg = f # E: Incompatible types in assignment (expression has type Callable[[int, str], None], variable has type Callable[[Arg('a', int), Arg('b', str)], None])
[case testLackOfNamesFastparse]
# flags: --fast-parser
def f(__a: int, __b: str) -> None: pass
def g(a: int, b: str) -> None: pass
ff = f
gg = g
ff = g
gg = f # E: Incompatible types in assignment (expression has type Callable[[int, str], None], variable has type Callable[[Arg('a', int), Arg('b', str)], None])
[case testFunctionTypeCompatibilityWithOtherTypes]
from typing import Callable
f = None # type: Callable[[], None]
a, o = None, None # type: (A, object)
a = f # E: Incompatible types in assignment (expression has type Callable[[], None], variable has type "A")
f = a # E: Incompatible types in assignment (expression has type "A", variable has type Callable[[], None])
f = o # E: Incompatible types in assignment (expression has type "object", variable has type Callable[[], None])
f = f() # E: Function does not return a value
f = f
f = None
o = f
class A: pass
[case testFunctionSubtypingWithVoid]
from typing import Callable
f = None # type: Callable[[], None]
g = None # type: Callable[[], object]
f = g # E: Incompatible types in assignment (expression has type Callable[[], object], variable has type Callable[[], None])
g = f # E: Incompatible types in assignment (expression has type Callable[[], None], variable has type Callable[[], object])
f = f
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]
f = g # E: Incompatible types in assignment (expression has type Callable[[A, B], None], variable has type Callable[[A, A], None])
f = h # E: Incompatible types in assignment (expression has type Callable[[B, B], None], variable has type Callable[[A, A], None])
g = h # E: Incompatible types in assignment (expression has type Callable[[B, B], None], variable has type Callable[[A, B], None])
g = f
h = f
h = g
f = f
g = g
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]
f = g # E: Incompatible types in assignment (expression has type Callable[[A], None], variable has type Callable[[], None])
f = h # E: Incompatible types in assignment (expression has type Callable[[A, A], None], variable has type Callable[[], None])
h = f # E: Incompatible types in assignment (expression has type Callable[[], None], variable has type Callable[[A, A], None])
h = g # E: Incompatible types in assignment (expression has type Callable[[A], None], variable has type Callable[[A, A], None])
f = f
g = g
h = h
class A: pass
[out]
[case testCompatibilityOfSimpleTypeObjectWithStdType]
t = None # type: type
a = None # type: A
a = A # E: Incompatible types in assignment (expression has type "A" (type object), variable has type "A")
t = f # E: Incompatible types in assignment (expression has type Callable[[], None], variable has type "type")
t = A
class A:
def __init__(self, a: 'A') -> None: pass
def f() -> None: pass
[case testFunctionTypesWithOverloads]
from typing import Callable, overload
f = None # type: Callable[[AA], A]
g = None # type: Callable[[B], B]
h = None # type: Callable[[A], AA]
h = i # E: Incompatible types in assignment (expression has type overloaded function, variable has type Callable[[A], AA])
f = j
f = i
g = i
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 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)
b = f(a) # E: Incompatible types in assignment (expression has type "A", variable has type "B")
a = f(b) # E: Incompatible types in assignment (expression has type "B", variable has type "A")
b = f(c) # E: Incompatible types in assignment (expression has type "C", variable has type "B")
g4 = f # E: Incompatible types in assignment (expression has type overloaded function, variable has type Callable[[A], B])
g1 = f
g2 = f
g3 = f
a = f(a)
b = f(b)
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
[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
class D:
def __init__(self, a, b): pass
f([D]) # E: List item 0 has incompatible type
[builtins fixtures/list.pyi]
-- Default argument values
-- -----------------------
[case testCallingFunctionsWithDefaultArgumentValues]
a, b = None, None # type: (A, B)
a = f() # E: Incompatible types in assignment (expression has type "B", variable has type "A")
b = f(b) # E: Argument 1 to "f" has incompatible type "B"; expected "A"
b = f(a, a) # E: Too many arguments for "f"
b = f()
b = f(a)
b = f(AA())
def f(x: 'A' = None) -> 'B': pass
class A: pass
class AA(A): pass
class B: pass
[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 types in assignment (expression has type "B", variable 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
[out]
[case testDefaultArgumentsWithSubtypes]
import typing
def f(x: 'B' = A()) -> None: # E: Incompatible types in assignment (expression has type "A", variable 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 types in assignment (expression has type "B", variable 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 types in assignment (expression has type "A", variable 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: Invalid method type
a.g() # E: Invalid method type
[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 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 types [__main__.A]
[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 method type
[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:
b = a # fail
aa = a # type: A # ok
b = B()
g(a) # fail
g(B())
class A: pass
class B: pass
[out]
main:4: error: Incompatible types in assignment (expression has type "A", variable has type "B")
main:7: error: Argument 1 to "g" has incompatible type "A"; expected "B"
[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: Too few arguments for "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 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
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'
[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'
[case testCallingNoTypeCheckFunction]
import typing
@typing.no_type_check
def foo(x: {1:2}) -> [1]:
1 + 'x'
foo()
foo(1, 'b')
[case testCallingNoTypeCheckFunction2]
import typing
def f() -> None:
foo()
@typing.no_type_check
def foo(x: {1:2}) -> [1]:
1 + 'x'
[case testNoTypeCheckDecoratorSemanticError]
import typing
@typing.no_type_check
def foo(x: {1:2}) -> [1]:
x = y
-- 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: Too few arguments for "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: Too few arguments for "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:
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
x = 1
else:
def f(x: int) -> None:
x + 'x' # fail
x = 1
f(1)
f('x') # fail
[out]
main:5: error: Incompatible types in assignment (expression has type "str", variable has type "int")
main:9: error: Unsupported operand types for + ("int" and "str")
main:12: 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:
x = 'x' # fail
x = 1
else:
def f(x: int) -> None:
x + 'x' # fail
x = 1
f(1)
f('x') # fail
[out]
main:6: error: Incompatible types in assignment (expression has type "str", variable has type "int")
main:10: error: Unsupported operand types for + ("int" and "str")
main:13: error: 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
[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 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 testConditionalRedefinitionOfAnUnconditionalFunctionDefinition1]
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: Too few arguments for "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 variable
if object():
def f(): pass # E: Incompatible redefinition
f()
f(1)
[builtins fixtures/list.pyi]
-- Conditional method definition
-- -----------------------------
[case testTypeCheckBodyOfConditionalMethod]
from typing import Any
x = None # type: Any
class A:
if x:
def f(self, x: int) -> None:
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
x = 1
else:
def f(self, x: int) -> None:
x + 'x' # fail
x = 1
A().f(1)
A().f('x') # fail
[out]
main:6: error: Incompatible types in assignment (expression has type "str", variable has type "int")
main:10: error: Unsupported operand types for + ("int" and "str")
main:13: 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
[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"
-- 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:
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('y', int)], str]; expected Callable[..., int]
[case testCallableWithArbitraryArgsSubtypingWithGenericFunc]
from typing import Callable, TypeVar
T = TypeVar('T')
def f(x: Callable[..., int]) -> None: pass
def g1(x: T) -> int: pass
def g2(*x: T) -> int: pass
def g3(*x: T) -> T: pass
f(g1)
f(g2)
f(g3)
-- (...) -> 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: Parse error before ): 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: Parse error before ): 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 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]
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('y', Any)], Any], variable has type Callable[[Arg('x', Any)], Any])
f = g # E: Incompatible types in assignment (expression has type Callable[[Any, Any], Any], variable has type Callable[[Any], Any])
[case testRedefineFunction2]
def f() -> None: pass
def f() -> None: pass # E: Name 'f' already defined
-- 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) # E: Revealed type is 'builtins.function'
h(7) # E: Cannot call function of unknown type
[builtins fixtures/bool.pyi]
-- Positional-only arguments
-- -------------------------
[case testPositionalOnlyArg]
def f(__a: int) -> None: pass
f(1)
f(__a=1) # E: Unexpected keyword argument "__a" for "f"
[builtins fixtures/bool.pyi]
[out]
main:1: note: "f" defined here
[case testPositionalOnlyArgFastparse]
# flags: --fast-parser
def f(__a: int) -> None: pass
f(1)
f(__a=1) # E: Unexpected keyword argument "__a" for "f"
[builtins fixtures/bool.pyi]
[out]
main:3: note: "f" defined here
[case testMagicMethodPositionalOnlyArg]
class A(object):
def __eq__(self, other) -> bool: return True # We are all equal.
a = A()
a.__eq__(a)
a.__eq__(other=a) # E: Unexpected keyword argument "other" for "__eq__" of "A"
[builtins fixtures/bool.pyi]
[case testMagicMethodPositionalOnlyArgFastparse]
# flags: --fast-parser
class A(object):
def __eq__(self, other) -> bool: return True # We are all equal.
a = A()
a.__eq__(a)
a.__eq__(other=a) # E: Unexpected keyword argument "other" for "__eq__" of "A"
[builtins fixtures/bool.pyi]
[case testTupleArguments]
# flags: --python-version 2.7
def f(a, (b, c), d): pass
[case testTupleArgumentsFastparse]
# flags: --fast-parser --python-version 2.7
def f(a, (b, c), d): pass