MCPcopy Index your code
hub / github.com/python/mypy / find_stale_sccs

Function find_stale_sccs

mypy/build.py:4473–4552  ·  view source on GitHub ↗

Split a list of ready SCCs into stale and fresh. Fresh SCCs are those where: * We have valid cache files for all modules in the SCC. * There are no changes in dependencies (files removed from/added to the build). * The interface hashes of dependencies matches those recorded in the c

(
    sccs: list[SCC], graph: Graph, manager: BuildManager
)

Source from the content-addressed store, hash-verified

4471
4472
4473def find_stale_sccs(
4474 sccs: list[SCC], graph: Graph, manager: BuildManager
4475) -> tuple[list[SCC], list[SCC]]:
4476 """Split a list of ready SCCs into stale and fresh.
4477
4478 Fresh SCCs are those where:
4479 * We have valid cache files for all modules in the SCC.
4480 * There are no changes in dependencies (files removed from/added to the build).
4481 * The interface hashes of dependencies matches those recorded in the cache.
4482 * All indirect dependencies are still reachable via direct ones.
4483 The first and second conditions are verified by is_fresh().
4484 """
4485 stale_sccs = []
4486 fresh_sccs = []
4487 for ascc in sccs:
4488 stale_scc = {id for id in ascc.mod_ids if not graph[id].is_fresh()}
4489 fresh = not stale_scc
4490
4491 # Verify that interfaces of dependencies still present in graph are up-to-date (fresh).
4492 stale_deps = set()
4493 for id in ascc.mod_ids:
4494 for dep in graph[id].dep_hashes:
4495 if dep in graph and graph[dep].interface_hash != graph[id].dep_hashes[dep]:
4496 stale_deps.add(dep)
4497 fresh = fresh and not stale_deps
4498
4499 # Verify the invariant that indirect dependencies are a subset of transitive direct
4500 # dependencies. Note: the case where indirect dependency is removed from the graph
4501 # completely is already handled above.
4502 stale_indirect = None
4503 if fresh:
4504 stale_indirect = verify_transitive_deps(ascc, graph, manager)
4505 if stale_indirect is not None:
4506 fresh = False
4507
4508 if manager.logging_enabled:
4509 if fresh:
4510 fresh_msg = "fresh"
4511 elif stale_scc:
4512 fresh_msg = "inherently stale"
4513 if stale_scc != ascc.mod_ids:
4514 fresh_msg += f" ({' '.join(sorted(stale_scc))})"
4515 if stale_deps:
4516 fresh_msg += f" with stale deps ({' '.join(sorted(stale_deps))})"
4517 elif stale_deps:
4518 fresh_msg = f"stale due to deps ({' '.join(sorted(stale_deps))})"
4519 else:
4520 assert stale_indirect is not None
4521 fresh_msg = f"stale due to stale indirect dep(s): first {stale_indirect}"
4522 scc_str = " ".join(ascc.mod_ids)
4523
4524 if fresh:
4525 if manager.tracing_enabled:
4526 manager.trace(f"Found {fresh_msg} SCC ({scc_str})")
4527 # If there is at most one file with errors we can skip the ordering to save time.
4528 mods_with_errors = [id for id in ascc.mod_ids if graph[id].error_lines]
4529 if len(mods_with_errors) <= 1:
4530 scc = mods_with_errors

Callers 1

process_graphFunction · 0.85

Calls 14

setClass · 0.85
verify_transitive_depsFunction · 0.85
sortedFunction · 0.85
lenFunction · 0.85
order_ascc_exFunction · 0.85
is_freshMethod · 0.80
traceMethod · 0.80
simplify_pathMethod · 0.80
format_messagesMethod · 0.80
flush_errorsMethod · 0.80
appendMethod · 0.80
addMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…