(
sources: list[BuildSource],
manager: BuildManager,
stdout: TextIO,
connect_threads: list[Thread],
)
| 4055 | |
| 4056 | |
| 4057 | def dispatch( |
| 4058 | sources: list[BuildSource], |
| 4059 | manager: BuildManager, |
| 4060 | stdout: TextIO, |
| 4061 | connect_threads: list[Thread], |
| 4062 | ) -> Graph: |
| 4063 | log_configuration(manager, sources) |
| 4064 | |
| 4065 | t0 = time.time() |
| 4066 | |
| 4067 | # We disable GC while loading the graph as a performance optimization for |
| 4068 | # cold-cache runs. The parsed ASTs are trees, and therefore should not have any |
| 4069 | # reference cycles. This is an important optimization, since we create a lot of |
| 4070 | # new objects while parsing files. |
| 4071 | global initial_gc_freeze_done |
| 4072 | if ( |
| 4073 | not manager.options.test_env |
| 4074 | and platform.python_implementation() == "CPython" |
| 4075 | and not initial_gc_freeze_done |
| 4076 | ): |
| 4077 | gc.disable() |
| 4078 | graph = load_graph(sources, manager) |
| 4079 | |
| 4080 | # This is a kind of unfortunate hack to work around some of fine-grained's |
| 4081 | # fragility: if we have loaded less than 50% of the specified files from |
| 4082 | # cache in fine-grained cache mode, load the graph again honestly. |
| 4083 | # In this case, we just turn the cache off entirely, so we don't need |
| 4084 | # to worry about some files being loaded and some from cache and so |
| 4085 | # that fine-grained mode never *writes* to the cache. |
| 4086 | if manager.use_fine_grained_cache() and len(graph) < 0.50 * len(sources): |
| 4087 | manager.log("Redoing load_graph without cache because too much was missing") |
| 4088 | manager.cache_enabled = False |
| 4089 | graph = load_graph(sources, manager) |
| 4090 | |
| 4091 | if ( |
| 4092 | not manager.options.test_env |
| 4093 | and platform.python_implementation() == "CPython" |
| 4094 | and not initial_gc_freeze_done |
| 4095 | ): |
| 4096 | gc.freeze() |
| 4097 | gc.unfreeze() |
| 4098 | gc.enable() |
| 4099 | initial_gc_freeze_done = True |
| 4100 | |
| 4101 | for id in graph: |
| 4102 | manager.import_map[id] = graph[id].dependencies_set |
| 4103 | |
| 4104 | t1 = time.time() |
| 4105 | manager.add_stats( |
| 4106 | graph_size=len(graph), |
| 4107 | stubs_found=sum(g.path is not None and g.path.endswith(".pyi") for g in graph.values()), |
| 4108 | graph_load_time=(t1 - t0), |
| 4109 | fm_cache_size=len(manager.find_module_cache.results), |
| 4110 | ) |
| 4111 | if not graph: |
| 4112 | print("Nothing to do?!", file=stdout) |
| 4113 | return graph |
| 4114 | manager.log(f"Loaded graph with {len(graph)} nodes ({t1 - t0:.3f} sec)") |
no test coverage detected
searching dependent graphs…