From cd5838c14c58d6904433e9037ec20071eb897185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Noord?= <13665637+DanielNoord@users.noreply.github.com> Date: Mon, 18 Oct 2021 22:01:27 +0200 Subject: [PATCH] Fix asterisks parsing of ``mising-param-doc`` (#5175) Closes #3733 --- ChangeLog | 5 +++ doc/whatsnew/2.12.rst | 5 +++ pylint/extensions/_check_docs_utils.py | 6 ++-- pylint/extensions/docparams.py | 8 ++--- pylint/reporters/text.py | 2 +- tests/extensions/test_check_docs.py | 22 ++++++------ .../functional/m/missing/missing_param_doc.py | 36 +++++++++++++++++++ 7 files changed, 65 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index f26007d1e4..5b5461d121 100644 --- a/ChangeLog +++ b/ChangeLog @@ -66,6 +66,11 @@ Release date: TBA Closes #4774 +* ``mising-param-doc`` now correctly parses asterisks for variable length and + keyword parameters + + Closes #3733 + * Update ``literal-comparison``` checker to ignore tuple literals Closes #3031 diff --git a/doc/whatsnew/2.12.rst b/doc/whatsnew/2.12.rst index be1e5245c4..4af23d50b5 100644 --- a/doc/whatsnew/2.12.rst +++ b/doc/whatsnew/2.12.rst @@ -74,3 +74,8 @@ Other Changes used in metaclass declarations Closes #4031 + +* ``mising-param-doc`` now correctly parses asterisks for variable length and + keyword parameters + + Closes #3733 diff --git a/pylint/extensions/_check_docs_utils.py b/pylint/extensions/_check_docs_utils.py index e1a7301e0c..52f9e470cc 100644 --- a/pylint/extensions/_check_docs_utils.py +++ b/pylint/extensions/_check_docs_utils.py @@ -279,7 +279,7 @@ class SphinxDocstring(Docstring): \s+ )? - (\w+) # Parameter name + (\*{{0,2}}\w+) # Parameter name with potential asterisks \s* # whitespace : # final colon """ @@ -472,7 +472,7 @@ class GoogleDocstring(Docstring): re_param_line = re.compile( fr""" - \s* \*{{0,2}}(\w+) # identifier potentially with asterisks + \s* (\*{{0,2}}\w+) # identifier potentially with asterisks \s* ( [(] {re_multiple_type} (?:,\s+optional)? @@ -731,7 +731,7 @@ class NumpyDocstring(GoogleDocstring): re_param_line = re.compile( fr""" - \s* (\w+) # identifier + \s* (\*{{0,2}}\w+) # identifier with potential asterisks \s* : \s* (?:({GoogleDocstring.re_multiple_type})(?:,\s+optional)?)? # optional type declaration \s* (.*) # optional description diff --git a/pylint/extensions/docparams.py b/pylint/extensions/docparams.py index 14d6ebc9f5..17ec303a9a 100644 --- a/pylint/extensions/docparams.py +++ b/pylint/extensions/docparams.py @@ -536,11 +536,11 @@ class constructor. } if arguments_node.vararg is not None: - expected_argument_names.add(arguments_node.vararg) - not_needed_type_in_docstring.add(arguments_node.vararg) + expected_argument_names.add(f"*{arguments_node.vararg}") + not_needed_type_in_docstring.add(f"*{arguments_node.vararg}") if arguments_node.kwarg is not None: - expected_argument_names.add(arguments_node.kwarg) - not_needed_type_in_docstring.add(arguments_node.kwarg) + expected_argument_names.add(f"**{arguments_node.kwarg}") + not_needed_type_in_docstring.add(f"**{arguments_node.kwarg}") params_with_doc, params_with_type = doc.match_param_docs() # Tolerate no parameter documentation at all. if not params_with_doc and not params_with_type and accept_no_param_doc: diff --git a/pylint/reporters/text.py b/pylint/reporters/text.py index 8af3f879c6..42bd6b2ea3 100644 --- a/pylint/reporters/text.py +++ b/pylint/reporters/text.py @@ -147,7 +147,7 @@ def colorize_ansi( :param style: the message's style elements, this will be deprecated - :param kwargs: used to accept `color` parameter while it is being deprecated + :param **kwargs: used to accept `color` parameter while it is being deprecated :return: the ansi escaped string """ diff --git a/tests/extensions/test_check_docs.py b/tests/extensions/test_check_docs.py index 0d50b85355..79836c21a3 100644 --- a/tests/extensions/test_check_docs.py +++ b/tests/extensions/test_check_docs.py @@ -1141,7 +1141,7 @@ def my_func(named_arg, *args): ''' ) with self.assertAddsMessages( - MessageTest(msg_id="missing-param-doc", node=node, args=("args",)) + MessageTest(msg_id="missing-param-doc", node=node, args=("*args",)) ): self.checker.visit_functiondef(node) @@ -1161,7 +1161,7 @@ def my_func(named_arg, **kwargs): ''' ) with self.assertAddsMessages( - MessageTest(msg_id="missing-param-doc", node=node, args=("kwargs",)) + MessageTest(msg_id="missing-param-doc", node=node, args=("**kwargs",)) ): self.checker.visit_functiondef(node) @@ -1182,7 +1182,7 @@ def my_func(named_arg, *args): ''' ) with self.assertAddsMessages( - MessageTest(msg_id="missing-param-doc", node=node, args=("args",)) + MessageTest(msg_id="missing-param-doc", node=node, args=("*args",)) ): self.checker.visit_functiondef(node) @@ -1203,7 +1203,7 @@ def my_func(named_arg, **kwargs): ''' ) with self.assertAddsMessages( - MessageTest(msg_id="missing-param-doc", node=node, args=("kwargs",)) + MessageTest(msg_id="missing-param-doc", node=node, args=("**kwargs",)) ): self.checker.visit_functiondef(node) @@ -1228,7 +1228,7 @@ def my_func(named_arg, *args): ''' ) with self.assertAddsMessages( - MessageTest(msg_id="missing-param-doc", node=node, args=("args",)) + MessageTest(msg_id="missing-param-doc", node=node, args=("*args",)) ): self.checker.visit_functiondef(node) @@ -1253,7 +1253,7 @@ def my_func(named_arg, **kwargs): ''' ) with self.assertAddsMessages( - MessageTest(msg_id="missing-param-doc", node=node, args=("kwargs",)) + MessageTest(msg_id="missing-param-doc", node=node, args=("**kwargs",)) ): self.checker.visit_functiondef(node) @@ -1265,7 +1265,7 @@ def my_func(named_arg, *args): :param named_arg: Returned :type named_arg: object - :param args: Optional arguments + :param *args: Optional arguments :returns: Maybe named_arg :rtype: object or None """ @@ -1284,7 +1284,7 @@ def my_func(named_arg, **kwargs): :param named_arg: Returned :type named_arg: object - :param kwargs: Keyword arguments + :param **kwargs: Keyword arguments :returns: Maybe named_arg :rtype: object or None """ @@ -1345,7 +1345,7 @@ def my_func(named_arg, *args): ---- named_arg : object Returned - args : + *args : Optional Arguments Returns @@ -1390,7 +1390,7 @@ def my_func(named_arg, *args): ---- named_arg : `example.value` Returned - args : + *args : Optional Arguments Returns @@ -1415,7 +1415,7 @@ def my_func(named_arg, **kwargs): ---- named_arg : object Returned - kwargs : + **kwargs : Keyword arguments Returns diff --git a/tests/functional/m/missing/missing_param_doc.py b/tests/functional/m/missing/missing_param_doc.py index 37c85b0582..75f813578d 100644 --- a/tests/functional/m/missing/missing_param_doc.py +++ b/tests/functional/m/missing/missing_param_doc.py @@ -104,3 +104,39 @@ def foobar12(arg1, arg2, arg3): #[missing-param-doc, missing-type-doc] arg3 """ print(arg1, arg2, arg3) + +def foobar13(arg1, *args, arg3=";"): + """Description of the function + + Parameters + ---------- + arg1 : str + Path to the input. + *args : + Relevant parameters. + arg3 : str, optional + File separator. + """ + print(arg1, args, arg3) + +def foobar14(arg1, *args): + """Description of the function + + Parameters + ---------- + arg1 : str + Path to the input. + *args : + Relevant parameters. + """ + print(arg1, args) + +def foobar15(*args): + """Description of the function + + Parameters + ---------- + *args : + Relevant parameters. + """ + print(args)