Skip to content

Commit

Permalink
[skip ci] Integrate flake8 and flake8-rst into validate_docstrings.py
Browse files Browse the repository at this point in the history
Signed-off-by: Fabian Haase <haase.fabian@gmail.com>
  • Loading branch information
FHaase committed Oct 28, 2018
1 parent 77df97f commit ee36f34
Showing 1 changed file with 46 additions and 13 deletions.
59 changes: 46 additions & 13 deletions scripts/validate_docstrings.py
Expand Up @@ -14,6 +14,7 @@
$ ./validate_docstrings.py pandas.DataFrame.head
"""
import os
import subprocess
import sys
import json
import re
Expand All @@ -24,6 +25,7 @@
import inspect
import importlib
import doctest

try:
from io import StringIO
except ImportError:
Expand All @@ -40,7 +42,6 @@
from numpydoc.docscrape import NumpyDocString
from pandas.io.formats.printing import pprint_thing


PRIVATE_CLASSES = ['NDFrame', 'IndexOpsMixin']
DIRECTIVES = ['versionadded', 'versionchanged', 'deprecated']

Expand Down Expand Up @@ -446,7 +447,7 @@ def validate_one(func_name):
if doc.summary != doc.summary.lstrip():
errs.append('Summary contains heading whitespaces.')
elif (doc.is_function_or_method
and doc.summary.split(' ')[0][-1] == 's'):
and doc.summary.split(' ')[0][-1] == 's'):
errs.append('Summary must start with infinitive verb, '
'not third person (e.g. use "Generate" instead of '
'"Generates")')
Expand Down Expand Up @@ -529,15 +530,16 @@ def validate_one(func_name):
if examples_errs:
errs.append('Examples do not pass tests')

return {'type': doc.type,
'docstring': doc.clean_doc,
'deprecated': doc.deprecated,
'file': doc.source_file_name,
'file_line': doc.source_file_def_line,
'github_link': doc.github_url,
'errors': errs,
'warnings': wrns,
'examples_errors': examples_errs}
return ({'type': doc.type,
'docstring': doc.clean_doc,
'deprecated': doc.deprecated,
'file': doc.source_file_name,
'file_line': doc.source_file_def_line,
'github_link': doc.github_url,
'errors': errs,
'warnings': wrns,
'examples_errors': examples_errs},
doc)


def validate_all():
Expand Down Expand Up @@ -598,10 +600,15 @@ def header(title, width=80, char='#'):
full_line=full_line, title_line=title_line)

if func_name is None:
flake8 = _call_flake8_plugin()
if flake8:
fd.write('Flake8 reported issues:\n')
fd.write(flake8)

json_doc = validate_all()
fd.write(json.dumps(json_doc))
else:
doc_info = validate_one(func_name)
doc_info, doc = validate_one(func_name)

fd.write(header('Docstring ({})'.format(func_name)))
fd.write('{}\n'.format(doc_info['docstring']))
Expand All @@ -615,14 +622,40 @@ def header(title, width=80, char='#'):
for wrn in doc_info['warnings']:
fd.write('\t{}\n'.format(wrn))

if not doc_info['errors']:
flake8 = _call_flake8_plugin(doc.source_file_name)
if flake8:
fd.write('Flake8 reported issues:\n')
fd.write(flake8)

if not doc_info['errors'] and not flake8:
fd.write('Docstring for "{}" correct. :)\n'.format(func_name))

if doc_info['examples_errors']:
fd.write(header('Doctests'))
fd.write(doc_info['examples_errors'])


def _call_flake8_plugin(*source_file_name):
sub_cmds = (['flake8', '--doctest', *source_file_name],
['flake8-rst', *source_file_name])

check_output = [_check_output_safe(sub_cmd) for sub_cmd in sub_cmds]
output = [output for output in check_output if output]
return '\n\n'.join(output) if output else None


def _check_output_safe(sub_cmd):
try:
output = subprocess.check_output(sub_cmd)
except subprocess.CalledProcessError as e:
output = e.output
if output:
return '\n'.join(['Invoking command "{}" returned:'
.format(' '.join(sub_cmd)), output.decode("utf-8")])
else:
return None


if __name__ == '__main__':
func_help = ('function or method to validate (e.g. pandas.DataFrame.head) '
'if not provided, all docstrings are validated and returned '
Expand Down

0 comments on commit ee36f34

Please sign in to comment.