-- Test cases for taking a diff of two module ASTs/symbol tables.
-- The diffs are used for fined-grained incremental checking.

[case testChangeTypeOfModuleAttribute]
x = 1
y = 1
[file next.py]
x = ''
y = 1
[out]
__main__.x

[case testChangeSignatureOfModuleFunction]
def f(x: int) -> None:
    pass
def g(y: str) -> None:
    pass
[file next.py]
def f(x: str) -> None:
    x = ''
def g(y: str) -> None:
    y = ''
[out]
__main__.f

[case testAddModuleAttribute]
x = 1
[file next.py]
x = 1
y = 1
[out]
__main__.y

[case testRemoveModuleAttribute]
x = 1
y = 1
[file next.py]
x = 1
[out]
__main__.y

--
-- Classes
--

[case testChangeMethodSignature]
class A:
    def f(self) -> None: pass
    def g(self) -> None: pass
[file next.py]
class A:
    def f(self, x: int) -> None: pass
    def g(self) -> None: pass
[out]
__main__.A.f

[case testChangeAttributeType]
class A:
    def f(self) -> None:
        self.x = 1
        self.y = 1
[file next.py]
class A:
    def f(self) -> None:
        self.x = 1
        self.y = ''
[out]
__main__.A.y

[case testAddAttribute]
class A: pass
[file next.py]
class A:
    def f(self) -> None:
        self.x = 1
[out]
__main__.A.f
__main__.A.x

[case testAddAttribute2]
class A:
    def f(self) -> None: pass
[file next.py]
class A:
    def f(self) -> None:
        self.x = 1
[out]
__main__.A.x

[case testRemoveAttribute]
class A:
    def f(self) -> None:
        self.x = 1
[file next.py]
class A: pass
[out]
__main__.A.f
__main__.A.x

[case testAddMethod]
class A:
    def f(self) -> None: pass
[file next.py]
class A:
    def f(self) -> None: pass
    def g(self) -> None: pass
[out]
__main__.A.g

[case testRemoveMethod]
class A:
    def f(self) -> None: pass
    def g(self) -> None: pass
[file next.py]
class A:
    def f(self) -> None: pass
[out]
__main__.A.g

[case testAddImport]
import nn
[file next.py]
import n
import nn
[file n.py]
x = 1
[file nn.py]
y = 1
[out]
__main__.n

[case testRemoveImport]
import n
[file next.py]
[file n.py]
x = 1
[out]
__main__.n

[case testChangeClassIntoFunction]
class A: pass
[file next.py]
def A() -> None: pass
[out]
__main__.A

[case testDeleteClass]
class A: pass
[file next.py]
[out]
__main__.A

[case testAddBaseClass]
class A: pass
[file next.py]
class B: pass
class A(B): pass
[out]
__main__.A
__main__.B

[case testChangeBaseClass]
class A: pass
class B: pass
class C(A): pass
[file next.py]
class A: pass
class B: pass
class C(B): pass
[out]
__main__.C

[case testRemoveBaseClass]
class A: pass
class B(A): pass
[file next.py]
class A: pass
class B: pass
[out]
__main__.B

[case testRemoveClassFromMiddleOfMro]
class A: pass
class B(A): pass
class C(B): pass
[file next.py]
class A: pass
class B: pass
class C(B): pass
[out]
__main__.B
__main__.C

[case testDifferenceInConstructor]
class A:
    def __init__(self) -> None: pass
[file next.py]
class A:
    def __init__(self, x: int) -> None: pass
[out]
__main__.A.__init__

[case testChangeSignatureOfMethodInNestedClass]
class A:
    class B:
        def f(self) -> int: pass
[file next.py]
class A:
    class B:
        def f(self) -> str: pass
[out]
__main__.A.B.f

[case testChangeTypeOfAttributeInNestedClass]
class A:
    class B:
        def f(self) -> None:
            self.x = 1
[file next.py]
class A:
    class B:
        def f(self) -> None:
            self.x = ''
[out]
__main__.A.B.x

[case testAddMethodToNestedClass]
class A:
    class B: pass
[file next.py]
class A:
    class B:
        def f(self) -> str: pass
[out]
__main__.A.B.f

[case testAddNestedClass]
class A: pass
[file next.py]
class A:
    class B:
        def f(self) -> None: pass
[out]
__main__.A.B

[case testRemoveNestedClass]
class A:
    class B:
        def f(self) -> None: pass
[file next.py]
class A: pass
[out]
__main__.A.B

[case testChangeNestedClassToMethod]
class A:
    class B: pass
[file next.py]
class A:
    def B(self) -> None: pass

[out]
__main__.A.B

[case testChangeNamedTupleAttribute]
from typing import NamedTuple
class A:
    x: str
N = NamedTuple('N', [('x', int), ('y', str)])
M = NamedTuple('M', [('x', int), ('y', str)])
[file next.py]
from typing import NamedTuple
N = NamedTuple('N', [('x', int), ('y', int)])
M = NamedTuple('M', [('x', int), ('y', str)])
[out]
__main__.A
__main__.N
__main__.N.__init__
__main__.N._asdict
__main__.N._make
__main__.N._replace
__main__.N.y

[case testSimpleDecoratedFunction]
from a import dec
@dec
def f() -> None: pass
@dec
def g() -> None: pass
[file next.py]
from a import dec
@dec
def f(x: int) -> None: pass
@dec
def g() -> None: pass
[file a.py]
from typing import TypeVar

T = TypeVar('T')

def dec(f: T) -> T:
    return f
[out]
__main__.f

[case testSimpleDecoratedMethod]
from a import dec
class A:
    @dec
    def f(self) -> None:
        self.g()
    @dec
    def g(self) -> None: pass
[file next.py]
from a import dec
class A:
    @dec
    def f(self, x: int) -> None:
        self.g()
    @dec
    def g(self) -> None: pass
[file a.py]
from typing import TypeVar

T = TypeVar('T')

def dec(f: T) -> T:
    return f
[out]
__main__.A.f

[case testTypeVarBound]
from typing import TypeVar
T = TypeVar('T')
S = TypeVar('S')
[file next.py]
from typing import TypeVar
T = TypeVar('T', bound=int)
S = TypeVar('S')
[out]
__main__.T

[case testTypeVarVariance]
from typing import TypeVar
A = TypeVar('A', covariant=True)
B = TypeVar('B', covariant=True)
C = TypeVar('C', covariant=True)
[file next.py]
from typing import TypeVar
A = TypeVar('A', covariant=True)
B = TypeVar('B', contravariant=True)
C = TypeVar('C')
[out]
__main__.B
__main__.C

[case testTypeVarValues]
from typing import TypeVar
A = TypeVar('A', int, str)
B = TypeVar('B', int, str)
C = TypeVar('C', int, str)
[file next.py]
from typing import TypeVar
A = TypeVar('A', int, str)
B = TypeVar('B', int, str, object)
C = TypeVar('C')
[out]
__main__.B
__main__.C

[case testGenericFunction]
from typing import TypeVar
T = TypeVar('T')
S = TypeVar('S')
def f(x: T) -> T: pass
def g(x: S) -> S: pass
[file next.py]
from typing import TypeVar
T = TypeVar('T', int, str)
S = TypeVar('S')
def f(x: T) -> T: pass
def g(x: S) -> S: pass
[out]
__main__.T
__main__.f

[case testGenericTypes]
from typing import List
x: List[int]
y: List[int]
[file next.py]
from typing import List
x: List[int]
y: List[str]
[builtins fixtures/list.pyi]
[out]
__main__.y

[case testTypeAliasOfList]
from typing import List
X = List[int]
Y = List[int]
[file next.py]
from typing import List
X = List[str]
Y = List[int]
[builtins fixtures/list.pyi]
[out]
__main__.X

[case testTypeAliasOfCallable]
from typing import Callable
A = Callable[[int], str]
B = Callable[[int], str]
C = Callable[[int], str]
[file next.py]
from typing import Callable
A = Callable[[int], str]
B = Callable[[], str]
C = Callable[[int], int]
[out]
__main__.B
__main__.C

[case testGenericTypeAlias]
from typing import Callable, TypeVar
T = TypeVar('T')
A = Callable[[T], T]
B = Callable[[T], T]
[file next.py]
from typing import Callable, TypeVar
T = TypeVar('T')
S = TypeVar('S')
A = Callable[[T], T]
B = Callable[[T], S]
[out]
__main__.B
__main__.S

[case testDifferentListTypes]
from typing import List
A = List
B = list
C = List
[file next.py]
from typing import List
A = List
B = list
C = list
[builtins fixtures/list.pyi]
[out]
__main__.C

[case testDecoratorChangesSignature]
from contextlib import contextmanager
from typing import Iterator, List, Tuple

@contextmanager
def f(x: List[Tuple[int]]) -> Iterator[None]:
    yield

@contextmanager
def g(x: str) -> Iterator[None]:
    yield
[file next.py]
from contextlib import contextmanager
from typing import Iterator, List, Tuple

@contextmanager
def f(x: List[Tuple[int]]) -> Iterator[None]:
    yield

@contextmanager
def g(x: object) -> Iterator[None]:
    yield
[typing fixtures/typing-full.pyi]
[builtins fixtures/list.pyi]
[out]
__main__.g

[case testOverloadedMethod]
from typing import overload

class A:
    @overload
    def f(self, x: int) -> int: pass
    @overload
    def f(self, x: str) -> str: pass
    def f(self, x): pass

    @overload
    def g(self, x: int) -> int: pass
    @overload
    def g(self, x: str) -> str: pass
    def g(self, x): pass
[file next.py]
from typing import overload

class A:
    @overload
    def f(self, x: int) -> int: pass
    @overload
    def f(self, x: str) -> str: pass
    def f(self, x): pass

    @overload
    def g(self, x: int) -> int: pass
    @overload
    def g(self, x: object) -> object: pass
    def g(self, x): pass
[out]
__main__.A.g

[case testPropertyWithSetter]
class A:
    @property
    def x(self) -> int:
        pass

    @x.setter
    def x(self, o: int) -> None:
        pass

class B:
    @property
    def x(self) -> int:
        pass

    @x.setter
    def x(self, o: int) -> None:
        pass
[file next.py]
class A:
    @property
    def x(self) -> int:
        pass

    @x.setter
    def x(self, o: int) -> None:
        pass

class B:
    @property
    def x(self) -> str:
        pass

    @x.setter
    def x(self, o: str) -> None:
        pass
[builtins fixtures/property.pyi]
[out]
__main__.B.x

[case testFunctionalEnum]
from enum import Enum, IntEnum
A = Enum('A', 'x')
B = Enum('B', 'x')
C = Enum('C', 'x')
D = IntEnum('D', 'x')
[file next.py]
from enum import Enum, IntEnum
A = Enum('A', 'x')
B = Enum('B', 'y')
C = IntEnum('C', 'x')
D = IntEnum('D', 'x y')
[out]
__main__.B.x
__main__.B.y
__main__.C
__main__.D.y

[case testClassBasedEnum]
from enum import Enum
class A(Enum):
    X = 0
    Y = 1
class B(Enum):
    X = 0
    Y = 1
class C(Enum):
    X = 0
    Y = 1
class D(Enum):
    X = 0
    Y = 1
class E(Enum):
    X = 0
[file next.py]
from enum import Enum
class A(Enum):
    X = 0
    Y = 1
class B(Enum):
    X = 0
    Z = 1
class C(Enum):
    X = 0
    Y = 1
    Z = 2
class D(Enum):
    X = 'a'
    Y = 'b'
class F(Enum):
    X = 0
[out]
__main__.B.Y
__main__.B.Z
__main__.C.Z
__main__.D.X
__main__.D.Y
__main__.E
__main__.F

[case testTypedDict]
from mypy_extensions import TypedDict
Point = TypedDict('Point', {'x': int, 'y': int})
p = Point(dict(x=42, y=1337))
[file next.py]
from mypy_extensions import TypedDict
Point = TypedDict('Point', {'x': int, 'y': str})
p = Point(dict(x=42, y='lurr'))
[builtins fixtures/dict.pyi]
[out]
__main__.Point
__main__.p

[case testTypedDict2]
from mypy_extensions import TypedDict
class Point(TypedDict):
    x: int
    y: int
p = Point(dict(x=42, y=1337))
[file next.py]
from mypy_extensions import TypedDict
class Point(TypedDict):
    x: int
    y: str
p = Point(dict(x=42, y='lurr'))
[builtins fixtures/dict.pyi]
[out]
__main__.Point
__main__.p

[case testTypedDict3]
from mypy_extensions import TypedDict
Point = TypedDict('Point', {'x': int, 'y': int})
p = Point(dict(x=42, y=1337))
[file next.py]
from mypy_extensions import TypedDict
Point = TypedDict('Point', {'x': int})
p = Point(dict(x=42))
[builtins fixtures/dict.pyi]
[out]
__main__.Point
__main__.p

[case testTypedDict4]
from mypy_extensions import TypedDict
Point = TypedDict('Point', {'x': int, 'y': int})
p = Point(dict(x=42, y=1337))
[file next.py]
from mypy_extensions import TypedDict
Point = TypedDict('Point', {'x': int, 'y': int}, total=False)
p = Point(dict(x=42, y=1337))
[builtins fixtures/dict.pyi]
[out]
__main__.Point
__main__.p

[case testTypeAliasSimple]
A = int
B = int
[file next.py]
A = str
B = int
[out]
__main__.A

[case testTypeAliasGeneric]
from typing import List
A = List[int]
B = List[int]
[file next.py]
from typing import List
A = List[str]
B = List[int]
[builtins fixtures/list.pyi]
[out]
__main__.A

[case testTypeAliasGenToNonGen]
from typing import List
A = List[str]
B = List
[file next.py]
from typing import List
A = List
B = List
[builtins fixtures/list.pyi]
[out]
__main__.A

[case testTypeAliasNonGenToGen]
from typing import List
A = List
B = List
[file next.py]
from typing import List
A = List[str]
B = List
[builtins fixtures/list.pyi]
[out]
__main__.A

[case testTypeAliasGenericTypeVar]
from typing import TypeVar, Dict
T = TypeVar('T')
S = TypeVar('S')
A = Dict[str, T]
B = Dict[str, S]
[file next.py]
from typing import TypeVar, Dict
class T: pass
S = TypeVar('S')
A = Dict[str, T]
B = Dict[str, S]
[builtins fixtures/dict.pyi]
[out]
__main__.A
__main__.T

[case testNewType]
from typing import NewType
class C: pass
class D: pass
N1 = NewType('N1', C)
N2 = NewType('N2', D)
N3 = NewType('N3', C)
class N4(C): pass
[file next.py]
from typing import NewType
class C: pass
class D(C): pass
N1 = NewType('N1', C)
N2 = NewType('N2', D)
class N3(C): pass
N4 = NewType('N4', C)
[out]
__main__.D
__main__.N2
__main__.N3
__main__.N3.__init__
__main__.N4
__main__.N4.__init__

[case testChangeGenericBaseClassOnly]
from typing import List
class C(List[int]): pass
[file next.py]
from typing import List
class C(List[str]): pass
[builtins fixtures/list.pyi]
[out]
__main__.C

[case testOverloads]
from typing import overload
class C: pass
@overload
def a(x: int) -> None: pass
@overload
def a(x: str) -> str: pass
def a(x):
    pass
@overload
def b(x: int) -> None: pass
@overload
def b(x: str) -> str: pass
def b(x):
    pass
@overload
def c(x: int) -> None: pass
@overload
def c(x: str) -> str: pass
def c(x):
    pass
@overload
def d(x: int) -> None: pass
@overload
def d(x: str) -> str: pass
def d(x):
    pass
[file next.py]
from typing import overload
class C: pass
@overload
def a(x: int) -> None: pass
@overload
def a(x: str) -> str: pass
def a(x):
    pass
@overload
def b(x: str) -> str: pass
@overload
def b(x: int) -> None: pass
def b(x):
    pass
@overload
def c(x: int) -> None: pass
@overload
def c(x: str) -> str: pass
@overload
def c(x: C) -> C: pass
def c(x):
    pass
def d(x: int) -> None:
    pass
@overload
def e(x: int) -> None: pass
@overload
def e(x: str) -> str: pass
def e(x):
    pass
[out]
__main__.b
__main__.c
__main__.d
__main__.e

[case testOverloadsExternalOnly]
from typing import overload
class Base: pass
class A(Base): pass
class B(Base): pass
class C(Base): pass
@overload
def f(x: A) -> A: pass
@overload
def f(x: B) -> B: pass
def f(x: Base) -> Base:
    pass
@overload
def g(x: A) -> A: pass
@overload
def g(x: B) -> B: pass
def g(x: Base) -> Base:
    pass
[file next.py]
from typing import overload
class Base: pass
class A(Base): pass
class B(Base): pass
class C(Base): pass
@overload
def f(x: A) -> A: pass
@overload
def f(x: B) -> B: pass
def f(x: object) -> object:
    pass
@overload
def g(x: A) -> A: pass
@overload
def g(x: C) -> C: pass
def g(x: Base) -> Base:
    pass
[out]
__main__.g

[case testNestedFunctionDoesntMatter]
class A: pass
class B: pass
def outer() -> None:
    def inner(x: A) -> B:
        pass
[file next.py]
class A: pass
class B: pass
def outer() -> None:
    def inner(y: B) -> A:
        pass
[out]

[case testProtocolVsNominal]
from typing import Protocol
class A(Protocol):
    x: int
class B(Protocol):
    x: int
class C(Protocol):
    x: int
class D(Protocol):
    x: int
[file next.py]
from typing import Protocol
class A(Protocol):
    x: int
class B(Protocol):
    x: str
class C(Protocol):
    x: int
    y: int
class D:
    x: int
[out]
__main__.B.x
__main__.C.(abstract)
__main__.C.y
__main__.D
__main__.D.(abstract)

[case testProtocolNormalVsGeneric]
from typing import Protocol, TypeVar
T = TypeVar('T')
class P(Protocol[T]):
    x: T
class P2(Protocol[T]):
    x: T
    y: T
[file next.py]
from typing import Protocol, TypeVar
T = TypeVar('T')
class P(Protocol):
    x: int
class P2(Protocol[T]):
    x: T
[out]
__main__.P
__main__.P.x
__main__.P2.(abstract)
__main__.P2.y

[case testAddAbstractMethod]
from abc import abstractmethod
class A:
    @abstractmethod
    def f(self) -> None: pass
[file next.py]
from abc import abstractmethod
class A:
    @abstractmethod
    def f(self) -> None: pass
    @abstractmethod
    def g(self) -> None: pass
[out]
__main__.A.(abstract)
__main__.A.g
