Skip to content

Commit c741333

Browse files
author
Guido van Rossum
committed
Ensure that cache files for modules without errors are written
1 parent af1fd2f commit c741333

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

mypy/build.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1516,7 +1516,14 @@ def valid_references(self) -> Set[str]:
15161516
return valid_refs
15171517

15181518
def write_cache(self) -> None:
1519-
if self.path and self.options.incremental and not self.manager.errors.is_errors():
1519+
ok = self.path and self.options.incremental
1520+
if ok:
1521+
if self.manager.options.quick_and_dirty:
1522+
is_errors = self.manager.errors.is_errors_for_file(self.path)
1523+
else:
1524+
is_errors = self.manager.errors.is_errors()
1525+
ok = not is_errors
1526+
if ok:
15201527
dep_prios = [self.priorities.get(dep, PRI_HIGH) for dep in self.dependencies]
15211528
new_interface_hash = write_cache(
15221529
self.id, self.path, self.tree,

mypy/errors.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ class Errors:
7676
# Current error context: nested import context/stack, as a list of (path, line) pairs.
7777
import_ctx = None # type: List[Tuple[str, int]]
7878

79+
# Set of files with errors.
80+
error_files = None # type: Set[str]
81+
7982
# Path name prefix that is removed from all paths, if set.
8083
ignore_prefix = None # type: str
8184

@@ -110,6 +113,7 @@ def __init__(self, show_error_context: bool = False,
110113
show_column_numbers: bool = False) -> None:
111114
self.error_info = []
112115
self.import_ctx = []
116+
self.error_files = set()
113117
self.type_name = [None]
114118
self.function_or_member = [None]
115119
self.ignored_lines = OrderedDict()
@@ -230,6 +234,7 @@ def add_error_info(self, info: ErrorInfo) -> None:
230234
return
231235
self.only_once_messages.add(info.message)
232236
self.error_info.append(info)
237+
self.error_files.add(file)
233238

234239
def generate_unused_ignore_notes(self) -> None:
235240
for file, ignored_lines in self.ignored_lines.items():
@@ -257,6 +262,10 @@ def is_blockers(self) -> bool:
257262
"""Are the any errors that are blockers?"""
258263
return any(err for err in self.error_info if err.blocker)
259264

265+
def is_errors_for_file(self, file: str) -> bool:
266+
"""Are there any errors for the given file?"""
267+
return file in self.error_files
268+
260269
def raise_error(self) -> None:
261270
"""Raise a CompileError with the generated messages.
262271

test-data/unit/check-incremental.test

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
-- errors expected in the second run should be in the `[out2]` section. If a
77
-- section is omitted, it is expected there are no errors on that run.
88
--
9+
-- As always, extra flags may be specified using
10+
-- # flags: --some-flag
11+
-- If the second run requires different flags, those can be specified using
12+
-- # flags2: --another-flag
13+
--
914
-- Any files that we expect to be rechecked should be annotated in the [rechecked]
1015
-- annotation, and any files expect to be stale (aka have a modified interface)
1116
-- should be annotated in the [stale] annotation. Note that a file that ends up
@@ -1903,3 +1908,19 @@ import b
19031908
import a
19041909
[rechecked a, b, builtins]
19051910
[stale a, b, builtins]
1911+
1912+
[case testQuickAndDirty4]
1913+
# flags: --quick-and-dirty
1914+
import a, b
1915+
[file a.py]
1916+
import b
1917+
def foo() -> int: return ''
1918+
[file b.py]
1919+
import a
1920+
[file a.py.next]
1921+
def foo() -> int: return 0
1922+
[out1]
1923+
tmp/a.py:2: error: Incompatible return value type (got "str", expected "int")
1924+
[out2]
1925+
[rechecked a]
1926+
[stale a]

0 commit comments

Comments
 (0)