From e9fc69d84f65d89a57f19d8eca8979c5d3de7f68 Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Fri, 17 Nov 2017 01:53:08 +0100 Subject: [PATCH] Fix crash in relative imports (#4259) Fixes #4111 This corrects a previous wrong --strict-optional change (and adds various tests). --- mypy/fastparse.py | 4 ++-- mypy/fastparse2.py | 4 ++-- test-data/unit/check-fastparse.test | 29 +++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/mypy/fastparse.py b/mypy/fastparse.py index cb1eeba02c20..d9fc59ae98ac 100644 --- 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 index 3156f9eac728..3f4a21fbbf77 100644 --- 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, diff --git a/test-data/unit/check-fastparse.test b/test-data/unit/check-fastparse.test index 7aa1521e320b..cb4b6306271a 100644 --- 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