Skip to content

Commit e282180

Browse files
committed
Add more test facilities, fix a bug revealed by them
1 parent 3a27fa2 commit e282180

File tree

7 files changed

+152
-50
lines changed

7 files changed

+152
-50
lines changed

mypy/dmypy_server.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -273,9 +273,6 @@ def initialize_fine_grained(self, sources: List[mypy.build.BuildSource]) -> Dict
273273
self.fscache = FileSystemCache(self.options.python_version)
274274
self.fswatcher = FileSystemWatcher(self.fscache)
275275
self.update_sources(sources)
276-
if not self.options.use_fine_grained_cache:
277-
# Stores the initial state of sources as a side effect.
278-
self.fswatcher.find_changed()
279276
try:
280277
result = mypy.build.build(sources=sources,
281278
options=self.options,
@@ -292,7 +289,6 @@ def initialize_fine_grained(self, sources: List[mypy.build.BuildSource]) -> Dict
292289
graph = result.graph
293290
self.fine_grained_manager = FineGrainedBuildManager(manager, graph)
294291
self.previous_sources = sources
295-
self.fscache.flush()
296292

297293
# If we are using the fine-grained cache, build hasn't actually done
298294
# the typechecking on the updated files yet.
@@ -310,14 +306,20 @@ def initialize_fine_grained(self, sources: List[mypy.build.BuildSource]) -> Dict
310306

311307
# Run an update
312308
changed = self.find_changed(sources)
309+
310+
# Find anything that has had its dependency list change
313311
for state in self.fine_grained_manager.graph.values():
314312
if not state.is_fresh():
315313
assert state.path is not None
316314
changed.append((state.id, state.path))
317315

318316
if changed:
319317
messages = self.fine_grained_manager.update(changed)
320-
self.fscache.flush()
318+
else:
319+
# Stores the initial state of sources as a side effect.
320+
self.fswatcher.find_changed()
321+
322+
self.fscache.flush()
321323

322324
status = 1 if messages else 0
323325
self.previous_messages = messages[:]

mypy/server/update.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,14 @@ def __init__(self,
174174
# for the cache.
175175
self.manager.cache_enabled = False
176176
manager.saved_cache = {}
177+
178+
# Some hints to the test suite about what is going on:
177179
# Active triggers during the last update
178180
self.triggered = [] # type: List[str]
181+
# Modules passed to update during the last update
182+
self.changed_modules = [] # type: List[Tuple[str, str]]
183+
# Modules processed during the last update
184+
self.updated_modules = [] # type: List[str]
179185

180186
def update(self, changed_modules: List[Tuple[str, str]]) -> List[str]:
181187
"""Update previous build result by processing changed modules.
@@ -196,10 +202,13 @@ def update(self, changed_modules: List[Tuple[str, str]]) -> List[str]:
196202
"""
197203
assert changed_modules, 'No changed modules'
198204

205+
self.changed_modules = changed_modules
206+
199207
# Reset global caches for the new build.
200208
find_module_clear_caches()
201209

202210
self.triggered = []
211+
self.updated_modules = []
203212
changed_modules = dedupe_modules(changed_modules + self.stale)
204213
initial_set = {id for id, _ in changed_modules}
205214
self.manager.log_fine_grained('==== update %s ====' % ', '.join(
@@ -256,6 +265,7 @@ def update_single(self, module: str, path: str) -> Tuple[List[str],
256265
- Whether there was a blocking error in the module
257266
"""
258267
self.manager.log_fine_grained('--- update single %r ---' % module)
268+
self.updated_modules.append(module)
259269

260270
# TODO: If new module brings in other modules, we parse some files multiple times.
261271
manager = self.manager

mypy/test/helpers.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import time
66
import shutil
77

8-
from typing import List, Dict, Tuple, Callable, Any, Optional
8+
from typing import List, Iterable, Dict, Tuple, Callable, Any, Optional
99

1010
from mypy import defaults
1111
from mypy.test.config import test_temp_dir
@@ -98,6 +98,21 @@ def assert_string_arrays_equal(expected: List[str], actual: List[str],
9898
raise AssertionError(msg)
9999

100100

101+
def assert_module_equivalence(name: str,
102+
expected: Optional[Iterable[str]], actual: Iterable[str]) -> None:
103+
if expected is not None:
104+
expected_normalized = sorted(expected)
105+
actual_normalized = sorted(set(actual).difference({"__main__"}))
106+
assert_string_arrays_equal(
107+
expected_normalized,
108+
actual_normalized,
109+
('Actual modules ({}) do not match expected modules ({}) '
110+
'for "[{} ...]"').format(
111+
', '.join(actual_normalized),
112+
', '.join(expected_normalized),
113+
name))
114+
115+
101116
def update_testcase_output(testcase: DataDrivenTestCase, output: List[str]) -> None:
102117
assert testcase.old_cwd is not None, "test was not properly set up"
103118
testcase_path = os.path.join(testcase.old_cwd, testcase.file)

mypy/test/testcheck.py

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from mypy.test.config import test_temp_dir
1212
from mypy.test.data import DataDrivenTestCase, DataSuite
1313
from mypy.test.helpers import (
14-
assert_string_arrays_equal, normalize_error_messages,
14+
assert_string_arrays_equal, normalize_error_messages, assert_module_equivalence,
1515
retry_on_error, update_testcase_output, parse_options,
1616
copy_and_fudge_mtime
1717
)
@@ -190,29 +190,15 @@ def run_case_once(self, testcase: DataDrivenTestCase, incremental_step: int = 0)
190190
self.verify_cache(module_data, a, res.manager)
191191
if incremental_step > 1:
192192
suffix = '' if incremental_step == 2 else str(incremental_step - 1)
193-
self.check_module_equivalence(
193+
assert_module_equivalence(
194194
'rechecked' + suffix,
195195
testcase.expected_rechecked_modules.get(incremental_step - 1),
196196
res.manager.rechecked_modules)
197-
self.check_module_equivalence(
197+
assert_module_equivalence(
198198
'stale' + suffix,
199199
testcase.expected_stale_modules.get(incremental_step - 1),
200200
res.manager.stale_modules)
201201

202-
def check_module_equivalence(self, name: str,
203-
expected: Optional[Set[str]], actual: Set[str]) -> None:
204-
if expected is not None:
205-
expected_normalized = sorted(expected)
206-
actual_normalized = sorted(actual.difference({"__main__"}))
207-
assert_string_arrays_equal(
208-
expected_normalized,
209-
actual_normalized,
210-
('Actual modules ({}) do not match expected modules ({}) '
211-
'for "[{} ...]"').format(
212-
', '.join(actual_normalized),
213-
', '.join(expected_normalized),
214-
name))
215-
216202
def verify_cache(self, module_data: List[Tuple[str, str, str]], a: List[str],
217203
manager: build.BuildManager) -> None:
218204
# There should be valid cache metadata for each module except

mypy/test/testfinegrained.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import os
1111
import re
1212

13-
from typing import List, Tuple, Optional, cast
13+
from typing import List, Set, Tuple, Optional, cast
1414

1515
from mypy import build
1616
from mypy.build import BuildManager, BuildSource, Graph
@@ -21,7 +21,9 @@
2121
from mypy.test.data import (
2222
DataDrivenTestCase, DataSuite, UpdateFile, module_from_path
2323
)
24-
from mypy.test.helpers import assert_string_arrays_equal, parse_options, copy_and_fudge_mtime
24+
from mypy.test.helpers import (
25+
assert_string_arrays_equal, parse_options, copy_and_fudge_mtime, assert_module_equivalence,
26+
)
2527
from mypy.server.mergecheck import check_consistency
2628
from mypy.dmypy_server import Server
2729
from mypy.main import expand_dir
@@ -96,6 +98,7 @@ def run_case(self, testcase: DataDrivenTestCase) -> None:
9698

9799
steps = testcase.find_steps()
98100
all_triggered = []
101+
99102
for operations in steps:
100103
step += 1
101104
for op in operations:
@@ -108,10 +111,26 @@ def run_case(self, testcase: DataDrivenTestCase) -> None:
108111
sources = self.parse_sources(main_src, step)
109112
new_messages = self.run_check(server, sources)
110113

114+
assert server.fine_grained_manager
115+
116+
updated, changed = [], []
111117
if server.fine_grained_manager:
112118
if CHECK_CONSISTENCY:
113119
check_consistency(server.fine_grained_manager)
114120
all_triggered.append(server.fine_grained_manager.triggered)
121+
122+
updated = server.fine_grained_manager.updated_modules
123+
changed = [mod for mod, file in server.fine_grained_manager.changed_modules]
124+
125+
assert_module_equivalence(
126+
'stale' + str(step - 1),
127+
testcase.expected_stale_modules.get(step - 1),
128+
changed)
129+
assert_module_equivalence(
130+
'rechecked' + str(step - 1),
131+
testcase.expected_rechecked_modules.get(step - 1),
132+
updated)
133+
115134
new_messages = normalize_messages(new_messages)
116135

117136
a.append('==')

0 commit comments

Comments
 (0)