summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantina Saketou <56515303+ksaketou@users.noreply.github.com>2021-10-10 11:45:05 +0300
committerGitHub <noreply@github.com>2021-10-10 10:45:05 +0200
commitf2b0c48536c008410e6c3eab51ea1042b96829e2 (patch)
tree3645b82be657071d49aff8567e833553890300a2
parent1eaf5aa211a16607a0f15cae56a90e94555f3809 (diff)
downloadpylint-git-f2b0c48536c008410e6c3eab51ea1042b96829e2.tar.gz
Properly identify undocumented parameters and add new message called missing-any-param-doc (#5097)
* Correctly identify parameters with no doc and add new message This commit fixes the problem where non documented parameters where not being identified properly. Also, it adds a new message called ``missing-any-param-doc`` for when a function has no parameter and type doc at all. Adds new test cases for the ``missing-param-doc`` and ``missing-type-doc`` messages and tests for the new message ``missing-any-param-doc``. * Replace old messages with the new one where needed Fix pylint's code where the new message where needed in other files instead of triggering both missing-param-doc and missing-type-doc. Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
-rw-r--r--ChangeLog3
-rw-r--r--doc/whatsnew/2.12.rst7
-rw-r--r--pylint/extensions/_check_docs_utils.py17
-rw-r--r--pylint/extensions/docparams.py51
-rw-r--r--tests/extensions/test_check_docs.py3
-rw-r--r--tests/functional/ext/docparams.py4
-rw-r--r--tests/functional/ext/docparams.txt6
-rw-r--r--tests/functional/m/missing/missing_param_doc.py106
-rw-r--r--tests/functional/m/missing/missing_param_doc.rc8
-rw-r--r--tests/functional/m/missing/missing_param_doc.txt18
-rw-r--r--tests/functional/u/useless/useless_type_doc.py1
-rw-r--r--tests/functional/u/useless/useless_type_doc.txt8
12 files changed, 199 insertions, 33 deletions
diff --git a/ChangeLog b/ChangeLog
index 30de6af72..e1699f0d2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,6 +11,9 @@ Release date: TBA
..
Put new features here and also in 'doc/whatsnew/2.12.rst'
+* Properly identify parameters with no documentation and add new message called ``missing-any-param-doc``
+
+ Closes #3799
* Add checkers ``overridden-final-method`` & ``subclassed-final-class``
Closes #3197
diff --git a/doc/whatsnew/2.12.rst b/doc/whatsnew/2.12.rst
index 7cdd12003..f6d99185a 100644
--- a/doc/whatsnew/2.12.rst
+++ b/doc/whatsnew/2.12.rst
@@ -12,6 +12,13 @@ Summary -- Release highlights
New checkers
============
+* Added ``missing-any-param-doc`` triggered when a function has neither parameter nor parameter type
+ documentation. Undocumented parameters are now being properly identified. A warning might start to
+ appear unexpectedly if ``missing-param-doc`` and ``missing-type-doc`` were disabled, as a new message
+ ``missing-any-param-doc`` will be emitted instead.
+
+ Closes #3799
+
* Checkers for ``typing.final``
* Added ``overridden-final-method``: Emitted when a method which is annotated with ``typing.final`` is overridden
diff --git a/pylint/extensions/_check_docs_utils.py b/pylint/extensions/_check_docs_utils.py
index 66b4be24c..e1a7301e0 100644
--- a/pylint/extensions/_check_docs_utils.py
+++ b/pylint/extensions/_check_docs_utils.py
@@ -645,9 +645,17 @@ class GoogleDocstring(Docstring):
if not match:
continue
- param_name = match.group(1)
- param_type = match.group(2)
- param_desc = match.group(3)
+ # check if parameter has description only
+ re_only_desc = re.search(":\n", entry)
+ if re_only_desc:
+ param_name = match.group(1)
+ param_desc = match.group(2)
+ param_type = None
+ else:
+ param_name = match.group(1)
+ param_type = match.group(2)
+ param_desc = match.group(3)
+
if param_type:
params_with_type.add(param_name)
@@ -726,8 +734,7 @@ class NumpyDocstring(GoogleDocstring):
\s* (\w+) # identifier
\s* :
\s* (?:({GoogleDocstring.re_multiple_type})(?:,\s+optional)?)? # optional type declaration
- \n # description starts on a new line
- \s* (.*) # description
+ \s* (.*) # optional description
""",
re.X | re.S,
)
diff --git a/pylint/extensions/docparams.py b/pylint/extensions/docparams.py
index 32abedfb8..14d6ebc9f 100644
--- a/pylint/extensions/docparams.py
+++ b/pylint/extensions/docparams.py
@@ -145,6 +145,11 @@ class DocstringParameterChecker(BaseChecker):
"useless-type-doc",
"Please remove the ignored parameter type documentation.",
),
+ "W9021": (
+ 'Missing any documentation in "%s"',
+ "missing-any-param-doc",
+ "Please add parameter and/or type documentation.",
+ ),
}
options = (
@@ -541,16 +546,6 @@ class DocstringParameterChecker(BaseChecker):
if not params_with_doc and not params_with_type and accept_no_param_doc:
tolerate_missing_params = True
- if not tolerate_missing_params:
- self._compare_missing_args(
- params_with_doc,
- "missing-param-doc",
- self.not_needed_param_in_docstring
- | expected_but_ignored_argument_names,
- expected_argument_names,
- warning_node,
- )
-
# This is before the update of param_with_type because this must check only
# the type documented in a docstring, not the one using pep484
# See #4117 and #4593
@@ -568,13 +563,37 @@ class DocstringParameterChecker(BaseChecker):
params_with_type.add(arg_name.name)
if not tolerate_missing_params:
- self._compare_missing_args(
- params_with_type,
- "missing-type-doc",
- not_needed_type_in_docstring | expected_but_ignored_argument_names,
- expected_argument_names,
- warning_node,
+ missing_param_doc = (expected_argument_names - params_with_doc) - (
+ self.not_needed_param_in_docstring | expected_but_ignored_argument_names
)
+ missing_type_doc = (expected_argument_names - params_with_type) - (
+ not_needed_type_in_docstring | expected_but_ignored_argument_names
+ )
+ if (
+ missing_param_doc == expected_argument_names == missing_type_doc
+ and len(expected_argument_names) != 0
+ ):
+ self.add_message(
+ "missing-any-param-doc",
+ args=(warning_node.name),
+ node=warning_node,
+ )
+ else:
+ self._compare_missing_args(
+ params_with_doc,
+ "missing-param-doc",
+ self.not_needed_param_in_docstring
+ | expected_but_ignored_argument_names,
+ expected_argument_names,
+ warning_node,
+ )
+ self._compare_missing_args(
+ params_with_type,
+ "missing-type-doc",
+ not_needed_type_in_docstring | expected_but_ignored_argument_names,
+ expected_argument_names,
+ warning_node,
+ )
self._compare_different_args(
params_with_doc,
diff --git a/tests/extensions/test_check_docs.py b/tests/extensions/test_check_docs.py
index 1c250bc9b..04919c27b 100644
--- a/tests/extensions/test_check_docs.py
+++ b/tests/extensions/test_check_docs.py
@@ -325,8 +325,7 @@ class TestParamDocChecker(CheckerTestCase):
"""
)
with self.assertAddsMessages(
- MessageTest(msg_id="missing-param-doc", node=node, args=("x, y",)),
- MessageTest(msg_id="missing-type-doc", node=node, args=("x, y",)),
+ MessageTest(msg_id="missing-any-param-doc", node=node, args=(node.name)),
):
self.checker.visit_functiondef(node)
diff --git a/tests/functional/ext/docparams.py b/tests/functional/ext/docparams.py
index 269686a01..8dbb0295a 100644
--- a/tests/functional/ext/docparams.py
+++ b/tests/functional/ext/docparams.py
@@ -16,7 +16,7 @@ def _private_func3(param1): # [missing-raises-doc]
raise Exception('Example')
-def public_func1(param1): # [missing-param-doc, missing-type-doc]
+def public_func1(param1): # [missing-any-param-doc]
"""This is a test docstring without params"""
print(param1)
@@ -36,6 +36,6 @@ async def _async_private_func3(param1): # [missing-raises-doc]
raise Exception('Example')
-async def async_public_func1(param1): # [missing-param-doc, missing-type-doc]
+async def async_public_func1(param1): # [missing-any-param-doc]
"""This is a test docstring without params"""
print(param1)
diff --git a/tests/functional/ext/docparams.txt b/tests/functional/ext/docparams.txt
index cccc78126..7aa6631ed 100644
--- a/tests/functional/ext/docparams.txt
+++ b/tests/functional/ext/docparams.txt
@@ -3,12 +3,10 @@ missing-return-type-doc:4:0:_private_func1:Missing return type documentation
missing-yield-doc:9:0:_private_func2:Missing yield documentation
missing-yield-type-doc:9:0:_private_func2:Missing yield type documentation
missing-raises-doc:14:0:_private_func3:"""Exception""" not documented as being raised
-missing-param-doc:19:0:public_func1:"""param1""" missing in parameter documentation
-missing-type-doc:19:0:public_func1:"""param1""" missing in parameter type documentation
+missing-any-param-doc:19:0:public_func1:"Missing any documentation in ""public_func1"""
missing-return-doc:24:0:_async_private_func1:Missing return documentation
missing-return-type-doc:24:0:_async_private_func1:Missing return type documentation
missing-yield-doc:29:0:_async_private_func2:Missing yield documentation
missing-yield-type-doc:29:0:_async_private_func2:Missing yield type documentation
missing-raises-doc:34:0:_async_private_func3:"""Exception""" not documented as being raised
-missing-param-doc:39:0:async_public_func1:"""param1""" missing in parameter documentation
-missing-type-doc:39:0:async_public_func1:"""param1""" missing in parameter type documentation
+missing-any-param-doc:39:0:async_public_func1:"Missing any documentation in ""async_public_func1"""
diff --git a/tests/functional/m/missing/missing_param_doc.py b/tests/functional/m/missing/missing_param_doc.py
new file mode 100644
index 000000000..37c85b058
--- /dev/null
+++ b/tests/functional/m/missing/missing_param_doc.py
@@ -0,0 +1,106 @@
+#pylint: disable= missing-module-docstring
+
+def foobar1(arg1, arg2): #[missing-any-param-doc]
+ """function foobar ...
+ """
+ print(arg1, arg2)
+
+def foobar2(arg1, arg2): #[missing-any-param-doc]
+ """function foobar ...
+ Parameters
+ ----------
+ """
+ print(arg1, arg2)
+
+def foobar3(arg1, arg2, arg3): #[missing-param-doc, missing-type-doc]
+ """function foobar ...
+ Parameters
+ ----------
+ arg1: int
+ arg3: float
+ """
+ print(arg1, arg2, arg3)
+
+def foobar4(arg1, arg2): #[missing-param-doc, missing-type-doc]
+ """function foobar ...
+ Parameters
+ ----------
+ arg1: int
+ description
+ """
+ print(arg1, arg2)
+
+def foobar5(arg1, arg2): #[missing-param-doc, missing-type-doc]
+ """function foobar ...
+ Parameters
+ ----------
+ arg1:
+ description
+ arg2: str
+ """
+ print(arg1, arg2)
+
+def foobar6(arg1, arg2, arg3): #[missing-param-doc, missing-type-doc]
+ """function foobar ...
+ Parameters
+ ----------
+ arg1: int
+ description
+ arg2: int
+ """
+ print(arg1, arg2, arg3)
+
+def foobar7(arg1, arg2): #[missing-any-param-doc]
+ """function foobar ...
+ Parameters
+ ----------
+ arg1
+ """
+ print(arg1, arg2)
+
+def foobar8(arg1): #[missing-any-param-doc]
+ """function foobar"""
+
+ print(arg1)
+
+def foobar9(arg1, arg2, arg3): #[missing-param-doc]
+ """function foobar ...
+ Parameters
+ ----------
+ arg1: int
+ arg2: int
+ arg3: str
+ """
+ print(arg1, arg2, arg3)
+
+def foobar10(arg1, arg2, arg3): #[missing-param-doc, missing-type-doc]
+ """function foobar ...
+ Parameters
+ ----------
+ arg1:
+ desc1
+ arg2: int
+ arg3:
+ desc3
+ """
+ print(arg1, arg2, arg3)
+
+def foobar11(arg1, arg2): #[missing-any-param-doc]
+ """function foobar ...
+ Args
+ ----------
+ arg1
+ arg2
+ """
+ print(arg1, arg2)
+
+def foobar12(arg1, arg2, arg3): #[missing-param-doc, missing-type-doc]
+ """function foobar ...
+ Args
+ ----------
+ arg1: int
+ arg2:
+ does something
+ arg3
+ """
+ print(arg1, arg2, arg3)
diff --git a/tests/functional/m/missing/missing_param_doc.rc b/tests/functional/m/missing/missing_param_doc.rc
new file mode 100644
index 000000000..d4a6dc172
--- /dev/null
+++ b/tests/functional/m/missing/missing_param_doc.rc
@@ -0,0 +1,8 @@
+[MASTER]
+load-plugins=pylint.extensions.docparams,
+
+[PARAMETER_DOCUMENTATION]
+accept-no-param-doc=no
+accept-no-raise-doc=no
+accept-no-return-doc=no
+accept-no-yields-doc=no
diff --git a/tests/functional/m/missing/missing_param_doc.txt b/tests/functional/m/missing/missing_param_doc.txt
new file mode 100644
index 000000000..b03e20072
--- /dev/null
+++ b/tests/functional/m/missing/missing_param_doc.txt
@@ -0,0 +1,18 @@
+missing-any-param-doc:3:0:foobar1:"Missing any documentation in ""foobar1"""
+missing-any-param-doc:8:0:foobar2:"Missing any documentation in ""foobar2"""
+missing-param-doc:15:0:foobar3:"""arg1, arg2, arg3"" missing in parameter documentation"
+missing-type-doc:15:0:foobar3:"""arg2"" missing in parameter type documentation"
+missing-param-doc:24:0:foobar4:"""arg2"" missing in parameter documentation"
+missing-type-doc:24:0:foobar4:"""arg2"" missing in parameter type documentation"
+missing-param-doc:33:0:foobar5:"""arg2"" missing in parameter documentation"
+missing-type-doc:33:0:foobar5:"""arg1"" missing in parameter type documentation"
+missing-param-doc:43:0:foobar6:"""arg2, arg3"" missing in parameter documentation"
+missing-type-doc:43:0:foobar6:"""arg3"" missing in parameter type documentation"
+missing-any-param-doc:53:0:foobar7:"Missing any documentation in ""foobar7"""
+missing-any-param-doc:61:0:foobar8:"Missing any documentation in ""foobar8"""
+missing-param-doc:66:0:foobar9:"""arg1, arg2, arg3"" missing in parameter documentation"
+missing-param-doc:76:0:foobar10:"""arg2"" missing in parameter documentation"
+missing-type-doc:76:0:foobar10:"""arg1, arg3"" missing in parameter type documentation"
+missing-any-param-doc:88:0:foobar11:Missing any documentation in "foobar11"
+missing-param-doc:97:0:foobar12:"""arg1, arg3"" missing in parameter documentation"
+missing-type-doc:97:0:foobar12:"""arg2, arg3"" missing in parameter type documentation"
diff --git a/tests/functional/u/useless/useless_type_doc.py b/tests/functional/u/useless/useless_type_doc.py
index 6714755fd..110a7a5f5 100644
--- a/tests/functional/u/useless/useless_type_doc.py
+++ b/tests/functional/u/useless/useless_type_doc.py
@@ -1,3 +1,4 @@
+#pylint: disable = missing-any-param-doc
"""demonstrate FP with useless-type-doc"""
diff --git a/tests/functional/u/useless/useless_type_doc.txt b/tests/functional/u/useless/useless_type_doc.txt
index 20083ed79..9e1963e90 100644
--- a/tests/functional/u/useless/useless_type_doc.txt
+++ b/tests/functional/u/useless/useless_type_doc.txt
@@ -1,4 +1,4 @@
-useless-param-doc:33:0:function_useless_doc:"""_some_private_param"" useless ignored parameter documentation":HIGH
-useless-type-doc:33:0:function_useless_doc:"""_some_private_param"" useless ignored parameter type documentation":HIGH
-useless-param-doc:66:0:test_two:"""_new"" useless ignored parameter documentation":HIGH
-useless-type-doc:66:0:test_two:"""_new"" useless ignored parameter type documentation":HIGH
+useless-param-doc:34:0:function_useless_doc:"""_some_private_param"" useless ignored parameter documentation":HIGH
+useless-type-doc:34:0:function_useless_doc:"""_some_private_param"" useless ignored parameter type documentation":HIGH
+useless-param-doc:67:0:test_two:"""_new"" useless ignored parameter documentation":HIGH
+useless-type-doc:67:0:test_two:"""_new"" useless ignored parameter type documentation":HIGH