Skip to content

Commit

Permalink
Fix #7868: Added lint check for a newline above args in python doc st…
Browse files Browse the repository at this point in the history
…ring (#7929)

* Added lint check for newline above args

* Added more tests

* Added lint check for newline above args

* Split test in modules
  • Loading branch information
Hudda authored and kevinlee12 committed Nov 12, 2019
1 parent 4dd489d commit cb99e89
Show file tree
Hide file tree
Showing 2 changed files with 405 additions and 2 deletions.
81 changes: 79 additions & 2 deletions scripts/pylint_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,6 @@ def check_single_constructor_params(self, class_doc, init_doc, class_node):
"""Checks whether a class and corresponding init() method are
documented. If both of them are documented, it adds an error message.
Args:
class_doc: Docstring. Pylint docstring class instance representing
a class's docstring.
Expand All @@ -658,6 +657,7 @@ def check_single_constructor_params(self, class_doc, init_doc, class_node):
def _handle_no_raise_doc(self, excs, node):
"""Checks whether the raised exception in a function has been
documented, add a message otherwise.
Args:
excs: list(str). A list of exception types.
node: astroid.scoped_nodes.Function. Node to access module content.
Expand Down Expand Up @@ -1010,7 +1010,6 @@ def process_module(self, node):

if file_content[line_num] == b'\n':
blank_line_counter += 1

else:
blank_line_counter = 0

Expand All @@ -1020,6 +1019,83 @@ def process_module(self, node):
self.add_message('excessive-new-lines', line=line_num + 1)


class SingleNewlineAboveArgsChecker(checkers.BaseChecker):
"""Checker for single space above args in python doc string."""

__implements__ = interfaces.IRawChecker
name = 'single-space-above-args-raises-returns'
priority = -1
msgs = {
'C0012': (
'Files must have a single newline above args in doc string.',
'single-space-above-args',
'Please enter a single newline above args in doc string.'
),
'C0013': (
'Files must have a single newline above returns in doc string.',
'single-space-above-returns',
'Please enter a single newline above returns in doc string.'
),
'C0014': (
'Files must have a single newline above raises in doc string.',
'single-space-above-raises',
'Please enter a single newline above raises in doc string.'
)
}

def process_module(self, node):
"""Process a module to ensure that there is a single newline above args,
raises, returns in python doc string.
Args:
node: astroid.scoped_nodes.Function. Node to access module content.
"""

in_multi_line_comment = False
multi_line_indicator = b'"""'
file_content = read_from_node(node)
file_length = len(file_content)
blank_line_counter = 0

for line_num in python_utils.RANGE(file_length):
line = file_content[line_num].strip()

# Single multi-line comment, ignore it.
if line.count(multi_line_indicator) == 2:
continue

# Flip multi-line boolean depending on whether or not we see
# the multi-line indicator. Possible for multiline comment to
# be somewhere other than the start of a line (e.g. func arg),
# so we can't look at start of or end of a line, which is why
# the case where two indicators in a single line is handled
# separately (i.e. one line comment with multi-line strings).
if multi_line_indicator in line:
in_multi_line_comment = not in_multi_line_comment

# Ignore anything inside a multi-line comment.
if in_multi_line_comment:
continue

if file_content[line_num] == b'\n':
blank_line_counter += 1
else:
blank_line_counter = 0

if (line_num + 1 < file_length and (
blank_line_counter == 0 or blank_line_counter > 1)):
line = file_content[line_num + 1].strip()
if line == b'Args:':
self.add_message(
'single-space-above-args', line=line_num + 1)
elif line == b'Returns:':
self.add_message(
'single-space-above-returns', line=line_num + 1)
elif line == b'Raises:':
self.add_message(
'single-space-above-raises', line=line_num + 1)


def register(linter):
"""Registers the checker with pylint.
Expand All @@ -1036,3 +1112,4 @@ def register(linter):
linter.register_checker(SingleCharAndNewlineAtEOFChecker(linter))
linter.register_checker(SingleSpaceAfterYieldChecker(linter))
linter.register_checker(ExcessiveEmptyLinesChecker(linter))
linter.register_checker(SingleNewlineAboveArgsChecker(linter))
Loading

0 comments on commit cb99e89

Please sign in to comment.