-- Methods
-- -------


[case testMethodCall]

a = None # type: A
b = None # type: B

a.foo(B())        # Fail
a.bar(B(), A())   # Fail

a.foo(A())
b.bar(B(), A())

class A:
    def foo(self, x: 'A') -> None: pass
class B:
    def bar(self, x: 'B', y: A) -> None: pass
[out]
main:5: error: Argument 1 to "foo" of "A" has incompatible type "B"; expected "A"
main:6: error: "A" has no attribute "bar"

[case testMethodCallWithSubtype]

a = None # type: A
a.foo(A())
a.foo(B())
a.bar(A()) # Fail
a.bar(B())

class A:
    def foo(self, x: 'A') -> None: pass
    def bar(self, x: 'B') -> None: pass
class B(A): pass
[out]
main:5: error: Argument 1 to "bar" of "A" has incompatible type "A"; expected "B"

[case testInheritingMethod]

a = None # type: B
a.foo(A()) # Fail
a.foo(B())

class A:
    def foo(self, x: 'B') -> None: pass
class B(A): pass
[out]
main:3: error: Argument 1 to "foo" of "A" has incompatible type "A"; expected "B"

[case testMethodCallWithInvalidNumberOfArguments]

a = None # type: A
a.foo()               # Fail
a.foo(object(), A())  # Fail

class A:
    def foo(self, x: 'A') -> None: pass
[out]
main:3: error: Too few arguments for "foo" of "A"
main:4: error: Too many arguments for "foo" of "A"
main:4: error: Argument 1 to "foo" of "A" has incompatible type "object"; expected "A"

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

[case testMethodArguments]
import typing
class A:
    def f(self, a: 'A', b: 'B') -> None:
        a = B() # Fail
        b = A() # Fail
        a = A()
        b = B()
        a = a
        a = b # Fail
class B: pass
[out]
main:4: error: Incompatible types in assignment (expression has type "B", variable has type "A")
main:5: 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 testReturnFromMethod]
import typing
class A:
    def f(self) -> 'A':
        return B() # Fail
        return A()
class B: pass
[out]
main:4: error: Incompatible return value type (got "B", expected "A")

[case testSelfArgument]
import typing
class A:
    def f(self) -> None:
        o = self # type: B    # Fail
        self.g()      # Fail
        a = self # type: A
        self.f()
class B: pass
[out]
main:4: error: Incompatible types in assignment (expression has type "A", variable has type "B")
main:5: error: "A" has no attribute "g"

[case testAssignToMethodViaInstance]
import typing
class A:
    def f(self): pass
A().f = None # E: Cannot assign to a method


-- Attributes
-- ----------


[case testReferToInvalidAttribute]

class A:
    def __init__(self) -> None:
        self.x = object()
a: A
a.y  # E: "A" has no attribute "y"
a.y = object()  # E: "A" has no attribute "y"
a.x
a.x = object()

[case testReferToInvalidAttributeUnannotatedInit]
class A:
    def __init__(self):
        self.x = object()

a: A
a.y  # E: "A" has no attribute "y"
a.y = object()  # E: "A" has no attribute "y"
a.x
a.x = object()

[case testArgumentTypeInference]

class A:
    def __init__(self, aa: 'A', bb: 'B') -> None:
        self.a = aa
        self.b = bb
class B: pass
a = None # type: A
b = None # type: B
a.a = b # Fail
a.b = a # Fail
b.a     # Fail
a.a = a
a.b = b
[out]
main:9: error: Incompatible types in assignment (expression has type "B", variable has type "A")
main:10: error: Incompatible types in assignment (expression has type "A", variable has type "B")
main:11: error: "B" has no attribute "a"

[case testExplicitAttributeInBody]

a = None # type: A
a.x = object() # Fail
a.x = A()
class A:
  x = None # type: A
[out]
main:3: error: Incompatible types in assignment (expression has type "object", variable has type "A")

[case testAttributeDefinedInNonInitMethod]
import typing
class A:
    def f(self) -> None:
        self.x = 1
        self.y = ''
        self.x = 1
a = A()
a.x = 1
a.y = ''
a.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int")
a.z = 0  # E: "A" has no attribute "z"

[case testInheritanceAndAttributeAssignment]
import typing
class A:
    def f(self) -> None:
        self.x = 0
class B(A):
    def f(self) -> None:
        self.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int")
[out]

[case testAssignmentToAttributeInMultipleMethods]
import typing
class A:
    def f(self) -> None:
        self.x = 0
    def g(self) -> None:
        self.x = '' # Fail
    def __init__(self) -> None:
        self.x = '' # Fail
[out]
main:6: error: Incompatible types in assignment (expression has type "str", variable has type "int")
main:8: error: Incompatible types in assignment (expression has type "str", variable has type "int")

[case testClassNamesDefinedOnSelUsedInClassBody]
class A(object):
    def f(self):
        self.attr = 1
    attr = 0

class B(object):
    attr = 0
    def f(self):
        self.attr = 1

class C(object):
    attr = 0
    def f(self):
        self.attr = 1
    attr = 0

class D(object):
    def g(self):
        self.attr = 1
    attr = 0
    def f(self):
        self.attr = 1
[out]

[case testClassNamesDefinedOnSelUsedInClassBodyReveal]
class A(object):
    def f(self) -> None:
        self.attr = 1
    reveal_type(attr)  # E: Revealed type is 'builtins.int'

class B(object):
    attr = 0
    def f(self) -> None:
        reveal_type(self.attr)  # E: Revealed type is 'builtins.int'
[out]


-- Method overriding
-- -----------------


[case testMethodOverridingWithIdenticalSignature]
import typing
class A:
    def f(self, x: 'A') -> None: pass
    def g(self, x: 'B' , y: object) -> 'A': pass
    def h(self) -> None: pass
class B(A):
    def f(self, x: A) -> None: pass
    def g(self, x: 'B' , y: object) -> A: pass
    def h(self) -> None: pass
[out]

[case testMethodOverridingWithCovariantType]
import typing
class A:
  def f(self, x: 'A', y: 'B') -> 'A': pass
  def g(self, x: 'A', y: 'B') -> 'A': pass
class B(A):
  def f(self, x: A, y: 'B') -> 'B': pass
  def g(self, x: A, y: A) -> 'A': pass
[out]

[case testMethodOverridingWithIncompatibleTypes]
import typing
class A:
  def f(self, x: 'A', y: 'B') -> 'A': pass
  def g(self, x: 'A', y: 'B') -> 'A': pass
  def h(self, x: 'A', y: 'B') -> 'A': pass
class B(A):
  def f(self, x: 'B', y: 'B') -> A: pass  # Fail
  def g(self, x: A, y: A) -> A: pass
  def h(self, x: A, y: 'B') -> object: pass  # Fail
[out]
main:7: error: Argument 1 of "f" incompatible with supertype "A"
main:9: error: Return type of "h" incompatible with supertype "A"

[case testMethodOverridingWithIncompatibleArgumentCount]
import typing
class A:
    def f(self, x: 'A') -> None: pass
    def g(self, x: 'A', y: 'B') -> 'A': pass
class B(A):
    def f(self, x: A, y: A) -> None: pass # Fail
    def g(self, x: A) -> A: pass # Fail
[out]
main:6: error: Signature of "f" incompatible with supertype "A"
main:7: error: Signature of "g" incompatible with supertype "A"

[case testMethodOverridingAcrossDeepInheritanceHierarchy1]
import typing
class A:
    def f(self, x: 'B') -> None: pass
class B(A): pass
class C(B): # with gap in implementations
    def f(self, x: 'C') -> None:  # Fail
        pass
[out]
main:6: error: Argument 1 of "f" incompatible with supertype "A"

[case testMethodOverridingAcrossDeepInheritanceHierarchy2]
import typing
class A:
    def f(self) -> 'B': pass
class B(A):
    def f(self) -> 'C': pass
class C(B): # with multiple implementations
    def f(self) -> B:  # Fail
        pass
[out]
main:7: error: Return type of "f" incompatible with supertype "B"

[case testMethodOverridingWithVoidReturnValue]
import typing
class A:
    def f(self) -> None: pass
    def g(self) -> 'A': pass
class B(A):
    def f(self) -> A: pass  # Fail
    def g(self) -> None: pass
[out]
main:6: error: Return type of "f" incompatible with supertype "A"

[case testOverride__new__WithDifferentSignature]
class A:
    def __new__(cls, x: int) -> str:
        return ''

class B(A):
    def __new__(cls) -> int:
        return 1

[case testInnerFunctionNotOverriding]
class A:
    def f(self) -> int: pass

class B(A):
    def g(self) -> None:
        def f(self) -> str: pass

[case testOverride__init_subclass__WithDifferentSignature]
class A:
    def __init_subclass__(cls, x: int) -> None: pass
class B(A):
    def __init_subclass__(cls) -> None: pass

[case testOverrideWithDecorator]
from typing import Callable

def int_to_none(f: Callable[..., int]) -> Callable[..., None]: ...
def str_to_int(f: Callable[..., str]) -> Callable[..., int]: ...

class A:
    def f(self) -> None: pass
    def g(self) -> str: pass
    def h(self) -> None: pass

class B(A):
    @int_to_none
    def f(self) -> int: pass
    @str_to_int
    def g(self) -> str: pass # E: Signature of "g" incompatible with supertype "A"
    @int_to_none
    @str_to_int
    def h(self) -> str: pass

[case testOverrideDecorated]
from typing import Callable

def str_to_int(f: Callable[..., str]) -> Callable[..., int]: ...

class A:
    @str_to_int
    def f(self) -> str: pass
    @str_to_int
    def g(self) -> str: pass
    @str_to_int
    def h(self) -> str: pass

class B(A):
    def f(self) -> int: pass
    def g(self) -> str: pass # E: Signature of "g" incompatible with supertype "A"
    @str_to_int
    def h(self) -> str: pass

[case testOverrideWithDecoratorReturningAny]
def dec(f): pass

class A:
    def f(self) -> str: pass

class B(A):
    @dec
    def f(self) -> int: pass

[case testOverrideWithDecoratorReturningInstance]
def dec(f) -> str: pass

class A:
    def f(self) -> str: pass
    @dec
    def g(self) -> int: pass
    @dec
    def h(self) -> int: pass

class B(A):
    @dec
    def f(self) -> int: pass # E: Signature of "f" incompatible with supertype "A"
    def g(self) -> int: pass # E: Signature of "g" incompatible with supertype "A"
    @dec
    def h(self) -> str: pass

[case testOverrideStaticMethodWithStaticMethod]
class A:
    @staticmethod
    def f(x: int, y: str) -> None: pass
    @staticmethod
    def g(x: int, y: str) -> None: pass

class B(A):
    @staticmethod
    def f(x: int, y: str) -> None: pass
    @staticmethod
    def g(x: str, y: str) -> None: pass # E: Argument 1 of "g" incompatible with supertype "A"
[builtins fixtures/classmethod.pyi]

[case testOverrideClassMethodWithClassMethod]
class A:
    @classmethod
    def f(cls, x: int, y: str) -> None: pass
    @classmethod
    def g(cls, x: int, y: str) -> None: pass

class B(A):
    @classmethod
    def f(cls, x: int, y: str) -> None: pass
    @classmethod
    def g(cls, x: str, y: str) -> None: pass # E: Argument 1 of "g" incompatible with supertype "A"
[builtins fixtures/classmethod.pyi]

[case testOverrideClassMethodWithStaticMethod]
class A:
    @classmethod
    def f(cls, x: int) -> None: pass
    @classmethod
    def g(cls, x: int) -> int: pass
    @classmethod
    def h(cls) -> int: pass

class B(A):
    @staticmethod
    def f(x: int) -> None: pass
    @staticmethod
    def g(x: str) -> int: pass # E: Argument 1 of "g" incompatible with supertype "A"
    @staticmethod
    def h() -> int: pass
[builtins fixtures/classmethod.pyi]

[case testOverrideStaticMethodWithClassMethod]
class A:
    @staticmethod
    def f(x: int) -> None: pass
    @staticmethod
    def g(x: str) -> int: pass
    @staticmethod
    def h() -> int: pass

class B(A):
    @classmethod
    def f(cls, x: int) -> None: pass
    @classmethod
    def g(cls, x: int) -> int: pass # E: Argument 1 of "g" incompatible with supertype "A"
    @classmethod
    def h(cls) -> int: pass
[builtins fixtures/classmethod.pyi]


-- Constructors
-- ------------


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

[case testConstructor]
import typing
a = A(B()) # type: A
aa = A(object()) # type: A  # Fail
b = A(B()) # type: B       # Fail
class A:
    def __init__(self, x: 'B') -> None: pass
class B: pass
[out]
main:3: error: Argument 1 to "A" has incompatible type "object"; expected "B"
main:4: error: Incompatible types in assignment (expression has type "A", variable has type "B")

[case testConstructorWithTwoArguments]
import typing
a = A(C(), B()) # type: A  # Fail

class A:
    def __init__(self, x: 'B', y: 'C') -> None: pass
class B: pass
class C(B): pass
[out]
main:2: error: Argument 2 to "A" has incompatible type "B"; expected "C"

[case testInheritedConstructor]
import typing
b = B(C()) # type: B
a = B(D()) # type: A # Fail
class A:
    def __init__(self, x: 'C') -> None: pass
class B(A): pass
class C: pass
class D: pass
[out]
main:3: error: Argument 1 to "B" has incompatible type "D"; expected "C"

[case testOverridingWithIncompatibleConstructor]
import typing
A()    # Fail
B(C()) # Fail
A(C())
B()
class A:
    def __init__(self, x: 'C') -> None: pass
class B(A):
    def __init__(self) -> None: pass
class C: pass
[out]
main:2: error: Too few arguments for "A"
main:3: error: Too many arguments for "B"

[case testConstructorWithReturnValueType]
import typing
class A:
    def __init__(self) -> 'A': pass
[out]
main:3: error: The return type of "__init__" must be None

[case testConstructorWithImplicitReturnValueType]
import typing
class A:
    def __init__(self, x: int): pass
[out]
main:3: error: The return type of "__init__" must be None

[case testInitSubclassWithReturnValueType]
import typing
class A:
    def __init_subclass__(cls) -> 'A': pass
[out]
main:3: error: The return type of "__init_subclass__" must be None

[case testInitSubclassWithImplicitReturnValueType]
import typing
class A:
    def __init_subclass__(cls, x: int=1): pass
[out]
main:3: error: The return type of "__init_subclass__" must be None

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

[case testAccessingInit]
from typing import Any, cast
class A:
    def __init__(self, a: 'A') -> None: pass
a = None # type: A
a.__init__(a)  # E: Cannot access "__init__" directly
(cast(Any, a)).__init__(a)

[case testDeepInheritanceHierarchy]
import typing
d = C() # type: D  # Fail
d = B()      # Fail
d = A()      # Fail
d = D2()     # Fail
a = D() # type: A
a = D2()
b = D() # type: B
b = D2()

class A: pass
class B(A): pass
class C(B): pass
class D(C): pass
class D2(C): pass
[out]
main:2: error: Incompatible types in assignment (expression has type "C", variable has type "D")
main:3: error: Incompatible types in assignment (expression has type "B", variable has type "D")
main:4: error: Incompatible types in assignment (expression has type "A", variable has type "D")
main:5: error: Incompatible types in assignment (expression has type "D2", variable has type "D")


-- Attribute access in class body
-- ------------------------------


[case testDataAttributeRefInClassBody]
import typing
class B: pass
class A:
    x = B()
    y = x
    b = x # type: B
    b = x
    c = x # type: A # E: Incompatible types in assignment (expression has type "B", variable has type "A")
    c = b   # E: Incompatible types in assignment (expression has type "B", variable has type "A")
[out]

[case testMethodRefInClassBody]
from typing import Callable
class B: pass
class A:
    def f(self) -> None: pass
    g = f
    h = f # type: Callable[[A], None]
    h = f
    g = h
    ff = f # type: Callable[[B], None]  # E: Incompatible types in assignment (expression has type "Callable[[A], None]", variable has type "Callable[[B], None]")
    g = ff                # E: Incompatible types in assignment (expression has type "Callable[[B], None]", variable has type "Callable[[A], None]")
[out]


-- Arbitrary statements in class body
-- ----------------------------------


[case testStatementsInClassBody]
import typing
class B: pass
class A:
    for x in [A()]:
        y = x
        y = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A")
    x = A()
    y = A()
    x = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A")
[builtins fixtures/for.pyi]
[out]


-- Class attributes
-- ----------------


[case testAccessMethodViaClass]
import typing
class A:
    def f(self) -> None: pass
A.f(A())
A.f(object())     # E: Argument 1 to "f" of "A" has incompatible type "object"; expected "A"
A.f()             # E: Too few arguments for "f" of "A"
A.f(None, None)   # E: Too many arguments for "f" of "A"

[case testAccessAttributeViaClass]
import typing
class B: pass
class A:
    x = None # type: A
a = A.x # type: A
b = A.x # type: B # E: Incompatible types in assignment (expression has type "A", variable has type "B")

[case testAccessingUndefinedAttributeViaClass]
import typing
class A: pass
A.x # E: "Type[A]" has no attribute "x"

[case testAccessingUndefinedAttributeViaClassWithOverloadedInit]
from foo import *
[file foo.pyi]
from typing import overload
class A:
    @overload
    def __init__(self): pass
    @overload
    def __init__(self, x): pass
A.x # E: "Type[A]" has no attribute "x"

[case testAccessMethodOfClassWithOverloadedInit]
from foo import *
[file foo.pyi]
from typing import overload, Any
class A:
    @overload
    def __init__(self) -> None: pass
    @overload
    def __init__(self, x: Any) -> None: pass
    def f(self) -> None: pass
A.f(A())
A.f()    # E: Too few arguments for "f" of "A"

[case testAssignmentToClassDataAttribute]
import typing
class B: pass
class A:
    x = None # type: B
A.x = B()
A.x = object()  # E: Incompatible types in assignment (expression has type "object", variable has type "B")

[case testAssignmentToInferredClassDataAttribute]
import typing
class B: pass
class A:
     x = B()
A.x = B()
A.x = A()   # E: Incompatible types in assignment (expression has type "A", variable has type "B")

[case testInitMethodUnbound]

class B: pass
class A:
    def __init__(self, b: B) -> None: pass
a = None # type: A
b = None # type: B
A.__init__(a, b)
A.__init__(b, b) # E: Argument 1 to "__init__" of "A" has incompatible type "B"; expected "A"
A.__init__(a, a) # E: Argument 2 to "__init__" of "A" has incompatible type "A"; expected "B"

[case testAssignToMethodViaClass]
import typing
class A:
    def f(self): pass
A.f = None # E: Cannot assign to a method

[case testAssignToNestedClassViaClass]
import typing
class A:
    class B: pass
A.B = None # E: Cannot assign to a type

[case testAccessingClassAttributeWithTypeInferenceIssue]
x = C.x # E: Cannot determine type of 'x'
def f() -> int: return 1
class C:
    x = f()
[builtins fixtures/list.pyi]

[case testAccessingClassAttributeWithTypeInferenceIssue2]
class C:
    x = []
x = C.x
[builtins fixtures/list.pyi]
[out]
main:2: error: Need type annotation for 'x'

[case testAccessingGenericClassAttribute]
from typing import Generic, TypeVar
T = TypeVar('T')
class A(Generic[T]):
    x = None  # type: T
A.x  # E: Access to generic instance variables via class is ambiguous
A[int].x  # E: Access to generic instance variables via class is ambiguous

[case testAccessingNestedGenericClassAttribute]
from typing import Generic, List, TypeVar, Union
T = TypeVar('T')
U = TypeVar('U')
class A(Generic[T, U]):
    x = None  # type: Union[T, List[U]]
A.x  # E: Access to generic instance variables via class is ambiguous
A[int, int].x  # E: Access to generic instance variables via class is ambiguous
[builtins fixtures/list.pyi]


-- Nested classes
-- --------------


[case testClassWithinFunction]

def f() -> None:
    class A:
        def g(self) -> None: pass
    a = None # type: A
    a.g()
    a.g(a) # E: Too many arguments for "g" of "A"
[out]

[case testConstructNestedClass]
import typing
class A:
    class B: pass
    b = B()
    b = A() # E: Incompatible types in assignment (expression has type "A", variable has type "B")
    b = B(b) # E: Too many arguments for "B"
[out]

[case testConstructNestedClassWithCustomInit]
import typing
class A:
    def f(self) -> None:
        class B:
            def __init__(self, a: 'A') -> None: pass
        b = B(A())
        b = A() # E: Incompatible types in assignment (expression has type "A", variable has type "B")
        b = B() # E: Too few arguments for "B"
[out]

[case testDeclareVariableWithNestedClassType]

def f() -> None:
    class A: pass
    a = None # type: A
    a = A()
    a = object() # E: Incompatible types in assignment (expression has type "object", variable has type "A")
[out]

[case testExternalReferenceToClassWithinClass]

class A:
    class B: pass
b = None # type: A.B
b = A.B()
b = A() # E: Incompatible types in assignment (expression has type "A", variable has type "B")
b = A.B(b) # E: Too many arguments for "B"

[case testAliasNestedClass]
class Outer:
    class Inner:
        def make_int(self) -> int: return 1
    reveal_type(Inner().make_int)  # E: Revealed type is 'def () -> builtins.int'
    some_int = Inner().make_int()

reveal_type(Outer.Inner.make_int)  # E: Revealed type is 'def (self: __main__.Outer.Inner) -> builtins.int'
reveal_type(Outer().some_int) # E: Revealed type is 'builtins.int'
Bar = Outer.Inner
reveal_type(Bar.make_int)  # E: Revealed type is 'def (self: __main__.Outer.Inner) -> builtins.int'
x = Bar()  # type: Bar
def produce() -> Bar:
    reveal_type(Bar().make_int)  # E: Revealed type is 'def () -> builtins.int'
    return Bar()

[case testInnerClassPropertyAccess]
class Foo:
    class Meta:
        name = 'Bar'
    meta = Meta

reveal_type(Foo.Meta)  # E: Revealed type is 'def () -> __main__.Foo.Meta'
reveal_type(Foo.meta)  # E: Revealed type is 'def () -> __main__.Foo.Meta'
reveal_type(Foo.Meta.name)  # E: Revealed type is 'builtins.str'
reveal_type(Foo.meta.name)  # E: Revealed type is 'builtins.str'
reveal_type(Foo().Meta)  # E: Revealed type is 'def () -> __main__.Foo.Meta'
reveal_type(Foo().meta)  # E: Revealed type is 'def () -> __main__.Foo.Meta'
reveal_type(Foo().meta.name)  # E: Revealed type is 'builtins.str'
reveal_type(Foo().Meta.name)  # E: Revealed type is 'builtins.str'

-- Declaring attribute type in method
-- ----------------------------------


[case testDeclareAttributeTypeInInit]

class A:
    def __init__(self):
        self.x = None # type: int
a = None # type: A
a.x = 1
a.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int")

[case testAccessAttributeDeclaredInInitBeforeDeclaration]

a = None # type: A
a.x = 1
a.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int")
class A:
    def __init__(self):
        self.x = None # type: int


-- Special cases
-- -------------


[case testMultipleClassDefinition]
import typing
A()
class A: pass
class A: pass
[out]
main:4: error: Name 'A' already defined on line 3

[case testDocstringInClass]
import typing
class A:
    """Foo"""
class B:
    'x'
    y = B()
[builtins fixtures/primitives.pyi]

[case testErrorMessageInFunctionNestedWithinMethod]
import typing
class A:
    def f(self) -> None:
        def g() -> None:
            "" + 1  # E: Unsupported operand types for + ("str" and "int")
        "" + 1  # E: Unsupported operand types for + ("str" and "int")
[out]

-- Static methods
-- --------------


[case testSimpleStaticMethod]
import typing
class A:
  @staticmethod
  def f(x: int) -> None: pass
A.f(1)
A().f(1)
A.f('') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int"
A().f('') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int"
[builtins fixtures/staticmethod.pyi]

[case testBuiltinStaticMethod]
import typing
int.from_bytes(b'', '')
int.from_bytes('', '') # E: Argument 1 to "from_bytes" of "int" has incompatible type "str"; expected "bytes"
[builtins fixtures/staticmethod.pyi]

[case testAssignStaticMethodOnInstance]
import typing
class A:
  @staticmethod
  def f(x: int) -> None: pass
A().f = A.f # E: Cannot assign to a method
[builtins fixtures/staticmethod.pyi]


-- Class methods
-- -------------


[case testSimpleClassMethod]
import typing
class A:
  @classmethod
  def f(cls, x: int) -> None: pass
A.f(1)
A().f(1)
A.f('') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int"
A().f('') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int"
[builtins fixtures/classmethod.pyi]

[case testBuiltinClassMethod]
import typing
int.from_bytes(b'', '')
int.from_bytes('', '') # E: Argument 1 to "from_bytes" of "int" has incompatible type "str"; expected "bytes"
[builtins fixtures/classmethod.pyi]

[case testAssignClassMethodOnClass]
import typing
class A:
  @classmethod
  def f(cls, x: int) -> None: pass
A.f = A.f # E: Cannot assign to a method
[builtins fixtures/classmethod.pyi]

[case testAssignClassMethodOnInstance]
import typing
class A:
  @classmethod
  def f(cls, x: int) -> None: pass
A().f = A.f # E: Cannot assign to a method
[builtins fixtures/classmethod.pyi]

[case testClassMethodCalledInClassMethod]
import typing
class C:
  @classmethod
  def foo(cls) -> None: pass
  @classmethod
  def bar(cls) -> None:
    cls()
    cls(1)      # E: Too many arguments for "C"
    cls.bar()
    cls.bar(1)  # E: Too many arguments for "bar" of "C"
    cls.bozo()  # E: "Type[C]" has no attribute "bozo"
[builtins fixtures/classmethod.pyi]
[out]

[case testClassMethodCalledOnClass]
import typing
class C:
  @classmethod
  def foo(cls) -> None: pass
C.foo()
C.foo(1)  # E: Too many arguments for "foo" of "C"
C.bozo()  # E: "Type[C]" has no attribute "bozo"
[builtins fixtures/classmethod.pyi]

[case testClassMethodCalledOnInstance]
import typing
class C:
  @classmethod
  def foo(cls) -> None: pass
C().foo()
C().foo(1)  # E: Too many arguments for "foo" of "C"
C.bozo()    # E: "Type[C]" has no attribute "bozo"
[builtins fixtures/classmethod.pyi]

[case testClassMethodMayCallAbstractMethod]
from abc import abstractmethod
import typing
class C:
  @classmethod
  def foo(cls) -> None:
      cls().bar()
  @abstractmethod
  def bar(self) -> None:
      pass
[builtins fixtures/classmethod.pyi]

[case testClassMethodSubclassing]
class A:
    @classmethod
    def f(cls) -> None: pass

    def g(self) -> None: pass

class B(A):
    def f(self) -> None: pass  # E: Signature of "f" incompatible with supertype "A"

    @classmethod
    def g(cls) -> None: pass

class C(A):
    @staticmethod
    def f() -> None: pass
[builtins fixtures/classmethod.pyi]

-- Properties
-- ----------


[case testAccessingReadOnlyProperty]
import typing
class A:
    @property
    def f(self) -> str: pass
a = A()
reveal_type(a.f)  # E: Revealed type is 'builtins.str'
[builtins fixtures/property.pyi]

[case testAssigningToReadOnlyProperty]
import typing
class A:
    @property
    def f(self) -> str: pass
A().f = '' # E: Property "f" defined in "A" is read-only
[builtins fixtures/property.pyi]

[case testAssigningToInheritedReadOnlyProperty]
class A:
    @property
    def f(self) -> str: pass
class B(A): pass
class C(A):
    @property
    def f(self) -> str: pass

A().f = '' # E: Property "f" defined in "A" is read-only
B().f = '' # E: Property "f" defined in "A" is read-only
C().f = '' # E: Property "f" defined in "C" is read-only
[builtins fixtures/property.pyi]

[case testPropertyGetterBody]
import typing
class A:
    @property
    def f(self) -> str:
        self.x = 1
        self.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int")
        return ''
[builtins fixtures/property.pyi]
[out]

[case testDynamicallyTypedProperty]
import typing
class A:
    @property
    def f(self): pass
a = A()
a.f.xx
a.f = '' # E: Property "f" defined in "A" is read-only
[builtins fixtures/property.pyi]

[case testPropertyWithSetter]
import typing
class A:
    @property
    def f(self) -> int:
        return 1
    @f.setter
    def f(self, x: int) -> None:
        pass
a = A()
a.f = a.f
a.f.x # E: "int" has no attribute "x"
a.f = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int")
a.f = 1
reveal_type(a.f)  # E: Revealed type is 'builtins.int'
[builtins fixtures/property.pyi]

[case testPropertyWithDeleterButNoSetter]
import typing
class A:
    @property
    def f(self) -> int:
        return 1
    @f.deleter
    def f(self, x) -> None:
        pass
a = A()
a.f = a.f # E: Property "f" defined in "A" is read-only
a.f.x # E: "int" has no attribute "x"
[builtins fixtures/property.pyi]

-- Descriptors
-- -----------


[case testAccessingNonDataDescriptor]
from typing import Any
class D:
    def __get__(self, inst: Any, own: Any) -> str: return 's'
class A:
    f = D()
a = A()
reveal_type(a.f)  # E: Revealed type is 'builtins.str'

[case testSettingNonDataDescriptor]
from typing import Any
class D:
    def __get__(self, inst: Any, own: Any) -> str: return 's'
class A:
    f = D()
a = A()
a.f = 'foo'
a.f = D()  # E: Incompatible types in assignment (expression has type "D", variable has type "str")

[case testSettingDataDescriptor]
from typing import Any
class D:
    def __get__(self, inst: Any, own: Any) -> str: return 's'
    def __set__(self, inst: Any, value: str) -> None: pass
class A:
    f = D()
a = A()
a.f = ''
a.f = 1 # E: Argument 2 to "__set__" of "D" has incompatible type "int"; expected "str"

[case testReadingDescriptorWithoutDunderGet]
from typing import Union, Any
class D:
    def __set__(self, inst: Any, value: str) -> None: pass
class A:
    f = D()
    def __init__(self): self.f = 's'
a = A()
reveal_type(a.f)  # E: Revealed type is '__main__.D'

[case testAccessingDescriptorFromClass]
# flags: --strict-optional
from d import D, Base
class A(Base):
    f = D()
reveal_type(A.f)  # E: Revealed type is 'd.D'
reveal_type(A().f)  # E: Revealed type is 'builtins.str'
[file d.pyi]
from typing import TypeVar, Type, Generic, overload
class Base: pass
class D:
    def __init__(self) -> None: pass
    @overload
    def __get__(self, inst: None, own: Type[Base]) -> D: pass
    @overload
    def __get__(self, inst: Base, own: Type[Base]) -> str: pass
[builtins fixtures/bool.pyi]

[case testAccessingDescriptorFromClassWrongBase]
# flags: --strict-optional
from d import D, Base
class A:
    f = D()
reveal_type(A.f)
reveal_type(A().f)
[file d.pyi]
from typing import TypeVar, Type, Generic, overload
class Base: pass
class D:
    def __init__(self) -> None: pass
    @overload
    def __get__(self, inst: None, own: Type[Base]) -> D: pass
    @overload
    def __get__(self, inst: Base, own: Type[Base]) -> str: pass
[builtins fixtures/bool.pyi]
[out]
main:5: error: Revealed type is 'd.D'
main:5: error: Argument 2 to "__get__" of "D" has incompatible type "Type[A]"; expected "Type[Base]"
main:6: error: Revealed type is 'Any'
main:6: error: No overload variant of "__get__" of "D" matches argument types "A", "Type[A]"
main:6: note: Possible overload variants:
main:6: note:     def __get__(self, inst: None, own: Type[Base]) -> D
main:6: note:     def __get__(self, inst: Base, own: Type[Base]) -> str


[case testAccessingGenericNonDataDescriptor]
from typing import TypeVar, Type, Generic, Any
V = TypeVar('V')
class D(Generic[V]):
    def __init__(self, v: V) -> None: self.v = v
    def __get__(self, inst: Any, own: Type) -> V: return self.v
class A:
    f = D(10)
    g = D('10')
a = A()
reveal_type(a.f)  # E: Revealed type is 'builtins.int*'
reveal_type(a.g)  # E: Revealed type is 'builtins.str*'

[case testSettingGenericDataDescriptor]
from typing import TypeVar, Type, Generic, Any
V = TypeVar('V')
class D(Generic[V]):
    def __init__(self, v: V) -> None: self.v = v
    def __get__(self, inst: Any, own: Type) -> V: return self.v
    def __set__(self, inst: Any, v: V) -> None: pass
class A:
    f = D(10)
    g = D('10')
a = A()
a.f = 1
a.f = '' # E: Argument 2 to "__set__" of "D" has incompatible type "str"; expected "int"
a.g = ''
a.g = 1 # E: Argument 2 to "__set__" of "D" has incompatible type "int"; expected "str"

[case testAccessingGenericDescriptorFromClass]
# flags: --strict-optional
from d import D
class A:
    f = D(10)  # type: D[A, int]
    g = D('10')  # type: D[A, str]
reveal_type(A.f)  # E: Revealed type is 'd.D[__main__.A*, builtins.int*]'
reveal_type(A.g)  # E: Revealed type is 'd.D[__main__.A*, builtins.str*]'
reveal_type(A().f)  # E: Revealed type is 'builtins.int*'
reveal_type(A().g)  # E: Revealed type is 'builtins.str*'
[file d.pyi]
from typing import TypeVar, Type, Generic, overload
T = TypeVar('T')
V = TypeVar('V')
class D(Generic[T, V]):
    def __init__(self, v: V) -> None: pass
    @overload
    def __get__(self, inst: None, own: Type[T]) -> 'D[T, V]': pass
    @overload
    def __get__(self, inst: T, own: Type[T]) -> V: pass
[builtins fixtures/bool.pyi]

[case testAccessingGenericDescriptorFromInferredClass]
# flags: --strict-optional
from typing import Type
from d import D
class A:
    f = D(10)  # type: D[A, int]
    g = D('10')  # type: D[A, str]
def f(some_class: Type[A]):
    reveal_type(some_class.f)
    reveal_type(some_class.g)
[file d.pyi]
from typing import TypeVar, Type, Generic, overload
T = TypeVar('T')
V = TypeVar('V')
class D(Generic[T, V]):
    def __init__(self, v: V) -> None: pass
    @overload
    def __get__(self, inst: None, own: Type[T]) -> 'D[T, V]': pass
    @overload
    def __get__(self, inst: T, own: Type[T]) -> V: pass
[builtins fixtures/bool.pyi]
[out]
main:8: error: Revealed type is 'd.D[__main__.A*, builtins.int*]'
main:9: error: Revealed type is 'd.D[__main__.A*, builtins.str*]'

[case testAccessingGenericDescriptorFromClassBadOverload]
# flags: --strict-optional
from d import D
class A:
    f = D(10)  # type: D[A, int]
reveal_type(A.f)
[file d.pyi]
from typing import TypeVar, Type, Generic, overload
T = TypeVar('T')
V = TypeVar('V')
class D(Generic[T, V]):
    def __init__(self, v: V) -> None: pass
    @overload
    def __get__(self, inst: None, own: None) -> 'D[T, V]': pass
    @overload
    def __get__(self, inst: T, own: Type[T]) -> V: pass
[builtins fixtures/bool.pyi]
[out]
main:5: error: Revealed type is 'Any'
main:5: error: No overload variant of "__get__" of "D" matches argument types "None", "Type[A]"
main:5: note: Possible overload variants:
main:5: note:     def __get__(self, inst: None, own: None) -> D[A, int]
main:5: note:     def __get__(self, inst: A, own: Type[A]) -> int


[case testAccessingNonDataDescriptorSubclass]
from typing import Any
class C:
    def __get__(self, inst: Any, own: Any) -> str: return 's'
class D(C): pass
class A:
    f = D()
a = A()
reveal_type(a.f)  # E: Revealed type is 'builtins.str'

[case testSettingDataDescriptorSubclass]
from typing import Any
class C:
    def __get__(self, inst: Any, own: Any) -> str: return 's'
    def __set__(self, inst: Any, v: str) -> None: pass
class D(C): pass
class A:
    f = D()
a = A()
a.f = ''
a.f = 1 # E: Argument 2 to "__set__" of "C" has incompatible type "int"; expected "str"

[case testReadingDescriptorSubclassWithoutDunderGet]
from typing import Union, Any
class C:
    def __set__(self, inst: Any, v: str) -> None: pass
class D(C): pass
class A:
    f = D()
    def __init__(self): self.f = 's'
a = A()
reveal_type(a.f)  # E: Revealed type is '__main__.D'

[case testAccessingGenericNonDataDescriptorSubclass]
from typing import TypeVar, Type, Generic, Any
V = TypeVar('V')
class C(Generic[V]):
    def __init__(self, v: V) -> None: self.v = v
    def __get__(self, inst: Any, own: Type) -> V: return self.v
class D(C[V], Generic[V]): pass
class A:
    f = D(10)
    g = D('10')
a = A()
reveal_type(a.f)  # E: Revealed type is 'builtins.int*'
reveal_type(a.g)  # E: Revealed type is 'builtins.str*'

[case testSettingGenericDataDescriptorSubclass]
from typing import TypeVar, Type, Generic
T = TypeVar('T')
V = TypeVar('V')
class C(Generic[T, V]):
    def __init__(self, v: V) -> None: self.v = v
    def __get__(self, inst: T, own: Type[T]) -> V: return self.v
    def __set__(self, inst: T, v: V) -> None: pass
class D(C[T, V], Generic[T, V]): pass
class A:
    f = D(10)  # type: D[A, int]
    g = D('10')  # type: D[A, str]
a = A()
a.f = 1
a.f = '' # E: Argument 2 to "__set__" of "C" has incompatible type "str"; expected "int"
a.g = ''
a.g = 1 # E: Argument 2 to "__set__" of "C" has incompatible type "int"; expected "str"

[case testSetDescriptorOnClass]
from typing import TypeVar, Type, Generic
T = TypeVar('T')
V = TypeVar('V')
class D(Generic[T, V]):
    def __init__(self, v: V) -> None: self.v = v
    def __get__(self, inst: T, own: Type[T]) -> V: return self.v
    def __set__(self, inst: T, v: V) -> None: pass
class A:
    f = D(10)  # type: D[A, int]
A.f = D(20)
A.f = D('some string')  # E: Argument 1 to "D" has incompatible type "str"; expected "int"

[case testSetDescriptorOnInferredClass]
from typing import TypeVar, Type, Generic, Any
V = TypeVar('V')
class D(Generic[V]):
    def __init__(self, v: V) -> None: self.v = v
    def __get__(self, inst: Any, own: Type) -> V: return self.v
    def __set__(self, inst: Any, v: V) -> None: pass
class A:
    f = D(10)
def f(some_class: Type[A]):
    A.f = D(20)
    A.f = D('some string')
[out]
main:11: error: Argument 1 to "D" has incompatible type "str"; expected "int"

[case testDescriptorUncallableDunderSet]
class D:
    __set__ = 's'
class A:
    f = D()
A().f = 'x'  # E: __main__.D.__set__ is not callable

[case testDescriptorDunderSetTooFewArgs]
class D:
    def __set__(self, inst): pass
class A:
    f = D()
A().f = 'x'  # E: Too many arguments for "__set__"

[case testDescriptorDunderSetTooManyArgs]
class D:
    def __set__(self, inst, v, other): pass
class A:
    f = D()
A().f = 'x'  # E: Too few arguments for "__set__"

[case testDescriptorDunderSetWrongArgTypes]
class D:
    def __set__(self, inst: str, v:str) -> None: pass
class A:
    f = D()
A().f = 'x'  # E: Argument 1 to "__set__" of "D" has incompatible type "A"; expected "str"

[case testDescriptorUncallableDunderGet]
class D:
    __get__ = 's'
class A:
    f = D()
A().f  # E: __main__.D.__get__ is not callable

[case testDescriptorDunderGetTooFewArgs]
class D:
    def __get__(self, inst): pass
class A:
    f = D()
A().f  # E: Too many arguments for "__get__"

[case testDescriptorDunderGetTooManyArgs]
class D:
    def __get__(self, inst, own, other): pass
class A:
    f = D()
A().f = 'x'  # E: Too few arguments for "__get__"

[case testDescriptorDunderGetWrongArgTypeForInstance]
from typing import Any
class D:
    def __get__(self, inst: str, own: Any) -> Any: pass
class A:
    f = D()
A().f  # E: Argument 1 to "__get__" of "D" has incompatible type "A"; expected "str"

[case testDescriptorDunderGetWrongArgTypeForOwner]
from typing import Any
class D:
    def __get__(self, inst: Any, own: str) -> Any: pass
class A:
    f = D()
A().f  # E: Argument 2 to "__get__" of "D" has incompatible type "Type[A]"; expected "str"

[case testDescriptorGetSetDifferentTypes]
from typing import Any
class D:
    def __get__(self, inst: Any, own: Any) -> str: return 's'
    def __set__(self, inst: Any, v: int) -> None: pass
class A:
    f = D()
a = A()
a.f = 1
reveal_type(a.f)  # E: Revealed type is 'builtins.str'

[case testDescriptorGetUnion]
from typing import Any, Union
class String:
    def __get__(self, inst: Any, owner: Any) -> str:
        return ''

class A:
    attr: str

class B:
    attr = String()

def foo(x: Union[A, B]) -> None:
    reveal_type(x.attr)  # E: Revealed type is 'builtins.str'

-- _promote decorators
-- -------------------


[case testSimpleDucktypeDecorator]
from typing import _promote
class A: pass
@_promote(A)
class B: pass
a = None  # type: A
b = None  # type: B
b = a # E: Incompatible types in assignment (expression has type "A", variable has type "B")
a = b

[case testDucktypeTransitivityDecorator]
from typing import _promote
class A: pass
@_promote(A)
class B: pass
@_promote(B)
class C: pass
a = None  # type: A
c = None  # type: C
c = a # E: Incompatible types in assignment (expression has type "A", variable has type "C")
a = c


-- Hard coded type promotions
-- --------------------------

[case testHardCodedTypePromotions]
import typing
def f(x: float) -> None: pass
def g(x: complex) -> None: pass
f(1)
g(1)
g(1.1)
[builtins fixtures/complex.pyi]


-- Operator methods
-- ----------------


[case testOperatorMethodOverrideIntroducingOverloading]
from foo import *
[file foo.pyi]
from typing import overload
class A:
    def __add__(self, x: int) -> int: pass
class B(A):
    @overload  # E: Signature of "__add__" incompatible with supertype "A" \
               # N: Overloaded operator methods can't have wider argument types in overrides
    def __add__(self, x: int) -> int: pass
    @overload
    def __add__(self, x: str) -> str: pass
[out]

[case testOperatorMethodOverrideWideningArgumentType]
import typing
class A:
    def __add__(self, x: int) -> int: pass
class B(A):
    def __add__(self, x: object) -> int: pass
[out]

[case testOperatorMethodOverrideNarrowingReturnType]
import typing
class A:
    def __add__(self, x: int) -> 'A': pass
class B(A):
    def __add__(self, x: int) -> 'B': pass

[case testOperatorMethodOverrideWithDynamicallyTyped]
import typing
class A:
    def __add__(self, x: int) -> 'A': pass
class B(A):
    def __add__(self, x): pass

[case testOperatorMethodAgainstSameType]
class A:
    def __add__(self, x: int) -> 'A':
        if isinstance(x, int):
            return A()
        else:
            return NotImplemented

    def __radd__(self, x: 'A') -> 'A':
        if isinstance(x, A):
            return A()
        else:
            return NotImplemented

class B(A): pass

# Note: This is a runtime error. If we run x.__add__(y)
# where x and y are *not* the same type, Python will not try
# calling __radd__.
A() + A()               # E: Unsupported operand types for + ("A" and "A")

# Here, Python *will* call __radd__(...)
reveal_type(B() + A())  # E: Revealed type is '__main__.A'
reveal_type(A() + B())  # E: Revealed type is '__main__.A'
[builtins fixtures/isinstance.pyi]

[case testOperatorMethodOverrideWithIdenticalOverloadedType]
from foo import *
[file foo.pyi]
from typing import overload
class A:
    @overload
    def __add__(self, x: int) -> 'A': pass
    @overload
    def __add__(self, x: str) -> 'A': pass
class B(A):
    @overload
    def __add__(self, x: int) -> 'A': pass
    @overload
    def __add__(self, x: str) -> 'A': pass

[case testOverloadedOperatorMethodOverrideWithDynamicallyTypedMethod]
from foo import *
[file foo.pyi]
from typing import overload, Any
class A:
    @overload
    def __add__(self, x: int) -> 'A': pass
    @overload
    def __add__(self, x: str) -> 'A': pass
class B(A):
    def __add__(self, x): pass
class C(A):
    def __add__(self, x: Any) -> A: pass

[case testOverloadedOperatorMethodOverrideWithNewItem]
from foo import *
[file foo.pyi]
from typing import overload, Any
class A:
    @overload
    def __add__(self, x: int) -> 'A': pass
    @overload
    def __add__(self, x: str) -> 'A': pass
class B(A):
    @overload  # E: Signature of "__add__" incompatible with supertype "A" \
               # N: Overloaded operator methods can't have wider argument types in overrides
    def __add__(self, x: int) -> A: pass
    @overload
    def __add__(self, x: str) -> A: pass
    @overload
    def __add__(self, x: type) -> A: pass

[case testOverloadedOperatorMethodOverrideWithSwitchedItemOrder]
from foo import *
[file foo.pyi]
from typing import overload, Any
class A:
    @overload
    def __add__(self, x: 'B') -> 'B': pass
    @overload
    def __add__(self, x: 'A') -> 'A': pass
class B(A):
    @overload
    def __add__(self, x: 'A') -> 'A': pass
    @overload
    def __add__(self, x: 'B') -> 'B': pass
class C(A):
    @overload
    def __add__(self, x: 'B') -> 'B': pass
    @overload
    def __add__(self, x: 'A') -> 'A': pass
[out]
tmp/foo.pyi:8: error: Signature of "__add__" incompatible with supertype "A"
tmp/foo.pyi:8: note: Overload variants must be defined in the same order as they are in "A"
tmp/foo.pyi:11: error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader

[case testReverseOperatorMethodArgumentType]
from typing import Any
class A: pass
class B:
    def __radd__(self, x: A) -> int: pass # Error
class C:
    def __radd__(self, x: A) -> Any: pass
class D:
    def __radd__(self, x: A) -> object: pass
[out]

[case testReverseOperatorMethodArgumentType2]
from typing import Any, Tuple, Callable
class A:
    def __radd__(self, x: Tuple[int, str]) -> int: pass
class B:
    def __radd__(self, x: Callable[[], int]) -> int: pass
class C:
    def __radd__(self, x: Any) -> int: pass
[out]

[case testReverseOperatorMethodInvalid]
from foo import *
[file foo.pyi]
class A: ...
class B:
    def __rmul__(self) -> A: ...
class C:
    def __radd__(self, other, oops) -> int: ...
[out]
tmp/foo.pyi:3: error: Invalid signature "def (foo.B) -> foo.A"
tmp/foo.pyi:5: error: Invalid signature "def (foo.C, Any, Any) -> builtins.int"

[case testReverseOperatorOrderingCase1]
class A:
    def __radd__(self, other: 'A') -> int: ...

# Note: Python only tries calling __add__ and never __radd__, even though it's present
A() + A()  # E: Unsupported left operand type for + ("A")

[case testReverseOperatorOrderingCase2]
class A:
    def __lt__(self, other: object) -> bool: ...

# Not all operators have the above shortcut though.
reveal_type(A() > A())   # E: Revealed type is 'builtins.bool'
reveal_type(A() < A())   # E: Revealed type is 'builtins.bool'
[builtins fixtures/bool.pyi]

[case testReverseOperatorOrderingCase3]
class A:
    def __add__(self, other: B) -> int: ...

class B:
    def __radd__(self, other: A) -> str: ...  # E: Signatures of "__radd__" of "B" and "__add__" of "A" are unsafely overlapping

# Normally, we try calling __add__ before __radd__
reveal_type(A() + B())  # E: Revealed type is 'builtins.int'

[case testReverseOperatorOrderingCase4]
class A:
    def __add__(self, other: B) -> int: ...

class B(A):
    def __radd__(self, other: A) -> str: ...  # E: Signatures of "__radd__" of "B" and "__add__" of "A" are unsafely overlapping

# However, if B is a subtype of A, we try calling __radd__ first.
reveal_type(A() + B())  # E: Revealed type is 'builtins.str'

[case testReverseOperatorOrderingCase5]
# Note: these two methods are not unsafely overlapping because __radd__ is
# never called -- see case 1.
class A:
    def __add__(self, other: B) -> int: ...
    def __radd__(self, other: A) -> str: ...

class B(A): pass

# ...but only if B specifically defines a new __radd__.
reveal_type(A() + B())  # E: Revealed type is 'builtins.int'

[case testReverseOperatorOrderingCase6]
class A:
    def __add__(self, other: B) -> int: ...
    def __radd__(self, other: A) -> str: ...

class B(A):
    # Although A.__radd__ can never be called, B.__radd__ *can* be -- so the
    # unsafe overlap check kicks in here.
    def __radd__(self, other: A) -> str: ...  # E: Signatures of "__radd__" of "B" and "__add__" of "A" are unsafely overlapping

reveal_type(A() + B())  # E: Revealed type is 'builtins.str'

[case testReverseOperatorOrderingCase7]
class A:
    def __add__(self, other: B) -> int: ...
    def __radd__(self, other: A) -> str: ...

class B(A):
    def __radd__(self, other: A) -> str: ...  # E: Signatures of "__radd__" of "B" and "__add__" of "A" are unsafely overlapping

class C(B): pass

# A refinement made by a parent also counts
reveal_type(A() + C())  # E: Revealed type is 'builtins.str'

[case testReverseOperatorWithOverloads1]
from typing import overload

class A:
    def __add__(self, other: C) -> int: ...

class B:
    def __add__(self, other: C) -> int: ...

class C:
    @overload
    def __radd__(self, other: A) -> str: ...   # E: Signatures of "__radd__" of "C" and "__add__" of "A" are unsafely overlapping
    @overload
    def __radd__(self, other: B) -> str: ...   # E: Signatures of "__radd__" of "C" and "__add__" of "B" are unsafely overlapping
    def __radd__(self, other): pass

reveal_type(A() + C())   # E: Revealed type is 'builtins.int'
reveal_type(B() + C())   # E: Revealed type is 'builtins.int'

[case testReverseOperatorWithOverloads2]
from typing import overload, Union

class Num1:
    def __add__(self, other: Num1) -> Num1: ...
    def __radd__(self, other: Num1) -> Num1: ...

class Num2(Num1):
    @overload
    def __add__(self, other: Num2) -> Num2: ...  
    @overload
    def __add__(self, other: Num1) -> Num2: ...
    def __add__(self, other): pass

    @overload
    def __radd__(self, other: Num2) -> Num2: ...
    @overload
    def __radd__(self, other: Num1) -> Num2: ...
    def __radd__(self, other): pass

class Num3(Num1):
    def __add__(self, other: Union[Num1, Num3]) -> Num3: ...
    def __radd__(self, other: Union[Num1, Num3]) -> Num3: ...

reveal_type(Num1() + Num2())  # E: Revealed type is '__main__.Num2'
reveal_type(Num2() + Num1())  # E: Revealed type is '__main__.Num2'

reveal_type(Num1() + Num3())  # E: Revealed type is '__main__.Num3'
reveal_type(Num3() + Num1())  # E: Revealed type is '__main__.Num3'

reveal_type(Num2() + Num3())  # E: Revealed type is '__main__.Num2'
reveal_type(Num3() + Num2())  # E: Revealed type is '__main__.Num3'

[case testDivReverseOperatorPython3]
# No error: __div__ has no special meaning in Python 3
class A1:
    def __div__(self, x: B1) -> int: ...
class B1:
    def __rdiv__(self, x: A1) -> str: ...

class A2:
    def __truediv__(self, x: B2) -> int: ...
class B2:
    def __rtruediv__(self, x: A2) -> str: ...  # E: Signatures of "__rtruediv__" of "B2" and "__truediv__" of "A2" are unsafely overlapping

A1() / B1()                 # E: Unsupported left operand type for / ("A1")
reveal_type(A2() / B2())    # E: Revealed type is 'builtins.int'

[case testDivReverseOperatorPython2]
# flags: --python-version 2.7

# Note: if 'from __future__ import division' is called, we use
# __truediv__. Otherwise, we use __div__. So, we check both:
class A1:
    def __div__(self, x):
        # type: (B1) -> int
        pass
class B1:
    def __rdiv__(self, x):   # E: Signatures of "__rdiv__" of "B1" and "__div__" of "A1" are unsafely overlapping
        # type: (A1) -> str
        pass

class A2:
    def __truediv__(self, x):
        # type: (B2) -> int
        pass
class B2:
    def __rtruediv__(self, x):  # E: Signatures of "__rtruediv__" of "B2" and "__truediv__" of "A2" are unsafely overlapping
        # type: (A2) -> str
        pass

# That said, mypy currently doesn't handle the actual division operation very
# gracefully -- it doesn't correctly switch to using __truediv__ when
# 'from __future__ import division' is included, it doesn't display a very
# graceful error if __div__ is missing but __truediv__ is present...
# Also see https://github.com/python/mypy/issues/2048
reveal_type(A1() / B1())        # E: Revealed type is 'builtins.int'
A2() / B2()                     # E: "A2" has no attribute "__div__"

[case testReverseOperatorMethodForwardIsAny]
from typing import Any
def deco(f: Any) -> Any: return f
class C:
    @deco
    def __add__(self, other: C) -> C: return C()
    def __radd__(self, other: C) -> C: return C()
[out]

[case testReverseOperatorMethodForwardIsAny2]
from typing import Any
def deco(f: Any) -> Any: return f
class C:
    __add__ = None  # type: Any
    def __radd__(self, other: C) -> C: return C()
[out]

[case testReverseOperatorMethodForwardIsAny3]
from typing import Any
def deco(f: Any) -> Any: return f
class C:
    __add__ = 42
    def __radd__(self, other: C) -> C: return C()
[out]
main:5: error: Forward operator "__add__" is not callable

[case testOverloadedReverseOperatorMethodArgumentType]
from foo import *
[file foo.pyi]
from typing import overload, Any
class A:
    @overload
    def __radd__(self, x: 'A') -> str: pass
    @overload
    def __radd__(self, x: 'A') -> Any: pass  # E: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader
[out]

[case testReverseOperatorMethodArgumentTypeAndOverloadedMethod]
from foo import *
[file foo.pyi]
from typing import overload
class A:
    @overload
    def __add__(self, x: int) -> int: pass
    @overload
    def __add__(self, x: str) -> int: pass
    def __radd__(self, x: 'A') -> str: pass

[case testReverseOperatorStar]
class B:
    def __radd__(*self) -> int: pass
    def __rsub__(*self: 'B') -> int: pass

[case testReverseOperatorTypeVar1]
from typing import TypeVar, Any
T = TypeVar("T", bound='Real')
class Real:
    def __add__(self, other: Any) -> str: ...
class Fraction(Real):
    def __radd__(self, other: T) -> T: ...  # E: Signatures of "__radd__" of "Fraction" and "__add__" of "T" are unsafely overlapping

# Note: When doing A + B and if B is a subtype of A, we will always call B.__radd__(A) first
# and only try A.__add__(B) second if necessary.
reveal_type(Real() + Fraction())      # E: Revealed type is '__main__.Real*'

# Note: When doing A + A, we only ever call A.__add__(A), never A.__radd__(A).
reveal_type(Fraction() + Fraction())  # E: Revealed type is 'builtins.str'

[case testReverseOperatorTypeVar2a]
from typing import TypeVar
T = TypeVar("T", bound='Real')
class Real:
    def __add__(self, other: Fraction) -> str: ...
class Fraction(Real):
    def __radd__(self, other: T) -> T: ...  # E: Signatures of "__radd__" of "Fraction" and "__add__" of "T" are unsafely overlapping

reveal_type(Real() + Fraction())      # E: Revealed type is '__main__.Real*'
reveal_type(Fraction() + Fraction())  # E: Revealed type is 'builtins.str'


[case testReverseOperatorTypeVar2b]
from typing import TypeVar
T = TypeVar("T", Real, Fraction)
class Real:
    def __add__(self, other: Fraction) -> str: ...
class Fraction(Real):
    def __radd__(self, other: T) -> T: ...  # E: Signatures of "__radd__" of "Fraction" and "__add__" of "Real" are unsafely overlapping

reveal_type(Real() + Fraction())      # E: Revealed type is '__main__.Real*'
reveal_type(Fraction() + Fraction())  # E: Revealed type is 'builtins.str'

[case testReverseOperatorTypeVar3]
from typing import TypeVar, Any
T = TypeVar("T", bound='Real')
class Real:
    def __add__(self, other: FractionChild) -> str: ...
class Fraction(Real):
    def __radd__(self, other: T) -> T: ...  # E: Signatures of "__radd__" of "Fraction" and "__add__" of "T" are unsafely overlapping
class FractionChild(Fraction): pass

reveal_type(Real() + Fraction())                # E: Revealed type is '__main__.Real*'
reveal_type(FractionChild() + Fraction())       # E: Revealed type is '__main__.FractionChild*'
reveal_type(FractionChild() + FractionChild())  # E: Revealed type is 'builtins.str'

# Runtime error: we try calling __add__, it doesn't match, and we don't try __radd__ since
# the LHS and the RHS are not the same.
Fraction() + Fraction()                         # E: Unsupported operand types for + ("Fraction" and "Fraction")

[case testReverseOperatorTypeType]
from typing import TypeVar, Type
class Real(type):
    def __add__(self, other: FractionChild) -> str: ...
class Fraction(Real):
    def __radd__(self, other: Type['A']) -> Real: ...  # E: Signatures of "__radd__" of "Fraction" and "__add__" of "Type[A]" are unsafely overlapping
class FractionChild(Fraction): pass

class A(metaclass=Real): pass

[case testOperatorDoubleUnionIntFloat]
from typing import Union

a: Union[int, float]
b: int
c: float

reveal_type(a + a)  # E: Revealed type is 'builtins.float'
reveal_type(a + b)  # E: Revealed type is 'builtins.float'
reveal_type(b + a)  # E: Revealed type is 'builtins.float'
reveal_type(a + c)  # E: Revealed type is 'builtins.float'
reveal_type(c + a)  # E: Revealed type is 'builtins.float'
[builtins fixtures/ops.pyi]

[case testOperatorDoubleUnionStandardSubtyping]
from typing import Union

class Parent:
    def __add__(self, x: Parent) -> Parent: pass
    def __radd__(self, x: Parent) -> Parent: pass

class Child(Parent):
    def __add__(self, x: Parent) -> Child: pass
    def __radd__(self, x: Parent) -> Child: pass

a: Union[Parent, Child]
b: Parent
c: Child

reveal_type(a + a)  # E: Revealed type is '__main__.Parent'
reveal_type(a + b)  # E: Revealed type is '__main__.Parent'
reveal_type(b + a)  # E: Revealed type is '__main__.Parent'
reveal_type(a + c)  # E: Revealed type is '__main__.Child'
reveal_type(c + a)  # E: Revealed type is '__main__.Child'

[case testOperatorDoubleUnionNoRelationship1]
from typing import Union

class Foo:
    def __add__(self, x: Foo) -> Foo: pass
    def __radd__(self, x: Foo) -> Foo: pass

class Bar:
    def __add__(self, x: Bar) -> Bar: pass
    def __radd__(self, x: Bar) -> Bar: pass

a: Union[Foo, Bar]
b: Foo
c: Bar

a + a  # E: Unsupported operand types for + ("Foo" and "Bar") \
       # E: Unsupported operand types for + ("Bar" and "Foo") \
       # N: Both left and right operands are unions

a + b  # E: Unsupported operand types for + ("Bar" and "Foo") \
       # N: Left operand is of type "Union[Foo, Bar]"

b + a  # E: Unsupported operand types for + ("Foo" and "Bar") \
       # N: Right operand is of type "Union[Foo, Bar]"

a + c  # E: Unsupported operand types for + ("Foo" and "Bar") \
       # N: Left operand is of type "Union[Foo, Bar]"

c + a  # E: Unsupported operand types for + ("Bar" and "Foo") \
       # N: Right operand is of type "Union[Foo, Bar]"

[case testOperatorDoubleUnionNoRelationship2]
from typing import Union

class Foo:
    def __add__(self, x: Foo) -> Foo: pass
    def __radd__(self, x: Foo) -> Foo: pass

class Bar:
    def __add__(self, x: Union[Foo, Bar]) -> Bar: pass
    def __radd__(self, x: Union[Foo, Bar]) -> Bar: pass

a: Union[Foo, Bar]
b: Foo
c: Bar

reveal_type(a + a)  # E: Revealed type is 'Union[__main__.Foo, __main__.Bar]'
reveal_type(a + b)  # E: Revealed type is 'Union[__main__.Foo, __main__.Bar]'
reveal_type(b + a)  # E: Revealed type is 'Union[__main__.Foo, __main__.Bar]'
reveal_type(a + c)  # E: Revealed type is '__main__.Bar'
reveal_type(c + a)  # E: Revealed type is '__main__.Bar'

[case testOperatorDoubleUnionNaiveAdd]
from typing import Union

class A: pass
class B: pass
class C:
    def __radd__(self, x: A) -> int: pass
class D:
    def __radd__(self, x: B) -> str: pass

x: Union[A, B]
y: Union[C, D]

x + y  # E: Unsupported operand types for + ("A" and "D") \
       # E: Unsupported operand types for + ("B" and "C") \
       # N: Both left and right operands are unions

[case testOperatorDoubleUnionInterwovenUnionAdd]
from typing import Union

class Out1: pass
class Out2: pass
class Out3: pass
class Out4: pass

class A:
    def __add__(self, x: D) -> Out1: pass
class B:
    def __add__(self, x: C) -> Out2: pass
class C:
    def __radd__(self, x: A) -> Out3: pass
class D:
    def __radd__(self, x: B) -> Out4: pass

x: Union[A, B]
y: Union[C, D]

reveal_type(x + y)    # E: Revealed type is 'Union[__main__.Out3, __main__.Out1, __main__.Out2, __main__.Out4]'
reveal_type(A() + y)  # E: Revealed type is 'Union[__main__.Out3, __main__.Out1]'
reveal_type(B() + y)  # E: Revealed type is 'Union[__main__.Out2, __main__.Out4]'
reveal_type(x + C())  # E: Revealed type is 'Union[__main__.Out3, __main__.Out2]'
reveal_type(x + D())  # E: Revealed type is 'Union[__main__.Out1, __main__.Out4]'

[case testOperatorDoubleUnionDivisionPython2]
# flags: --python-version 2.7
from typing import Union
def f(a):
    # type: (Union[int, float]) -> None
    a /= 1.1
    b = a / 1.1
    reveal_type(b)  # E: Revealed type is 'builtins.float'
[builtins_py2 fixtures/ops.pyi]

[case testOperatorDoubleUnionDivisionPython3]
from typing import Union
def f(a):
    # type: (Union[int, float]) -> None
    a /= 1.1
    b = a / 1.1
    reveal_type(b)  # E: Revealed type is 'builtins.float'
[builtins fixtures/ops.pyi]

[case testOperatorWithInference]
from typing import TypeVar, Iterable, Union

T = TypeVar('T')
def sum(x: Iterable[T]) -> Union[T, int]: ...

def len(x: Iterable[T]) -> int: ...

x = [1.1, 2.2, 3.3]
reveal_type(sum(x))  # E: Revealed type is 'builtins.float*'
reveal_type(sum(x) / len(x))  # E: Revealed type is 'builtins.float'
[builtins fixtures/floatdict.pyi]

[case testOperatorWithEmptyListAndSum]
from typing import TypeVar, Iterable, Union, overload

T = TypeVar('T')
S = TypeVar('S')
@overload
def sum(x: Iterable[T]) -> Union[T, int]: ...
@overload
def sum(x: Iterable[T], default: S) -> Union[T, S]: ...
def sum(*args): pass

x = ["a", "b", "c"]
reveal_type(x + sum([x, x, x], []))  # E: Revealed type is 'builtins.list[builtins.str*]'
[builtins fixtures/floatdict.pyi]

[case testAbstractReverseOperatorMethod]
import typing
from abc import abstractmethod
class A:
    @abstractmethod
    def __lt__(self, x: 'A') -> int: pass
class B:
    @abstractmethod
    def __lt__(self, x: 'B') -> int: pass
    @abstractmethod
    def __gt__(self, x: 'B') -> int: pass
[out]

[case testOperatorMethodsAndOverloadingSpecialCase]
from foo import *
[file foo.pyi]
from typing import overload
class A:
    @overload
    def __add__(self, x: 'A') -> int: pass
    @overload
    def __add__(self, x: str) -> int: pass
class B:
    def __radd__(self, x: 'A') -> str: pass
[out]

[case testUnsafeOverlappingWithOperatorMethodsAndOverloading2]
from foo import A, B
from foo import *
[file foo.pyi]
from typing import overload
class A:
    def __add__(self, x: 'A') -> int: pass
class B:
    @overload
    def __radd__(self, x: 'X') -> str: pass # Error
    @overload
    def __radd__(self, x: A) -> str: pass   # Error
class X:
    def __add__(self, x: B) -> int: pass
[out]
tmp/foo.pyi:6: error: Signatures of "__radd__" of "B" and "__add__" of "X" are unsafely overlapping

[case testUnsafeOverlappingWithLineNo]
from typing import TypeVar
class Real:
    def __add__(self, other) -> str: ...
class Fraction(Real):
    def __radd__(self, other: Real) -> Real: ...
[out]
main:5: error: Signatures of "__radd__" of "Fraction" and "__add__" of "Real" are unsafely overlapping

[case testOverlappingNormalAndInplaceOperatorMethod]
import typing
class A:
    # Incompatible (potential trouble with __radd__)
    def __add__(self, x: 'A') -> int: pass
    def __iadd__(self, x: 'B') -> int: pass
class B:
    # Safe
    def __add__(self, x: 'C') -> int: pass
    def __iadd__(self, x: A) -> int: pass
class C(A): pass
[out]
main:5: error: Signatures of "__iadd__" and "__add__" are incompatible

[case testOverloadedNormalAndInplaceOperatorMethod]
from foo import *
[file foo.pyi]
from typing import overload
class A:
    @overload
    def __add__(self, x: int) -> int: pass
    @overload
    def __add__(self, x: str) -> int: pass
    @overload # Error
    def __iadd__(self, x: int) -> int: pass
    @overload
    def __iadd__(self, x: object) -> int: pass
class B:
    @overload
    def __add__(self, x: int) -> int: pass
    @overload
    def __add__(self, x: str) -> str: pass
    @overload
    def __iadd__(self, x: int) -> int: pass
    @overload
    def __iadd__(self, x: str) -> str: pass
[out]
tmp/foo.pyi:7: error: Signatures of "__iadd__" and "__add__" are incompatible

[case testIntroducingInplaceOperatorInSubclass]
import typing
class A:
    def __add__(self, x: 'A') -> 'B': pass
class B(A):
    # __iadd__ effectively partially overrides __add__
    def __iadd__(self, x: 'A') -> 'A': pass # Error
class C(A):
    def __iadd__(self, x: int) -> 'B': pass # Error
class D(A):
    def __iadd__(self, x: 'A') -> 'B': pass
[out]
main:6: error: Return type of "__iadd__" incompatible with "__add__" of supertype "A"
main:8: error: Argument 1 of "__iadd__" incompatible with "__add__" of supertype "A"
main:8: error: Signatures of "__iadd__" and "__add__" are incompatible

[case testGetattribute]

a, b = None, None # type: A, B
class A:
    def __getattribute__(self, x: str) -> A:
        return A()
class B: pass

a = a.foo
b = a.bar
[out]
main:9: error: Incompatible types in assignment (expression has type "A", variable has type "B")

[case testGetattributeSignature]
class A:
    def __getattribute__(self, x: str) -> A: pass
class B:
    def __getattribute__(self, x: A) -> B: pass
class C:
    def __getattribute__(self, x: str, y: str) -> C: pass
class D:
    def __getattribute__(self, x: str) -> None: pass
[out]
main:4: error: Invalid signature "def (__main__.B, __main__.A) -> __main__.B" for "__getattribute__"
main:6: error: Invalid signature "def (__main__.C, builtins.str, builtins.str) -> __main__.C" for "__getattribute__"

[case testGetattr]

a, b = None, None # type: A, B
class A:
    def __getattr__(self, x: str) -> A:
        return A()
class B: pass

a = a.foo
b = a.bar
[out]
main:9: error: Incompatible types in assignment (expression has type "A", variable has type "B")

[case testNestedGetattr]
def foo() -> object:
    def __getattr__() -> None:  # no error because not in a class
        pass
    return __getattr__

class X:
    def foo(self) -> object:
        def __getattr__() -> None:  # no error because not directly inside a class
            pass
        return __getattr__

[case testGetattrSignature]
class A:
    def __getattr__(self, x: str) -> A: pass
class B:
    def __getattr__(self, x: A) -> B: pass
class C:
    def __getattr__(self, x: str, y: str) -> C: pass
class D:
    def __getattr__(self, x: str) -> None: pass
[out]
main:4: error: Invalid signature "def (__main__.B, __main__.A) -> __main__.B" for "__getattr__"
main:6: error: Invalid signature "def (__main__.C, builtins.str, builtins.str) -> __main__.C" for "__getattr__"

[case testSetattr]
from typing import Union, Any
class A:
    def __setattr__(self, name: str, value: Any) -> None: ...

a = A()
a.test = 'hello'

class B:
   def __setattr__(self, name: str, value: Union[int, str]) -> None: ...

b = B()
b.both = 1
b.work = '2'

class C:
    def __setattr__(self, name: str, value: str) -> None: ...

c = C()
c.fail = 4  # E: Incompatible types in assignment (expression has type "int", variable has type "str")

class D:
    __setattr__ = 'hello'  # E: Invalid signature "builtins.str" for "__setattr__"

d = D()
d.crash = 4  # E: "D" has no attribute "crash"

class Ex:
    def __setattr__(self, name: str, value: int) -> None:...
    test = '42'  # type: str
e = Ex()
e.test = 'hello'
e.t = 4

class Super:
    def __setattr__(self, name: str, value: int) -> None: ...

class Sub(Super):
    ...
s = Sub()
s.success = 4
s.fail = 'fail'  # E: Incompatible types in assignment (expression has type "str", variable has type "int")

[case testSetattrSignature]
from typing import Any

class Test:
    def __setattr__() -> None: ...  # E: Method must have at least one argument # E: Invalid signature "def ()" for "__setattr__"
t = Test()
t.crash = 'test'  # E: "Test" has no attribute "crash"

class A:
    def __setattr__(self): ...  # E: Invalid signature "def (self: Any) -> Any" for "__setattr__"
a = A()
a.test = 4  # E: "A" has no attribute "test"

class B:
    def __setattr__(self, name, value: int): ...
b = B()
b.integer = 5

class C:
    def __setattr__(self, name: int, value: int) -> None: ...  # E: Invalid signature "def (__main__.C, builtins.int, builtins.int)" for "__setattr__"
c = C()
c.check = 13

class X:
    __setattr__ = ...  # type: Any

[case testGetattrAndSetattr]
from typing import Any
class A:
    def __setattr__(self, name: str, value: Any) -> None: ...
    def __getattr__(self, name: str) -> Any: ...
a = A()
a.test = 4
t = a.test

class B:
    def __setattr__(self, name: str, value: int) -> None: ...
    def __getattr__(self, name: str) -> str: ...
integer = 0
b = B()
b.at = '3'  # E: Incompatible types in assignment (expression has type "str", variable has type "int")
integer = b.at  # E: Incompatible types in assignment (expression has type "str", variable has type "int")

-- CallableType objects
-- ----------------


[case testCallableObject]
import typing
a = A()
b = B()

a()  # E: Too few arguments for "__call__" of "A"
a(a, a)  # E: Too many arguments for "__call__" of "A"
a = a(a)
a = a(b)  # E: Argument 1 to "__call__" of "A" has incompatible type "B"; expected "A"
b = a(a)  # E: Incompatible types in assignment (expression has type "A", variable has type "B")

class A:
    def __call__(self, x: A) -> A:
        pass
class B: pass


-- __new__
-- --------


[case testConstructInstanceWith__new__]
class C:
    def __new__(cls, foo: int = None) -> 'C':
        obj = object.__new__(cls)
        return obj

x = C(foo=12)
x.a # E: "C" has no attribute "a"
C(foo='') # E: Argument "foo" to "C" has incompatible type "str"; expected "Optional[int]"
[builtins fixtures/__new__.pyi]

[case testConstructInstanceWithDynamicallyTyped__new__]
class C:
    def __new__(cls, foo):
        obj = object.__new__(cls)
        return obj

x = C(foo=12)
x = C(foo='x')
x.a # E: "C" has no attribute "a"
C(bar='') # E: Unexpected keyword argument "bar" for "C"
[builtins fixtures/__new__.pyi]

[case testClassWith__new__AndCompatibilityWithType]
class C:
    def __new__(cls, foo: int = None) -> 'C':
        obj = object.__new__(cls)
        return obj
def f(x: type) -> None: pass
def g(x: int) -> None: pass
f(C)
g(C) # E: Argument 1 to "g" has incompatible type "Type[C]"; expected "int"
[builtins fixtures/__new__.pyi]

[case testClassWith__new__AndCompatibilityWithType2]
class C:
    def __new__(cls, foo):
        obj = object.__new__(cls)
        return obj
def f(x: type) -> None: pass
def g(x: int) -> None: pass
f(C)
g(C) # E: Argument 1 to "g" has incompatible type "Type[C]"; expected "int"
[builtins fixtures/__new__.pyi]

[case testGenericClassWith__new__]
from typing import TypeVar, Generic
T = TypeVar('T')
class C(Generic[T]):
    def __new__(cls, foo: T) -> 'C[T]':
        obj = object.__new__(cls)
        return obj
    def set(self, x: T) -> None: pass
c = C('')
c.set('')
c.set(1) # E: Argument 1 to "set" of "C" has incompatible type "int"; expected "str"
[builtins fixtures/__new__.pyi]

[case testOverloaded__new__]
from foo import *
[file foo.pyi]
from typing import overload
class C:
    @overload
    def __new__(cls, foo: int) -> 'C':
        obj = object.__new__(cls)
        return obj
    @overload
    def __new__(cls, x: str, y: str) -> 'C':
        obj = object.__new__(cls)
        return obj
c = C(1)
c.a # E: "C" has no attribute "a"
C('', '')
C('') # E: No overload variant of "C" matches argument type "str" \
      # N: Possible overload variant: \
      # N:     def __new__(cls, foo: int) -> C \
      # N:     <1 more non-matching overload not shown>
[builtins fixtures/__new__.pyi]


-- Special cases
-- -------------


[case testSubclassInt]
import typing
class A(int): pass
n = 0
n = A()
a = A()
a = 0 # E: Incompatible types in assignment (expression has type "int", variable has type "A")

[case testForwardReferenceToNestedClass]
def f(o: 'B.C') -> None:
    o.f('') # E: Argument 1 to "f" of "C" has incompatible type "str"; expected "int"

class B:
    class C:
        def f(self, x: int) -> None: pass
[out]

[case testForwardReferenceToNestedClassDeep]
def f(o: 'B.C.D') -> None:
    o.f('') # E: Argument 1 to "f" of "D" has incompatible type "str"; expected "int"

class B:
    class C:
        class D:
            def f(self, x: int) -> None: pass
[out]

[case testForwardReferenceToNestedClassWithinClass]
class B:
    def f(self, o: 'C.D') -> None:
        o.f('') # E: Argument 1 to "f" of "D" has incompatible type "str"; expected "int"

    class C:
        class D:
            def f(self, x: int) -> None: pass
[out]

[case testClassVsInstanceDisambiguation]
class A: pass
def f(x: A) -> None: pass
f(A) # E: Argument 1 to "f" has incompatible type "Type[A]"; expected "A"
[out]

-- TODO
--   attribute inherited from superclass; assign in __init__
--   refer to attribute before type has been inferred (the initialization in
--   __init__ has not been analyzed)

[case testAnyBaseClassUnconstrainedConstructor]
from typing import Any
B = None  # type: Any
class C(B): pass
C(0)
C(arg=0)
[out]

[case testErrorMapToSupertype]
import typing
class X(Nope): pass  # E: Name 'Nope' is not defined
a, b = X()  # Used to crash here (#2244)


-- Class-valued attributes
-- -----------------------

[case testClassValuedAttributesBasics]
class A: ...
class B:
    a = A
    bad = lambda: 42

B().bad() # E: Attribute function "bad" with type "Callable[[], int]" does not accept self argument
reveal_type(B.a) # E: Revealed type is 'def () -> __main__.A'
reveal_type(B().a) # E: Revealed type is 'def () -> __main__.A'
reveal_type(B().a()) # E: Revealed type is '__main__.A'

class C:
    a = A
    def __init__(self) -> None:
        self.aa = self.a()

reveal_type(C().aa) # E: Revealed type is '__main__.A'
[out]

[case testClassValuedAttributesGeneric]
from typing import Generic, TypeVar, Type
T = TypeVar('T')

class A(Generic[T]):
    def __init__(self, x: T) -> None:
        self.x = x
class B(Generic[T]):
    a: Type[A[T]] = A

reveal_type(B[int]().a) # E: Revealed type is 'Type[__main__.A[builtins.int*]]'
B[int]().a('hi') # E: Argument 1 to "A" has incompatible type "str"; expected "int"

class C(Generic[T]):
    a = A
    def __init__(self) -> None:
        self.aa = self.a(42)

reveal_type(C().aa) # E: Revealed type is '__main__.A[builtins.int]'
[out]

[case testClassValuedAttributesAlias]
from typing import Generic, TypeVar
T = TypeVar('T')
S = TypeVar('S')

class A(Generic[T, S]): ...

SameA = A[T, T]

class B:
    a_any = SameA
    a_int = SameA[int]

reveal_type(B().a_any) # E: Revealed type is 'def () -> __main__.A[Any, Any]'
reveal_type(B().a_int()) # E: Revealed type is '__main__.A[builtins.int, builtins.int]'

class C:
    a_int = SameA[int]
    def __init__(self) -> None:
        self.aa = self.a_int()

reveal_type(C().aa) # E: Revealed type is '__main__.A[builtins.int*, builtins.int*]'
[out]


-- Type[C]
-- -------


[case testTypeUsingTypeCBasic]
from typing import Type
class User: pass
class ProUser(User): pass
def new_user(user_class: Type[User]) -> User:
    return user_class()
reveal_type(new_user(User))  # E: Revealed type is '__main__.User'
reveal_type(new_user(ProUser))  # E: Revealed type is '__main__.User'
[out]

[case testTypeUsingTypeCDefaultInit]
from typing import Type
class B:
    pass
def f(A: Type[B]) -> None:
    A(0)  # E: Too many arguments for "B"
    A()
[out]

[case testTypeUsingTypeCInitWithArg]
from typing import Type
class B:
    def __init__(self, a: int) -> None: pass
def f(A: Type[B]) -> None:
    A(0)
    A()  # E: Too few arguments for "B"
[out]

[case testTypeUsingTypeCTypeVar]
from typing import Type, TypeVar
class User: pass
class ProUser(User): pass
U = TypeVar('U', bound=User)
def new_user(user_class: Type[U]) -> U:
    user = user_class()
    reveal_type(user)
    return user
pro_user = new_user(ProUser)
reveal_type(pro_user)
[out]
main:7: error: Revealed type is 'U`-1'
main:10: error: Revealed type is '__main__.ProUser*'

[case testTypeUsingTypeCTypeVarDefaultInit]
from typing import Type, TypeVar
class B:
    pass
T = TypeVar('T', bound=B)
def f(A: Type[T]) -> None:
    A()
    A(0)  # E: Too many arguments for "B"
[out]

[case testTypeUsingTypeCTypeVarWithInit]
from typing import Type, TypeVar
class B:
    def __init__(self, a: int) -> None: pass
T = TypeVar('T', bound=B)
def f(A: Type[T]) -> None:
    A()  # E: Too few arguments for "B"
    A(0)
[out]

[case testTypeUsingTypeCTwoTypeVars]
from typing import Type, TypeVar
class User: pass
class ProUser(User): pass
class WizUser(ProUser): pass
U = TypeVar('U', bound=User)
def new_user(u_c: Type[U]) -> U: pass
P = TypeVar('P', bound=ProUser)
def new_pro(pro_c: Type[P]) -> P:
    return new_user(pro_c)
wiz = new_pro(WizUser)
reveal_type(wiz)
def error(u_c: Type[U]) -> P:
    return new_pro(u_c)  # Error here, see below
[out]
main:11: error: Revealed type is '__main__.WizUser*'
main:13: error: Incompatible return value type (got "U", expected "P")
main:13: error: Value of type variable "P" of "new_pro" cannot be "U"

[case testTypeUsingTypeCCovariance]
from typing import Type, TypeVar
class User: pass
class ProUser(User): pass
def new_user(user_class: Type[User]) -> User:
    return user_class()
def new_pro_user(user_class: Type[ProUser]):
    new_user(user_class)
[out]

[case testAllowCovariantArgsInConstructor]
from typing import Generic, TypeVar

T_co = TypeVar('T_co', covariant=True)

class C(Generic[T_co]):
    def __init__(self, x: T_co) -> None: # This should be allowed
        self.x = x
    def meth(self) -> None:
        reveal_type(self.x) # E: Revealed type is 'T_co`1'

reveal_type(C(1).x) # E: Revealed type is 'builtins.int*'
[builtins fixtures/property.pyi]
[out]

[case testTypeUsingTypeCErrorCovariance]
from typing import Type, TypeVar
class User: pass
def new_user(user_class: Type[User]):
    return user_class()
def foo(arg: Type[int]):
    new_user(arg)  # E: Argument 1 to "new_user" has incompatible type "Type[int]"; expected "Type[User]"
[out]

[case testTypeUsingTypeCUnionOverload]
from foo import *
[file foo.pyi]
from typing import Type, Union, overload
class X:
    @overload
    def __init__(self) -> None: pass
    @overload
    def __init__(self, a: int) -> None: pass
class Y:
    def __init__(self) -> None: pass
def bar(o: Type[Union[X, Y]]): pass
bar(X)
bar(Y)
[out]

[case testTypeUsingTypeCTypeAny]
from typing import Type, Any
def foo(arg: Type[Any]):
    x = arg()
    x = arg(0)
    x = arg('', ())
    reveal_type(x)  # E: Revealed type is 'Any'
    x.foo
class X: pass
foo(X)
[out]

[case testTypeUsingTypeCTypeAnyMember]
from typing import Type, Any
def foo(arg: Type[Any]):
    x = arg.member_name
    arg.new_member_name = 42
    # Member access is ok and types as Any
    reveal_type(x)  # E: Revealed type is 'Any'
    # But Type[Any] is distinct from Any
    y: int = arg  # E: Incompatible types in assignment (expression has type "Type[Any]", variable has type "int")
[out]

[case testTypeUsingTypeCTypeAnyMemberFallback]
from typing import Type, Any
def foo(arg: Type[Any]):
    reveal_type(arg.__str__)  # E: Revealed type is 'def () -> builtins.str'
    reveal_type(arg.mro())  # E: Revealed type is 'builtins.list[builtins.type]'
[builtins fixtures/type.pyi]
[out]

[case testTypeUsingTypeCTypeNoArg]
from typing import Type
def foo(arg: Type):
    x = arg()
    reveal_type(x)  # E: Revealed type is 'Any'
class X: pass
foo(X)
[out]

[case testTypeUsingTypeCBuiltinType]
from typing import Type
def foo(arg: type): pass
class X: pass
def bar(arg: Type[X]):
    foo(arg)
foo(X)
[builtins fixtures/tuple.pyi]
[out]

[case testTypeUsingTypeCClassMethod]
from typing import Type
class User:
    @classmethod
    def foo(cls) -> int: pass
    def bar(self) -> int: pass
def process(cls: Type[User]):
    reveal_type(cls.foo())  # E: Revealed type is 'builtins.int'
    obj = cls()
    reveal_type(cls.bar(obj))  # E: Revealed type is 'builtins.int'
    cls.mro()  # Defined in class type
    cls.error  # E: "Type[User]" has no attribute "error"
[builtins fixtures/classmethod.pyi]
[out]

[case testTypeUsingTypeCClassMethodUnion]
from typing import Type, Union
class User:
    @classmethod
    def foo(cls) -> int: pass
    def bar(self) -> int: pass
class ProUser(User): pass
class BasicUser(User): pass
def process(cls: Type[Union[BasicUser, ProUser]]):
    cls.foo()
    obj = cls()
    cls.bar(obj)
    cls.mro()  # Defined in class type
    cls.error  # E: Item "type" of "Union[Type[BasicUser], Type[ProUser]]" has no attribute "error"
[builtins fixtures/classmethod.pyi]
[out]

[case testTypeUsingTypeCClassMethodFromTypeVar]
from typing import Type, TypeVar
class User:
    @classmethod
    def foo(cls) -> int: pass
    def bar(self) -> int: pass
U = TypeVar('U', bound=User)
def process(cls: Type[U]):
    reveal_type(cls.foo())  # E: Revealed type is 'builtins.int'
    obj = cls()
    reveal_type(cls.bar(obj))  # E: Revealed type is 'builtins.int'
    cls.mro()  # Defined in class type
    cls.error  # E: "Type[U]" has no attribute "error"
[builtins fixtures/classmethod.pyi]
[out]

[case testTypeUsingTypeCClassMethodFromTypeVarUnionBound]
# Ideally this would work, but not worth the effort; just don't crash
from typing import Type, TypeVar, Union
class User:
    @classmethod
    def foo(cls) -> int: pass
    def bar(self) -> int: pass
class ProUser(User): pass
class BasicUser(User): pass
U = TypeVar('U', bound=Union[ProUser, BasicUser])
def process(cls: Type[U]):
    cls.foo()  # E: "Type[U]" has no attribute "foo"
    obj = cls()
    cls.bar(obj)  # E: "Type[U]" has no attribute "bar"
    cls.mro()  # Defined in class type
    cls.error  # E: "Type[U]" has no attribute "error"
[builtins fixtures/classmethod.pyi]
[out]

[case testTypeUsingTypeCErrorUnsupportedType]
from typing import Type, Tuple
def foo(arg: Type[Tuple[int]]):  # E: Unsupported type Type["Tuple[int]"]
    arg()
[builtins fixtures/tuple.pyi]
[out]

[case testTypeUsingTypeCOverloadedClass]
from foo import *
[file foo.pyi]
from typing import Type, TypeVar, overload
class User:
    @overload
    def __init__(self) -> None: pass
    @overload
    def __init__(self, arg: int) -> None: pass
    @classmethod
    def foo(cls) -> None: pass
U = TypeVar('U', bound=User)
def new(uc: Type[U]) -> U:
    uc.foo()
    u = uc()
    u.foo()
    u = uc(0)
    u.foo()
    u = uc('')
    u.foo(0)
    return uc()
u = new(User)
[builtins fixtures/classmethod.pyi]
[out]
tmp/foo.pyi:16: error: No overload variant of "User" matches argument type "str"
tmp/foo.pyi:16: note: Possible overload variant:
tmp/foo.pyi:16: note:     def __init__(self, arg: int) -> U
tmp/foo.pyi:16: note:     <1 more non-matching overload not shown>
tmp/foo.pyi:17: error: Too many arguments for "foo" of "User"

[case testTypeUsingTypeCInUpperBound]
from typing import TypeVar, Type
class B: pass
T = TypeVar('T', bound=Type[B])
def f(a: T): pass
[out]

[case testTypeUsingTypeCTuple]
from typing import Type, Tuple
def f(a: Type[Tuple[int, int]]):
    a()
[out]
main:2: error: Unsupported type Type["Tuple[int, int]"]

[case testTypeUsingTypeCNamedTuple]
from typing import Type, NamedTuple
N = NamedTuple('N', [('x', int), ('y', int)])
def f(a: Type[N]):
    a()
[builtins fixtures/list.pyi]
[out]
main:3: error: Unsupported type Type["N"]

[case testTypeUsingTypeCJoin]
from typing import Type
class B: pass
class C(B): pass
class D(B): pass
def foo(c: Type[C], d: Type[D]) -> None:
    x = [c, d]
    reveal_type(x)

[builtins fixtures/list.pyi]
[out]
main:7: error: Revealed type is 'builtins.list[Type[__main__.B]]'

[case testTypeEquivalentTypeAny]
from typing import Type, Any

a = None # type: Type[Any]
b = a # type: type

x = None # type: type
y = x # type: Type[Any]

class C: ...

p = None # type: type
q = p # type: Type[C]

[builtins fixtures/list.pyi]
[out]

[case testTypeEquivalentTypeAny2]
from typing import Type, Any, TypeVar, Generic

class C: ...
x = None # type: type
y = None # type: Type[Any]
z = None # type: Type[C]

lst = [x, y, z]
reveal_type(lst) # E: Revealed type is 'builtins.list[builtins.type*]'

T1 = TypeVar('T1', bound=type)
T2 = TypeVar('T2', bound=Type[Any])
class C1(Generic[T1]): ...
class C2(Generic[T2]): ...

C1[Type[Any]], C2[type] # both these should not fail
[builtins fixtures/list.pyi]
[out]

[case testTypeEquivalentTypeAnyEdgeCase]
class C:
    pass

class M(type):
    def __init__(cls, x) -> None:
        type.__init__(cls, x)

class Mbad(type):
    def __init__(cls, x) -> None:
        type.__init__(C(), x) # E: Argument 1 to "__init__" of "type" has incompatible type "C"; expected "type"
[builtins fixtures/primitives.pyi]
[out]

[case testTypeMatchesOverloadedFunctions]
from foo import *
[file foo.pyi]
from typing import Type, overload, Any

class User: pass
UserType = User  # type: Type[User]

@overload
def f(a: int) -> Any: pass
@overload
def f(a: object) -> int: pass

reveal_type(f(User))  # E: Revealed type is 'builtins.int'
reveal_type(f(UserType))  # E: Revealed type is 'builtins.int'
[builtins fixtures/classmethod.pyi]
[out]

[case testTypeMatchesGeneralTypeInOverloadedFunctions]
from foo import *
[file foo.pyi]
from typing import Type, overload

class User: pass
UserType = User  # type: Type[User]

@overload
def f(a: type) -> int:
    return 1
@overload
def f(a: int) -> str:
    return "a"

reveal_type(f(User))  # E: Revealed type is 'builtins.int'
reveal_type(f(UserType))  # E: Revealed type is 'builtins.int'
reveal_type(f(1))  # E: Revealed type is 'builtins.str'
[builtins fixtures/classmethod.pyi]
[out]

[case testTypeMatchesSpecificTypeInOverloadedFunctions]
from foo import *
[file foo.pyi]
from typing import Type, overload

class User: pass
UserType = User  # type: Type[User]

@overload
def f(a: User) -> User:
    return User()
@overload
def f(a: Type[User]) -> int:
    return 1
@overload
def f(a: int) -> str:
    return "a"

reveal_type(f(User))  # E: Revealed type is 'builtins.int'
reveal_type(f(UserType))  # E: Revealed type is 'builtins.int'
reveal_type(f(User()))  # E: Revealed type is 'foo.User'
reveal_type(f(1))  # E: Revealed type is 'builtins.str'
[builtins fixtures/classmethod.pyi]
[out]

[case testMixingTypeTypeInOverloadedFunctions]
from foo import *
[file foo.pyi]
from typing import Type, overload

class User: pass

@overload
def f(a: User) -> Type[User]:
    return User
@overload
def f(a: Type[User]) -> User:
    return a()
@overload
def f(a: int) -> Type[User]:
    return User
@overload
def f(a: str) -> User:
    return User()

reveal_type(f(User()))  # E: Revealed type is 'Type[foo.User]'
reveal_type(f(User))  # E: Revealed type is 'foo.User'
reveal_type(f(3))  # E: Revealed type is 'Type[foo.User]'
reveal_type(f("hi"))  # E: Revealed type is 'foo.User'
[builtins fixtures/classmethod.pyi]
[out]

[case testGeneralTypeMatchesSpecificTypeInOverloadedFunctions]
from foo import *
[file foo.pyi]
from typing import Type, Any, overload

class User: pass

@overload
def f(a: Type[User]) -> None: pass
@overload
def f(a: int) -> None: pass

def mock_1() -> type: return User
def mock_2() -> Type[Any]: return User

f(User)
f(mock_1())
f(mock_2())
[builtins fixtures/classmethod.pyi]
[out]

[case testNonTypeDoesNotMatchOverloadedFunctions]
from foo import *
[file foo.pyi]
from typing import Type, overload

class User: pass

@overload
def f(a: Type[User]) -> None: pass
@overload
def f(a: type) -> None: pass

f(3)  # E: No overload variant of "f" matches argument type "int" \
      # N: Possible overload variants: \
      # N:     def f(a: Type[User]) -> None \
      # N:     def f(a: type) -> None
[builtins fixtures/classmethod.pyi]
[out]

[case testInstancesDoNotMatchTypeInOverloadedFunctions]
from foo import *
[file foo.pyi]
from typing import Type, overload

class User: pass

@overload
def f(a: Type[User]) -> None: pass
@overload
def f(a: int) -> None: pass

f(User)
f(User())  # E: No overload variant of "f" matches argument type "User" \
           # N: Possible overload variants: \
           # N:     def f(a: Type[User]) -> None \
           # N:     def f(a: int) -> None
[builtins fixtures/classmethod.pyi]
[out]

[case testTypeCovarianceWithOverloadedFunctions]
from foo import *
[file foo.pyi]
from typing import Type, overload

class A: pass
class B(A): pass
class C(B): pass
AType = A  # type: Type[A]
BType = B  # type: Type[B]
CType = C  # type: Type[C]

@overload
def f(a: Type[B]) -> None: pass
@overload
def f(a: int) -> None: pass

f(A)  # E: Argument 1 to "f" has incompatible type "Type[A]"; expected "Type[B]"
f(B)
f(C)
f(AType)  # E: Argument 1 to "f" has incompatible type "Type[A]"; expected "Type[B]"
f(BType)
f(CType)
[builtins fixtures/classmethod.pyi]
[out]


[case testOverloadedCovariantTypesFail]
from foo import *
[file foo.pyi]
from typing import Type, overload

class A: pass
class B(A): pass

@overload
def f(a: Type[B]) -> int: pass  # E: Overloaded function signatures 1 and 2 overlap with incompatible return types
@overload
def f(a: Type[A]) -> str: pass
[builtins fixtures/classmethod.pyi]
[out]

[case testDistinctOverloadedCovariantTypesSucceed]
from foo import *
[file foo.pyi]
from typing import Type, overload

class A: pass
class AChild(A): pass
class B: pass
class BChild(B): pass

@overload
def f(a: Type[A]) -> int: pass
@overload
def f(a: Type[B]) -> str: pass
@overload
def f(a: A) -> A: pass
@overload
def f(a: B) -> B: pass

reveal_type(f(A))  # E: Revealed type is 'builtins.int'
reveal_type(f(AChild))  # E: Revealed type is 'builtins.int'
reveal_type(f(B))  # E: Revealed type is 'builtins.str'
reveal_type(f(BChild))  # E: Revealed type is 'builtins.str'

reveal_type(f(A()))  # E: Revealed type is 'foo.A'
reveal_type(f(AChild()))  # E: Revealed type is 'foo.A'
reveal_type(f(B()))  # E: Revealed type is 'foo.B'
reveal_type(f(BChild()))  # E: Revealed type is 'foo.B'
[builtins fixtures/classmethod.pyi]
[out]

[case testSubtypeWithMoreOverloadsThanSupertypeSucceeds]
from foo import *
[file foo.pyi]
from typing import overload


class X: pass
class Y: pass
class Z: pass


class A:
    @overload
    def f(self, x: X) -> X: pass
    @overload
    def f(self, y: Y) -> Y: pass

class B(A):
    @overload
    def f(self, x: X) -> X: pass
    @overload
    def f(self, y: Y) -> Y: pass
    @overload
    def f(self, z: Z) -> Z: pass
[builtins fixtures/classmethod.pyi]
[out]

[case testSubtypeOverloadCoveringMultipleSupertypeOverloadsSucceeds]
from foo import *
[file foo.pyi]
from typing import overload


class A: pass
class B(A): pass
class C(A): pass
class D: pass


class Super:
    @overload
    def foo(self, a: B) -> C: pass
    @overload
    def foo(self, a: C) -> A: pass
    @overload
    def foo(self, a: D) -> D: pass

class Sub(Super):
    @overload
    def foo(self, a: A) -> C: pass
    @overload
    def foo(self, a: D) -> D: pass
[builtins fixtures/classmethod.pyi]
[out]

[case testSubtypeOverloadWithOverlappingArgumentsButWrongReturnType]
from foo import *
[file foo.pyi]
from typing import overload


class A: pass
class B(A): pass
class C: pass


class Super:
    @overload
    def foo(self, a: A) -> A: pass
    @overload
    def foo(self, a: C) -> C: pass

class Sub(Super):
    @overload  # E: Signature of "foo" incompatible with supertype "Super"
    def foo(self, a: A) -> A: pass
    @overload
    def foo(self, a: B) -> C: pass  # E: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader
    @overload
    def foo(self, a: C) -> C: pass
[builtins fixtures/classmethod.pyi]
[out]

[case testTypeTypeOverlapsWithObjectAndType]
from foo import *
[file foo.pyi]
from typing import Type, overload

class User: pass

@overload
def f(a: Type[User]) -> int: pass  # E: Overloaded function signatures 1 and 2 overlap with incompatible return types
@overload
def f(a: object) -> str: pass

@overload
def g(a: Type[User]) -> int: pass  # E: Overloaded function signatures 1 and 2 overlap with incompatible return types
@overload
def g(a: type) -> str: pass
[builtins fixtures/classmethod.pyi]
[out]

[case testTypeOverlapsWithObject]
from foo import *
[file foo.pyi]
from typing import Type, overload

class User: pass

@overload
def f(a: type) -> int: pass  # E: Overloaded function signatures 1 and 2 overlap with incompatible return types
@overload
def f(a: object) -> str: pass
[builtins fixtures/classmethod.pyi]
[out]

[case testTypeConstructorReturnsTypeType]
class User:
    @classmethod
    def test_class_method(cls) -> int: pass
    @staticmethod
    def test_static_method() -> str: pass
    def test_instance_method(self) -> None: pass

u = User()

reveal_type(type(u))  # E: Revealed type is 'Type[__main__.User]'
reveal_type(type(u).test_class_method())  # E: Revealed type is 'builtins.int'
reveal_type(type(u).test_static_method())  # E: Revealed type is 'builtins.str'
type(u).test_instance_method()  # E: Too few arguments for "test_instance_method" of "User"
[builtins fixtures/classmethod.pyi]
[out]

[case testObfuscatedTypeConstructorReturnsTypeType]
from typing import TypeVar
class User: pass

f1 = type

A = TypeVar('A')
def f2(func: A) -> A:
    return func

u = User()

reveal_type(f1(u))  # E: Revealed type is 'Type[__main__.User]'
reveal_type(f2(type)(u))  # E: Revealed type is 'Type[__main__.User]'
[builtins fixtures/classmethod.pyi]
[out]

[case testTypeConstructorLookalikeFails]
class User: pass

def fake1(a: object) -> type:
    return User
def fake2(a: int) -> type:
    return User

reveal_type(type(User()))  # E: Revealed type is 'Type[__main__.User]'
reveal_type(fake1(User()))  # E: Revealed type is 'builtins.type'
reveal_type(fake2(3))  # E: Revealed type is 'builtins.type'
[builtins fixtures/classmethod.pyi]
[out]

[case testOtherTypeConstructorsSucceed]
def foo(self) -> int: return self.attr

User = type('User', (object,), {'foo': foo, 'attr': 3})
reveal_type(User)  # E: Revealed type is 'builtins.type'
[builtins fixtures/args.pyi]
[out]

[case testTypeTypeComparisonWorks]
class User: pass

User == User
User == type(User())
type(User()) == User
type(User()) == type(User())

User != User
User != type(User())
type(User()) != User
type(User()) != type(User())

int == int
int == type(3)
type(3) == int
type(3) == type(3)

int != int
int != type(3)
type(3) != int
type(3) != type(3)

User is User
User is type(User)
type(User) is User
type(User) is type(User)

int is int
int is type(3)
type(3) is int
type(3) is type(3)

int.__eq__(int)
int.__eq__(3, 4)
[builtins fixtures/args.pyi]
[out]
main:33: error: Too few arguments for "__eq__" of "int"
main:33: error: Unsupported operand types for == ("int" and "Type[int]")

[case testMroSetAfterError]
class C(str, str):
    foo = 0
    bar = foo
[out]
main:1: error: Duplicate base class "str"

[case testCannotDetermineMro]
class A: pass
class B(A): pass
class C(B): pass
class D(A, B): pass # E: Cannot determine consistent method resolution order (MRO) for "D"
class E(C, D): pass # E: Cannot determine consistent method resolution order (MRO) for "E"

[case testInconsistentMroLocalRef]
class A: pass
class B(object, A): # E: Cannot determine consistent method resolution order (MRO) for "B"
    def readlines(self): pass
    __iter__ = readlines

[case testDynamicMetaclass]
class C(metaclass=int()):  # E: Dynamic metaclass not supported for 'C'
    pass

[case testDynamicMetaclassCrash]
class C(metaclass=int().x):  # E: Dynamic metaclass not supported for 'C'
    pass

[case testVariableSubclass]
class A:
    a = 1  # type: int
class B(A):
    a = 1
[out]

[case testVariableSubclassAssignMismatch]
class A:
    a = 1  # type: int
class B(A):
    a = "a"
[out]
main:4: error: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "int")

[case testVariableSubclassAssignment]
class A:
    a = None  # type: int
class B(A):
    def __init__(self) -> None:
        self.a = "a"
[out]
main:5: error: Incompatible types in assignment (expression has type "str", variable has type "int")

[case testVariableSubclassTypeOverwrite]
class A:
    a = None  # type: int
class B(A):
    a = None  # type: str
class C(B):
    a = "a"
[out]
main:4: error: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "int")

[case testVariableSubclassTypeOverwriteImplicit]
class A:
    a = 1
class B(A):
    a = None  # type: str
[out]
main:4: error: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "int")

[case testVariableSuperUsage]
class A:
    a = []  # type: list
class B(A):
    a = [1, 2]
class C(B):
    a = B.a + [3]
[builtins fixtures/list.pyi]
[out]

[case testClassAllBases]
from typing import Union
class A:
    a = None  # type: Union[int, str]
class B(A):
    a = 1
class C(B):
    a = "str"
class D(A):
    a = "str"
[out]
main:7: error: Incompatible types in assignment (expression has type "str", base class "B" defined the type as "int")

[case testVariableTypeVar]
from typing import TypeVar, Generic
T = TypeVar('T')
class A(Generic[T]):
    a = None  # type: T
class B(A[int]):
    a = 1

[case testVariableTypeVarInvalid]
from typing import TypeVar, Generic
T = TypeVar('T')
class A(Generic[T]):
    a = None  # type: T
class B(A[int]):
    a = "abc"
[out]
main:6: error: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "int")

[case testVariableTypeVarIndirectly]
from typing import TypeVar, Generic
T = TypeVar('T')
class A(Generic[T]):
    a = None  # type: T
class B(A[int]):
    pass
class C(B):
    a = "a"
[out]
main:8: error: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "int")

[case testVariableTypeVarList]
from typing import List, TypeVar, Generic
T = TypeVar('T')
class A(Generic[T]):
    a = None  # type: List[T]
    b = None  # type: List[T]
class B(A[int]):
    a = [1]
    b = ['']
[builtins fixtures/list.pyi]
[out]
main:8: error: List item 0 has incompatible type "str"; expected "int"

[case testVariableMethod]
class A:
    def a(self) -> None: pass
    b = 1
class B(A):
    a = 1
    def b(self) -> None: pass
[out]
main:5: error: Incompatible types in assignment (expression has type "int", base class "A" defined the type as "Callable[[A], None]")
main:6: error: Signature of "b" incompatible with supertype "A"

[case testVariableProperty]
class A:
    @property
    def a(self) -> bool: pass
class B(A):
    a = None  # type: bool
class C(A):
    a = True
class D(A):
    a = 1
[builtins fixtures/property.pyi]
[out]
main:9: error: Incompatible types in assignment (expression has type "int", base class "A" defined the type as "bool")

[case testVariableOverwriteAny]
from typing import Any
class A:
    a = 1
class B(A):
    a = 'x'  # type: Any
[out]

[case testInstanceMethodOverwrite]
class B():
    def n(self, a: int) -> None: pass
class C(B):
    def m(self, a: int) -> None: pass
    n = m
[out]

[case testInstanceMethodOverwriteError]
class B():
    def n(self, a: int) -> None: pass
class C(B):
    def m(self, a: str) -> None: pass
    n = m
[out]
main:5: error: Incompatible types in assignment (expression has type "Callable[[str], None]", base class "B" defined the type as "Callable[[int], None]")

[case testInstanceMethodOverwriteTypevar]
from typing import Generic, TypeVar
T = TypeVar("T")
class B(Generic[T]):
    def n(self, a: T) -> None: pass
class C(B[int]):
    def m(self, a: int) -> None: pass
    n = m

[case testInstanceMethodOverwriteTwice]
class I:
    def foo(self) -> None: pass
class A(I):
    def foo(self) -> None: pass
class B(A):
    def bar(self) -> None: pass
    foo = bar
class C(B):
    def bar(self) -> None: pass
    foo = bar

[case testClassMethodOverwrite]
class B():
    @classmethod
    def n(self, a: int) -> None: pass
class C(B):
    @classmethod
    def m(self, a: int) -> None: pass
    n = m
[builtins fixtures/classmethod.pyi]
[out]

[case testClassMethodOverwriteError]
class B():
    @classmethod
    def n(self, a: int) -> None: pass
class C(B):
    @classmethod
    def m(self, a: str) -> None: pass
    n = m
[builtins fixtures/classmethod.pyi]
[out]
main:7: error: Incompatible types in assignment (expression has type "Callable[[str], None]", base class "B" defined the type as "Callable[[int], None]")

[case testClassSpec]
from typing import Callable
class A():
    b = None  # type: Callable[[A, int], int]
class B(A):
    def c(self, a: int) -> int: pass
    b = c

[case testClassSpecError]
from typing import Callable
class A():
    b = None  # type: Callable[[A, int], int]
class B(A):
    def c(self, a: str) -> int: pass
    b = c
[out]
main:6: error: Incompatible types in assignment (expression has type "Callable[[str], int]", base class "A" defined the type as "Callable[[int], int]")

[case testClassStaticMethod]
class A():
    @staticmethod
    def a(a: int) -> None: pass
class B(A):
    @staticmethod
    def b(a: str) -> None: pass
    a = b
[builtins fixtures/staticmethod.pyi]
[out]
main:7: error: Incompatible types in assignment (expression has type "Callable[[str], None]", base class "A" defined the type as "Callable[[int], None]")

[case testClassStaticMethodIndirect]
class A():
    @staticmethod
    def a(a: int) -> None: pass
    c = a
class B(A):
    @staticmethod
    def b(a: str) -> None: pass
    c = b
[builtins fixtures/staticmethod.pyi]
[out]
main:8: error: Incompatible types in assignment (expression has type "Callable[[str], None]", base class "A" defined the type as "Callable[[int], None]")

[case testClassStaticMethodSubclassing]
class A:
    @staticmethod
    def a() -> None: pass

    def b(self) -> None: pass

    @staticmethod
    def c() -> None: pass

class B(A):
    def a(self) -> None: pass  # E: Signature of "a" incompatible with supertype "A"

    @classmethod
    def b(cls) -> None: pass

    @staticmethod
    def c() -> None: pass
[builtins fixtures/classmethod.pyi]

[case testTempNode]
class A():
    def a(self) -> None: pass
class B(A):
    def b(self) -> None: pass
    a = c = b

[case testListObject]
from typing import List
class A:
    x = []  # type: List[object]
class B(A):
    x = [1]
[builtins fixtures/list.pyi]

[case testClassMemberObject]
class A:
    x = object()
class B(A):
    x = 1
class C(B):
    x = ''
[out]
main:6: error: Incompatible types in assignment (expression has type "str", base class "B" defined the type as "int")

[case testSlots]
class A:
    __slots__ = ("a")
class B(A):
    __slots__ = ("a", "b")

[case testClassOrderOfError]
class A:
    x = 1
class B(A):
    x = "a"
class C(B):
    x = object()
[out]
main:4: error: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "int")
main:6: error: Incompatible types in assignment (expression has type "object", base class "B" defined the type as "str")

[case testClassOneErrorPerLine]
class A:
  x = 1
class B(A):
  x = ""
  x = 1.0
[out]
main:4: error: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "int")
main:5: error: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "int")

[case testClassIgnoreType]
class A:
    x = 0
class B(A):
    x = ''  # type: ignore
class C(B):
    x = ''
[out]

[case testInvalidMetaclassStructure]
class X(type): pass
class Y(type): pass
class A(metaclass=X): pass
class B(A, metaclass=Y): pass  # E: Inconsistent metaclass structure for 'B'

[case testMetaclassNoTypeReveal]
class M:
    x = 0  # type: int

class A(metaclass=M): pass  # E: Metaclasses not inheriting from 'type' are not supported

A.x  # E: "Type[A]" has no attribute "x"

[case testMetaclassTypeReveal]
from typing import Type
class M(type):
    x = 0  # type: int

class A(metaclass=M): pass

def f(TA: Type[A]):
    reveal_type(TA)  # E: Revealed type is 'Type[__main__.A]'
    reveal_type(TA.x)  # E: Revealed type is 'builtins.int'

[case testSubclassMetaclass]
class M1(type):
    x = 0
class M2(M1): pass
class C(metaclass=M2):
    pass
reveal_type(C.x) # E: Revealed type is 'builtins.int'

[case testMetaclassSubclass]
from typing import Type
class M(type):
    x = 0  # type: int

class A(metaclass=M): pass
class B(A): pass

def f(TB: Type[B]):
    reveal_type(TB)  # E: Revealed type is 'Type[__main__.B]'
    reveal_type(TB.x)  # E: Revealed type is 'builtins.int'

[case testMetaclassIterable]
from typing import Iterable, Iterator

class ImplicitMeta(type):
    def __iter__(self) -> Iterator[int]: yield 1

class Implicit(metaclass=ImplicitMeta): pass

for _ in Implicit: pass
reveal_type(list(Implicit))  # E: Revealed type is 'builtins.list[builtins.int*]'

class ExplicitMeta(type, Iterable[int]):
    def __iter__(self) -> Iterator[int]: yield 1

class Explicit(metaclass=ExplicitMeta): pass
for _ in Explicit: pass
reveal_type(list(Explicit))  # E: Revealed type is 'builtins.list[builtins.int*]'

[builtins fixtures/list.pyi]

[case testMetaclassTuple]
from typing import Tuple

class M(Tuple[int]): pass
class C(metaclass=M): pass  # E: Invalid metaclass 'M'

[builtins fixtures/tuple.pyi]

[case testMetaclassOperatorBeforeReversed]
class X:
    def __radd__(self, x: int) -> int: ...

class Meta(type):
    def __add__(cls, x: X) -> str: ...

class Concrete(metaclass=Meta):
    pass

reveal_type(Concrete + X())  # E: Revealed type is 'builtins.str'
Concrete + "hello"  # E: Unsupported operand types for + ("Type[Concrete]" and "str")

[case testMetaclassOperatorTypeVar]
from typing import Type, TypeVar

class MetaClass(type):
    def __mul__(cls, other: int) -> str:
        return ""

class Test(metaclass=MetaClass):
    pass

S = TypeVar("S", bound=Test)

def f(x: Type[Test]) -> str:
    return x * 0
def g(x: Type[S]) -> str:
    return reveal_type(x * 0)  # E: Revealed type is 'builtins.str'

[case testMetaclassGetitem]
class M(type):
    def __getitem__(self, key) -> int: return 1

class A(metaclass=M): pass

reveal_type(A[M])  # E: Revealed type is 'builtins.int'

[case testMetaclassSelfType]
from typing import TypeVar, Type

class M(type): pass
T = TypeVar('T')

class M1(M):
    def foo(cls: Type[T]) -> T: ...

class A(metaclass=M1): pass
reveal_type(A.foo())  # E: Revealed type is '__main__.A*'

[case testMetaclassAndSkippedImport]
# flags: --ignore-missing-imports
from missing import M
class A(metaclass=M):
    y = 0
reveal_type(A.y) # E: Revealed type is 'builtins.int'
A.x # E: "Type[A]" has no attribute "x"

[case testAnyMetaclass]
from typing import Any
M = None  # type: Any
class A(metaclass=M):
    y = 0
reveal_type(A.y) # E: Revealed type is 'builtins.int'
A.x # E: "Type[A]" has no attribute "x"

[case testInvalidVariableAsMetaclass]
from typing import Any
M = 0  # type: int
MM = 0
class A(metaclass=M): # E: Invalid metaclass 'M'
    y = 0
class B(metaclass=MM): # E: Invalid metaclass 'MM'
    y = 0
reveal_type(A.y) # E: Revealed type is 'builtins.int'
A.x # E: "Type[A]" has no attribute "x"

[case testAnyAsBaseOfMetaclass]
from typing import Any, Type
M = None  # type: Any
class MM(M): pass

class A(metaclass=MM):
    y = 0
    @classmethod
    def f(cls) -> None: pass
    def g(self) -> None: pass

def h(a: Type[A], b: Type[object]) -> None:
    h(a, a)
    h(b, a) # E: Argument 1 to "h" has incompatible type "Type[object]"; expected "Type[A]"
    a.f(1) # E: Too many arguments for "f" of "A"
    reveal_type(a.y) # E: Revealed type is 'builtins.int'

x = A # type: MM
reveal_type(A.y) # E: Revealed type is 'builtins.int'
reveal_type(A.x) # E: Revealed type is 'Any'
A.f(1) # E: Too many arguments for "f" of "A"
A().g(1) # E: Too many arguments for "g" of "A"
[builtins fixtures/classmethod.pyi]

[case testMetaclassTypeCallable]
class M(type):
    x = 5

class A(metaclass=M): pass
reveal_type(type(A).x)  # E: Revealed type is 'builtins.int'

[case testMetaclassStrictSupertypeOfTypeWithClassmethods]
from typing import Type, TypeVar
TA = TypeVar('TA', bound='A')
TTA = TypeVar('TTA', bound='Type[A]')
TM = TypeVar('TM', bound='M')

class M(type):
    def g1(cls: 'Type[A]') -> A: pass #  E: The erased type of self 'Type[__main__.A]' is not a supertype of its class '__main__.M'
    def g2(cls: Type[TA]) -> TA: pass #  E: The erased type of self 'Type[__main__.A]' is not a supertype of its class '__main__.M'
    def g3(cls: TTA) -> TTA: pass #  E: The erased type of self 'Type[__main__.A]' is not a supertype of its class '__main__.M'
    def g4(cls: TM) -> TM: pass
m: M

class A(metaclass=M):
    def foo(self): pass

reveal_type(A.g1)  # E: Revealed type is 'def () -> __main__.A'
reveal_type(A.g2)  # E: Revealed type is 'def () -> __main__.A*'
reveal_type(A.g3)  # E: Revealed type is 'def () -> def () -> __main__.A'
reveal_type(A.g4)  # E: Revealed type is 'def () -> def () -> __main__.A'

class B(metaclass=M):
    def foo(self): pass

B.g1  # Should be error: Argument 0 to "g1" of "M" has incompatible type "B"; expected "Type[A]"
B.g2  # Should be error: Argument 0 to "g2" of "M" has incompatible type "B"; expected "Type[TA]"
B.g3  # Should be error: Argument 0 to "g3" of "M" has incompatible type "B"; expected "TTA"
reveal_type(B.g4)  # E: Revealed type is 'def () -> def () -> __main__.B'

# 4 examples of unsoundness - instantiation, classmethod, staticmethod and ClassVar:

ta: Type[A] = m  # E: Incompatible types in assignment (expression has type "M", variable has type "Type[A]")
a: A = ta()
reveal_type(ta.g1)  # E: Revealed type is 'def () -> __main__.A'
reveal_type(ta.g2)  # E: Revealed type is 'def () -> __main__.A*'
reveal_type(ta.g3)  # E: Revealed type is 'def () -> Type[__main__.A]'
reveal_type(ta.g4)  # E: Revealed type is 'def () -> Type[__main__.A]'

x: M = ta
x.g1  # should be error: Argument 0 to "g1" of "M" has incompatible type "M"; expected "Type[A]"
x.g2  # should be error: Argument 0 to "g2" of "M" has incompatible type "M"; expected "Type[TA]"
x.g3  # should be error: Argument 0 to "g3" of "M" has incompatible type "M"; expected "TTA"
reveal_type(x.g4)  # E: Revealed type is 'def () -> __main__.M*'

def r(ta: Type[TA], tta: TTA) -> None:
    x: M = ta
    y: M = tta

class Class(metaclass=M):
    @classmethod
    def f1(cls: Type[Class]) -> None: pass
    @classmethod
    def f2(cls: M) -> None: pass
cl: Type[Class] = m  # E: Incompatible types in assignment (expression has type "M", variable has type "Type[Class]")
reveal_type(cl.f1)  # E: Revealed type is 'def ()'
reveal_type(cl.f2)  # E: Revealed type is 'def ()'
x1: M = cl

class Static(metaclass=M):
    @staticmethod
    def f() -> None: pass
s: Type[Static] = m  # E: Incompatible types in assignment (expression has type "M", variable has type "Type[Static]")
reveal_type(s.f)  # E: Revealed type is 'def ()'
x2: M = s

from typing import ClassVar
class Cvar(metaclass=M):
    x = 1  # type: ClassVar[int]
cv: Type[Cvar] = m  # E: Incompatible types in assignment (expression has type "M", variable has type "Type[Cvar]")
cv.x
x3: M = cv

[builtins fixtures/classmethod.pyi]

[case testMetaclassOverloadResolution]
from typing import Type, overload
class A: pass

class EM(type): pass
class E(metaclass=EM): pass

class EM1(type): pass
class E1(metaclass=EM1): pass

@overload
def f(x: EM) -> int: ...
@overload
def f(x: EM1) -> A: ...
@overload
def f(x: str) -> str: ...
def f(x: object) -> object: return ''

e: EM
reveal_type(f(e))  # E: Revealed type is 'builtins.int'

et: Type[E]
reveal_type(f(et))  # E: Revealed type is 'builtins.int'

e1: EM1
reveal_type(f(e1))  # E: Revealed type is '__main__.A'

e1t: Type[E1]
reveal_type(f(e1t))  # E: Revealed type is '__main__.A'

reveal_type(f(''))  # E: Revealed type is 'builtins.str'

[case testTypeCErasesGenericsFromC]
from typing import Generic, Type, TypeVar

K = TypeVar('K')
V = TypeVar('V')
class ExampleDict(Generic[K, V]): ...

D = TypeVar('D')
def mkdict(dict_type: Type[D]) -> D: ...
reveal_type(mkdict(ExampleDict))  # E: Revealed type is '__main__.ExampleDict*[Any, Any]'

[case testTupleForwardBase]
from m import a
a[0]()  # E: "int" not callable

[file m.py]
from typing import Tuple
a = None # type: A
class A(Tuple[int, str]): pass
[builtins fixtures/tuple.pyi]

-- Synthetic types crashes
-- -----------------------

[case testCrashOnSelfRecursiveNamedTupleVar]
from typing import NamedTuple

N = NamedTuple('N', [('x', N)]) # E: Recursive types not fully supported yet, nested types replaced with "Any"
n: N
[out]

[case testCrashOnSelfRecursiveTypedDictVar]
from mypy_extensions import TypedDict

A = TypedDict('A', {'a': 'A'})  # type: ignore
a: A
[builtins fixtures/isinstancelist.pyi]
[out]

[case testCrashInJoinOfSelfRecursiveNamedTuples]
from typing import NamedTuple

class N(NamedTuple): # type: ignore
    x: N
class M(NamedTuple): # type: ignore
    x: M

n: N
m: M
lst = [n, m]
[builtins fixtures/isinstancelist.pyi]

[case testCorrectJoinOfSelfRecursiveTypedDicts]
from mypy_extensions import TypedDict

class N(TypedDict):
    x: N
class M(TypedDict):
    x: M

n: N
m: M
lst = [n, m]
reveal_type(lst[0]['x'])  # E: Revealed type is 'TypedDict('__main__.N', {'x': Any})'
[builtins fixtures/isinstancelist.pyi]
[out]
main:3: error: Recursive types not fully supported yet, nested types replaced with "Any"
main:5: error: Recursive types not fully supported yet, nested types replaced with "Any"

[case testCrashInForwardRefToNamedTupleWithIsinstance]
from typing import Dict, NamedTuple

NameDict = Dict[str, 'NameInfo']
class NameInfo(NamedTuple):
    ast: bool

def parse_ast(name_dict: NameDict) -> None:
    if isinstance(name_dict[''], int):
        pass
    reveal_type(name_dict['test']) # E: Revealed type is 'Tuple[builtins.bool, fallback=__main__.NameInfo]'
[builtins fixtures/isinstancelist.pyi]
[out]

[case testCrashInForwardRefToTypedDictWithIsinstance]
from mypy_extensions import TypedDict
from typing import Dict

NameDict = Dict[str, 'NameInfo']
class NameInfo(TypedDict):
    ast: bool

def parse_ast(name_dict: NameDict) -> None:
    if isinstance(name_dict[''], int):
        pass
    reveal_type(name_dict['']['ast'])  # E: Revealed type is 'builtins.bool'
[builtins fixtures/isinstancelist.pyi]
[out]

[case testCorrectIsinstanceInForwardRefToNewType]
from typing import Dict, NewType

NameDict = Dict[str, 'NameInfo']
class Base:
    ast: bool
NameInfo = NewType('NameInfo', Base)

def parse_ast(name_dict: NameDict) -> None:
    if isinstance(name_dict[''], int):
        pass
    x = name_dict['']
    reveal_type(x) # E: Revealed type is '__main__.NameInfo*'
    x = NameInfo(Base()) # OK
    x = Base() # E: Incompatible types in assignment (expression has type "Base", variable has type "NameInfo")
[builtins fixtures/isinstancelist.pyi]
[out]

[case testNoCrashForwardRefToBrokenDoubleNewType]
from typing import Any, Dict, List, NewType

Foo = NewType('NotFoo', int) # E: String argument 1 'NotFoo' to NewType(...) does not match variable name 'Foo'
Foos = NewType('Foos', List[Foo]) # type: ignore

def frob(foos: Dict[Any, Foos]) -> None:
    foo = foos.get(1)
    dict(foo)
[builtins fixtures/dict.pyi]
[out]

[case testNoCrashForwardRefToBrokenDoubleNewTypeClass]
from typing import Any, Dict, List, NewType

Foo = NewType('NotFoo', int) # type: ignore
Foos = NewType('Foos', List[Foo]) # type: ignore

x: C
class C:
    def frob(self, foos: Dict[Any, Foos]) -> None:
        foo = foos.get(1)
        dict(foo)

reveal_type(x.frob) # E: Revealed type is 'def (foos: builtins.dict[Any, __main__.Foos])'
[builtins fixtures/dict.pyi]
[out]

[case testNewTypeFromForwardNamedTuple]
from typing import NewType, NamedTuple, Tuple

NT = NewType('NT', N)
class N(NamedTuple):
    x: int

x: NT = N(1) # E: Incompatible types in assignment (expression has type "N", variable has type "NT")
x = NT(N(1))
[out]

[case testNewTypeFromForwardTypedDict]
from typing import NewType, Tuple
from mypy_extensions import TypedDict

NT = NewType('NT', N) # E: Argument 2 to NewType(...) must be subclassable (got TypedDict('__main__.N', {'x': builtins.int}))
class N(TypedDict):
    x: int
[builtins fixtures/dict.pyi]
[out]

[case testCorrectAttributeInForwardRefToNamedTuple]
from typing import NamedTuple
proc: Process
reveal_type(proc.state)  # E: Revealed type is 'builtins.int'

def get_state(proc: 'Process') -> int:
    return proc.state
class Process(NamedTuple):
     state: int
[out]

[case testCorrectItemTypeInForwardRefToTypedDict]
from mypy_extensions import TypedDict
proc: Process
reveal_type(proc['state'])  # E: Revealed type is 'builtins.int'

def get_state(proc: 'Process') -> int:
    return proc['state']
class Process(TypedDict):
     state: int
[builtins fixtures/isinstancelist.pyi]
[out]

[case testCorrectDoubleForwardNamedTuple]
from typing import NamedTuple

x: A
class A(NamedTuple):
    one: 'B'
    other: int
class B(NamedTuple):
    attr: str
y: A
y = x
reveal_type(x.one.attr)  # E: Revealed type is 'builtins.str'
[out]

[case testCrashOnDoubleForwardTypedDict]
from mypy_extensions import TypedDict

x: A
class A(TypedDict):
    one: 'B'
    other: int
class B(TypedDict):
    attr: str

reveal_type(x['one']['attr'])  # E: Revealed type is 'builtins.str'
[builtins fixtures/isinstancelist.pyi]
[out]

[case testCrashOnForwardUnionOfNamedTuples]
from typing import Union, NamedTuple

Node = Union['Foo', 'Bar']
class Foo(NamedTuple):
    x: int
class Bar(NamedTuple):
    x: int

def foo(node: Node) -> int:
    x = node
    reveal_type(node) # E: Revealed type is 'Union[Tuple[builtins.int, fallback=__main__.Foo], Tuple[builtins.int, fallback=__main__.Bar]]'
    return x.x
[out]

[case testCrashOnForwardUnionOfTypedDicts]
from mypy_extensions import TypedDict
from typing import Union

NodeType = Union['Foo', 'Bar']
class Foo(TypedDict):
    x: int
class Bar(TypedDict):
    x: int

def foo(node: NodeType) -> int:
    x = node
    return x['x']
[builtins fixtures/isinstancelist.pyi]
[out]

[case testSupportForwardUnionOfNewTypes]
from typing import Union, NewType
x: Node
reveal_type(x.x) # E: Revealed type is 'builtins.int'

class A:
    x: int
class B:
    x: int

Node = Union['Foo', 'Bar']
Foo = NewType('Foo', A)
Bar = NewType('Bar', B)

def foo(node: Node) -> Node:
    x = node
    return Foo(A())
[out]

[case testForwardReferencesInNewTypeMRORecomputed]
from typing import NewType
x: Foo
Foo = NewType('Foo', B)
class A:
    x: int
class B(A):
    pass

reveal_type(x.x) # E: Revealed type is 'builtins.int'
[out]

[case testCrashOnComplexNamedTupleUnionProperty]
from typing import NamedTuple, Union

x: AOrB
AOrB = Union['A', 'B']
class A(NamedTuple):
    x: int

class B(object):
    def __init__(self, a: AOrB) -> None:
        self.a = a
    @property
    def x(self) -> int:
        return self.a.x

reveal_type(x.x) # E: Revealed type is 'builtins.int'
[builtins fixtures/property.pyi]
[out]

[case testCorrectIsinstanceWithForwardUnion]
from typing import Union, NamedTuple

ForwardUnion = Union['TP', int]
class TP(NamedTuple('TP', [('x', int)])): pass

def f(x: ForwardUnion) -> None:
  reveal_type(x)  # E: Revealed type is 'Union[Tuple[builtins.int, fallback=__main__.TP], builtins.int]'
  if isinstance(x, TP):
    reveal_type(x)  # E: Revealed type is 'Tuple[builtins.int, fallback=__main__.TP]'
[builtins fixtures/isinstance.pyi]
[out]

[case testCrashInvalidArgsSyntheticClassSyntax]
from typing import List, NamedTuple
from mypy_extensions import TypedDict
class TD(TypedDict):
    x: List[int, str] # E: "list" expects 1 type argument, but 2 given
class NM(NamedTuple):
    x: List[int, str] # E: "list" expects 1 type argument, but 2 given

# These two should never crash, reveals are in the next test
TD({'x': []})
NM(x=[])
[builtins fixtures/dict.pyi]
[out]

[case testCrashInvalidArgsSyntheticClassSyntaxReveals]
from typing import List, NamedTuple
from mypy_extensions import TypedDict
class TD(TypedDict):
    x: List[int, str] # E: "list" expects 1 type argument, but 2 given
class NM(NamedTuple):
    x: List[int, str] # E: "list" expects 1 type argument, but 2 given

x: TD
x1 = TD({'x': []})
y: NM
y1 = NM(x=[])
reveal_type(x) # E: Revealed type is 'TypedDict('__main__.TD', {'x': builtins.list[Any]})'
reveal_type(x1) # E: Revealed type is 'TypedDict('__main__.TD', {'x': builtins.list[Any]})'
reveal_type(y) # E: Revealed type is 'Tuple[builtins.list[Any], fallback=__main__.NM]'
reveal_type(y1) # E: Revealed type is 'Tuple[builtins.list[Any], fallback=__main__.NM]'
[builtins fixtures/dict.pyi]
[out]

[case testCrashInvalidArgsSyntheticFunctionSyntax]
from typing import List, NewType, NamedTuple
from mypy_extensions import TypedDict
TD = TypedDict('TD', {'x': List[int, str]}) # E: "list" expects 1 type argument, but 2 given
NM = NamedTuple('NM', [('x', List[int, str])]) # E: "list" expects 1 type argument, but 2 given
NT = NewType('NT', List[int, str]) # E: "list" expects 1 type argument, but 2 given

# These three should not crash
TD({'x': []})
NM(x=[])
NT([])
[builtins fixtures/dict.pyi]
[out]

[case testCrashForwardSyntheticClassSyntax]
from typing import NamedTuple
from mypy_extensions import TypedDict
class A1(NamedTuple):
    b: 'B'
    x: int
class A2(TypedDict):
    b: 'B'
    x: int
class B:
    pass
x: A1
y: A2
reveal_type(x.b) # E: Revealed type is '__main__.B'
reveal_type(y['b']) # E: Revealed type is '__main__.B'
[builtins fixtures/dict.pyi]
[out]

[case testCrashForwardSyntheticFunctionSyntax]
from typing import NamedTuple
from mypy_extensions import TypedDict
A1 = NamedTuple('A1', [('b', 'B'), ('x', int)])
A2 = TypedDict('A2', {'b': 'B', 'x': int})
class B:
    pass
x: A1
y: A2
reveal_type(x.b) # E: Revealed type is '__main__.B'
reveal_type(y['b']) # E: Revealed type is '__main__.B'
[builtins fixtures/dict.pyi]
[out]

-- Special support for six
-- -----------------------

[case testSixMetaclass]
import six
class M(type):
    x = 5
class A(six.with_metaclass(M)): pass
@six.add_metaclass(M)
class B: pass
reveal_type(type(A).x)  # E: Revealed type is 'builtins.int'
reveal_type(type(B).x)  # E: Revealed type is 'builtins.int'

[case testSixMetaclass_python2]
import six
class M(type):
    x = 5
class A(six.with_metaclass(M)): pass
@six.add_metaclass(M)
class B: pass
reveal_type(type(A).x)  # E: Revealed type is 'builtins.int'
reveal_type(type(B).x)  # E: Revealed type is 'builtins.int'

[case testFromSixMetaclass]
from six import with_metaclass, add_metaclass
class M(type):
    x = 5
class A(with_metaclass(M)): pass
@add_metaclass(M)
class B: pass
reveal_type(type(A).x)  # E: Revealed type is 'builtins.int'
reveal_type(type(B).x)  # E: Revealed type is 'builtins.int'

[case testSixMetaclassImportFrom]
import six
from metadefs import M
class A(six.with_metaclass(M)): pass
@six.add_metaclass(M)
class B: pass
reveal_type(type(A).x)  # E: Revealed type is 'builtins.int'
reveal_type(type(B).x)  # E: Revealed type is 'builtins.int'
[file metadefs.py]
class M(type):
    x = 5

[case testSixMetaclassImport]
import six
import metadefs
class A(six.with_metaclass(metadefs.M)): pass
@six.add_metaclass(metadefs.M)
class B: pass
reveal_type(type(A).x)  # E: Revealed type is 'builtins.int'
reveal_type(type(B).x)  # E: Revealed type is 'builtins.int'
[file metadefs.py]
class M(type):
    x = 5

[case testSixMetaclassAndBase]
from typing import Iterable, Iterator
import six
class M(type, Iterable[int]):
    x = 5
    def __iter__(self) -> Iterator[int]: ...
class A:
    def foo(self): pass
class B:
    def bar(self): pass
class C1(six.with_metaclass(M, A)): pass
@six.add_metaclass(M)
class D1(A): pass
class C2(six.with_metaclass(M, A, B)): pass
@six.add_metaclass(M)
class D2(A, B): pass
reveal_type(type(C1).x)  # E: Revealed type is 'builtins.int'
reveal_type(type(D1).x)  # E: Revealed type is 'builtins.int'
reveal_type(type(C2).x)  # E: Revealed type is 'builtins.int'
reveal_type(type(D2).x)  # E: Revealed type is 'builtins.int'
C1().foo()
D1().foo()
C1().bar()  # E: "C1" has no attribute "bar"
D1().bar()  # E: "D1" has no attribute "bar"
for x in C1: reveal_type(x)  # E: Revealed type is 'builtins.int*'
for x in C2: reveal_type(x)  # E: Revealed type is 'builtins.int*'
C2().foo()
D2().foo()
C2().bar()
D2().bar()
C2().baz()  # E: "C2" has no attribute "baz"
D2().baz()  # E: "D2" has no attribute "baz"

[case testSixMetaclassGenerics]
from typing import Generic, GenericMeta, TypeVar
import six
class DestroyableMeta(type):
    pass
class Destroyable(six.with_metaclass(DestroyableMeta)):
    pass
T_co = TypeVar('T_co', bound='Destroyable', covariant=True)
class ArcMeta(GenericMeta, DestroyableMeta):
    pass
class Arc(six.with_metaclass(ArcMeta, Generic[T_co], Destroyable)):
    pass
@six.add_metaclass(ArcMeta)
class Arc1(Generic[T_co], Destroyable):
    pass
class MyDestr(Destroyable):
    pass
reveal_type(Arc[MyDestr]())  # E: Revealed type is '__main__.Arc[__main__.MyDestr*]'
reveal_type(Arc1[MyDestr]())  # E: Revealed type is '__main__.Arc1[__main__.MyDestr*]'
[builtins fixtures/bool.pyi]
[typing fixtures/typing-full.pyi]

[case testSixMetaclassErrors]
import six
class M(type): pass
class A(object): pass
def f() -> type: return M
class C1(six.with_metaclass(M), object): pass  # E: Invalid base class
class C2(C1, six.with_metaclass(M)): pass  # E: Invalid base class
class C3(six.with_metaclass(A)): pass  # E: Metaclasses not inheriting from 'type' are not supported
@six.add_metaclass(A)  # E: Argument 1 to "add_metaclass" has incompatible type "Type[A]"; expected "Type[type]" \
                       # E: Metaclasses not inheriting from 'type' are not supported
class D3(A): pass
class C4(six.with_metaclass(M), metaclass=M): pass  # E: Multiple metaclass definitions
@six.add_metaclass(M)  # E: Multiple metaclass definitions
class D4(metaclass=M): pass
class C5(six.with_metaclass(f())): pass  # E: Dynamic metaclass not supported for 'C5'
@six.add_metaclass(f())  # E: Dynamic metaclass not supported for 'D5'
class D5: pass

@six.add_metaclass(M)  # E: Multiple metaclass definitions
class CD(six.with_metaclass(M)): pass

class M1(type): pass
class Q1(metaclass=M1): pass
@six.add_metaclass(M)  # E: Inconsistent metaclass structure for 'CQA'
class CQA(Q1): pass
class CQW(six.with_metaclass(M, Q1)): pass  # E: Inconsistent metaclass structure for 'CQW'

[case testSixMetaclassErrors_python2]
# flags: --python-version 2.7
import six
class M(type): pass
class C4(six.with_metaclass(M)):  # E: Multiple metaclass definitions
    __metaclass__ = M

[case testSixMetaclassAny]
import t  # type: ignore
import six
class E(metaclass=t.M): pass
class F(six.with_metaclass(t.M)): pass
@six.add_metaclass(t.M)
class G: pass

-- Misc
-- ----

[case testCorrectEnclosingClassPushedInDeferred]
class C:
    def __getattr__(self, attr: str) -> int:
        x: F
        return x.f

class F:
    def __init__(self, f: int) -> None:
        self.f = f
[out]

[case testCorrectEnclosingClassPushedInDeferred2]
from typing import TypeVar
T = TypeVar('T', bound=C)
class C:
    def m(self: T) -> T:
        class Inner:
            x: F
            f = x.f
        return self

class F:
    def __init__(self, f: int) -> None:
        self.f = f
[out]

[case testCorrectEnclosingClassPushedInDeferred3]
class A:
    def f(self) -> None:
        def g(x: int) -> int:
            return y

y = int()
[out]

[case testMetaclassMemberAccessViaType]
from typing import Type
class M(type):
    def m(cls, x: int) -> int:
        pass

class C(metaclass=M):
    pass
x = C
y: Type[C] = C

reveal_type(type(C).m) # E: Revealed type is 'def (cls: __main__.M, x: builtins.int) -> builtins.int'
reveal_type(type(x).m) # E: Revealed type is 'def (cls: __main__.M, x: builtins.int) -> builtins.int'
reveal_type(type(y).m) # E: Revealed type is 'def (cls: __main__.M, x: builtins.int) -> builtins.int'
[out]

[case testMetaclassMemberAccessViaType2]
from typing import Any, Type
class M(type):
    def m(cls, x: int) -> int:
        pass
B: Any
class C(B, metaclass=M):
    pass

x: Type[C]
reveal_type(x.m) # E: Revealed type is 'def (x: builtins.int) -> builtins.int'
reveal_type(x.whatever) # E: Revealed type is 'Any'
[out]

[case testMetaclassMemberAccessViaType3]
from typing import Any, Type, TypeVar
T = TypeVar('T')
class C(Any):
    def bar(self: T) -> Type[T]: pass
    def foo(self) -> None:
        reveal_type(self.bar()) # E: Revealed type is 'Type[__main__.C*]'
        reveal_type(self.bar().__name__) # E: Revealed type is 'builtins.str'
[builtins fixtures/type.pyi]
[out]

[case testClassDecoratorIsTypeChecked]
from typing import Callable, Type
def decorate(x: int) -> Callable[[type], type]:  # N: "decorate" defined here
    ...
def decorate_forward_ref() -> Callable[[Type[A]], Type[A]]:
    ...
@decorate(y=17)    # E: Unexpected keyword argument "y" for "decorate"
@decorate()        # E: Too few arguments for "decorate"
@decorate(22, 25)  # E: Too many arguments for "decorate"
@decorate_forward_ref()
@decorate(11)
class A: pass

@decorate  # E: Argument 1 to "decorate" has incompatible type "Type[A2]"; expected "int"
class A2: pass

[case testClassDecoratorIncorrect]
def not_a_class_decorator(x: int) -> int: ...
@not_a_class_decorator(7)  # E: "int" not callable
class A3: pass

not_a_function = 17
@not_a_function()  # E: "int" not callable
class B: pass

@not_a_function    # E: "int" not callable
class B2: pass

b = object()
@b.nothing         # E: "object" has no attribute "nothing"
class C: pass

@undefined         # E: Name 'undefined' is not defined
class D: pass

[case testSlotsCompatibility]
class A:
    __slots__ = ()
class B(A):
    __slots__ = ('a', 'b')
class C:
    __slots__ = ('x',)
class D(B, C):
    __slots__ = ('aa', 'bb', 'cc')

[case testRevealLocalsOnClassVars]
class C1(object):
    t = 'a'
    y = 3.0
    reveal_locals()

[out]
main:4: error: Revealed local types are:
main:4: error: t: builtins.str
main:4: error: y: builtins.float

[case testAbstractClasses]
import a
import b

[file a.pyi]
from abc import ABCMeta, abstractmethod
from typing import Protocol

class A:  # OK, has @abstractmethod
    @abstractmethod
    def f(self) -> None:
        pass

class B(A):  # E: Class a.B has abstract attributes "f"  # N: If it is meant to be abstract, add 'abc.ABCMeta' as an explicit metaclass
    pass

class C(A, metaclass=ABCMeta):  # OK, has ABCMeta as a metaclass
    pass

class D(A):  # OK, implements the abstract method
    def f(self) -> None:
        pass

class E(Protocol):  # OK, is a protocol
    @abstractmethod
    def f(self) -> None:
        pass

class F(E, Protocol):  # OK, is a protocol
    pass

[file b.py]
# All of these are OK because this is not a stub file.
from abc import ABCMeta, abstractmethod
from typing import Protocol

class A:
    @abstractmethod
    def f(self) -> None:
        pass

class B(A):
    pass

class C(A, metaclass=ABCMeta):
    pass

class D(A):
    def f(self) -> None:
        pass

class E(Protocol):
    @abstractmethod
    def f(self) -> None:
        pass

class F(E, Protocol):
    pass

[case testClassMethodOverride]
from typing import Callable, Any

def deco(f: Callable[..., Any]) -> Callable[..., Any]: ...

class B:
    @classmethod
    def meth(cls, x: int) -> int: ...

class C(B):
    @classmethod
    @deco
    def meth(cls, x: int) -> int: ...
[builtins fixtures/classmethod.pyi]
[out]

[case testGetAttrImportAnnotation]
import a
x: a.A
[file a.pyi]
from typing import Any
def __getattr__(attr: str) -> Any: ...
[builtins fixtures/module.pyi]
[out]

[case testGetAttrImportBaseClass]
import a
class B(a.A): ...
[file a.pyi]
from typing import Any
def __getattr__(attr: str) -> Any: ...
[builtins fixtures/module.pyi]
[out]

[case testGetAttrDescriptor]
from typing import TypeVar, Generic, Any

T = TypeVar('T')
class C(Generic[T]):
    normal: T
    def __getattr__(self, attr: str) -> T: ...

class Descr:
    def __get__(self, inst: Any, owner: Any) -> int: ...

class D(C[Descr]):
    other: Descr

d: D
reveal_type(d.normal)  # E: Revealed type is 'builtins.int'
reveal_type(d.dynamic)  # E: Revealed type is '__main__.Descr*'
reveal_type(D.other)  # E: Revealed type is 'builtins.int'
D.dynamic  # E: "Type[D]" has no attribute "dynamic"
[out]

[case testSelfDescriptorAssign]
from typing import Any

class Descr:
    def __get__(self, inst: Any, owner: Any) -> int: ...

class C:
    def __init__(self, x: Descr) -> None:
        self.x = x

c = C(Descr())
reveal_type(c.x)  # E: Revealed type is '__main__.Descr'
[out]

[case testForwardInstanceWithWrongArgCount]
from typing import TypeVar, Generic

T = TypeVar('T')
class G(Generic[T]): ...

A = G
x: A[B[int, int]]  # E: "G" expects 1 type argument, but 2 given
B = G
[out]

[case testForwardInstanceWithNoArgs]
from typing import TypeVar, Generic

T = TypeVar('T')
class G(Generic[T]): ...

A = G
x: A[B]
reveal_type(x)  # E: Revealed type is '__main__.G[__main__.G[Any]]'
B = G
[out]

[case testForwardInstanceWithBound]
from typing import TypeVar, Generic

T = TypeVar('T', bound=str)
class G(Generic[T]): ...

A = G
x: A[B[int]]
B = G
[out]
main:7: error: Type argument "builtins.int" of "G" must be a subtype of "builtins.str"
main:7: error: Type argument "__main__.G[builtins.int]" of "G" must be a subtype of "builtins.str"

[case testExtremeForwardReferencing]
from typing import TypeVar, Generic

T = TypeVar('T')
class B(Generic[T]): ...

y: A
z: A[int]
x = [y, z]
reveal_type(x)  # E: Revealed type is 'builtins.list[__main__.B*[Any]]'

A = B
[builtins fixtures/list.pyi]
[out]

[case testNoneAnyFallback]
from typing import Any
dynamic: Any
class C(dynamic): pass
x: None = C()  # E: Incompatible types in assignment (expression has type "C", variable has type "None")
[out]

[case testNoneAnyFallbackDescriptor]
from typing import Any
from d import Descr

dynamic: Any
class C(dynamic):
    id = Descr(int)
    name = Descr(str)

c: C
reveal_type(c.id)  # E: Revealed type is 'builtins.int*'
reveal_type(C.name)  # E: Revealed type is 'd.Descr[builtins.str*]'

[file d.pyi]
from typing import Any, overload, Generic, TypeVar, Type

T = TypeVar('T')
class Descr(Generic[T]):
    def __init__(self, tp: Type[T]) -> None: ...
    @overload
    def __get__(self, inst: None, owner: Any) -> Descr[T]: ...
    @overload
    def __get__(self, inst: object, owner: Any) -> T: ...
[out]

[case testClassCustomPropertyWorks]
from typing import TypeVar, Generic, Callable, Any

V = TypeVar('V')

class classproperty(Generic[V]):
    def __init__(self, getter: Callable[[Any], V]) -> None:
        self.getter = getter
    def __get__(self, instance: Any, owner: Any) -> V:
        return self.getter(owner)

class C:
    @classproperty
    def foo(cls) -> int:
        return 42

reveal_type(C.foo)  # E: Revealed type is 'builtins.int*'
reveal_type(C().foo)  # E: Revealed type is 'builtins.int*'
[out]

[case testMultipleInheritanceCycle]
import b
[file a.py]
from b import B
class A: ...
class C(A, B): ...
class D(C): ...
class Other: ...
[file b.py]
from a import Other
class B: ...
[out]

[case testMultipleInheritanceCycle2]
import b
[file a.py]
from b import B
class A: ...
class C(A, B): ...
class D(C): ...
class Other: ...
a: A
b: B
c: C
d: D
d = A()  # E: Incompatible types in assignment (expression has type "A", variable has type "D")
d = B()  # E: Incompatible types in assignment (expression has type "B", variable has type "D")
d = C()  # E: Incompatible types in assignment (expression has type "C", variable has type "D")
a = D()
b = D()
c = D()
[file b.py]
from a import Other
class B: ...
[out]

[case testAllowPropertyAndInit1]
class C:
    def __init__(self, x: int) -> None:
        self.x = x
    @property
    def x(self) -> int: pass
    @x.setter
    def x(self, x: int) -> None: pass
[builtins fixtures/property.pyi]
[out]

[case testAllowPropertyAndInit2]
class C:
    @property
    def x(self) -> int: pass
    @x.setter
    def x(self, x: int) -> None: pass
    def __init__(self, x: int) -> None:
        self.x = x
[builtins fixtures/property.pyi]

[case testAllowPropertyAndInit3]
class C:
    def __init__(self, x: int) -> None:
        self.x = x  # type: ignore
    @property  # Should be no error here
    def x(self) -> int: pass
[builtins fixtures/property.pyi]
[out]
