| # Copyright (c) 2014-2015 Bruno Daniel <[email protected]> |
| # Copyright (c) 2015-2020 Claudiu Popa <[email protected]> |
| # Copyright (c) 2016-2019 Ashley Whetter <[email protected]> |
| # Copyright (c) 2016 Derek Gustafson <[email protected]> |
| # Copyright (c) 2016 Glenn Matthews <[email protected]> |
| # Copyright (c) 2016 Glenn Matthews <[email protected]> |
| # Copyright (c) 2017, 2020 hippo91 <[email protected]> |
| # Copyright (c) 2017 Mitar <[email protected]> |
| # Copyright (c) 2017 John Paraskevopoulos <[email protected]> |
| # Copyright (c) 2018 Sushobhit <[email protected]> |
| # Copyright (c) 2018 Adrian Chirieac <[email protected]> |
| # Copyright (c) 2019-2021 Pierre Sassoulas <[email protected]> |
| # Copyright (c) 2019 Hugo van Kemenade <[email protected]> |
| # Copyright (c) 2020 Luigi <[email protected]> |
| # Copyright (c) 2021 Marc Mueller <[email protected]> |
| # Copyright (c) 2021 Logan Miller <[email protected]> |
| |
| # 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` |
| """ |
| |
| # pylint: disable=too-many-public-methods |
| |
| import astroid |
| import pytest |
| from astroid import nodes |
| |
| from pylint.extensions.docparams import DocstringParameterChecker |
| from pylint.testutils import CheckerTestCase, Message, set_config |
| |
| |
| class TestParamDocChecker(CheckerTestCase): |
| """Tests for pylint_plugin.ParamDocChecker""" |
| |
| CHECKER_CLASS = DocstringParameterChecker |
| CONFIG = { |
| "accept_no_param_doc": False, |
| "no_docstring_rgx": "", |
| "docstring_min_length": -1, |
| } |
| |
| def test_missing_func_params_in_sphinx_docstring(self) -> None: |
| """Example of a function with missing Sphinx parameter documentation in |
| the docstring |
| """ |
| node = astroid.extract_node( |
| """ |
| def function_foo(x, y, z): |
| '''docstring ... |
| |
| :param x: bla |
| |
| :param int z: bar |
| ''' |
| pass |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=node, args=("y",)), |
| Message(msg_id="missing-type-doc", node=node, args=("x, y",)), |
| ): |
| self.checker.visit_functiondef(node) |
| |
| def test_missing_func_params_in_google_docstring(self) -> None: |
| """Example of a function with missing Google style parameter |
| documentation in the docstring |
| """ |
| node = astroid.extract_node( |
| """ |
| def function_foo(x, y, z): |
| '''docstring ... |
| |
| Args: |
| x: bla |
| z (int): bar |
| |
| some other stuff |
| ''' |
| pass |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=node, args=("y",)), |
| Message(msg_id="missing-type-doc", node=node, args=("x, y",)), |
| ): |
| self.checker.visit_functiondef(node) |
| |
| def test_missing_type_doc_google_docstring_exempt_kwonly_args(self) -> None: |
| node = astroid.extract_node( |
| """ |
| def identifier_kwarg_method(arg1: int, arg2: int, *, value1: str, value2: str): |
| '''Code to show failure in missing-type-doc |
| |
| Args: |
| arg1: First argument. |
| arg2: Second argument. |
| value1: First kwarg. |
| value2: Second kwarg. |
| ''' |
| print("NOTE: It doesn't like anything after the '*'.") |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_missing_func_params_with_annotations_in_google_docstring(self) -> None: |
| """Example of a function with missing Google style parameter |
| documentation in the docstring. |
| """ |
| node = astroid.extract_node( |
| """ |
| def function_foo(x: int, y: bool, z): |
| '''docstring ... |
| |
| Args: |
| x: bla |
| y: blah blah |
| z (int): bar |
| |
| some other stuff |
| ''' |
| pass |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_default_arg_with_annotations_in_google_docstring(self) -> None: |
| """Example of a function with missing Google style parameter |
| documentation in the docstring. |
| """ |
| node = astroid.extract_node( |
| """ |
| def function_foo(x: int, y: bool, z: int = 786): |
| '''docstring ... |
| |
| Args: |
| x: bla |
| y: blah blah |
| z: bar |
| |
| some other stuff |
| ''' |
| pass |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_missing_func_params_with_partial_annotations_in_google_docstring( |
| self, |
| ) -> None: |
| """Example of a function with missing Google style parameter |
| documentation in the docstring. |
| """ |
| node = astroid.extract_node( |
| """ |
| def function_foo(x, y: bool, z): |
| '''docstring ... |
| |
| Args: |
| x: bla |
| y: blah blah |
| z (int): bar |
| |
| some other stuff |
| ''' |
| pass |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-type-doc", node=node, args=("x",)) |
| ): |
| self.checker.visit_functiondef(node) |
| |
| def test_non_builtin_annotations_in_google_docstring(self) -> None: |
| """Example of a function with missing Google style parameter |
| documentation in the docstring. |
| """ |
| node = astroid.extract_node( |
| """ |
| def area(bottomleft: Point, topright: Point) -> float: |
| '''Calculate area of fake rectangle. |
| Args: |
| bottomleft: bottom left point of rectangle |
| topright: top right point of rectangle |
| ''' |
| pass |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_non_builtin_annotations_for_returntype_in_google_docstring(self) -> None: |
| """Example of a function with missing Google style parameter |
| documentation in the docstring. |
| """ |
| node = astroid.extract_node( |
| """ |
| def get_midpoint(bottomleft: Point, topright: Point) -> Point: |
| '''Calculate midpoint of fake rectangle. |
| Args: |
| bottomleft: bottom left point of rectangle |
| topright: top right point of rectangle |
| ''' |
| pass |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_func_params_and_keyword_params_in_google_docstring(self) -> None: |
| """Example of a function with Google style parameter splitted |
| in Args and Keyword Args in the docstring |
| """ |
| node = astroid.extract_node( |
| """ |
| def my_func(this, other, that=True): |
| '''Prints this, other and that |
| |
| Args: |
| this (str): Printed first |
| other (int): Other args |
| |
| Keyword Args: |
| that (bool): Printed second |
| ''' |
| print(this, that, other) |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_func_params_and_wrong_keyword_params_in_google_docstring(self) -> None: |
| """Example of a function with Google style parameter splitted |
| in Args and Keyword Args in the docstring but with wrong keyword args |
| """ |
| node = astroid.extract_node( |
| """ |
| def my_func(this, other, that=True): |
| '''Prints this, other and that |
| |
| Args: |
| this (str): Printed first |
| other (int): Other args |
| |
| Keyword Args: |
| these (bool): Printed second |
| ''' |
| print(this, that, other) |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=node, args=("that",)), |
| Message(msg_id="missing-type-doc", node=node, args=("that",)), |
| Message(msg_id="differing-param-doc", node=node, args=("these",)), |
| Message(msg_id="differing-type-doc", node=node, args=("these",)), |
| ): |
| self.checker.visit_functiondef(node) |
| |
| def test_missing_func_params_in_numpy_docstring(self) -> None: |
| """Example of a function with missing NumPy style parameter |
| documentation in the docstring |
| """ |
| node = astroid.extract_node( |
| """ |
| def function_foo(x, y, z): |
| '''docstring ... |
| |
| Parameters |
| ---------- |
| x: |
| bla |
| z: int |
| bar |
| |
| some other stuff |
| ''' |
| pass |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=node, args=("y",)), |
| Message(msg_id="missing-type-doc", node=node, args=("x, y",)), |
| ): |
| self.checker.visit_functiondef(node) |
| |
| @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( |
| Message(msg_id="missing-param-doc", node=node, args=("x, y",)), |
| Message(msg_id="missing-type-doc", node=node, args=("x, y",)), |
| ): |
| 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_missing_method_params_in_sphinx_docstring(self) -> None: |
| """Example of a class method with missing parameter documentation in |
| the Sphinx style docstring |
| """ |
| node = astroid.extract_node( |
| """ |
| class Foo(object): |
| def method_foo(self, x, y): |
| '''docstring ... |
| |
| missing parameter documentation |
| |
| :param x: bla |
| ''' |
| pass |
| """ |
| ) |
| method_node = node.body[0] |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=method_node, args=("y",)), |
| Message(msg_id="missing-type-doc", node=method_node, args=("x, y",)), |
| ): |
| self._visit_methods_of_class(node) |
| |
| def test_missing_method_params_in_google_docstring(self) -> None: |
| """Example of a class method with missing parameter documentation in |
| the Google style docstring |
| """ |
| node = astroid.extract_node( |
| """ |
| class Foo(object): |
| def method_foo(self, x, y): |
| '''docstring ... |
| |
| missing parameter documentation |
| |
| Args: |
| x: bla |
| ''' |
| pass |
| """ |
| ) |
| method_node = node.body[0] |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=method_node, args=("y",)), |
| Message(msg_id="missing-type-doc", node=method_node, args=("x, y",)), |
| ): |
| self._visit_methods_of_class(node) |
| |
| def test_missing_method_params_in_numpy_docstring(self) -> None: |
| """Example of a class method with missing parameter documentation in |
| the Numpy style docstring |
| """ |
| node = astroid.extract_node( |
| """ |
| class Foo(object): |
| def method_foo(self, x, y): |
| '''docstring ... |
| |
| missing parameter documentation |
| |
| Parameters |
| ---------- |
| x: |
| bla |
| ''' |
| pass |
| """ |
| ) |
| method_node = node.body[0] |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=method_node, args=("y",)), |
| Message(msg_id="missing-type-doc", node=method_node, args=("x, y",)), |
| ): |
| self._visit_methods_of_class(node) |
| |
| def test_existing_func_params_in_sphinx_docstring(self) -> None: |
| """Example of a function with correctly documented parameters and |
| return values (Sphinx style) |
| """ |
| node = astroid.extract_node( |
| """ |
| def function_foo(xarg, yarg, zarg, warg): |
| '''function foo ... |
| |
| :param xarg: bla xarg |
| :type xarg: int |
| |
| :parameter yarg: bla yarg |
| :type yarg: my.qualified.type |
| |
| :arg int zarg: bla zarg |
| |
| :keyword my.qualified.type warg: bla warg |
| |
| :return: sum |
| :rtype: float |
| ''' |
| return xarg + yarg |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_existing_func_params_in_google_docstring(self) -> None: |
| """Example of a function with correctly documented parameters and |
| return values (Google style) |
| """ |
| node = astroid.extract_node( |
| """ |
| def function_foo(xarg, yarg, zarg, warg): |
| '''function foo ... |
| |
| Args: |
| xarg (int): bla xarg |
| yarg (my.qualified.type): bla |
| bla yarg |
| |
| zarg (int): bla zarg |
| warg (my.qualified.type): bla warg |
| |
| Returns: |
| float: sum |
| ''' |
| return xarg + yarg |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_existing_func_params_in_numpy_docstring(self) -> None: |
| """Example of a function with correctly documented parameters and |
| return values (Numpy style) |
| """ |
| node = astroid.extract_node( |
| """ |
| def function_foo(xarg, yarg, zarg, warg): |
| '''function foo ... |
| |
| Parameters |
| ---------- |
| xarg: int |
| bla xarg |
| yarg: my.qualified.type |
| bla yarg |
| |
| zarg: int |
| bla zarg |
| warg: my.qualified.type |
| bla warg |
| |
| Returns |
| ------- |
| float |
| sum |
| ''' |
| return xarg + yarg |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_wrong_name_of_func_params_in_sphinx_docstring(self) -> None: |
| """Example of functions with inconsistent parameter names in the |
| signature and in the Sphinx style documentation |
| """ |
| node = astroid.extract_node( |
| """ |
| def function_foo(xarg, yarg, zarg): |
| '''function foo ... |
| |
| :param xarg1: bla xarg |
| :type xarg: int |
| |
| :param yarg: bla yarg |
| :type yarg1: float |
| |
| :param str zarg1: bla zarg |
| ''' |
| return xarg + yarg |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=node, args=("xarg, zarg",)), |
| Message(msg_id="missing-type-doc", node=node, args=("yarg, zarg",)), |
| Message(msg_id="differing-param-doc", node=node, args=("xarg1, zarg1",)), |
| Message(msg_id="differing-type-doc", node=node, args=("yarg1, zarg1",)), |
| ): |
| self.checker.visit_functiondef(node) |
| |
| node = astroid.extract_node( |
| """ |
| def function_foo(xarg, yarg): |
| '''function foo ... |
| |
| :param yarg1: bla yarg |
| :type yarg1: float |
| |
| For the other parameters, see bla. |
| ''' |
| return xarg + yarg |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="differing-param-doc", node=node, args=("yarg1",)), |
| Message(msg_id="differing-type-doc", node=node, args=("yarg1",)), |
| ): |
| self.checker.visit_functiondef(node) |
| |
| def test_wrong_name_of_func_params_in_google_docstring(self) -> None: |
| """Example of functions with inconsistent parameter names in the |
| signature and in the Google style documentation |
| """ |
| node = astroid.extract_node( |
| """ |
| def function_foo(xarg, yarg, zarg): |
| '''function foo ... |
| |
| Args: |
| xarg1 (int): bla xarg |
| yarg (float): bla yarg |
| |
| zarg1 (str): bla zarg |
| ''' |
| return xarg + yarg |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=node, args=("xarg, zarg",)), |
| Message(msg_id="missing-type-doc", node=node, args=("xarg, zarg",)), |
| Message(msg_id="differing-param-doc", node=node, args=("xarg1, zarg1",)), |
| Message(msg_id="differing-type-doc", node=node, args=("xarg1, zarg1",)), |
| ): |
| self.checker.visit_functiondef(node) |
| |
| node = astroid.extract_node( |
| """ |
| def function_foo(xarg, yarg): |
| '''function foo ... |
| |
| Args: |
| yarg1 (float): bla yarg |
| |
| For the other parameters, see bla. |
| ''' |
| return xarg + yarg |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="differing-param-doc", node=node, args=("yarg1",)), |
| Message(msg_id="differing-type-doc", node=node, args=("yarg1",)), |
| ): |
| self.checker.visit_functiondef(node) |
| |
| def test_wrong_name_of_func_params_in_numpy_docstring(self) -> None: |
| """Example of functions with inconsistent parameter names in the |
| signature and in the Numpy style documentation |
| """ |
| node = astroid.extract_node( |
| """ |
| def function_foo(xarg, yarg, zarg): |
| '''function foo ... |
| |
| Parameters |
| ---------- |
| xarg1: int |
| bla xarg |
| yarg: float |
| bla yarg |
| |
| zarg1: str |
| bla zarg |
| ''' |
| return xarg + yarg |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=node, args=("xarg, zarg",)), |
| Message(msg_id="missing-type-doc", node=node, args=("xarg, zarg",)), |
| Message(msg_id="differing-param-doc", node=node, args=("xarg1, zarg1",)), |
| Message(msg_id="differing-type-doc", node=node, args=("xarg1, zarg1",)), |
| ): |
| self.checker.visit_functiondef(node) |
| |
| node = astroid.extract_node( |
| """ |
| def function_foo(xarg, yarg): |
| '''function foo ... |
| |
| Parameters |
| ---------- |
| yarg1: float |
| bla yarg |
| |
| For the other parameters, see bla. |
| ''' |
| return xarg + yarg |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="differing-param-doc", node=node, args=("yarg1",)), |
| Message(msg_id="differing-type-doc", node=node, args=("yarg1",)), |
| ): |
| self.checker.visit_functiondef(node) |
| |
| def test_see_sentence_for_func_params_in_sphinx_docstring(self) -> None: |
| """Example for the usage of "For the other parameters, see" to avoid |
| too many repetitions, e.g. in functions or methods adhering to a |
| given interface (Sphinx style) |
| """ |
| node = astroid.extract_node( |
| """ |
| def function_foo(xarg, yarg): |
| '''function foo ... |
| |
| :param yarg: bla yarg |
| :type yarg: float |
| |
| For the other parameters, see :func:`bla` |
| ''' |
| return xarg + yarg |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_see_sentence_for_func_params_in_google_docstring(self) -> None: |
| """Example for the usage of "For the other parameters, see" to avoid |
| too many repetitions, e.g. in functions or methods adhering to a |
| given interface (Google style) |
| """ |
| node = astroid.extract_node( |
| """ |
| def function_foo(xarg, yarg): |
| '''function foo ... |
| |
| Args: |
| yarg (float): bla yarg |
| |
| For the other parameters, see :func:`bla` |
| ''' |
| return xarg + yarg |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_see_sentence_for_func_params_in_numpy_docstring(self) -> None: |
| """Example for the usage of "For the other parameters, see" to avoid |
| too many repetitions, e.g. in functions or methods adhering to a |
| given interface (Numpy style) |
| """ |
| node = astroid.extract_node( |
| """ |
| def function_foo(xarg, yarg): |
| '''function foo ... |
| |
| Parameters |
| ---------- |
| yarg: float |
| bla yarg |
| |
| For the other parameters, see :func:`bla` |
| ''' |
| return xarg + yarg |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_constr_params_in_class_sphinx(self) -> None: |
| """Example of a class with missing constructor parameter documentation |
| (Sphinx style) |
| |
| Everything is completely analogous to functions. |
| """ |
| node = astroid.extract_node( |
| """ |
| class ClassFoo(object): |
| '''docstring foo |
| |
| :param y: bla |
| |
| missing constructor parameter documentation |
| ''' |
| |
| def __init__(self, x, y): |
| pass |
| |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=node, args=("x",)), |
| Message(msg_id="missing-type-doc", node=node, args=("x, y",)), |
| ): |
| self._visit_methods_of_class(node) |
| |
| def test_constr_params_in_class_google(self) -> None: |
| """Example of a class with missing constructor parameter documentation |
| (Google style) |
| |
| Everything is completely analogous to functions. |
| """ |
| node = astroid.extract_node( |
| """ |
| class ClassFoo(object): |
| '''docstring foo |
| |
| Args: |
| y: bla |
| |
| missing constructor parameter documentation |
| ''' |
| |
| def __init__(self, x, y): |
| pass |
| |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=node, args=("x",)), |
| Message(msg_id="missing-type-doc", node=node, args=("x, y",)), |
| ): |
| self._visit_methods_of_class(node) |
| |
| def test_constr_params_in_class_numpy(self) -> None: |
| """Example of a class with missing constructor parameter documentation |
| (Numpy style) |
| |
| Everything is completely analogous to functions. |
| """ |
| node = astroid.extract_node( |
| """ |
| class ClassFoo(object): |
| '''docstring foo |
| |
| Parameters |
| ---------- |
| y: |
| bla |
| |
| missing constructor parameter documentation |
| ''' |
| |
| def __init__(self, x, y): |
| pass |
| |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=node, args=("x",)), |
| Message(msg_id="missing-type-doc", node=node, args=("x, y",)), |
| ): |
| self._visit_methods_of_class(node) |
| |
| def test_constr_params_and_attributes_in_class_numpy(self) -> None: |
| """Example of a class with correct constructor parameter documentation |
| and an attributes section (Numpy style) |
| """ |
| node = astroid.extract_node( |
| """ |
| class ClassFoo(object): |
| ''' |
| Parameters |
| ---------- |
| foo : str |
| Something. |
| |
| Attributes |
| ---------- |
| bar : str |
| Something. |
| ''' |
| def __init__(self, foo): |
| self.bar = None |
| """ |
| ) |
| with self.assertNoMessages(): |
| self._visit_methods_of_class(node) |
| |
| def test_constr_params_in_init_sphinx(self) -> None: |
| """Example of a class with missing constructor parameter documentation |
| (Sphinx style) |
| |
| Everything is completely analogous to functions. |
| """ |
| node = astroid.extract_node( |
| """ |
| class ClassFoo(object): |
| def __init__(self, x, y): |
| '''docstring foo constructor |
| |
| :param y: bla |
| |
| missing constructor parameter documentation |
| ''' |
| |
| pass |
| |
| """ |
| ) |
| constructor_node = node.body[0] |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=constructor_node, args=("x",)), |
| Message(msg_id="missing-type-doc", node=constructor_node, args=("x, y",)), |
| ): |
| self._visit_methods_of_class(node) |
| |
| def test_constr_params_in_init_google(self) -> None: |
| """Example of a class with missing constructor parameter documentation |
| (Google style) |
| |
| Everything is completely analogous to functions. |
| """ |
| node = astroid.extract_node( |
| """ |
| class ClassFoo(object): |
| def __init__(self, x, y): |
| '''docstring foo constructor |
| |
| Args: |
| y: bla |
| |
| missing constructor parameter documentation |
| ''' |
| pass |
| |
| """ |
| ) |
| constructor_node = node.body[0] |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=constructor_node, args=("x",)), |
| Message(msg_id="missing-type-doc", node=constructor_node, args=("x, y",)), |
| ): |
| self._visit_methods_of_class(node) |
| |
| def test_constr_params_in_init_numpy(self) -> None: |
| """Example of a class with missing constructor parameter documentation |
| (Numpy style) |
| |
| Everything is completely analogous to functions. |
| """ |
| node = astroid.extract_node( |
| """ |
| class ClassFoo(object): |
| def __init__(self, x, y): |
| '''docstring foo constructor |
| |
| Parameters |
| ---------- |
| y: |
| bla |
| |
| missing constructor parameter documentation |
| ''' |
| pass |
| |
| """ |
| ) |
| constructor_node = node.body[0] |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=constructor_node, args=("x",)), |
| Message(msg_id="missing-type-doc", node=constructor_node, args=("x, y",)), |
| ): |
| self._visit_methods_of_class(node) |
| |
| 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_constr_params_in_class_and_init_sphinx(self) -> None: |
| """Example of a class with missing constructor parameter documentation |
| in both the init docstring and the class docstring |
| (Sphinx style) |
| |
| Everything is completely analogous to functions. |
| """ |
| node = astroid.extract_node( |
| """ |
| class ClassFoo(object): |
| '''docstring foo |
| |
| :param y: None |
| |
| missing constructor parameter documentation |
| ''' |
| |
| def __init__(self, x, y): |
| '''docstring foo |
| |
| :param y: bla |
| |
| missing constructor parameter documentation |
| ''' |
| pass |
| |
| """ |
| ) |
| constructor_node = node.body[0] |
| with self.assertAddsMessages( |
| Message(msg_id="multiple-constructor-doc", node=node, args=(node.name,)), |
| Message(msg_id="missing-param-doc", node=node, args=("x",)), |
| Message(msg_id="missing-type-doc", node=node, args=("x, y",)), |
| Message(msg_id="missing-param-doc", node=constructor_node, args=("x",)), |
| Message(msg_id="missing-type-doc", node=constructor_node, args=("x, y",)), |
| ): |
| self._visit_methods_of_class(node) |
| |
| def test_constr_params_in_class_and_init_google(self) -> None: |
| """Example of a class with missing constructor parameter documentation |
| in both the init docstring and the class docstring |
| (Google style) |
| |
| Everything is completely analogous to functions. |
| """ |
| node = astroid.extract_node( |
| """ |
| class ClassFoo(object): |
| '''docstring foo |
| |
| Args: |
| y: bla |
| |
| missing constructor parameter documentation |
| ''' |
| |
| def __init__(self, x, y): |
| '''docstring foo |
| |
| Args: |
| y: bla |
| |
| missing constructor parameter documentation |
| ''' |
| pass |
| |
| """ |
| ) |
| constructor_node = node.body[0] |
| with self.assertAddsMessages( |
| Message(msg_id="multiple-constructor-doc", node=node, args=(node.name,)), |
| Message(msg_id="missing-param-doc", node=node, args=("x",)), |
| Message(msg_id="missing-type-doc", node=node, args=("x, y",)), |
| Message(msg_id="missing-param-doc", node=constructor_node, args=("x",)), |
| Message(msg_id="missing-type-doc", node=constructor_node, args=("x, y",)), |
| ): |
| self._visit_methods_of_class(node) |
| |
| def test_constr_params_in_class_and_init_numpy(self) -> None: |
| """Example of a class with missing constructor parameter documentation |
| in both the init docstring and the class docstring |
| (Numpy style) |
| |
| Everything is completely analogous to functions. |
| """ |
| node = astroid.extract_node( |
| """ |
| class ClassFoo(object): |
| '''docstring foo |
| |
| Parameters |
| ---------- |
| y: |
| bla |
| |
| missing constructor parameter documentation |
| ''' |
| |
| def __init__(self, x, y): |
| '''docstring foo |
| |
| Parameters |
| ---------- |
| y: |
| bla |
| |
| missing constructor parameter documentation |
| ''' |
| pass |
| |
| """ |
| ) |
| constructor_node = node.body[0] |
| with self.assertAddsMessages( |
| Message(msg_id="multiple-constructor-doc", node=node, args=(node.name,)), |
| Message(msg_id="missing-param-doc", node=node, args=("x",)), |
| Message(msg_id="missing-type-doc", node=node, args=("x, y",)), |
| Message(msg_id="missing-param-doc", node=constructor_node, args=("x",)), |
| Message(msg_id="missing-type-doc", node=constructor_node, args=("x, y",)), |
| ): |
| 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( |
| Message(msg_id="missing-param-doc", node=node, args=("missing_kwonly",)), |
| Message(msg_id="missing-type-doc", node=node, args=("missing_kwonly",)), |
| ): |
| self.checker.visit_functiondef(node) |
| |
| def test_warns_missing_args_sphinx(self) -> None: |
| node = astroid.extract_node( |
| ''' |
| def my_func(named_arg, *args): |
| """The docstring |
| |
| :param named_arg: Returned |
| :type named_arg: object |
| :returns: Maybe named_arg |
| :rtype: object or None |
| """ |
| if args: |
| return named_arg |
| ''' |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=node, args=("args",)) |
| ): |
| self.checker.visit_functiondef(node) |
| |
| def test_warns_missing_kwargs_sphinx(self) -> None: |
| node = astroid.extract_node( |
| ''' |
| def my_func(named_arg, **kwargs): |
| """The docstring |
| |
| :param named_arg: Returned |
| :type named_arg: object |
| :returns: Maybe named_arg |
| :rtype: object or None |
| """ |
| if kwargs: |
| return named_arg |
| ''' |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=node, args=("kwargs",)) |
| ): |
| self.checker.visit_functiondef(node) |
| |
| def test_warns_missing_args_google(self) -> None: |
| node = astroid.extract_node( |
| ''' |
| def my_func(named_arg, *args): |
| """The docstring |
| |
| Args: |
| named_arg (object): Returned |
| |
| Returns: |
| object or None: Maybe named_arg |
| """ |
| if args: |
| return named_arg |
| ''' |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=node, args=("args",)) |
| ): |
| self.checker.visit_functiondef(node) |
| |
| def test_warns_missing_kwargs_google(self) -> None: |
| node = astroid.extract_node( |
| ''' |
| def my_func(named_arg, **kwargs): |
| """The docstring |
| |
| Args: |
| named_arg (object): Returned |
| |
| Returns: |
| object or None: Maybe named_arg |
| """ |
| if kwargs: |
| return named_arg |
| ''' |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=node, args=("kwargs",)) |
| ): |
| self.checker.visit_functiondef(node) |
| |
| def test_warns_missing_args_numpy(self) -> None: |
| node = astroid.extract_node( |
| ''' |
| def my_func(named_arg, *args): |
| """The docstring |
| |
| Args |
| ---- |
| named_arg : object |
| Returned |
| |
| Returns |
| ------- |
| object or None |
| Maybe named_arg |
| """ |
| if args: |
| return named_arg |
| ''' |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=node, args=("args",)) |
| ): |
| self.checker.visit_functiondef(node) |
| |
| def test_warns_missing_kwargs_numpy(self) -> None: |
| node = astroid.extract_node( |
| ''' |
| def my_func(named_arg, **kwargs): |
| """The docstring |
| |
| Args |
| ---- |
| named_arg : object |
| Returned |
| |
| Returns |
| ------- |
| object or None |
| Maybe named_arg |
| """ |
| if kwargs: |
| return named_arg |
| ''' |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-param-doc", node=node, args=("kwargs",)) |
| ): |
| self.checker.visit_functiondef(node) |
| |
| def test_finds_args_without_type_sphinx(self) -> None: |
| node = astroid.extract_node( |
| ''' |
| def my_func(named_arg, *args): |
| """The docstring |
| |
| :param named_arg: Returned |
| :type named_arg: object |
| :param args: Optional arguments |
| :returns: Maybe named_arg |
| :rtype: object or None |
| """ |
| if args: |
| return named_arg |
| ''' |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_finds_kwargs_without_type_sphinx(self) -> None: |
| node = astroid.extract_node( |
| ''' |
| def my_func(named_arg, **kwargs): |
| """The docstring |
| |
| :param named_arg: Returned |
| :type named_arg: object |
| :param kwargs: Keyword arguments |
| :returns: Maybe named_arg |
| :rtype: object or None |
| """ |
| if kwargs: |
| return named_arg |
| ''' |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_finds_args_without_type_google(self) -> None: |
| node = astroid.extract_node( |
| ''' |
| def my_func(named_arg, *args): |
| """The docstring |
| |
| Args: |
| named_arg (object): Returned |
| *args: Optional arguments |
| |
| Returns: |
| object or None: Maybe named_arg |
| """ |
| if args: |
| return named_arg |
| ''' |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_finds_kwargs_without_type_google(self) -> None: |
| node = astroid.extract_node( |
| ''' |
| def my_func(named_arg, **kwargs): |
| """The docstring |
| |
| Args: |
| named_arg (object): Returned |
| **kwargs: Keyword arguments |
| |
| Returns: |
| object or None: Maybe named_arg |
| """ |
| if kwargs: |
| return named_arg |
| ''' |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_finds_args_without_type_numpy(self) -> None: |
| node = astroid.extract_node( |
| ''' |
| def my_func(named_arg, *args): |
| """The docstring |
| |
| Args |
| ---- |
| named_arg : object |
| Returned |
| args : |
| Optional Arguments |
| |
| Returns |
| ------- |
| object or None |
| Maybe named_arg |
| """ |
| if args: |
| return named_arg |
| ''' |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_finds_args_with_xref_type_google(self) -> None: |
| node = astroid.extract_node( |
| ''' |
| def my_func(named_arg, **kwargs): |
| """The docstring |
| |
| Args: |
| named_arg (`example.value`): Returned |
| **kwargs: Keyword arguments |
| |
| Returns: |
| `example.value`: Maybe named_arg |
| """ |
| if kwargs: |
| return named_arg |
| ''' |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_finds_args_with_xref_type_numpy(self) -> None: |
| node = astroid.extract_node( |
| ''' |
| def my_func(named_arg, *args): |
| """The docstring |
| |
| Args |
| ---- |
| named_arg : `example.value` |
| Returned |
| args : |
| Optional Arguments |
| |
| Returns |
| ------- |
| `example.value` |
| Maybe named_arg |
| """ |
| if args: |
| return named_arg |
| ''' |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_finds_kwargs_without_type_numpy(self) -> None: |
| node = astroid.extract_node( |
| ''' |
| def my_func(named_arg, **kwargs): |
| """The docstring |
| |
| Args |
| ---- |
| named_arg : object |
| Returned |
| kwargs : |
| Keyword arguments |
| |
| Returns |
| ------- |
| object or None |
| Maybe named_arg |
| """ |
| if kwargs: |
| return named_arg |
| ''' |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| CONTAINER_TYPES = [ |
| "dict(str,str)", |
| "dict[str,str]", |
| "tuple(int)", |
| "list[tokenize.TokenInfo]", |
| ] |
| |
| COMPLEX_TYPES = CONTAINER_TYPES + [ |
| "dict(str, str)", |
| "dict[str, str]", |
| "int or str", |
| "tuple(int or str)", |
| "tuple(int) or list(int)", |
| "tuple(int or str) or list(int or str)", |
| ] |
| |
| @pytest.mark.parametrize("complex_type", COMPLEX_TYPES) |
| def test_finds_multiple_types_sphinx(self, complex_type): |
| node = astroid.extract_node( |
| f''' |
| def my_func(named_arg): |
| """The docstring |
| |
| :param named_arg: Returned |
| :type named_arg: {complex_type} |
| |
| :returns: named_arg |
| :rtype: {complex_type} |
| """ |
| return named_arg |
| ''' |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| @pytest.mark.parametrize("complex_type", COMPLEX_TYPES) |
| def test_finds_multiple_types_google(self, complex_type): |
| node = astroid.extract_node( |
| f''' |
| def my_func(named_arg): |
| """The docstring |
| |
| Args: |
| named_arg ({complex_type}): Returned |
| |
| Returns: |
| {complex_type}: named_arg |
| """ |
| return named_arg |
| ''' |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| @pytest.mark.parametrize("complex_type", COMPLEX_TYPES) |
| def test_finds_multiple_types_numpy(self, complex_type): |
| node = astroid.extract_node( |
| f''' |
| def my_func(named_arg): |
| """The docstring |
| |
| Args |
| ---- |
| named_arg : {complex_type} |
| Returned |
| |
| Returns |
| ------- |
| {complex_type} |
| named_arg |
| """ |
| return named_arg |
| ''' |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| @pytest.mark.parametrize("container_type", CONTAINER_TYPES) |
| def test_finds_compact_container_types_sphinx(self, container_type): |
| node = astroid.extract_node( |
| f''' |
| def my_func(named_arg): |
| """The docstring |
| |
| :param {container_type} named_arg: Returned |
| |
| :returns: named_arg |
| :rtype: {container_type} |
| """ |
| return named_arg |
| ''' |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_ignores_optional_specifier_google(self) -> None: |
| node = astroid.extract_node( |
| ''' |
| def do_something(param1, param2, param3=(), param4=[], param5=[], param6=True): |
| """Do something. |
| |
| Args: |
| param1 (str): Description. |
| param2 (dict(str, int)): Description. |
| param3 (tuple(str), optional): Defaults to empty. Description. |
| param4 (List[str], optional): Defaults to empty. Description. |
| param5 (list[tuple(str)], optional): Defaults to empty. Description. |
| param6 (bool, optional): Defaults to True. Description. |
| |
| Returns: |
| int: Description. |
| """ |
| return param1, param2, param3, param4, param5, param6 |
| ''' |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_ignores_optional_specifier_numpy(self) -> None: |
| node = astroid.extract_node( |
| ''' |
| def do_something(param, param2='all'): |
| """Do something. |
| |
| Parameters |
| ---------- |
| param : str |
| Description. |
| param2 : str, optional |
| Description (the default is 'all'). |
| |
| Returns |
| ------- |
| int |
| Description. |
| """ |
| return param, param2 |
| ''' |
| ) |
| with self.assertNoMessages(): |
| 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) |
| |
| def test_finds_missing_raises_from_setter_sphinx(self) -> None: |
| """Example of a setter having missing raises documentation in |
| the Sphinx style docstring of the property |
| """ |
| property_node, node = astroid.extract_node( |
| """ |
| class Foo(object): |
| @property |
| def foo(self): #@ |
| '''docstring ... |
| |
| :type: int |
| ''' |
| return 10 |
| |
| @foo.setter |
| def foo(self, value): |
| raise AttributeError() #@ |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message( |
| msg_id="missing-raises-doc", |
| node=property_node, |
| args=("AttributeError",), |
| ) |
| ): |
| self.checker.visit_raise(node) |
| |
| def test_finds_missing_raises_from_setter_google(self) -> None: |
| """Example of a setter having missing raises documentation in |
| the Google style docstring of the property |
| """ |
| property_node, node = astroid.extract_node( |
| """ |
| class Foo(object): |
| @property |
| def foo(self): #@ |
| '''int: docstring |
| |
| Include a "Raises" section so that this is identified |
| as a Google docstring and not a Numpy docstring. |
| |
| Raises: |
| RuntimeError: Always |
| ''' |
| raise RuntimeError() |
| return 10 |
| |
| @foo.setter |
| def foo(self, value): |
| raise AttributeError() #@ |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message( |
| msg_id="missing-raises-doc", |
| node=property_node, |
| args=("AttributeError",), |
| ) |
| ): |
| self.checker.visit_raise(node) |
| |
| def test_finds_missing_raises_from_setter_numpy(self) -> None: |
| """Example of a setter having missing raises documentation in |
| the Numpy style docstring of the property |
| """ |
| property_node, node = astroid.extract_node( |
| """ |
| class Foo(object): |
| @property |
| def foo(self): #@ |
| '''int: docstring |
| |
| Include a "Raises" section so that this is identified |
| as a Numpy docstring and not a Google docstring. |
| |
| Raises |
| ------ |
| RuntimeError |
| Always |
| ''' |
| raise RuntimeError() |
| return 10 |
| |
| @foo.setter |
| def foo(self, value): |
| raise AttributeError() #@ |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message( |
| msg_id="missing-raises-doc", |
| node=property_node, |
| args=("AttributeError",), |
| ) |
| ): |
| self.checker.visit_raise(node) |
| |
| def test_finds_missing_raises_in_setter_sphinx(self) -> None: |
| """Example of a setter having missing raises documentation in |
| its own Sphinx style docstring |
| """ |
| setter_node, node = astroid.extract_node( |
| """ |
| class Foo(object): |
| @property |
| def foo(self): |
| '''docstring ... |
| |
| :type: int |
| :raises RuntimeError: Always |
| ''' |
| raise RuntimeError() |
| return 10 |
| |
| @foo.setter |
| def foo(self, value): #@ |
| '''setter docstring ... |
| |
| :type: None |
| ''' |
| raise AttributeError() #@ |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message( |
| msg_id="missing-raises-doc", node=setter_node, args=("AttributeError",) |
| ) |
| ): |
| self.checker.visit_raise(node) |
| |
| def test_finds_missing_raises_from_setter_google_2(self) -> None: |
| """Example of a setter having missing raises documentation in |
| its own Google style docstring of the property |
| """ |
| setter_node, node = astroid.extract_node( |
| """ |
| class Foo(object): |
| @property |
| def foo(self): |
| '''int: docstring ... |
| |
| Raises: |
| RuntimeError: Always |
| ''' |
| raise RuntimeError() |
| return 10 |
| |
| @foo.setter |
| def foo(self, value): #@ |
| '''setter docstring ... |
| |
| Raises: |
| RuntimeError: Never |
| ''' |
| if True: |
| raise AttributeError() #@ |
| raise RuntimeError() |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message( |
| msg_id="missing-raises-doc", node=setter_node, args=("AttributeError",) |
| ) |
| ): |
| self.checker.visit_raise(node) |
| |
| def test_finds_missing_raises_from_setter_numpy_2(self) -> None: |
| """Example of a setter having missing raises documentation in |
| its own Numpy style docstring of the property |
| """ |
| setter_node, node = astroid.extract_node( |
| """ |
| class Foo(object): |
| @property |
| def foo(self): |
| '''int: docstring ... |
| |
| Raises |
| ------ |
| RuntimeError |
| Always |
| ''' |
| raise RuntimeError() |
| return 10 |
| |
| @foo.setter |
| def foo(self, value): #@ |
| '''setter docstring ... |
| |
| Raises |
| ------ |
| RuntimeError |
| Never |
| ''' |
| if True: |
| raise AttributeError() #@ |
| raise RuntimeError() |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message( |
| msg_id="missing-raises-doc", node=setter_node, args=("AttributeError",) |
| ) |
| ): |
| self.checker.visit_raise(node) |
| |
| def test_finds_property_return_type_sphinx(self) -> None: |
| """Example of a property having return documentation in |
| a Sphinx style docstring |
| """ |
| node = astroid.extract_node( |
| """ |
| class Foo(object): |
| @property |
| def foo(self): #@ |
| '''docstring ... |
| |
| :type: int |
| ''' |
| return 10 |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_finds_property_return_type_google(self) -> None: |
| """Example of a property having return documentation in |
| a Google style docstring |
| """ |
| node = astroid.extract_node( |
| """ |
| class Foo(object): |
| @property |
| def foo(self): #@ |
| '''int: docstring ... |
| |
| Raises: |
| RuntimeError: Always |
| ''' |
| raise RuntimeError() |
| return 10 |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_finds_property_return_type_numpy(self) -> None: |
| """Example of a property having return documentation in |
| a numpy style docstring |
| """ |
| node = astroid.extract_node( |
| """ |
| class Foo(object): |
| @property |
| def foo(self): #@ |
| '''int: docstring ... |
| |
| Raises |
| ------ |
| RuntimeError |
| Always |
| ''' |
| raise RuntimeError() |
| return 10 |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_finds_annotation_property_return_type_sphinx(self) -> None: |
| """Example of a property having missing return documentation in |
| a Sphinx style docstring |
| """ |
| _, node = astroid.extract_node( |
| """ |
| class Foo(object): |
| @property |
| def foo(self) -> int: #@ |
| '''docstring ... |
| |
| :raises RuntimeError: Always |
| ''' |
| raise RuntimeError() |
| return 10 #@ |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_return(node) |
| |
| def test_finds_missing_property_return_type_sphinx(self) -> None: |
| """Example of a property having missing return documentation in |
| a Sphinx style docstring |
| """ |
| property_node, node = astroid.extract_node( |
| """ |
| class Foo(object): |
| @property |
| def foo(self): #@ |
| '''docstring ... |
| |
| :raises RuntimeError: Always |
| ''' |
| raise RuntimeError() |
| return 10 #@ |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-return-type-doc", node=property_node) |
| ): |
| self.checker.visit_return(node) |
| |
| def test_finds_annotation_property_return_type_google(self) -> None: |
| """Example of a property having return documentation in |
| a Google style docstring |
| """ |
| _, node = astroid.extract_node( |
| """ |
| class Foo(object): |
| @property |
| def foo(self) -> int: #@ |
| '''docstring ... |
| |
| Raises: |
| RuntimeError: Always |
| ''' |
| raise RuntimeError() |
| return 10 #@ |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_return(node) |
| |
| def test_finds_missing_property_return_type_google(self) -> None: |
| """Example of a property having return documentation in |
| a Google style docstring |
| """ |
| property_node, node = astroid.extract_node( |
| """ |
| class Foo(object): |
| @property |
| def foo(self): #@ |
| '''docstring ... |
| |
| Raises: |
| RuntimeError: Always |
| ''' |
| raise RuntimeError() |
| return 10 #@ |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-return-type-doc", node=property_node) |
| ): |
| self.checker.visit_return(node) |
| |
| def test_finds_missing_property_return_type_numpy(self) -> None: |
| """Example of a property having return documentation in |
| a numpy style docstring |
| """ |
| property_node, node = astroid.extract_node( |
| """ |
| class Foo(object): |
| @property |
| def foo(self): #@ |
| '''docstring ... |
| |
| Raises |
| ------ |
| RuntimeError |
| Always |
| ''' |
| raise RuntimeError() |
| return 10 #@ |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-return-type-doc", node=property_node) |
| ): |
| self.checker.visit_return(node) |
| |
| def test_ignores_non_property_return_type_sphinx(self) -> None: |
| """Example of a class function trying to use `type` as return |
| documentation in a Sphinx style docstring |
| """ |
| func_node, node = astroid.extract_node( |
| """ |
| class Foo(object): |
| def foo(self): #@ |
| '''docstring ... |
| |
| :type: int |
| ''' |
| return 10 #@ |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-return-doc", node=func_node), |
| Message(msg_id="missing-return-type-doc", node=func_node), |
| ): |
| self.checker.visit_return(node) |
| |
| def test_ignores_non_property_return_type_google(self) -> None: |
| """Example of a class function trying to use `type` as return |
| documentation in a Google style docstring |
| """ |
| func_node, node = astroid.extract_node( |
| """ |
| class Foo(object): |
| def foo(self): #@ |
| '''int: docstring ... |
| |
| Raises: |
| RuntimeError: Always |
| ''' |
| raise RuntimeError() |
| return 10 #@ |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-return-doc", node=func_node), |
| Message(msg_id="missing-return-type-doc", node=func_node), |
| ): |
| self.checker.visit_return(node) |
| |
| def test_ignores_non_property_return_type_numpy(self) -> None: |
| """Example of a class function trying to use `type` as return |
| documentation in a numpy style docstring |
| """ |
| func_node, node = astroid.extract_node( |
| """ |
| class Foo(object): |
| def foo(self): #@ |
| '''int: docstring ... |
| |
| Raises |
| ------ |
| RuntimeError |
| Always |
| ''' |
| raise RuntimeError() |
| return 10 #@ |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-return-doc", node=func_node), |
| Message(msg_id="missing-return-type-doc", node=func_node), |
| ): |
| self.checker.visit_return(node) |
| |
| def test_non_property_annotation_return_type_numpy(self) -> None: |
| """Example of a class function trying to use `type` as return |
| documentation in a numpy style docstring |
| """ |
| func_node, node = astroid.extract_node( |
| """ |
| class Foo(object): |
| def foo(self) -> int: #@ |
| '''int: docstring ... |
| |
| Raises |
| ------ |
| RuntimeError |
| Always |
| ''' |
| raise RuntimeError() |
| return 10 #@ |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="missing-return-doc", node=func_node) |
| ): |
| self.checker.visit_return(node) |
| |
| def test_ignores_return_in_abstract_method_sphinx(self) -> None: |
| """Example of an abstract method documenting the return type that an |
| implementation should return. |
| """ |
| node = astroid.extract_node( |
| """ |
| import abc |
| class Foo(object): |
| @abc.abstractmethod |
| def foo(self): #@ |
| '''docstring ... |
| |
| :returns: Ten |
| :rtype: int |
| ''' |
| return 10 |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_ignores_return_in_abstract_method_google(self) -> None: |
| """Example of an abstract method documenting the return type that an |
| implementation should return. |
| """ |
| node = astroid.extract_node( |
| """ |
| import abc |
| class Foo(object): |
| @abc.abstractmethod |
| def foo(self): #@ |
| '''docstring ... |
| |
| Returns: |
| int: Ten |
| ''' |
| return 10 |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_ignores_return_in_abstract_method_numpy(self) -> None: |
| """Example of an abstract method documenting the return type that an |
| implementation should return. |
| """ |
| node = astroid.extract_node( |
| """ |
| import abc |
| class Foo(object): |
| @abc.abstractmethod |
| def foo(self): #@ |
| '''docstring ... |
| |
| Returns |
| ------- |
| int |
| Ten |
| ''' |
| return 10 |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_ignores_raise_notimplementederror_sphinx(self) -> None: |
| """Example of an abstract""" |
| node = astroid.extract_node( |
| """ |
| class Foo(object): |
| def foo(self, arg): #@ |
| '''docstring ... |
| |
| :param arg: An argument. |
| :type arg: int |
| ''' |
| raise NotImplementedError() |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_ignores_return_in_abstract_method_google_2(self) -> None: |
| """Example of a method documenting the return type that an |
| implementation should return. |
| """ |
| node = astroid.extract_node( |
| """ |
| class Foo(object): |
| def foo(self, arg): #@ |
| '''docstring ... |
| |
| Args: |
| arg (int): An argument. |
| ''' |
| raise NotImplementedError() |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_ignores_return_in_abstract_method_numpy_2(self) -> None: |
| """Example of a method documenting the return type that an |
| implementation should return. |
| """ |
| node = astroid.extract_node( |
| """ |
| class Foo(object): |
| def foo(self, arg): #@ |
| '''docstring ... |
| |
| Parameters |
| ---------- |
| arg : int |
| An argument. |
| ''' |
| raise NotImplementedError() |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_ignores_ignored_argument_names_sphinx(self) -> None: |
| """Example of a method documenting the return type that an |
| implementation should return. |
| """ |
| node = astroid.extract_node( |
| """ |
| class Foo(object): |
| def foo(self, arg, _): #@ |
| '''docstring ... |
| |
| :param arg: An argument. |
| :type arg: int |
| ''' |
| pass |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_ignores_ignored_argument_names_google(self) -> None: |
| """Example of a method documenting the return type that an |
| implementation should return. |
| """ |
| node = astroid.extract_node( |
| """ |
| class Foo(object): |
| def foo(self, arg, _): #@ |
| '''docstring ... |
| |
| Args: |
| arg (int): An argument. |
| ''' |
| pass |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_ignores_ignored_argument_names_numpy(self) -> None: |
| """Example of a method documenting the return type that an |
| implementation should return. |
| """ |
| node = astroid.extract_node( |
| """ |
| class Foo(object): |
| def foo(self, arg, _): #@ |
| '''docstring ... |
| |
| Parameters |
| ---------- |
| arg : int |
| An argument. |
| ''' |
| pass |
| """ |
| ) |
| with self.assertNoMessages(): |
| self.checker.visit_functiondef(node) |
| |
| def test_useless_docs_ignored_argument_names_sphinx(self) -> None: |
| """Example of a method documenting the return type that an |
| implementation should return. |
| """ |
| node = astroid.extract_node( |
| """ |
| class Foo(object): |
| def foo(self, arg, _, _ignored): #@ |
| '''docstring ... |
| |
| :param arg: An argument. |
| :type arg: int |
| |
| :param _: Another argument. |
| :type _: float |
| |
| :param _ignored: Ignored argument. |
| ''' |
| pass |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="useless-type-doc", node=node, args=("_",)), |
| Message(msg_id="useless-param-doc", node=node, args=("_, _ignored",)), |
| ): |
| self.checker.visit_functiondef(node) |
| |
| def test_useless_docs_ignored_argument_names_google(self) -> None: |
| """Example of a method documenting the return type that an |
| implementation should return. |
| """ |
| node = astroid.extract_node( |
| """ |
| class Foo(object): |
| def foo(self, arg, _, _ignored): #@ |
| '''docstring ... |
| |
| Args: |
| arg (int): An argument. |
| _ (float): Another argument. |
| _ignored: Ignored argument. |
| ''' |
| pass |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="useless-type-doc", node=node, args=("_",)), |
| Message(msg_id="useless-param-doc", node=node, args=("_, _ignored",)), |
| ): |
| self.checker.visit_functiondef(node) |
| |
| def test_useless_docs_ignored_argument_names_numpy(self) -> None: |
| """Example of a method documenting the return type that an |
| implementation should return. |
| """ |
| node = astroid.extract_node( |
| """ |
| class Foo(object): |
| def foo(self, arg, _, _ignored): #@ |
| '''docstring ... |
| |
| Parameters |
| ---------- |
| arg : int |
| An argument. |
| |
| _ : float |
| Another argument. |
| |
| _ignored : |
| Ignored Argument |
| ''' |
| pass |
| """ |
| ) |
| with self.assertAddsMessages( |
| Message(msg_id="useless-type-doc", node=node, args=("_",)), |
| Message(msg_id="useless-param-doc", node=node, args=("_, _ignored",)), |
| ): |
| self.checker.visit_functiondef(node) |
| |
| @set_config(no_docstring_rgx=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) |
| |
| @set_config(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) |