Skip to content
This repository was archived by the owner on Nov 3, 2023. It is now read-only.

Commit 1011866

Browse files
rmorsheaRyan Morsheadsambhav
authored
Allow for hanging indent when documenting args in Google style (#564)
Co-authored-by: Ryan Morshead <[email protected]> Co-authored-by: Sambhav Kothari <[email protected]>
1 parent 8dee619 commit 1011866

File tree

3 files changed

+35
-6
lines changed

3 files changed

+35
-6
lines changed

docs/release_notes.rst

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Current Development Version
1010

1111
New Features
1212

13+
* Allow for hanging indent when documenting args in Google style. (#449)
1314
* Add support for `property_decorators` config to ignore D401.
1415
* Add support for Python 3.10 (#554).
1516
* Replace D10X errors with D419 if docstring exists but is empty (#559).

src/pydocstyle/checker.py

+33-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from collections import namedtuple
77
from itertools import chain, takewhile
88
from re import compile as re
9+
from textwrap import dedent
910

1011
from . import violations
1112
from .config import IllegalConfiguration
@@ -122,6 +123,8 @@ class ConventionChecker:
122123
r"\s*"
123124
# Followed by a colon
124125
r":"
126+
# Might have a new line and leading whitespace
127+
r"\n?\s*"
125128
# Followed by 1 or more characters - which is the docstring for the parameter
126129
".+"
127130
)
@@ -843,10 +846,38 @@ def _check_args_section(docstring, definition, context):
843846
* The section documents all function arguments (D417)
844847
except `self` or `cls` if it is a method.
845848
849+
Documentation for each arg should start at the same indentation
850+
level. For example, in this case x and y are distinguishable::
851+
852+
Args:
853+
x: Lorem ipsum dolor sit amet
854+
y: Ut enim ad minim veniam
855+
856+
In the case below, we only recognize x as a documented parameter
857+
because the rest of the content is indented as if it belongs
858+
to the description for x::
859+
860+
Args:
861+
x: Lorem ipsum dolor sit amet
862+
y: Ut enim ad minim veniam
846863
"""
847864
docstring_args = set()
848-
for line in context.following_lines:
849-
match = ConventionChecker.GOOGLE_ARGS_REGEX.match(line)
865+
# normalize leading whitespace
866+
args_content = dedent("\n".join(context.following_lines)).strip()
867+
868+
args_sections = []
869+
for line in args_content.splitlines(keepends=True):
870+
if not line[:1].isspace():
871+
# This line is the start of documentation for the next
872+
# parameter because it doesn't start with any whitespace.
873+
args_sections.append(line)
874+
else:
875+
# This is a continuation of documentation for the last
876+
# parameter because it does start with whitespace.
877+
args_sections[-1] += line
878+
879+
for section in args_sections:
880+
match = ConventionChecker.GOOGLE_ARGS_REGEX.match(section)
850881
if match:
851882
docstring_args.add(match.group(1))
852883
yield from ConventionChecker._check_missing_args(

src/tests/test_cases/sections.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -367,10 +367,7 @@ def test_missing_docstring(a, b): # noqa: D213, D407
367367
"""
368368

369369
@staticmethod
370-
@expect("D417: Missing argument descriptions in the docstring "
371-
"(argument(s) skip, verbose are missing descriptions in "
372-
"'test_missing_docstring_another' docstring)", arg_count=2)
373-
def test_missing_docstring_another(skip, verbose): # noqa: D213, D407
370+
def test_hanging_indent(skip, verbose): # noqa: D213, D407
374371
"""Do stuff.
375372
376373
Args:

0 commit comments

Comments
 (0)