8000 Changes to validate_docstring script to be able to check all docstrings at once by datapythonista · Pull Request #22408 · pandas-dev/pandas · GitHub
[go: up one dir, main page]

Skip to content

Changes to validate_docstring script to be able to check all docstrings at once #22408

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Oct 13, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Addressing comments from the code review
  • Loading branch information
datapythonista committed Aug 20, 2018
commit 188f4a39870fb1565af8a17b731023e1c7ef3243
28 changes: 18 additions & 10 deletions pandas/tests/scripts/test_validate_docstrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,25 +490,33 @@ def _import_path(self, klass=None, func=None):
return base_path

def test_good_class(self):
assert len(validate_one(self._import_path( # noqa: F821
klass='GoodDocStrings'))['errors']) == 0
errors = validate_one(self._import_path( # noqa: F821
klass='GoodDocStrings'))['errors']
assert isinstance(errors, list)
assert not errors

@pytest.mark.parametrize("func", [
'plot', 'sample', 'random_letters', 'sample_values', 'head', 'head1',
'contains'])
def test_good_functions(self, func):
assert len(validate_one(self._import_path( # noqa: F821
klass='GoodDocStrings', func=func))['errors']) == 0
errors = validate_one(self._import_path( # noqa: F821
klass='GoodDocStrings', func=func))['errors']
assert isinstance(errors, list)
assert not errors

def test_bad_class(self):
assert len(validate_one(self._import_path( # noqa: F821
klass='BadGenericDocStrings'))['errors']) > 0
errors = validate_one(self._import_path( # noqa: F821
klass='BadGenericDocStrings'))['errors']
assert isinstance(errors, list)
assert errors

@pytest.mark.parametrize("func", [
'func', 'astype', 'astype1', 'astype2', 'astype3', 'plot', 'method'])
def test_bad_generic_functions(self, func):
assert len(validate_one(self._import_path( # noqa:F821
klass='BadGenericDocStrings', func=func))['errors']) > 0
errors = validate_one(self._import_path( # noqa:F821
klass='BadGenericDocStrings', func=func))['errors']
assert isinstance(errors, list)
assert errors

@pytest.mark.parametrize("klass,func,msgs", [
# Summary tests
Expand Down Expand Up @@ -546,6 +554,6 @@ def test_bad_generic_functions(self, func):
marks=pytest.mark.xfail)
])
def test_bad_examples(self, capsys, klass, func, msgs):
res = validate_one(self._import_path(klass=klass, func=func)) # noqa:F821
result = validate_one(self._import_path(klass=klass, func=func)) # noqa:F821
for msg in msgs:
assert msg in ''.join(res['errors'])
assert msg in ' '.join(result['errors'])
30 changes: 30 additions & 0 deletions scripts/validate_docstrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,24 @@


def get_api_items():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather complex function - can we add a docstring to explain what this is doing?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the docstring it helps a lot! Is there a way to make a minimal test for this? Don't want to go overboard with tests here but I am worried that if this were to somehow break in the future it could allow subtle failures in subsequent tests to go through unnoticed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to me, but I'd address it in a separate PR

"""
Parse api.rst file from the documentation, and extract all the functions,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we make the first sentence one line?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you change this? Maybe missed on prior review

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've got the one liner summary above.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My mistake - thanks for clarifying

methods, classes, attributes... This should include all pandas public API.

Yields
------
name : str
The name of the object (e.g. 'pandas.Series.str.upper).
func : function
The object itself. In most cases this will be a function or method,
but it can also be classes, properties, cython objects...
section : str
The name of the section in the API page where the object item is
located.
subsection : str
The name of the subsection in the API page where the object item is
located.
"""
api_fname = os.path.join(BASE_PATH, 'doc', 'source', 'api.rst')

previous_line = current_section = current_subsection = ''
Expand Down Expand Up @@ -177,9 +195,15 @@ def is_function_or_method(self):

@property
def source_file_name(self):
"""
File name where the object is implemented (e.g. pandas/core/frame.py).
"""
try:
fname = inspect.getsourcefile(self.code_obj)
except TypeError:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this do?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what exactly? the inspect.getsourcefile() returns the source file where a Python object is implemented. The except TypeError is explain in the comment below.

# In some cases the object is something complex like a cython
# object that can't be easily introspected. An it's better to
# return the source code file of the object as None, than crash
pass
else:
if fname:
Expand All @@ -188,9 +212,15 @@ def source_file_name(self):

@property
def source_file_def_line(self):
"""
Number of line where the object is defined in its file.
"""
try:
return inspect.getsourcelines(self.code_obj)[-1]
except (OSError, TypeError):
# In some cases the object is something complex like a cython
# object that can't be easily introspected. An it's better to
# return the line number as None, than crash
pass

@property
Expand Down
0