-- Type checker test cases dealing with modules and imports.

[case testAccessImportedDefinitions]
import m
import typing
m.f()           # E: Too few arguments for "f"
m.f(object())   # E: Argument 1 to "f" has incompatible type "object"; expected "A"
m.x = object()  # E: Incompatible types in assignment (expression has type "object", variable has type "A")
m.f(m.A())
m.x = m.A()
[file m.py]
class A: pass
def f(a: A) -> None: pass
x = A()

[case testAccessImportedDefinitions]
import m
import typing
m.f(object()) # E: Argument 1 to "f" has incompatible type "object"; expected "A"
m.f(m.A())
[file m.py]
class A: pass
def f(a: A) -> None: pass

[case testAccessImportedDefinitions2]
from m import f, A
import typing
f(object()) # E: Argument 1 to "f" has incompatible type "object"; expected "A"
f(A())
[file m.py]
class A: pass
def f(a: A) -> None: pass

[case testImportedExceptionType]
import m
import typing
try:
    pass
except m.Err:
    pass
except m.Bad: # E: Exception type must be derived from BaseException
    pass
[file m.py]
class Err(BaseException): pass
class Bad: pass
[builtins fixtures/exception.pyi]

[case testImportedExceptionType2]
from m import Err, Bad
import typing
try:
    pass
except Err:
    pass
except Bad: # E: Exception type must be derived from BaseException
    pass
[file m.py]
class Err(BaseException): pass
class Bad: pass
[builtins fixtures/exception.pyi]

[case testImportWithinBlock]
import typing
if 1:
    import m
    m.a = m.b   # E: Incompatible types in assignment (expression has type "B", variable has type "A")
    m.a = m.a
    m.f()
    m.f(m.a)    # E: Too many arguments for "f"
    m.a = m.A()
    m.a = m.B() # E: Incompatible types in assignment (expression has type "B", variable has type "A")
[file m.py]
class A: pass
class B: pass
a = A()
b = B()
def f() -> None: pass

[case testImportWithinFunction]
import typing
def f() -> None:
    from m import a, b, f, A, B
    a = b   # E: Incompatible types in assignment (expression has type "B", variable has type "A")
    a = a
    f()
    f(a)    # E: Too many arguments for "f"
    a = A()
    a = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A")
[file m.py]
class A: pass
class B: pass
a = A()
b = B()
def f() -> None: pass
[out]

[case testImportWithinMethod]
import typing
class C:
    def f(self) -> None:
        from m import *
        a = b   # E: Incompatible types in assignment (expression has type "B", variable has type "A")
        a = a
        f()
        f(a)    # E: Too many arguments for "f"
        a = A()
        a = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A")
[file m.py]
class A: pass
class B: pass
a = A()
b = B()
def f() -> None: pass
[out]

[case testImportWithinClassBody]
import typing
class C:
    import m
    m.f()
    m.f(C) # E: Too many arguments for "f"
[file m.py]
def f() -> None: pass
[out]

[case testImportWithinClassBody2]
import typing
class C:
    from m import f
    f()
    f(C) # E: Too many arguments for "f"
[file m.py]
def f() -> None: pass
[out]

[case testImportWithStub]
import _m
_m.f("hola")
[file _m.pyi]
def f(c:str) -> None: pass
[out]

[case testImportWithStubIncompatibleType]
import _m
_m.f("hola")
_m.f(12)  # E: Argument 1 to "f" has incompatible type "int"; expected "str"
[file _m.py]
def f(c):
  print(c)
[file _m.pyi]
def f(c:str) -> None: pass

[case testInvalidOperationsOnModules]
import m
import typing

class A: pass
m()      # E: Module not callable
a = m # type: A  # E: Incompatible types in assignment (expression has type Module, variable has type "A")
m + None # E: Unsupported left operand type for + (Module)
[file m.py]
[builtins fixtures/module.pyi]

[case testNameDefinedInDifferentModule]
import m, n
import typing
m.x # E: Module has no attribute "x"
[file m.py]
y = object()
[file n.py]
x = object()
[builtins fixtures/module.pyi]

[case testChainedAssignmentAndImports]
import m

i, s = None, None # type: (int, str)
i = m.x
i = m.y
s = m.x # E: Incompatible types in assignment (expression has type "int", variable has type "str")
s = m.y # E: Incompatible types in assignment (expression has type "int", variable has type "str")
[file m.py]
x = y = 1
[builtins fixtures/primitives.pyi]

[case testConditionalFunctionDefinitionAndImports]
import m
import typing
m.f(1)
m.f('x') # E: Argument 1 to "f" has incompatible type "str"; expected "int"
[file m.py]
x = object()
if x:
    def f(x: int) -> None: pass
else:
    def f(x: int) -> None: pass

[case testTypeCheckWithUnknownModule]
import nonexistent
None + ''
[out]
main:1: error: Cannot find module named 'nonexistent'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:2: error: Unsupported left operand type for + ("None")

[case testTypeCheckWithUnknownModule2]
import m, nonexistent
None + ''
m.x = 1
m.x = ''
[file m.py]
x = 1
[out]
main:1: error: Cannot find module named 'nonexistent'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:2: error: Unsupported left operand type for + ("None")
main:4: error: Incompatible types in assignment (expression has type "str", variable has type "int")

[case testTypeCheckWithUnknownModule3]
import nonexistent, m
None + ''
m.x = 1
m.x = ''
[file m.py]
x = 1
[out]
main:1: error: Cannot find module named 'nonexistent'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:2: error: Unsupported left operand type for + ("None")
main:4: error: Incompatible types in assignment (expression has type "str", variable has type "int")

[case testTypeCheckWithUnknownModule4]
import nonexistent, another
None + ''
[out]
main:1: error: Cannot find module named 'nonexistent'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:1: error: Cannot find module named 'another'
main:2: error: Unsupported left operand type for + ("None")

[case testTypeCheckWithUnknownModule5]
import nonexistent as x
None + ''
[out]
main:1: error: Cannot find module named 'nonexistent'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:2: error: Unsupported left operand type for + ("None")

[case testTypeCheckWithUnknownModuleUsingFromImport]
from nonexistent import x
None + ''
[out]
main:1: error: Cannot find module named 'nonexistent'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:2: error: Unsupported left operand type for + ("None")

[case testTypeCheckWithUnknownModuleUsingImportStar]
from nonexistent import *
None + ''
[out]
main:1: error: Cannot find module named 'nonexistent'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:2: error: Unsupported left operand type for + ("None")

[case testAccessingUnknownModule]
import xyz
xyz.foo()
xyz()
[out]
main:1: error: Cannot find module named 'xyz'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)

[case testAccessingUnknownModule2]
import xyz, bar
xyz.foo()
bar()
[out]
main:1: error: Cannot find module named 'xyz'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:1: error: Cannot find module named 'bar'

[case testAccessingUnknownModule3]
import xyz as z
xyz.foo()
z()
[out]
main:1: error: Cannot find module named 'xyz'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:2: error: Name 'xyz' is not defined

[case testAccessingNameImportedFromUnknownModule]
from xyz import y, z
y.foo()
z()
[out]
main:1: error: Cannot find module named 'xyz'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)

[case testAccessingNameImportedFromUnknownModule2]
from xyz import *
y
[out]
main:1: error: Cannot find module named 'xyz'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:2: error: Name 'y' is not defined

[case testAccessingNameImportedFromUnknownModule3]
from xyz import y as z
y
z
[out]
main:1: error: Cannot find module named 'xyz'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:2: error: Name 'y' is not defined

[case testUnknownModuleRedefinition]
import xab
def xab(): pass
[out]
main:1: error: Cannot find module named 'xab'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)

[case testAccessingUnknownModuleFromOtherModule]
import x
x.nonexistent.foo
x.z
[file x.py]
import nonexistent
[builtins fixtures/module.pyi]
[out]
tmp/x.py:1: error: Cannot find module named 'nonexistent'
tmp/x.py:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:3: error: Module has no attribute "z"

[case testUnknownModuleImportedWithinFunction]
def f():
    import foobar
def foobar(): pass
foobar('')
[out]
main:2: error: Cannot find module named 'foobar'
main:2: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:4: error: Too many arguments for "foobar"

[case testUnknownModuleImportedWithinFunction2]
def f():
    from foobar import x
def x(): pass
x('')
[out]
main:2: error: Cannot find module named 'foobar'
main:2: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:4: error: Too many arguments for "x"

[case testRelativeImports]
import typing
import m.a
m.a.x = m.a.y # Error
[file m/__init__.py]
[file m/a.py]
import typing
from .b import A, B, x, y
z = x
z = y # Error
[file m/b.py]
import typing
class A: pass
class B: pass
x = A()
y = B()
[out]
tmp/m/a.py:4: error: Incompatible types in assignment (expression has type "B", variable has type "A")
main:3: error: Incompatible types in assignment (expression has type "B", variable has type "A")

[case testRelativeImports2]
import typing
import m.a
m.a.x = m.a.y # E: Incompatible types in assignment (expression has type "B", variable has type "A")
[file m/__init__.py]
[file m/a.py]
import typing
from .b import A, B, x, y
[file m/b.py]
import typing
class A: pass
class B: pass
x = A()
y = B()

[case testExportedValuesInImportAll]
import typing
from m import *
_ = a
_ = b
_ = c
_ = d
_ = e
_ = f # E: Name 'f' is not defined
_ = _g # E: Name '_g' is not defined
[file m.py]
__all__ = ['a']
__all__ += ('b',)
__all__.append('c')
__all__.extend(('d', 'e'))

a = b = c = d = e = f = _g = 1
[builtins fixtures/module_all.pyi]

[case testAllMustBeSequenceStr]
import typing
__all__ = [1, 2, 3]
[builtins fixtures/module_all.pyi]
[out]
main:2: error: Type of __all__ must be "Sequence[str]", not "List[int]"

[case testAllMustBeSequenceStr_python2]
import typing
__all__ = [1, 2, 3]
[builtins_py2 fixtures/module_all_python2.pyi]
[out]
main:2: error: Type of __all__ must be "Sequence[unicode]", not "List[int]"

[case testAllUnicodeSequenceOK_python2]
import typing
__all__ = [u'a', u'b', u'c']
[builtins_py2 fixtures/module_all_python2.pyi]

[out]

[case testUnderscoreExportedValuesInImportAll]
import typing
from m import *
_ = a
_ = _b
_ = __c__
_ = ___d
_ = e
_ = f # E: Name 'f' is not defined
_ = _g # E: Name '_g' is not defined
[file m.py]
__all__ = ['a']
__all__ += ('_b',)
__all__.append('__c__')
__all__.extend(('___d', 'e'))

a = _b = __c__ = ___d = e = f = _g = 1
[builtins fixtures/module_all.pyi]

[case testEllipsisInitializerInStubFileWithType]
import m
m.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int")
[file m.pyi]
x = ... # type: int

[case testEllipsisInitializerInStubFileWithoutType]
import m
m.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "ellipsis")
[file m.pyi]
# Ellipsis is only special with a # type: comment (not sure though if this is great)
x = ...

[case testEllipsisInitializerInModule]
x = ... # type: int # E: Incompatible types in assignment (expression has type "ellipsis", variable has type "int")

[case testEllipsisDefaultArgValueInStub]
import m
m.f(1)
m.f('') # E: Argument 1 to "f" has incompatible type "str"; expected "int"
[file m.pyi]
def f(x: int = ...) -> None: pass

[case testEllipsisDefaultArgValueInStub2]
import m
def f(x: int = ...) -> None: pass
[file m.pyi]
def g(x: int = '') -> None: pass
[out]
tmp/m.pyi:1: error: Incompatible default for argument "x" (default has type "str", argument has type "int")
main:2: error: Incompatible default for argument "x" (default has type "ellipsis", argument has type "int")

[case testEllipsisDefaultArgValueInNonStub]
def f(x: int = ...) -> None: pass # E: Incompatible default for argument "x" (default has type "ellipsis", argument has type "int")
[out]

[case testStarImportOverlapping]
from m1 import *
from m2 import *
j = ''
[file m1.py]
x = 1
[file m2.py]
x = 1

[case testStarImportOverlappingMismatch]
from m1 import *
from m2 import * # E: Incompatible import of "x" (imported name has type "int", local name has type "str")
j = ''
[file m1.py]
x = ''
[file m2.py]
x = 1

[case testStarImportOverridingLocalImports-skip]
from m1 import *
from m2 import *
x = '' # E: TODO (cannot assign str to int)
[file m1.py]
x = 1
[file m2.py]
x = 1

[case testAssignToFuncDefViaImport]
from m import *  # E: Incompatible import of "x" (imported name has type "int", local name has type "str")
f = None
x = ''
[file m.py]
def f(): pass
x = 1+0
[out]


-- Conditional definitions and function redefinitions via module object
-- --------------------------------------------------------------------


[case testConditionalImportAndAssign]
try:
    from m import x
except:
    x = None
try:
    from m import x as y
except:
    y = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str")
[file m.py]
x = ''

[case testAssignAndConditionalImport]
x = ''
try:
    from m import x
except:
    pass
y = 1
try:
    from m import x as y  # E: Incompatible import of "y" (imported name has type "str", local name has type "int")
except:
    pass
[file m.py]
x = ''

[case testAssignAndConditionalStarImport]
x = ''
y = 1
try:
    from m import * # E: Incompatible import of "y" (imported name has type "str", local name has type "int")
except:
    pass
[file m.py]
x = ''
y = ''

[case testRedefineImportedFunctionViaImport]
try:
    from m import f, g
except:
    def f(x): pass
    def g(x): pass # E: All conditional function variants must have identical signatures
[file m.py]
def f(x): pass
def g(x, y): pass

[case testImportedVariableViaImport]
try:
    from m import x
except:
    from n import x # E: Incompatible import of "x" (imported name has type "str", local name has type "int")
[file m.py]
x = 1
[file n.py]
x = ''

[case testRedefineFunctionViaImport]
def f(x): pass
def g(x): pass
try:
    from m import f, g # E: Incompatible import of "g" (imported name has type "Callable[[Any, Any], Any]", local name has type "Callable[[Any], Any]")
except:
    pass
[file m.py]
def f(x): pass
def g(x, y): pass

[case testImportVariableAndAssignNone]
try:
    from m import x
except:
    x = None
[file m.py]
x = 1

[case testImportFunctionAndAssignNone]
try:
    from m import f
except:
    f = None
[file m.py]
def f(): pass

[case testImportFunctionAndAssignFunction]
def g(x): pass
try:
    from m import f
except:
    f = g
[file m.py]
def f(x): pass

[case testImportFunctionAndAssignIncompatible]
try:
    from m import f
except:
    f = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "Callable[[], Any]")
[file m.py]
def f(): pass

[case testAssignToFuncDefViaGlobalDecl2]
import typing
from m import f
def g() -> None:
    global f
    f = None
    f = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "Callable[[], Any]")
[file m.py]
def f(): pass
[out]

[case testAssignToFuncDefViaNestedModules]
import m.n
m.n.f = None
m.n.f = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "Callable[[], Any]")
[file m/__init__.py]
[file m/n.py]
def f(): pass
[out]

[case testAssignToFuncDefViaModule]
import m
m.f = None
m.f = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "Callable[[], Any]")
[file m.py]
def f(): pass
[out]

[case testConditionalImportAndAssignNoneToModule]
if object():
    import m
else:
    m = None
m.f(1) # E: Argument 1 to "f" has incompatible type "int"; expected "str"
[file m.py]
def f(x: str) -> None: pass
[builtins fixtures/module.pyi]
[out]

[case testConditionalImportAndAssignInvalidToModule]
if object():
    import m
else:
    m = 1 # E: Incompatible types in assignment (expression has type "int", variable has type Module)
[file m.py]
[builtins fixtures/module.pyi]
[out]

[case testImportAndAssignToModule]
import m
m = None
m.f(1) # E: Argument 1 to "f" has incompatible type "int"; expected "str"
[file m.py]
def f(x: str) -> None: pass
[builtins fixtures/module.pyi]
[out]


-- Test cases that simulate 'mypy -m modname'
--
-- The module name to import is encoded in a comment.

[case testTypeCheckNamedModule]
# cmd: mypy -m m.a
[file m/__init__.py]
None + 1
[file m/a.py]
[out]
tmp/m/__init__.py:1: error: Unsupported left operand type for + ("None")

[case testTypeCheckNamedModule2]
# cmd: mypy -m m.a
[file m/__init__.py]
[file m/a.py]
None + 1
[out]
tmp/m/a.py:1: error: Unsupported left operand type for + ("None")

[case testTypeCheckNamedModule3]
# cmd: mypy -m m
[file m/__init__.py]
None + 1
[file m/a.py]
[out]
tmp/m/__init__.py:1: error: Unsupported left operand type for + ("None")

[case testTypeCheckNamedModule4]
# cmd: mypy -m m
[file m/__init__.py]
[file m/a.py]
None + 1  # Not analyzed.
[out]

[case testTypeCheckNamedModule5]
# cmd: mypy -m m
None + ''  # Not analyzed.
[file m.py]
None + 1
[out]
tmp/m.py:1: error: Unsupported left operand type for + ("None")

[case testTypeCheckNamedModuleWithImportCycle]
# cmd: mypy -m m.a
None + 1  # Does not generate error, as this file won't be analyzed.
[file m/__init__.py]
import m.a
[file m/a.py]
[out]


-- Checks dealing with submodules and different kinds of imports
-- -------------------------------------------------------------

[case testSubmoduleRegularImportAddsAllParents]
import a.b.c
reveal_type(a.value)  # E: Revealed type is 'builtins.int'
reveal_type(a.b.value)  # E: Revealed type is 'builtins.str'
reveal_type(a.b.c.value)  # E: Revealed type is 'builtins.float'
b.value  # E: Name 'b' is not defined
c.value  # E: Name 'c' is not defined

[file a/__init__.py]
value = 3
[file a/b/__init__.py]
value = "a"
[file a/b/c.py]
value = 3.2
[out]

[case testSubmoduleImportAsDoesNotAddParents]
import a.b.c as foo
reveal_type(foo.value)  # E: Revealed type is 'builtins.float'
a.value  # E: Name 'a' is not defined
b.value  # E: Name 'b' is not defined
c.value  # E: Name 'c' is not defined

[file a/__init__.py]
value = 3
[file a/b/__init__.py]
value = "a"
[file a/b/c.py]
value = 3.2
[out]

[case testSubmoduleImportFromDoesNotAddParents]
from a import b
reveal_type(b.value)  # E: Revealed type is 'builtins.str'
b.c.value  # E: Module has no attribute "c"
a.value  # E: Name 'a' is not defined

[file a/__init__.py]
value = 3
[file a/b/__init__.py]
value = "a"
[file a/b/c.py]
value = 3.2
[builtins fixtures/module.pyi]
[out]

[case testSubmoduleImportFromDoesNotAddParents2]
from a.b import c
reveal_type(c.value)  # E: Revealed type is 'builtins.float'
a.value  # E: Name 'a' is not defined
b.value  # E: Name 'b' is not defined

[file a/__init__.py]
value = 3
[file a/b/__init__.py]
value = "a"
[file a/b/c.py]
value = 3.2
[out]

[case testSubmoduleRegularImportNotDirectlyAddedToParent]
import a.b.c
def accept_float(x: float) -> None: pass
accept_float(a.b.c.value)

[file a/__init__.py]
value = 3
b.value
a.b.value

[file a/b/__init__.py]
value = "a"
c.value
a.b.c.value

[file a/b/c.py]
value = 3.2
[out]
tmp/a/b/__init__.py:2: error: Name 'c' is not defined
tmp/a/b/__init__.py:3: error: Name 'a' is not defined
tmp/a/__init__.py:2: error: Name 'b' is not defined
tmp/a/__init__.py:3: error: Name 'a' is not defined

[case testSubmoduleMixingLocalAndQualifiedNames]
from a.b import MyClass
val1 = None  # type: a.b.MyClass  # E: Name 'a' is not defined
val2 = None  # type: MyClass

[file a/__init__.py]
[file a/b.py]
class MyClass: pass
[out]

[case testSubmoduleMixingImportFrom]
import parent.child

[file parent/__init__.py]

[file parent/common.py]
class SomeClass: pass

[file parent/child.py]
from parent.common import SomeClass
from parent import common
foo = parent.common.SomeClass()

[builtins fixtures/module.pyi]
[out]
tmp/parent/child.py:3: error: Name 'parent' is not defined

[case testSubmoduleMixingImportFromAndImport]
import parent.child

[file parent/__init__.py]

[file parent/common.py]
class SomeClass: pass

[file parent/unrelated.py]
class ShouldNotLoad: pass

[file parent/child.py]
from parent.common import SomeClass
import parent

# Note, since this might be unintuitive -- when `parent.common` is loaded in any way,
# shape, or form, it's added to `parent`'s namespace, which is why the below line
# succeeds.
foo = parent.common.SomeClass()
reveal_type(foo)
bar = parent.unrelated.ShouldNotLoad()

[builtins fixtures/module.pyi]
[out]
tmp/parent/child.py:8: error: Revealed type is 'parent.common.SomeClass'
tmp/parent/child.py:9: error: Module has no attribute "unrelated"

[case testSubmoduleMixingImportFromAndImport2]
import parent.child

[file parent/__init__.py]

[file parent/common.py]
class SomeClass: pass

[file parent/child.py]
from parent import common
import parent
foo = parent.common.SomeClass()
reveal_type(foo)

[builtins fixtures/module.pyi]
[out]
tmp/parent/child.py:4: error: Revealed type is 'parent.common.SomeClass'

-- Tests repeated imports

[case testIdenticalImportFromTwice]
from a import x, y, z
from b import x, y, z
[file a.py]
from common import x, y, z
[file b.py]
from common import x, y, z
[file common.py]
x = 3
def y() -> int: return 3
class z: pass
[out]

[case testIdenticalImportStarTwice]
from a import *
from b import *
[file a.py]
from common import x, y, z
[file b.py]
from common import x, y, z
[file common.py]
x = 3
def y() -> int: return 3
class z: pass
[out]

[case testDifferentImportSameNameTwice]
from a import x, y, z
from b import x, y, z
[file a.py]
x = 3
def y() -> int: return 1
class z: pass
[file b.py]
x = "foo"
def y() -> str: return "foo"
class z: pass
[out]
main:2: error: Incompatible import of "x" (imported name has type "str", local name has type "int")
main:2: error: Incompatible import of "y" (imported name has type "Callable[[], str]", local name has type "Callable[[], int]")
main:2: error: Incompatible import of "z" (imported name has type "Type[b.z]", local name has type "Type[a.z]")

-- Misc

[case testInheritFromBadImport]
# cmd: mypy -m bar
[file foo.py]
pass
[file bar.py]
from foo import B
class C(B):
    pass
[out]
tmp/bar.py:1: error: Module 'foo' has no attribute 'B'

[case testImportSuppressedWhileAlmostSilent]
# cmd: mypy -m main
# flags: --follow-imports=error
[file main.py]
import mod
[file mod.py]
[builtins fixtures/module.pyi]
[out]
tmp/main.py:1: note: Import of 'mod' ignored
tmp/main.py:1: note: (Using --follow-imports=error, module not passed on command line)

[case testAncestorSuppressedWhileAlmostSilent]
# cmd: mypy -m foo.bar
# flags: --follow-imports=error
[file foo/bar.py]
[file foo/__init__.py]
[builtins fixtures/module.pyi]
[out]
tmp/foo/bar.py: note: Ancestor package 'foo' ignored
tmp/foo/bar.py: note: (Using --follow-imports=error, submodule passed on command line)

[case testStubImportNonStubWhileSilent]
# cmd: mypy -m main
# flags: --follow-imports=skip
[file main.py]
from stub import x, z  # Followed
from other import y  # Not followed
x + ''  # No error here
y + ''  # No error here
z + ''  # Error here
[file stub.pyi]
from non_stub import x as x  # this import is not followed

z = 42
[file non_stub.py]
x = 42

x + ''  # no error because file is not analyzed
[file other.py]
y = 42
[builtins fixtures/module.pyi]
[out]
tmp/main.py:5: error: Unsupported left operand type for + ("int")

[case testSilentSubmoduleImport]
# cmd: mypy -m foo
# flags: --follow-imports=skip
[file foo/__init__.py]
from foo import bar
[file foo/bar.py]
pass

[case testImportReExportFromChildrenInCycle1]
# cmd: mypy -m project.root project.study.a project.neighbor
[file project/__init__.py]
from project.study import CustomType
x = 10
[file project/root.py]
[file project/study/__init__.py]
from project.study.a import CustomType
[file project/study/a.py]
from project import root
# TODO (#4498): This test is basically testing the `all_are_submodules` logic
# in build, which skips generating a dependenecy to a module if
# everything in it is a submodule. But that is still all just a
# workaround for bugs in cycle handling. If we uncomment the next
# line, we'll still break:
# from project import x
CustomType = str
[file project/neighbor/__init__.py]
from project.study import CustomType
def m(arg: CustomType) -> str:
    return 'test'

[case testImportReExportFromChildrenInCycle2]
# cmd: mypy -m project project.b project.ba project.c
# See comments in above test about this being a workaround.
[file foo.py]
def get_foo() -> int: return 12

[file project/ba.py]
from . import b
b.FOO

[file project/b.py]
import foo
from . import c
FOO = foo.get_foo()

[file project/c.py]

[file project/__init__.py]
from . import ba

[case testSuperclassInImportCycle]
import a
import d
a.A().f(d.D())
[file a.py]
if 0:
    import d
class B: pass
class C(B): pass
class A:
    def f(self, x: B) -> None: pass
[file d.py]
import a
class D(a.C): pass

[case testSuperclassInImportCycleReversedImports]
import d
import a
a.A().f(d.D())
[file a.py]
if 0:
    import d
class B: pass
class C(B): pass
class A:
    def f(self, x: B) -> None: pass
[file d.py]
import a
class D(a.C): pass

[case testPreferPackageOverFile]
import a
[file a.py]
/  # intentional syntax error -- this file shouldn't be parsed
[file a/__init__.py]
pass
[out]

[case testPreferPackageOverFile2]
from a import x
[file a.py]
/  # intentional syntax error -- this file shouldn't be parsed
[file a/__init__.py]
x = 0
[out]

[case testImportInClass]
class C:
    import foo
reveal_type(C.foo.bar)  # E: Revealed type is 'builtins.int'
[file foo.py]
bar = 0
[builtins fixtures/module.pyi]
[out]

[case testIfFalseImport]
if False:
    import a
def f(x: 'a.A') -> int:
    return x.f()
[file a.py]
class A:
    def f(self) -> int:
        return 0
[builtins fixtures/bool.pyi]


-- Test stability under import cycles
-- ----------------------------------

-- The first two tests are identical except one main has 'import x'
-- and the other 'import y'.  Previously (before build.order_ascc()
-- was added) one of these would fail because the imports were
-- processed in the (reverse) order in which the files were
-- encountered.

[case testImportCycleStability1]
import x
[file x.py]
def f() -> str: return ''
class Base:
    attr = f()
def foo():
    import y
[file y.py]
import x
class Sub(x.Base):
    attr = x.Base.attr
[out]

[case testImportCycleStability2]
import y
[file x.py]
def f() -> str: return ''
class Base:
    attr = f()
def foo():
    import y
[file y.py]
import x
class Sub(x.Base):
    attr = x.Base.attr
[out]

-- This case isn't fixed by order_ascc(), but is fixed by the
-- lightweight type inference added to semanal.py
-- (analyze_simple_literal_type()).

[case testImportCycleStability3]
import y
[file x.py]
class Base:
    pass
def foo() -> int:
    import y
    reveal_type(y.Sub.attr)
    return y.Sub.attr
[file y.py]
import x
class Sub(x.Base):
    attr = 0
[out]
tmp/x.py:5: error: Revealed type is 'builtins.int'

-- This case has a symmetrical cycle, so it doesn't matter in what
-- order the files are processed.  It depends on the lightweight type
-- interference.

[case testImportCycleStability4]
import x
[file x.py]
import y
class C:
    attr = ''
def foo() -> int:
    return y.D.attr
[file y.py]
import x
class D:
    attr = 0
def bar() -> str:
    return x.C.attr

-- These cases test all supported literal types.

[case testImportCycleStability5]
import y
[file x.py]
class Base:
    pass
def foo() -> None:
    import y
    i = y.Sub.iattr  # type: int
    f = y.Sub.fattr  # type: float
    s = y.Sub.sattr  # type: str
    b = y.Sub.battr  # type: bytes
[file y.py]
import x
class Sub(x.Base):
    iattr = 0
    fattr = 0.0
    sattr = ''
    battr = b''
[out]

[case testImportCycleStability6_python2]
import y
[file x.py]
class Base:
    pass
def foo():
    # type: () -> None
    import y
    i = y.Sub.iattr  # type: int
    f = y.Sub.fattr  # type: float
    s = y.Sub.sattr  # type: str
    u = y.Sub.uattr  # type: unicode
[file y.py]
import x
class Sub(x.Base):
    iattr = 0
    fattr = 0.0
    sattr = ''
    uattr = u''
[out]

-- This case tests module-level variables.

[case testImportCycleStability7]
import x
[file x.py]
def foo() -> int:
    import y
    reveal_type(y.value)
    return y.value
[file y.py]
import x
value = 12
[out]
tmp/x.py:3: error: Revealed type is 'builtins.int'

-- This is not really cycle-related but still about the lightweight
-- type checker.

[case testImportCycleStability8]
x = 1  # type: str
reveal_type(x)
[out]
main:1: error: Incompatible types in assignment (expression has type "int", variable has type "str")
main:2: error: Revealed type is 'builtins.str'

-- Tests for cross-module second_pass checking.

[case testSymmetricImportCycle1]
import a
[file a.py]
import b
def f() -> int:
    return b.x
y = 0 + 0
[file b.py]
import a
def g() -> int:
    reveal_type(a.y)
    return a.y
x = 1 + 1
[out]
tmp/b.py:3: error: Revealed type is 'builtins.int'

[case testSymmetricImportCycle2]
import b
[file a.py]
import b
def f() -> int:
    reveal_type(b.x)
    return b.x
y = 0 + 0
[file b.py]
import a
def g() -> int:
    return a.y
x = 1 + 1
[out]
tmp/a.py:3: error: Revealed type is 'builtins.int'

[case testThreePassesRequired]
import b
[file a.py]
import b
class C:
    def f1(self) -> None:
        self.x2
    def f2(self) -> None:
        self.x2 = b.b
[file b.py]
import a
b = 1 + 1
[out]
tmp/a.py:4: error: Cannot determine type of 'x2'

[case testErrorInPassTwo1]
import b
[file a.py]
import b
def f() -> None:
    a = b.x + 1
    a + ''
[file b.py]
import a
x = 1 + 1
[out]
tmp/a.py:4: error: Unsupported operand types for + ("int" and "str")

[case testErrorInPassTwo2]
import a
[file a.py]
import b
def f() -> None:
    a = b.x + 1
    a + ''
[file b.py]
import a
x = 1 + 1
[out]
tmp/a.py:4: error: Unsupported operand types for + ("int" and "str")

[case testDeferredDecorator]
import a
[file a.py]
import b
def g() -> None:
    f('')
@b.deco
def f(a: str) -> int: pass
reveal_type(f)
x = 1 + 1
[file b.py]
from typing import Callable, TypeVar
import a
T = TypeVar('T')
def deco(f: Callable[[T], int]) -> Callable[[T], int]:
    a.x
    return f
[out]
tmp/a.py:6: error: Revealed type is 'def (builtins.str*) -> builtins.int'

[case testDeferredClassContext]
class A:
    def f(self) -> str: return 'foo'
class B(A):
    def f(self) -> str: return self.x
    def initialize(self) -> None: self.x = 'bar'

[case testDeferredClassContextUnannotated]
class A:
    def f(self) -> str: return 'foo'
class B(A):
    def f(self) -> str: return self.x
    def initialize(self): self.x = 'bar'

-- Scripts and __main__

[case testScriptsAreModules]
# flags: --scripts-are-modules
[file a]
pass
[file b]
pass

-- Misc

[case testScriptsAreNotModules]
# cmd: mypy a b
[file a]
pass
[file b]
pass
[out]

[case testTypeCheckPrio]
# cmd: mypy -m part1 part2 part3 part4

[file part1.py]
from part3 import Thing
class FirstThing: pass

[file part2.py]
from part4 import part4_thing as Thing

[file part3.py]
from part2 import Thing
reveal_type(Thing)

[file part4.py]
from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from part1 import FirstThing
def part4_thing(a: int) -> str: pass

[builtins fixtures/bool.pyi]
[out]
tmp/part3.py:2: error: Revealed type is 'def (a: builtins.int) -> builtins.str'

[case testImportStarAliasAnyList]
import bar

[file bar.py]
from foo import *
def bar(y: AnyAlias) -> None:  pass

l = None # type: ListAlias[int]
reveal_type(l)

[file foo.py]
from typing import Any, List
AnyAlias = Any
ListAlias = List
[builtins fixtures/list.pyi]
[out]
tmp/bar.py:5: error: Revealed type is 'builtins.list[builtins.int]'

[case testImportStarAliasSimpleGeneric]
from ex2a import *

def do_something(dic: Row) -> None:
    pass

def do_another() -> Row:
    return {}

do_something({'good': 'bad'}) # E: Dict entry 0 has incompatible type "str": "str"; expected "str": "int"
reveal_type(do_another()) # E: Revealed type is 'builtins.dict[builtins.str, builtins.int]'

[file ex2a.py]
from typing import Dict
Row = Dict[str, int]
[builtins fixtures/dict.pyi]
[out]

[case testImportStarAliasGeneric]
from y import *
notes = None  # type: G[X]
another = G[X]()
second = XT[str]()
last = XT[G]()

reveal_type(notes) # E: Revealed type is 'y.G[y.G[builtins.int]]'
reveal_type(another) # E: Revealed type is 'y.G[y.G*[builtins.int]]'
reveal_type(second) # E: Revealed type is 'y.G[builtins.str*]'
reveal_type(last) # E: Revealed type is 'y.G[y.G*[Any]]'

[file y.py]
from typing import Generic, TypeVar

T = TypeVar('T')

class G(Generic[T]):
    pass

X = G[int]
XT = G[T]
[out]

[case testImportStarAliasCallable]
from foo import *
from typing import Any

def bar(x: Any, y: AnyCallable) -> Any:
    return 'foo'

cb = None # type: AnyCallable
reveal_type(cb) # E: Revealed type is 'def (*Any, **Any) -> Any'

[file foo.py]
from typing import Callable, Any
AnyCallable = Callable[..., Any]
[out]

[case testRevealType]
import types
def f() -> types.ModuleType:
    return types
reveal_type(f())  # E: Revealed type is 'types.ModuleType'
reveal_type(types)  # E: Revealed type is 'types.ModuleType'

[builtins fixtures/module.pyi]

[case testClassImportAccessedInMethod]
class C:
    import m
    def foo(self) -> None:
        x = self.m.a
        reveal_type(x)  # E: Revealed type is 'builtins.str'
        # ensure we distinguish self from other variables
        y = 'hello'
        z = y.m.a  # E: "str" has no attribute "m"
    @classmethod
    def cmethod(cls) -> None:
        y = cls.m.a
        reveal_type(y)  # E: Revealed type is 'builtins.str'
    @staticmethod
    def smethod(foo: int) -> None:
        # we aren't confused by first arg of a staticmethod
        y = foo.m.a  # E: "int" has no attribute "m"

[file m.py]
a = 'foo'

[builtins fixtures/module.pyi]

[case testModuleAlias]
import m
m2 = m
reveal_type(m2.a)  # E: Revealed type is 'builtins.str'
m2.b  # E: Module has no attribute "b"
m2.c = 'bar'  # E: Module has no attribute "c"

[file m.py]
a = 'foo'

[builtins fixtures/module.pyi]

[case testClassModuleAlias]
import m

class C:
    x = m
    def foo(self) -> None:
        reveal_type(self.x.a)  # E: Revealed type is 'builtins.str'

[file m.py]
a = 'foo'

[builtins fixtures/module.pyi]

[case testLocalModuleAlias]
import m

def foo() -> None:
    x = m
    reveal_type(x.a)  # E: Revealed type is 'builtins.str'

class C:
    def foo(self) -> None:
        x = m
        reveal_type(x.a)  # E: Revealed type is 'builtins.str'

[file m.py]
a = 'foo'

[builtins fixtures/module.pyi]

[case testChainedModuleAlias]
import m
m3 = m2 = m
m4 = m3
m5 = m4
reveal_type(m2.a)  # E: Revealed type is 'builtins.str'
reveal_type(m3.a)  # E: Revealed type is 'builtins.str'
reveal_type(m4.a)  # E: Revealed type is 'builtins.str'
reveal_type(m5.a)  # E: Revealed type is 'builtins.str'

[file m.py]
a = 'foo'

[builtins fixtures/module.pyi]

[case testMultiModuleAlias]
import m, n
m2, n2, (m3, n3) = m, n, [m, n]
reveal_type(m2.a)  # E: Revealed type is 'builtins.str'
reveal_type(n2.b)  # E: Revealed type is 'builtins.str'
reveal_type(m3.a)  # E: Revealed type is 'builtins.str'
reveal_type(n3.b)  # E: Revealed type is 'builtins.str'

x, y = m  # E: 'types.ModuleType' object is not iterable
x, y, z = m, n  # E: Need more than 2 values to unpack (3 expected)
x, y = m, m, m  # E: Too many values to unpack (2 expected, 3 provided)
x, (y, z) = m, n  # E: 'types.ModuleType' object is not iterable
x, (y, z) = m, (n, n, n)  # E: Too many values to unpack (2 expected, 3 provided)

[file m.py]
a = 'foo'

[file n.py]
b = 'bar'

[builtins fixtures/module.pyi]

[case testModuleAliasWithExplicitAnnotation]
from typing import Any
import types
import m
mod_mod: types.ModuleType = m
mod_mod2: types.ModuleType
mod_mod2 = m
mod_mod3 = m  # type: types.ModuleType
mod_any: Any = m
mod_int: int = m  # E: Incompatible types in assignment (expression has type Module, variable has type "int")

reveal_type(mod_mod)  # E: Revealed type is 'types.ModuleType'
mod_mod.a  # E: Module has no attribute "a"
reveal_type(mod_mod2)  # E: Revealed type is 'types.ModuleType'
mod_mod2.a  # E: Module has no attribute "a"
reveal_type(mod_mod3)  # E: Revealed type is 'types.ModuleType'
mod_mod3.a  # E: Module has no attribute "a"
reveal_type(mod_any)  # E: Revealed type is 'Any'

[file m.py]
a = 'foo'

[builtins fixtures/module.pyi]

[case testModuleAliasPassedToFunction]
import types
import m

def takes_module(x: types.ModuleType):
    reveal_type(x.__file__)  # E: Revealed type is 'builtins.str'

n = m
takes_module(m)
takes_module(n)

[file m.py]
a = 'foo'

[builtins fixtures/module.pyi]

[case testModuleAliasRepeated]
import m, n

if bool():
    x = m
else:
    x = 3  # E: Incompatible types in assignment (expression has type "int", variable has type Module)

if bool():
    y = 3
else:
    y = m  # E: Incompatible types in assignment (expression has type Module, variable has type "int")

if bool():
    z = m
else:
    z = n  # E: Cannot assign multiple modules to name 'z' without explicit 'types.ModuleType' annotation

[file m.py]
a = 'foo'

[file n.py]
a = 3

[builtins fixtures/module.pyi]

[case testModuleAliasRepeatedWithAnnotation]
import types
import m, n

x: types.ModuleType
if bool():
    x = m
else:
    x = n

x.a  # E: Module has no attribute "a"
reveal_type(x.__file__)  # E: Revealed type is 'builtins.str'

[file m.py]
a = 'foo'

[file n.py]
a = 3

[builtins fixtures/module.pyi]

[case testModuleAliasRepeatedComplex]
import m, n, o

x = m
x = n  # E: Cannot assign multiple modules to name 'x' without explicit 'types.ModuleType' annotation
x = o  # E: Cannot assign multiple modules to name 'x' without explicit 'types.ModuleType' annotation

y = o
y, z = m, n  # E: Cannot assign multiple modules to name 'y' without explicit 'types.ModuleType' annotation

xx = m
xx = m
reveal_type(xx.a)  # E: Revealed type is 'builtins.str'

[file m.py]
a = 'foo'

[file n.py]
a = 3

[file o.py]
a = 'bar'

[builtins fixtures/module.pyi]

[case testModuleAliasToOtherModule]
import m, n
m = n  # E: Cannot assign multiple modules to name 'm' without explicit 'types.ModuleType' annotation

[file m.py]

[file n.py]

[builtins fixtures/module.pyi]

[case testNoReExportFromStubs]
from stub import Iterable  # E: Module 'stub' has no attribute 'Iterable'
from stub import C

c = C()
reveal_type(c.x)  # E: Revealed type is 'builtins.int'
it: Iterable[int]
reveal_type(it)  # E: Revealed type is 'Any'

[file stub.pyi]
from typing import Iterable
from substub import C as C

def fun(x: Iterable[str]) -> Iterable[int]: pass

[file substub.pyi]
class C:
    x: int

[builtins fixtures/module.pyi]

[case testNoReExportFromStubsMemberType]
import stub

c = stub.C()
reveal_type(c.x)  # E: Revealed type is 'builtins.int'
it: stub.Iterable[int]  # E: Name 'stub.Iterable' is not defined
reveal_type(it)  # E: Revealed type is 'Any'

[file stub.pyi]
from typing import Iterable
from substub import C as C

def fun(x: Iterable[str]) -> Iterable[int]: pass

[file substub.pyi]
class C:
    x: int

[builtins fixtures/module.pyi]

[case testNoReExportFromStubsMemberVar]
import stub

reveal_type(stub.y)  # E: Revealed type is 'builtins.int'
reveal_type(stub.z)  # E: Revealed type is 'Any' \
                     # E: Module has no attribute "z"

[file stub.pyi]
from substub import y as y
from substub import z

[file substub.pyi]
y = 42
z: int

[builtins fixtures/module.pyi]

[case testReExportChildStubs]
import mod
from mod import submod

reveal_type(mod.x)  # E: Revealed type is 'mod.submod.C'
y = submod.C()
reveal_type(y.a)  # E: Revealed type is 'builtins.str'

[file mod/__init__.pyi]
from . import submod
x: submod.C

[file mod/submod.pyi]
class C:
    a: str

[builtins fixtures/module.pyi]

[case testReExportChildStubs2]
import mod.submod

y = mod.submod.C()
reveal_type(y.a)  # E: Revealed type is 'builtins.str'

[file mod/__init__.pyi]
from . import submod
x: submod.C

[file mod/submod.pyi]
class C:
    a: str

[builtins fixtures/module.pyi]

[case testNoReExportChildStubs]
import mod
from mod import C, D  # E: Module 'mod' has no attribute 'C'

reveal_type(mod.x)  # E: Revealed type is 'mod.submod.C'
mod.C  # E: Module has no attribute "C"
y = mod.D()
reveal_type(y.a)  # E: Revealed type is 'builtins.str'

[file mod/__init__.pyi]
from .submod import C, D as D
x: C

[file mod/submod.pyi]
class C: pass
class D:
    a: str
[builtins fixtures/module.pyi]

[case testNoReExportNestedStub]
from stub import substub  # E: Module 'stub' has no attribute 'substub'

[file stub.pyi]
import substub

[file substub.pyi]
x = 42

[file mod/submod.pyi]

[case testModuleAliasToQualifiedImport]
import package.module
alias = package.module
reveal_type(alias.whatever('/'))  # E: Revealed type is 'builtins.str*'
[file package/__init__.py]

[file package/module.py]
from typing import TypeVar
T = TypeVar('T')
def whatever(x: T) -> T: pass
[builtins fixtures/module.pyi]

[case testModuleAliasToQualifiedImport2]
import mod
import othermod
alias = mod.submod
reveal_type(alias.whatever('/'))  # E: Revealed type is 'builtins.str*'
alias = othermod  # E: Cannot assign multiple modules to name 'alias' without explicit 'types.ModuleType' annotation
[file mod.py]
import submod
[file submod.py]
from typing import TypeVar
T = TypeVar('T')
def whatever(x: T) -> T: pass
[file othermod.py]

[builtins fixtures/module.pyi]

[case testModuleLevelGetattr]
import has_getattr

reveal_type(has_getattr.any_attribute)  # E: Revealed type is 'Any'

[file has_getattr.pyi]
from typing import Any

def __getattr__(name: str) -> Any: ...

[builtins fixtures/module.pyi]

[case testModuleLevelGetattrReturnType]
import has_getattr

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

[file has_getattr.pyi]
def __getattr__(name: str) -> str: ...

[builtins fixtures/module.pyi]

[case testModuleLevelGetattrInvalidSignature]
import has_getattr

reveal_type(has_getattr.any_attribute)

[file has_getattr.pyi]
def __getattr__(x: int, y: str) -> str: ...

[out]
tmp/has_getattr.pyi:1: error: Invalid signature "def (builtins.int, builtins.str) -> builtins.str" for "__getattr__"
main:3: error: Revealed type is 'builtins.str'

[builtins fixtures/module.pyi]

[case testModuleLevelGetattrNotCallable]
import has_getattr

reveal_type(has_getattr.any_attribute)

[file has_getattr.pyi]
__getattr__ = 3

[out]
tmp/has_getattr.pyi:1: error: Invalid signature "builtins.int" for "__getattr__"
main:3: error: Revealed type is 'Any'

[builtins fixtures/module.pyi]

[case testModuleLevelGetattrUntyped]
import has_getattr
reveal_type(has_getattr.any_attribute)  # E: Revealed type is 'Any'

[file has_getattr.pyi]
def __getattr__(name): ...

[builtins fixtures/module.pyi]

[case testModuleLevelGetattrNotStub36]
# flags: --python-version 3.6
import has_getattr
reveal_type(has_getattr.any_attribute)  # E: Revealed type is 'Any'  # E: Module has no attribute "any_attribute"

[file has_getattr.py]
def __getattr__(name) -> str: ...

[builtins fixtures/module.pyi]

[case testModuleLevelGetattrNotStub37]
# flags: --python-version 3.7

import has_getattr
reveal_type(has_getattr.any_attribute)  # E: Revealed type is 'builtins.str'

[file has_getattr.py]
def __getattr__(name) -> str: ...

[builtins fixtures/module.pyi]

[case testModuleLevelGetattribute]

def __getattribute__(): ...  # E: __getattribute__ is not valid at the module level

[case testModuleLevelGetattrImportFrom]
from has_attr import name
reveal_type(name)  # E: Revealed type is 'Any'

[file has_attr.pyi]
from typing import Any
def __getattr__(name: str) -> Any: ...

[builtins fixtures/module.pyi]

[case testModuleLevelGetattrImportFromRetType]
from has_attr import int_attr
reveal_type(int_attr)  # E: Revealed type is 'builtins.int'

[file has_attr.pyi]
def __getattr__(name: str) -> int: ...

[builtins fixtures/module.pyi]

[case testModuleLevelGetattrImportFromNotStub36]
# flags: --python-version 3.6
from non_stub import name  # E: Module 'non_stub' has no attribute 'name'
reveal_type(name)  # E: Revealed type is 'Any'

[file non_stub.py]
from typing import Any
def __getattr__(name: str) -> Any: ...

[builtins fixtures/module.pyi]

[case testModuleLevelGetattrImportFromNotStub37]
# flags: --python-version 3.7
from non_stub import name
reveal_type(name)  # E: Revealed type is 'Any'

[file non_stub.py]
from typing import Any
def __getattr__(name: str) -> Any: ...

[builtins fixtures/module.pyi]

[case testModuleLevelGetattrImportFromAs]
from has_attr import name as n
reveal_type(name)
reveal_type(n)

[file has_attr.pyi]
from typing import Any
def __getattr__(name: str) -> Any: ...

[out]
main:2: error: Revealed type is 'Any'
main:2: error: Name 'name' is not defined
main:3: error: Revealed type is 'Any'

[builtins fixtures/module.pyi]

[case testModuleLevelGetattrAssignedGood]
# flags: --python-version 3.7
import non_stub
reveal_type(non_stub.name)  # E: Revealed type is 'builtins.int'

[file non_stub.py]
from typing import Callable

def make_getattr_good() -> Callable[[str], int]: ...
__getattr__ = make_getattr_good()  # OK

[case testModuleLevelGetattrAssignedBad]
# flags: --python-version 3.7
import non_stub
reveal_type(non_stub.name)

[file non_stub.py]
from typing import Callable

def make_getattr_bad() -> Callable[[], int]: ...
__getattr__ = make_getattr_bad()

[out]
tmp/non_stub.py:4: error: Invalid signature "def () -> builtins.int" for "__getattr__"
main:3: error: Revealed type is 'builtins.int'

[case testModuleLevelGetattrImportedGood]
# flags: --python-version 3.7
import non_stub
reveal_type(non_stub.name)  # E: Revealed type is 'builtins.int'

[file non_stub.py]
from has_getattr import __getattr__

[file has_getattr.py]
def __getattr__(name: str) -> int: ...

[case testModuleLevelGetattrImportedBad]
# flags: --python-version 3.7
import non_stub
reveal_type(non_stub.name)

[file non_stub.py]
from has_getattr import __getattr__

[file has_getattr.py]
def __getattr__() -> int: ...

[out]
tmp/has_getattr.py:1: error: Invalid signature "def () -> builtins.int" for "__getattr__"
main:3: error: Revealed type is 'builtins.int'

[builtins fixtures/module.pyi]

[case testFailedImportFromTwoModules]
import c
import b
[file b.py]
import c

[out]
-- TODO: it would be better for this to be in the other order
tmp/b.py:1: error: Cannot find module named 'c'
main:1: error: Cannot find module named 'c'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)

[case testIndirectFromImportWithinCycle1]
import a
[file a.py]
from b import f
from c import x
[file b.py]
from c import y
from a import x
def f() -> None: pass
reveal_type(x) # E: Revealed type is 'builtins.str'
[file c.py]
x = str()
y = int()

[case testIndirectFromImportWithinCycle2]
import a
[file a.py]
from c import y
from b import x
def f() -> None: pass
reveal_type(x) # E: Revealed type is 'builtins.str'
[file b.py]
from a import f
from c import x
[file c.py]
x = str()
y = int()

[case testIndirectFromImportWithinCycleInPackage]
import p.a
[file p/__init__.py]
[file p/a.py]
from p.b import f
from p.c import x
[file p/b.py]
from p.c import y
from p.a import x
def f() -> None: pass
reveal_type(x) # E: Revealed type is 'builtins.str'
[file p/c.py]
x = str()
y = int()

[case testIndirectFromImportWithinCycleInPackageIgnoredInit]
# cmd: mypy -m p.a p.b p.c
# flags: --follow-imports=skip --ignore-missing-imports
[file p/__init__.py]
[file p/a.py]
from p.b import f
from p.c import x
[file p/b.py]
from p.c import y
from p.a import x
def f() -> None: pass
reveal_type(x) # E: Revealed type is 'builtins.str'
[file p/c.py]
x = str()
y = int()

[case testForwardReferenceToListAlias-skip]
# TODO: This fails because of missing ImportedName handling in
#     mypy.typeanal.TypeAnalyser.visit_unbound_type.
x: List[int]
reveal_type(x) # E: Revealed type is 'builtins.list[builtins.int]'
def f() -> 'List[int]': pass
reveal_type(f) # E: Revealed type is 'def () -> builtins.list[builtins.int]'
class A:
    y: 'List[str]'
    def g(self, x: 'List[int]') -> None: pass
reveal_type(A().y) # E: Revealed type is 'builtins.list[builtins.str]'
reveal_type(A().g) # E: Revealed type is 'def (x: builtins.list[builtins.int])'
from typing import List
[builtins fixtures/list.pyi]

[case testIndirectStarImportWithinCycle1]
import a
[file a.py]
from b import f
from c import x
[file b.py]
from c import y
from a import *
def f() -> None: pass
reveal_type(x) # E: Revealed type is 'builtins.str'
[file c.py]
x = str()
y = int()

[case testIndirectStarImportWithinCycle2]
import a
[file a.py]
from c import y
from b import *
def f() -> None: pass
reveal_type(x) # E: Revealed type is 'builtins.str'
[file b.py]
from a import f
from c import x
[file c.py]
x = str()
y = int()

[case testModuleGetattrInit1]
from a import b

x = b.f()
[file a/__init__.pyi]
from typing import Any
def __getattr__(attr: str) -> Any: ...
[builtins fixtures/module.pyi]
[out]

[case testModuleGetattrInit2]
import a.b

x = a.b.f()
[file a/__init__.pyi]
from typing import Any
def __getattr__(attr: str) -> Any: ...
[builtins fixtures/module.pyi]
[out]

[case testModuleGetattrInit3]
import a.b

x = a.b.f()
[file a/__init__.py]
from typing import Any
def __getattr__(attr: str) -> Any: ...
[builtins fixtures/module.pyi]
[out]
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 testModuleGetattrInit4]
import a.b.c

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

[case testModuleGetattrInit5]
from a.b import f

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

[case testModuleGetattrInit5a]
from a.b import f

x = f()
[file a/__init__.pyi]
from types import ModuleType
def __getattr__(attr: str) -> ModuleType: ...
[builtins fixtures/module.pyi]
[out]


[case testModuleGetattrInit5b]
from a.b import f

x = f()
[file a/__init__.pyi]
def __getattr__(attr: str) -> int: ...
[builtins fixtures/module.pyi]
[out]
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 testModuleGetattrInit8]
import a.b.c.d

x = a.b.c.d.f()
[file a/__init__.pyi]
from typing import Any
def __getattr__(attr: str) -> Any: ...
[file a/b/__init__.pyi]
# empty (i.e. complete subpackage)
[builtins fixtures/module.pyi]
[out]
main:1: error: Cannot find module named 'a.b.c'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
main:1: error: Cannot find module named 'a.b.c.d'

[case testModuleGetattrInit8a]
import a.b.c  # Error
import a.d  # OK
[file a/__init__.pyi]
from typing import Any
def __getattr__(attr: str) -> Any: ...
[file a/b/__init__.pyi]
# empty (i.e. complete subpackage)
[builtins fixtures/module.pyi]
[out]
main:1: error: Cannot find module named 'a.b.c'
main:1: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)

[case testModuleGetattrInit10]
# flags: --config-file tmp/mypy.ini
import a.b.c  # silenced
import a.b.d  # error

[file a/__init__.pyi]
from typing import Any
def __getattr__(attr: str) -> Any: ...
[file a/b/__init__.pyi]
# empty (i.e. complete subpackage)

[file mypy.ini]
[[mypy]
[[mypy-a.b.c]
ignore_missing_imports = True
[builtins fixtures/module.pyi]
[out]
main:3: error: Cannot find module named 'a.b.d'
main:3: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)

[case testIndirectFromImportWithinCycleUsedAsBaseClass-skip]
-- TODO: Fails because of missing ImportedName handling in mypy.typeanal
import a
[file a.py]
from b import f
from c import B
[file b.py]
from c import y
class A(B): pass
reveal_type(A().x) # E: Revealed type is 'builtins.str'
from a import B
def f() -> None: pass
[file c.py]
class B:
    x: int
x = str()
y = int()

[case testImportFromReExportInCycleUsingRelativeImport1]
from m import One
reveal_type(One)
[file m/__init__.py]
from .one import One
from .two import Two
reveal_type(One)
[file m/one.py]
class One:
    pass
[file m/two.py]
from m import One
reveal_type(One)
x: One
reveal_type(x)

class Two(One):
    pass
y: Two
y = x
x = y
[out]
tmp/m/two.py:2: error: Revealed type is 'def () -> m.one.One'
tmp/m/two.py:4: error: Revealed type is 'm.one.One'
tmp/m/two.py:9: error: Incompatible types in assignment (expression has type "One", variable has type "Two")
tmp/m/__init__.py:3: error: Revealed type is 'def () -> m.one.One'
main:2: error: Revealed type is 'def () -> m.one.One'

[case testImportReExportInCycleUsingRelativeImport2]
from m import One
reveal_type(One)
[file m/__init__.py]
from .one import One
from .two import Two
reveal_type(One)
[file m/one.py]
class One:
    pass
[file m/two.py]
import m
reveal_type(m.One)
x: m.One
reveal_type(x)
class Two:
    pass
[out]
tmp/m/two.py:2: error: Revealed type is 'def () -> m.one.One'
tmp/m/two.py:4: error: Revealed type is 'm.one.One'
tmp/m/__init__.py:3: error: Revealed type is 'def () -> m.one.One'
main:2: error: Revealed type is 'def () -> m.one.One'

[case testImportReExportedNamedTupleInCycle1]
from m import One
[file m/__init__.py]
from .one import One
from .two import Two
[file m/one.py]
from typing import NamedTuple
class One(NamedTuple):
    name: str
[file m/two.py]
import m
x = m.One(name="Foo")
reveal_type(x.name)
class Two:
    pass
[out]
tmp/m/two.py:3: error: Revealed type is 'builtins.str'

[case testImportReExportedNamedTupleInCycle2]
from m import One
[file m/__init__.py]
from .one import One
from .two import Two
[file m/one.py]
from typing import NamedTuple
One = NamedTuple('One', [('name', str)])
[file m/two.py]
import m
x = m.One(name="Foo")
reveal_type(x.name)
class Two:
    pass
[out]
tmp/m/two.py:3: error: Revealed type is 'builtins.str'

[case testImportReExportedTypeAliasInCycle]
from m import One
[file m/__init__.py]
from .one import One
from .two import Two
[file m/one.py]
from typing import Union
One = Union[int, str]
[file m/two.py]
import m
x: m.One
reveal_type(x)
class Two:
    pass
[out]
tmp/m/two.py:3: error: Revealed type is 'Union[builtins.int, builtins.str]'

[case testImportCycleSpecialCase]
import p
[file p/__init__.py]
from . import a
from . import b
reveal_type(a.foo())
[file p/a.py]
import p
def foo() -> int: pass
[file p/b.py]
import p

def run() -> None:
    reveal_type(p.a.foo())
[builtins fixtures/module.pyi]
[out]
tmp/p/b.py:4: error: Revealed type is 'builtins.int'
tmp/p/__init__.py:3: error: Revealed type is 'builtins.int'

[case testMissingSubmoduleImportedWithIgnoreMissingImports]
# flags: --ignore-missing-imports
import whatever.works
import a.b
x = whatever.works.f()
y = a.b.f()
[file a/__init__.py]
# empty
[out]

[case testMissingSubmoduleImportedWithIgnoreMissingImportsStub]
# flags: --ignore-missing-imports --follow-imports=skip
import whatever.works
import a.b
x = whatever.works.f()
y = a.b.f()
[file a/__init__.pyi]
# empty
[out]

[case testMissingSubmoduleImportedWithIgnoreMissingImportsNested]
# flags: --ignore-missing-imports
import a.b.c.d
y = a.b.c.d.f()
[file a/__init__.py]
# empty
[file a/b/__init__.py]
# empty
[out]

[case testModuleGetattrBusted]
from a import A
x: A
reveal_type(x)  # E: Revealed type is 'Any'
[file a.pyi]
from typing import Any
def __getattr__(attr: str) -> Any: ...
[builtins fixtures/module.pyi]
[out]

[case testModuleGetattrBusted2]
from a import A
def f(x: A.B) -> None: ...
reveal_type(f)  # E: Revealed type is 'def (x: Any)'
[file a.pyi]
from typing import Any
def __getattr__(attr: str) -> Any: ...
[builtins fixtures/module.pyi]
[out]

[case testNoGetattrInterference]
import testmod as t
def f(x: t.Cls) -> None:
    reveal_type(x)  # E: Revealed type is 'testmod.Cls'
[file testmod.pyi]
from typing import Any
def __getattr__(attr: str) -> Any: ...
class Cls: ...
[builtins fixtures/module.pyi]
[out]

[case testFunctionWithDunderName]
def __add__(self) -> int: ...

[case testFunctionWithReversibleDunderName]
def __radd__(self) -> int: ...

[case testFunctionWithInPlaceDunderName]
def __iadd__(self) -> int: ...
