diff --git a/doc/whatsnew/fragments/10104.false_positive b/doc/whatsnew/fragments/10104.false_positive new file mode 100644 index 00000000000..3a036d5a50e --- /dev/null +++ b/doc/whatsnew/fragments/10104.false_positive @@ -0,0 +1,3 @@ +Fix false positive for `missing-raises-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 b19560b7fb6..cef8397109b 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): @@ -364,6 +366,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 +677,22 @@ 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 + """ + node_line_count = checker_utils.get_node_last_lineno(node) - node.lineno + min_lines = self.linter.config.docstring_min_length + result = -1 < node_line_count < min_lines + assert isinstance( + result, bool + ), "Result of int comparison should have been a boolean" + return result + 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 00000000000..b5a487ca634 --- /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 00000000000..6c6bb7072f0 --- /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/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 00000000000..72d8f845a3d --- /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 00000000000..789ae21b579 --- /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=^$