-- Checks for incremental mode (see testcheck.py).
-- Each test is run at least twice, once with a cold cache, once with a warm cache.
-- Before the tests are run again, in step N any *.py.N files are copied to
-- *.py.  There are at least two runs; more as long as there are *.py.N files.
--
-- You can add an empty section like `[delete mod.py.2]` to delete `mod.py`
-- before the second run.
--
-- Errors expected in the first run should be in the `[out1]` section, and
-- errors expected in the second run should be in the `[out2]` section, and so on.
-- If a section is omitted, it is expected there are no errors on that run.
-- The number of runs is determined by the highest N in all [outN] sections, but
-- there are always at least two runs. (Note that [out] is equivalent to [out1].)
--
-- The list of modules to be checked can be specified using
-- # cmd: mypy -m mod1 mod2 mod3
-- To check a different list on the second run, use
-- # cmd2: mypy -m mod1 mod3
-- (and cmd3 for the third run, and so on).
--
-- Extra command line flags may be specified using
-- # flags: --some-flag
-- If the second run requires different flags, those can be specified using
-- # flags2: --another-flag
-- (and flags3 for the third run, and so on).
--
-- Any files that we expect to be rechecked should be annotated in the [rechecked]
-- annotation, and any files expect to be stale (aka have a modified interface)
-- should be annotated in the [stale] annotation. Note that a file that ends up
-- producing an error has its caches deleted and is marked stale automatically.
-- Such files do not need to be included in [stale ...] list.
--
-- The test suite will automatically assume that __main__ is stale and rechecked in
-- all cases so we can avoid constantly having to annotate it. The list of
-- rechecked/stale files can be in any arbitrary order, or can be left empty
-- if no files should be rechecked/stale.
--
-- There are additional incremental mode test cases in check-serialize.test.

[case testIncrementalEmpty]
[rechecked]
[stale]

[case testIncrementalBasics]
import m
[file m.py]
def foo():
    pass
[file m.py.2]
def foo() -> None:
    pass
[rechecked m]
[stale m]

[case testIncrementalError]
import m
[file m.py]
def foo() -> None:
    pass
[file m.py.2]
def foo() -> None:
    bar()
[rechecked m]
[stale]
[out2]
tmp/m.py:2: error: Name 'bar' is not defined

[case testIncrementalSimpleImportSequence]
import mod1
mod1.func1()

[file mod1.py]
import mod2
def func1() -> None: mod2.func2()

[file mod2.py]
import mod3
def func2() -> None: mod3.func3()

[file mod3.py]
def func3() -> None: pass

[rechecked]
[stale]


[case testIncrementalInternalChangeOnly]
import mod1
mod1.func1()

[file mod1.py]
import mod2
def func1() -> None: mod2.func2()

[file mod2.py]
import mod3
def func2() -> None: mod3.func3()

[file mod3.py]
def func3() -> None: pass

[file mod3.py.2]
def func3() -> None: 3 + 2

[rechecked mod3]
[stale]


[case testIncrementalImportGone]
import mod1

[file mod1.py]
from mod2 import A
def func1() -> A: pass

[file mod2.py]
class A: pass

[file mod1.py.2]
def func1() -> A: pass

[rechecked mod1]
[stale]
[out2]
tmp/mod1.py:1: error: Name 'A' is not defined

[case testIncrementalCallable]
import mod1

[file mod1.py]
from typing import Callable
from mypy_extensions import Arg
def func1() -> Callable[[Arg(int, 'x')], int]: pass

[file mod1.py.2]
from typing import Callable
from mypy_extensions import Arg
def func1() -> Callable[[Arg(int, 'x')], int]: ...


[rechecked mod1]
[stale]

[builtins fixtures/dict.pyi]

[case testIncrementalSameNameChange]
import mod1

[file mod1.py]
from mod2 import A
def func1() -> A: pass

[file mod2.py]
class A: pass

[file mod2.py.2]
class Parent: pass
class A(Parent): pass

[rechecked mod1, mod2]
[stale mod2]

[case testIncrementalPartialInterfaceChange]
import mod1
mod1.func1()

[file mod1.py]
import mod2
def func1() -> None: mod2.func2()

[file mod2.py]
import mod3
def func2() -> None: mod3.func3()

[file mod3.py]
def func3() -> None: pass

[file mod3.py.2]
def func3() -> int: return 2

[rechecked mod2, mod3]
[stale mod3]

[case testIncrementalInternalFunctionDefinitionChange]
import mod1

[file mod1.py]
import mod2
def accepts_int(a: int) -> int: return a
accepts_int(mod2.foo())

[file mod2.py]
def foo() -> int:
    def inner() -> int:
        return 42
    return inner()

[file mod2.py.2]
def foo() -> int:
    def inner2() -> str:
        return "foo"
    return inner2()

[rechecked mod1, mod2]
[stale]
[out2]
tmp/mod2.py:4: error: Incompatible return value type (got "str", expected "int")

[case testIncrementalInternalScramble]
import mod1

[file mod1.py]
import mod2
mod2.foo()

[file mod2.py]
def baz() -> int:
    return 3

def bar() -> int:
    return baz()

def foo() -> int:
    return bar()

[file mod2.py.2]
def foo() -> int:
    return baz()

def bar() -> int:
    return bar()

def baz() -> int:
    return 42
[rechecked mod2]
[stale]

[case testIncrementalMethodInterfaceChange]
import mod1

[file mod1.py]
import mod2

[file mod2.py]
class Foo:
    def bar(self, a: str) -> str:
        return "a"

[file mod2.py.2]
class Foo:
    def bar(self, a: float) -> str:
        return "a"

[rechecked mod1, mod2]
[stale mod2]

[case testIncrementalBaseClassChange]
import mod1

[file mod1.py]
from mod2 import Child
Child().good_method()

[file mod2.py]
class Good:
    def good_method(self) -> int: return 1
class Bad: pass
class Child(Good): pass

[file mod2.py.2]
class Good:
    def good_method(self) -> int: return 1
class Bad: pass
class Child(Bad): pass

[rechecked mod1, mod2]
[stale mod2]
[out2]
tmp/mod1.py:2: error: "Child" has no attribute "good_method"

[case testIncrementalCascadingChange]
import mod1

[file mod1.py]
from mod2 import A
def accepts_int(a: int) -> None: pass
accepts_int(A)

[file mod2.py]
from mod3 import B
A = B

[file mod3.py]
from mod4 import C
B = C

[file mod4.py]
C = 3

[file mod4.py.2]
C = "A"

[rechecked mod1, mod2, mod3, mod4]
[stale mod2, mod3, mod4]
[out2]
tmp/mod1.py:3: error: Argument 1 to "accepts_int" has incompatible type "str"; expected "int"

[case testIncrementalBrokenCascade]
import mod1

[file mod1.py]
import mod2
def accept_int(a: int) -> int: return a
accept_int(mod2.mod3.mod4.const)

[file mod2.py]
import mod3

[file mod3.py]
import mod4

[file mod4.py]
const = 3

[file mod3.py.2]
# Import to mod4 is gone!

[rechecked mod1, mod2, mod3]
[stale mod3]
[builtins fixtures/module.pyi]
[out2]
tmp/mod1.py:3: error: Module has no attribute "mod4"

[case testIncrementalLongBrokenCascade]
import mod1

[file mod1.py]
import mod2
def accept_int(a: int) -> int: return a
accept_int(mod2.mod3.mod4.mod5.mod6.mod7.const)

[file mod2.py]
import mod3

[file mod3.py]
import mod4

[file mod4.py]
import mod5

[file mod5.py]
import mod6

[file mod6.py]
import mod7

[file mod7.py]
const = 3

[file mod6.py.2]
# Import to mod7 is gone!

[rechecked mod1, mod5, mod6]
[stale mod6]
[builtins fixtures/module.pyi]
[out2]
tmp/mod1.py:3: error: Module has no attribute "mod7"

[case testIncrementalNestedBrokenCascade]
import mod1

[file mod1.py]
import mod2
def accept_int(a: int) -> int: return a
accept_int(mod2.mod3.mod4.const)

[file mod2/__init__.py]
import mod2.mod3 as mod3

[file mod2/mod3/__init__.py]
import mod2.mod3.mod4 as mod4

[file mod2/mod3/__init__.py.2]
# Import is gone!

[file mod2/mod3/mod4.py]
const = 3

[rechecked mod1, mod2, mod2.mod3]
[stale mod2.mod3]
[builtins fixtures/module.pyi]
[out2]
tmp/mod1.py:3: error: Module has no attribute "mod4"

[case testIncrementalNestedBrokenCascadeWithType1]
import mod1, mod2.mod3.mod5

[file mod1.py]
import mod2
def accept_int(x: int) -> None: pass
def produce() -> mod2.CustomType:
    return mod2.CustomType()
a = produce()
accept_int(a.foo())

[file mod2/__init__.py]
from mod2.mod3 import CustomType

[file mod2/mod3/__init__.py]
from mod2.mod3.mod4 import CustomType

[file mod2/mod3/__init__.py.2]
# Import a different class that also happens to be called 'CustomType'
from mod2.mod3.mod5 import CustomType
def produce() -> CustomType:
    return CustomType()

[file mod2/mod3/mod4.py]
class CustomType:
    def foo(self) -> int: return 1

[file mod2/mod3/mod5.py]
class CustomType:
    def foo(self) -> str: return "a"

[rechecked mod1, mod2, mod2.mod3]
[stale mod2, mod2.mod3]
[builtins fixtures/module.pyi]
[out1]
[out2]
tmp/mod1.py:6: error: Argument 1 to "accept_int" has incompatible type "str"; expected "int"

[case testIncrementalNestedBrokenCascadeWithType2]
import mod1, mod2.mod3.mod5

[file mod1.py]
from mod2 import produce
def accept_int(x: int) -> None: pass
a = produce()
accept_int(a.foo())

[file mod2/__init__.py]
from mod2.mod3 import produce

[file mod2/mod3/__init__.py]
from mod2.mod3.mod4 import CustomType
def produce() -> CustomType:
    return CustomType()

[file mod2/mod3/__init__.py.2]
# Import a different class that also happens to be called 'CustomType'
from mod2.mod3.mod5 import CustomType
def produce() -> CustomType:
    return CustomType()

[file mod2/mod3/mod4.py]
class CustomType:
    def foo(self) -> int: return 1

[file mod2/mod3/mod5.py]
class CustomType:
    def foo(self) -> str: return "a"

[rechecked mod1, mod2, mod2.mod3]
[stale mod2.mod3]
[builtins fixtures/module.pyi]
[out1]
[out2]
tmp/mod1.py:4: error: Argument 1 to "accept_int" has incompatible type "str"; expected "int"

[case testIncrementalRemoteChange]
import mod1

[file mod1.py]
import mod2
def accepts_int(a: int) -> None: pass
accepts_int(mod2.mod3.mod4.const)

[file mod2.py]
import mod3

[file mod3.py]
import mod4

[file mod4.py]
const = 3

[file mod4.py.2]
const = "foo"

[rechecked mod1, mod3, mod4]
[stale mod4]
[out2]
tmp/mod1.py:3: error: Argument 1 to "accepts_int" has incompatible type "str"; expected "int"

[case testIncrementalBadChange]
import mod1

[file mod1.py]
from mod2 import func2

def func1() -> int:
    return func2()

[file mod2.py]
def func2() -> int:
    return 1

[file mod2.py.2]
def func2() -> str:
    return "foo"

[rechecked mod1, mod2]
[stale mod2]
[out2]
tmp/mod1.py:4: error: Incompatible return value type (got "str", expected "int")

[case testIncrementalBadChangeWithSave]
import mod0

[file mod0.py]
import mod1
A = mod1.func2()

[file mod1.py]
from mod2 import func2

def func1() -> int:
    return func2()

[file mod2.py]
def func2() -> int:
    return 1

[file mod2.py.2]
def func2() -> str:
    return "foo"

[rechecked mod0, mod1, mod2]
[stale mod2]
[out2]
tmp/mod1.py:4: error: Incompatible return value type (got "str", expected "int")

[case testIncrementalOkChangeWithSave]
import mod0

[file mod0.py]
import mod1
A = mod1.func2()

[file mod1.py]
from mod2 import func2

def func1() -> int:
    func2()
    return 1

[file mod2.py]
def func2() -> int:
    return 1

[file mod2.py.2]
def func2() -> str:
    return "foo"

[rechecked mod0, mod1, mod2]
[stale mod0, mod2]
[out2]

[case testIncrementalWithComplexDictExpression]
import mod1

[file mod1.py]
import mod1_private

[file mod1_private.py]
my_dict = {
    'a': [1, 2, 3],
    'b': [4, 5, 6]
}

[file mod1_private.py.2]
my_dict = {
    'a': [1, 2, 3],
    'b': [4, 5, 'a']
}

[rechecked mod1, mod1_private]
[stale mod1_private]
[builtins fixtures/dict.pyi]

[case testIncrementalWithComplexConstantExpressionNoAnnotation]
import mod1

[file mod1.py]
import mod1_private

[file mod1_private.py]
def foobar() -> int: return 1
def baz() -> int: return 2
const = 1 + foobar()

[file mod1_private.py.2]
def foobar() -> int: return 1
def baz() -> int: return 2
const = 1 + baz()

[rechecked mod1_private]
[stale]

[case testIncrementalWithComplexConstantExpressionWithAnnotation]
import mod1

[file mod1.py]
import mod1_private

[file mod1_private.py]
def foobar() -> int: return 1
def baz() -> int: return 2
const = 1 + foobar()  # type: int

[file mod1_private.py.2]
def foobar() -> int: return 1
def baz() -> int: return 2
const = 1 + baz()  # type: int

[rechecked mod1_private]
[stale]

[case testIncrementalSmall]
import mod1

[file mod1.py]
import mod1_private
def accepts_int(a: int) -> None: pass
accepts_int(mod1_private.some_func(12))

[file mod1_private.py]
def some_func(a: int) -> int:
    return 1

[file mod1_private.py.2]
def some_func(a: int) -> str:
    return "a"

[rechecked mod1, mod1_private]
[stale mod1_private]
[builtins fixtures/ops.pyi]
[out2]
tmp/mod1.py:3: error: Argument 1 to "accepts_int" has incompatible type "str"; expected "int"

[case testIncrementalWithDecorators]
import mod1

[file mod1.py]
import mod1_private
def accepts_int(a: int) -> None: pass
accepts_int(mod1_private.some_func(12))

[file mod1_private.py]
from typing import Callable
def multiply(f: Callable[[int], int]) -> Callable[[int], int]:
    return lambda a: f(a) * 10

def stringify(f: Callable[[int], int]) -> Callable[[int], str]:
    return lambda a: str(f(a))

@multiply
def some_func(a: int) -> int:
    return a + 2

[file mod1_private.py.2]
from typing import Callable
def multiply(f: Callable[[int], int]) -> Callable[[int], int]:
    return lambda a: f(a) * 10

def stringify(f: Callable[[int], int]) -> Callable[[int], str]:
    return lambda a: str(f(a))

@stringify
def some_func(a: int) -> int:
    return a + 2
[rechecked mod1, mod1_private]
[stale mod1_private]
[builtins fixtures/ops.pyi]
[out2]
tmp/mod1.py:3: error: Argument 1 to "accepts_int" has incompatible type "str"; expected "int"

[case testIncrementalChangingClassAttributes]
import mod1

[file mod1.py]
import mod2
mod2.Foo.A

[file mod2.py]
class Foo:
    A = 3

[file mod2.py.2]
class Foo:
    A = "hello"

[rechecked mod1, mod2]
[stale mod2]

[case testIncrementalChangingFields]
import mod1

[file mod1.py]
import mod2
f = mod2.Foo()
f.A

[file mod2.py]
class Foo:
    def __init__(self) -> None:
        self.A = 3

[file mod2.py.2]
class Foo:
    def __init__(self) -> None:
        self.A = "hello"

[rechecked mod1, mod2]
[stale mod2]
[out2]

[case testIncrementalChangingFieldsWithAssignment]
import mod1

[file mod1.py]
import mod2
f = mod2.Foo()
B = f.A

[file mod2.py]
class Foo:
    def __init__(self) -> None:
        self.A = 3

[file mod2.py.2]
class Foo:
    def __init__(self) -> None:
        self.A = "hello"

[rechecked mod1, mod2]
[stale mod1, mod2]

[case testIncrementalCheckingChangingFields]
import mod1

[file mod1.py]
import mod2
def accept_int(a: int) -> int: return a
f = mod2.Foo()
accept_int(f.A)

[file mod2.py]
class Foo:
    def __init__(self) -> None:
        self.A = 3

[file mod2.py.2]
class Foo:
    def __init__(self) -> None:
        self.A = "hello"

[rechecked mod1, mod2]
[stale mod2]
[out2]
tmp/mod1.py:4: error: Argument 1 to "accept_int" has incompatible type "str"; expected "int"

[case testIncrementalNestedClassDefinition]
import mod1

[file mod1.py]
import mod2
b = mod2.Foo.Bar()
b.attr

[file mod2.py]
class Foo:
    class Bar:
        attr = 3

[file mod2.py.2]
class Foo:
    class Bar:
        attr = "foo"

[rechecked mod1, mod2]
[stale mod2]

[case testIncrementalSimpleBranchingModules]
import mod1
import mod2

[file mod1.py]
def func() -> None: pass

[file mod2.py]
def func() -> None: pass

[file mod1.py.2]
def func() -> int: return 1

[rechecked mod1]
[stale mod1]

[case testIncrementalSubmoduleImport]
from parent.childA import Foo

def func1() -> Foo:
    return Foo()

[file parent/__init__.py]
from parent.childA import Foo
from parent.childB import Bar

__all__ = ['Foo', 'Bar']

[file parent/childA.py]
import parent

class Foo:
    def test(self) -> int:
        return parent.Bar().test()

[file parent/childB.py]
class Bar:
    def test(self) -> int: return 3

[builtins fixtures/module_all.pyi]
[rechecked]
[stale]

[case testIncrementalSubmoduleWithAttr]
import mod.child
x = mod.child.Foo()
x.bar()

[file mod/__init__.py]

[file mod/child.py]
class Foo:
    def bar(self) -> None: pass
[builtins fixtures/module.pyi]
[rechecked]
[stale]

[case testIncrementalNestedSubmoduleImportFromWithAttr]
from mod1.mod2 import mod3
def accept_int(a: int) -> None: pass

accept_int(mod3.val3)

[file mod1/__init__.py]
val1 = 1

[file mod1/mod2/__init__.py]
val2 = 1

[file mod1/mod2/mod3.py]
val3 = 1

[builtins fixtures/module.pyi]
[rechecked]
[stale]

[case testIncrementalNestedSubmoduleWithAttr]
import mod1.mod2.mod3
def accept_int(a: int) -> None: pass

accept_int(mod1.mod2.mod3.val3)
accept_int(mod1.mod2.val2)
accept_int(mod1.val1)

[file mod1/__init__.py]
val1 = 1

[file mod1/mod2/__init__.py]
val2 = 1

[file mod1/mod2/mod3.py]
val3 = 1

[builtins fixtures/module.pyi]
[rechecked]
[stale]

[case testIncrementalSubmoduleParentWithImportFrom]
import parent

[file parent/__init__.py]
from parent import a

[file parent/a.py]
val = 3

[builtins fixtures/args.pyi]
[stale]

[case testIncrementalSubmoduleParentBackreference]
import parent

[file parent/__init__.py]
from parent import a

[file parent/a.py]
import parent.b

[file parent/b.py]

[builtins fixtures/args.pyi]
[stale]

[case testIncrementalSubmoduleParentBackreferenceComplex]
import parent

[file parent/__init__.py]
import parent.a

[file parent/a.py]
import parent.b
import parent.c

[file parent/b.py]
import parent.a

[file parent/c.py]
import parent.a

[builtins fixtures/args.pyi]
[stale]

[case testIncrementalReferenceNewFileWithImportFrom]
from parent import a

[file parent/__init__.py]

[file parent/a.py]

[file parent/a.py.2]
from parent import b

[file parent/b.py.2]

[stale parent.a, parent.b]
[rechecked parent, parent.a, parent.b]

[case testIncrementalReferenceExistingFileWithImportFrom]
from parent import a, b

[file parent/__init__.py]

[file parent/a.py]

[file parent/b.py]

[file parent/a.py.2]
from parent import b

[stale parent.a]

[case testIncrementalWithTypeIgnoreOnDirectImport]
import a, b

[file a.py]
import b  # type: ignore

[file b.py]
import c

[file c.py]

[stale]

[case testIncrementalWithTypeIgnoreOnImportFrom]
import a, b

[file a.py]
from b import something # type: ignore

[file b.py]
import c
something = 3

[file c.py]

[stale]

[case testIncrementalWithPartialTypeIgnore]
import a  # type: ignore
import a.b

[file a/__init__.py]

[file a/b.py]

[stale]

[case testIncrementalAnyIsDifferentFromIgnore]
import b

[file b.py]
from typing import Any
import a.b

[file b.py.2]
from typing import Any

a = 3  # type: Any
import a.b

[file a/__init__.py]

[file a/b.py]

[rechecked b]
[stale]
[out2]
tmp/b.py:4: error: Name 'a' already defined on line 3

[case testIncrementalSilentImportsAndImportsInClass]
# flags: --ignore-missing-imports
class MyObject(object):
    from bar import FooBar
[stale]

[case testIncrementalSameFileSize]
import m

[file m.py]
def foo(a: int) -> None: pass
def bar(a: str) -> None: pass

foo(3)

[file m.py.2]
def foo(a: int) -> None: pass
def bar(a: str) -> None: pass

bar(3)

[rechecked m]
[stale]
[out2]
tmp/m.py:4: error: Argument 1 to "bar" has incompatible type "int"; expected "str"

[case testIncrementalUnsilencingModule]
# cmd: mypy -m main package.subpackage.mod2
# cmd2: mypy -m main package.subpackage.mod1
# flags: --follow-imports=skip

[file main.py]
from package.subpackage.mod1 import Class

def handle(c: Class) -> None:
    c.some_attribute

[file package/__init__.py]
# empty

[file package/subpackage/__init__.py]
# empty

[file package/subpackage/mod1.py]
import collections # Any previously unloaded package works here

class Class: pass

[file package/subpackage/mod2.py]
# empty

[builtins fixtures/args.pyi]
[rechecked collections, main, package.subpackage.mod1]
[stale collections, package.subpackage.mod1]
[out2]
tmp/main.py:4: error: "Class" has no attribute "some_attribute"

[case testIncrementalWithIgnores]
import foo # type: ignore

[builtins fixtures/module.pyi]
[stale]

[case testIncrementalWithSilentImportsAndIgnore]
# cmd: mypy -m main b
# cmd2: mypy -m main c c.submodule
# flags: --follow-imports=skip

[file main.py]
import a  # type: ignore
import b
import c

a.A().foo()
b.B().foo()
c.C().foo()

[file b.py]
class B:
    def foo(self) -> None: pass

[file b.py.2]

[file c/__init__.py]
class C: pass

[file c/submodule.py]
val = 3  # type: int
val = "foo"

[builtins fixtures/module_all.pyi]
[rechecked main, c, c.submodule]
[stale c]
[out2]
tmp/c/submodule.py:2: error: Incompatible types in assignment (expression has type "str", variable has type "int")
tmp/main.py:7: error: "C" has no attribute "foo"

[case testIncrementalRemoteError]
import m
m.C().foo().bar()
[file m.py]
import n
class C:
  def foo(self) -> n.A: pass
[file n.py]
class A:
  def bar(self): pass
[file n.py.2]
class A:
  pass
[rechecked m, n]
[stale n]
[out2]
main:2: error: "A" has no attribute "bar"

[case testIncrementalRemoteErrorFixed]
import m
m.C().foo().bar()
[file m.py]
import n
class C:
  def foo(self) -> n.A: pass
[file n.py]
class A:
  pass
[file n.py.2]
class A:
  def bar(self): pass
[rechecked m, n]
[stale n]
[out1]
main:2: error: "A" has no attribute "bar"

[case testIncrementalChangedError]
import m
[file m.py]
import n
def accept_int(x: int) -> None: pass
accept_int(n.foo)
[file n.py]
foo = "hello"
reveal_type(foo)
[file n.py.2]
foo = 3.14
reveal_type(foo)
[rechecked m, n]
[stale]
[out1]
tmp/n.py:2: error: Revealed type is 'builtins.str'
tmp/m.py:3: error: Argument 1 to "accept_int" has incompatible type "str"; expected "int"
[out2]
tmp/n.py:2: error: Revealed type is 'builtins.float'
tmp/m.py:3: error: Argument 1 to "accept_int" has incompatible type "float"; expected "int"

[case testIncrementalReplacingImports]
import good, bad, client

[file good.py]
def foo(a: int) -> None: pass

[file bad.py]
def foo(a: str) -> None: pass

[file client.py]
import good
import bad
from good import foo
foo(3)

[file client.py.2]
import good
import bad
from bad import foo
foo(3)

[rechecked client]
[stale]
[out2]
tmp/client.py:4: error: Argument 1 to "foo" has incompatible type "int"; expected "str"

[case testIncrementalChangingAlias]
import m1, m2, m3, m4, m5

[file m1.py]
from m2 import A
def accepts_int(x: int) -> None: pass
accepts_int(A())

[file m2.py]
from m3 import A

[file m3.py]
from m4 import B
A = B

[file m3.py.2]
from m5 import C
A = C

[file m4.py]
def B() -> int:
    return 42

[file m5.py]
def C() -> str:
    return "hello"

[rechecked m1, m2, m3]
[stale m3]
[out2]
tmp/m1.py:3: error: Argument 1 to "accepts_int" has incompatible type "str"; expected "int"

[case testIncrementalStoresAliasTypeVars]
import a

[file mod.py]
from typing import TypeVar, Union
T = TypeVar('T')
Alias = Union[int, T]
x: Alias[str]

[file a.py]
from mod import Alias, x

[file a.py.2]
from mod import Alias, x

reveal_type(x)
y: Alias[int]
reveal_type(y)
[out2]
tmp/a.py:3: error: Revealed type is 'Union[builtins.int, builtins.str]'
tmp/a.py:5: error: Revealed type is 'Union[builtins.int, builtins.int]'

[case testIncrementalSilentImportsWithBlatantError]
# cmd: mypy -m main
# flags: --follow-imports=skip

[file main.py]
from evil import Hello

[file main.py.2]
from evil import Hello
reveal_type(Hello())

[file evil.py]
def accept_int(x: int) -> None: pass
accept_int("not an int")

[rechecked main]
[stale]
[out2]
tmp/main.py:2: error: Revealed type is 'Any'

[case testIncrementalImportIsNewlySilenced]
# cmd: mypy -m main foo
# cmd2: mypy -m main
# flags: --follow-imports=skip

[file main.py]
from foo import bar
def accept_int(x: int) -> None: pass
accept_int(bar)

[file foo.py]
bar = 3

[file foo.py.2]
# Empty!

[rechecked main]
[stale main]

[case testIncrementalSilencedModuleNoLongerCausesError]
# cmd: mypy -m main evil
# cmd2: mypy -m main
# flags: --follow-imports=skip

[file main.py]
from evil import bar
def accept_int(x: int) -> None: pass
accept_int(bar)
reveal_type(bar)

[file evil.py]
bar = "str"

[rechecked main]
[stale]
[out1]
tmp/main.py:3: error: Argument 1 to "accept_int" has incompatible type "str"; expected "int"
tmp/main.py:4: error: Revealed type is 'builtins.str'
[out2]
tmp/main.py:4: error: Revealed type is 'Any'

[case testIncrementalFixedBugCausesPropagation]
import mod1

[file mod1.py]
from mod2 import A
val = A().makeB().makeC().foo()
reveal_type(val)

[file mod2.py]
from mod3 import B
class A:
    def makeB(self) -> B: return B()

[file mod3.py]
from mod4 import C
class B:
    def makeC(self) -> C:
        val = 3  # type: int
        val = "str"   # deliberately triggering error
        return C()

[file mod3.py.2]
from mod4 import C
class B:
    def makeC(self) -> C: return C()

[file mod4.py]
class C:
    def foo(self) -> int: return 1

[rechecked mod3, mod2, mod1]
[stale mod3, mod2]
[out1]
tmp/mod3.py:5: error: Incompatible types in assignment (expression has type "str", variable has type "int")
tmp/mod1.py:3: error: Revealed type is 'builtins.int'

[out2]
tmp/mod1.py:3: error: Revealed type is 'builtins.int'

[case testIncrementalIncidentalChangeWithBugCausesPropagation]
import mod1

[file mod1.py]
from mod2 import A
val = A().makeB().makeC().foo()
reveal_type(val)

[file mod2.py]
from mod3 import B
class A:
    def makeB(self) -> B: return B()

[file mod3.py]
from mod4 import C
class B:
    def makeC(self) -> C:
        val = 3  # type: int
        val = "str"   # deliberately triggering error
        return C()

[file mod4.py]
class C:
    def foo(self) -> int: return 1

[file mod4.py.2]
class C:
    def foo(self) -> str: return 'a'

[rechecked mod4, mod3, mod2, mod1]
[stale mod4]
[out1]
tmp/mod3.py:5: error: Incompatible types in assignment (expression has type "str", variable has type "int")
tmp/mod1.py:3: error: Revealed type is 'builtins.int'

[out2]
tmp/mod3.py:5: error: Incompatible types in assignment (expression has type "str", variable has type "int")
tmp/mod1.py:3: error: Revealed type is 'builtins.str'

[case testIncrementalIncidentalChangeWithBugFixCausesPropagation]
import mod1

[file mod1.py]
from mod2 import A
val = A().makeB().makeC().foo()
reveal_type(val)

[file mod2.py]
from mod3 import B
class A:
    def makeB(self) -> B: return B()

[file mod3.py]
from mod4 import C
class B:
    def makeC(self) -> C:
        val = 3  # type: int
        val = "str"   # deliberately triggering error
        return C()

[file mod3.py.2]
from mod4 import C
class B:
    def makeC(self) -> C: return C()

[file mod4.py]
class C:
    def foo(self) -> int: return 1

[file mod4.py.2]
class C:
    def foo(self) -> str: return 'a'

[rechecked mod4, mod3, mod2, mod1]
[stale mod4, mod3, mod2]
[out1]
tmp/mod3.py:5: error: Incompatible types in assignment (expression has type "str", variable has type "int")
tmp/mod1.py:3: error: Revealed type is 'builtins.int'

[out2]
tmp/mod1.py:3: error: Revealed type is 'builtins.str'

[case testIncrementalSilentImportsWithInnerImports]
# cmd: mypy -m main foo
# flags: --ignore-missing-imports

[file main.py]
from foo import MyClass
m = MyClass()

[file main.py.2]
from foo import MyClass
m = MyClass()
reveal_type(m.val)

[file foo.py]
class MyClass:
    def __init__(self) -> None:
        import unrelated
        self.val = unrelated.test()

[rechecked main]
[stale]
[out2]
tmp/main.py:3: error: Revealed type is 'Any'

[case testIncrementalSilentImportsWithInnerImportsAndNewFile]
# cmd: mypy -m main foo
# cmd2: mypy -m main foo unrelated
# flags: --follow-imports=skip

[file main.py]
from foo import MyClass
m = MyClass()

[file main.py.2]
from foo import MyClass
m = MyClass()
reveal_type(m.val)

[file foo.py]
class MyClass:
    def __init__(self) -> None:
        import unrelated
        self.val = unrelated.test()

[file unrelated.py]
def test() -> str: return "foo"

[rechecked main, foo, unrelated]
[stale foo, unrelated]
[out2]
tmp/main.py:3: error: Revealed type is 'builtins.str'

[case testIncrementalWorksWithNestedClasses]
import foo

[file foo.py]
class MyClass:
    class NestedClass:
        pass

    class_attr = NestedClass()

[rechecked]
[stale]

[case testIncrementalWorksWithBasicProtocols]
import a
[file a.py]
from b import P

x: int
y: P[int]
x = y.meth()

class C:
    def meth(self) -> int:
        pass
y = C()

[file a.py.2]
from b import P

x: str
y: P[str]
x = y.meth()

class C:
    def meth(self) -> str:
        pass
y = C()
[file b.py]
from typing import Protocol, TypeVar

T = TypeVar('T', covariant=True)
class P(Protocol[T]):
    def meth(self) -> T:
        pass

[case testIncrementalSwitchFromNominalToStructural]
import a
[file a.py]
from b import B, fun
class C(B):
    def x(self) -> int: pass
    def y(self) -> int: pass
fun(C())

[file b.py]
from typing import Protocol
class B:
    def x(self) -> float: pass
def fun(arg: B) -> None:
    arg.x()

[file b.py.2]
from typing import Protocol
class B(Protocol):
    def x(self) -> float: pass
def fun(arg: B) -> None:
    arg.x()

[file a.py.3]
from b import fun
class C:
    def x(self) -> int: pass
    def y(self) -> int: pass
fun(C())
[out1]
[out2]
[out3]

[case testIncrementalSwitchFromStructuralToNominal]
import a
[file a.py]
from b import fun
class C:
    def x(self) -> int: pass
    def y(self) -> int: pass
fun(C())

[file b.py]
from typing import Protocol
class B(Protocol):
    def x(self) -> float: pass
def fun(arg: B) -> None:
    arg.x()

[file b.py.2]
from typing import Protocol
class B:
    def x(self) -> float: pass
def fun(arg: B) -> None:
    arg.x()

[out1]
[out2]
tmp/a.py:5: error: Argument 1 to "fun" has incompatible type "C"; expected "B"

[case testIncrementalWorksWithNamedTuple]
import foo

[file foo.py]
from mid import MyTuple
def accept_int(x: int) -> None: pass
accept_int(MyTuple(1, "b", "c").a)

[file mid.py]
from bar import MyTuple

[file bar.py]
from typing import NamedTuple
MyTuple = NamedTuple('MyTuple', [
    ('a', int),
    ('b', str),
    ('c', str)
])

[file bar.py.2]
from typing import NamedTuple
MyTuple = NamedTuple('MyTuple', [
    ('b', int),  # a and b are swapped
    ('a', str),
    ('c', str)
])

[rechecked bar, mid, foo]
[stale bar]
[out2]
tmp/foo.py:3: error: Argument 1 to "accept_int" has incompatible type "str"; expected "int"

[case testIncrementalWorksWithNestedNamedTuple]
import foo

[file foo.py]
from mid import Outer
def accept_int(x: int) -> None: pass
accept_int(Outer.MyTuple(1, "b", "c").a)

[file mid.py]
from bar import Outer

[file bar.py]
from typing import NamedTuple
class Outer:
    MyTuple = NamedTuple('MyTuple', [
        ('a', int),
        ('b', str),
        ('c', str)
    ])

[file bar.py.2]
from typing import NamedTuple
class Outer:
    MyTuple = NamedTuple('MyTuple', [
        ('b', int),  # a and b are swapped
        ('a', str),
        ('c', str)
    ])

[rechecked bar, mid, foo]
[stale bar]
[out2]
tmp/foo.py:3: error: Argument 1 to "accept_int" has incompatible type "str"; expected "int"

[case testIncrementalPartialSubmoduleUpdate]
# cmd: mypy -m a
# cmd2: mypy -m a a.c
# flags: --follow-imports=skip

[file a/__init__.py]
from .b import B
from .c import C

[file a/b.py]
class B: pass

[file a/c.py]
class C: pass

[file a/c.py.2]
class C: pass
pass

[rechecked a, a.c]
[stale a, a.c]
[out]

[case testIncrementalNestedClassRef]
import top

[file top.py]
from funcs import callee
from classes import Outer
def caller(a: Outer.Inner) -> None:
    callee(a)

[file funcs.py]
from classes import Outer
def callee(a: Outer.Inner) -> None:
    pass

[file classes.py]
class Outer:
    class Inner:
        pass

[file top.py.2]
from funcs import callee
from classes import Outer
def caller(a: Outer.Inner) -> int:
    callee(a)
    return 0

[case testIncrementalLoadsParentAfterChild]
# cmd: mypy -m r.s

[file r/__init__.py]
from . import s

[file r/m.py]
class R: pass

[file r/s.py]
from . import m
R = m.R
a = None  # type: R

[file r/s.py.2]
from . import m
R = m.R
a = None  # type: R

[case testIncrementalBaseClassAttributeConflict]
class A: pass
class B: pass

class X:
    attr = None  # type: A
class Y:
    attr = None  # type: B
class Z(X, Y): pass
[stale]
[out]
main:8: error: Definition of "attr" in base class "X" is incompatible with definition in base class "Y"
[out2]
main:8: error: Definition of "attr" in base class "X" is incompatible with definition in base class "Y"

[case testIncrementalFollowImportsSilent]
# flags: --follow-imports=silent
import a
[file a.py]
x = 0
[file a.py.2]
x = 0
x + ''

[case testIncrementalFollowImportsSkip]
# flags: --follow-imports=skip
import a
reveal_type(a.x)
[file a.py]
/
[file a.py.2]
//
[out]
main:3: error: Revealed type is 'Any'
[out2]
main:3: error: Revealed type is 'Any'

[case testIncrementalFollowImportsError]
# flags: --follow-imports=error
import a
[file a.py]
/
[file a.py.2]
//
[out1]
main:2: note: Import of 'a' ignored
main:2: note: (Using --follow-imports=error, module not passed on command line)
[out2]
main:2: note: Import of 'a' ignored
main:2: note: (Using --follow-imports=error, module not passed on command line)

[case testIncrementalFollowImportsVariable]
# flags: --config-file tmp/mypy.ini
import a
reveal_type(a.x)
[file a.py]
x = 0
[file mypy.ini]
[[mypy]
follow_imports = normal
[file mypy.ini.2]
[[mypy]
follow_imports = skip
[out1]
main:3: error: Revealed type is 'builtins.int'
[out2]
main:3: error: Revealed type is 'Any'

[case testIncrementalNamedTupleInMethod]
from ntcrash import nope
[file ntcrash.py]
from typing import NamedTuple
class C:
    def f(self) -> None:
        A = NamedTuple('A', [('x', int), ('y', int)])
[out1]
main:1: error: Module 'ntcrash' has no attribute 'nope'
[out2]
main:1: error: Module 'ntcrash' has no attribute 'nope'

[case testIncrementalNamedTupleInMethod2]
from ntcrash import nope
[file ntcrash.py]
from typing import NamedTuple
class C:
    class D:
        def f(self) -> None:
            A = NamedTuple('A', [('x', int), ('y', int)])
[out1]
main:1: error: Module 'ntcrash' has no attribute 'nope'
[out2]
main:1: error: Module 'ntcrash' has no attribute 'nope'

[case testIncrementalNamedTupleInMethod3]
from ntcrash import nope
[file ntcrash.py]
from typing import NamedTuple
class C:
    def a(self):
        class D:
            def f(self) -> None:
                A = NamedTuple('A', [('x', int), ('y', int)])
[out1]
main:1: error: Module 'ntcrash' has no attribute 'nope'
[out2]
main:1: error: Module 'ntcrash' has no attribute 'nope'

[case testIncrementalTypedDictInMethod]
from tdcrash import nope
[file tdcrash.py]
from mypy_extensions import TypedDict
class C:
    def f(self) -> None:
        A = TypedDict('A', {'x': int, 'y': int})
[builtins fixtures/dict.pyi]
[out1]
main:1: error: Module 'tdcrash' has no attribute 'nope'
[out2]
main:1: error: Module 'tdcrash' has no attribute 'nope'

[case testIncrementalTypedDictInMethod2]
from tdcrash import nope
[file tdcrash.py]
from mypy_extensions import TypedDict
class C:
    class D:
        def f(self) -> None:
            A = TypedDict('A', {'x': int, 'y': int})
[builtins fixtures/dict.pyi]
[out1]
main:1: error: Module 'tdcrash' has no attribute 'nope'
[out2]
main:1: error: Module 'tdcrash' has no attribute 'nope'

[case testIncrementalTypedDictInMethod3]
from tdcrash import nope
[file tdcrash.py]
from mypy_extensions import TypedDict
class C:
    def a(self):
        class D:
            def f(self) -> None:
                A = TypedDict('A', {'x': int, 'y': int})
[builtins fixtures/dict.pyi]
[out1]
main:1: error: Module 'tdcrash' has no attribute 'nope'
[out2]
main:1: error: Module 'tdcrash' has no attribute 'nope'

[case testIncrementalInnerClassAttrInMethod]
import crash
nonexisting
[file crash.py]
class C:
    def f(self) -> None:
        class A:
            pass
        self.a = A()
[out1]
main:2: error: Name 'nonexisting' is not defined
[out2]
main:2: error: Name 'nonexisting' is not defined

[case testIncrementalInnerClassAttrInMethodReveal]
import crash
reveal_type(crash.C().a)
reveal_type(crash.D().a)
[file crash.py]
from typing import TypeVar, Generic
T = TypeVar('T')
class C:
    def f(self) -> None:
        class A:
            pass
        self.a = A()
reveal_type(C().a)
class D:
    def f(self) -> None:
        class A:
            def g(self) -> None:
                class B(Generic[T]):
                    pass
                self.b = B[int]()
        self.a = A().b
reveal_type(D().a)
[out1]
tmp/crash.py:8: error: Revealed type is 'crash.A@5'
tmp/crash.py:17: error: Revealed type is 'crash.B@13[builtins.int*]'
main:2: error: Revealed type is 'crash.A@5'
main:3: error: Revealed type is 'crash.B@13[builtins.int*]'
[out2]
tmp/crash.py:8: error: Revealed type is 'crash.A@5'
tmp/crash.py:17: error: Revealed type is 'crash.B@13[builtins.int*]'
main:2: error: Revealed type is 'crash.A@5'
main:3: error: Revealed type is 'crash.B@13[builtins.int*]'

[case testGenericMethodRestoreMetaLevel]
from typing import Dict

d = {}  # type: Dict[str, int]
g = d.get  # This should not crash: see https://github.com/python/mypy/issues/2804
[builtins fixtures/dict.pyi]

[case testGenericMethodRestoreMetaLevel2]
from typing import TypeVar

T = TypeVar('T')

class D:
    def m(self, x: T) -> T:
        return x

g = D().m  # This should not crash: see https://github.com/python/mypy/issues/2804
[builtins fixtures/dict.pyi]

[case testGenericMethodRestoreMetaLevel3]
from typing import TypeVar
T = TypeVar('T')

class C:
    def m(self, x: T) -> T:
        return x

class D(C):
    def __init__(self) -> None:
        self.d = super().m # This should not crash: see https://github.com/python/mypy/issues/2804
[builtins fixtures/dict.pyi]

[case testIncrementalPerFileFlags]
# flags: --config-file tmp/mypy.ini
import a
[file a.py]
pass
[file mypy.ini]
[[mypy]
warn_no_return = False
[[mypy-a]
warn_no_return = True
[rechecked]

[case testIncrementalClassVar]
from typing import ClassVar
class A:
    x = None  # type: ClassVar
A().x = 0
[out1]
main:4: error: Cannot assign to class variable "x" via instance
[out2]
main:4: error: Cannot assign to class variable "x" via instance

[case testIncrementalClassVarGone]
import m
m.A().x = 0
[file m.py]
from typing import ClassVar
class A:
    x = None  # type: ClassVar[int]
[file m.py.2]
class A:
    x = None  # type: int
[out1]
main:2: error: Cannot assign to class variable "x" via instance

[case testCachingClassVar]
import b
[file a.py]
from typing import ClassVar
class A:
    x = None  # type: ClassVar[int]
[file b.py]
import a
[file b.py.2]
import a
a.A().x = 0
[out2]
tmp/b.py:2: error: Cannot assign to class variable "x" via instance

[case testSerializeTypedDict]
import b
reveal_type(b.x)
y: b.A
reveal_type(y)
[file b.py]
from mypy_extensions import TypedDict
A = TypedDict('A', {'x': int, 'y': str})
x: A
[builtins fixtures/dict.pyi]
[out1]
main:2: error: Revealed type is 'TypedDict('b.A', {'x': builtins.int, 'y': builtins.str})'
main:4: error: Revealed type is 'TypedDict('b.A', {'x': builtins.int, 'y': builtins.str})'
[out2]
main:2: error: Revealed type is 'TypedDict('b.A', {'x': builtins.int, 'y': builtins.str})'
main:4: error: Revealed type is 'TypedDict('b.A', {'x': builtins.int, 'y': builtins.str})'

[case testSerializeMetaclass]
import b
reveal_type(b.A.f())
m: b.M = b.A
reveal_type(b.a.f())
[file b.py]
from typing import Type

class M(type):
    def f(cls) -> int: return 0
class A(metaclass=M): pass
a: Type[A]
[out]
main:2: error: Revealed type is 'builtins.int'
main:4: error: Revealed type is 'builtins.int'
[out2]
main:2: error: Revealed type is 'builtins.int'
main:4: error: Revealed type is 'builtins.int'

[case testSerializeMetaclassInImportCycle1]
import b
import c
reveal_type(b.A.f())
m: c.M = b.A
reveal_type(b.a.f())
[file b.py]
from typing import Type
from c import M
class A(metaclass=M): pass
a: Type[A]
[file c.py]
class M(type):
    def f(cls) -> int: return 0
[out]
main:3: error: Revealed type is 'builtins.int'
main:5: error: Revealed type is 'builtins.int'
[out2]
main:3: error: Revealed type is 'builtins.int'
main:5: error: Revealed type is 'builtins.int'

-- TODO: Add another test for metaclass in import cycle (reversed from the above test).
--       This currently does not work.

[case testDeleteFile]
import n
[file n.py]
import m
[file m.py]
x = 1
[delete m.py.2]
[rechecked n]
[stale]
[out2]
tmp/n.py:1: error: Cannot find module named 'm'
tmp/n.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)

[case testDeleteFileWithinCycle]
import a
[file a.py]
import b
[file b.py]
import c
[file c.py]
import a
[file a.py.2]
import c
[delete b.py.2]
[rechecked a, c]
[stale a]
[out2]

[case testThreePassesBasic]
import m
[file m.py]
def foo():
    pass
[file m.py.2]
def foo() -> None:
    pass
[file m.py.3]
def foo():
    pass
[rechecked m]
[stale m]
[rechecked2 m]
[stale2 m]
[out3]

[case testThreePassesErrorInThirdPass]
import m
[file m.py]
def foo():
    pass
[file m.py.2]
def foo() -> None:
    pass
[file m.py.3]
def foo() -> int:
    return ''
[rechecked m]
[stale m]
[rechecked2 m]
[stale2]
[out3]
tmp/m.py:2: error: Incompatible return value type (got "str", expected "int")

[case testThreePassesThirdPassFixesError]
import n
[file n.py]
import m
x = m.foo(1)
[file m.py]
def foo(x):
    pass
[file m.py.2]
def foo() -> str:
    pass
[file m.py.3]
def foo(x) -> int:
    pass
[rechecked m, n]
[stale m]
[rechecked2 m, n]
[stale2 m, n]
[out2]
tmp/n.py:2: error: Too many arguments for "foo"
[out3]

--
-- Quick mode
--

[case testQuickAndDirtyInterfaceChangeDoesNotPropagate]
# flags: --quick-and-dirty
import b, c
[file a.py]
def a(): pass
[file b.py]
import a
import c
[file c.py]
import a
import b
[file a.py.2]
def a(x): pass
[rechecked a]
[stale a]

[case testQuickAndDirtyDoesNotInvalidateImportCycle]
# flags: --quick-and-dirty
import b, c
[file a.py]
def a(): pass
[file b.py]
import a
import c
[file c.py]
import a
import b
[file b.py.2]
import a
import c
x = 0
[rechecked b]
[stale b]

[case testQuickAndDirtySwitchToIncrementalMode]
# flags: --quick-and-dirty
# flags2: --incremental
import a, b
[file a.py]
import b
[file b.py]
import a
[rechecked a, b, builtins]
[stale a, b, builtins]

[case testQuickAndDirtyFixErrorInExistingFunction]
# flags: --quick-and-dirty
import a, b
[file a.py]
import b
def foo() -> int: return ''
[file b.py]
import a
[file a.py.2]
def foo() -> int: return 0
[out1]
tmp/a.py:2: error: Incompatible return value type (got "str", expected "int")
[out2]
[rechecked a]
[stale a]

[case testQuickAndDirtyIntroduceErrorInNewFunction]
# flags: --quick-and-dirty
import a, b
[file a.py]
import b
[file b.py]
import a
[file a.py.2]
import b
def foo() -> int: return ''
[out1]
[out2]
tmp/a.py:2: error: Incompatible return value type (got "str", expected "int")
[rechecked a]
[stale]

[case testQuickAndDirtyPersistingError]
# flags: --quick-and-dirty
import a, b
[file a.py]
import b
def foo() -> int: return ''
[file b.py]
import a
[file a.py.2]
import b
def foo() -> int: return 0.5
[out1]
tmp/a.py:2: error: Incompatible return value type (got "str", expected "int")
[out2]
tmp/a.py:2: error: Incompatible return value type (got "float", expected "int")
[rechecked a]
[stale]

[case testQuickAndDirtyIntroduceReferencesWithinCycle]
# flags: --quick-and-dirty
import a, b
[file a.py]
import b
[file b.py]
import a
class C: pass
def f() -> int: pass
[file a.py.2]
import b
reveal_type(b.C)
reveal_type(b.f)
[out1]
[out2]
tmp/a.py:2: error: Revealed type is 'def () -> b.C'
tmp/a.py:3: error: Revealed type is 'def () -> builtins.int'
[rechecked a]
[stale]

[case testQuickAndDirtyIntroduceReferencesWithinCycle2]
# flags: --quick-and-dirty
import a, b
[file a.py]
import b
class C: pass
def f() -> int: pass
[file b.py]
import a
[file b.py.2]
import a
reveal_type(a.C)
reveal_type(a.f)
[out1]
[out2]
tmp/b.py:2: error: Revealed type is 'def () -> a.C'
tmp/b.py:3: error: Revealed type is 'def () -> builtins.int'
[rechecked b]
[stale]

[case testQuickAndDirtyIntroduceReferencesWithinCycleNoError]
# flags: --quick-and-dirty
import a, b, c
[file a.py]
import b
[file b.py]
import a
class C: pass
def f() -> int: pass
[file c.py]
[file a.py.2]
import b
def g() -> b.C: pass
h = b.f
[file c.py.3]
import a
reveal_type(a.g)
reveal_type(a.h)
[out1]
[out2]
[out3]
tmp/c.py:2: error: Revealed type is 'def () -> b.C'
tmp/c.py:3: error: Revealed type is 'def () -> builtins.int'
[rechecked a]
[stale a]
[rechecked2 c]
[stale2]

[case testQuickAndDirtyIntroduceReferencesWithinCycleNoError2]
# flags: --quick-and-dirty
import a, b, c
[file a.py]
import b
class C: pass
def f() -> int: pass
[file b.py]
import a
[file c.py]
[file b.py.2]
import a
def g() -> a.C: pass
h = a.f
[file c.py.3]
import b
reveal_type(b.g)
reveal_type(b.h)
[out1]
[out2]
[out3]
tmp/c.py:2: error: Revealed type is 'def () -> a.C'
tmp/c.py:3: error: Revealed type is 'def () -> builtins.int'
[rechecked b]
[stale b]
[rechecked2 c]
[stale2]

-- (The behavior for blockers is actually no different than in regular incremental mode)
[case testQuickAndDirtyBlockerOnFirstRound]
# flags: --quick-and-dirty
import a, b
[file a.py]
import b
class B(C): pass
class C(B): pass  # blocker
[file b.py]
import a
[file a.py.2]
import b
class B: pass
class C(B): pass
[out1]
tmp/a.py:3: error: Cycle in inheritance hierarchy
[out2]
[rechecked a, b]
[stale a, b]

[case testQuickAndDirtyBlockerOnSecondRound]
# flags: --quick-and-dirty
import a, b
[file a.py]
import b
class B: pass
class C(B): pass
[file b.py]
import a
[file a.py.2]
import b
class B(C): pass
class C(B): pass  # blocker
[out1]
[out2]
tmp/a.py:3: error: Cycle in inheritance hierarchy
[rechecked a, b]
[stale a, b]

[case testQuickAndDirtyRenameFunctionInTwoModules]
# flags: --quick-and-dirty
import a, b, c, d
[file a.py]
import d
def f(): pass
[file b.py]
from a import f
[file c.py]
from b import f
[file d.py]
from c import f
[file a.py.2]
import d
def g(): pass  # renamed f to g
[file c.py.2]
from a import g

[case testQuickAndDirtyUnmodifiedModuleDoesNotGenerateError]
# flags: --quick-and-dirty
import a, b, c, d
[file a.py]
import d
class C:
    def f(self): pass
[file b.py]
from a import C
[file c.py]
from b import C
[file d.py]
from c import C
C().f()  # no error because unmodified
[file a.py.2]
import d
class C:
    def g(self): pass  # renamed f to g
[file c.py.2]
from a import C
[out1]
[out2]

[case testQuickAndDirtyUnmodifiedModuleDoesNotGenerateError2]
# flags: --quick-and-dirty
import a, b, c
[file a.py]
import c
class C:
    x = 0
[file b.py]
import a
x = a.C.x  # type: int
[file c.py]
import b
x = b.x
[file a.py.2]
import c
class C:
    pass  # Removed x
[out1]
[out2]
[rechecked a]
[stale a]

[case testQuickAndDirtyTypeAliasReference]
# flags: --quick-and-dirty
import a, b
[file a.py]
import b
def f(x: b.S) -> b.S: return x
[file b.py]
import a
S = str
[file a.py.2]
import b
def f(x: b.S) -> int: return 0

[case testQuickAndDirtyNamedTupleReference]
# flags: --quick-and-dirty
import a, b
[file a.py]
import b
def f(x: b.P) -> b.P: return x
[file b.py]
from typing import NamedTuple
import a
P = NamedTuple('P', (('x', int),))
[file a.py.2]
import b
def f(x: b.P) -> int: return 0

[case testQuickAndDirtyTypeVarReference]
# flags: --quick-and-dirty
import a, b
[file a.py]
import b
def f(x: b.T) -> b.T: return x
[file b.py]
from typing import TypeVar
import a
T = TypeVar('T')
[file a.py.2]
import b
def f(x: b.T) -> int: return 0

[case testQuickAndDirtyDeleteFunctionUsedByOtherModule]
# flags: --quick-and-dirty
import a
[file a.py]
from b import f
[file b.py]
import a
def f() -> int: pass
a.f()
[file b.py.2]
import a
reveal_type(a.f)
[out2]
tmp/b.py:2: error: Revealed type is 'def () -> <stale cache: consider running mypy without --quick>'

[case testQuickAndDirtyDeleteClassUsedInAnnotation]
# flags: --quick-and-dirty
import a
[file a.py]
import b
def f() -> b.C: pass
[file b.py]
import a
class C: pass
[file b.py.2]
import a
reveal_type(a.f)
a.f().x
[out2]
tmp/b.py:2: error: Revealed type is 'def () -> <stale cache: consider running mypy without --quick>'
tmp/b.py:3: error: "<stale cache: consider running mypy without --quick>" has no attribute "x"

[case testQuickAndDirtyDeleteSuperClass]
# flags: --quick-and-dirty
import a
[file a.py]
from b import Foo
z = (1, Foo())

class Bar:
    pass
[file b.py]
from e import Quux
class Baz:
    pass
class Foo(Baz, Quux):
    pass
[file e.py]
from a import Bar
class Quux(Bar):
    pass

[file a.py.2]
from b import Foo
z = (1, Foo())
[out]
[out2]

[case testQuickAndDirtyDeleteClassUsedAsBase]
# flags: --quick-and-dirty
import a
[file a.py]
import b
class D(b.C): pass
[file b.py]
import a
class C: pass
[file b.py.2]
import a
reveal_type(a.D)
a.D().x
[out2]
tmp/b.py:2: error: Revealed type is 'def () -> a.D'
tmp/b.py:3: error: "D" has no attribute "x"

[case testQuickAndDirtyDeleteNestedClassUsedInAnnotation]
# flags: --quick-and-dirty
import a
[file a.py]
import b
def f() -> b.C.D: pass
[file b.py]
import a
class C:
    class D: pass
[file b.py.2]
import a
class C:
    pass
reveal_type(a.f)
a.f().x
[out2]
tmp/b.py:4: error: Revealed type is 'def () -> <stale cache: consider running mypy without --quick>'
tmp/b.py:5: error: "<stale cache: consider running mypy without --quick>" has no attribute "x"

[case testQuickAndDirtyTurnGenericClassIntoNonGeneric-skip]
# flags: --quick-and-dirty
import a
[file a.py]
import b
def f() -> b.C[int]: pass
[file b.py]
from typing import TypeVar, Generic
import a
T = TypeVar('T')
class C(Generic[T]): pass
[file b.py.2]
import a
class C: pass
reveal_type(a.f)
c: C
d = a.f()
c = d
d = c
[out2]
# TODO: Crashes (https://github.com/python/mypy/issues/3279)

[case testQuickAndDirtyTurnClassIntoGenericOne-skip]
# flags: --quick-and-dirty
import a
[file a.py]
import b
def f() -> b.C: pass
[file b.py]
import a
class C: pass
[file b.py.2]
from typing import TypeVar, Generic
import a
T = TypeVar('T')
class C(Generic[T]): pass
reveal_type(a.f)
c: C[int]
d = a.f()
d = c
c = d
[out2]
# TODO: Crashes (https://github.com/python/mypy/issues/3279)

[case testQuickAndDirtyDeleteTypeVarUsedInAnnotation]
# flags: --quick-and-dirty
import a
[file a.py]
import b
def f(x: b.T) -> b.T: return x
[file b.py]
from typing import TypeVar
import a
T = TypeVar('T')
[file b.py.2]
import a
reveal_type(a.f)
reveal_type(a.f(1))
[out2]
tmp/b.py:2: error: Revealed type is 'def [b.T] (x: b.T`-1) -> b.T`-1'
tmp/b.py:3: error: Revealed type is 'builtins.int*'

[case testQuickAndDirtyDeleteNewTypeUsedInAnnotation]
# flags: --quick-and-dirty
import a
[file a.py]
import b
def f() -> b.C: pass
[file b.py]
from typing import NewType
import a
C = NewType('C', int)
[file b.py.2]
import a
reveal_type(a.f)
a.f().x
[out2]
tmp/b.py:2: error: Revealed type is 'def () -> <stale cache: consider running mypy without --quick>'
tmp/b.py:3: error: "<stale cache: consider running mypy without --quick>" has no attribute "x"

[case testQuickAndDirtyChangeClassIntoFunction]
# flags: --quick-and-dirty
import a
[file a.py]
import b
def f() -> b.C: pass
[file b.py]
import a
class C: pass
[file b.py.2]
import a
def C() -> None: pass
reveal_type(a.f)
a.f().x
[out2]
tmp/b.py:3: error: Revealed type is 'def () -> <stale cache: consider running mypy without --quick>'
tmp/b.py:4: error: "<stale cache: consider running mypy without --quick>" has no attribute "x"

[case testQuickAndDirtyChangeClassIntoVariable]
# flags: --quick-and-dirty
import a
[file a.py]
import b
def f() -> b.C: pass
[file b.py]
import a
class C: pass
[file b.py.2]
import a
C = 0
reveal_type(a.f)
a.f().x
[out2]
tmp/b.py:3: error: Revealed type is 'def () -> <stale cache: consider running mypy without --quick>'
tmp/b.py:4: error: "<stale cache: consider running mypy without --quick>" has no attribute "x"

[case testQuickAndDirtyAddFile]
# flags: --quick-and-dirty
import a
[file a.py]
import b
x = ''
[file b.py]
import a
[file b.py.2]
import c
reveal_type(c.x)
[file c.py.2]
import a
x = 1
reveal_type(a.x)
[rechecked b, c]
[stale]
[out2]
tmp/c.py:3: error: Revealed type is 'builtins.str'
tmp/b.py:2: error: Revealed type is 'builtins.int'

[case testQuickAndDirtyDeleteFile]
# flags: --quick-and-dirty
import b
[file a.py]
def f() -> None: pass
[file b.py]
import a
a.f()
[delete a.py.2]
[file b.py.3]
import a
a.f() # Comment change
[file b.py.4]
# Remove import
[rechecked b]
[stale]
[rechecked2 b]
[stale2]
[rechecked3 b]
[stale3 b]
[out2]
tmp/b.py:1: error: Cannot find module named 'a'
tmp/b.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
[out3]
tmp/b.py:1: error: Cannot find module named 'a'
tmp/b.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
[out4]

[case testQuickAndDirtyRenameModule]
# flags: --quick-and-dirty
import a
[file a.py]
import b
b.f()
[file b.py]
def f() -> None: pass
[delete b.py.2]
[file c.py.2]
def f() -> None: pass
[file a.py.2]
import c
c.f(1)
[file c.py.3]
def f() -> None: pass # comment change
[file c.py.4]
def f(x) -> None: pass
[out]
[out2]
tmp/a.py:2: error: Too many arguments for "f"
[out3]
tmp/a.py:2: error: Too many arguments for "f"
[out4]
[rechecked a, c]
[stale c]
[rechecked2 a, c]
[stale2]
[rechecked3 a, c]
[stale3 a, c]

[case testQuickAndDirtyMultiplePasses]
# flags: --quick-and-dirty
import a
[file a.py]
import b
b.f()
[file b.py]
def f() -> None: pass
[file b.py.2]
# Write cache file but the error in a is not caught yet.
def f(x) -> None: pass
[file a.py.3]
# Editing a triggers the error.
import b
b.f()
[rechecked b]
[rechecked2 a]
[out2]
[out3]
tmp/a.py:3: error: Too few arguments for "f"

[case testQuickAndDirtySerializeStaleType]
# flags: --quick-and-dirty
import a, c
[file a.py]
import b
def f() -> b.C: pass
[file b.py]
import a
class C: pass
[file c.py]
[file b.py.2]
import a
x = a.f()
[file c.py.3]
import b
reveal_type(b.x)
def g(x: object) -> None: pass
g(b.x)
b.x.y
[rechecked b]
[stale b]
[rechecked2 c]
[stale2]
[out3]
tmp/c.py:2: error: Revealed type is '<stale cache: consider running mypy without --quick>'
tmp/c.py:5: error: "<stale cache: consider running mypy without --quick>" has no attribute "y"

[case testCacheDeletedAfterErrorsFound]
import a
[file a.py]
from b import x
[file b.py]
from c import x
[file c.py]
x = 1
[file c.py.2]
1 + 1
[file a.py.3]
from b import x
1 + 1
[out]
[out2]
tmp/b.py:1: error: Module 'c' has no attribute 'x'
[out3]
tmp/b.py:1: error: Module 'c' has no attribute 'x'

[case testCacheDeletedAfterErrorsFound2]
import a
[file a.py]
from b import x
[file b.py]
from c import C
x: C
[file c.py]
class C: pass
[file c.py.2]
def C(): pass
[file a.py.3]
from b import x
1 + 1
[out]
[out2]
tmp/b.py:2: error: Invalid type "c.C"
[out3]
tmp/b.py:2: error: Invalid type "c.C"

[case testCacheDeletedAfterErrorsFound3]
import a
[file a.py]
import b
b.f()
[file b.py]
def f() -> None: pass
[file b.py.2]
def f(x) -> None: pass
[out]
[out2]
tmp/a.py:2: error: Too few arguments for "f"
[out3]
tmp/a.py:2: error: Too few arguments for "f"

[case testCacheDeletedAfterErrorsFound4]
import a
[file a.py]
from b import x
[file b.py]
from c import x
[file c.py]
from d import x
[file d.py]
x = 1
[file d.py.2]
1 + 1
[file a.py.3]
from b import x
1 + 1
[out]
[out2]
tmp/c.py:1: error: Module 'd' has no attribute 'x'
[out3]
tmp/c.py:1: error: Module 'd' has no attribute 'x'

[case testNoCrashOnDeletedWithCacheOnCmdline]
# cmd: mypy -m nonexistent
# cmd2: mypy -m nonexistent
[file nonexistent.py]
[delete nonexistent.py.2]
[out]
[out2]
mypy: can't read file 'tmp/nonexistent.py': No such file or directory

[case testNoCrashOnDoubleImportAliasQuick]
# cmd: mypy -m e
# cmd2: mypy -m c
# cmd3: mypy -m e
# flags: --quick
[file c.py]
from typing import List
Alias = List[int]
[file c.py.2]
from typing import List
Alias = int

[file d.py]
from c import Alias

[file e.py]
from d import Alias
[file e.py.3]
from d import Alias
x: Alias
[out3]
[builtins fixtures/list.pyi]

[case testSerializeAbstractPropertyIncremental]
from abc import abstractmethod
import typing
class A:
    @property
    def f(self) -> int:
        return 1
    @f.setter  # type: ignore
    @abstractmethod
    def f(self, x: int) -> None:
        pass
a = A()
[builtins fixtures/property.pyi]

[case testSerializeAbstractPropertyDisallowUntypedIncremental]
# flags: --disallow-untyped-defs
from abc import abstractmethod
import typing
class A:
    @property
    def f(self) -> int:
        return 1
    @f.setter  # type: ignore
    @abstractmethod
    def f(self, x: int) -> None:
        pass
a = A()
[builtins fixtures/property.pyi]

[case testClassNamesResolutionCrashAccess]
import mod

[file mod.py]
class C:
    def __init__(self) -> None:
        self.int = ''

    def f(self, f: int) -> None:
        pass

[file mod.py.2]
class C:
    def __init__(self) -> None:
        self.int = ''

    def f(self, f: int) -> None:
        f.x

[out]
[out2]
tmp/mod.py:6: error: "int" has no attribute "x"

[case testClassNamesResolutionCrashReadCache]
import mod

[file mod.py]
import submod

[file mod.py.2]
from submod import C

c = C()
reveal_type(c.int)
reveal_type(c.y)

[file submod.py]
from typing import List

class C:
    def __init__(self) -> None:
        self.int = []  # type: List[int]

    def f(self, f: int) -> None:
        self.y = f

[builtins fixtures/list.pyi]
[out]
[out2]
tmp/mod.py:4: error: Revealed type is 'builtins.list[builtins.int]'
tmp/mod.py:5: error: Revealed type is 'builtins.int'

[case testClassNamesResolutionCrashReveal]
import mod

[file mod.py]
class Foo(object):

    def __init__(self) -> None:
        self.bytes = b"foo"

    def bar(self, f: bytes):
        pass

foo = Foo()
foo.bar(b"test")

[file mod.py.2]
class Foo(object):

    def __init__(self) -> None:
        self.bytes = b"foo"

    def bar(self, f: bytes):
        reveal_type(f)

foo = Foo()
foo.bar(b"test")
[out]
[out2]
tmp/mod.py:7: error: Revealed type is 'builtins.bytes'

[case testIncrementalWithSilentImports]
# cmd: mypy -m a
# cmd2: mypy -m b
# flags: --follow-imports=silent
[file a.py]
import b

b.foo(1, 2)

[file b.py]
def foo(a: int, b: int) -> str:
    return a + b

[out1]
[out2]
tmp/b.py:2: error: Incompatible return value type (got "int", expected "str")

[case testForwardNamedTupleToUnionWithOtherNamedTUple]
from typing import NamedTuple, Union

class Person(NamedTuple):
    name: Union[str, "Pair"]

class Pair(NamedTuple):
    first: str
    last: str

Person(name=Pair(first="John", last="Doe"))
[out]

[case testNoCrashForwardRefToBrokenDoubleNewTypeIncremental]
from typing import Any, List, NewType

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

def frob(foos: List[Foos]) -> None:
    pass
[builtins fixtures/list.pyi]
[out]

[case testNoCrashForwardRefOverloadIncremental]
from typing import overload, List

@overload
def f(x: int) -> int: ...
@overload
def f(x: F) -> F: ...
def f(x):
    pass

F = List[int]
[builtins fixtures/list.pyi]
[out]

[case testNoCrashForwardRefOverloadIncrementalClass]
from typing import overload, Tuple, NamedTuple

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

class N(NamedTuple):
    x: A
A = Tuple[int]
[builtins fixtures/tuple.pyi]
[out]

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

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

x: NT = N(1) # type: ignore
x = NT(N(1))
[out]

[case testNewTypeFromForwardTypedDictIncremental]
from typing import NewType, Tuple, Dict
from mypy_extensions import TypedDict

NT = NewType('NT', N) # type: ignore
class N(TypedDict):
    x: A
A = Dict[str, int]
[builtins fixtures/dict.pyi]
[out]

-- Some crazy selef-referential named tuples, types dicts, and aliases
-- to be sure that everything can be _serialized_ (i.e. ForwardRef's are removed).
-- For this reason errors are silenced (tests with # type: ignore have equivalents in other files)

[case testForwardTypeAliasInBase1]
from typing import List
class C(List['A']):
    pass

A = List[int]
x: int = C()[0][0]
[builtins fixtures/list.pyi]
[out]

[case testForwardTypeAliasInBase2]
from typing import List, Generic, TypeVar, NamedTuple
T = TypeVar('T')

class C(A, B): #type: ignore
    pass
class G(Generic[T]): pass
A = G[C]
class B(NamedTuple):
    x: int

C().x
C()[0]
[builtins fixtures/list.pyi]
[out]

[case testSerializeRecursiveAliases1]
from typing import Type, Callable, Union

A = Union[A, int]  # type: ignore
B = Callable[[B], int] # type: ignore
C = Type[C] # type: ignore
[out]

[case testSerializeRecursiveAliases2]
from typing import Type, Callable, Union

A = Union[B, int]  # type: ignore
B = Callable[[C], int] # type: ignore
C = Type[A] # type: ignore
[out]

[case testSerializeRecursiveAliases3]
from typing import Type, Callable, Union, NamedTuple

A = Union[B, int]  # type: ignore
B = Callable[[C], int] # type: ignore
class C(NamedTuple): # type: ignore
    x: A
[out]

[case testGenericTypeAliasesForwardAnyIncremental1]
from typing import TypeVar, Generic
T = TypeVar('T')
S = TypeVar('S')
IntNode = Node[int, S]
AnyNode = Node[S, T]

class Node(Generic[T, S]):
    def __init__(self, x: T, y: S) -> None:
        self.x = x
        self.y = y

def output() -> IntNode[str]:
    return Node(1, 'x')
x = output() # type: IntNode

y = None # type: IntNode
y.x = 1
y.y = 1
y.y = 'x'

z = Node(1, 'x') # type: AnyNode
[out]

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

class Node(Generic[T, S]):
    def __init__(self, x: T, y: S) -> None:
        self.x = x
        self.y = y

def output() -> IntNode[str]:
    return Node(1, 'x')
x = output() # type: IntNode

y = None # type: IntNode
y.x = 1
y.y = 1
y.y = 'x'

z = Node(1, 'x') # type: AnyNode
IntNode = Node[int, S]
AnyNode = Node[S, T]
[out]

[case testNamedTupleForwardAsUpperBoundSerialization]
from typing import NamedTuple, TypeVar, Generic
T = TypeVar('T', bound='M')
class G(Generic[T]):
    x: T

yg: G[M]
z: int = G[M]().x.x
z = G[M]().x[0]
M = NamedTuple('M', [('x', int)])
[out]

[case testSelfRefNTIncremental1]
from typing import Tuple, NamedTuple

Node = NamedTuple('Node', [ # type: ignore
        ('name', str),
        ('children', Tuple['Node', ...]),
    ])
n: Node
[builtins fixtures/tuple.pyi]

[case testSelfRefNTIncremental2]
from typing import Tuple, NamedTuple

A = NamedTuple('A', [ # type: ignore
        ('x', str),
        ('y', Tuple['B', ...]),
    ])
class B(NamedTuple): # type: ignore
    x: A
    y: int

n: A
[builtins fixtures/tuple.pyi]

[case testSelfRefNTIncremental3]
from typing import NamedTuple, Tuple

class B(NamedTuple): # type: ignore
    x: Tuple[A, int]
    y: int
A = NamedTuple('A', [ # type: ignore
        ('x', str),
        ('y', 'B'),
    ])
n: B
m: A
lst = [m, n]
[builtins fixtures/tuple.pyi]

[case testSelfRefNTIncremental4]
from typing import NamedTuple

class B(NamedTuple): # type: ignore
    x: A
    y: int
class A(NamedTuple): # type: ignore
    x: str
    y: B

n: A
[builtins fixtures/tuple.pyi]

[case testSelfRefNTIncremental5]
from typing import NamedTuple

B = NamedTuple('B', [ # type: ignore
        ('x', A),
        ('y', int),
    ])
A = NamedTuple('A', [ # type: ignore
        ('x', str),
        ('y', 'B'),
    ])
n: A
def f(m: B) -> None: pass
[builtins fixtures/tuple.pyi]

[case testCrashWithPartialGlobalAndCycle]
import bar

[file foo.py]
import bar
my_global_dict = {}  # type: ignore
def external_func_0() -> None:
    global my_global_dict
    bar.external_list
    my_global_dict[12] = 0

[file bar.py]
import foo

external_list = [0]

[builtins fixtures/dict.pyi]

[case testIncrementalCrashOnTypeWithFunction]
import a
[file a.py]
import b
[file a.py.2]
from b import x

[file b.py]
from typing import TypeVar, Type
T = TypeVar('T')

def tp(arg: T) -> Type[T]:
    pass
def func(x: int) -> int:
    pass

x = tp(func)
[out]
[out2]

[case testReprocessModuleEvenIfInterfaceHashDoesNotChange]
import a
import d

[file a.py]
import b
x: b.c.A
x = b.c.A()

[file b.py]
import c

[file c.py]
class A:
    x = 1

[file d.py]
import a
def f() -> None: pass

[file a.py.2]
import b
x: b.c.A

[file c.py.3]
class A:
    x = 2

[file d.py.4]
import a
def f() -> None:
    from c import A
    a.x = [A(), a.x][0]

[builtins fixtures/list.pyi]
[stale]
[rechecked a]
[stale2]
[rechecked2 c]
[stale3]
[rechecked3 d]
[out1]
[out2]
[out3]
[out4]

[case testTreeShadowingViaParentPackage]
import m.semanal

[file m/__init__.py]
pass

[file m/nodes.py]
if False:
    import m.types
    import m.semanal
class Node:
    line: int
class FuncBase(Node):
    type: m.types.Type
class OverloadedFuncDef(FuncBase): pass

[file m/types.py]
from m.nodes import Node
class Type(Node): pass
class Overloaded(Type): pass

[file m/semanal.py]
from m.nodes import OverloadedFuncDef
from m.types import Overloaded

class C:
    def func(self, defn: OverloadedFuncDef):
        defn.type = Overloaded()
        defn.type.line = 0

[file m/nodes.py.2]
if False:
    import m.types
    import m.semanal
class Node:
    line: int
class FuncBase(Node):
    type: m.types.Type
class OverloadedFuncDef(FuncBase): pass
extra = 1

[file m/types.py.2]
from m.nodes import Node
class Type(Node): pass
class Overloaded(Type): pass
extra = 1
[builtins fixtures/list.pyi]

[file m/semanal.py.2]
from m.nodes import OverloadedFuncDef
from m.types import Overloaded

class C:
    def func(self, defn: OverloadedFuncDef):
        defn.type = Overloaded()
        defn.type.line = 0

extra = 1

[out1]
[out2]

[case testErrorsAffectDependentsOnly]
# cmd: mypy -m m.a m.b m.c
[file m/__init__.py]
[file m/a.py]
1 + ''  # Deliberate error
[file m/b.py]
import m.a  # Depends on module with error
[file m/c.py]
import m  # No error here
[rechecked m.a, m.b]
[out1]
tmp/m/a.py:1: error: Unsupported operand types for + ("int" and "str")
[out2]
tmp/m/a.py:1: error: Unsupported operand types for + ("int" and "str")

[case testDisallowAnyExprIncremental]
# cmd: mypy -m main
# flags:  --disallow-any-expr

[file ns.py]
class Namespace:
    def __init__(self):
        self.user = 0

[file main.py]
import ns
user = ns.Namespace.user

[out1]
tmp/main.py:2: error: Expression has type "Any"

[out2]
tmp/main.py:2: error: Expression has type "Any"

[case testIncrementalStrictOptional]
# flags: --strict-optional
import a
1 + a.foo()
[file a.py]
def foo() -> int: return 0
[file a.py.2]
from typing import Optional
def foo() -> Optional[int]: return 0
[out1]
[out2]
main:3: error: Unsupported operand types for + ("int" and "None")
main:3: note: Right operand is of type "Optional[int]"

[case testAttrsIncrementalSubclassingCached]
from a import A
import attr
@attr.s(auto_attribs=True)
class B(A):
    e: str = 'e'
a = B(5, [5], 'foo')
a.a = 6
a._b = [2]
a.c = 'yo'
a._d = 22
a.e = 'hi'

[file a.py]
import attr
import attr
from typing import List, ClassVar
@attr.s(auto_attribs=True)
class A:
    a: int
    _b: List[int]
    c: str = '18'
    _d: int = attr.ib(validator=None, default=18)
    E = 7
    F: ClassVar[int] = 22

[builtins fixtures/list.pyi]
[out1]
[out2]

[case testAttrsIncrementalSubclassingCachedConverter]
from a import A
import attr
@attr.s
class B(A):
    pass
reveal_type(B)

[file a.py]
def converter(s:int) -> str:
    return 'hello'

import attr
@attr.s
class A:
    x: str = attr.ib(converter=converter)

[builtins fixtures/list.pyi]
[out1]
main:6: error: Revealed type is 'def (x: builtins.int) -> __main__.B'

[out2]
main:6: error: Revealed type is 'def (x: builtins.int) -> __main__.B'

[case testAttrsIncrementalSubclassingCachedType]
from a import A
import attr
@attr.s
class B(A):
    pass
reveal_type(B)

[file a.py]
import attr
@attr.s
class A:
    x = attr.ib(type=int)

[builtins fixtures/list.pyi]
[out1]
main:6: error: Revealed type is 'def (x: builtins.int) -> __main__.B'
[out2]
main:6: error: Revealed type is 'def (x: builtins.int) -> __main__.B'

[case testAttrsIncrementalArguments]
from a import Frozen, NoInit, NoCmp
f = Frozen(5)
f.x = 6

g = NoInit()

Frozen(1) < Frozen(2)
Frozen(1) <= Frozen(2)
Frozen(1) > Frozen(2)
Frozen(1) >= Frozen(2)

NoCmp(1) < NoCmp(2)
NoCmp(1) <= NoCmp(2)
NoCmp(1) > NoCmp(2)
NoCmp(1) >= NoCmp(2)

[file a.py]
import attr
@attr.s(frozen=True)
class Frozen:
    x: int = attr.ib()
@attr.s(init=False)
class NoInit:
    x: int = attr.ib()
@attr.s(cmp=False)
class NoCmp:
    x: int = attr.ib()

[builtins fixtures/list.pyi]
[rechecked]
[stale]
[out1]
main:3: error: Property "x" defined in "Frozen" is read-only
main:12: error: Unsupported left operand type for < ("NoCmp")
main:13: error: Unsupported left operand type for <= ("NoCmp")
main:14: error: Unsupported left operand type for > ("NoCmp")
main:15: error: Unsupported left operand type for >= ("NoCmp")

[out2]
main:3: error: Property "x" defined in "Frozen" is read-only
main:12: error: Unsupported left operand type for < ("NoCmp")
main:13: error: Unsupported left operand type for <= ("NoCmp")
main:14: error: Unsupported left operand type for > ("NoCmp")
main:15: error: Unsupported left operand type for >= ("NoCmp")

[case testAttrsIncrementalDunder]
from a import A
reveal_type(A)  # E: Revealed type is 'def (a: builtins.int) -> a.A'
reveal_type(A.__eq__)  # E: Revealed type is 'def (self: a.A, other: builtins.object) -> builtins.bool'
reveal_type(A.__ne__)  # E: Revealed type is 'def (self: a.A, other: builtins.object) -> builtins.bool'
reveal_type(A.__lt__)  # E: Revealed type is 'def [AT] (self: AT`-1, other: AT`-1) -> builtins.bool'
reveal_type(A.__le__)  # E: Revealed type is 'def [AT] (self: AT`-1, other: AT`-1) -> builtins.bool'
reveal_type(A.__gt__)  # E: Revealed type is 'def [AT] (self: AT`-1, other: AT`-1) -> builtins.bool'
reveal_type(A.__ge__)  # E: Revealed type is 'def [AT] (self: AT`-1, other: AT`-1) -> builtins.bool'

A(1) < A(2)
A(1) <= A(2)
A(1) > A(2)
A(1) >= A(2)
A(1) == A(2)
A(1) != A(2)

A(1) < 1  # E: Unsupported operand types for < ("A" and "int")
A(1) <= 1  # E: Unsupported operand types for <= ("A" and "int")
A(1) > 1  # E: Unsupported operand types for > ("A" and "int")
A(1) >= 1  # E: Unsupported operand types for >= ("A" and "int")
A(1) == 1
A(1) != 1

1 < A(1)  # E: Unsupported operand types for > ("A" and "int")
1 <= A(1)  # E: Unsupported operand types for >= ("A" and "int")
1 > A(1)  # E: Unsupported operand types for < ("A" and "int")
1 >= A(1)  # E: Unsupported operand types for <= ("A" and "int")
1 == A(1)
1 != A(1)

[file a.py]
from attr import attrib, attrs
@attrs(auto_attribs=True)
class A:
    a: int

[builtins fixtures/attr.pyi]
[rechecked]
[stale]
[out2]
main:2: error: Revealed type is 'def (a: builtins.int) -> a.A'
main:3: error: Revealed type is 'def (self: a.A, other: builtins.object) -> builtins.bool'
main:4: error: Revealed type is 'def (self: a.A, other: builtins.object) -> builtins.bool'
main:5: error: Revealed type is 'def [AT] (self: AT`-1, other: AT`-1) -> builtins.bool'
main:6: error: Revealed type is 'def [AT] (self: AT`-1, other: AT`-1) -> builtins.bool'
main:7: error: Revealed type is 'def [AT] (self: AT`-1, other: AT`-1) -> builtins.bool'
main:8: error: Revealed type is 'def [AT] (self: AT`-1, other: AT`-1) -> builtins.bool'
main:17: error: Unsupported operand types for < ("A" and "int")
main:18: error: Unsupported operand types for <= ("A" and "int")
main:19: error: Unsupported operand types for > ("A" and "int")
main:20: error: Unsupported operand types for >= ("A" and "int")
main:24: error: Unsupported operand types for > ("A" and "int")
main:25: error: Unsupported operand types for >= ("A" and "int")
main:26: error: Unsupported operand types for < ("A" and "int")
main:27: error: Unsupported operand types for <= ("A" and "int")

[case testAttrsIncrementalSubclassModified]
from b import B
B(5, 'foo')

[file a.py]
import attr
@attr.s(auto_attribs=True)
class A:
    x: int

[file b.py]
import attr
from a import A
@attr.s(auto_attribs=True)
class B(A):
    y: str

[file b.py.2]
import attr
from a import A
@attr.s(auto_attribs=True)
class B(A):
    y: int

[builtins fixtures/list.pyi]
[out1]
[out2]
main:2: error: Argument 2 to "B" has incompatible type "str"; expected "int"
[rechecked b]

[case testAttrsIncrementalSubclassModifiedErrorFirst]
from b import B
B(5, 'foo')
[file a.py]
import attr
@attr.s(auto_attribs=True)
class A:
    x: int

[file b.py]
import attr
from a import A
@attr.s(auto_attribs=True)
class B(A):
    y: int

[file b.py.2]
import attr
from a import A
@attr.s(auto_attribs=True)
class B(A):
    y: str

[builtins fixtures/list.pyi]
[out1]
main:2: error: Argument 2 to "B" has incompatible type "str"; expected "int"

[out2]
[rechecked b]

[case testAttrsIncrementalThreeFiles]
from c import C
C(5, 'foo', True)

[file a.py]
import attr
@attr.s
class A:
    a: int = attr.ib()

[file b.py]
import attr
@attr.s
class B:
    b: str = attr.ib()

[file c.py]
from a import A
from b import B
import attr
@attr.s
class C(A, B):
    c: bool = attr.ib()

[builtins fixtures/list.pyi]
[out1]
[out2]

[case testAttrsIncrementalConverterInSubmodule]
from a.a import A
reveal_type(A)
[file a/__init__.py]
[file a/a.py]
from typing import Optional
def converter(s:Optional[int]) -> int:
    ...

import attr
@attr.s
class A:
    x: int = attr.ib(converter=converter)

[builtins fixtures/list.pyi]
[out1]
main:2: error: Revealed type is 'def (x: Union[builtins.int, None]) -> a.a.A'
[out2]
main:2: error: Revealed type is 'def (x: Union[builtins.int, None]) -> a.a.A'

[case testAttrsIncrementalConverterManyStyles]
import a
[file a.py]
from base import Base
Base(1, 'str', True)
Base(None, None, None)

from subclass import A, B
A(1, 'str', True)
A(None, None, None)
B(1, 'str', True, 1, 'str', True)
B(None, None, None, None, None, None)

from submodule.base import SubBase
SubBase(1, 'str', True)
SubBase(None, None, None)

from submodule.subclass import AA, BB
AA(1, 'str', True)
AA(None, None, None)
BB(1, 'str', True, 1, 'str', True)
BB(None, None, None, None, None, None)

from submodule.subsubclass import SubAA, SubBB
SubAA(1, 'str', True)
SubAA(None, None, None)
SubBB(1, 'str', True, 1, 'str', True)
SubBB(None, None, None, None, None, None)

[file a.py.2]
# Now with errors.
from base import Base
Base(1, 1, True)

from subclass import A, B
A(1, 1, True)
B(1, 'str', True, 1, 1, True)

from submodule.base import SubBase
SubBase(1, 1, True)

from submodule.subclass import AA, BB
AA(1, 1, True)
BB(1, 'str', True, 1, 1, True)

from submodule.subsubclass import SubAA, SubBB
SubAA(1, 1, True)
SubBB(1, 'str', True, 1, 1, True)

[file foo.py]
from typing import Optional
def maybe_int(x: Optional[int]) -> int:
   ...
[file bar.py]
from typing import Optional
def maybe_bool(x: Optional[bool]) -> bool:
   ...
[file base.py]
from typing import Optional
import attr
import bar
from foo import maybe_int
def maybe_str(x: Optional[str]) -> str:
   ...
@attr.s
class Base:
    x: int = attr.ib(converter=maybe_int)
    y: str = attr.ib(converter=maybe_str)
    z: bool = attr.ib(converter=bar.maybe_bool)
[file subclass.py]
from typing import Optional
import attr
from base import Base
@attr.s
class A(Base): pass

import bar
from foo import maybe_int
def maybe_str(x: Optional[str]) -> str:
   ...
@attr.s
class B(Base):
    xx: int = attr.ib(converter=maybe_int)
    yy: str = attr.ib(converter=maybe_str)
    zz: bool = attr.ib(converter=bar.maybe_bool)

[file submodule/__init__.py]
[file submodule/base.py]
from typing import Optional
import attr
import bar
from foo import maybe_int
def maybe_str(x: Optional[str]) -> str:
   ...
@attr.s
class SubBase:
    x: int = attr.ib(converter=maybe_int)
    y: str = attr.ib(converter=maybe_str)
    z: bool = attr.ib(converter=bar.maybe_bool)

[file submodule/subclass.py]
from typing import Optional
import attr
from base import Base
@attr.s
class AA(Base): pass

import bar
from foo import maybe_int
def maybe_str(x: Optional[str]) -> str:
   ...
@attr.s
class BB(Base):
    xx: int = attr.ib(converter=maybe_int)
    yy: str = attr.ib(converter=maybe_str)
    zz: bool = attr.ib(converter=bar.maybe_bool)

[file submodule/subsubclass.py]
from typing import Optional
import attr
from .base import SubBase
@attr.s
class SubAA(SubBase): pass

import bar
from foo import maybe_int
def maybe_str(x: Optional[str]) -> str:
   ...
@attr.s
class SubBB(SubBase):
    xx: int = attr.ib(converter=maybe_int)
    yy: str = attr.ib(converter=maybe_str)
    zz: bool = attr.ib(converter=bar.maybe_bool)
[builtins fixtures/list.pyi]
[out1]
[out2]
tmp/a.py:3: error: Argument 2 to "Base" has incompatible type "int"; expected "Optional[str]"
tmp/a.py:6: error: Argument 2 to "A" has incompatible type "int"; expected "Optional[str]"
tmp/a.py:7: error: Argument 5 to "B" has incompatible type "int"; expected "Optional[str]"
tmp/a.py:10: error: Argument 2 to "SubBase" has incompatible type "int"; expected "Optional[str]"
tmp/a.py:13: error: Argument 2 to "AA" has incompatible type "int"; expected "Optional[str]"
tmp/a.py:14: error: Argument 5 to "BB" has incompatible type "int"; expected "Optional[str]"
tmp/a.py:17: error: Argument 2 to "SubAA" has incompatible type "int"; expected "Optional[str]"
tmp/a.py:18: error: Argument 5 to "SubBB" has incompatible type "int"; expected "Optional[str]"

[case testAttrsIncrementalConverterInFunction]
import attr
def foo() -> None:
    def foo(x: str) -> int:
        ...
    @attr.s
    class A:
        x: int = attr.ib(converter=foo)
    reveal_type(A)
[builtins fixtures/list.pyi]
[out1]
main:8: error: Revealed type is 'def (x: builtins.str) -> __main__.A@5'
[out2]
main:8: error: Revealed type is 'def (x: builtins.str) -> __main__.A@5'

[case testAttrsIncrementalConverterInSubmoduleForwardRef]
from a.a import A
reveal_type(A)
[file a/__init__.py]
[file a/a.py]
from typing import List
def converter(s:F) -> int:
    ...

import attr
@attr.s
class A:
    x: int = attr.ib(converter=converter)

F = List[int]

[builtins fixtures/list.pyi]
[out1]
main:2: error: Revealed type is 'def (x: builtins.list[builtins.int]) -> a.a.A'
[out2]
main:2: error: Revealed type is 'def (x: builtins.list[builtins.int]) -> a.a.A'

[case testAttrsIncrementalConverterType]
from a import C
import attr
o = C("1", "2", "3", "4")
o = C(1, 2, "3", 4)
reveal_type(C)
@attr.s
class D(C):
    x: str = attr.ib()
reveal_type(D)
[file a.py]
from typing import overload
import attr
@attr.dataclass
class A:
    x: str
@overload
def parse(x: int) -> int:
   ...
@overload
def parse(x: str, y: str = '') -> int:
   ...
def parse(x, y): ...
@attr.s
class C:
    a: complex = attr.ib(converter=complex)
    b: int = attr.ib(converter=int)
    c: A = attr.ib(converter=A)
    d: int = attr.ib(converter=parse)
[builtins fixtures/attr.pyi]
[out1]
main:5: error: Revealed type is 'def (a: Union[builtins.float, builtins.str], b: Union[builtins.str, builtins.bytes, builtins.int], c: builtins.str, d: Union[builtins.int, builtins.str]) -> a.C'
main:9: error: Revealed type is 'def (a: Union[builtins.float, builtins.str], b: Union[builtins.str, builtins.bytes, builtins.int], c: builtins.str, d: Union[builtins.int, builtins.str], x: builtins.str) -> __main__.D'
[out2]
main:5: error: Revealed type is 'def (a: Union[builtins.float, builtins.str], b: Union[builtins.str, builtins.bytes, builtins.int], c: builtins.str, d: Union[builtins.int, builtins.str]) -> a.C'
main:9: error: Revealed type is 'def (a: Union[builtins.float, builtins.str], b: Union[builtins.str, builtins.bytes, builtins.int], c: builtins.str, d: Union[builtins.int, builtins.str], x: builtins.str) -> __main__.D'

[case testAttrsIncrementalThreeRuns]
from a import A
A(5)

[file a.py]
import attr
@attr.s(auto_attribs=True)
class A:
    a: int

[file a.py.2]
import attr
@attr.s(auto_attribs=True)
class A:
    a: str

[file a.py.3]
import attr
@attr.s(auto_attribs=True)
class A:
    a: int = 6

[builtins fixtures/list.pyi]
[out1]
[out2]
main:2: error: Argument 1 to "A" has incompatible type "int"; expected "str"
[out3]

[case testDeletedDepLineNumber]
# The import is not on line 1 and that data should be preserved
import a
[file a.py]
[delete a.py.2]
[out1]

[out2]
main:2: error: Cannot find module named 'a'
main:2: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)

[case testIncrementalInheritanceAddAnnotation]
# flags: --strict-optional
import a
[file a.py]
import b
def foo() -> None:
    1 + b.Bar().get()
[file b.py]
from c import Baz
class Bar(Baz): pass

[file c.py]
class Baz:
    def get(self):
        return 1
[file c.py.2]
from typing import Optional
class Baz:
    def get(self) -> Optional[int]:
        return 1
[out]
[out2]
tmp/a.py:3: error: Unsupported operand types for + ("int" and "None")
tmp/a.py:3: note: Right operand is of type "Optional[int]"

[case testIncrementalMetaclassUpdate]
import a
[file a.py]
from b import B
B.x

[file b.py]
import c
class B(metaclass=c.M): pass

[file c.py]
class M(type):
    x: int

[file c.py.2]
class M(type):
    y: int
[out]
[out2]
tmp/a.py:2: error: "Type[B]" has no attribute "x"

[case testIncrementalLotsOfInheritance]
import a
[file a.py]
from b import B
from d import D
def take(d: D) -> None: pass
def foo() -> None:
    take(B())
[file b.py]
from c import C
class B(C): pass

[file c.py]
from d import D
class C(D): pass

[file c.py.2]
from d import D
class C: pass

[file d.py]
class D: pass
[out]
[out2]
tmp/a.py:5: error: Argument 1 to "take" has incompatible type "B"; expected "D"

[case testIncrementalInheritanceProperty]
import a
[file a.py]
import b
def foo() -> None:
    1 + b.Bar().x
[file b.py]
from c import Baz
class Bar(Baz): pass

[file c.py]
class Baz:
    def __init__(self):
        self.x = 12  # type: int
[file c.py.2]
class Baz:
    def __init__(self):
        self.x = 'lol'  # type: str
[out]
[out2]
tmp/a.py:3: error: Unsupported operand types for + ("int" and "str")

[case testIncrementalWithIgnoresTwice]
import a
[file a.py]
import b
import foo # type: ignore
[file b.py]
x = 1
[file b.py.2]
x = 'hi'
[file b.py.3]
x = 1
[builtins fixtures/module.pyi]
[out]
[out2]
[out3]

[case testIgnoredImport2]
import x
[file y.py]
import xyz  # type: ignore
B = 0
from x import A
[file x.py]
A = 0
from y import B
[file x.py.2]
A = 1
from y import B
[file x.py.3]
A = 2
from y import B
[out]
[out2]
[out3]

[case testDeletionOfSubmoduleTriggersImportFrom2]
from p.q import f
f()
[file p/__init__.py]
[file p/q.py]
def f() -> None: pass
[delete p/q.py.2]
[file p/q.py.3]
def f(x: int) -> None: pass
[out]
[out2]
main:1: error: Cannot find module named 'p.q'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
[out3]
main:2: error: Too few arguments for "f"

[case testDeleteIndirectDependency]
import b
b.x.foo()
[file b.py]
import c
x = c.Foo()
[file c.py]
class Foo:
    def foo(self) -> None: pass
[delete c.py.2]
[file b.py.2]
class Foo:
    def foo(self) -> None: pass
x = Foo()
[out]
[out2]

[case testImportReExportInCycle]
from m import One
[file m/__init__.py]
from .one import One
from .two import Two
[file m/one.py]
class One:
    pass
[file m/two.py]
import m
class Two:
    pass
[file m/one.py.2]
class One:
    name: str
[file m/two.py.2]
import m
reveal_type(m.One.name)
class Two:
    pass
[out2]
tmp/m/two.py:2: error: Revealed type is 'builtins.str'

[case testImportUnusedIgnore1]
# flags: --warn-unused-ignores
import a
[file a.py]
import b
import foo  # type: ignore
[file b.py]
x = 1
[file b.py.2]
x = '2'

-- TODO: Fails due to #4856
[case testImportUnusedIgnore2-skip]
# flags: --warn-unused-ignores
import a
[file a.py]
import b
import c  # type: ignore
[file b.py]
x = 1
[file b.py.2]
x = 'hi'
[file c.py.3]
pass
[out]
[out2]
[out3]
tmp/a.py:1: note: unused 'type: ignore' comment

-- Test that a non cache_fine_grained run can use a fine-grained cache
[case testRegularUsesFgCache]
# flags: --config-file tmp/mypy.ini
import a
[file a.py]
x = 0
[file mypy.ini]
[[mypy]
cache_fine_grained = True
[file mypy.ini.2]
[[mypy]
cache_fine_grained = False
-- Nothing should get rechecked
[rechecked]
[stale]

[case testFgCacheNeedsFgCache]
# flags: --config-file tmp/mypy.ini
import a
[file a.py]
x = 0
[file mypy.ini]
[[mypy]
cache_fine_grained = False
[file mypy.ini.2]
[[mypy]
cache_fine_grained = True
[rechecked a, builtins]
[stale a, builtins]

[case testIncrementalPackageNameOverload]
# cmd: mypy -m main a
# flags: --follow-imports=skip
[file main.py]
from a import x
x.foo()
[file a/__init__.py]
pass
[file a/__init__.py.2]
x = 10
[file a/x.py]
def foo() -> None:
    pass
[out]
[out2]
tmp/main.py:2: error: "int" has no attribute "foo"

[case testIncrementalBustedFineGrainedCache1]
# flags: --cache-fine-grained
import a
import b
[file a.py]
[file b.py]
-- This is a heinous hack, but we simulate having a invalid cache by clobbering
-- the proto deps file with something with hash mismatches.
[file ../.mypy_cache/3.6/@proto_deps.meta.json.2]
{"__main__": "00000000000000000000000000000000", "a": "d41d8cd98f00b204e9800998ecf8427e", "b": "d41d8cd98f00b204e9800998ecf8427e", "builtins": "00000000000000000000000000000000"}
[file b.py.2]
# uh
-- Every file should get reloaded, since the cache was invalidated
[stale a, b, builtins]
[rechecked a, b, builtins]

[case testIncrementalBustedFineGrainedCache2]
# flags2: --cache-fine-grained
import a
import b
[file a.py]
[file b.py]
[file b.py.2]
# uh
-- Every file should get reloaded, since the settings changed
[stale a, b, builtins]
[rechecked a, b, builtins]

[case testIncrementalWorkingFineGrainedCache]
# flags: --cache-fine-grained
# flags2: --cache-fine-grained
import a
import b
[file a.py]
[file b.py]
[file b.py.2]
# uh
-- b gets rechecked because it changed, but nothing is stale
-- since the interface did not change
[stale]
[rechecked b]

[case testIncrementalDataclassesSubclassingCached]
from a import A
from dataclasses import dataclass

@dataclass
class B(A):
    e: str = 'e'

a = B(5, [5], 'foo')
a.a = 6
a._b = [2]
a.c = 'yo'
a._d = 22
a.e = 'hi'

[file a.py]
from dataclasses import dataclass, field
from typing import ClassVar, List

@dataclass
class A:
    a: int
    _b: List[int]
    c: str = '18'
    _d: int = field(default=False)
    E = 7
    F: ClassVar[int] = 22

[builtins fixtures/list.pyi]
[out1]
[out2]

[case testIncrementalDataclassesSubclassingCachedType]
import b

[file b.py]
from a import A
from dataclasses import dataclass

@dataclass
class B(A):
    pass

[file b.py.2]
from a import A
from dataclasses import dataclass

@dataclass
class B(A):
    pass

reveal_type(B)

[file a.py]
from dataclasses import dataclass

@dataclass
class A:
    x: int

[builtins fixtures/list.pyi]
[out1]
[out2]
tmp/b.py:8: error: Revealed type is 'def (x: builtins.int) -> b.B'

[case testIncrementalDataclassesArguments]
import b

[file b.py]
from a import Frozen, NoInit, NoCmp

[file b.py.2]
from a import Frozen, NoInit, NoCmp

f = Frozen(5)
f.x = 6

g = NoInit()

Frozen(1) < Frozen(2)
Frozen(1) <= Frozen(2)
Frozen(1) > Frozen(2)
Frozen(1) >= Frozen(2)

NoCmp(1) < NoCmp(2)
NoCmp(1) <= NoCmp(2)
NoCmp(1) > NoCmp(2)
NoCmp(1) >= NoCmp(2)

[file a.py]
from dataclasses import dataclass

@dataclass(frozen=True, order=True)
class Frozen:
    x: int

@dataclass(init=False)
class NoInit:
    x: int

@dataclass(order=False)
class NoCmp:
    x: int

[builtins fixtures/list.pyi]
[out1]
[out2]
tmp/b.py:4: error: Property "x" defined in "Frozen" is read-only
tmp/b.py:13: error: Unsupported left operand type for < ("NoCmp")
tmp/b.py:14: error: Unsupported left operand type for <= ("NoCmp")
tmp/b.py:15: error: Unsupported left operand type for > ("NoCmp")
tmp/b.py:16: error: Unsupported left operand type for >= ("NoCmp")

[case testIncrementalDataclassesDunder]
import b

[file b.py]
from a import A

[file b.py.2]
from a import A

reveal_type(A)
reveal_type(A.__eq__)
reveal_type(A.__ne__)
reveal_type(A.__lt__)
reveal_type(A.__le__)
reveal_type(A.__gt__)
reveal_type(A.__ge__)

A(1) < A(2)
A(1) <= A(2)
A(1) > A(2)
A(1) >= A(2)
A(1) == A(2)
A(1) != A(2)

A(1) < 1
A(1) <= 1
A(1) > 1
A(1) >= 1
A(1) == 1
A(1) != 1

1 < A(1)
1 <= A(1)
1 > A(1)
1 >= A(1)
1 == A(1)
1 != A(1)

[file a.py]
from dataclasses import dataclass

@dataclass(order=True)
class A:
    a: int

[builtins fixtures/attr.pyi]
[out1]
[out2]
tmp/b.py:3: error: Revealed type is 'def (a: builtins.int) -> a.A'
tmp/b.py:4: error: Revealed type is 'def (builtins.object, builtins.object) -> builtins.bool'
tmp/b.py:5: error: Revealed type is 'def (builtins.object, builtins.object) -> builtins.bool'
tmp/b.py:6: error: Revealed type is 'def [T] (self: T`-1, other: T`-1) -> builtins.bool'
tmp/b.py:7: error: Revealed type is 'def [T] (self: T`-1, other: T`-1) -> builtins.bool'
tmp/b.py:8: error: Revealed type is 'def [T] (self: T`-1, other: T`-1) -> builtins.bool'
tmp/b.py:9: error: Revealed type is 'def [T] (self: T`-1, other: T`-1) -> builtins.bool'
tmp/b.py:18: error: Unsupported operand types for < ("A" and "int")
tmp/b.py:19: error: Unsupported operand types for <= ("A" and "int")
tmp/b.py:20: error: Unsupported operand types for > ("A" and "int")
tmp/b.py:21: error: Unsupported operand types for >= ("A" and "int")
tmp/b.py:25: error: Unsupported operand types for > ("A" and "int")
tmp/b.py:26: error: Unsupported operand types for >= ("A" and "int")
tmp/b.py:27: error: Unsupported operand types for < ("A" and "int")
tmp/b.py:28: error: Unsupported operand types for <= ("A" and "int")

[case testIncrementalDataclassesSubclassModified]
from b import B
B(5, 'foo')

[file a.py]
from dataclasses import dataclass

@dataclass
class A:
    x: int

[file b.py]
from a import A
from dataclasses import dataclass

@dataclass
class B(A):
    y: str

[file b.py.2]
from a import A
from dataclasses import dataclass

@dataclass
class B(A):
    y: int

[builtins fixtures/list.pyi]
[out1]
[out2]
main:2: error: Argument 2 to "B" has incompatible type "str"; expected "int"
[rechecked b]

[case testIncrementalDataclassesSubclassModifiedErrorFirst]
from b import B
B(5, 'foo')

[file a.py]
from dataclasses import dataclass

@dataclass
class A:
    x: int

[file b.py]
from a import A
from dataclasses import dataclass

@dataclass
class B(A):
    y: int

[file b.py.2]
from a import A
from dataclasses import dataclass

@dataclass
class B(A):
    y: str

[builtins fixtures/list.pyi]
[out1]
main:2: error: Argument 2 to "B" has incompatible type "str"; expected "int"

[out2]
[rechecked b]

[case testIncrementalDataclassesThreeFiles]
from c import C
C(5, 'foo', True)

[file a.py]
from dataclasses import dataclass

@dataclass
class A:
    a: int

[file b.py]
from dataclasses import dataclass

@dataclass
class B:
    b: str

[file b.py.2]
from dataclasses import dataclass

@dataclass
class B:
    b: str
    c: str

[file c.py]
from a import A
from b import B
from dataclasses import dataclass

@dataclass
class C(A, B):
    c: bool

[builtins fixtures/list.pyi]
[out1]
[out2]
tmp/c.py:7: error: Incompatible types in assignment (expression has type "bool", base class "B" defined the type as "str")

[case testIncrementalDataclassesThreeRuns]
from a import A
A(5)

[file a.py]
from dataclasses import dataclass

@dataclass
class A:
    a: int

[file a.py.2]
from dataclasses import dataclass

@dataclass
class A:
    a: str

[file a.py.3]
from dataclasses import dataclass

@dataclass
class A:
    a: int = 6

[builtins fixtures/list.pyi]
[out1]
[out2]
main:2: error: Argument 1 to "A" has incompatible type "int"; expected "str"
[out3]

[case testParentPatchingMess]
# flags: --ignore-missing-imports --follow-imports=skip
# cmd: mypy -m d d.k d.k.a d.k.v t
[file d/__init__.py]
[file d/k/__init__.py]
from d.k.a import x
[file d/k/a.py]
x = 10
[file d/k/v.py]
from d.k.e import x

[file t.py]
from d import k
[file t.py.2]
from d import k
# dummy change

[case testCachedBadProtocolNote]
import b
[file a.py]
from mypy_extensions import TypedDict
Point = TypedDict('Point', {'x': int, 'y': int})
[file b.py]
from typing import Iterable
from a import Point
p: Point
it: Iterable[int] = p
[file b.py.2]
from typing import Iterable
from a import Point
p: Point
it: Iterable[int] = p  # change
[typing fixtures/typing-full.pyi]
[builtins fixtures/dict.pyi]
[out]
tmp/b.py:4: error: Incompatible types in assignment (expression has type "Point", variable has type "Iterable[int]")
tmp/b.py:4: note: Following member(s) of "Point" have conflicts:
tmp/b.py:4: note:     Expected:
tmp/b.py:4: note:         def __iter__(self) -> Iterator[int]
tmp/b.py:4: note:     Got:
tmp/b.py:4: note:         def __iter__(self) -> Iterator[str]
[out2]
tmp/b.py:4: error: Incompatible types in assignment (expression has type "Point", variable has type "Iterable[int]")
tmp/b.py:4: note: Following member(s) of "Point" have conflicts:
tmp/b.py:4: note:     Expected:
tmp/b.py:4: note:         def __iter__(self) -> Iterator[int]
tmp/b.py:4: note:     Got:
tmp/b.py:4: note:         def __iter__(self) -> Iterator[str]

[case testIndirectDepsAlwaysPatched-writescache]
# flags: --no-incremental
# flags2: --incremental
from b import C
def f() -> None:
    x: int = C().x
[file b.py]
from c import C
[file c.pyi]
class C:
    x: int
[file c.pyi.2]
class C:
    x: str
[out]
[out2]
main:5: error: Incompatible types in assignment (expression has type "str", variable has type "int")

[case testBazelFlagIgnoresFileChanges]
-- Since the initial run wrote a cache file, the second run ignores the source
# flags: --bazel
from a import f
f()
[file a.py]
def f(): pass
[file a.py.2]
[out]
[out2]

[case testModuleGetattrInitIncremental]
import c
[file c.py]
import a.b
x = a.b.f()
[file c.py.2]
import a.b
x = a.b.f()
# touch
[file a/__init__.pyi]
from typing import Any
def __getattr__(attr: str) -> Any: ...
[builtins fixtures/module.pyi]
[out]
[out2]

[case testModuleGetattrInitIncremental2]
import c
[file c.py]
import a.b.c
[file c.py.2]
import a.b.c
# touch
[file a/__init__.pyi]
from typing import Any
def __getattr__(attr: str) -> Any: ...
[file a/b.pyi]
# empty
[builtins fixtures/module.pyi]
[out]
tmp/c.py:1: error: Cannot find module named 'a.b.c'
tmp/c.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
[out2]
tmp/c.py:1: error: Cannot find module named 'a.b.c'
tmp/c.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)

[case testAddedMissingStubs]
# flags: --ignore-missing-imports
from missing import f
f(int())
[file missing.pyi.2]
def f(x: str) -> None: pass
[out]
[out2]
main:3: error: Argument 1 to "f" has incompatible type "int"; expected "str"

[case testAddedMissingStubsPackage]
# flags: --ignore-missing-imports
import package.missing
package.missing.f(int())
[file package/__init__.pyi.2]
[file package/missing.pyi.2]
def f(x: str) -> None: pass
[out]
[out2]
main:3: error: Argument 1 to "f" has incompatible type "int"; expected "str"

[case testAddedMissingStubsPackageFrom]
# flags: --ignore-missing-imports
from package import missing
missing.f(int())
[file package/__init__.pyi.2]
[file package/missing.pyi.2]
def f(x: str) -> None: pass
[out]
[out2]
main:3: error: Argument 1 to "f" has incompatible type "int"; expected "str"

[case testAddedMissingStubsPackagePartial]
# flags: --ignore-missing-imports
import package.missing
package.missing.f(int())
[file package/__init__.pyi]
[file package/missing.pyi.2]
def f(x: str) -> None: pass
[out]
[out2]
main:3: error: Argument 1 to "f" has incompatible type "int"; expected "str"

[case testAddedMissingStubsPackagePartialGetAttr]
import package.missing
package.missing.f(int())
[file package/__init__.pyi]
from typing import Any
def __getattr__(attr: str) -> Any: ...
[file package/missing.pyi.2]
def f(x: str) -> None: pass
[out]
[out2]
main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"

[case testAddedMissingStubsIgnore]
from missing import f  # type: ignore
f(int())
[file missing.pyi.2]
def f(x: str) -> None: pass
[out]
[out2]
main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"

[case testAddedMissingStubsIgnorePackage]
import package.missing  # type: ignore
package.missing.f(int())
[file package/__init__.pyi.2]
[file package/missing.pyi.2]
def f(x: str) -> None: pass
[out]
[out2]
main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"

[case testAddedMissingStubsIgnorePackageFrom]
from package import missing  # type: ignore
missing.f(int())
[file package/__init__.pyi.2]
[file package/missing.pyi.2]
def f(x: str) -> None: pass
[out]
[out2]
main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"

[case testAddedMissingStubsIgnorePackagePartial]
import package.missing  # type: ignore
package.missing.f(int())
[file package/__init__.pyi]
[file package/missing.pyi.2]
def f(x: str) -> None: pass
[out]
[out2]
main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"

-- These tests should just not crash
[case testOverrideByBadVar]
import a
[file a.py]
import lib
x = 1
[file a.py.2]
import lib
x = 2
[file lib.py]
class Slow:
    pass

s: Slow
from cext import Slow  # type: ignore
[out]
[out2]

[case testOverrideByBadVarAlias]
import a
[file a.py]
import lib
x = 1
[file a.py.2]
import lib
x = 2
[file lib.py]
class Slow:
    pass

A = Slow
from cext import Slow  # type: ignore
[out]
[out2]

[case testOverrideByBadVarClass]
import a
[file a.py]
import lib
x = 1
[file a.py.2]
import lib
x = 2
[file lib.py]
class C:
    class Slow:
        pass
    s: Slow
    from cext import Slow  # type: ignore
[out]
[out2]

[case testOverrideByBadVarClassAlias]
import a
[file a.py]
import lib
x = 1
[file a.py.2]
import lib
x = 2
[file lib.py]
class C:
    class Slow:
        pass
    A = Slow
    from cext import Slow  # type: ignore
[out]
[out2]

[case testOverrideByBadVarExisting]
import a
[file a.py]
import lib
x = 1
[file a.py.2]
import lib
x = 2
[file lib.py]
class Slow:
    pass

s: Slow
from cext import Slow  # type: ignore
[file cext.py]
Slow = 1
[out]
[out2]

[case testOverrideByBadVarAliasExisting]
import a
[file a.py]
import lib
x = 1
[file a.py.2]
import lib
x = 2
[file lib.py]
class Slow:
    pass

A = Slow
from cext import Slow  # type: ignore
[file cext.py]
Slow = 1
[out]
[out2]

[case testOverrideByBadFunction]
import a
[file a.py]
import lib
x = 1
[file a.py.2]
import lib
x = 2
[file lib.py]
class C:
    class Slow:
        pass

    s: Slow
    def Slow() -> None: ...  # type: ignore
[out]
[out2]

[case testOverrideByBadVarLocal]
import a
[file a.py]
import lib
x = 1
[file a.py.2]
import lib
x = 2
[file lib.py]
def outer() -> None:
    class Slow:
        pass

    s: Slow
    from cext import Slow  # type: ignore
[out]
[out2]

[case testFollowImportSkipNotInvalidatedOnPresent]
# flags: --follow-imports=skip
# cmd: mypy -m main
[file main.py]
import other
[file other.py]
x = 1
[file other.py.2]
x = 'hi'
[stale]
[rechecked]

[case testFollowImportSkipNotInvalidatedOnPresentPackage]
# flags: --follow-imports=skip
# cmd: mypy -m main
[file main.py]
import other
[file other/__init__.py]
x = 1
[file other/__init__.py.2]
x = 'hi'
[stale]
[rechecked]

[case testFollowImportSkipNotInvalidatedOnAdded]
# flags: --follow-imports=skip --ignore-missing-imports
# cmd: mypy -m main
[file main.py]
import other
[file other.py.2]
x = 1
[stale]
[rechecked]

[case testFollowImportSkipInvalidatedOnAddedStub]
# flags: --follow-imports=skip --ignore-missing-imports
# cmd: mypy -m main
[file main.py]
import other
[file other.pyi.2]
x = 1
[stale main, other]
[rechecked main, other]

[case testFollowImportSkipNotInvalidatedOnAddedStubOnFollowForStubs]
# flags: --follow-imports=skip --ignore-missing-imports --config-file=tmp/mypy.ini
# cmd: mypy -m main
[file main.py]
import other
[file other.pyi.2]
x = 1
[file mypy.ini]
[[mypy]
follow_imports_for_stubs = True
[stale]
[rechecked]

[case testAddedSkippedStubsPackageFrom]
# flags: --follow-imports=skip --ignore-missing-imports
# cmd: mypy -m main
# cmd2: mypy -m main package package.missing
[file main.py]
from package import missing
missing.f(int())
[file package/__init__.py]
[file package/missing.py]
def f(x: str) -> None: pass
[out]
[out2]
tmp/main.py:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"
