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

Return injection fix #445

Merged
merged 3 commits into from
Apr 10, 2024
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
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
97 changes: 92 additions & 5 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -1268,14 +1268,100 @@ 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,
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 +1371,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