From 2e7c6d17753711fcc0fdeff059fa7c6393dca534 Mon Sep 17 00:00:00 2001 From: Ryan Nazareth Date: Sat, 20 Oct 2018 02:44:53 +0100 Subject: [PATCH] Modifed test and validate docstrings for section ordering --- scripts/tests/test_validate_docstrings.py | 76 ++++++++++++++++++++++- scripts/validate_docstrings.py | 16 +++++ 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/scripts/tests/test_validate_docstrings.py b/scripts/tests/test_validate_docstrings.py index 27c63e3ba3a79..1fb893d7bba21 100644 --- a/scripts/tests/test_validate_docstrings.py +++ b/scripts/tests/test_validate_docstrings.py @@ -146,6 +146,37 @@ def head1(self, n=5): """ return self.iloc[:n] + def order(self): + """ + In this case, we are illustrating the correct ordering + of sections in a docstring + + Parameters + ---------- + pat : str + Pattern to check for within each element. + case : bool, default True + Whether check should be done with case sensitivity. + na : object, default np.nan + Fill value for missing data. + + Returns + ------- + Series + Original series with boolean values. + + Examples + -------- + >>> s = pd.Series(['Antelope', 'Lion', 'Zebra', np.nan]) + >>> s.str.contains(pat='a') + 0 False + 1 False + 2 True + 3 NaN + dtype: object + """ + pass + def contains(self, pat, case=True, na=np.nan): """ Return whether each value contains `pat`. @@ -502,6 +533,42 @@ def no_punctuation(self): return "Hello world!" +class BadOrder(object): + + def wrong_section_order(self): + """ + See also should not come before Returns section. + + See Also + ------- + + Returns + ------- + str + A nice greeting + """ + + def wrong_section_order1(self): + """ + Examples should not come before Parameters section. + + Examples + ------- + >>> s = pd.Series(['Antelope', 'Lion', 'Zebra', np.nan]) + >>> s.str.contains(pat='a') + 0 False + 1 False + 2 True + 3 NaN + dtype: object + + Parameters + ------- + str + A nice greeting + """ + + class TestValidator(object): def _import_path(self, klass=None, func=None): @@ -540,7 +607,7 @@ def test_good_class(self): @capture_stderr @pytest.mark.parametrize("func", [ 'plot', 'sample', 'random_letters', 'sample_values', 'head', 'head1', - 'contains', 'mode']) + 'order', 'contains', 'mode']) def test_good_functions(self, func): errors = validate_one(self._import_path( klass='GoodDocStrings', func=func))['errors'] @@ -600,7 +667,12 @@ def test_bad_generic_functions(self, func): pytest.param('BadReturns', 'no_description', ('foo',), marks=pytest.mark.xfail), pytest.param('BadReturns', 'no_punctuation', ('foo',), - marks=pytest.mark.xfail) + marks=pytest.mark.xfail), + # Section ordering tests + ('BadOrder', 'wrong_section_order', + ('Section See Also should not be before Return section',)), + ('BadOrder', 'wrong_section_order1', + ('Examples section should not be before Parameters',)) ]) def test_bad_examples(self, capsys, klass, func, msgs): result = validate_one(self._import_path(klass=klass, func=func)) # noqa:F821 diff --git a/scripts/validate_docstrings.py b/scripts/validate_docstrings.py index 6588522331433..01f58fab040eb 100755 --- a/scripts/validate_docstrings.py +++ b/scripts/validate_docstrings.py @@ -389,6 +389,18 @@ def deprecated(self): def mentioned_private_classes(self): return [klass for klass in PRIVATE_CLASSES if klass in self.raw_doc] + @property + def section_order(self): + sections = ["Summary", "Parameters", "Returns", + "Yields", "See Also", "Notes", "Examples"] + section_index = [] + for section in sections: + if section not in self.raw_doc: + continue + else: + section_index.append(self.raw_doc.index(section)) + return section_index + @property def examples_errors(self): flags = doctest.NORMALIZE_WHITESPACE | doctest.IGNORE_EXCEPTION_DETAIL @@ -492,6 +504,10 @@ def validate_one(func_name): errs.append('Private classes ({}) should not be mentioned in public ' 'docstring.'.format(mentioned_errs)) + section_index = doc.section_order + if sorted(section_index) != section_index: + errs.append("The section titles are not in the correct order.") + if not doc.see_also: wrns.append('See Also section not found') else: