From 228837190169769b2bb15d183305ae712434dc11 Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Thu, 10 Oct 2019 14:53:08 +0100 Subject: [PATCH] Always show the cause of error in dmypy suggest (#7680) This PR prints the type errors that prevented `dmypy suggest` from running. Since this will be mostly used by interactive tools, I don't pipe the errors though normal formatting and colors, but if you think it makes sense, then I can do this. --- mypy/suggestions.py | 5 ++--- test-data/unit/daemon.test | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/mypy/suggestions.py b/mypy/suggestions.py index 8edb3d42d6e7..48df65afd02c 100644 --- a/mypy/suggestions.py +++ b/mypy/suggestions.py @@ -536,10 +536,9 @@ def reload(self, state: State, check_errors: bool = False) -> List[str]: """ assert state.path is not None res = self.fgmanager.update([(state.id, state.path)], []) - # if res: - # print('\n'.join(res)) if check_errors and res: - raise SuggestionFailure("Error while trying to load %s" % state.id) + # TODO: apply color and formatting to error messages? + raise SuggestionFailure("Error while processing %s:\n" % state.id + '\n'.join(res)) return res def ensure_loaded(self, state: State, force: bool = False) -> MypyFile: diff --git a/test-data/unit/daemon.test b/test-data/unit/daemon.test index 782bb0b81ba4..3777a1b4966c 100644 --- a/test-data/unit/daemon.test +++ b/test-data/unit/daemon.test @@ -255,3 +255,28 @@ from foo import foo def bar() -> None: x = foo('abc') # type: str foo(arg='xyz') + +[case testDaemonSuggestErrorsShown] +$ dmypy start --log-file log.txt -- --follow-imports=error --no-error-summary +Daemon started +$ dmypy check foo.py +$ dmypy suggest tmp/foo.py:1 +() -> int +$ {python} -c "import shutil; shutil.copy('foo.py.2', 'foo.py')" +$ dmypy suggest tmp/foo.py:4 +Error while processing foo: +foo.py:3: error: Unsupported operand types for + ("int" and "str") +== Return code: 2 +[file foo.py] +def foo(): + return 0 +foo() + 'no' +def bar(): + return None +[file foo.py.2] +def foo() -> int: + return 0 +foo() + 'no' +def bar(): + return None +[out]