Skip to content

Commit

Permalink
Override RSTParser instead of trying to adjust the line parsing.
Browse files Browse the repository at this point in the history
Add tests for prolog and epilog. Add test runs to run all tests with configs of both.
  • Loading branch information
caffeinepills committed Apr 9, 2024
1 parent 03a9beb commit 1fe6ed7
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 2 deletions.
3 changes: 3 additions & 0 deletions src/sphinx_autodoc_typehints/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,9 @@ def node_line_no(node: Node) -> int | None:
docutils rst parser source code. An example where the node doesn't have a line number but the first child does is
all `definition_list` nodes. It seems like bullet_list and option_list get line numbers, but enum_list also doesn't.
"""
if node is None:
return None

while node.line is None and node.children:
node = node.children[0]
return node.line
Expand Down
9 changes: 8 additions & 1 deletion src/sphinx_autodoc_typehints/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,20 @@

from docutils import nodes
from docutils.frontend import Values
from docutils.statemachine import StringList


class _RstSnippetParser(RSTParser):
@staticmethod
def decorate(_content: StringList) -> None:
"""Override to skip processing rst_epilog/rst_prolog for typing."""


def parse(inputstr: str, settings: Values | optparse.Values) -> nodes.document:
"""Parse inputstr and return a docutils document."""
doc = new_document("", settings=settings)
with sphinx_domains(settings.env):
parser = RSTParser()
parser = _RstSnippetParser()
parser.set_application(settings.env.app)
parser.parse(inputstr, doc)
return doc
94 changes: 94 additions & 0 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -1267,15 +1267,108 @@ def typehints_use_signature(a: AsyncGenerator) -> AsyncGenerator:
"""
return a

prolog = """
.. |test_node_start| replace:: {test_node_start}
""".format(
test_node_start="test_start"
)

@expected(
"""
mod.docstring_with_multiline_note_after_params_prolog_replace(param)
Do something.
Parameters:
**param** ("int") -- A parameter.
Return type:
"None"
Note:
Some notes. test_start More notes
""",
rst_prolog=prolog
)

def docstring_with_multiline_note_after_params_prolog_replace(param: int) -> None: # noqa: ARG001
"""Do something.
Args:
param: A parameter.
Note:
Some notes. |test_node_start|
More notes
"""

epilog = """
.. |test_node_end| replace:: {test_node_end}
""".format(
test_node_end="test_end"
)
@expected(
"""
mod.docstring_with_multiline_note_after_params_epilog_replace(param)
Do something.
Parameters:
**param** ("int") -- A parameter.
Return type:
"None"
Note:
Some notes. test_end More notes
""",
rst_epilog=epilog
)

def docstring_with_multiline_note_after_params_epilog_replace(param: int) -> None: # noqa: ARG001
"""Do something.
Args:
param: A parameter.
Note:
Some notes. |test_node_end|
More notes
"""

# Config settings for each test run.
# Config Name: Sphinx Options as Dict.
configs = {
"default_conf": {},
"prolog_conf": {
"rst_prolog": prolog
},
"epilog_conf": {
"rst_epilog": epilog,
},
"bothlog_conf": {
"rst_prolog": prolog,
"rst_epilog": epilog,
}
}


@pytest.mark.parametrize("val", [x for x in globals().values() if hasattr(x, "EXPECTED")])
@pytest.mark.parametrize("conf_run", ["default_conf", "prolog_conf", "epilog_conf", "bothlog_conf"])
@pytest.mark.sphinx("text", testroot="integration")
def test_integration(
app: SphinxTestApp,
status: StringIO,
warning: StringIO,
monkeypatch: pytest.MonkeyPatch,
val: Any,
conf_run: str
) -> None:
if isclass(val) and issubclass(val, BaseException):
template = AUTO_EXCEPTION
Expand All @@ -1285,6 +1378,7 @@ def test_integration(
template = AUTO_FUNCTION

(Path(app.srcdir) / "index.rst").write_text(template.format(val.__name__))
app.config.__dict__.update(configs[conf_run])
app.config.__dict__.update(val.OPTIONS)
monkeypatch.setitem(sys.modules, "mod", sys.modules[__name__])
app.build()
Expand Down
4 changes: 3 additions & 1 deletion tests/test_sphinx_autodoc_typehints.py
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,9 @@ def test_sphinx_output_default_role(app: SphinxTestApp, status: StringIO) -> Non

assert "build succeeded" in status.getvalue() # Build succeeded

contents_lines = (Path(app.srcdir) / "_build/pseudoxml/simple_default_role.pseudoxml").read_text().splitlines()
contents_lines = (
(Path(app.srcdir) / "_build/pseudoxml/simple_default_role.pseudoxml").read_text(encoding="utf-8").splitlines()
)
list_item_idxs = [i for i, line in enumerate(contents_lines) if line.strip() == "<list_item>"]
foo_param = dedent("\n".join(contents_lines[list_item_idxs[0] : list_item_idxs[1]]))
expected_foo_param = """\
Expand Down

0 comments on commit 1fe6ed7

Please sign in to comment.