-- 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(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

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(int, 'a'), Arg(str, 'b')], None]")
ff = f # reset
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]")
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

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[[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

ff = g
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

ff = g
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)
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  # OK

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 "Type[A]", 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 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]

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 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)

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 "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]
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)
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 "Optional[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 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 variant: \
       # N:     def f(self, b: B) -> None \
       # N:     <1 more non-matching overload not shown>

[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:
         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 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:
    # TODO: This should be okay.
    @dec # E: Name 'f' already defined on line 7
    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: We should report an incompatible redefinition.
    @dec # E: Name 'f' already defined on line 7
    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 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 'f'
if object():
    def f(): pass # E: Incompatible redefinition
f()
f(1)
[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-full.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 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

[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 alias # E: Value of type "int" is not indexable
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   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  # 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  # 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  # 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 # E: invalid type comment or annotation
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 comment or annotation
[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:
    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)

-- (...) -> 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) # 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
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)  # E: Revealed type is 'def [T] (T`-1) -> T`-1'
def g(__x: T) -> T: pass
f = g
reveal_type(f)  # E: Revealed type is 'def [T] (T`-1) -> T`-1'
i = f(3)
reveal_type(i)  # E: Revealed type is 'builtins.int*'

[case testFunctionReturningGenericFunction]
from typing import Callable, TypeVar

T = TypeVar('T')
def deco() -> Callable[[T], T]: pass
reveal_type(deco)  # E: Revealed type is 'def () -> def [T] (T`-1) -> T`-1'
f = deco()
reveal_type(f)  # E: Revealed type is 'def [T] (T`-1) -> T`-1'
i = f(3)
reveal_type(i)  # E: 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)  # E: Revealed type is 'def [U] (x: U`-1) -> def [T] (T`-2, U`-1) -> T`-2'
f = deco("foo")
reveal_type(f)  # E: Revealed type is 'def [T] (T`-2, builtins.str*) -> T`-2'
i = f(3, "eggs")
reveal_type(i)  # E: 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)  # E: Revealed type is 'def [T] (T`-1) -> def [R] (T`-1, R`-2) -> R`-2'
g = f(3)
reveal_type(g)  # E: Revealed type is 'def [R] (builtins.int*, R`-2) -> R`-2'
s = g(4, "foo")
reveal_type(s)  # E: 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)  # E: Revealed type is 'def (x: builtins.int) -> builtins.str'
s = lol(4)
reveal_type(s)  # E: 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'
[builtins fixtures/list.pyi]

[case testAnonymousArgumentError]
def foo(__b: int, x: int, y: int) -> int: pass
foo(x=2, y=2)  # E: Missing positional argument
foo(y=2)  # E: Missing positional arguments

[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: 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: 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: Perhaps you need a type annotation for "x"? Suggestion: "List[Union[int, float]]"

[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: error: Revealed type is 'def () -> builtins.int'

[case testRevealLocalsFunction]
a = 1.0

def f(a: int, b: int) -> int:
    reveal_locals()
    c = a + b
    reveal_locals()
    return c

reveal_locals()
[out]
main:4: error: Revealed local types are:
main:4: error: a: builtins.int
main:4: error: b: builtins.int
main:6: error: Revealed local types are:
main:6: error: a: builtins.int
main:6: error: b: builtins.int
main:6: error: c: builtins.int
main:9: error: Revealed local types are:
main:9: error: a: builtins.float
