diff options
Diffstat (limited to 'pylint/extensions/docparams.py')
-rw-r--r-- | pylint/extensions/docparams.py | 361 |
1 files changed, 193 insertions, 168 deletions
diff --git a/pylint/extensions/docparams.py b/pylint/extensions/docparams.py index 67fcc82af..d55515a56 100644 --- a/pylint/extensions/docparams.py +++ b/pylint/extensions/docparams.py @@ -49,95 +49,141 @@ class DocstringParameterChecker(BaseChecker): :param linter: linter object :type linter: :class:`pylint.lint.PyLinter` """ + __implements__ = IAstroidChecker - name = 'parameter_documentation' + name = "parameter_documentation" msgs = { - 'W9005': ('"%s" has constructor parameters documented in class and __init__', - 'multiple-constructor-doc', - 'Please remove parameter declarations in the class or constructor.'), - 'W9006': ('"%s" not documented as being raised', - 'missing-raises-doc', - 'Please document exceptions for all raised exception types.'), - 'W9008': ('Redundant returns documentation', - 'redundant-returns-doc', - 'Please remove the return/rtype documentation from this method.'), - 'W9010': ('Redundant yields documentation', - 'redundant-yields-doc', - 'Please remove the yields documentation from this method.'), - 'W9011': ('Missing return documentation', - 'missing-return-doc', - 'Please add documentation about what this method returns.', - {'old_names': [('W9007', 'missing-returns-doc')]}), - 'W9012': ('Missing return type documentation', - 'missing-return-type-doc', - 'Please document the type returned by this method.', - # we can't use the same old_name for two different warnings - # {'old_names': [('W9007', 'missing-returns-doc')]}, - ), - 'W9013': ('Missing yield documentation', - 'missing-yield-doc', - 'Please add documentation about what this generator yields.', - {'old_names': [('W9009', 'missing-yields-doc')]}), - 'W9014': ('Missing yield type documentation', - 'missing-yield-type-doc', - 'Please document the type yielded by this method.', - # we can't use the same old_name for two different warnings - # {'old_names': [('W9009', 'missing-yields-doc')]}, - ), - 'W9015': ('"%s" missing in parameter documentation', - 'missing-param-doc', - 'Please add parameter declarations for all parameters.', - {'old_names': [('W9003', 'missing-param-doc')]}), - 'W9016': ('"%s" missing in parameter type documentation', - 'missing-type-doc', - 'Please add parameter type declarations for all parameters.', - {'old_names': [('W9004', 'missing-type-doc')]}), - 'W9017': ('"%s" differing in parameter documentation', - 'differing-param-doc', - 'Please check parameter names in declarations.', - ), - 'W9018': ('"%s" differing in parameter type documentation', - 'differing-type-doc', - 'Please check parameter names in type declarations.', - ), + "W9005": ( + '"%s" has constructor parameters documented in class and __init__', + "multiple-constructor-doc", + "Please remove parameter declarations in the class or constructor.", + ), + "W9006": ( + '"%s" not documented as being raised', + "missing-raises-doc", + "Please document exceptions for all raised exception types.", + ), + "W9008": ( + "Redundant returns documentation", + "redundant-returns-doc", + "Please remove the return/rtype documentation from this method.", + ), + "W9010": ( + "Redundant yields documentation", + "redundant-yields-doc", + "Please remove the yields documentation from this method.", + ), + "W9011": ( + "Missing return documentation", + "missing-return-doc", + "Please add documentation about what this method returns.", + {"old_names": [("W9007", "missing-returns-doc")]}, + ), + "W9012": ( + "Missing return type documentation", + "missing-return-type-doc", + "Please document the type returned by this method.", + # we can't use the same old_name for two different warnings + # {'old_names': [('W9007', 'missing-returns-doc')]}, + ), + "W9013": ( + "Missing yield documentation", + "missing-yield-doc", + "Please add documentation about what this generator yields.", + {"old_names": [("W9009", "missing-yields-doc")]}, + ), + "W9014": ( + "Missing yield type documentation", + "missing-yield-type-doc", + "Please document the type yielded by this method.", + # we can't use the same old_name for two different warnings + # {'old_names': [('W9009', 'missing-yields-doc')]}, + ), + "W9015": ( + '"%s" missing in parameter documentation', + "missing-param-doc", + "Please add parameter declarations for all parameters.", + {"old_names": [("W9003", "missing-param-doc")]}, + ), + "W9016": ( + '"%s" missing in parameter type documentation', + "missing-type-doc", + "Please add parameter type declarations for all parameters.", + {"old_names": [("W9004", "missing-type-doc")]}, + ), + "W9017": ( + '"%s" differing in parameter documentation', + "differing-param-doc", + "Please check parameter names in declarations.", + ), + "W9018": ( + '"%s" differing in parameter type documentation', + "differing-type-doc", + "Please check parameter names in type declarations.", + ), } - options = (('accept-no-param-doc', - {'default': True, 'type' : 'yn', 'metavar' : '<y or n>', - 'help': 'Whether to accept totally missing parameter ' - 'documentation in the docstring of a function that has ' - 'parameters.' - }), - ('accept-no-raise-doc', - {'default': True, 'type' : 'yn', 'metavar' : '<y or n>', - 'help': 'Whether to accept totally missing raises ' - 'documentation in the docstring of a function that ' - 'raises an exception.' - }), - ('accept-no-return-doc', - {'default': True, 'type' : 'yn', 'metavar' : '<y or n>', - 'help': 'Whether to accept totally missing return ' - 'documentation in the docstring of a function that ' - 'returns a statement.' - }), - ('accept-no-yields-doc', - {'default': True, 'type' : 'yn', 'metavar': '<y or n>', - 'help': 'Whether to accept totally missing yields ' - 'documentation in the docstring of a generator.' - }), - ('default-docstring-type', - {'type': 'choice', 'default': 'default', - 'choices': list(utils.DOCSTRING_TYPES), - 'help': 'If the docstring type cannot be guessed ' - 'the specified docstring type will be used.' - }), - ) + options = ( + ( + "accept-no-param-doc", + { + "default": True, + "type": "yn", + "metavar": "<y or n>", + "help": "Whether to accept totally missing parameter " + "documentation in the docstring of a function that has " + "parameters.", + }, + ), + ( + "accept-no-raise-doc", + { + "default": True, + "type": "yn", + "metavar": "<y or n>", + "help": "Whether to accept totally missing raises " + "documentation in the docstring of a function that " + "raises an exception.", + }, + ), + ( + "accept-no-return-doc", + { + "default": True, + "type": "yn", + "metavar": "<y or n>", + "help": "Whether to accept totally missing return " + "documentation in the docstring of a function that " + "returns a statement.", + }, + ), + ( + "accept-no-yields-doc", + { + "default": True, + "type": "yn", + "metavar": "<y or n>", + "help": "Whether to accept totally missing yields " + "documentation in the docstring of a generator.", + }, + ), + ( + "default-docstring-type", + { + "type": "choice", + "default": "default", + "choices": list(utils.DOCSTRING_TYPES), + "help": "If the docstring type cannot be guessed " + "the specified docstring type will be used.", + }, + ), + ) priority = -2 - constructor_names = {'__init__', '__new__'} - not_needed_param_in_docstring = {'self', 'cls'} + constructor_names = {"__init__", "__new__"} + not_needed_param_in_docstring = {"self", "cls"} def visit_functiondef(self, node): """Called for function and method definitions (def). @@ -145,9 +191,7 @@ class DocstringParameterChecker(BaseChecker): :param node: Node for a function or method definition in the AST :type node: :class:`astroid.scoped_nodes.Function` """ - node_doc = utils.docstringify( - node.doc, self.config.default_docstring_type, - ) + node_doc = utils.docstringify(node.doc, self.config.default_docstring_type) self.check_functiondef_params(node, node_doc) self.check_functiondef_returns(node, node_doc) self.check_functiondef_yields(node, node_doc) @@ -158,50 +202,49 @@ class DocstringParameterChecker(BaseChecker): class_node = checker_utils.node_frame_class(node) if class_node is not None: class_doc = utils.docstringify( - class_node.doc, self.config.default_docstring_type, + class_node.doc, self.config.default_docstring_type ) self.check_single_constructor_params(class_doc, node_doc, class_node) # __init__ or class docstrings can have no parameters documented # as long as the other documents them. node_allow_no_param = ( - class_doc.has_params() or - class_doc.params_documented_elsewhere() or - None + class_doc.has_params() + or class_doc.params_documented_elsewhere() + or None ) class_allow_no_param = ( - node_doc.has_params() or - node_doc.params_documented_elsewhere() or - None + node_doc.has_params() + or node_doc.params_documented_elsewhere() + or None ) self.check_arguments_in_docstring( - class_doc, node.args, class_node, class_allow_no_param) + class_doc, node.args, class_node, class_allow_no_param + ) self.check_arguments_in_docstring( - node_doc, node.args, node, node_allow_no_param) + node_doc, node.args, node, node_allow_no_param + ) def check_functiondef_returns(self, node, node_doc): - if ((not node_doc.supports_yields and node.is_generator()) - or node.is_abstract()): + if (not node_doc.supports_yields and node.is_generator()) or node.is_abstract(): return return_nodes = node.nodes_of_class(astroid.Return) - if ((node_doc.has_returns() or node_doc.has_rtype()) and - not any(utils.returns_something(ret_node) for ret_node in return_nodes)): - self.add_message( - 'redundant-returns-doc', - node=node) + if (node_doc.has_returns() or node_doc.has_rtype()) and not any( + utils.returns_something(ret_node) for ret_node in return_nodes + ): + self.add_message("redundant-returns-doc", node=node) def check_functiondef_yields(self, node, node_doc): if not node_doc.supports_yields or node.is_abstract(): return - if ((node_doc.has_yields() or node_doc.has_yields_type()) and - not node.is_generator()): - self.add_message( - 'redundant-yields-doc', - node=node) + if ( + node_doc.has_yields() or node_doc.has_yields_type() + ) and not node.is_generator(): + self.add_message("redundant-yields-doc", node=node) def visit_raise(self, node): func_node = node.frame() @@ -219,9 +262,7 @@ class DocstringParameterChecker(BaseChecker): if property_: func_node = property_ - doc = utils.docstringify( - func_node.doc, self.config.default_docstring_type, - ) + doc = utils.docstringify(func_node.doc, self.config.default_docstring_type) if not doc.is_valid(): if doc.doc: self._handle_no_raise_doc(expected_excs, func_node) @@ -239,39 +280,27 @@ class DocstringParameterChecker(BaseChecker): if not isinstance(func_node, astroid.FunctionDef): return - doc = utils.docstringify( - func_node.doc, self.config.default_docstring_type, - ) + doc = utils.docstringify(func_node.doc, self.config.default_docstring_type) if not doc.is_valid() and self.config.accept_no_return_doc: return is_property = checker_utils.decorated_with_property(func_node) - if not (doc.has_returns() or - (doc.has_property_returns() and is_property)): - self.add_message( - 'missing-return-doc', - node=func_node - ) + if not (doc.has_returns() or (doc.has_property_returns() and is_property)): + self.add_message("missing-return-doc", node=func_node) if func_node.returns: return - if not (doc.has_rtype() or - (doc.has_property_type() and is_property)): - self.add_message( - 'missing-return-type-doc', - node=func_node - ) + if not (doc.has_rtype() or (doc.has_property_type() and is_property)): + self.add_message("missing-return-type-doc", node=func_node) def visit_yield(self, node): func_node = node.frame() if not isinstance(func_node, astroid.FunctionDef): return - doc = utils.docstringify( - func_node.doc, self.config.default_docstring_type, - ) + doc = utils.docstringify(func_node.doc, self.config.default_docstring_type) if not doc.is_valid() and self.config.accept_no_yields_doc: return @@ -283,22 +312,17 @@ class DocstringParameterChecker(BaseChecker): doc_has_yields_type = doc.has_rtype() if not doc_has_yields: - self.add_message( - 'missing-yield-doc', - node=func_node - ) + self.add_message("missing-yield-doc", node=func_node) if not doc_has_yields_type: - self.add_message( - 'missing-yield-type-doc', - node=func_node - ) + self.add_message("missing-yield-type-doc", node=func_node) def visit_yieldfrom(self, node): self.visit_yield(node) - def check_arguments_in_docstring(self, doc, arguments_node, warning_node, - accept_no_param_doc=None): + def check_arguments_in_docstring( + self, doc, arguments_node, warning_node, accept_no_param_doc=None + ): """Check that all parameters in a function, method or class constructor on the one hand and the parameters mentioned in the parameter documentation (e.g. the Sphinx tags 'param' and 'type') on the other @@ -344,8 +368,7 @@ class DocstringParameterChecker(BaseChecker): # Collect the function arguments. expected_argument_names = {arg.name for arg in arguments_node.args} expected_argument_names.update(arg.name for arg in arguments_node.kwonlyargs) - not_needed_type_in_docstring = ( - self.not_needed_param_in_docstring.copy()) + not_needed_type_in_docstring = self.not_needed_param_in_docstring.copy() if arguments_node.vararg is not None: expected_argument_names.add(arguments_node.vararg) @@ -356,12 +379,10 @@ class DocstringParameterChecker(BaseChecker): params_with_doc, params_with_type = doc.match_param_docs() # Tolerate no parameter documentation at all. - if (not params_with_doc and not params_with_type - and accept_no_param_doc): + if not params_with_doc and not params_with_type and accept_no_param_doc: tolerate_missing_params = True - def _compare_missing_args(found_argument_names, message_id, - not_needed_names): + def _compare_missing_args(found_argument_names, message_id, not_needed_names): """Compare the found argument names with the expected ones and generate a message if there are arguments missing. @@ -375,17 +396,16 @@ class DocstringParameterChecker(BaseChecker): """ if not tolerate_missing_params: missing_argument_names = ( - (expected_argument_names - found_argument_names) - - not_needed_names) + expected_argument_names - found_argument_names + ) - not_needed_names if missing_argument_names: self.add_message( message_id, - args=(', '.join( - sorted(missing_argument_names)),), - node=warning_node) + args=(", ".join(sorted(missing_argument_names)),), + node=warning_node, + ) - def _compare_different_args(found_argument_names, message_id, - not_needed_names): + def _compare_different_args(found_argument_names, message_id, not_needed_names): """Compare the found argument names with the expected ones and generate a message if there are extra arguments found. @@ -399,36 +419,41 @@ class DocstringParameterChecker(BaseChecker): """ differing_argument_names = ( (expected_argument_names ^ found_argument_names) - - not_needed_names - expected_argument_names) + - not_needed_names + - expected_argument_names + ) if differing_argument_names: self.add_message( message_id, - args=(', '.join( - sorted(differing_argument_names)),), - node=warning_node) + args=(", ".join(sorted(differing_argument_names)),), + node=warning_node, + ) - _compare_missing_args(params_with_doc, 'missing-param-doc', - self.not_needed_param_in_docstring) + _compare_missing_args( + params_with_doc, "missing-param-doc", self.not_needed_param_in_docstring + ) for index, arg_name in enumerate(arguments_node.args): if arguments_node.annotations[index]: params_with_type.add(arg_name.name) - _compare_missing_args(params_with_type, 'missing-type-doc', - not_needed_type_in_docstring) + _compare_missing_args( + params_with_type, "missing-type-doc", not_needed_type_in_docstring + ) - _compare_different_args(params_with_doc, 'differing-param-doc', - self.not_needed_param_in_docstring) - _compare_different_args(params_with_type, 'differing-type-doc', - not_needed_type_in_docstring) + _compare_different_args( + params_with_doc, "differing-param-doc", self.not_needed_param_in_docstring + ) + _compare_different_args( + params_with_type, "differing-type-doc", not_needed_type_in_docstring + ) def check_single_constructor_params(self, class_doc, init_doc, class_node): if class_doc.has_params() and init_doc.has_params(): self.add_message( - 'multiple-constructor-doc', - args=(class_node.name,), - node=class_node) + "multiple-constructor-doc", args=(class_node.name,), node=class_node + ) def _handle_no_raise_doc(self, excs, node): if self.config.accept_no_raise_doc: @@ -448,7 +473,7 @@ class DocstringParameterChecker(BaseChecker): """ if node.is_abstract(): try: - missing_excs.remove('NotImplementedError') + missing_excs.remove("NotImplementedError") except KeyError: pass @@ -456,9 +481,9 @@ class DocstringParameterChecker(BaseChecker): return self.add_message( - 'missing-raises-doc', - args=(', '.join(sorted(missing_excs)),), - node=node) + "missing-raises-doc", args=(", ".join(sorted(missing_excs)),), node=node + ) + def register(linter): """Required method to auto register this checker. |