Skip to content

Commit

Permalink
DOC: Adding validation of the section order in docstrings (pandas-dev…
Browse files Browse the repository at this point in the history
…#23607)

* Adding validation of the section order in docstrings

* Updating allowed sections
  • Loading branch information
datapythonista authored and tm9k1 committed Nov 19, 2018
1 parent bf6986c commit 75758a1
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 0 deletions.
34 changes: 34 additions & 0 deletions scripts/tests/test_validate_docstrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,35 @@ def private_classes(self):
This mentions NDFrame, which is not correct.
"""

def unknown_section(self):
"""
This section has an unknown section title.
Unknown Section
---------------
This should raise an error in the validation.
"""

def sections_in_wrong_order(self):
"""
This docstring has the sections in the wrong order.
Parameters
----------
name : str
This section is in the right position.
Examples
--------
>>> print('So far Examples is good, as it goes before Parameters')
So far Examples is good, as it goes before Parameters
See Also
--------
function : This should generate an error, as See Also needs to go
before Examples.
"""


class BadSummaries(object):

Expand Down Expand Up @@ -706,6 +735,11 @@ def test_bad_generic_functions(self, func):
('BadGenericDocStrings', 'private_classes',
("Private classes (NDFrame) should not be mentioned in public "
'docstrings',)),
('BadGenericDocStrings', 'unknown_section',
('Found unknown section "Unknown Section".',)),
('BadGenericDocStrings', 'sections_in_wrong_order',
('Wrong order of sections. "See Also" should be located before '
'"Notes"',)),
('BadSeeAlso', 'desc_no_period',
('Missing period at end of description for See Also "Series.iloc"',)),
('BadSeeAlso', 'desc_first_letter_lowercase',
Expand Down
38 changes: 38 additions & 0 deletions scripts/validate_docstrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@

PRIVATE_CLASSES = ['NDFrame', 'IndexOpsMixin']
DIRECTIVES = ['versionadded', 'versionchanged', 'deprecated']
ALLOWED_SECTIONS = ['Parameters', 'Attributes', 'Methods', 'Returns', 'Yields',
'Other Parameters', 'Raises', 'Warns', 'See Also', 'Notes',
'References', 'Examples']
ERROR_MSGS = {
'GL01': 'Docstring text (summary) should start in the line immediately '
'after the opening quotes (not in the same line, or leaving a '
Expand All @@ -69,6 +72,10 @@
'mentioned in public docstrings',
'GL05': 'Tabs found at the start of line "{line_with_tabs}", please use '
'whitespace only',
'GL06': 'Found unknown section "{section}". Allowed sections are: '
'{allowed_sections}',
'GL07': 'Wrong order of sections. "{wrong_section}" should be located '
'before "{goes_before}", the right order is: {sorted_sections}',
'SS01': 'No summary found (a short summary in a single line should be '
'present at the beginning of the docstring)',
'SS02': 'Summary does not start with a capital letter',
Expand Down Expand Up @@ -353,6 +360,18 @@ def double_blank_lines(self):
prev = row.strip()
return False

@property
def section_titles(self):
sections = []
self.doc._doc.reset()
while not self.doc._doc.eof():
content = self.doc._read_to_next_section()
if (len(content) > 1
and len(content[0]) == len(content[1])
and set(content[1]) == {'-'}):
sections.append(content[0])
return sections

@property
def summary(self):
return ' '.join(self.doc['Summary'])
Expand Down Expand Up @@ -580,6 +599,25 @@ def validate_one(func_name):
if re.match("^ *\t", line):
errs.append(error('GL05', line_with_tabs=line.lstrip()))

unseen_sections = list(ALLOWED_SECTIONS)
for section in doc.section_titles:
if section not in ALLOWED_SECTIONS:
errs.append(error('GL06',
section=section,
allowed_sections=', '.join(ALLOWED_SECTIONS)))
else:
if section in unseen_sections:
section_idx = unseen_sections.index(section)
unseen_sections = unseen_sections[section_idx + 1:]
else:
section_idx = ALLOWED_SECTIONS.index(section)
goes_before = ALLOWED_SECTIONS[section_idx + 1]
errs.append(error('GL07',
sorted_sections=' > '.join(ALLOWED_SECTIONS),
wrong_section=section,
goes_before=goes_before))
break

if not doc.summary:
errs.append(error('SS01'))
else:
Expand Down

0 comments on commit 75758a1

Please sign in to comment.