4343from mypy .checker import TypeChecker
4444from mypy .error_formatter import OUTPUT_CHOICES , ErrorFormatter
4545from mypy .errors import CompileError , ErrorInfo , Errors , report_internal_error
46- from mypy .graph_utils import strongly_connected_components , topsort
46+ from mypy .graph_utils import prepare_sccs , strongly_connected_components , topsort
4747from mypy .indirection import TypeIndirectionVisitor
4848from mypy .messages import MessageBuilder
4949from mypy .nodes import Import , ImportAll , ImportBase , ImportFrom , MypyFile , SymbolTable
@@ -3360,7 +3360,7 @@ def process_graph(graph: Graph, manager: BuildManager) -> None:
33603360 ready .append (scc_by_id [dependent ])
33613361
33623362
3363- def order_ascc (graph : Graph , ascc : AbstractSet [str ], pri_max : int = PRI_ALL ) -> list [str ]:
3363+ def order_ascc (graph : Graph , ascc : AbstractSet [str ], pri_max : int = PRI_INDIRECT ) -> list [str ]:
33643364 """Come up with the ideal processing order within an SCC.
33653365
33663366 Using the priorities assigned by all_imported_modules_in_file(),
@@ -3402,9 +3402,9 @@ def order_ascc(graph: Graph, ascc: AbstractSet[str], pri_max: int = PRI_ALL) ->
34023402 # Filtered dependencies are uniform -- order by global order.
34033403 return sorted (ascc , key = lambda id : - graph [id ].order )
34043404 pri_max = max (pri_spread )
3405- sccs = sorted_components (graph , ascc , pri_max )
3405+ sccs = sorted_components_inner (graph , ascc , pri_max )
34063406 # The recursion is bounded by the len(pri_spread) check above.
3407- return [s for ss in sccs for s in order_ascc (graph , ss . mod_ids , pri_max )]
3407+ return [s for ss in sccs for s in order_ascc (graph , ss , pri_max )]
34083408
34093409
34103410def process_fresh_modules (graph : Graph , modules : list [str ], manager : BuildManager ) -> None :
@@ -3526,7 +3526,9 @@ def process_stale_scc(graph: Graph, ascc: SCC, manager: BuildManager) -> None:
35263526 manager .done_sccs .add (ascc .id )
35273527
35283528
3529- def prepare_sccs (raw_sccs : Iterator [set [str ]], edges : dict [str , list [str ]]) -> dict [SCC , set [SCC ]]:
3529+ def prepare_sccs_full (
3530+ raw_sccs : Iterator [set [str ]], edges : dict [str , list [str ]]
3531+ ) -> dict [SCC , set [SCC ]]:
35303532 sccs = [SCC (raw_scc ) for raw_scc in raw_sccs ]
35313533 scc_map = {}
35323534 for scc in sccs :
@@ -3544,10 +3546,7 @@ def prepare_sccs(raw_sccs: Iterator[set[str]], edges: dict[str, list[str]]) -> d
35443546 return scc_deps_map
35453547
35463548
3547- # TODO: add version just for sorting (no sense to create all the other infra there).
3548- def sorted_components (
3549- graph : Graph , vertices : AbstractSet [str ] | None = None , pri_max : int = PRI_INDIRECT
3550- ) -> list [SCC ]:
3549+ def sorted_components (graph : Graph ) -> list [SCC ]:
35513550 """Return the graph's SCCs, topologically sorted by dependencies.
35523551
35533552 The sort order is from leaves (nodes without dependencies) to
@@ -3557,10 +3556,9 @@ def sorted_components(
35573556 dependencies that aren't present in graph.keys() are ignored.
35583557 """
35593558 # Compute SCCs.
3560- if vertices is None :
3561- vertices = set (graph )
3562- edges = {id : deps_filtered (graph , vertices , id , pri_max ) for id in vertices }
3563- scc_dep_map = prepare_sccs (strongly_connected_components (vertices , edges ), edges )
3559+ vertices = set (graph )
3560+ edges = {id : deps_filtered (graph , vertices , id , PRI_INDIRECT ) for id in vertices }
3561+ scc_dep_map = prepare_sccs_full (strongly_connected_components (vertices , edges ), edges )
35643562 # Topsort.
35653563 res = []
35663564 for ready in topsort (scc_dep_map ):
@@ -3580,6 +3578,17 @@ def sorted_components(
35803578 return res
35813579
35823580
3581+ def sorted_components_inner (
3582+ graph : Graph , vertices : AbstractSet [str ], pri_max : int
3583+ ) -> list [AbstractSet [str ]]:
3584+ edges = {id : deps_filtered (graph , vertices , id , pri_max ) for id in vertices }
3585+ sccs = list (strongly_connected_components (vertices , edges ))
3586+ res = []
3587+ for ready in topsort (prepare_sccs (sccs , edges )):
3588+ res .extend (sorted (ready , key = lambda scc : - min (graph [id ].order for id in scc )))
3589+ return res
3590+
3591+
35833592def deps_filtered (graph : Graph , vertices : AbstractSet [str ], id : str , pri_max : int ) -> list [str ]:
35843593 """Filter dependencies for id with pri < pri_max."""
35853594 if id not in vertices :
0 commit comments