Skip to content

Commit

Permalink
Add allow_missing_func_desc
Browse files Browse the repository at this point in the history
when this option in set to ``True``
this will ignore the warning.
Allowing docstrings to start with params.
Add setting ``indent_size``.
Add subsequent test case.
  • Loading branch information
damngamerz committed Jun 13, 2017
1 parent 49200f4 commit 7ad62fb
Show file tree
Hide file tree
Showing 15 changed files with 209 additions and 64 deletions.
29 changes: 22 additions & 7 deletions bears/documentation/DocumentationStyleBear.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ class DocumentationStyleBear(LocalBear):
LICENSE = 'AGPL-3.0'
ASCIINEMA_URL = 'https://asciinema.org/a/7sfk3i9oxs1ixg2ncsu3pym0u'
CAN_DETECT = {'Documentation'}
CAN_FIX = {'Documentation'}

def run(self, filename, file, language: str, docstyle: str='default'):
def run(self, filename, file, language: str,
docstyle: str='default', allow_missing_func_desc: str=False,
indent_size: int=4):
"""
Checks for certain in-code documentation styles.
Expand All @@ -38,6 +41,10 @@ def run(self, filename, file, language: str, docstyle: str='default'):
:param docstyle: The docstyle to use. For example ``default`` or
``doxygen``. Docstyles are language dependent, meaning
not every language is supported by a certain docstyle.
:param allow_missing_func_desc: When set ``True`` this will allow
functions with missing descriptions, allowing
functions to start with params.
:param indent_size: Number of spaces per indentation level.
"""
for doc_comment in extract_documentation(file, language, docstyle):
parsed = doc_comment.parse()
Expand All @@ -47,8 +54,16 @@ def run(self, filename, file, language: str, docstyle: str='default'):
# description.
main_description = next(metadata)

# 1 empty line shall follow main description (except it's empty or
# no annotations follow).
if main_description.desc == '\n' and not allow_missing_func_desc:
warning_desc = """
Missing function description.
Please set allow_missing_func_desc = True to ignore this warning.
"""
else:
warning_desc = 'Documentation does not have correct style.'

# one empty line shall follow main description (except it's empty
# or no annotations follow).
if main_description.desc.strip() != '':
main_description = main_description._replace(
desc='\n' + main_description.desc.strip() + '\n' *
Expand All @@ -70,13 +85,13 @@ def run(self, filename, file, language: str, docstyle: str='default'):
stripped_desc.insert(0, '')

# Indent with 4 spaces.
stripped_desc = ('' if line == '' else ' ' * 4 + line for line
in stripped_desc)
stripped_desc = ('' if line == '' else ' ' * indent_size
+ line for line in stripped_desc)

new_desc = '\n'.join(stripped_desc)

# Strip away trailing whitespaces and obsolete newlines (except
# 1 newline which is mandatory).
# one newline which is mandatory).
new_desc = new_desc.rstrip() + '\n'

new_metadata.append(m._replace(desc=new_desc.lstrip(' ')))
Expand All @@ -100,6 +115,6 @@ def run(self, filename, file, language: str, docstyle: str='default'):

yield Result(
origin=self,
message='Documentation does not have correct style.',
message=warning_desc,
affected_code=(diff.range(filename),),
diffs={filename: diff})
3 changes: 3 additions & 0 deletions tests/documentation/DocumentationStyleBearTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ def test_function(self):
test_file_content = load_testfile(test_file).splitlines(True)

arguments = {'language': 'python', 'docstyle': 'default'}
if test_file == 'good_file3.py.test':
arguments.update({'allow_missing_func_desc': 'True'})
section = Section('test-section')
for key, value in arguments.items():
section[key] = value
Expand Down Expand Up @@ -53,3 +55,4 @@ class DocumentationStyleBearTest(unittest.TestCase):
test_bad5 = test('bad_file5.py.test', 'bad_file5.py.test.correct')
test_good1 = test('good_file.py.test', 'good_file.py.test')
test_good2 = test('good_file2.py.test', 'good_file2.py.test')
test_good3 = test('good_file3.py.test', 'good_file3.py.test')
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
def hello_there(x):
def improper_indents(indents):
"""
hello and no following empty lines
:param x:
Contains improper indents and no following empty line below.
:param indents:
5 space indent
just a second test
4 space indent

:return:
3 space indent
following lines are 4 space indented
4 space indent
"""
return None
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
def hello_there(x):
def improper_indents(indents):
"""
hello and no following empty lines
Contains improper indents and no following empty line below.

:param x:
:param indents:
5 space indent
just a second test
4 space indent
:return:
3 space indent
following lines are 4 space indented
4 space indent
"""
return None
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
def x():
return 55
def docstring_missing():
return None


def qr():
def docstring_testcase(dummy):
"""
this is heavy
Improper 3 indents.

:param x:
ss
:return:abc"""; return 88
:param dummy:
dummy description
:return:nothing""" return None


def w():
""" Hello world """
def docstring_singleliner():
""" This is singleliner docstring. """


def docstring_inline():
"""
Docstring followed by an inline docstring.
""" # This is inline docstring
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
def x():
return 55
def docstring_missing():
return None


def qr():
def docstring_testcase(dummy):
"""
this is heavy
Improper 3 indents.

:param x:
ss
:param dummy:
dummy description
:return:
abc
"""; return 88
nothing
""" return None


def w():
def docstring_singleliner():
"""
Hello world
This is singleliner docstring.
"""


def docstring_inline():
"""
Docstring followed by an inline docstring.
""" # This is inline docstring
Original file line number Diff line number Diff line change
@@ -1,3 +1,49 @@
"""
:param t:xyz
:return:123"""
def docstring_missing_description(dummy):
"""
:param dummy:dummy description
:return:nothing"""
return None


class docstring_class_testcase(dummy):
"""
Example docstring class.
:param dummy:dummy description
:return:nothing
"""

def docstring_memberfunction(self, dummy):
"""
This is a member function.
:param dummy:dummy description
:return:nothing
"""
return None
return None


class docstring_if_indented():
"""This is if indented function example."""

if 1 != 0:
def hello_planet(self):
"""
This is `if` indented block function.
"""
else:
def hello_venus(self):
"""This is `if` indented block function."""


def docstring_inner_function(dummy):
"""
This is docstring inner function example.
:param dummy: dummy description
"""
def check_directory(dummy):
"""
This is the inner function.
:param dummy: dummy description
:return: nothing
"""
return None
Original file line number Diff line number Diff line change
@@ -1,6 +1,67 @@
"""
:param t:
xyz
:return:
123
"""
def docstring_missing_description(dummy):
"""
:param dummy:
dummy description
:return:
nothing
"""
return None


class docstring_class_testcase(dummy):
"""
Example docstring class.

:param dummy:
dummy description
:return:
nothing
"""

def docstring_memberfunction(self, dummy):
"""
This is a member function.

:param dummy:
dummy description
:return:
nothing
"""
return None
return None


class docstring_if_indented():
"""
This is if indented function example.
"""

if 1 != 0:
def hello_planet(self):
"""
This is `if` indented block function.
"""
else:
def hello_venus(self):
"""
This is `if` indented block function.
"""


def docstring_inner_function(dummy):
"""
This is docstring inner function example.

:param dummy:
dummy description
"""
def check_directory(dummy):
"""
This is the inner function.

:param dummy:
dummy description
:return:
nothing
"""
return None
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
def myfunc(a, b, x):
def docstring_missing_descriptions(a, b, x):
"""

:param a:slope
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
def myfunc(a, b, x):
def docstring_missing_descriptions(a, b, x):
"""

:param a:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
def empty():
def docstring_improper_alignment():
"""
first line not correctly aligned.
First line not correctly aligned.
But second can be aligned differently.
Tabs are used here instead of spaces.

:param x:
:return:
"""; return 88
""" return None
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
def empty():
def docstring_improper_alignment():
"""
first line not correctly aligned.
First line not correctly aligned.
But second can be aligned differently.
Tabs are used here instead of spaces.

:param x:
:return:
"""; return 88
""" return None
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
def hello_there(x):
def docstring_accepted(dummy):
"""
hello
This is the accepted standard of a docstring.

:param x:
4 space indent
just a second test
:param dummy:
first line description
second line description
:return:
4 space indent
following lines are 4 space indented
first line description
second line description
"""
return None
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
def empty():
def docstring_missing_descriptions(dummy):
"""
this is heavy
This contains missing descriptions of parsed metadata.

:param x:
:param dummy:
:return:
"""; return 88
""" return None
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
def docstring_missing_description(dummy):
"""
:param dummy:
a function starting with `param`
in this case allow_missing_func_desc = True
"""

0 comments on commit 7ad62fb

Please sign in to comment.