Skip to content

Commit ceb4d7f

Browse files
authored
Fix re-added file with errors in mypy daemon (#15440)
Fixes #5343 Fixes #12249 This can potentially slow down runs in situations where multiple unchanged files are re-added to source list. Potentially, we can track whether modules had errors permanently (not just from previous run), and then only re-check those unchanged re-added files that had errors before. I am not sure if this is important.
1 parent bf92309 commit ceb4d7f

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

mypy/dmypy_server.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,21 @@ def _find_changed(
857857
assert path
858858
removed.append((source.module, path))
859859

860+
# Always add modules that were (re-)added, since they may be detected as not changed by
861+
# fswatcher (if they were actually not changed), but they may still need to be checked
862+
# in case they had errors before they were deleted from sources on previous runs.
863+
previous_modules = {source.module for source in self.previous_sources}
864+
changed_set = set(changed)
865+
changed.extend(
866+
[
867+
(source.module, source.path)
868+
for source in sources
869+
if source.path
870+
and source.module not in previous_modules
871+
and (source.module, source.path) not in changed_set
872+
]
873+
)
874+
860875
# Find anything that has had its module path change because of added or removed __init__s
861876
last = {s.path: s.module for s in self.previous_sources}
862877
for s in sources:

test-data/unit/daemon.test

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,28 @@ Daemon started
6262
\[mypy]
6363
files = ./foo.py
6464

65+
[case testDaemonRunMultipleStrict]
66+
$ dmypy run -- foo.py --strict --follow-imports=error
67+
Daemon started
68+
foo.py:1: error: Function is missing a return type annotation
69+
foo.py:1: note: Use "-> None" if function does not return a value
70+
Found 1 error in 1 file (checked 1 source file)
71+
== Return code: 1
72+
$ dmypy run -- bar.py --strict --follow-imports=error
73+
bar.py:1: error: Function is missing a return type annotation
74+
bar.py:1: note: Use "-> None" if function does not return a value
75+
Found 1 error in 1 file (checked 1 source file)
76+
== Return code: 1
77+
$ dmypy run -- foo.py --strict --follow-imports=error
78+
foo.py:1: error: Function is missing a return type annotation
79+
foo.py:1: note: Use "-> None" if function does not return a value
80+
Found 1 error in 1 file (checked 1 source file)
81+
== Return code: 1
82+
[file foo.py]
83+
def f(): pass
84+
[file bar.py]
85+
def f(): pass
86+
6587
[case testDaemonRunRestart]
6688
$ dmypy run -- foo.py --follow-imports=error
6789
Daemon started

test-data/unit/fine-grained.test

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10340,3 +10340,24 @@ reveal_type(x)
1034010340
[out]
1034110341
==
1034210342
a.py:3: note: Revealed type is "Union[def (x: builtins.int) -> builtins.int, def (*x: builtins.int) -> builtins.int]"
10343+
10344+
[case testErrorInReAddedModule]
10345+
# flags: --disallow-untyped-defs --follow-imports=error
10346+
# cmd: mypy a.py
10347+
# cmd2: mypy b.py
10348+
# cmd3: mypy a.py
10349+
10350+
[file a.py]
10351+
def f(): pass
10352+
[file b.py]
10353+
def f(): pass
10354+
[file unrelated.txt.3]
10355+
[out]
10356+
a.py:1: error: Function is missing a return type annotation
10357+
a.py:1: note: Use "-> None" if function does not return a value
10358+
==
10359+
b.py:1: error: Function is missing a return type annotation
10360+
b.py:1: note: Use "-> None" if function does not return a value
10361+
==
10362+
a.py:1: error: Function is missing a return type annotation
10363+
a.py:1: note: Use "-> None" if function does not return a value

0 commit comments

Comments
 (0)