-- Test cases for fine-grained incremental mode related to modules
--
-- Covers adding and deleting modules, changes to multiple modules,
-- changes to import graph, and changes to module references.
--
-- The comments in fine-grained.test explain how these tests work.


-- Add file
-- --------


[case testAddFile]
import b
[file b.py]
[file a.py.2]
def f() -> None: pass
[file b.py.3]
import a
a.f(1)
[out]
==
==
b.py:2: error: Too many arguments for "f"

[case testAddFileWithErrors]
import b
[file b.py]
[file a.py.2]
def f() -> str:
    return 1
[file b.py.3]
import a
a.f(1)
[file a.py.4]
def f(x: int) -> None: pass
[out]
==
a.py:2: error: Incompatible return value type (got "int", expected "str")
==
b.py:2: error: Too many arguments for "f"
a.py:2: error: Incompatible return value type (got "int", expected "str")
==

[case testAddFileFixesError]
import b
[file b.py]
[file b.py.2]
from a import f
f()
[file a.py.3]
def f() -> None: pass
[out]
==
b.py:1: error: Cannot find module named 'a'
b.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
==

[case testAddFileFixesAndGeneratesError1]
import b
[file b.py]
[file b.py.2]
from a import f
[file b.py.3]
from a import f
f(1)
[file a.py.4]
def f() -> None: pass
[out]
==
b.py:1: error: Cannot find module named 'a'
b.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
==
b.py:1: error: Cannot find module named 'a'
b.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
==
b.py:2: error: Too many arguments for "f"

[case testAddFileFixesAndGeneratesError2]
import b
[file b.py]
[file b.py.2]
from a import f
f(1)
[file c.py.3]
x = 'whatever'
[file a.py.4]
def f() -> None: pass
[out]
==
b.py:1: error: Cannot find module named 'a'
b.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
==
b.py:1: error: Cannot find module named 'a'
b.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
==
b.py:2: error: Too many arguments for "f"

[case testAddFileGeneratesError1]
# flags: --ignore-missing-imports
import a
[file a.py]
from b import f
f(1)
[file b.py.2]
def f() -> None: pass
[out]
==
a.py:2: error: Too many arguments for "f"

[case testAddFilePreservesError1]
import b
[file b.py]
[file b.py.2]
from a import f
f(1)
[file x.py.3]
# unrelated change
[out]
==
b.py:1: error: Cannot find module named 'a'
b.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
==
b.py:1: error: Cannot find module named 'a'
b.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)

[case testAddFilePreservesError2]
import b
[file b.py]
f()
[file a.py.2]
[out]
b.py:1: error: Name 'f' is not defined
==
b.py:1: error: Name 'f' is not defined

[case testRemoveSubmoduleFromBuild1]
# cmd1: mypy a.py b/__init__.py b/c.py
# cmd2: mypy a.py b/__init__.py
# flags: --follow-imports=skip --ignore-missing-imports
[file a.py]
from b import c
x=1
[file a.py.2]
from b import c
x=2
[file a.py.3]
from b import c
x=3
[file b/__init__.py]
[file b/c.py]
[out]
==
==

[case testImportLineNumber1]
import b
[file b.py]
[file b.py.2]
x = 1
import a
[out]
==
b.py:2: error: Cannot find module named 'a'
b.py:2: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)

[case testImportLineNumber2]
import b
[file b.py]
[file b.py.2]
x = 1
import a
from c import f
[file x.py.3]
[out]
==
b.py:2: error: Cannot find module named 'a'
b.py:2: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
b.py:3: error: Cannot find module named 'c'
==
b.py:2: error: Cannot find module named 'a'
b.py:2: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
b.py:3: error: Cannot find module named 'c'

[case testAddPackage1]
import p.a
p.a.f(1)
[file p/__init__.py.2]
[file p/a.py.2]
def f(x: str) -> None: pass
[out]
main:1: error: Cannot find module named 'p'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:1: error: Cannot find module named 'p.a'
==
main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"

[case testAddPackage2]
import p
p.f(1)
[file p/__init__.py.2]
from p.a import f
[file p/a.py.2]
def f(x: str) -> None: pass
[out]
main:1: error: Cannot find module named 'p'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
==
main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"

[case testAddPackage3]
import p.a
p.a.f(1)
[file p/__init__.py.2]
[file p/a.py.3]
def f(x: str) -> None: pass
[out]
main:1: error: Cannot find module named 'p'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:1: error: Cannot find module named 'p.a'
==
main:1: error: Cannot find module named 'p.a'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
==
main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"
[builtins fixtures/module.pyi]

[case testAddPackage4]
import p.a
p.a.f(1)
[file p/a.py.2]
def f(x: str) -> None: pass
[file p/__init__.py.3]
[out]
main:1: error: Cannot find module named 'p'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:1: error: Cannot find module named 'p.a'
==
main:1: error: Cannot find module named 'p'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:1: error: Cannot find module named 'p.a'
==
main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"

[case testAddNonPackageSubdir]
# cmd: mypy x.py
# cmd2: mypy x.py foo/a.py foo/b.py
[file x.py]
[file foo/a.py.2]
import b
b.foo(5)
[file foo/b.py.2]
def foo(x: str) -> None: pass
[out]
==
foo/a.py:2: error: Argument 1 to "foo" has incompatible type "int"; expected "str"

[case testAddPackage5]
# cmd: mypy main p/a.py
# cmd2: mypy main p/a.py
# cmd3: mypy main p/a.py p/__init__.py
import p.a
p.a.f(1)
[file p/a.py]
[file p/a.py.2]
def f(x: str) -> None: pass
[file p/__init__.py.3]
[out]
main:4: error: Cannot find module named 'p'
main:4: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:4: error: Cannot find module named 'p.a'
==
main:4: error: Cannot find module named 'p'
main:4: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:4: error: Cannot find module named 'p.a'
==
main:5: error: Argument 1 to "f" has incompatible type "int"; expected "str"

[case testAddPackage6]
# flags: --follow-imports=skip --ignore-missing-imports
# cmd: mypy x.py
# cmd2: mypy x.py p/a.py
[file x.py]
import p.a
p.a.f(1)
[file p/a.py.2]
def f(x: str) -> None: pass
[file p/__init__.py.2]
[out]
==
-- It is a bug (#4797) that this isn't an error, but not a fine-grained specific one

[case testAddPackage7]
# flags: --follow-imports=skip
# cmd: mypy x.py
# cmd2: mypy x.py p/a.py
[file x.py]
from p.a import f
f(1)
[file p/a.py.2]
def f(x: str) -> None: pass
[file p/__init__.py.2]
[out]
x.py:1: error: Cannot find module named 'p.a'
x.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
==
x.py:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"


[case testAddPackage8]
# cmd: mypy x.py p/a.py
# cmd2: mypy x.py p/a.py p/__init__.py
# cmd3: mypy x.py p/a.py p/__init__.py
[file x.py]
[file p/a.py]
1+'hi'
[file p/__init__.py.2]
[file p/a.py.3]
'1'+'hi'
[out]
p/a.py:1: error: Unsupported operand types for + ("int" and "str")
==
p/a.py:1: error: Unsupported operand types for + ("int" and "str")
==


-- Delete file
-- -----------


[case testDeleteBasic]
import a
[file a.py]
import b
[file b.py]
def f() -> None: pass
[file a.py.2]
[delete b.py.3]
[out]
==
==

[case testDeleteDepOfDunderInit1]
[file p/__init__.py]
from .foo import Foo
[file p/foo.py]
class Foo: pass
[file p/__init__.py.2]
[delete p/foo.py.2]
[out]
==

[case testDeleteDepOfDunderInit2]
[file p/__init__.py]
from p.foo import Foo
[file p/foo.py]
class Foo: pass
[file p/__init__.py.2]
[delete p/foo.py.2]
[out]
==

[case testDeletionTriggersImportFrom]
import a
[file a.py]
from b import f

def g() -> None:
    f()
[file b.py]
def f() -> None: pass
[delete b.py.2]
[file b.py.3]
def f(x: int) -> None: pass
[out]
==
a.py:1: error: Cannot find module named 'b'
a.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
==
a.py:4: error: Too few arguments for "f"

[case testDeletionTriggersImport]
import a
[file a.py]
def f() -> None: pass
[delete a.py.2]
[file a.py.3]
def f() -> None: pass
[out]
==
main:1: error: Cannot find module named 'a'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
==

[case testDeletionOfSubmoduleTriggersImportFrom1-skip-cache]
-- Different cache/no-cache tests because:
-- missing module error message mismatch
from p import q
[file p/__init__.py]
[file p/q.py]
[delete p/q.py.2]
[file p/q.py.3]
[out]
==
main:1: error: Module 'p' has no attribute 'q'
-- TODO: The following messages are different compared to non-incremental mode
main:1: error: Cannot find module named 'p.q'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
==

-- TODO: Fix this bug. It is a real bug that was been papered over
-- by the test harness.
[case testDeletionOfSubmoduleTriggersImportFrom1-skip-nocache-skip]
-- Different cache/no-cache tests because:
-- missing module error message mismatch
from p import q
[file p/__init__.py]
[file p/q.py]
[delete p/q.py.2]
[file p/q.py.3]
[out]
==
main:1: error: Cannot find module named 'p.q'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
==

[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]
==
main:1: error: Cannot find module named 'p.q'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
==
main:2: error: Too few arguments for "f"

[case testDeletionOfSubmoduleTriggersImport]
import p.q
[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]
==
main:1: error: Cannot find module named 'p.q'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
==

[case testDeleteSubpackageWithNontrivialParent1]
[file p/__init__.py]
def g() -> None:
    pass
[file p/b.py.2]
def foo() -> None: pass
foo()
[delete p/b.py.3]
[out]
==
==

[case testDeleteModuleWithError]
import a
[file a.py]
def f() -> int:
    return 1
[file a.py.2]
def f() -> str:
    return 1
[delete a.py.3]
def f() -> str:
    return 1
[out]
==
a.py:2: error: Incompatible return value type (got "int", expected "str")
==
main:1: error: Cannot find module named 'a'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)

[case testDeleteModuleWithErrorInsidePackage]
import a.b
[file a/__init__.py]
[file a/b.py]
def f() -> int:
    return ''
[delete a/b.py.2]
def f() -> str:
    return 1
[out]
a/b.py:2: error: Incompatible return value type (got "str", expected "int")
==
main:1: error: Cannot find module named 'a.b'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)

[case testModifyTwoFilesNoError1]
import a
[file a.py]
import b
b.f()
[file b.py]
def f() -> None: pass
[file a.py.2]
import b
b.f(1)
[file b.py.2]
def f(x: int) -> None: pass
[out]
==

[case testDeleteSubpackageInit1]
# cmd: mypy q/r/s.py
# flags: --follow-imports=skip --ignore-missing-imports
[file q/__init__.py]
[file q/r/__init__.py]
[file q/r/s.py]
[delete q/__init__.py.2]
[out]
==

[case testAddSubpackageInit2]
# cmd: mypy q/r/s.py
# flags: --follow-imports=skip --ignore-missing-imports
[file q/r/__init__.py]
[file q/r/s.py]
1
[file q/r/s.py.2]
2
[file q/__init__.py.2]
[out]
==

[case testModifyTwoFilesNoError2]
import a
[file a.py]
from b import g
def f() -> None: pass
[file b.py]
import a
def g() -> None: pass
a.f()
[file a.py.2]
from b import g
def f(x: int) -> None: pass
[file b.py.2]
import a
def g() -> None: pass
a.f(1)
[out]
==

[case testModifyTwoFilesErrorsElsewhere]
import a
import b
a.f()
b.g(1)
[file a.py]
def f() -> None: pass
[file b.py]
def g(x: int) -> None: pass
[file a.py.2]
def f(x: int) -> None: pass
[file b.py.2]
def g() -> None: pass
[out]
==
main:3: error: Too few arguments for "f"
main:4: error: Too many arguments for "g"

[case testModifyTwoFilesErrorsInBoth]
import a
[file a.py]
import b
def f() -> None: pass
b.g(1)
[file b.py]
import a
def g(x: int) -> None: pass
a.f()
[file a.py.2]
import b
def f(x: int) -> None: pass
b.g(1)
[file b.py.2]
import a
def g() -> None: pass
a.f()
[out]
==
b.py:3: error: Too few arguments for "f"
a.py:3: error: Too many arguments for "g"

[case testModifyTwoFilesFixErrorsInBoth]
import a
[file a.py]
import b
def f(x: int) -> None: pass
b.g(1)
[file b.py]
import a
def g() -> None: pass
a.f()
[file a.py.2]
import b
def f() -> None: pass
b.g(1)
[file b.py.2]
import a
def g(x: int) -> None: pass
a.f()
[out]
b.py:3: error: Too few arguments for "f"
a.py:3: error: Too many arguments for "g"
==

[case testAddTwoFilesNoError]
import a
[file a.py]
import b
import c
b.f()
c.g()
[file b.py.2]
import c
def f() -> None: pass
c.g()
[file c.py.2]
import b
def g() -> None: pass
b.f()
[out]
a.py:1: error: Cannot find module named 'b'
a.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
a.py:2: error: Cannot find module named 'c'
==

[case testAddTwoFilesErrorsInBoth]
import a
[file a.py]
import b
import c
b.f()
c.g()
[file b.py.2]
import c
def f() -> None: pass
c.g(1)
[file c.py.2]
import b
def g() -> None: pass
b.f(1)
[out]
a.py:1: error: Cannot find module named 'b'
a.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
a.py:2: error: Cannot find module named 'c'
==
c.py:3: error: Too many arguments for "f"
b.py:3: error: Too many arguments for "g"

[case testAddTwoFilesErrorsElsewhere]
import a
import b
a.f(1)
b.g(1)
[file a.py.2]
def f() -> None: pass
[file b.py.2]
def g() -> None: pass
[out]
main:1: error: Cannot find module named 'a'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:2: error: Cannot find module named 'b'
==
main:3: error: Too many arguments for "f"
main:4: error: Too many arguments for "g"

[case testDeleteTwoFilesErrorsElsewhere]
import a
import b
a.f()
b.g()
[file a.py]
def f() -> None: pass
[file b.py]
def g() -> None: pass
[delete a.py.2]
[delete b.py.2]
[out]
==
main:1: error: Cannot find module named 'a'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:2: error: Cannot find module named 'b'

[case testDeleteTwoFilesNoErrors]
import a
[file a.py]
import b
import c
b.f()
c.g()
[file b.py]
def f() -> None: pass
[file c.py]
def g() -> None: pass
[file a.py.2]
[delete b.py.3]
[delete c.py.3]
[out]
==
==

[case testDeleteTwoFilesFixErrors]
import a
import b
a.f()
b.g()
[file a.py]
import b
def f() -> None: pass
b.g(1)
[file b.py]
import a
def g() -> None: pass
a.f(1)
[delete a.py.2]
[delete b.py.2]
[out]
b.py:3: error: Too many arguments for "f"
a.py:3: error: Too many arguments for "g"
==
main:1: error: Cannot find module named 'a'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:2: error: Cannot find module named 'b'

[case testAddFileWhichImportsLibModule]
import a
a.x = 0
[file a.py.2]
import sys
x = sys.platform
[out]
main:1: error: Cannot find module named 'a'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
==
main:2: error: Incompatible types in assignment (expression has type "int", variable has type "str")

[case testAddFileWhichImportsLibModuleWithErrors]
# flags: --no-silence-site-packages
import a
a.x = 0
[file a.py.2]
import broken
x = broken.x
z
[out]
main:2: error: Cannot find module named 'a'
main:2: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
==
a.py:3: error: Name 'z' is not defined
<ROOT>/test-data/unit/lib-stub/broken.pyi:2: error: Name 'y' is not defined

[case testRenameModule]
import a
[file a.py]
import b
b.f()
[file b.py]
def f() -> None: pass
[file a.py.2]
import c
c.f()
[file c.py.2]
def f() -> None: pass
[file a.py.3]
import c
c.f(1)
[out]
==
==
a.py:2: error: Too many arguments for "f"

[case testDeleteFileWSuperClass]
# flags: --ignore-missing-imports
[file a.py]
from c import Bar
from b import Foo
z = (1, Foo())
[file b.py]
from e import Quux
from d import Baz
class Foo(Baz, Quux):
    pass

[file e.py]
from c import Bar
class Quux(Bar):
    pass
[file c.py]
class Bar:
    pass
[file d.py]
class Baz:
    pass
[delete c.py.2]
[out]
==

[case testDeleteFileWithinPackage]
import a
[file a.py]
import m.x
m.x.g(1)
[file m/__init__.py]
[file m/x.py]
def g() -> None: pass
[delete m/x.py.2]
[builtins fixtures/module.pyi]
[out]
a.py:2: error: Too many arguments for "g"
==
a.py:1: error: Cannot find module named 'm.x'
a.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)

[case testDeletePackage1]
import p.a
p.a.f(1)
[file p/__init__.py]
[file p/a.py]
def f(x: str) -> None: pass
[delete p/__init__.py.2]
[delete p/a.py.2]
def f(x: str) -> None: pass
[out]
main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"
==
main:1: error: Cannot find module named 'p'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:1: error: Cannot find module named 'p.a'

[case testDeletePackage2]
import p
p.f(1)
[file p/__init__.py]
from p.a import f
[file p/a.py]
def f(x: str) -> None: pass
[delete p/__init__.py.2]
[delete p/a.py.2]
[out]
main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"
==
main:1: error: Cannot find module named 'p'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)

[case testDeletePackage3]
import p.a
p.a.f(1)
[file p/__init__.py]
[file p/a.py]
def f(x: str) -> None: pass
[delete p/a.py.2]
[delete p/__init__.py.3]
[builtins fixtures/module.pyi]
[out]
main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"
==
main:1: error: Cannot find module named 'p.a'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
==
main:1: error: Cannot find module named 'p'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:1: error: Cannot find module named 'p.a'

[case testDeletePackage4]
import p.a
p.a.f(1)
[file p/a.py]
def f(x: str) -> None: pass
[file p/__init__.py]
[delete p/__init__.py.2]
[delete p/a.py.3]
[out]
main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"
==
main:1: error: Cannot find module named 'p'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:1: error: Cannot find module named 'p.a'
==
main:1: error: Cannot find module named 'p'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:1: error: Cannot find module named 'p.a'

[case testDeletePackage5]
# cmd1: mypy main p/a.py p/__init__.py
# cmd2: mypy main p/a.py
# cmd3: mypy main

import p.a
p.a.f(1)
[file p/a.py]
def f(x: str) -> None: pass
[file p/__init__.py]
[delete p/__init__.py.2]
[delete p/a.py.3]
[out]
main:6: error: Argument 1 to "f" has incompatible type "int"; expected "str"
==
main:5: error: Cannot find module named 'p'
main:5: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:5: error: Cannot find module named 'p.a'
==
main:5: error: Cannot find module named 'p'
main:5: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:5: error: Cannot find module named 'p.a'


[case testDeletePackage6]
# cmd1: mypy p/a.py p/b.py p/__init__.py
# cmd2: mypy p/a.py p/b.py
# cmd3: mypy p/a.py p/b.py
[file p/a.py]
def f(x: str) -> None: pass
[file p/b.py]
from p.a import f
f(12)
[file p/__init__.py]
[delete p/__init__.py.2]
[file p/b.py.3]
from a import f
f(12)
[out]
p/b.py:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"
==
p/b.py:1: error: Cannot find module named 'p.a'
p/b.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
==
p/b.py:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"


-- TODO:
-- - add one file which imports another new file, blocking error in new file
-- - arbitrary blocking errors
-- - order of processing makes a difference
-- - mix of modify, add and delete in one iteration


-- Controlling imports using command line options
-- ----------------------------------------------


[case testIgnoreMissingImports]
# flags: --ignore-missing-imports
import a
[file a.py]
import b
import c
[file c.py]
[delete c.py.2]
[file b.py.3]
import d
1 + ''
[out]
==
==
b.py:2: error: Unsupported operand types for + ("int" and "str")

[case testSkipImports]
# cmd: mypy main a.py
# flags: --follow-imports=skip --ignore-missing-imports
import a
[file a.py]
import b
[file b.py]
1 + ''
class A: pass
[file a.py.2]
import b
reveal_type(b)
reveal_type(b.A)
[file a.py.3]
import b
reveal_type(b)
reveal_type(b.A)
[file b.py.3]
1 + ''
class A: pass
[out]
==
a.py:2: error: Revealed type is 'Any'
a.py:3: error: Revealed type is 'Any'
==
a.py:2: error: Revealed type is 'Any'
a.py:3: error: Revealed type is 'Any'

[case testSkipImportsWithinPackage]
# cmd: mypy a/b.py
# flags: --follow-imports=skip --ignore-missing-imports
[file a/__init__.py]
1 + ''
[file a/b.py]
import a.c
[file a/b.py.2]
import a.c
import x
reveal_type(a.c)
[file a/b.py.3]
import a.c
import x
1 + ''
[out]
==
a/b.py:3: error: Revealed type is 'Any'
==
a/b.py:3: error: Unsupported operand types for + ("int" and "str")

[case testDeleteModuleWithinPackageInitIgnored-skip-cache]
-- Disabled in cache mode because incorrect behavior:
-- Having deleted files specified on command line seems dodgy, though.
# cmd: mypy x.py a/b.py
# flags: --follow-imports=skip --ignore-missing-imports
[file x.py]
import a.b
[file a/__init__.py]
[file a/b.py]
x = 1
[delete a/b.py.2]
[out]
==

[case testAddImport]
import what.b
[file aaa/__init__.py]
[file aaa/z.py]
def foo(x: int) -> None:
    pass
[file aaa/z.py.2]
import config
def foo() -> None:
    pass
[file what/__init__.py]
[file what/b.py]
import config
import aaa.z
def main() -> None:
    aaa.z.foo(5)
[file what/b.py.2]
import aaa.z
def main() -> None:
    aaa.z.foo()
[file config.py]
[out]
==

[case testAddImport2]
import what.b
[file aaa/__init__.py]
[file aaa/z.py]
def foo(x: int) -> None:
    pass
[file aaa/z.py.2]
def foo() -> None:
    pass
[file what/__init__.py]
[file what/b.py]
import aaa.z
def main() -> None:
    aaa.z.foo(5)
[file what/b.py.2]
import config
import aaa.z
def main() -> None:
    aaa.z.foo()
[file config.py]
[out]
==


-- Misc
-- ----


[case testChangeModuleToVariable]
from a import m
m.x
[file a.py]
from b import m
[file b.py]
import m
[file b.py.2]
m = ''
[file m.py]
x = 1
[file m2.py]
[out]
==
main:2: error: "str" has no attribute "x"

[case testChangeVariableToModule]
from a import m
y: str = m
[file a.py]
from b import m
[file b.py]
m = ''
[file b.py.2]
import m
[file m.py]
x = 1
[file m2.py]
[builtins fixtures/module.pyi]
[out]
==
main:2: error: Incompatible types in assignment (expression has type Module, variable has type "str")

[case testRefreshImportOfIgnoredModule1]
# flags: --follow-imports=skip --ignore-missing-imports
# cmd: mypy c.py a/__init__.py b.py
[file c.py]
from a import a2
import b
b.x
[file a/__init__.py]
[file b.py]
x = 0
[file b.py.2]
x = ''
[file b.py.3]
x = 0
[file a/a2.py]
[out]
==
==

[case testRefreshImportOfIgnoredModule2]
# flags: --follow-imports=skip --ignore-missing-imports
# cmd: mypy c.py a/__init__.py b.py
[file c.py]
from a import a2
import b
b.x
[file a/__init__.py]
[file b.py]
x = 0
[file b.py.2]
x = ''
[file b.py.3]
x = 0
[file a/a2/__init__.py]
[out]
==
==

[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
[out]
==
==

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

[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()
[file b.py.3]
class Foo:
    def foo(self, x: int) -> None: pass
x = Foo()
[out]
==
==
main:2: error: Too few arguments for "foo" of "Foo"

-- This series of tests is designed to test adding a new module that
-- does not appear in the cache, for cache mode. They are run in
-- cache mode only because stale and rechecked differ heavily between
-- the modes.
[case testAddModuleAfterCache1-skip-nocache]
# cmd: mypy main a.py
# cmd2: mypy main a.py b.py
# cmd3: mypy main a.py b.py
import a
[file a.py]
pass
[file a.py.2]
import b
b.foo(0)
[file b.py.2]
def foo() -> None: pass

[stale a, b]
[rechecked a, b]

[file b.py.3]
def foo(x: int) -> None: pass

[stale2 b]
[rechecked2 b]

[out]
==
a.py:2: error: Too many arguments for "foo"
==

[case testAddModuleAfterCache2-skip-nocache]
# cmd: mypy main a.py
# cmd2: mypy main a.py b.py
# cmd3: mypy main a.py b.py
# flags: --ignore-missing-imports --follow-imports=skip
import a
[file a.py]
import b
b.foo(0)
[file b.py.2]
def foo() -> None: pass

[stale b]
[rechecked a, b]

[file b.py.3]
def foo(x: int) -> None: pass

[stale2 b]

[out]
==
a.py:2: error: Too many arguments for "foo"
==

[case testAddModuleAfterCache3-skip-nocache]
# cmd: mypy main a.py
# cmd2: mypy main a.py b.py c.py d.py e.py f.py g.py
# cmd3: mypy main a.py b.py c.py d.py e.py f.py g.py
# flags: --ignore-missing-imports --follow-imports=skip
import a
[file a.py]
import b, c, d, e, f, g
b.foo(10)
[file b.py.2]
def foo() -> None: pass
[file c.py.2]
[file d.py.2]
[file e.py.2]
[file f.py.2]
[file g.py.2]

-- No files should be stale or reprocessed in the first step since the large number
-- of missing files will force build to give up on cache loading.
[stale]

[file b.py.3]
def foo(x: int) -> None: pass
[stale2 b]

[out]
==
a.py:2: error: Too many arguments for "foo"
==


[case testAddModuleAfterCache4-skip-nocache]
# cmd: mypy main a.py
# cmd2: mypy main a.py b.py
# cmd3: mypy main a.py b.py
# flags: --ignore-missing-imports --follow-imports=skip
import a
import b
[file a.py]
def foo() -> None: pass
[file b.py.2]
import a
a.foo(10)
[file a.py.3]
def foo(x: int) -> None: pass
[out]
==
b.py:2: error: Too many arguments for "foo"
==

[case testAddModuleAfterCache5-skip-nocache]
# cmd: mypy main a.py
# cmd2: mypy main a.py b.py
# cmd3: mypy main a.py b.py
# flags: --ignore-missing-imports --follow-imports=skip
import a
import b
[file a.py]
def foo(x: int) -> None: pass
[file a.py.2]
def foo() -> None: pass
[file b.py.2]
import a
a.foo(10)

[stale a, b]

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

[stale2 a]

[out]
==
b.py:2: error: Too many arguments for "foo"
==

[case testAddModuleAfterCache6-skip-nocache]
# cmd: mypy main a.py
# cmd2: mypy main a.py b.py
# cmd3: mypy main a.py b.py
# flags: --ignore-missing-imports --follow-imports=skip
import a
[file a.py]
import b
b.foo()

[file a.py.2]
import b
b.foo(0)
[file b.py.2]
def foo() -> None: pass

[stale a, b]

[file b.py.3]
def foo(x: int) -> None: pass

[stale2 b]

[out]
==
a.py:2: error: Too many arguments for "foo"
==

[case testRenameAndDeleteModuleAfterCache-skip-nocache]
import a
[file a.py]
from b1 import f
f()
[file b1.py]
def f() -> None: pass
[file b2.py.2]
def f() -> None: pass
[delete b1.py.2]
[file a.py.2]
from b2 import f
f()

-- in cache mode, there is no way to know about b1 yet
[stale a, b2]

[out]
==

[case testDeleteModuleAfterCache-skip-nocache]
import a
[file a.py]
from b import f
f()
[file b.py]
def f() -> None: pass
[delete b.py.2]

-- in cache mode, there is no way to know about b yet,
-- but a should get flagged as changed by the initial cache
-- check, since one of its dependencies is missing.
[stale a]

[out]
==
a.py:1: error: Cannot find module named 'b'
a.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)


[case testRefreshImportIfMypyElse1]
import a
[file a.py]
from b import foo

MYPY = False
if MYPY:
    x = 0
else:
    from fictional import x

x = 1
[file b/__init__.py]
[file b/foo.py]
[file b/__init__.py.2]
# Dummy change
[builtins fixtures/bool.pyi]
[out]
==

[case testImportStarPropagateChange1]
from b import f
f()
[file b.py]
from c import *
[file c.py]
def f() -> None: pass
[file c.py.2]
def f(x: int) -> None: pass
[out]
==
main:2: error: Too few arguments for "f"

[case testImportStarPropagateChange2]
from b import *
f()
[file b.py]
def f() -> None: pass
[file b.py.2]
def f(x: int) -> None: pass
[out]
==
main:2: error: Too few arguments for "f"

[case testImportStarAddMissingDependency1]
from b import f
f()
[file b.py]
from c import *
[file c.py]
[file c.py.2]
def f(x: int) -> None: pass
[out]
main:1: error: Module 'b' has no attribute 'f'
==
main:2: error: Too few arguments for "f"

[case testImportStarAddMissingDependency2]
from b import *
f()
[file b.py]
[file b.py.2]
def f(x: int) -> None: pass
[out]
main:2: error: Name 'f' is not defined
==
main:2: error: Too few arguments for "f"

[case testImportStarAddMissingDependencyWithinClass]
class A:
    from b import *
    f()
    x: C
[file b.py]
[file b.py.2]
def f(x: int) -> None: pass
[file b.py.3]
def f(x: int) -> None: pass
class C: pass
[file b.py.4]
def f() -> None: pass
class C: pass
[out]
main:3: error: Name 'f' is not defined
main:4: error: Name 'C' is not defined
==
main:3: error: Too few arguments for "f"
main:4: error: Name 'C' is not defined
==
main:3: error: Too few arguments for "f"
==

[case testImportStarAddMissingDependencyInsidePackage1]
from p.b import f
f()
[file p/__init__.py]
[file p/b.py]
from p.c import *
[file p/c.py]
[file p/c.py.2]
def f(x: int) -> None: pass
[out]
main:1: error: Module 'p.b' has no attribute 'f'
==
main:2: error: Too few arguments for "f"

[case testImportStarAddMissingDependencyInsidePackage2]
import p.a
[file p/__init__.py]
[file p/a.py]
from p.b import *
f()
[file p/b.py]
[file p/b.py.2]
def f(x: int) -> None: pass
[out]
p/a.py:2: error: Name 'f' is not defined
==
p/a.py:2: error: Too few arguments for "f"

[case testImportStarRemoveDependency1]
from b import f
f()
[file b.py]
from c import *
[file c.py]
def f() -> None: pass
[file c.py.2]
[out]
==
main:1: error: Module 'b' has no attribute 'f'

[case testImportStarRemoveDependency2]
from b import *
f()
[file b.py]
def f() -> None: pass
[file b.py.2]
[out]
==
main:2: error: Name 'f' is not defined

[case testImportStarWithinFunction]
def f() -> None:
    from m import *
    f()
[file m.py]
[file m.py.2]
def f(x: int) -> None: pass
[file m.py.3]
def f() -> None: pass
[out]
==
main:3: error: Too few arguments for "f"
==

[case testImportStarMutuallyRecursive]
import a
[file a.py]
from b import *
[file b.py]
from a import *
[file b.py.2]
from a import *
x = 0
[file b.py.3]
from a import *
x = ''
[out]
==
==

[case testImportStarSomethingMoved]
import p
[file p.py]
from r2 import *
[file r2.py]
class A: pass

[file p.py.2]
from r1 import *
from r2 import *
[file r2.py.2]

[file r1.py.2]
class A: pass

[out]
==

[case testImportStarOverlap]
from b import *
from c import *  # type: ignore
[file b.py]
from d import T
[file c.py]
from d import T
[file c.py.2]
from d import T
z = 10
[file d.py]
from typing import TypeVar
T = TypeVar('T')
[out]
==

[case testImportStarOverlap2]
from b import *
import typing
def foo(x: typing.List[int]) -> int:
    return x[0]
[file b.py]
import typing
z = 10
[file b.py.2]
import typing
z = '10'
[builtins fixtures/list.pyi]
[out]
==


[case testImportStarOverlap3]
from b import *
from c import typing
def foo(x: typing.List[int]) -> int:
    return x[0]
[file b.py]
import typing
z = 10
[file b.py.2]
import typing
z = '10'
[file c.py]
import typing
z = 10
[builtins fixtures/list.pyi]
[out]
==


[case testImportPartialAssign]
import a
[file a.py]
from c import *
from b import A, x
[file b.py]
A = 10
x = 1
[file b.py.2]
class A: pass
x = 1
[file c.py]
x = 10
[out]
==

[case testDeleteFileWithErrors]
# cmd: mypy main a.py
# cmd2: mypy main
# flags: --follow-imports=skip --ignore-missing-imports
import a
[file a.py]
def f() -> None:
    1()
''()
[file b.py.2]
# unrelated change
[out]
a.py:2: error: "int" not callable
a.py:3: error: "str" not callable
==

[case testAddAndUseClass1]
[file a.py]
[file a.py.2]
from b import Foo
def bar(f: Foo) -> None:
    f.foo(12)
[file b.py.2]
class Foo:
    def foo(self, s: str) -> None: pass
[out]
==
a.py:3: error: Argument 1 to "foo" of "Foo" has incompatible type "int"; expected "str"

[case testAddAndUseClass2]
[file a.py]
[file a.py.3]
from b import Foo
def bar(f: Foo) -> None:
    f.foo(12)
[file b.py.2]
class Foo:
    def foo(self, s: str) -> None: pass
[out]
==
==
a.py:3: error: Argument 1 to "foo" of "Foo" has incompatible type "int"; expected "str"

[case testAddAndUseClass3]
# flags: --ignore-missing-imports
[file a.py]
[file a.py.2]
from b import Foo
def bar(f: Foo) -> None:
    f.foo(12)
[file b.py.3]
class Foo:
    def foo(self, s: str) -> None: pass
[out]
==
==
a.py:3: error: Argument 1 to "foo" of "Foo" has incompatible type "int"; expected "str"

[case testAddAndUseClass4]
[file a.py]
[file a.py.2]
from b import *
def bar(f: Foo) -> None:
    f.foo(12)
[file b.py.2]
class Foo:
    def foo(self, s: str) -> None: pass
[out]
==
a.py:3: error: Argument 1 to "foo" of "Foo" has incompatible type "int"; expected "str"

[case testAddAndUseClass4]
[file a.py]
[file a.py.2]
from p.b import *
def bar(f: Foo) -> None:
    f.foo(12)
[file p/__init__.py]
[file p/b.py.2]
class Foo:
    def foo(self, s: str) -> None: pass
[out]
==
a.py:3: error: Argument 1 to "foo" of "Foo" has incompatible type "int"; expected "str"

[case testAddAndUseClass5]
[file a.py]
[file a.py.2]
from b import *
def bar(f: Foo) -> None:
    f.foo(12)
[file b.py.2]
class Foo:
    def foo(self, s: str) -> None: pass
[out]
==
a.py:3: error: Argument 1 to "foo" of "Foo" has incompatible type "int"; expected "str"

[case testSkipButDontIgnore1]
# cmd: mypy a.py c.py
# flags: --follow-imports=skip
[file a.py]
import b
from c import x
[file b.py]
1+'lol'
[file c.py]
x = 1
[file c.py.2]
x = '2'
[file b.py.3]
[out]
==
==

[case testSkipButDontIgnore2]
# cmd: mypy a.py c.py
# flags: --follow-imports=skip
[file a.py]
from c import x
import b
[file b.py]
[file c.py]
x = 1
[file b.py]
1+'x'
[file c.py.2]
x = '2'
[file c.py.3]
x = 2
[delete b.py.3]
[out]
==
==
a.py:2: error: Cannot find module named 'b'
a.py:2: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)

[case testErrorButDontIgnore1]
# cmd: mypy a.py c.py
# flags: --follow-imports=error
[file a.py]
from c import x
import b
[file b.py]
[file c.py]
x = 1
[file c.py.2]
x = '2'
[out]
a.py:2: note: Import of 'b' ignored
a.py:2: note: (Using --follow-imports=error, module not passed on command line)
==
a.py:2: note: Import of 'b' ignored
a.py:2: note: (Using --follow-imports=error, module not passed on command line)

[case testErrorButDontIgnore2]
# cmd1: mypy a.py c.py b.py
# cmd2: mypy a.py c.py
# flags: --follow-imports=error
[file a.py]
from c import x
import b
[file b.py]
[file c.py]
x = 1
[file c.py.2]
x = '2'
[out]
==
a.py:2: note: Import of 'b' ignored
a.py:2: note: (Using --follow-imports=error, module not passed on command line)

-- TODO: This test fails because p.b does not depend on p (#4847)
[case testErrorButDontIgnore3-skip]
# cmd1: mypy a.py c.py p/b.py p/__init__.py
# cmd2: mypy a.py c.py p/b.py
# flags: --follow-imports=error
[file a.py]
from c import x
from p.b import y
[file p/b.py]
y = 12
[file p/__init__.py]
[file c.py]
x = 1
[file c.py.2]
x = '2'
[out]
==
p/b.py: note: Ancestor package 'p' ignored
p/b.py: note: (Using --follow-imports=error, submodule passed on command line)

[case testErrorButDontIgnore4]
# cmd: mypy a.py z.py p/b.py p/__init__.py
# cmd2: mypy a.py p/b.py
# flags: --follow-imports=error
[file a.py]
from p.b import y
[file p/b.py]
from z import x
y = 12
[file p/__init__.py]
[file z.py]
x = 1
[delete z.py.2]
[out]
==
p/b.py: note: Ancestor package 'p' ignored
p/b.py: note: (Using --follow-imports=error, submodule passed on command line)
p/b.py:1: error: Cannot find module named 'z'
p/b.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)

[case testTurnPackageToModule]
[file a.py]
[file b.py]
import p
x = p.f()
[file p/__init__.py]
def f() -> int: pass
[delete p/__init__.py.2]
[file p.py.2]
def f() -> str: pass
[file a.py.3]
import b
reveal_type(b.x)
[out]
==
==
a.py:2: error: Revealed type is 'builtins.str'

[case testModuleToPackage]
[file a.py]
[file b.py]
import p
x = p.f()
[file p.py]
def f() -> str: pass
[delete p.py.2]
[file p/__init__.py.2]
def f() -> int: pass
[file a.py.3]
import b
reveal_type(b.x)
[out]
==
==
a.py:2: error: Revealed type is 'builtins.int'

[case testQualifiedSubpackage1]
[file c/__init__.py]
[file c/a.py]
from lurr import x
from c.d import f

[file c/d.py]
def f() -> None: pass
def g(x: int) -> None: pass
[file lurr.py]
x = 10
[file lurr.py.2]
x = '10'
[out]
==

[case testImportedMissingSubpackage]
# flags: --follow-imports=skip --ignore-missing-imports
# cmd: mypy a.py b/__init__.py
[file a.py]
from b.foo import bar
x = 10
[file b/__init__.py]
[file a.py.2]
from b.foo import bar
x = '10'
[out]
==

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

[case testFineAddedMissingStubsPackage]
# 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]
==
main:3: error: Argument 1 to "f" has incompatible type "int"; expected "str"

[case testFineAddedMissingStubsPackageFrom]
# 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]
==
main:3: error: Argument 1 to "f" has incompatible type "int"; expected "str"

[case testFineAddedMissingStubsPackagePartial]
# 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]
==
main:3: error: Argument 1 to "f" has incompatible type "int"; expected "str"

[case testFineAddedMissingStubsPackagePartialGetAttr]
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]
==
main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"

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

[case testFineAddedMissingStubsIgnorePackage]
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]
==
main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"

[case testFineAddedMissingStubsIgnorePackageFrom]
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]
==
main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"

[case testFineAddedMissingStubsIgnorePackagePartial]
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]
==
main:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"

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

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

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

-- TODO: Fix this: stubs should be followed normally even with follow-imports=skip
[case testFineFollowImportSkipInvalidatedOnAddedStub-skip]
# flags: --follow-imports=skip --ignore-missing-imports
# cmd: mypy main.py
[file main.py]
import other
x: str = other.x
[file other.pyi.2]
x = 1
[stale main, other]
[rechecked main, other]
[out]
==
main:2: error: Incompatible types in assignment (expression has type "int", variable has type "str")

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

[case testFineAddedSkippedStubsPackageFrom]
# flags: --follow-imports=skip --ignore-missing-imports
# cmd: mypy main.py
# cmd2: mypy main.py package/__init__.py package/missing.py
[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]
==
main.py:2: error: Argument 1 to "f" has incompatible type "int"; expected "str"
