Repository: python/mypy

Issue:
Mypy crashes with `from .. import *` import
In my example at #4110 , if I change the import in `backends/Bla.py` to `from .. import *` and remove references to `blamodule.`, like so: 

I have the following directory structure:
```
blamodule
|-- __init__.py
|-- backends
|   |-- Bla.py
|   `-- __init__.py
`-- call_command.py
```

With the following contents: 
* `blamodule/__init__.py`
```
from . import call_command
from . import backends
```
* `blamodule/backends/__init__.py`
```
from .Bla import Bla
```
* `blamodule/backends/Bla.py`
```
from .. import *
from typing import Iterable

class Bla:
    def __init__(self, path: str) -> None:
        self.path = path

    def method(self, options: Iterable[str]) -> str:
        return call_command.call(["BLA"])
```
* `blamodule/call_command.py`
```
import io

def call() -> str:

    output_buffer = io.StringIO()

    return output_buffer.getvalue()
```

I crash mypy with the following backtrace: 
```
Traceback (most recent call last):
  File "/path/py3env/bin/mypy", line 11, in <module>
    sys.exit(console_entry())
  File "/path/py3env/lib/python3.5/site-packages/mypy/__main__.py", line 7, in console_entry
    main(None)
  File "/path/py3env/lib/python3.5/site-packages/mypy/main.py", line 50, in main
    res = type_check_only(sources, bin_dir, options)
  File "/path/py3env/lib/python3.5/site-packages/mypy/main.py", line 103, in type_check_only
    options=options)
  File "/path/py3env/lib/python3.5/site-packages/mypy/build.py", line 198, in build
    graph = dispatch(sources, manager)
  File "/path/py3env/lib/python3.5/site-packages/mypy/build.py", line 1833, in dispatch
    graph = load_graph(sources, manager)
  File "/path/py3env/lib/python3.5/site-packages/mypy/build.py", line 1946, in load_graph
    caller_state=st, caller_line=st.dep_line_map.get(dep, 1))
  File "/path/py3env/lib/python3.5/site-packages/mypy/build.py", line 1466, in __init__
    self.parse_file()
  File "/path/py3env/lib/python3.5/site-packages/mypy/build.py", line 1663, in parse_file
    self.ignore_all or self.options.ignore_errors)
  File "/usr/lib/python3.5/contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "/path/py3env/lib/python3.5/site-packages/mypy/build.py", line 1554, in wrap_context
    yield
  File "/path/py3env/lib/python3.5/site-packages/mypy/build.py", line 1663, in parse_file
    self.ignore_all or self.options.ignore_errors)
  File "/path/py3env/lib/python3.5/site-packages/mypy/build.py", line 589, in parse_file
    tree = parse(source, path, self.errors, options=self.options)
  File "/path/py3env/lib/python3.5/site-packages/mypy/parse.py", line 25, in parse
    options=options)
  File "/path/py3env/lib/python3.5/site-packages/mypy/fastparse.py", line 96, in parse
    ).visit(ast)
  File "/path/py3env/lib/python3.5/site-packages/mypy/fastparse.py", line 169, in visit
    return super().visit(node)
  File "/path/py3env/lib/python3.5/site-packages/typed_ast/ast3.py", line 275, in visit
    return visitor(node)
  File "/path/py3env/lib/python3.5/site-packages/mypy/fastparse.py", line 289, in visit_Module
    body = self.fix_function_overloads(self.translate_stmt_list(mod.body))
  File "/path/py3env/lib/python3.5/site-packages/mypy/fastparse.py", line 182, in translate_stmt_list
    stmt = self.visit(e)
  File "/path/py3env/lib/python3.5/site-packages/mypy/fastparse.py", line 169, in visit
    return super().visit(node)
  File "/path/py3env/lib/python3.5/site-packages/typed_ast/ast3.py", line 275, in visit
    return visitor(node)
  File "/path/py3env/lib/python3.5/site-packages/mypy/fastparse.py", line 126, in wrapper
    node = f(self, ast)
  File "/path/py3env/lib/python3.5/site-packages/mypy/fastparse.py", line 654, in visit_ImportFrom
    assert n.module is not None
AssertionError: 

```


Discussion:
Yes, this is actually a regression introduced by me. Fortunately, this one is easy to fix (just replace ``None`` with ``''``).

Resolving patch:
diff --git a/mypy/fastparse.py b/mypy/fastparse.py
--- a/mypy/fastparse.py
+++ b/mypy/fastparse.py
@@ -651,8 +651,8 @@ def visit_Import(self, n: ast3.Import) -> Import:
     def visit_ImportFrom(self, n: ast3.ImportFrom) -> ImportBase:
         assert n.level is not None
         if len(n.names) == 1 and n.names[0].name == '*':
-            assert n.module is not None
-            i = ImportAll(n.module, n.level)  # type: ImportBase
+            mod = n.module if n.module is not None else ''
+            i = ImportAll(mod, n.level)  # type: ImportBase
         else:
             i = ImportFrom(self.translate_module_id(n.module) if n.module is not None else '',
                            n.level,
diff --git a/mypy/fastparse2.py b/mypy/fastparse2.py
--- a/mypy/fastparse2.py
+++ b/mypy/fastparse2.py
@@ -647,8 +647,8 @@ def visit_Import(self, n: ast27.Import) -> Import:
     def visit_ImportFrom(self, n: ast27.ImportFrom) -> ImportBase:
         assert n.level is not None
         if len(n.names) == 1 and n.names[0].name == '*':
-            assert n.module is not None
-            i = ImportAll(n.module, n.level)  # type: ImportBase
+            mod = n.module if n.module is not None else ''
+            i = ImportAll(mod, n.level)  # type: ImportBase
         else:
             i = ImportFrom(self.translate_module_id(n.module) if n.module is not None else '',
                            n.level,


Test patch:
diff --git a/test-data/unit/check-fastparse.test b/test-data/unit/check-fastparse.test
--- a/test-data/unit/check-fastparse.test
+++ b/test-data/unit/check-fastparse.test
@@ -364,3 +364,32 @@ def m(x, ((x, y), z)):  # E: Duplicate argument 'x' in function definition
   pass
 
 lambda x, (y, x): None  # E: Duplicate argument 'x' in function definition
+
+[case testNoCrashOnImportFromStar]
+from pack import *
+[file pack/__init__.py]
+from . import *
+
+[case testNoCrashOnImportFromStarNested]
+import blamodule
+[file blamodule/__init__.py]
+from . import command
+from . import backends
+
+[file blamodule/backends/__init__.py]
+from .Bla import Bla
+reveal_type(Bla().method())  # E: Revealed type is 'builtins.str'
+
+[file blamodule/backends/Bla.py]
+from .. import *
+
+class Bla:
+    def method(self) -> str:
+        return command.call()
+
+[file blamodule/command.py]
+def call() -> str: pass
+
+[case testNoCrashOnImportFromStarPython2]
+# flags: --py2
+from . import * # E: No parent module -- cannot perform relative import