Repository: python/mypy

Issue:
Bug: traceback error from importing type with import *?
Ran into a bug that prompted me to report a traceback here. I fiddled with the code and narrowed down the issue to this example.

 In test.py:

``` python
from foo import *
from typing import Any

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

And in foo.py:

``` python
from typing import Callable, Any

AnyCallable = Callable[..., Any]
```

This hits an error in mypy. If I switch "from foo import *" to "from foo import AnyCallable", everything works great.

And the traceback:

src/test.py:1: error: INTERNAL ERROR -- please report a bug at https://github.com/python/mypy/issues
Traceback (most recent call last):
  File "/opt/venv/bin/mypy", line 6, in <module>
    main(**file**)
  File "/opt/venv/lib/python3.4/site-packages/mypy/main.py", line 40, in main
    res = type_check_only(sources, bin_dir, options)
  File "/opt/venv/lib/python3.4/site-packages/mypy/main.py", line 81, in type_check_only
    options=options)
  File "/opt/venv/lib/python3.4/site-packages/mypy/build.py", line 184, in build
    dispatch(sources, manager)
  File "/opt/venv/lib/python3.4/site-packages/mypy/build.py", line 1456, in dispatch
    process_graph(graph, manager)
  File "/opt/venv/lib/python3.4/site-packages/mypy/build.py", line 1612, in process_graph
    process_stale_scc(graph, scc)
  File "/opt/venv/lib/python3.4/site-packages/mypy/build.py", line 1705, in process_stale_scc
    graph[id].semantic_analysis_pass_three()
  File "/opt/venv/lib/python3.4/site-packages/mypy/build.py", line 1421, in semantic_analysis_pass_three
    self.manager.semantic_analyzer_pass3.visit_file(self.tree, self.xpath)
  File "/opt/venv/lib/python3.4/site-packages/mypy/semanal.py", line 2673, in visit_file
    self.accept(file_node)
  File "/opt/venv/lib/python3.4/site-packages/mypy/semanal.py", line 2677, in accept
    node.accept(self)
  File "/opt/venv/lib/python3.4/site-packages/mypy/nodes.py", line 200, in accept
    return visitor.visit_mypy_file(self)
  File "/opt/venv/lib/python3.4/site-packages/mypy/traverser.py", line 29, in visit_mypy_file
    d.accept(self)
  File "/opt/venv/lib/python3.4/site-packages/mypy/nodes.py", line 477, in accept
    return visitor.visit_func_def(self)
  File "/opt/venv/lib/python3.4/site-packages/mypy/semanal.py", line 2688, in visit_func_def
    self.analyze(fdef.type)
  File "/opt/venv/lib/python3.4/site-packages/mypy/semanal.py", line 2774, in analyze
    type.accept(analyzer)
  File "/opt/venv/lib/python3.4/site-packages/mypy/types.py", line 620, in accept
    return visitor.visit_callable_type(self)
  File "/opt/venv/lib/python3.4/site-packages/mypy/typeanal.py", line 378, in visit_callable_type
    arg_type.accept(self)
AttributeError: 'NoneType' object has no attribute 'accept'
src/test.py:1: note: use --pdb to drop into pdb



Discussion:
Which version of mypy are you using here? Is there any chance that it's
already been fixed in the current repo?

This feels familiar -- importing a type alias using `import *` was also
implicated in #2156 although the traceback there was different. (I fixed
that two days ago.)

Looks like I'm on 0.4.4. I installed with pip.

I don't personally care about the error on my end, so you're free to ignore it. I just thought it might be helpful for you guys.

And thanks for reporting it! But it would be even more useful if you could
confirm whether it's still present in the latest version from the repo. If
you don't have time for that, no worries, we'll eventually get to it (and
thanks for the simple repro!).

Here what I get on the latest version:

test.py:1: error: INTERNAL ERROR -- please report a bug at https://github.com/python/mypy/issues
Traceback (most recent call last):
  File "/usr/bin/mypy", line 6, in <module>
    main(**file**)
  File "/usr/lib/python3.5/site-packages/mypy/main.py", line 42, in main
    res = type_check_only(sources, bin_dir, options)
  File "/usr/lib/python3.5/site-packages/mypy/main.py", line 83, in type_check_only
    options=options)
  File "/usr/lib/python3.5/site-packages/mypy/build.py", line 185, in build
    dispatch(sources, manager)
  File "/usr/lib/python3.5/site-packages/mypy/build.py", line 1473, in dispatch
    process_graph(graph, manager)
  File "/usr/lib/python3.5/site-packages/mypy/build.py", line 1650, in process_graph
    process_stale_scc(graph, scc)
  File "/usr/lib/python3.5/site-packages/mypy/build.py", line 1723, in process_stale_scc
    graph[id].semantic_analysis_pass_three()
  File "/usr/lib/python3.5/site-packages/mypy/build.py", line 1409, in semantic_analysis_pass_three
    self.manager.semantic_analyzer_pass3.visit_file(self.tree, self.xpath)
  File "/usr/lib/python3.5/site-packages/mypy/semanal.py", line 2772, in visit_file
    self.accept(file_node)
  File "/usr/lib/python3.5/site-packages/mypy/semanal.py", line 2776, in accept
    node.accept(self)
  File "/usr/lib/python3.5/site-packages/mypy/nodes.py", line 200, in accept
    return visitor.visit_mypy_file(self)
  File "/usr/lib/python3.5/site-packages/mypy/traverser.py", line 29, in visit_mypy_file
    d.accept(self)
  File "/usr/lib/python3.5/site-packages/mypy/nodes.py", line 492, in accept
    return visitor.visit_func_def(self)
  File "/usr/lib/python3.5/site-packages/mypy/semanal.py", line 2787, in visit_func_def
    self.analyze(fdef.type)
  File "/usr/lib/python3.5/site-packages/mypy/semanal.py", line 2873, in analyze
    type.accept(analyzer)
  File "/usr/lib/python3.5/site-packages/mypy/types.py", line 620, in accept
    return visitor.visit_callable_type(self)
  File "/usr/lib/python3.5/site-packages/mypy/typeanal.py", line 378, in visit_callable_type
    arg_type.accept(self)
AttributeError: 'NoneType' object has no attribute 'accept'
test.py:1: note: use --pdb to drop into pdb

Thanks! We'll be on it soon.

Reduced:

``` Python
[case testImportStarTyperef]
import bar

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

[file foo.py]
from typing import Any
Any1 = Any
```

There's a todo for this apparently: [typeanal.py#L140-L142](https://github.com/python/mypy/blob/master/mypy/typeanal.py#L144-L145) returns None when it shouldn't.

``` Python
        elif sym.kind == TYPE_ALIAS:
            # TODO: Generic type aliases.
-           return sym.type_override
+           return sym.type_override or AnyType()
```

Avoids the crash without actually fixing the problem.

I suppose avoiding the crash is nice -- but what would it take to actually fix the bug?


Resolving patch:
diff --git a/mypy/semanal.py b/mypy/semanal.py
--- a/mypy/semanal.py
+++ b/mypy/semanal.py
@@ -1090,7 +1090,8 @@ def visit_import_all(self, i: ImportAll) -> None:
                                 name, existing_symbol, node, i):
                             continue
                     self.add_symbol(name, SymbolTableNode(node.kind, node.node,
-                                                          self.cur_mod_id), i)
+                                                          self.cur_mod_id,
+                                                          node.type_override), i)
         else:
             # Don't add any dummy symbols for 'from x import *' if 'x' is unknown.
             pass


Test patch:
diff --git a/test-data/unit/check-modules.test b/test-data/unit/check-modules.test
--- a/test-data/unit/check-modules.test
+++ b/test-data/unit/check-modules.test
@@ -1345,3 +1345,79 @@ 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]
+main:1: note: In module imported here:
+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: List item 0 has incompatible type "Tuple[str, str]"
+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*]'
+
+[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]