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

Commit 485888a

Browse files
sambhavNurdok
authored andcommitted
Add support for methods for Google style arg check (#384)
This patch adds support for checking the Args section of methods.
1 parent 32d5519 commit 485888a

File tree

8 files changed

+101
-28
lines changed

8 files changed

+101
-28
lines changed

docs/error_codes.rst

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,19 @@ Grouping
99
Default conventions
1010
-------------------
1111

12-
Not all error codes are checked for by default. There are two
13-
conventions that may be used by pydocstyle: pep257 and numpy.
12+
Not all error codes are checked for by default. There are three
13+
conventions that may be used by pydocstyle: pep257, numpy and google.
1414

1515
The pep257 convention, which is enabled by default in pydocstyle,
1616
checks for all of the above errors except for D203, D212, D213, D214,
17-
D215, D404, D405, D406, D407, D408, D409, D410, and D411 (as specified
18-
in `PEP257 <http://www.python.org/dev/peps/pep-0257/>`_).
17+
D215, D404, D405, D406, D407, D408, D409, D410, D411, D415, D416 and D417
18+
(as specified in `PEP257 <http://www.python.org/dev/peps/pep-0257/>`_).
1919

2020
The numpy convention checks for all of the above errors except for
21-
D107, D203, D212, D213, D402, and D413.
21+
D107, D203, D212, D213, D402, D413, D415, D416 and D417.
22+
23+
The google convention checks for all of the above errors except for
24+
D203, D204, D213, D215, D400, D401, D404, D406, D407, D408 and D409.
2225

2326
These conventions may be specified using `--convention=<name>` when
2427
running pydocstyle from the command line or by specifying the

docs/release_notes.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ Release Notes
44
**pydocstyle** version numbers follow the
55
`Semantic Versioning <http://semver.org/>`_ specification.
66

7+
Current Development Version
8+
---------------------------
9+
10+
New Features
11+
12+
* Extend support for detecting missing arguments in Google style
13+
docstrings to method calls (#384).
14+
715
4.0.1 - August 14th, 2019
816
-------------------------
917

docs/snippets/cli.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Usage
5454
--convention=<name>
5555
choose the basic list of checked errors by specifying
5656
an existing convention. Possible conventions: pep257,
57-
numpy.
57+
numpy, google.
5858
--add-select=<codes>
5959
add extra error codes to check to the basic list of
6060
errors previously set by --select, --ignore or

src/pydocstyle/checker.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -682,16 +682,21 @@ def _check_args_section(docstring, definition, context):
682682
except `self` or `cls` if it is a method.
683683
684684
"""
685-
if definition.kind == 'function':
686-
function_pos_args = get_function_args(definition.source)
687-
docstring_args = set()
688-
for line in context.following_lines:
689-
match = ConventionChecker.GOOGLE_ARGS_REGEX.match(line)
690-
if match:
691-
docstring_args.add(match.group(1))
692-
missing_args = function_pos_args - docstring_args
693-
if missing_args:
694-
yield violations.D417(", ".join(missing_args), definition.name)
685+
docstring_args = set()
686+
for line in context.following_lines:
687+
match = ConventionChecker.GOOGLE_ARGS_REGEX.match(line)
688+
if match:
689+
docstring_args.add(match.group(1))
690+
function_args = get_function_args(definition.source)
691+
# If the method isn't static, then we skip the first
692+
# positional argument as it is `cls` or `self`
693+
if definition.kind == 'method' and not definition.is_static:
694+
function_args = function_args[1:]
695+
missing_args = set(function_args) - docstring_args
696+
if missing_args:
697+
yield violations.D417(", ".join(sorted(missing_args)),
698+
definition.name)
699+
695700

696701
@classmethod
697702
def _check_google_section(cls, docstring, definition, context):
@@ -921,4 +926,4 @@ def get_function_args(function_string):
921926
function_arg_node = ast.parse(textwrap.dedent(function_string)).body[0].args
922927
arg_nodes = function_arg_node.args
923928
kwonly_arg_nodes = function_arg_node.kwonlyargs
924-
return set(arg_node.arg for arg_node in chain(arg_nodes, kwonly_arg_nodes))
929+
return [arg_node.arg for arg_node in chain(arg_nodes, kwonly_arg_nodes)]

src/pydocstyle/parser.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,13 @@ def is_public(self):
181181
self.is_magic)
182182
return self.parent.is_public and name_is_public
183183

184+
@property
185+
def is_static(self):
186+
for decorator in self.decorators:
187+
if decorator.name == "staticmethod":
188+
return True
189+
return False
190+
184191

185192
class Class(Definition):
186193
"""A Python source code class."""

src/pydocstyle/violations.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,8 @@ def to_rst(cls) -> str:
252252
'mark, or exclamation point', 'not {0!r}')
253253
D416 = D4xx.create_error('D416', 'Section name should end with a semicolon',
254254
'{0!r}, not {1!r}')
255-
D417 = D4xx.create_error('D417', 'Missing arguments in the function docstring',
256-
'argument(s) {0!r} missing in function {1!r} docstring')
255+
D417 = D4xx.create_error('D417', 'Missing arguments in the docstring',
256+
'argument(s) {0!r} missing in {1!r} docstring')
257257

258258
class AttrDict(dict):
259259
def __getattr__(self, item: str) -> Any:

src/tests/test_cases/expected.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ class Expectation:
44
def __init__(self):
55
self.expected = set()
66

7-
def expect(self, *args):
7+
def expect(self, *args, arg_count=0):
88
"""Decorator that expects a certain PEP 257 violation."""
9-
def none(_):
10-
return None
11-
9+
# The `arg_count` parameter helps the decorator
10+
# with functions that have positional arguments.
1211
if len(args) == 1:
13-
return lambda f: (self.expected.add((f.__name__, args[0])) or
14-
none(f()) or f)
12+
def decorate(f):
13+
self.expected.add((f.__name__, args[0]))
14+
f(*[None]*arg_count)
15+
return f
16+
return decorate
1517
self.expected.add(args)

src/tests/test_cases/sections.py

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,13 +275,61 @@ def missing_colon_google_style_section(): # noqa: D406, D407
275275

276276

277277
@expect(_D213)
278-
@expect("D417: Missing arguments in the function docstring "
279-
"(argument(s) 'y' missing in function "
278+
@expect("D417: Missing arguments in the docstring "
279+
"(argument(s) 'y' missing in "
280280
"'test_missing_args' docstring)")
281-
def test_missing_args(x=1, y=2): # noqa: D407, D407
281+
def test_missing_args(x=1, y=2): # noqa: D406, D407
282282
"""Toggle the gizmo.
283283
284284
Args:
285285
x (int): The greatest integer.
286286
287287
"""
288+
289+
290+
class Test: # noqa: D203
291+
"""Test class."""
292+
293+
def test_method(self, test, another_test): # noqa: D213, D407
294+
"""Test a valid args section.
295+
296+
Args:
297+
test: A parameter.
298+
another_test: Another parameter.
299+
300+
"""
301+
302+
@expect("D417: Missing arguments in the docstring "
303+
"(argument(s) 'test, y, z' missing in "
304+
"'test_missing_args' docstring)", arg_count=4)
305+
def test_missing_args(self, test, x, y, z=3): # noqa: D213, D407
306+
"""Test a valid args section.
307+
308+
Args:
309+
x: Another parameter.
310+
311+
"""
312+
313+
@classmethod
314+
@expect("D417: Missing arguments in the docstring "
315+
"(argument(s) 'test, y, z' missing in "
316+
"'test_missing_args_class_method' docstring)", arg_count=4)
317+
def test_missing_args_class_method(cls, test, x, y, z=3): # noqa: D213, D407
318+
"""Test a valid args section.
319+
320+
Args:
321+
x: Another parameter.
322+
323+
"""
324+
325+
@staticmethod
326+
@expect("D417: Missing arguments in the docstring "
327+
"(argument(s) 'a, y, z' missing in "
328+
"'test_missing_args_static_method' docstring)", arg_count=3)
329+
def test_missing_args_static_method(a, x, y, z=3): # noqa: D213, D407
330+
"""Test a valid args section.
331+
332+
Args:
333+
x: Another parameter.
334+
335+
"""

0 commit comments

Comments
 (0)