diff --git a/doc/whatsnew/fragments/10104.false_negative b/doc/whatsnew/fragments/10104.false_negative new file mode 100644 index 0000000000..8a7a247de8 --- /dev/null +++ b/doc/whatsnew/fragments/10104.false_negative @@ -0,0 +1,3 @@ +Fix false negative for `missing-raises-doc`, `missing-return-doc` and `missing-yield-doc` when the method length is less than docstring-min-length. + +Refs #10104 diff --git a/pylint/extensions/docparams.py b/pylint/extensions/docparams.py index b19560b7fb..c5889d7ccd 100644 --- a/pylint/extensions/docparams.py +++ b/pylint/extensions/docparams.py @@ -209,9 +209,7 @@ def visit_functiondef(self, node: nodes.FunctionDef) -> None: return # skip functions smaller than 'docstring-min-length' - lines = checker_utils.get_node_last_lineno(node) - node.lineno - max_lines = self.linter.config.docstring_min_length - if max_lines > -1 and lines < max_lines: + if self._is_shorter_than_min_length(node): return self.check_functiondef_params(node, node_doc) @@ -281,6 +279,10 @@ def visit_raise(self, node: nodes.Raise) -> None: if not isinstance(func_node, astroid.FunctionDef): return + # skip functions smaller than 'docstring-min-length' + if self._is_shorter_than_min_length(node): + return + # skip functions that match the 'no-docstring-rgx' config option no_docstring_rgx = self.linter.config.no_docstring_rgx if no_docstring_rgx and re.match(no_docstring_rgx, func_node.name): @@ -338,6 +340,10 @@ def visit_return(self, node: nodes.Return) -> None: if self.linter.config.accept_no_return_doc: return + # skip functions smaller than 'docstring-min-length' + if self._is_shorter_than_min_length(node): + return + func_node: astroid.FunctionDef = node.frame() # skip functions that match the 'no-docstring-rgx' config option @@ -364,6 +370,10 @@ def visit_yield(self, node: nodes.Yield | nodes.YieldFrom) -> None: if self.linter.config.accept_no_yields_doc: return + # skip functions smaller than 'docstring-min-length' + if self._is_shorter_than_min_length(node): + return + func_node: astroid.FunctionDef = node.frame() # skip functions that match the 'no-docstring-rgx' config option @@ -671,6 +681,18 @@ def _add_raise_message( confidence=HIGH, ) + def _is_shorter_than_min_length(self, node: nodes.FunctionDef) -> bool: + """Returns true on functions smaller than 'docstring-min-length'. + + :param node: Node for a function or method definition in the AST + :type node: :class:`astroid.scoped_nodes.Function` + + :rtype: bool + """ + lines = checker_utils.get_node_last_lineno(node) - node.lineno + min_lines = self.linter.config.docstring_min_length + return bool(min_lines > -1) and bool(lines < min_lines) + def register(linter: PyLinter) -> None: linter.register_checker(DocstringParameterChecker(linter)) diff --git a/tests/functional/ext/docparams/raise/missing_raises_doc_required_min_length.py b/tests/functional/ext/docparams/raise/missing_raises_doc_required_min_length.py new file mode 100644 index 0000000000..b5a487ca63 --- /dev/null +++ b/tests/functional/ext/docparams/raise/missing_raises_doc_required_min_length.py @@ -0,0 +1,10 @@ +"""Tests for missing-raises-doc for non-specified style docstrings +with accept-no-raise-doc = no and docstring-min-length = 3 +""" +# pylint: disable=invalid-name, broad-exception-raised + +# Example of a function that is less than 'docstring-min-length' config option +# No error message is emitted. +def test_skip_docstring_min_length(): + """function is too short and is missing raise documentation""" + raise Exception diff --git a/tests/functional/ext/docparams/raise/missing_raises_doc_required_min_length.rc b/tests/functional/ext/docparams/raise/missing_raises_doc_required_min_length.rc new file mode 100644 index 0000000000..6c6bb7072f --- /dev/null +++ b/tests/functional/ext/docparams/raise/missing_raises_doc_required_min_length.rc @@ -0,0 +1,7 @@ +[MAIN] +load-plugins = pylint.extensions.docparams + +[BASIC] +accept-no-raise-doc=no +docstring-min-length=3 +no-docstring-rgx=^$ diff --git a/tests/functional/ext/docparams/return/missing_return_doc_required_min_length.py b/tests/functional/ext/docparams/return/missing_return_doc_required_min_length.py new file mode 100644 index 0000000000..37cfb4f26b --- /dev/null +++ b/tests/functional/ext/docparams/return/missing_return_doc_required_min_length.py @@ -0,0 +1,10 @@ +"""Tests for missing-return-doc for non-specified style docstrings +with accept-no-return-doc = no and docstring-min-length = 3 +""" +# pylint: disable=invalid-name + +# Example of a function that is less than 'docstring-min-length' config option +# No error message is emitted. +def test_skip_docstring_min_length() -> None: + """function is too short and is missing return documentation""" + return None diff --git a/tests/functional/ext/docparams/return/missing_return_doc_required_min_length.rc b/tests/functional/ext/docparams/return/missing_return_doc_required_min_length.rc new file mode 100644 index 0000000000..0136eabb08 --- /dev/null +++ b/tests/functional/ext/docparams/return/missing_return_doc_required_min_length.rc @@ -0,0 +1,7 @@ +[MAIN] +load-plugins = pylint.extensions.docparams + +[BASIC] +accept-no-return-doc=no +docstring-min-length=3 +no-docstring-rgx=^$ diff --git a/tests/functional/ext/docparams/yield/missing_yield_doc_required_min_length.py b/tests/functional/ext/docparams/yield/missing_yield_doc_required_min_length.py new file mode 100644 index 0000000000..72d8f845a3 --- /dev/null +++ b/tests/functional/ext/docparams/yield/missing_yield_doc_required_min_length.py @@ -0,0 +1,10 @@ +"""Tests for missing-yield-doc for non-specified style docstrings +with accept-no-yields-doc = no and docstring-min-length = 3 +""" +# pylint: disable=invalid-name + +# Example of a function that is less than 'docstring-min-length' config option +# No error message is emitted. +def test_skip_docstring_min_length(): + """function is too short and is missing yield documentation""" + yield None diff --git a/tests/functional/ext/docparams/yield/missing_yield_doc_required_min_length.rc b/tests/functional/ext/docparams/yield/missing_yield_doc_required_min_length.rc new file mode 100644 index 0000000000..789ae21b57 --- /dev/null +++ b/tests/functional/ext/docparams/yield/missing_yield_doc_required_min_length.rc @@ -0,0 +1,7 @@ +[MAIN] +load-plugins = pylint.extensions.docparams + +[BASIC] +accept-no-yields-doc=no +docstring-min-length=3 +no-docstring-rgx=^$