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

Allow for hanging indent when documenting args in Google style #564

Merged
merged 13 commits into from Dec 30, 2021
1 change: 1 addition & 0 deletions docs/release_notes.rst
Expand Up @@ -10,6 +10,7 @@ Current Development Version

New Features

* Allow for hanging indent when documenting args in Google style. (#449)
* Add support for `property_decorators` config to ignore D401.
* Add support for Python 3.10 (#554).

Expand Down
2 changes: 1 addition & 1 deletion requirements/tests.txt
@@ -1,4 +1,4 @@
pytest==6.2.5
mypy==0.782
black==20.8b1
black==21.10b0
isort==5.4.2
35 changes: 33 additions & 2 deletions src/pydocstyle/checker.py
Expand Up @@ -6,6 +6,7 @@
from collections import namedtuple
from itertools import chain, takewhile
from re import compile as re
from textwrap import dedent

from . import violations
from .config import IllegalConfiguration
Expand Down Expand Up @@ -122,6 +123,8 @@ class ConventionChecker:
r"\s*"
# Followed by a colon
r":"
# Might have a new line and leading whitespace
r"\n?\s*"
# Followed by 1 or more characters - which is the docstring for the parameter
".+"
)
Expand Down Expand Up @@ -836,10 +839,38 @@ def _check_args_section(docstring, definition, context):
* The section documents all function arguments (D417)
except `self` or `cls` if it is a method.

Documentation for each arg should start at the same indentation
level. For example, in this case x and y are distinguishable::

Args:
x: Lorem ipsum dolor sit amet
y: Ut enim ad minim veniam

In the case below, we only recognize x as a documented parameter
because the rest of the content is indented as if it belongs
to the description for x::

Args:
x: Lorem ipsum dolor sit amet
y: Ut enim ad minim veniam
"""
docstring_args = set()
for line in context.following_lines:
match = ConventionChecker.GOOGLE_ARGS_REGEX.match(line)
# normalize leading whitespace
args_content = dedent("\n".join(context.following_lines)).strip()

args_sections = []
for line in args_content.splitlines(keepends=True):
if not line[:1].isspace():
# This line is the start of documentation for the next
# parameter because it doesn't start with any whitespace.
args_sections.append(line)
else:
# This is a continuation of documentation for the last
# parameter because it does start with whitespace.
args_sections[-1] += line

for section in args_sections:
match = ConventionChecker.GOOGLE_ARGS_REGEX.match(section)
if match:
docstring_args.add(match.group(1))
yield from ConventionChecker._check_missing_args(
Expand Down
3 changes: 0 additions & 3 deletions src/tests/test_cases/sections.py
Expand Up @@ -367,9 +367,6 @@ def test_missing_docstring(a, b): # noqa: D213, D407
"""

@staticmethod
@expect("D417: Missing argument descriptions in the docstring "
"(argument(s) skip, verbose are missing descriptions in "
"'test_missing_docstring_another' docstring)", arg_count=2)
def test_missing_docstring_another(skip, verbose): # noqa: D213, D407
samj1912 marked this conversation as resolved.
Show resolved Hide resolved
"""Do stuff.

Expand Down