From 465085a7da0542d7e4288d9900a313a46da701a4 Mon Sep 17 00:00:00 2001 From: HardMax71 Date: Thu, 3 Sep 2026 17:36:38 +0200 Subject: [PATCH] google: parse docstrings that open with a section title (#115) --- docstring_parser/google.py | 6 ++++++ docstring_parser/tests/test_google.py | 31 +++++++++++++++++++++++++++ docstring_parser/tests/test_parser.py | 15 +++++++++++++ 3 files changed, 52 insertions(+) diff --git a/docstring_parser/google.py b/docstring_parser/google.py index d5e6499..6559584 100644 --- a/docstring_parser/google.py +++ b/docstring_parser/google.py @@ -215,6 +215,12 @@ def parse(self, text: T.Optional[str]) -> Docstring: if not text: return ret + # A title on the first line has no summary before it. Push it below + # one so that cleandoc dedents it with its entries instead of stripping + # only the first line and leaving the entries flush with the title. + if self.titles_re.match(text.lstrip()): + text = "\n" + text + # Clean according to PEP-0257 text = inspect.cleandoc(text) diff --git a/docstring_parser/tests/test_google.py b/docstring_parser/tests/test_google.py index 31ad746..3e87aa3 100644 --- a/docstring_parser/tests/test_google.py +++ b/docstring_parser/tests/test_google.py @@ -469,6 +469,37 @@ def test_params() -> None: assert docstring.params[1].description == "description 2" +def test_params_without_summary() -> None: + """Test parsing params when the docstring opens with the section title.""" + docstring = parse( + """Args: + name: description 1. + priority (int): description 2. + """ + ) + assert docstring.short_description is None + assert docstring.long_description is None + assert len(docstring.params) == 2 + assert docstring.params[0].arg_name == "name" + assert docstring.params[0].description == "description 1." + assert docstring.params[1].arg_name == "priority" + assert docstring.params[1].type_name == "int" + assert docstring.params[1].description == "description 2." + + +def test_returns_without_summary() -> None: + """Test parsing returns when the docstring opens with the section title.""" + docstring = parse( + """Returns: + int: description + """ + ) + assert docstring.short_description is None + assert docstring.returns is not None + assert docstring.returns.type_name == "int" + assert docstring.returns.description == "description" + + def test_attributes() -> None: """Test parsing attributes.""" docstring = parse("Short description") diff --git a/docstring_parser/tests/test_parser.py b/docstring_parser/tests/test_parser.py index e624976..5e6aecc 100644 --- a/docstring_parser/tests/test_parser.py +++ b/docstring_parser/tests/test_parser.py @@ -245,3 +245,18 @@ def test_autodetection_error_detection() -> None: assert docstring assert docstring.style == DocstringStyle.GOOGLE + + +def test_google_without_summary_is_detected() -> None: + """A Google docstring that opens with a section title must not fall + back to a REST parse with no params. + """ + docstring = parse( + """Args: + spam: description + """ + ) + assert docstring.style == DocstringStyle.GOOGLE + assert len(docstring.params) == 1 + assert docstring.params[0].arg_name == "spam" + assert docstring.params[0].description == "description"