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

fix(checker): allow whitespace before inner functions and class #426

Merged
merged 3 commits into from
Nov 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ Bug Fixes
* Fix decorator parsing (#411).
* Google-style sections no longer cause false errors when used with
Numpy-style sections (#388, #424).
* D202: Allow a blank line after function docstring when followed by
declaration of an inner function or class (#395, #426).
* Fix D401 and D404 checks not working for docstrings containing only one word and ending with non-alpha character (#421)

4.0.1 - August 14th, 2019
Expand All @@ -48,7 +50,6 @@ Bug Fixes
the violation code table (#396).
* Fixed IndentationError when parsing function arguments (#392).


4.0.0 - July 6th, 2019
----------------------

Expand Down
17 changes: 12 additions & 5 deletions src/pydocstyle/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ def check_one_liners(self, definition, docstring):
def check_no_blank_before(self, function, docstring): # def
"""D20{1,2}: No blank lines allowed around function/method docstring.
There's no blank line either before or after the docstring.
There's no blank line either before or after the docstring unless directly
followed by an inner function or class.
"""
if docstring:
before, _, after = function.source.partition(docstring)
Expand All @@ -198,7 +198,14 @@ def check_no_blank_before(self, function, docstring): # def
if blanks_before_count != 0:
yield violations.D201(blanks_before_count)
if not all(blanks_after) and blanks_after_count != 0:
yield violations.D202(blanks_after_count)
# Report a D202 violation if the docstring is followed by a blank line
# and the blank line is not itself followed by an inner function or
# class.
if not (
johanfleury marked this conversation as resolved.
Show resolved Hide resolved
blanks_after_count == 1 and
re(r"\s+(?:(?:class|def)\s|@)").match(after)
):
yield violations.D202(blanks_after_count)

@check_for(Class)
def check_blank_before_after_class(self, class_, docstring):
Expand Down Expand Up @@ -976,15 +983,15 @@ def is_ascii(string):

def leading_space(string):
"""Return any leading space from `string`."""
return re('\s*').match(string).group()
return re(r'\s*').match(string).group()


def get_leading_words(line):
"""Return any leading set of words from `line`.
For example, if `line` is " Hello world!!!", returns "Hello world".
"""
result = re("[\w ]+").match(line.strip())
result = re(r"[\w ]+").match(line.strip())
if result is not None:
return result.group()

Expand Down
53 changes: 53 additions & 0 deletions src/tests/test_cases/functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""A valid module docstrings."""

from .expected import Expectation

expectation = Expectation()
expect = expectation.expect


@expect("D201: No blank lines allowed before function docstring (found 1)")
def func_with_space_before():

"""Test a function with space before docstring."""
pass


@expect("D202: No blank lines allowed after function docstring (found 1)")
def func_with_space_after():
"""Test a function with space after docstring."""

pass


def func_with_inner_func_after():
"""Test a function with inner function after docstring."""

def inner():
pass

pass


def fake_decorator(decorated):
"""Fake decorator used to test decorated inner func."""
return decorated


def func_with_inner_decorated_func_after():
"""Test a function with inner decorated function after docstring."""

@fake_decorator
def inner():
pass

pass


def func_with_inner_class_after():
"""Test a function with inner class after docstring."""

class inner():
pass

pass
1 change: 1 addition & 0 deletions src/tests/test_definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
'superfluous_quotes',
'noqa',
'sections',
'functions',
'canonical_google_examples',
'canonical_numpy_examples',
'canonical_pep257_examples',
Expand Down