From c15902462af9100b5f7301f0cc978f2296e5d42f Mon Sep 17 00:00:00 2001 From: Marco Pernigotti <7657251+mpernigo@users.noreply.github.com> Date: Thu, 23 Jun 2022 09:04:33 +0200 Subject: [PATCH] Fix differing param doc false positive (#6980) * Read `posonly` args and annotations on `check_arguments_in_docstring` Co-authored-by: Pierre Sassoulas --- doc/whatsnew/2/2.14/full.rst | 3 ++ pylint/extensions/docparams.py | 4 ++ tests/functional/ext/docparams/docparams.py | 53 +++++++++++++++++++ tests/functional/ext/docparams/docparams.txt | 4 ++ .../ext/docparams/docparams_py38.py | 34 ++++++++++++ .../ext/docparams/docparams_py38.rc | 11 ++++ .../ext/docparams/docparams_py38.txt | 2 + 7 files changed, 111 insertions(+) create mode 100644 tests/functional/ext/docparams/docparams_py38.py create mode 100644 tests/functional/ext/docparams/docparams_py38.rc create mode 100644 tests/functional/ext/docparams/docparams_py38.txt diff --git a/doc/whatsnew/2/2.14/full.rst b/doc/whatsnew/2/2.14/full.rst index 6b68892b33..02feecd437 100644 --- a/doc/whatsnew/2/2.14/full.rst +++ b/doc/whatsnew/2/2.14/full.rst @@ -5,6 +5,9 @@ What's New in Pylint 2.14.4? ---------------------------- Release date: TBA +* The ``differing-param-doc`` check was triggered by positional only arguments. + + Closes #6950 What's New in Pylint 2.14.3? diff --git a/pylint/extensions/docparams.py b/pylint/extensions/docparams.py index 7e0dc12c3b..884b2afe61 100644 --- a/pylint/extensions/docparams.py +++ b/pylint/extensions/docparams.py @@ -524,6 +524,7 @@ class constructor. # Collect the function arguments. expected_argument_names = {arg.name for arg in arguments_node.args} expected_argument_names.update(arg.name for arg in arguments_node.kwonlyargs) + expected_argument_names.update(arg.name for arg in arguments_node.posonlyargs) not_needed_type_in_docstring = self.not_needed_param_in_docstring.copy() expected_but_ignored_argument_names = set() @@ -561,6 +562,9 @@ class constructor. for index, arg_name in enumerate(arguments_node.kwonlyargs): if arguments_node.kwonlyargs_annotations[index]: params_with_type.add(arg_name.name) + for index, arg_name in enumerate(arguments_node.posonlyargs): + if arguments_node.posonlyargs_annotations[index]: + params_with_type.add(arg_name.name) if not tolerate_missing_params: missing_param_doc = (expected_argument_names - params_with_doc) - ( diff --git a/tests/functional/ext/docparams/docparams.py b/tests/functional/ext/docparams/docparams.py index 8dbb0295af..295cf430d6 100644 --- a/tests/functional/ext/docparams/docparams.py +++ b/tests/functional/ext/docparams/docparams.py @@ -39,3 +39,56 @@ async def _async_private_func3(param1): # [missing-raises-doc] async def async_public_func1(param1): # [missing-any-param-doc] """This is a test docstring without params""" print(param1) + + +def differing_param_doc(par1: int) -> int: # [differing-param-doc] + """This is a test docstring documenting one non-existing param + + :param par1: some param + :param param: some param + :return: the sum of the params + """ + + return par1 + + +def differing_param_doc_kwords_only(*, par1: int) -> int: # [differing-param-doc] + """This is a test docstring documenting one non-existing param + + :param par1: some param + :param param: some param + :return: the sum of the params + """ + + return par1 + + +def missing_type_doc(par1) -> int: # [missing-type-doc] + """This is a test docstring params where the type is not specified + + :param par1: some param + :return: the param + """ + + return par1 + + +def missing_type_doc_kwords_only(*, par1) -> int: # [missing-type-doc] + """This is a test docstring params where the type is not specified + + :param par1: some param + :return: the param + """ + + return par1 + + +def params_are_documented(par1: int, *, par2: int) -> int: + """This is a test docstring params where nothing is raised as it is all documented + + :param par1: some param + :param par2: some other param + :return: the sum of params + """ + + return par1 + par2 diff --git a/tests/functional/ext/docparams/docparams.txt b/tests/functional/ext/docparams/docparams.txt index c75a954414..69baf08503 100644 --- a/tests/functional/ext/docparams/docparams.txt +++ b/tests/functional/ext/docparams/docparams.txt @@ -10,3 +10,7 @@ missing-yield-doc:29:0:29:30:_async_private_func2:Missing yield documentation:UN missing-yield-type-doc:29:0:29:30:_async_private_func2:Missing yield type documentation:UNDEFINED missing-raises-doc:34:0:34:30:_async_private_func3:"""Exception"" not documented as being raised":UNDEFINED missing-any-param-doc:39:0:39:28:async_public_func1:"Missing any documentation in ""async_public_func1""":UNDEFINED +differing-param-doc:44:0:44:23:differing_param_doc:"""param"" differing in parameter documentation":UNDEFINED +differing-param-doc:55:0:55:35:differing_param_doc_kwords_only:"""param"" differing in parameter documentation":UNDEFINED +missing-type-doc:66:0:66:20:missing_type_doc:"""par1"" missing in parameter type documentation":UNDEFINED +missing-type-doc:76:0:76:32:missing_type_doc_kwords_only:"""par1"" missing in parameter type documentation":UNDEFINED diff --git a/tests/functional/ext/docparams/docparams_py38.py b/tests/functional/ext/docparams/docparams_py38.py new file mode 100644 index 0000000000..7044fb369d --- /dev/null +++ b/tests/functional/ext/docparams/docparams_py38.py @@ -0,0 +1,34 @@ +"""Fixture for testing missing documentation in docparams (Python >=3.8 only).""" + + +def differing_param_doc_pos_only(par1: int, /) -> int: # [differing-param-doc] + """This is a test docstring documenting one non-existing param + + :param par1: some param + :param param: some param + :return: the sum of the params + """ + + return par1 + + +def missing_type_doc_pos_only(par1, /) -> int: # [missing-type-doc] + """This is a test docstring params where the type is not specified + + :param par1: some param + :return: the param + """ + + return par1 + + +def params_are_documented(par1: int, /, par2: int, *, par3: int) -> int: + """This is a test docstring params where nothing is raised as it is all documented + + :param par1: some param + :param par2: some other param + :param par3: some other param + :return: the sum of params + """ + + return par1 + par2 + par3 diff --git a/tests/functional/ext/docparams/docparams_py38.rc b/tests/functional/ext/docparams/docparams_py38.rc new file mode 100644 index 0000000000..8b1c245088 --- /dev/null +++ b/tests/functional/ext/docparams/docparams_py38.rc @@ -0,0 +1,11 @@ +[MAIN] +load-plugins = pylint.extensions.docparams + +[BASIC] +accept-no-param-doc = no +accept-no-raise-doc = no +accept-no-return-doc = no +accept-no-yields-doc = no + +[testoptions] +min_pyver=3.8 diff --git a/tests/functional/ext/docparams/docparams_py38.txt b/tests/functional/ext/docparams/docparams_py38.txt new file mode 100644 index 0000000000..96eaa445ad --- /dev/null +++ b/tests/functional/ext/docparams/docparams_py38.txt @@ -0,0 +1,2 @@ +differing-param-doc:4:0:4:32:differing_param_doc_pos_only:"""param"" differing in parameter documentation":UNDEFINED +missing-type-doc:15:0:15:29:missing_type_doc_pos_only:"""par1"" missing in parameter type documentation":UNDEFINED