[case testEmptyFile]
[out]

[case testAssignmentAndVarDef]

a = None # type: A
b = None # type: B
a = a
a = b # Fail
class A: pass
class B: pass
[out]
main:5: error: Incompatible types in assignment (expression has type "B", variable has type "A")

[case testConstructionAndAssignment]

x = None # type: A
x = A()
x = B()
class A:
    def __init__(self): pass
class B:
    def __init__(self): pass
[out]
main:4: error: Incompatible types in assignment (expression has type "B", variable has type "A")

[case testInheritInitFromObject]

x = None # type: A
x = A()
x = B()
class A(object): pass
class B(object): pass
[out]
main:4: error: Incompatible types in assignment (expression has type "B", variable has type "A")

[case testImplicitInheritInitFromObject]

x = None # type: A
o = None # type: object
x = o # E: Incompatible types in assignment (expression has type "object", variable has type "A")
x = A()
o = x
class A: pass
class B: pass
[out]

[case testTooManyConstructorArgs]
import typing
object(object())
[out]
main:2: error: Too many arguments for "object"

[case testVarDefWithInit]
import typing
a = A() # type: A
b = object() # type: A
class A: pass
[out]
main:3: error: Incompatible types in assignment (expression has type "object", variable has type "A")

[case testInheritanceBasedSubtyping]
import typing
x = B() # type: A
y = A() # type: B # Fail
class A: pass
class B(A): pass
[out]
main:3: error: Incompatible types in assignment (expression has type "A", variable has type "B")

[case testDeclaredVariableInParentheses]

(x) = None # type: int
x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int")
x = 1


-- Simple functions and calling
-- ----------------------------


[case testFunction]
import typing
def f(x: 'A') -> None: pass
f(A())
f(B()) # Fail
class A: pass
class B: pass
[out]
main:4: error: Argument 1 to "f" has incompatible type "B"; expected "A"

[case testNotCallable]
import typing
A()()
class A: pass
[out]
main:2: error: "A" not callable

[case testSubtypeArgument]
import typing
def f(x: 'A', y: 'B') -> None: pass
f(B(), A()) # Fail
f(B(), B())

class A: pass
class B(A): pass
[out]
main:3: error: Argument 2 to "f" has incompatible type "A"; expected "B"

[case testInvalidArgumentCount]
import typing
def f(x, y) -> None: pass
f(object())
f(object(), object(), object())
[out]
main:3: error: Too few arguments for "f"
main:4: error: Too many arguments for "f"


-- Locals
-- ------


[case testLocalVariables]

def f() -> None:
  x = None # type: A
  y = None # type: B
  x = x
  x = y # Fail
class A: pass
class B: pass
[out]
main:6: error: Incompatible types in assignment (expression has type "B", variable has type "A")

[case testLocalVariableScope]

def f() -> None:
  x = None # type: A
  x = A()
def g() -> None:
  x = None # type: B
  x = A() # Fail
class A: pass
class B: pass
[out]
main:7: error: Incompatible types in assignment (expression has type "A", variable has type "B")

[case testFunctionArguments]
import typing
def f(x: 'A', y: 'B') -> None:
  x = y # Fail
  x = x
  y = B()
class A: pass
class B: pass
[out]
main:3: error: Incompatible types in assignment (expression has type "B", variable has type "A")

[case testLocalVariableInitialization]
import typing
def f() -> None:
  a = A() # type: A
  b = B() # type: A # Fail
class A: pass
class B: pass
[out]
main:4: error: Incompatible types in assignment (expression has type "B", variable has type "A")

[case testVariableInitializationWithSubtype]
import typing
x = B() # type: A
y = A() # type: B # Fail
class A: pass
class B(A): pass
[out]
main:3: error: Incompatible types in assignment (expression has type "A", variable has type "B")


-- Misc
-- ----


[case testInvalidReturn]
import typing
def f() -> 'A':
  return B()
class A: pass
class B: pass
[out]
main:3: error: Incompatible return value type (got "B", expected "A")

[case testTopLevelContextAndInvalidReturn]
import typing
def f() -> 'A':
  return B()
a = B() # type: A
class A: pass
class B: pass
[out]
main:3: error: Incompatible return value type (got "B", expected "A")
main:4: error: Incompatible types in assignment (expression has type "B", variable has type "A")

[case testEmptyReturnInAnyTypedFunction]
from typing import Any
def f() -> Any:
  return

[case testEmptyYieldInAnyTypedFunction]
from typing import Any
def f() -> Any:
  yield

[case testModule__name__]
import typing
x = __name__ # type: str
a = __name__ # type: A  # E: Incompatible types in assignment (expression has type "str", variable has type "A")
class A: pass
[builtins fixtures/primitives.pyi]

[case testModule__doc__]
import typing
x = __doc__ # type: str
a = __doc__ # type: A  # E: Incompatible types in assignment (expression has type "str", variable has type "A")
class A: pass
[builtins fixtures/primitives.pyi]

[case testModule__file__]
import typing
x = __file__ # type: str
a = __file__ # type: A  # E: Incompatible types in assignment (expression has type "str", variable has type "A")
class A: pass
[builtins fixtures/primitives.pyi]

[case test__package__]
import typing
x = __package__ # type: str
a = __file__ # type: int  # E: Incompatible types in assignment (expression has type "str", variable has type "int")


-- Scoping and shadowing
-- ---------------------


[case testLocalVariableShadowing]

a = None # type: A
a = B()       # Fail
a = A()
def f() -> None:
  a = None # type: B
  a = A()     # Fail
  a = B()
a = B()       # Fail
a = A()

class A: pass
class B: pass
[out]
main:3: error: Incompatible types in assignment (expression has type "B", variable has type "A")
main:7: error: Incompatible types in assignment (expression has type "A", variable has type "B")
main:9: error: Incompatible types in assignment (expression has type "B", variable has type "A")

[case testGlobalDefinedInBlockWithType]

class A: pass
while A:
    a = None # type: A
    a = A()
    a = object() # E: Incompatible types in assignment (expression has type "object", variable has type "A")


-- # type: signatures
-- ------------------


[case testFunctionSignatureAsComment]
def f(x): # type: (int) -> str
    return 1
f('')
[out]
main:2: error: Incompatible return value type (got "int", expected "str")
main:3: error: Argument 1 to "f" has incompatible type "str"; expected "int"

[case testMethodSignatureAsComment]
class A:
    def f(self, x):
        # type: (int) -> str
        self.f('') # Fail
        return 1
A().f('') # Fail
[out]
main:4: error: Argument 1 to "f" of "A" has incompatible type "str"; expected "int"
main:5: error: Incompatible return value type (got "int", expected "str")
main:6: error: Argument 1 to "f" of "A" has incompatible type "str"; expected "int"

[case testTrailingCommaParsing-skip]
x = 1
x in 1,
if x in 1, :
    pass
[out]

[case testInitReturnTypeError]
class C:
    def __init__(self):
        # type: () -> int
        pass
[out]
main:2: error: The return type of "__init__" must be None

-- WritesCache signals to testcheck to do the cache validation
[case testWritesCache]
import a
import d
[file a.py]
import b
import c
[file b.py]
[file c.py]
[file d.py]

[case testWritesCacheErrors]
import a
import d
[file a.py]
import b
import c
[file b.py]
[file c.py]
[file d.py]
import e
[file e.py]
1+'no'  # E: Unsupported operand types for + ("int" and "str")

[case testModuleAsTypeNoCrash]
import mock
from typing import Union

class A: ...
class B: ...

x: Union[mock, A]  # E: Invalid type "mock"

if isinstance(x, B):
    pass
[file mock.py]
[builtins fixtures/isinstance.pyi]
[out]

[case testModuleAsTypeNoCrash2]
import mock
from typing import overload, Any, Union

@overload
def f(x: int) -> int: ...
@overload
def f(x: str) -> Union[mock, str]: ...  # E: Invalid type "mock"
def f(x):
    pass

x: Any
f(x)
[file mock.py]
[builtins fixtures/isinstance.pyi]
[out]
