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

Commit 01ce65b

Browse files
authored
Merge branch 'master' into sections
2 parents 88c788e + 1011866 commit 01ce65b

File tree

6 files changed

+57
-16
lines changed

6 files changed

+57
-16
lines changed

docs/release_notes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ 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
* No longer emit D401 for sections at the start of docstrings (#556).
17+
* Replace D10X errors with D419 if docstring exists but is empty (#559).
1618

1719
6.1.1 - May 17th, 2021
1820
---------------------------

src/pydocstyle/checker.py

Lines changed: 46 additions & 8 deletions
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
)
@@ -196,12 +199,7 @@ def check_docstring_missing(self, definition, docstring):
196199
with a single underscore.
197200
198201
"""
199-
if (
200-
not docstring
201-
and definition.is_public
202-
or docstring
203-
and is_blank(ast.literal_eval(docstring))
204-
):
202+
if not docstring and definition.is_public:
205203
codes = {
206204
Module: violations.D100,
207205
Class: violations.D101,
@@ -227,6 +225,18 @@ def check_docstring_missing(self, definition, docstring):
227225
}
228226
return codes[type(definition)]()
229227

228+
@check_for(Definition, terminal=True)
229+
def check_docstring_empty(self, definition, docstring):
230+
"""D419: Docstring is empty.
231+
232+
If the user provided a docstring but it was empty, it is like they never provided one.
233+
234+
NOTE: This used to report as D10X errors.
235+
236+
"""
237+
if docstring and is_blank(ast.literal_eval(docstring)):
238+
return violations.D419()
239+
230240
@check_for(Definition)
231241
def check_one_liners(self, definition, docstring):
232242
"""D200: One-liner docstrings should fit on one line with quotes.
@@ -854,10 +864,38 @@ def _check_args_section(docstring, definition, context):
854864
* The section documents all function arguments (D417)
855865
except `self` or `cls` if it is a method.
856866
867+
Documentation for each arg should start at the same indentation
868+
level. For example, in this case x and y are distinguishable::
869+
870+
Args:
871+
x: Lorem ipsum dolor sit amet
872+
y: Ut enim ad minim veniam
873+
874+
In the case below, we only recognize x as a documented parameter
875+
because the rest of the content is indented as if it belongs
876+
to the description for x::
877+
878+
Args:
879+
x: Lorem ipsum dolor sit amet
880+
y: Ut enim ad minim veniam
857881
"""
858882
docstring_args = set()
859-
for line in context.following_lines:
860-
match = ConventionChecker.GOOGLE_ARGS_REGEX.match(line)
883+
# normalize leading whitespace
884+
args_content = dedent("\n".join(context.following_lines)).strip()
885+
886+
args_sections = []
887+
for line in args_content.splitlines(keepends=True):
888+
if not line[:1].isspace():
889+
# This line is the start of documentation for the next
890+
# parameter because it doesn't start with any whitespace.
891+
args_sections.append(line)
892+
else:
893+
# This is a continuation of documentation for the last
894+
# parameter because it does start with whitespace.
895+
args_sections[-1] += line
896+
897+
for section in args_sections:
898+
match = ConventionChecker.GOOGLE_ARGS_REGEX.match(section)
861899
if match:
862900
docstring_args.add(match.group(1))
863901
yield from ConventionChecker._check_missing_args(

src/pydocstyle/violations.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,10 @@ def to_rst(cls) -> str:
415415
'D418',
416416
'Function/ Method decorated with @overload shouldn\'t contain a docstring',
417417
)
418+
D419 = D4xx.create_error(
419+
'D419',
420+
'Docstring is empty',
421+
)
418422

419423

420424
class AttrDict(dict):

src/tests/test_cases/capitalization.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def not_capitalized():
1313

1414

1515
# Make sure empty docstrings don't generate capitalization errors.
16-
@expect("D103: Missing docstring in public function")
16+
@expect("D419: Docstring is empty")
1717
def empty_docstring():
1818
""""""
1919

src/tests/test_cases/sections.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -383,10 +383,7 @@ def test_missing_docstring(a, b): # noqa: D213, D407
383383
"""
384384

385385
@staticmethod
386-
@expect("D417: Missing argument descriptions in the docstring "
387-
"(argument(s) skip, verbose are missing descriptions in "
388-
"'test_missing_docstring_another' docstring)", arg_count=2)
389-
def test_missing_docstring_another(skip, verbose): # noqa: D213, D407
386+
def test_hanging_indent(skip, verbose): # noqa: D213, D407
390387
"""Do stuff.
391388
392389
Args:

src/tests/test_cases/test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
class class_:
1515

16-
expect('meta', 'D106: Missing docstring in public nested class')
16+
expect('meta', 'D419: Docstring is empty')
1717

1818
class meta:
1919
""""""
@@ -64,13 +64,13 @@ def __call__(self=None, x=None, y=None, z=None):
6464
pass
6565

6666

67-
@expect('D103: Missing docstring in public function')
67+
@expect('D419: Docstring is empty')
6868
def function():
6969
""" """
7070
def ok_since_nested():
7171
pass
7272

73-
@expect('D103: Missing docstring in public function')
73+
@expect('D419: Docstring is empty')
7474
def nested():
7575
''
7676

0 commit comments

Comments
 (0)