Skip to content

Commit b1a10a0

Browse files
author
Arnaud Desmier
committed
Closes #13022: fix _toctree_copy with multi level 'only' nodes.
When copying toc tree, 'only' nodes should not be copied, but previous implementation always considered 'only' node children as duplicable nodes which is wrong when 'only' nodes is parent of other 'only' nodes.
1 parent c93723b commit b1a10a0

File tree

1 file changed

+16
-17
lines changed

1 file changed

+16
-17
lines changed

sphinx/environment/adapters/toctree.py

+16-17
Original file line numberDiff line numberDiff line change
@@ -464,16 +464,13 @@ def _toctree_add_classes(node: Element, depth: int, docname: str) -> None:
464464

465465
ET = TypeVar('ET', bound=Element)
466466

467-
468-
def _toctree_copy(
469-
node: ET, depth: int, maxdepth: int, collapse: bool, tags: Tags
470-
) -> ET:
467+
def _toctree_copy_children(
468+
copy: ET, node: ET, depth: int, maxdepth: int, collapse: bool, tags: Tags
469+
) -> None:
471470
"""Utility: Cut and deep-copy a TOC at a specified depth."""
472471
keep_bullet_list_sub_nodes = depth <= 1 or (
473472
(depth <= maxdepth or maxdepth <= 0) and (not collapse or 'iscurrent' in node)
474473
)
475-
476-
copy = node.copy()
477474
for subnode in node.children:
478475
if isinstance(subnode, addnodes.compact_paragraph | nodes.list_item):
479476
# for <p> and <li>, just recurse
@@ -489,18 +486,11 @@ def _toctree_copy(
489486
# copy sub toctree nodes for later processing
490487
copy.append(subnode.copy())
491488
elif isinstance(subnode, addnodes.only):
492-
# only keep children if the only node matches the tags
489+
# Only keep its children if the 'only' node matches the tags. When
490+
# matching, call recursively the current function without
491+
# incrementing the depth as 'only' nodes are not toctree nodes.
493492
if _only_node_keep_children(subnode, tags):
494-
for child in subnode.children:
495-
copy.append(
496-
_toctree_copy(
497-
child,
498-
depth,
499-
maxdepth,
500-
collapse,
501-
tags, # type: ignore[type-var]
502-
)
503-
)
493+
_toctree_copy_children(copy, subnode, depth, maxdepth, collapse, tags)
504494
elif isinstance(subnode, nodes.reference | nodes.title):
505495
# deep copy references and captions
506496
sub_node_copy = subnode.copy()
@@ -511,6 +501,15 @@ def _toctree_copy(
511501
else:
512502
msg = f'Unexpected node type {subnode.__class__.__name__!r}!'
513503
raise ValueError(msg)
504+
505+
return copy
506+
507+
508+
def _toctree_copy(
509+
node: ET, depth: int, maxdepth: int, collapse: bool, tags: Tags
510+
) -> ET:
511+
copy = node.copy()
512+
_toctree_copy_children(copy, node, depth, maxdepth, collapse, tags)
514513
return copy
515514

516515

0 commit comments

Comments
 (0)