diff options
20 files changed, 212 insertions, 305 deletions
diff --git a/tests/extensions/test_check_docs.py b/tests/extensions/test_check_docs.py deleted file mode 100644 index aab3bd761..000000000 --- a/tests/extensions/test_check_docs.py +++ /dev/null @@ -1,301 +0,0 @@ -# Copyright (c) 2014-2015 Bruno Daniel <bruno.daniel@blue-yonder.com> -# Copyright (c) 2015-2020 Claudiu Popa <pcmanticore@gmail.com> -# Copyright (c) 2016-2019 Ashley Whetter <ashley@awhetter.co.uk> -# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> -# Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net> -# Copyright (c) 2016 Glenn Matthews <glmatthe@cisco.com> -# Copyright (c) 2017, 2020 hippo91 <guillaume.peillex@gmail.com> -# Copyright (c) 2017 Mitar <mitar.github@tnode.com> -# Copyright (c) 2017 John Paraskevopoulos <io.paraskev@gmail.com> -# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> -# Copyright (c) 2018 Adrian Chirieac <chirieacam@gmail.com> -# Copyright (c) 2019-2021 Pierre Sassoulas <pierre.sassoulas@gmail.com> -# Copyright (c) 2019 Hugo van Kemenade <hugovk@users.noreply.github.com> -# Copyright (c) 2020 Luigi <luigi.cristofolini@q-ctrl.com> -# Copyright (c) 2021 Daniël van Noord <13665637+DanielNoord@users.noreply.github.com> -# Copyright (c) 2021 Konstantina Saketou <56515303+ksaketou@users.noreply.github.com> -# Copyright (c) 2021 Ville Skyttä <ville.skytta@iki.fi> -# Copyright (c) 2021 Marc Mueller <30130371+cdce8p@users.noreply.github.com> -# Copyright (c) 2021 Logan Miller <14319179+komodo472@users.noreply.github.com> - -# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html -# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE - -"""Unit tests for the pylint checkers in :mod:`pylint.extensions.check_docs`, -in particular the parameter documentation checker `DocstringChecker` -""" - - -import re - -import astroid -from astroid import nodes - -from pylint.extensions.docparams import DocstringParameterChecker -from pylint.testutils import CheckerTestCase, MessageTest, set_config -from pylint.testutils.decorator import set_config_directly - - -class TestParamDocChecker(CheckerTestCase): - """Tests for pylint_plugin.ParamDocChecker""" - - CHECKER_CLASS = DocstringParameterChecker - CONFIG = { - "accept_no_param_doc": False, - "no_docstring_rgx": re.compile("^$"), - "docstring_min_length": -1, - } - - @set_config(accept_no_param_doc=True) - def test_tolerate_no_param_documentation_at_all(self) -> None: - """Example of a function with no parameter documentation at all - - No error message is emitted. - """ - node = astroid.extract_node( - """ - def function_foo(x, y): - '''docstring ... - - missing parameter documentation''' - pass - """ - ) - with self.assertNoMessages(): - self.checker.visit_functiondef(node) - - def test_don_t_tolerate_no_param_documentation_at_all(self) -> None: - """Example of a function with no parameter documentation at all - - Missing documentation error message is emitted. - """ - node = astroid.extract_node( - """ - def function_foo(x, y): - '''docstring ... - - missing parameter documentation''' - pass - """ - ) - with self.assertAddsMessages( - MessageTest(msg_id="missing-any-param-doc", node=node, args=(node.name)), - ): - self.checker.visit_functiondef(node) - - def test_see_tolerate_no_param_documentation_at_all(self) -> None: - """Example for the usage of "For the parameters, see" - to suppress missing-param warnings. - """ - node = astroid.extract_node( - """ - def function_foo(x, y): - '''docstring ... - - For the parameters, see :func:`blah` - ''' - pass - """ - ) - with self.assertNoMessages(): - self.checker.visit_functiondef(node) - - def _visit_methods_of_class(self, node: nodes.ClassDef) -> None: - """Visit all methods of a class node - - :param node: class node - :type node: :class:`nodes.Class` - """ - for body_item in node.body: - if isinstance(body_item, nodes.FunctionDef) and hasattr(body_item, "name"): - self.checker.visit_functiondef(body_item) - - def test_see_sentence_for_constr_params_in_class(self) -> None: - """Example usage of "For the parameters, see" in class docstring""" - node = astroid.extract_node( - """ - class ClassFoo(object): - '''docstring foo - - For the parameters, see :func:`bla` - ''' - - def __init__(self, x, y): - '''init''' - pass - - """ - ) - with self.assertNoMessages(): - self._visit_methods_of_class(node) - - def test_see_sentence_for_constr_params_in_init(self) -> None: - """Example usage of "For the parameters, see" in init docstring""" - node = astroid.extract_node( - """ - class ClassFoo(object): - '''foo''' - - def __init__(self, x, y): - '''docstring foo constructor - - For the parameters, see :func:`bla` - ''' - pass - - """ - ) - with self.assertNoMessages(): - self._visit_methods_of_class(node) - - def test_kwonlyargs_are_taken_in_account(self) -> None: - node = astroid.extract_node( - ''' - def my_func(arg, *, kwonly, missing_kwonly): - """The docstring - - :param int arg: The argument. - :param bool kwonly: A keyword-arg. - """ - ''' - ) - with self.assertAddsMessages( - MessageTest( - msg_id="missing-param-doc", node=node, args=("missing_kwonly",) - ), - MessageTest(msg_id="missing-type-doc", node=node, args=("missing_kwonly",)), - ): - self.checker.visit_functiondef(node) - - def test_finds_short_name_exception(self) -> None: - node = astroid.extract_node( - ''' - from fake_package import BadError - - def do_something(): #@ - """Do something. - - Raises: - ~fake_package.exceptions.BadError: When something bad happened. - """ - raise BadError("A bad thing happened.") - ''' - ) - with self.assertNoMessages(): - self.checker.visit_functiondef(node) - - @set_config_directly(no_docstring_rgx=re.compile(r"^_(?!_).*$")) - def test_skip_no_docstring_rgx(self) -> None: - """Example of a function that matches the default 'no-docstring-rgx' config option - - No error message is emitted. - """ - node = astroid.extract_node( - """ - def _private_function_foo(x, y): - '''docstring ... - - missing parameter documentation''' - pass - """ - ) - with self.assertNoMessages(): - self.checker.visit_functiondef(node) - - def test_all_docstring_rgx(self) -> None: - """Function that matches "check all functions" 'no-docstring-rgx' config option - No error message is emitted. - """ - node = astroid.extract_node( - """ - #pylint disable=missing-module-docstring, too-few-public-methods, - class MyClass: - def __init__(self, my_param: int) -> None: - ''' - My init docstring - :param my_param: My first param - ''' - """ - ) - with self.assertNoMessages(): - self.checker.visit_functiondef(node.body[0]) - - def test_fail_empty_docstring_rgx(self) -> None: - """Function that matches "check all functions" 'no-docstring-rgx' config option - An error message is emitted. - """ - node = astroid.extract_node( - """ - #pylint disable=missing-module-docstring, too-few-public-methods, - class MyClass: - def __init__(self, my_param: int) -> None: - ''' - My init docstring - ''' - """ - ) - with self.assertAddsMessages( - MessageTest( - msg_id="missing-param-doc", node=node.body[0], args=("my_param",) - ), - ): - self.checker.visit_functiondef(node.body[0]) - - @set_config_directly(no_docstring_rgx=re.compile("^(?!__init__$)_")) - def test_fail_docparams_check_init(self) -> None: - """Check that __init__ is checked correctly, but other private methods aren't""" - node = astroid.extract_node( - """ - #pylint disable=missing-module-docstring, too-few-public-methods, - class MyClass: - def __init__(self, my_param: int) -> None: - ''' - My init docstring - ''' - - def _private_method(self, my_param: int) -> None: - ''' - My private method - ''' - """ - ) - with self.assertAddsMessages( - MessageTest( - msg_id="missing-param-doc", node=node.body[0], args=("my_param",) - ) - ): - self.checker.visit_functiondef(node.body[0]) - - @set_config_directly(no_docstring_rgx=re.compile("")) - def test_no_docstring_rgx(self) -> None: - """Function that matches "check no functions" 'no-docstring-rgx' config option - No error message is emitted. - """ - node = astroid.extract_node( - """ - #pylint disable=missing-module-docstring, too-few-public-methods, - class MyClass: - def __init__(self, my_param: int) -> None: - ''' - My init docstring - ''' - """ - ) - with self.assertNoMessages(): - self.checker.visit_functiondef(node.body[0]) - - @set_config_directly(docstring_min_length=3) - def test_skip_docstring_min_length(self) -> None: - """Example of a function that is less than 'docstring-min-length' config option - - No error message is emitted. - """ - node = astroid.extract_node( - """ - def function_foo(x, y): - '''function is too short and is missing parameter documentation''' - pass - """ - ) - with self.assertNoMessages(): - self.checker.visit_functiondef(node) diff --git a/tests/functional/ext/docparams/parameter/missing_param_doc.py b/tests/functional/ext/docparams/parameter/missing_param_doc.py new file mode 100644 index 000000000..6039c4b20 --- /dev/null +++ b/tests/functional/ext/docparams/parameter/missing_param_doc.py @@ -0,0 +1,12 @@ +"""Tests for missing-param-doc and missing-type-doc for non-specified style docstrings +with accept-no-param-doc = yes +""" +# pylint: disable=invalid-name, unused-argument + + +def test_tolerate_no_param_documentation_at_all(x, y): + """Example of a function with no parameter documentation at all + + No error message is emitted. + + missing parameter documentation""" diff --git a/tests/functional/ext/docparams/parameter/missing_param_doc.rc b/tests/functional/ext/docparams/parameter/missing_param_doc.rc new file mode 100644 index 000000000..4a81d2781 --- /dev/null +++ b/tests/functional/ext/docparams/parameter/missing_param_doc.rc @@ -0,0 +1,7 @@ +[MASTER] +load-plugins = pylint.extensions.docparams + +[BASIC] +accept-no-param-doc=yes +docstring-min-length: -1 +no-docstring-rgx=^$ diff --git a/tests/functional/ext/docparams/parameter/missing_param_doc_required.py b/tests/functional/ext/docparams/parameter/missing_param_doc_required.py new file mode 100644 index 000000000..072645505 --- /dev/null +++ b/tests/functional/ext/docparams/parameter/missing_param_doc_required.py @@ -0,0 +1,51 @@ +"""Tests for missing-param-doc and missing-type-doc for non-specified style docstrings +with accept-no-param-doc = no +""" +# pylint: disable=invalid-name, unused-argument, too-few-public-methods + + +def test_don_t_tolerate_no_param_documentation_at_all(x, y): # [missing-any-param-doc] + """Example of a function with no parameter documentation at all + + Missing documentation error message is emitted. + + missing parameter documentation""" + + +def test_see_tolerate_no_param_documentation_at_all(x, y): + """Example for the usage of "For the parameters, see" + to suppress missing-param warnings. + + For the parameters, see :func:`blah` + """ + + +class ClassFoo: + """Example usage of "For the parameters, see" in init docstring""" + + def __init__(self, x, y): + """docstring foo constructor + + For the parameters, see :func:`bla` + """ + + +class ClassFooTwo: + """test_see_sentence_for_constr_params_in_class + Example usage of "For the parameters, see" in class docstring + + For the parameters, see :func:`bla` + """ + + def __init__(self, x, y): + """init""" + + +def test_kwonlyargs_are_taken_in_account( # [missing-param-doc, missing-type-doc] + arg, *, kwonly, missing_kwonly +): + """The docstring + + :param int arg: The argument. + :param bool kwonly: A keyword-arg. + """ diff --git a/tests/functional/ext/docparams/parameter/missing_param_doc_required.rc b/tests/functional/ext/docparams/parameter/missing_param_doc_required.rc new file mode 100644 index 000000000..24cdf9ada --- /dev/null +++ b/tests/functional/ext/docparams/parameter/missing_param_doc_required.rc @@ -0,0 +1,7 @@ +[MASTER] +load-plugins = pylint.extensions.docparams + +[BASIC] +accept-no-param-doc=no +docstring-min-length: -1 +no-docstring-rgx=^$ diff --git a/tests/functional/ext/docparams/parameter/missing_param_doc_required.txt b/tests/functional/ext/docparams/parameter/missing_param_doc_required.txt new file mode 100644 index 000000000..e1672e427 --- /dev/null +++ b/tests/functional/ext/docparams/parameter/missing_param_doc_required.txt @@ -0,0 +1,3 @@ +missing-any-param-doc:7:0:12:38:test_don_t_tolerate_no_param_documentation_at_all:"Missing any documentation in ""test_don_t_tolerate_no_param_documentation_at_all""":UNDEFINED +missing-param-doc:44:0:51:7:test_kwonlyargs_are_taken_in_account:"""missing_kwonly"" missing in parameter documentation":UNDEFINED +missing-type-doc:44:0:51:7:test_kwonlyargs_are_taken_in_account:"""missing_kwonly"" missing in parameter type documentation":UNDEFINED diff --git a/tests/functional/ext/docparams/parameter/missing_param_doc_required_min_length.py b/tests/functional/ext/docparams/parameter/missing_param_doc_required_min_length.py new file mode 100644 index 000000000..765bb2d6c --- /dev/null +++ b/tests/functional/ext/docparams/parameter/missing_param_doc_required_min_length.py @@ -0,0 +1,9 @@ +"""Tests for missing-param-doc and missing-type-doc for non-specified style docstrings +with accept-no-param-doc = no and docstring-min-length = 3 +""" +# pylint: disable=invalid-name, unused-argument + +# Example of a function that is less than 'docstring-min-length' config option +# No error message is emitted. +def test_skip_docstring_min_length(x, y): + """function is too short and is missing parameter documentation""" diff --git a/tests/functional/ext/docparams/parameter/missing_param_doc_required_min_length.rc b/tests/functional/ext/docparams/parameter/missing_param_doc_required_min_length.rc new file mode 100644 index 000000000..a0538bf1b --- /dev/null +++ b/tests/functional/ext/docparams/parameter/missing_param_doc_required_min_length.rc @@ -0,0 +1,7 @@ +[MASTER] +load-plugins = pylint.extensions.docparams + +[BASIC] +accept-no-param-doc=no +docstring-min-length=3 +no-docstring-rgx=^$ diff --git a/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_check_init.py b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_check_init.py new file mode 100644 index 000000000..1d6d2c70b --- /dev/null +++ b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_check_init.py @@ -0,0 +1,18 @@ +"""Tests for missing-param-doc and missing-type-doc for non-specified style docstrings +with accept-no-param-doc = no and no-docstring-rgx = ^(?!__init__$)_ +""" +# pylint: disable=invalid-name, unused-argument, too-few-public-methods, missing-class-docstring + + +# test_fail_docparams_check_init +# Check that __init__ is checked correctly, but other private methods aren't +class MyClass: + def __init__(self, my_param: int) -> None: # [missing-param-doc] + """ + My init docstring + """ + + def _private_method(self, my_param: int) -> None: + """ + My private method + """ diff --git a/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_check_init.rc b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_check_init.rc new file mode 100644 index 000000000..3cba99ef4 --- /dev/null +++ b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_check_init.rc @@ -0,0 +1,7 @@ +[MASTER] +load-plugins = pylint.extensions.docparams + +[BASIC] +accept-no-param-doc=no +docstring-min-length=-1 +no-docstring-rgx=^(?!__init__$)_ diff --git a/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_check_init.txt b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_check_init.txt new file mode 100644 index 000000000..7cebb0a3c --- /dev/null +++ b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_check_init.txt @@ -0,0 +1 @@ +missing-param-doc:10:4:13:11:MyClass.__init__:"""my_param"" missing in parameter documentation":UNDEFINED diff --git a/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_check_none.py b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_check_none.py new file mode 100644 index 000000000..ca6eb2f7e --- /dev/null +++ b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_check_none.py @@ -0,0 +1,16 @@ +"""Tests for missing-param-doc and missing-type-doc for non-specified style docstrings +with accept-no-param-doc = no and no-docstring-rgx = "" +""" +# pylint: disable=invalid-name, unused-argument, too-few-public-methods + + +class MyClass: + """test_no_docstring_rgx + Function that matches "check no functions" 'no-docstring-rgx' config option + No error message is emitted. + """ + + def __init__(self, my_param: int) -> None: + """ + My init docstring + """ diff --git a/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_check_none.rc b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_check_none.rc new file mode 100644 index 000000000..1196467cd --- /dev/null +++ b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_check_none.rc @@ -0,0 +1,7 @@ +[MASTER] +load-plugins = pylint.extensions.docparams + +[BASIC] +accept-no-param-doc=no +docstring-min-length=-1 +no-docstring-rgx= diff --git a/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_default.py b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_default.py new file mode 100644 index 000000000..1d2daa1a1 --- /dev/null +++ b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_default.py @@ -0,0 +1,11 @@ +"""Tests for missing-param-doc and missing-type-doc for non-specified style docstrings +with accept-no-param-doc = no and the default value of no-docstring-rgx +""" +# pylint: disable=invalid-name, unused-argument + + +def _test_skip_no_docstring_rgx(x, y): + """Example of a function that matches the default 'no-docstring-rgx' config option + + No error message is emitted. + """ diff --git a/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_default.rc b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_default.rc new file mode 100644 index 000000000..c81f8bd6b --- /dev/null +++ b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_default.rc @@ -0,0 +1,6 @@ +[MASTER] +load-plugins = pylint.extensions.docparams + +[BASIC] +accept-no-param-doc=no +docstring-min-length=-1 diff --git a/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_test_all.py b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_test_all.py new file mode 100644 index 000000000..829119a09 --- /dev/null +++ b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_test_all.py @@ -0,0 +1,28 @@ +"""Tests for missing-param-doc and missing-type-doc for non-specified style docstrings +with accept-no-param-doc = no and no-docstring-rgx = ^$ +""" +# pylint: disable=invalid-name, unused-argument, too-few-public-methods, function-redefined +# pylint: disable=missing-class-docstring + + +class MyClass: + """test_all_docstring_rgx + Function that matches "check all functions" 'no-docstring-rgx' config option + No error message is emitted. + """ + + def __init__(self, my_param: int) -> None: + """ + My init docstring + :param my_param: My first param + """ + + +# test_fail_empty_docstring_rgx +# Function that matches "check all functions" 'no-docstring-rgx' config option +# An error message is emitted. +class MyClass: + def __init__(self, my_param: int) -> None: # [missing-param-doc] + """ + My init docstring + """ diff --git a/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_test_all.rc b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_test_all.rc new file mode 100644 index 000000000..a616b1a66 --- /dev/null +++ b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_test_all.rc @@ -0,0 +1,7 @@ +[MASTER] +load-plugins = pylint.extensions.docparams + +[BASIC] +accept-no-param-doc=no +docstring-min-length=-1 +no-docstring-rgx=^$ diff --git a/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_test_all.txt b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_test_all.txt new file mode 100644 index 000000000..d79aa94dd --- /dev/null +++ b/tests/functional/ext/docparams/parameter/missing_param_doc_required_no_doc_rgx_test_all.txt @@ -0,0 +1 @@ +missing-param-doc:25:4:28:11:MyClass.__init__:"""my_param"" missing in parameter documentation":UNDEFINED diff --git a/tests/functional/ext/docparams/raise/missing_raises_doc.py b/tests/functional/ext/docparams/raise/missing_raises_doc.py index 280d9f8e7..6ba112bd5 100644 --- a/tests/functional/ext/docparams/raise/missing_raises_doc.py +++ b/tests/functional/ext/docparams/raise/missing_raises_doc.py @@ -3,6 +3,7 @@ # pylint: disable=unused-argument, import-error, unused-variable, no-member, try-except-raise import collections +from fake_package import BadError from unknown import Unknown @@ -96,3 +97,12 @@ def test_no_error_notimplemented_documented(): NotImplementedError: When called. """ raise NotImplementedError + + +def test_finds_short_name_exception(): + """Do something. + + Raises: + ~fake_package.exceptions.BadError: When something bad happened. + """ + raise BadError("A bad thing happened.") diff --git a/tests/functional/ext/docparams/raise/missing_raises_doc.txt b/tests/functional/ext/docparams/raise/missing_raises_doc.txt index 6b11b43d0..6da4d57be 100644 --- a/tests/functional/ext/docparams/raise/missing_raises_doc.txt +++ b/tests/functional/ext/docparams/raise/missing_raises_doc.txt @@ -1,4 +1,4 @@ -unreachable:24:4:24:25:test_ignores_raise_uninferable:Unreachable code:UNDEFINED -missing-raises-doc:27:0:41:25:test_ignores_returns_from_inner_functions:"""RuntimeError"" not documented as being raised":UNDEFINED -unreachable:41:4:41:25:test_ignores_returns_from_inner_functions:Unreachable code:UNDEFINED -raising-bad-type:53:4:53:22:test_ignores_returns_use_only_names:Raising int while only classes or instances are allowed:UNDEFINED +unreachable:25:4:25:25:test_ignores_raise_uninferable:Unreachable code:UNDEFINED +missing-raises-doc:28:0:42:25:test_ignores_returns_from_inner_functions:"""RuntimeError"" not documented as being raised":UNDEFINED +unreachable:42:4:42:25:test_ignores_returns_from_inner_functions:Unreachable code:UNDEFINED +raising-bad-type:54:4:54:22:test_ignores_returns_use_only_names:Raising int while only classes or instances are allowed:UNDEFINED |