diff --git a/scripts/tests/test_validate_docstrings.py b/scripts/tests/test_validate_docstrings.py index 1506acc95edf9..d22eeb5a183ce 100644 --- a/scripts/tests/test_validate_docstrings.py +++ b/scripts/tests/test_validate_docstrings.py @@ -289,6 +289,59 @@ def say_hello(): else: return None + def parameters_with_bullet_points(self, method="min"): + """ + Allow bullet points to end without a period. + + Parameters + ---------- + method : {'min', 'max'}, default 'min' + Parameter introduction: + + * 'min': the description for min + * 'max': the description for max + """ + pass + + def parameters_with_bullet_points1(self, method="min"): + """ + Allow long description in bullet points to end without a period. + + Parameters + ---------- + method : {'min', 'max'}, default 'min' + Parameter introduction: + + * 'min': the description for min + * 'max': the description for max that can also be very long and + requires an extra row + """ + pass + + def parameters_bullet_points_and_directives(self, axis="index", method="min"): + """ + Test bullets points and directories. + + Parameters + ---------- + axis : {'index', 'columns'}, default 'index' + Parameter introduction and one directive: + + * 'index': the description for index + * 'columns': the description for columns + + .. versionchanged:: 0.1.2 + + method : {'min', 'max'}, default 'min' + Parameter introduction and two directives: + + * 'min': the description for min + * 'max': the description for max + + .. versionadded:: 0.1.2 + .. deprecated:: 0.00.0 + A description + """ def multiple_variables_on_one_line(self, matrix, a, b, i, j): """ Swap two values in a matrix. @@ -301,8 +354,8 @@ def multiple_variables_on_one_line(self, matrix, a, b, i, j): The indicies of the first value. i, j : int The indicies of the second value. - """ pass + """ class BadGenericDocStrings: @@ -898,6 +951,9 @@ def test_good_class(self, capsys): "good_imports", "no_returns", "empty_returns", + "parameters_with_bullet_points", + "parameters_with_bullet_points1", + "parameters_bullet_points_and_directives", "multiple_variables_on_one_line", ], ) diff --git a/scripts/validate_docstrings.py b/scripts/validate_docstrings.py index 1d0f4b583bd0c..c2f2554839839 100755 --- a/scripts/validate_docstrings.py +++ b/scripts/validate_docstrings.py @@ -60,6 +60,7 @@ PRIVATE_CLASSES = ["NDFrame", "IndexOpsMixin"] DIRECTIVES = ["versionadded", "versionchanged", "deprecated"] DIRECTIVE_PATTERN = re.compile(rf"^\s*\.\. ({'|'.join(DIRECTIVES)})(?!::)", re.I | re.M) +BULLET_LIST_PATTERN = re.compile(r"(?<=:)(\*|-|\+|•|‣|⁃)\s.*") ALLOWED_SECTIONS = [ "Parameters", "Attributes", @@ -508,6 +509,20 @@ def parameter_desc(self, param): desc = desc[: desc.index(full_directive)] return desc + def has_proper_punctuation(self, param): + """Return True if a parameter description is terminated correctly. + + A parameter description should always be terminated with a period, a + part from when it ends with a bullet point. + """ + if self.parameter_desc(param)[-1] == ".": + return True + else: + # Check if the parameter description ends with a bullet list + if re.search(BULLET_LIST_PATTERN, self.parameter_desc(param)): + return True + return False + @property def see_also(self): result = collections.OrderedDict() @@ -770,7 +785,7 @@ def get_validation_data(doc): else: if not doc.parameter_desc(param)[0].isupper(): errs.append(error("PR08", param_name=param)) - if doc.parameter_desc(param)[-1] != ".": + if not doc.has_proper_punctuation(param): errs.append(error("PR09", param_name=param)) if doc.is_function_or_method: