@@ -27,30 +27,29 @@ def render_dependency_branch[Node: Hashable](
2727 branch_style : Callable [[str ], str ],
2828 already_shown : Callable [[], str ],
2929) -> list [str ]:
30- """Render a box-drawing dependency branch for opaque node values ."""
30+ """Render a box-drawing dependency branch, expanding each node once across the tree ."""
3131
3232 lines : list [str ] = []
33- children : list [Node ] = sorted (deps .get (node , ()), key = sort_key )
34- index : int
35- child : Node
36- for index , child in enumerate (children ):
37- is_last : bool = index == len (children ) - 1
33+ shown : set [Node ] = set (seen )
34+ pending : list [tuple [Node , str , bool ]] = _pending_children (
35+ children = sorted (deps .get (node , ()), key = sort_key ), prefix = prefix
36+ )
37+ while pending :
38+ child : Node
39+ child_prefix : str
40+ is_last : bool
41+ child , child_prefix , is_last = pending .pop ()
3842 branch : str = _BRANCH_LAST if is_last else _BRANCH_MID
39- continuation : str = _CONTINUATION_LAST if is_last else _CONTINUATION_MID
40- suffix : str = already_shown () if child in seen else ""
41- lines .append (f"{ branch_style (prefix + branch )} { format_node (child )} { suffix } " )
42- if child in seen :
43+ suffix : str = already_shown () if child in shown else ""
44+ lines .append (f"{ branch_style (child_prefix + branch )} { format_node (child )} { suffix } " )
45+ if child in shown :
4346 continue
44- lines .extend (
45- render_dependency_branch (
46- node = child ,
47- deps = deps ,
48- prefix = prefix + continuation ,
49- seen = seen | {child },
50- format_node = format_node ,
51- sort_key = sort_key ,
52- branch_style = branch_style ,
53- already_shown = already_shown ,
47+ shown .add (child )
48+ continuation : str = _CONTINUATION_LAST if is_last else _CONTINUATION_MID
49+ pending .extend (
50+ _pending_children (
51+ children = sorted (deps .get (child , ()), key = sort_key ),
52+ prefix = child_prefix + continuation ,
5453 )
5554 )
5655 return lines
@@ -68,41 +67,59 @@ def render_column_trace_branch[Column, Edge](
6867 branch_style : Callable [[str ], str ],
6968 already_shown : Callable [[], str ],
7069) -> list [str ]:
71- """Render a box-drawing column-trace branch for opaque column/edge values ."""
70+ """Render a box-drawing column-trace branch, expanding each column once across the tree ."""
7271
7372 lines : list [str ] = []
74- edges : list [Edge ] = sorted (
75- deps .get (column_id (column ), ()),
76- key = lambda edge : column_id (related_column (edge )),
73+ shown : set [str ] = set (seen )
74+ pending : list [tuple [Edge , str , bool ]] = _pending_children (
75+ children = _sorted_edges (
76+ edges = deps .get (column_id (column ), ()),
77+ column_id = column_id ,
78+ related_column = related_column ,
79+ ),
80+ prefix = prefix ,
7781 )
78- index : int
79- edge : Edge
80- for index , edge in enumerate (edges ):
81- is_last : bool = index == len (edges ) - 1
82+ while pending :
83+ edge : Edge
84+ edge_prefix : str
85+ is_last : bool
86+ edge , edge_prefix , is_last = pending .pop ()
8287 branch : str = _BRANCH_LAST if is_last else _BRANCH_MID
83- continuation : str = _CONTINUATION_LAST if is_last else _CONTINUATION_MID
8488 related : Column = related_column (edge )
8589 related_id : str = column_id (related )
86- suffix : str = already_shown () if related_id in seen else ""
87- lines .append (f"{ prefix } { branch_style (branch )} { format_related (edge )} { suffix } " )
88- if related_id in seen :
90+ suffix : str = already_shown () if related_id in shown else ""
91+ lines .append (f"{ edge_prefix } { branch_style (branch )} { format_related (edge )} { suffix } " )
92+ if related_id in shown :
8993 continue
90- lines .extend (
91- render_column_trace_branch (
92- column = related ,
93- deps = deps ,
94- prefix = prefix + continuation ,
95- seen = seen | {related_id },
96- column_id = column_id ,
97- related_column = related_column ,
98- format_related = format_related ,
99- branch_style = branch_style ,
100- already_shown = already_shown ,
94+ shown .add (related_id )
95+ continuation : str = _CONTINUATION_LAST if is_last else _CONTINUATION_MID
96+ pending .extend (
97+ _pending_children (
98+ children = _sorted_edges (
99+ edges = deps .get (related_id , ()),
100+ column_id = column_id ,
101+ related_column = related_column ,
102+ ),
103+ prefix = edge_prefix + continuation ,
101104 )
102105 )
103106 return lines
104107
105108
109+ def _pending_children [Item ](* , children : list [Item ], prefix : str ) -> list [tuple [Item , str , bool ]]:
110+ last : int = len (children ) - 1
111+ return [(child , prefix , index == last ) for index , child in reversed (list (enumerate (children )))]
112+
113+
114+ def _sorted_edges [Column , Edge ](
115+ * ,
116+ edges : list [Edge ] | tuple [()],
117+ column_id : Callable [[Column ], str ],
118+ related_column : Callable [[Edge ], Column ],
119+ ) -> list [Edge ]:
120+ return sorted (edges , key = lambda edge : column_id (related_column (edge )))
121+
122+
106123def render_column_trace_limit_note (
107124 * ,
108125 total : int ,
0 commit comments