Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the MoveModuleTargets transform #11647

Merged
merged 3 commits into from Aug 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES
Expand Up @@ -4,6 +4,8 @@ Release 7.2.4 (in development)
Bugs fixed
----------

* #11618: Fix a regression in the MoveModuleTargets transform,
introduced in #10478 (#9662).

Release 7.2.3 (released Aug 23, 2023)
=====================================
Expand Down
12 changes: 8 additions & 4 deletions sphinx/transforms/__init__.py
Expand Up @@ -145,10 +145,14 @@ def apply(self, **kwargs: Any) -> None:
for node in list(self.document.findall(nodes.target)):
if not node['ids']:
continue
if ('ismod' in node and
node.parent.__class__ is nodes.section and
# index 0 is the section title node
node.parent.index(node) == 1):
if (
'ismod' in node
and type(node.parent) is nodes.section
# index 0: section title node
# index 1: index node
# index 2: target node
and node.parent.index(node) == 2
):
node.parent['ids'][0:0] = node['ids']
node.parent.remove(node)

Expand Down
77 changes: 77 additions & 0 deletions tests/test_transforms_move_module_targets.py
@@ -0,0 +1,77 @@
import pytest
from docutils import nodes

from sphinx import addnodes
from sphinx.testing.util import SphinxTestApp
from sphinx.transforms import MoveModuleTargets

CONTENT_PY = """\
move-module-targets
===================

.. py:module:: fish_licence.halibut
"""
CONTENT_JS = """\
move-module-targets
===================

.. js:module:: fish_licence.halibut
"""


@pytest.mark.parametrize('content', [
CONTENT_PY, # Python
CONTENT_JS, # JavaScript
])
@pytest.mark.usefixtures("rollback_sysmodules")
def test_move_module_targets(tmp_path, content):
# Test for the MoveModuleTargets transform
tmp_path.joinpath("conf.py").touch()
tmp_path.joinpath("index.rst").write_text(content, encoding="utf-8")

app = SphinxTestApp('dummy', srcdir=tmp_path)
app.build(force_all=True)
document = app.env.get_doctree('index')
section = document[0]

# target ID has been lifted into the section node
assert section["ids"] == ['module-fish_licence.halibut', 'move-module-targets']
# nodes.target has been removed from 'section'
assert isinstance(section[0], nodes.title)
assert isinstance(section[1], addnodes.index)
assert len(section) == 2


@pytest.mark.usefixtures("rollback_sysmodules")
def test_move_module_targets_no_section(tmp_path):
# Test for the MoveModuleTargets transform
tmp_path.joinpath("conf.py").touch()
tmp_path.joinpath("index.rst").write_text(".. py:module:: fish_licence.halibut\n", encoding="utf-8")

app = SphinxTestApp('dummy', srcdir=tmp_path)
app.build(force_all=True)
document = app.env.get_doctree('index')

assert document["ids"] == []


@pytest.mark.usefixtures("rollback_sysmodules")
def test_move_module_targets_disabled(tmp_path):
# Test for the MoveModuleTargets transform
tmp_path.joinpath("conf.py").touch()
tmp_path.joinpath("index.rst").write_text(CONTENT_PY, encoding="utf-8")

app = SphinxTestApp('dummy', srcdir=tmp_path)
app.registry.transforms.remove(MoveModuleTargets) # disable the transform
app.build(force_all=True)
document = app.env.get_doctree('index')
section = document[0]

# target ID is not lifted into the section node
assert section["ids"] == ['move-module-targets']
assert section[2]["ids"] == ['module-fish_licence.halibut']
# nodes.target remains in 'section'
assert isinstance(section[0], nodes.title)
assert isinstance(section[1], addnodes.index)
assert isinstance(section[2], nodes.target)
assert len(section) == 3