From 7cbfcea886fb7c97eb81df45c88a4eb2784b7f33 Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Thu, 15 Jun 2023 00:36:34 +0100 Subject: [PATCH 1/2] Fix re-added file with errors in mypy daemon --- mypy/dmypy_server.py | 14 ++++++++++++++ test-data/unit/daemon.test | 22 ++++++++++++++++++++++ test-data/unit/fine-grained.test | 21 +++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/mypy/dmypy_server.py b/mypy/dmypy_server.py index 631aab4ccbc82..0cd8cfa57890f 100644 --- a/mypy/dmypy_server.py +++ b/mypy/dmypy_server.py @@ -857,6 +857,20 @@ def _find_changed( assert path removed.append((source.module, path)) + # Always add modules that were (re-)added, since they may be detected as not changed by + # fswatcher (if they were actually not changed), but they may still need to be checked + # in case they had errors before they were deleted from sources on previous runs. + previous_modules = {source.module for source in self.previous_sources} + changed_set = set(changed) + changed.extend( + [ + (source.module, source.path) + for source in sources + if source.module not in previous_modules + and (source.module, source.path) not in changed_set + ] + ) + # Find anything that has had its module path change because of added or removed __init__s last = {s.path: s.module for s in self.previous_sources} for s in sources: diff --git a/test-data/unit/daemon.test b/test-data/unit/daemon.test index 424fc6d2b167b..1fae1514111c4 100644 --- a/test-data/unit/daemon.test +++ b/test-data/unit/daemon.test @@ -62,6 +62,28 @@ Daemon started \[mypy] files = ./foo.py +[case testDaemonRunMultipleStrict] +$ dmypy run -- foo.py --strict --follow-imports=error +Daemon started +foo.py:1: error: Function is missing a return type annotation +foo.py:1: note: Use "-> None" if function does not return a value +Found 1 error in 1 file (checked 1 source file) +== Return code: 1 +$ dmypy run -- bar.py --strict --follow-imports=error +bar.py:1: error: Function is missing a return type annotation +bar.py:1: note: Use "-> None" if function does not return a value +Found 1 error in 1 file (checked 1 source file) +== Return code: 1 +$ dmypy run -- foo.py --strict --follow-imports=error +foo.py:1: error: Function is missing a return type annotation +foo.py:1: note: Use "-> None" if function does not return a value +Found 1 error in 1 file (checked 1 source file) +== Return code: 1 +[file foo.py] +def f(): pass +[file bar.py] +def f(): pass + [case testDaemonRunRestart] $ dmypy run -- foo.py --follow-imports=error Daemon started diff --git a/test-data/unit/fine-grained.test b/test-data/unit/fine-grained.test index 88a11be31f340..a0d7d302fd08b 100644 --- a/test-data/unit/fine-grained.test +++ b/test-data/unit/fine-grained.test @@ -10340,3 +10340,24 @@ reveal_type(x) [out] == a.py:3: note: Revealed type is "Union[def (x: builtins.int) -> builtins.int, def (*x: builtins.int) -> builtins.int]" + +[case testErrorInReAddedModule] +# flags: --disallow-untyped-defs --follow-imports=error +# cmd: mypy a.py +# cmd2: mypy b.py +# cmd3: mypy a.py + +[file a.py] +def f(): pass +[file b.py] +def f(): pass +[file unrelated.txt.3] +[out] +a.py:1: error: Function is missing a return type annotation +a.py:1: note: Use "-> None" if function does not return a value +== +b.py:1: error: Function is missing a return type annotation +b.py:1: note: Use "-> None" if function does not return a value +== +a.py:1: error: Function is missing a return type annotation +a.py:1: note: Use "-> None" if function does not return a value From f8c5dd7e2abf859bf069de58ad96352b50b23f5b Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Thu, 15 Jun 2023 00:56:02 +0100 Subject: [PATCH 2/2] Fix self-check --- mypy/dmypy_server.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mypy/dmypy_server.py b/mypy/dmypy_server.py index 0cd8cfa57890f..54544f4c01ce4 100644 --- a/mypy/dmypy_server.py +++ b/mypy/dmypy_server.py @@ -866,7 +866,8 @@ def _find_changed( [ (source.module, source.path) for source in sources - if source.module not in previous_modules + if source.path + and source.module not in previous_modules and (source.module, source.path) not in changed_set ] )