From 096970ffa66f491ef34ae1121e8b907f2da4c742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Fri, 1 Sep 2023 19:40:46 +0200 Subject: [PATCH] feat: Add option to read return type of properties in their summary Issue #137: https://github.com/mkdocstrings/griffe/issues/137 PR #206: https://github.com/mkdocstrings/griffe/pull/206 --- docs/docstrings.md | 33 +++++++--------------------- src/griffe/docstrings/google.py | 22 +++++++++++++++++++ tests/test_docstrings/test_google.py | 19 ++++++++++++++++ 3 files changed, 49 insertions(+), 25 deletions(-) diff --git a/docs/docstrings.md b/docs/docstrings.md index 1e620e52..31707935 100644 --- a/docs/docstrings.md +++ b/docs/docstrings.md @@ -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 @@ -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 diff --git a/src/griffe/docstrings/google.py b/src/griffe/docstrings/google.py index 9074f785..84a55da5 100644 --- a/src/griffe/docstrings/google.py +++ b/src/griffe/docstrings/google.py @@ -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. @@ -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: @@ -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, } @@ -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 diff --git a/tests/test_docstrings/test_google.py b/tests/test_docstrings/test_google.py index 3f761892..201a7507 100644 --- a/tests/test_docstrings/test_google.py +++ b/tests/test_docstrings/test_google.py @@ -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 == ""