blob: 439d536b96f0256a28a1ba61e1b00d656ceb1f0a [file]
-- Checks for incremental mode (see testcheck.py).
-- Each test is run twice, once with a cold cache, once with a warm cache.
-- Before the tests are run the second time, any *.py.next files are copied to *.py.
--
-- 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. If a
-- section is omitted, it is expected there are no errors on that run.
--
-- 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 does not create a new cache file and so is not considered stale.
--
-- 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.
[case testIncrementalEmpty]
[rechecked]
[stale]
[case testIncrementalBasics]
import m
[file m.py]
def foo():
pass
[file m.py.next]
def foo() -> None:
pass
[rechecked m]
[stale m]
[case testIncrementalError]
import m
[file m.py]
def foo() -> None:
pass
[file m.py.next]
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.next]
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.next]
def func1() -> A: pass
[rechecked mod1]
[stale]
[out2]
tmp/mod1.py:1: error: Name 'A' is not defined
[case testIncrementalSameNameChange]
import mod1
[file mod1.py]
from mod2 import A
def func1() -> A: pass
[file mod2.py]
class A: pass
[file mod2.py.next]
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.next]
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.next]
def foo() -> int:
def inner2() -> str:
return "foo"
return inner2()
[rechecked 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.next]
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.next]
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.next]
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.next]
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.next]
# 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.next]
# 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.next]
# 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.next]
# 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.next]
# 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.next]
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.next]
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.next]
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.next]
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.next]
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.next]
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.next]
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.next]
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.next]
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.next]
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.next]
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.next]
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.next]
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.next]
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.next]
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.next]
from parent import b
[file parent/b.py.next]
[stale 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.next]
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.next]
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
[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.next]
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.next]
[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]
[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.next]
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.next]
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.next]
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.next]
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.next]
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 testIncrementalSilentImportsWithBlatantError]
# cmd: mypy -m main
# flags: --follow-imports=skip
[file main.py]
from evil import Hello
[file main.py.next]
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.next]
# 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.next]
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.next]
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.next]
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.next]
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.next]
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.next]
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 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.next]
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.next]
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.next]
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.next]
from funcs import callee
from classes import Outer
def caller(a: Outer.Inner) -> int:
callee(a)
[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.next]
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.next]
x = 0
x + ''
[case testIncrementalFollowImportsSkip]
# flags: --follow-imports=skip
import a
reveal_type(a.x)
[file a.py]
/
[file a.py.next]
//
[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.next]
//
[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.next]
[[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 testIncrementalNamedTupleInMethod4]
from ntcrash import C
reveal_type(C().a)
reveal_type(C().b)
reveal_type(C().c)
[file ntcrash.py]
from typing import NamedTuple
class C:
def __init__(self) -> None:
A = NamedTuple('A', [('x', int)])
self.a = A(0)
self.b = A(0) # type: A
self.c = A
[out1]
main:2: error: Revealed type is 'Tuple[builtins.int, fallback=ntcrash.C.A@4]'
main:3: error: Revealed type is 'Tuple[builtins.int, fallback=ntcrash.C.A@4]'
main:4: error: Revealed type is 'def (x: builtins.int) -> Tuple[builtins.int, fallback=ntcrash.C.A@4]'
[out2]
main:2: error: Revealed type is 'Tuple[builtins.int, fallback=ntcrash.C.A@4]'
main:3: error: Revealed type is 'Tuple[builtins.int, fallback=ntcrash.C.A@4]'
main:4: error: Revealed type is 'def (x: builtins.int) -> Tuple[builtins.int, fallback=ntcrash.C.A@4]'
[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 testIncrementalTypedDictInMethod4]
from ntcrash import C
reveal_type(C().a)
reveal_type(C().b)
reveal_type(C().c)
[file ntcrash.py]
from mypy_extensions import TypedDict
class C:
def __init__(self) -> None:
A = TypedDict('A', {'x': int})
self.a = A(x=0)
self.b = A(x=0) # type: A
self.c = A
[builtins fixtures/dict.pyi]
[out1]
main:2: error: Revealed type is 'TypedDict(x=builtins.int, _fallback=typing.Mapping[builtins.str, builtins.int])'
main:3: error: Revealed type is 'TypedDict(x=builtins.int, _fallback=ntcrash.C.A@4)'
main:4: error: Revealed type is 'def () -> ntcrash.C.A@4'
[out2]
main:2: error: Revealed type is 'TypedDict(x=builtins.int, _fallback=typing.Mapping[builtins.str, builtins.int])'
main:3: error: Revealed type is 'TypedDict(x=builtins.int, _fallback=ntcrash.C.A@4)'
main:4: error: Revealed type is 'def () -> ntcrash.C.A@4'
[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]