summaryrefslogtreecommitdiff
path: root/pylint/extensions/docparams.py
diff options
context:
space:
mode:
Diffstat (limited to 'pylint/extensions/docparams.py')
-rw-r--r--pylint/extensions/docparams.py361
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.