Skip to content

Commit

Permalink
feat: Add option to read return type of properties in their summary
Browse files Browse the repository at this point in the history
Issue #137: #137
PR #206: #206
  • Loading branch information
pawamoy authored Sep 1, 2023
1 parent b0620f8 commit 096970f
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 25 deletions.
33 changes: 8 additions & 25 deletions docs/docstrings.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,19 @@ def foo(a, b):
The parser accepts a few options:

- `ignore_init_summary`: Ignore the first line in `__init__` methods' docstrings.
Useful when merging `__init__` docstring into class' docstrings
Useful when merging `__init__` docstring into class' docstrings. Default: false.
with mkdocstrings-python's [`merge_init_into_class`][merge_init] option. Default: false.
- `trim_doctest_flags`: Remove the [doctest flags][] written as comments in `pycon` snippets within a docstring.
These flags are used to alter the behavior of [doctest][] when testing docstrings,
and should not be visible in your docs. Default: true.
- `warn_unknown_params`: Warn about parameters documented in docstrings that do not appear in the signature. Default: true.
- `returns_multiple_items`: Parse [Returns sections](#returns) as if they contain multiple items.
It means that continuation lines must be indented. Default: true.
- `returns_named_value`: Whether to parse `thing: Description` in [Returns sections](#returns) as a name and description,
rather than a type and description. When true, type must be wrapped in parentheses: `(int): Description.`.
When false, parentheses are optional but the items cannot be named: `int: Description`.

When false, parentheses are optional but the items cannot be named: `int: Description`. Default: true.
- `returns_type_in_property_summary`: Whether to parse the return type of properties
at the beginning of their summary: `str: Summary of the property`. Default: false.
- `trim_doctest_flags`: Remove the [doctest flags][] written as comments in `pycon` snippets within a docstring.
These flags are used to alter the behavior of [doctest][] when testing docstrings,
and should not be visible in your docs. Default: true.
- `warn_unknown_params`: Warn about parameters documented in docstrings that do not appear in the signature. Default: true.

#### Attributes

Expand Down Expand Up @@ -1575,21 +1576,3 @@ Returns | ✅ | ✅ | [❌][issue-xref-sphinx-returns]
[issue-xref-sphinx-yields]: https://github.com/mkdocstrings/griffe/issues/26
[issue-xref-numpy-func-cls]: https://github.com/mkdocstrings/griffe/issues/200
[issue-xref-google-func-cls]: https://github.com/mkdocstrings/griffe/issues/199

### Parsing options

Option | Description | Google | Numpy | Sphinx
-------------------------- | ----------------------------------------- | ------ | ----- | ------
`ignore_init_summary` | Ignore `__init__` summary. | ✅ | ✅ | [][issue-ignore-init-summary-sphinx]
`trim_doctest_flags` | Trim doctest flags. | ✅ | ✅ | [][issue-trim-doctest-flags-sphinx]
`warn_unknown_params` | Warn about unknown params. | ✅ | ✅ | [][issue-warn-unknown-params-sphinx]
`allow_section_blank_line` | Allow blank line in sections. | / | ✅ | /
`returns_multiple_items` | Parse multiple items in Returns sections. | ✅ | / | /

[issue-ignore-init-summary-sphinx]: https://github.com/mkdocstrings/griffe/issues/45
[issue-trim-doctest-flags-sphinx]: https://github.com/mkdocstrings/griffe/issues/49
[issue-warn-unknown-params-sphinx]: https://github.com/mkdocstrings/griffe/issues/64

[merge_init]: https://mkdocstrings.github.io/python/usage/configuration/docstrings/#merge_init_into_class
[doctest flags]: https://docs.python.org/3/library/doctest.html#option-flags
[doctest]: https://docs.python.org/3/library/doctest.html#module-doctest
22 changes: 22 additions & 0 deletions src/griffe/docstrings/google.py
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,7 @@ def parse(
returns_multiple_items: bool = True,
warn_unknown_params: bool = True,
returns_named_value: bool = True,
returns_type_in_property_summary: bool = False,
**options: Any,
) -> list[DocstringSection]:
"""Parse a docstring.
Expand All @@ -715,6 +716,8 @@ def parse(
returns_named_value: Whether to parse `thing: Description` in returns sections as a name and description,
rather than a type and description. When true, type must be wrapped in parentheses: `(int): Description.`.
When false, parentheses are optional but the items cannot be named: `int: Description`.
returns_type_in_property_summary: Whether to parse the return type of properties
at the beginning of their summary: `str: Summary of the property`.
**options: Additional parsing options.
Returns:
Expand All @@ -732,6 +735,7 @@ def parse(
"returns_multiple_items": returns_multiple_items,
"warn_unknown_params": warn_unknown_params,
"returns_named_value": returns_named_value,
"returns_type_in_property_summary": returns_type_in_property_summary,
**options,
}

Expand Down Expand Up @@ -829,6 +833,24 @@ def parse(
if current_section:
sections.append(DocstringSectionText("\n".join(current_section).rstrip("\n")))

if (
returns_type_in_property_summary
and sections
and docstring.parent
and docstring.parent.is_attribute
and "property" in docstring.parent.labels
):
lines = sections[0].value.lstrip().split("\n")
if ":" in lines[0]:
annotation, line = lines[0].split(":", 1)
lines = [line, *lines[1:]]
sections[0].value = "\n".join(lines)
sections.append(
DocstringSectionReturns(
[DocstringReturn("", description="", annotation=parse_annotation(annotation, docstring))],
),
)

return sections


Expand Down
19 changes: 19 additions & 0 deletions tests/test_docstrings/test_google.py
Original file line number Diff line number Diff line change
Expand Up @@ -1477,3 +1477,22 @@ def test_type_in_returns_without_parentheses(parse_google: ParserType) -> None:
assert retval.name == ""
assert retval.annotation is None
assert retval.description == "Description\non several lines."


def test_reading_property_type_in_summary(parse_google: ParserType) -> None:
"""Assert we can parse the return type of properties in their summary.
Parameters:
parse_google: Fixture parser.
"""
docstring = "str: Description of the property."
parent = Attribute("prop")
parent.labels.add("property")
sections, warnings = parse_google(docstring, returns_type_in_property_summary=True, parent=parent)
assert len(sections) == 2
assert sections[0].kind is DocstringSectionKind.text
assert sections[1].kind is DocstringSectionKind.returns
retval = sections[1].value[0]
assert retval.name == ""
assert retval.annotation.name == "str"
assert retval.description == ""

0 comments on commit 096970f

Please sign in to comment.