115115
116116- Fully support multiple type checking passes
117117- Use mypy.fscache to access file system
118- - Don't use load_graph() and update the import graph incrementally
119118"""
120119
121120import os .path
122121from typing import Dict , List , Set , Tuple , Iterable , Union , Optional , Mapping , NamedTuple
123122
124123from 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 ,
127126)
128127from mypy .checker import DeferredNode
129128from mypy .errors import Errors , CompileError
@@ -172,7 +171,6 @@ def __init__(self,
172171 # this directly reflected in load_graph's interface.
173172 self .options .cache_dir = os .devnull
174173 manager .saved_cache = {}
175- self .type_maps = extract_type_maps (graph )
176174 # Active triggers during the last update
177175 self .triggered = [] # type: List[str]
178176
@@ -253,6 +251,7 @@ def update_single(self, module: str, path: str) -> Tuple[List[str],
253251 # TODO: If new module brings in other modules, we parse some files multiple times.
254252 manager = self .manager
255253 previous_modules = self .previous_modules
254+ graph = self .graph
256255
257256 # Record symbol table snaphot of old version the changed module.
258257 old_snapshots = {} # type: Dict[str, Dict[str, SnapshotItem]]
@@ -261,14 +260,14 @@ def update_single(self, module: str, path: str) -> Tuple[List[str],
261260 old_snapshots [module ] = snapshot
262261
263262 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 )
265264 if isinstance (result , BlockedUpdate ):
266265 # Blocking error -- just give up
267266 module , path , remaining , errors = result
268267 self .previous_modules = get_module_to_path_map (manager )
269268 return errors , remaining , (module , path ), True
270269 assert isinstance (result , NormalUpdate ) # Work around #4124
271- module , path , remaining , tree , graph = result
270+ module , path , remaining , tree = result
272271
273272 # TODO: What to do with stale dependencies?
274273 triggered = calculate_active_triggers (manager , old_snapshots , {module : tree })
@@ -285,20 +284,7 @@ def update_single(self, module: str, path: str) -> Tuple[List[str],
285284
286285 # Preserve state needed for the next update.
287286 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
297287 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
302288
303289 return manager .errors .new_messages (), remaining , (module , path ), False
304290
@@ -317,15 +303,13 @@ def get_all_dependencies(manager: BuildManager, graph: Dict[str, State],
317303# - Id of the changed module (can be different from the module argument)
318304# - Path of the changed module
319305# - New AST for the changed module (None if module was deleted)
320- # - The entire updated build graph
321306# - Remaining changed modules that are not processed yet as (module id, path)
322307# tuples (non-empty if the original changed module imported other new
323308# modules)
324309NormalUpdate = NamedTuple ('NormalUpdate' , [('module' , str ),
325310 ('path' , str ),
326311 ('remaining' , List [Tuple [str , str ]]),
327- ('tree' , Optional [MypyFile ]),
328- ('graph' , Graph )])
312+ ('tree' , Optional [MypyFile ])])
329313
330314# The result of update_single_isolated when there is a blocking error. Items
331315# are similar to NormalUpdate (but there are fewer).
@@ -362,10 +346,11 @@ def update_single_isolated(module: str,
362346
363347 old_modules = dict (manager .modules )
364348 sources = get_sources (previous_modules , [(module , path )])
365- invalidate_stale_cache_entries (manager .saved_cache , graph , [(module , path )])
366349
367350 manager .missing_modules .clear ()
368351 try :
352+ if module in graph :
353+ del graph [module ]
369354 load_graph (sources , manager , graph )
370355 except CompileError as err :
371356 # Parse error somewhere in the program -- a blocker
@@ -383,8 +368,8 @@ def update_single_isolated(module: str,
383368 return BlockedUpdate (err .module_with_blocker , path , remaining_modules , err .messages )
384369
385370 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 )
388373
389374 # Find any other modules brought in by imports.
390375 changed_modules = get_all_changed_modules (module , path , previous_modules , graph )
@@ -438,7 +423,7 @@ def update_single_isolated(module: str,
438423
439424 graph [module ] = state
440425
441- return NormalUpdate (module , path , remaining_modules , state .tree , graph )
426+ return NormalUpdate (module , path , remaining_modules , state .tree )
442427
443428
444429def 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:
475460
476461
477462def delete_module (module_id : str ,
478- graph : Dict [ str , State ] ,
479- manager : BuildManager ) -> Dict [ str , State ] :
463+ graph : Graph ,
464+ manager : BuildManager ) -> None :
480465 manager .log_fine_grained ('delete module %r' % module_id )
481466 # TODO: Deletion of a package
482467 # 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 ]
486470 if module_id in manager .modules :
487471 del manager .modules [module_id ]
488472 if module_id in manager .saved_cache :
@@ -496,7 +480,6 @@ def delete_module(module_id: str,
496480 parent = manager .modules [parent_id ]
497481 if components [- 1 ] in parent .names :
498482 del parent .names [components [- 1 ]]
499- return new_graph
500483
501484
502485def dedupe_modules (modules : List [Tuple [str , str ]]) -> List [Tuple [str , str ]]:
@@ -518,15 +501,10 @@ def get_sources(modules: Dict[str, str],
518501 changed_modules : List [Tuple [str , str ]]) -> List [BuildSource ]:
519502 # TODO: Race condition when reading from the file system; we should only read each
520503 # 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 )]
525504 sources = []
526505 for id , path in changed_modules :
527- if os .path .isfile (path ):# and id not in modules:
506+ if os .path .isfile (path ):
528507 sources .append (BuildSource (path , id , None ))
529- # print(changed_modules, sources)
530508 return sources
531509
532510
@@ -544,16 +522,6 @@ def get_all_changed_modules(root_module: str,
544522 return changed_modules
545523
546524
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-
557525def verify_dependencies (state : State , manager : BuildManager ) -> None :
558526 """Report errors for import targets in module that don't exist."""
559527 for dep in state .dependencies + state .suppressed : # TODO: ancestors?
@@ -907,11 +875,5 @@ def lookup_target(modules: Dict[str, MypyFile], target: str) -> List[DeferredNod
907875 return [DeferredNode (node , active_class_name , active_class )]
908876
909877
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-
916878def is_verbose (manager : BuildManager ) -> bool :
917879 return manager .options .verbosity >= 1 or DEBUG_FINE_GRAINED
0 commit comments