Skip to content

Commit

Permalink
Fix napoleon handling of numpy docstrings with no explicitly provided…
Browse files Browse the repository at this point in the history
… return type (#311)
  • Loading branch information
hoodmane authored Jan 20, 2023
1 parent 53f7f00 commit 3aca67b
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 0 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 1.21.7

- Fixed a bug where if a class has an attribute and a constructor argument with the same name, the constructor argument
type would be rendered incorrectly (issue 308)

- Fixed napoleon handling of numpy docstrings with no specified return type.

## 1.21.6

- Fix a `Field list ends without a blank line` warning (issue 305).
Expand Down
42 changes: 42 additions & 0 deletions src/sphinx_autodoc_typehints/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,44 @@ def fix_autodoc_typehints_for_overloaded_methods() -> None:
del MethodDocumenter.format_signature


def napoleon_numpy_docstring_return_type_processor(
app: Sphinx, what: str, name: str, obj: Any, options: Options | None, lines: list[str] # noqa: U100
) -> None:
"""Insert a : under Returns: to tell napoleon not to look for a return type."""
if what not in ["function", "method"]:
return
if not getattr(app.config, "napoleon_numpy_docstring", False):
return

# Search for the returns header:
# Returns:
# --------
for idx, line in enumerate(lines[:-2]):
if line.lower().strip(":") not in ["return", "returns"]:
continue
# Underline detection.
chars = set(lines[idx + 1].strip())
# Napoleon allows the underline to consist of a bunch of weirder things...
if len(chars) != 1 or list(chars)[0] not in "=-~_*+#":
continue
idx = idx + 2
break
else:
return

lines.insert(idx, ":")


def fix_napoleon_numpy_docstring_return_type(app: Sphinx) -> None:
"""
If no return type is explicitly provided, numpy docstrings will mess up and
use the return type text as return types.
"""
# standard priority is 500. Setting priority to 499 ensures this runs before
# napoleon's docstring processor.
app.connect("autodoc-process-docstring", napoleon_numpy_docstring_return_type_processor, priority=499)


def patched_lookup_annotation(*_args: Any) -> str: # noqa: U101
"""GoogleDocstring._lookup_annotation sometimes adds incorrect type
annotations to constructor parameters (and otherwise does nothing). Disable
Expand All @@ -818,6 +856,9 @@ def patched_lookup_annotation(*_args: Any) -> str: # noqa: U101


def patch_google_docstring_lookup_annotation() -> None:
"""Fix issue 308:
https://github.com/tox-dev/sphinx-autodoc-typehints/issues/308
"""
GoogleDocstring._lookup_annotation = patched_lookup_annotation # type: ignore[assignment]


Expand All @@ -837,6 +878,7 @@ def setup(app: Sphinx) -> dict[str, bool]:
fix_autodoc_typehints_for_overloaded_methods()
patch_attribute_handling(app)
patch_google_docstring_lookup_annotation()
fix_napoleon_numpy_docstring_return_type(app)
return {"parallel_read_safe": True}


Expand Down
58 changes: 58 additions & 0 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,64 @@ def __init__(self, blah: CodeType): # noqa: U100
"""Description of attribute blah"""


@expected(
"""
mod.napoleon_returns()
A function.
Return type:
"CodeType"
Returns:
The info about the whatever.
"""
)
def napoleon_returns() -> CodeType:
"""
A function.
Returns
-------
The info about the whatever.
"""


@expected(
"""
mod.google_docstrings(arg1, arg2)
Summary line.
Extended description of function.
Parameters:
* **arg1** ("CodeType") -- Description of arg1
* **arg2** ("ModuleType") -- Description of arg2
Return type:
"CodeType"
Returns:
Description of return value
"""
)
def google_docstrings(arg1: CodeType, arg2: ModuleType) -> CodeType: # noqa: U100
"""Summary line.
Extended description of function.
Args:
arg1: Description of arg1
arg2: Description of arg2
Returns:
Description of return value
"""


AUTO_FUNCTION = ".. autofunction:: mod.{}"
AUTO_CLASS = """\
.. autoclass:: mod.{}
Expand Down
4 changes: 4 additions & 0 deletions whitelist.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
addnodes
arg1
arg2
ast3
astext
autodoc
Expand All @@ -14,6 +16,7 @@ delattr
desc
dirname
docnames
docstrings
Documenter
docutils
dunder
Expand Down Expand Up @@ -41,6 +44,7 @@ metaclass
ModuleType
multiline
newtype
numpy
nptyping
param
parametrized
Expand Down

0 comments on commit 3aca67b

Please sign in to comment.