115
115
116
116
- Fully support multiple type checking passes
117
117
- Use mypy.fscache to access file system
118
- - Don't use load_graph() and update the import graph incrementally
119
118
"""
120
119
121
120
import os .path
122
121
from typing import Dict , List , Set , Tuple , Iterable , Union , Optional , Mapping , NamedTuple
123
122
124
123
from mypy .build import (
125
- BuildManager , State , BuildSource , Graph , load_graph , SavedCache , CacheMeta ,
126
- cache_meta_from_dict , find_module_clear_caches , DEBUG_FINE_GRAINED
124
+ BuildManager , State , BuildSource , Graph , load_graph , find_module_clear_caches ,
125
+ DEBUG_FINE_GRAINED ,
127
126
)
128
127
from mypy .checker import DeferredNode
129
128
from mypy .errors import Errors , CompileError
@@ -172,7 +171,6 @@ def __init__(self,
172
171
# this directly reflected in load_graph's interface.
173
172
self .options .cache_dir = os .devnull
174
173
manager .saved_cache = {}
175
- self .type_maps = extract_type_maps (graph )
176
174
# Active triggers during the last update
177
175
self .triggered = [] # type: List[str]
178
176
@@ -253,6 +251,7 @@ def update_single(self, module: str, path: str) -> Tuple[List[str],
253
251
# TODO: If new module brings in other modules, we parse some files multiple times.
254
252
manager = self .manager
255
253
previous_modules = self .previous_modules
254
+ graph = self .graph
256
255
257
256
# Record symbol table snaphot of old version the changed module.
258
257
old_snapshots = {} # type: Dict[str, Dict[str, SnapshotItem]]
@@ -261,14 +260,14 @@ def update_single(self, module: str, path: str) -> Tuple[List[str],
261
260
old_snapshots [module ] = snapshot
262
261
263
262
manager .errors .reset ()
264
- result = update_single_isolated (module , path , manager , previous_modules , self . graph )
263
+ result = update_single_isolated (module , path , manager , previous_modules , graph )
265
264
if isinstance (result , BlockedUpdate ):
266
265
# Blocking error -- just give up
267
266
module , path , remaining , errors = result
268
267
self .previous_modules = get_module_to_path_map (manager )
269
268
return errors , remaining , (module , path ), True
270
269
assert isinstance (result , NormalUpdate ) # Work around #4124
271
- module , path , remaining , tree , graph = result
270
+ module , path , remaining , tree = result
272
271
273
272
# TODO: What to do with stale dependencies?
274
273
triggered = calculate_active_triggers (manager , old_snapshots , {module : tree })
@@ -285,20 +284,7 @@ def update_single(self, module: str, path: str) -> Tuple[List[str],
285
284
286
285
# Preserve state needed for the next update.
287
286
self .previous_targets_with_errors = manager .errors .targets ()
288
- # If deleted, module won't be in the graph.
289
- if module in graph :
290
- # Generate metadata so that we can reuse the AST in the next run.
291
- graph [module ].write_cache ()
292
- for id , state in graph .items ():
293
- # Look up missing ASTs from saved cache.
294
- if state .tree is None and id in manager .saved_cache :
295
- meta , tree , type_map = manager .saved_cache [id ]
296
- state .tree = tree
297
287
self .previous_modules = get_module_to_path_map (manager )
298
- self .type_maps = extract_type_maps (graph )
299
-
300
- # XXX: I want us to not need this
301
- self .graph = graph
302
288
303
289
return manager .errors .new_messages (), remaining , (module , path ), False
304
290
@@ -317,15 +303,13 @@ def get_all_dependencies(manager: BuildManager, graph: Dict[str, State],
317
303
# - Id of the changed module (can be different from the module argument)
318
304
# - Path of the changed module
319
305
# - New AST for the changed module (None if module was deleted)
320
- # - The entire updated build graph
321
306
# - Remaining changed modules that are not processed yet as (module id, path)
322
307
# tuples (non-empty if the original changed module imported other new
323
308
# modules)
324
309
NormalUpdate = NamedTuple ('NormalUpdate' , [('module' , str ),
325
310
('path' , str ),
326
311
('remaining' , List [Tuple [str , str ]]),
327
- ('tree' , Optional [MypyFile ]),
328
- ('graph' , Graph )])
312
+ ('tree' , Optional [MypyFile ])])
329
313
330
314
# The result of update_single_isolated when there is a blocking error. Items
331
315
# are similar to NormalUpdate (but there are fewer).
@@ -362,10 +346,11 @@ def update_single_isolated(module: str,
362
346
363
347
old_modules = dict (manager .modules )
364
348
sources = get_sources (previous_modules , [(module , path )])
365
- invalidate_stale_cache_entries (manager .saved_cache , graph , [(module , path )])
366
349
367
350
manager .missing_modules .clear ()
368
351
try :
352
+ if module in graph :
353
+ del graph [module ]
369
354
load_graph (sources , manager , graph )
370
355
except CompileError as err :
371
356
# Parse error somewhere in the program -- a blocker
@@ -383,8 +368,8 @@ def update_single_isolated(module: str,
383
368
return BlockedUpdate (err .module_with_blocker , path , remaining_modules , err .messages )
384
369
385
370
if not os .path .isfile (path ):
386
- graph = delete_module (module , graph , manager )
387
- return NormalUpdate (module , path , [], None , graph )
371
+ delete_module (module , graph , manager )
372
+ return NormalUpdate (module , path , [], None )
388
373
389
374
# Find any other modules brought in by imports.
390
375
changed_modules = get_all_changed_modules (module , path , previous_modules , graph )
@@ -438,7 +423,7 @@ def update_single_isolated(module: str,
438
423
439
424
graph [module ] = state
440
425
441
- return NormalUpdate (module , path , remaining_modules , state .tree , graph )
426
+ return NormalUpdate (module , path , remaining_modules , state .tree )
442
427
443
428
444
429
def find_relative_leaf_module (modules : List [Tuple [str , str ]], graph : Graph ) -> Tuple [str , str ]:
@@ -475,14 +460,13 @@ def assert_equivalent_paths(path1: str, path2: str) -> None:
475
460
476
461
477
462
def delete_module (module_id : str ,
478
- graph : Dict [ str , State ] ,
479
- manager : BuildManager ) -> Dict [ str , State ] :
463
+ graph : Graph ,
464
+ manager : BuildManager ) -> None :
480
465
manager .log_fine_grained ('delete module %r' % module_id )
481
466
# TODO: Deletion of a package
482
467
# TODO: Remove deps for the module (this only affects memory use, not correctness)
483
- new_graph = graph .copy ()
484
- if module_id in new_graph :
485
- del new_graph [module_id ]
468
+ if module_id in graph :
469
+ del graph [module_id ]
486
470
if module_id in manager .modules :
487
471
del manager .modules [module_id ]
488
472
if module_id in manager .saved_cache :
@@ -496,7 +480,6 @@ def delete_module(module_id: str,
496
480
parent = manager .modules [parent_id ]
497
481
if components [- 1 ] in parent .names :
498
482
del parent .names [components [- 1 ]]
499
- return new_graph
500
483
501
484
502
485
def dedupe_modules (modules : List [Tuple [str , str ]]) -> List [Tuple [str , str ]]:
@@ -518,15 +501,10 @@ def get_sources(modules: Dict[str, str],
518
501
changed_modules : List [Tuple [str , str ]]) -> List [BuildSource ]:
519
502
# TODO: Race condition when reading from the file system; we should only read each
520
503
# bit of external state once during a build to have a consistent view of the world
521
- items = sorted (modules .items (), key = lambda x : x [0 ])
522
- sources = [BuildSource (path , id , None )
523
- for id , path in items
524
- if os .path .isfile (path )]
525
504
sources = []
526
505
for id , path in changed_modules :
527
- if os .path .isfile (path ):# and id not in modules:
506
+ if os .path .isfile (path ):
528
507
sources .append (BuildSource (path , id , None ))
529
- # print(changed_modules, sources)
530
508
return sources
531
509
532
510
@@ -544,16 +522,6 @@ def get_all_changed_modules(root_module: str,
544
522
return changed_modules
545
523
546
524
547
- def invalidate_stale_cache_entries (cache : SavedCache ,
548
- graph : Graph ,
549
- changed_modules : List [Tuple [str , str ]]) -> None :
550
- for name , _ in changed_modules :
551
- if name in cache :
552
- del cache [name ]
553
- if name in graph :
554
- del graph [name ]
555
-
556
-
557
525
def verify_dependencies (state : State , manager : BuildManager ) -> None :
558
526
"""Report errors for import targets in module that don't exist."""
559
527
for dep in state .dependencies + state .suppressed : # TODO: ancestors?
@@ -907,11 +875,5 @@ def lookup_target(modules: Dict[str, MypyFile], target: str) -> List[DeferredNod
907
875
return [DeferredNode (node , active_class_name , active_class )]
908
876
909
877
910
- def extract_type_maps (graph : Graph ) -> Dict [str , Dict [Expression , Type ]]:
911
- # This is used to export information used only by the testmerge harness.
912
- return {id : state .type_map () for id , state in graph .items ()
913
- if state .tree }
914
-
915
-
916
878
def is_verbose (manager : BuildManager ) -> bool :
917
879
return manager .options .verbosity >= 1 or DEBUG_FINE_GRAINED
0 commit comments