summaryrefslogtreecommitdiff
path: root/venv/Lib/site-packages/pylint/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'venv/Lib/site-packages/pylint/extensions')
-rw-r--r--venv/Lib/site-packages/pylint/extensions/__init__.py0
-rw-r--r--venv/Lib/site-packages/pylint/extensions/__pycache__/__init__.cpython-37.pycbin0 -> 181 bytes
-rw-r--r--venv/Lib/site-packages/pylint/extensions/__pycache__/_check_docs_utils.cpython-37.pycbin0 -> 18819 bytes
-rw-r--r--venv/Lib/site-packages/pylint/extensions/__pycache__/bad_builtin.cpython-37.pycbin0 -> 1967 bytes
-rw-r--r--venv/Lib/site-packages/pylint/extensions/__pycache__/broad_try_clause.cpython-37.pycbin0 -> 1702 bytes
-rw-r--r--venv/Lib/site-packages/pylint/extensions/__pycache__/check_docs.cpython-37.pycbin0 -> 685 bytes
-rw-r--r--venv/Lib/site-packages/pylint/extensions/__pycache__/check_elif.cpython-37.pycbin0 -> 2647 bytes
-rw-r--r--venv/Lib/site-packages/pylint/extensions/__pycache__/comparetozero.cpython-37.pycbin0 -> 1959 bytes
-rw-r--r--venv/Lib/site-packages/pylint/extensions/__pycache__/docparams.cpython-37.pycbin0 -> 14746 bytes
-rw-r--r--venv/Lib/site-packages/pylint/extensions/__pycache__/docstyle.cpython-37.pycbin0 -> 2503 bytes
-rw-r--r--venv/Lib/site-packages/pylint/extensions/__pycache__/emptystring.cpython-37.pycbin0 -> 2035 bytes
-rw-r--r--venv/Lib/site-packages/pylint/extensions/__pycache__/mccabe.cpython-37.pycbin0 -> 5579 bytes
-rw-r--r--venv/Lib/site-packages/pylint/extensions/__pycache__/overlapping_exceptions.cpython-37.pycbin0 -> 2604 bytes
-rw-r--r--venv/Lib/site-packages/pylint/extensions/__pycache__/redefined_variable_type.cpython-37.pycbin0 -> 3248 bytes
-rw-r--r--venv/Lib/site-packages/pylint/extensions/_check_docs_utils.py792
-rw-r--r--venv/Lib/site-packages/pylint/extensions/bad_builtin.py69
-rw-r--r--venv/Lib/site-packages/pylint/extensions/broad_try_clause.py59
-rw-r--r--venv/Lib/site-packages/pylint/extensions/check_docs.py23
-rw-r--r--venv/Lib/site-packages/pylint/extensions/check_elif.py77
-rw-r--r--venv/Lib/site-packages/pylint/extensions/comparetozero.py74
-rw-r--r--venv/Lib/site-packages/pylint/extensions/docparams.py536
-rw-r--r--venv/Lib/site-packages/pylint/extensions/docstyle.py89
-rw-r--r--venv/Lib/site-packages/pylint/extensions/emptystring.py74
-rw-r--r--venv/Lib/site-packages/pylint/extensions/mccabe.py196
-rw-r--r--venv/Lib/site-packages/pylint/extensions/overlapping_exceptions.py88
-rw-r--r--venv/Lib/site-packages/pylint/extensions/redefined_variable_type.py116
26 files changed, 2193 insertions, 0 deletions
diff --git a/venv/Lib/site-packages/pylint/extensions/__init__.py b/venv/Lib/site-packages/pylint/extensions/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/__init__.py
diff --git a/venv/Lib/site-packages/pylint/extensions/__pycache__/__init__.cpython-37.pyc b/venv/Lib/site-packages/pylint/extensions/__pycache__/__init__.cpython-37.pyc
new file mode 100644
index 0000000..03323e7
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/__pycache__/__init__.cpython-37.pyc
Binary files differ
diff --git a/venv/Lib/site-packages/pylint/extensions/__pycache__/_check_docs_utils.cpython-37.pyc b/venv/Lib/site-packages/pylint/extensions/__pycache__/_check_docs_utils.cpython-37.pyc
new file mode 100644
index 0000000..271e216
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/__pycache__/_check_docs_utils.cpython-37.pyc
Binary files differ
diff --git a/venv/Lib/site-packages/pylint/extensions/__pycache__/bad_builtin.cpython-37.pyc b/venv/Lib/site-packages/pylint/extensions/__pycache__/bad_builtin.cpython-37.pyc
new file mode 100644
index 0000000..bb50903
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/__pycache__/bad_builtin.cpython-37.pyc
Binary files differ
diff --git a/venv/Lib/site-packages/pylint/extensions/__pycache__/broad_try_clause.cpython-37.pyc b/venv/Lib/site-packages/pylint/extensions/__pycache__/broad_try_clause.cpython-37.pyc
new file mode 100644
index 0000000..cd3cd71
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/__pycache__/broad_try_clause.cpython-37.pyc
Binary files differ
diff --git a/venv/Lib/site-packages/pylint/extensions/__pycache__/check_docs.cpython-37.pyc b/venv/Lib/site-packages/pylint/extensions/__pycache__/check_docs.cpython-37.pyc
new file mode 100644
index 0000000..9730100
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/__pycache__/check_docs.cpython-37.pyc
Binary files differ
diff --git a/venv/Lib/site-packages/pylint/extensions/__pycache__/check_elif.cpython-37.pyc b/venv/Lib/site-packages/pylint/extensions/__pycache__/check_elif.cpython-37.pyc
new file mode 100644
index 0000000..030378b
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/__pycache__/check_elif.cpython-37.pyc
Binary files differ
diff --git a/venv/Lib/site-packages/pylint/extensions/__pycache__/comparetozero.cpython-37.pyc b/venv/Lib/site-packages/pylint/extensions/__pycache__/comparetozero.cpython-37.pyc
new file mode 100644
index 0000000..83eaae3
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/__pycache__/comparetozero.cpython-37.pyc
Binary files differ
diff --git a/venv/Lib/site-packages/pylint/extensions/__pycache__/docparams.cpython-37.pyc b/venv/Lib/site-packages/pylint/extensions/__pycache__/docparams.cpython-37.pyc
new file mode 100644
index 0000000..3d447e1
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/__pycache__/docparams.cpython-37.pyc
Binary files differ
diff --git a/venv/Lib/site-packages/pylint/extensions/__pycache__/docstyle.cpython-37.pyc b/venv/Lib/site-packages/pylint/extensions/__pycache__/docstyle.cpython-37.pyc
new file mode 100644
index 0000000..e6d0d7d
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/__pycache__/docstyle.cpython-37.pyc
Binary files differ
diff --git a/venv/Lib/site-packages/pylint/extensions/__pycache__/emptystring.cpython-37.pyc b/venv/Lib/site-packages/pylint/extensions/__pycache__/emptystring.cpython-37.pyc
new file mode 100644
index 0000000..f5f4892
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/__pycache__/emptystring.cpython-37.pyc
Binary files differ
diff --git a/venv/Lib/site-packages/pylint/extensions/__pycache__/mccabe.cpython-37.pyc b/venv/Lib/site-packages/pylint/extensions/__pycache__/mccabe.cpython-37.pyc
new file mode 100644
index 0000000..cb64a4d
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/__pycache__/mccabe.cpython-37.pyc
Binary files differ
diff --git a/venv/Lib/site-packages/pylint/extensions/__pycache__/overlapping_exceptions.cpython-37.pyc b/venv/Lib/site-packages/pylint/extensions/__pycache__/overlapping_exceptions.cpython-37.pyc
new file mode 100644
index 0000000..f099683
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/__pycache__/overlapping_exceptions.cpython-37.pyc
Binary files differ
diff --git a/venv/Lib/site-packages/pylint/extensions/__pycache__/redefined_variable_type.cpython-37.pyc b/venv/Lib/site-packages/pylint/extensions/__pycache__/redefined_variable_type.cpython-37.pyc
new file mode 100644
index 0000000..eb897a3
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/__pycache__/redefined_variable_type.cpython-37.pyc
Binary files differ
diff --git a/venv/Lib/site-packages/pylint/extensions/_check_docs_utils.py b/venv/Lib/site-packages/pylint/extensions/_check_docs_utils.py
new file mode 100644
index 0000000..fe1603f
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/_check_docs_utils.py
@@ -0,0 +1,792 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2016-2018 Ashley Whetter <ashley@awhetter.co.uk>
+# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com>
+# Copyright (c) 2016 Yuri Bochkarev <baltazar.bz@gmail.com>
+# Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net>
+# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com>
+# Copyright (c) 2017 hippo91 <guillaume.peillex@gmail.com>
+# Copyright (c) 2017 Mitar <mitar.github@tnode.com>
+# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com>
+# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu>
+# Copyright (c) 2018 Mitchell T.H. Young <mitchelly@gmail.com>
+# Copyright (c) 2018 Adrian Chirieac <chirieacam@gmail.com>
+
+# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# For details: https://github.com/PyCQA/pylint/blob/master/COPYING
+
+"""Utility methods for docstring checking."""
+
+import re
+
+import astroid
+
+from pylint.checkers import utils
+
+
+def space_indentation(s):
+ """The number of leading spaces in a string
+
+ :param str s: input string
+
+ :rtype: int
+ :return: number of leading spaces
+ """
+ return len(s) - len(s.lstrip(" "))
+
+
+def get_setters_property_name(node):
+ """Get the name of the property that the given node is a setter for.
+
+ :param node: The node to get the property name for.
+ :type node: str
+
+ :rtype: str or None
+ :returns: The name of the property that the node is a setter for,
+ or None if one could not be found.
+ """
+ decorators = node.decorators.nodes if node.decorators else []
+ for decorator in decorators:
+ if (
+ isinstance(decorator, astroid.Attribute)
+ and decorator.attrname == "setter"
+ and isinstance(decorator.expr, astroid.Name)
+ ):
+ return decorator.expr.name
+ return None
+
+
+def get_setters_property(node):
+ """Get the property node for the given setter node.
+
+ :param node: The node to get the property for.
+ :type node: astroid.FunctionDef
+
+ :rtype: astroid.FunctionDef or None
+ :returns: The node relating to the property of the given setter node,
+ or None if one could not be found.
+ """
+ property_ = None
+
+ property_name = get_setters_property_name(node)
+ class_node = utils.node_frame_class(node)
+ if property_name and class_node:
+ class_attrs = class_node.getattr(node.name)
+ for attr in class_attrs:
+ if utils.decorated_with_property(attr):
+ property_ = attr
+ break
+
+ return property_
+
+
+def returns_something(return_node):
+ """Check if a return node returns a value other than None.
+
+ :param return_node: The return node to check.
+ :type return_node: astroid.Return
+
+ :rtype: bool
+ :return: True if the return node returns a value other than None,
+ False otherwise.
+ """
+ returns = return_node.value
+
+ if returns is None:
+ return False
+
+ return not (isinstance(returns, astroid.Const) and returns.value is None)
+
+
+def _get_raise_target(node):
+ if isinstance(node.exc, astroid.Call):
+ func = node.exc.func
+ if isinstance(func, (astroid.Name, astroid.Attribute)):
+ return utils.safe_infer(func)
+ return None
+
+
+def possible_exc_types(node):
+ """
+ Gets all of the possible raised exception types for the given raise node.
+
+ .. note::
+
+ Caught exception types are ignored.
+
+
+ :param node: The raise node to find exception types for.
+ :type node: astroid.node_classes.NodeNG
+
+ :returns: A list of exception types possibly raised by :param:`node`.
+ :rtype: set(str)
+ """
+ excs = []
+ if isinstance(node.exc, astroid.Name):
+ inferred = utils.safe_infer(node.exc)
+ if inferred:
+ excs = [inferred.name]
+ elif node.exc is None:
+ handler = node.parent
+ while handler and not isinstance(handler, astroid.ExceptHandler):
+ handler = handler.parent
+
+ if handler and handler.type:
+ inferred_excs = astroid.unpack_infer(handler.type)
+ excs = (exc.name for exc in inferred_excs if exc is not astroid.Uninferable)
+ else:
+ target = _get_raise_target(node)
+ if isinstance(target, astroid.ClassDef):
+ excs = [target.name]
+ elif isinstance(target, astroid.FunctionDef):
+ for ret in target.nodes_of_class(astroid.Return):
+ if ret.frame() != target:
+ # return from inner function - ignore it
+ continue
+
+ val = utils.safe_infer(ret.value)
+ if (
+ val
+ and isinstance(val, (astroid.Instance, astroid.ClassDef))
+ and utils.inherit_from_std_ex(val)
+ ):
+ excs.append(val.name)
+
+ try:
+ return {exc for exc in excs if not utils.node_ignores_exception(node, exc)}
+ except astroid.InferenceError:
+ return set()
+
+
+def docstringify(docstring, default_type="default"):
+ for docstring_type in [
+ SphinxDocstring,
+ EpytextDocstring,
+ GoogleDocstring,
+ NumpyDocstring,
+ ]:
+ instance = docstring_type(docstring)
+ if instance.is_valid():
+ return instance
+
+ docstring_type = DOCSTRING_TYPES.get(default_type, Docstring)
+ return docstring_type(docstring)
+
+
+class Docstring:
+ re_for_parameters_see = re.compile(
+ r"""
+ For\s+the\s+(other)?\s*parameters\s*,\s+see
+ """,
+ re.X | re.S,
+ )
+
+ supports_yields = None
+ """True if the docstring supports a "yield" section.
+
+ False if the docstring uses the returns section to document generators.
+ """
+
+ # These methods are designed to be overridden
+ # pylint: disable=no-self-use
+ def __init__(self, doc):
+ doc = doc or ""
+ self.doc = doc.expandtabs()
+
+ def is_valid(self):
+ return False
+
+ def exceptions(self):
+ return set()
+
+ def has_params(self):
+ return False
+
+ def has_returns(self):
+ return False
+
+ def has_rtype(self):
+ return False
+
+ def has_property_returns(self):
+ return False
+
+ def has_property_type(self):
+ return False
+
+ def has_yields(self):
+ return False
+
+ def has_yields_type(self):
+ return False
+
+ def match_param_docs(self):
+ return set(), set()
+
+ def params_documented_elsewhere(self):
+ return self.re_for_parameters_see.search(self.doc) is not None
+
+
+class SphinxDocstring(Docstring):
+ re_type = r"""
+ [~!.]? # Optional link style prefix
+ \w(?:\w|\.[^\.])* # Valid python name
+ """
+
+ re_simple_container_type = r"""
+ {type} # a container type
+ [\(\[] [^\n\s]+ [\)\]] # with the contents of the container
+ """.format(
+ type=re_type
+ )
+
+ re_xref = r"""
+ (?::\w+:)? # optional tag
+ `{}` # what to reference
+ """.format(
+ re_type
+ )
+
+ re_param_raw = r"""
+ : # initial colon
+ (?: # Sphinx keywords
+ param|parameter|
+ arg|argument|
+ key|keyword
+ )
+ \s+ # whitespace
+
+ (?: # optional type declaration
+ ({type}|{container_type})
+ \s+
+ )?
+
+ (\w+) # Parameter name
+ \s* # whitespace
+ : # final colon
+ """.format(
+ type=re_type, container_type=re_simple_container_type
+ )
+ re_param_in_docstring = re.compile(re_param_raw, re.X | re.S)
+
+ re_type_raw = r"""
+ :type # Sphinx keyword
+ \s+ # whitespace
+ ({type}) # Parameter name
+ \s* # whitespace
+ : # final colon
+ """.format(
+ type=re_type
+ )
+ re_type_in_docstring = re.compile(re_type_raw, re.X | re.S)
+
+ re_property_type_raw = r"""
+ :type: # Sphinx keyword
+ \s+ # whitespace
+ {type} # type declaration
+ """.format(
+ type=re_type
+ )
+ re_property_type_in_docstring = re.compile(re_property_type_raw, re.X | re.S)
+
+ re_raise_raw = r"""
+ : # initial colon
+ (?: # Sphinx keyword
+ raises?|
+ except|exception
+ )
+ \s+ # whitespace
+ ({type}) # exception type
+ \s* # whitespace
+ : # final colon
+ """.format(
+ type=re_type
+ )
+ re_raise_in_docstring = re.compile(re_raise_raw, re.X | re.S)
+
+ re_rtype_in_docstring = re.compile(r":rtype:")
+
+ re_returns_in_docstring = re.compile(r":returns?:")
+
+ supports_yields = False
+
+ def is_valid(self):
+ return bool(
+ self.re_param_in_docstring.search(self.doc)
+ or self.re_raise_in_docstring.search(self.doc)
+ or self.re_rtype_in_docstring.search(self.doc)
+ or self.re_returns_in_docstring.search(self.doc)
+ or self.re_property_type_in_docstring.search(self.doc)
+ )
+
+ def exceptions(self):
+ types = set()
+
+ for match in re.finditer(self.re_raise_in_docstring, self.doc):
+ raise_type = match.group(1)
+ types.add(raise_type)
+
+ return types
+
+ def has_params(self):
+ if not self.doc:
+ return False
+
+ return self.re_param_in_docstring.search(self.doc) is not None
+
+ def has_returns(self):
+ if not self.doc:
+ return False
+
+ return bool(self.re_returns_in_docstring.search(self.doc))
+
+ def has_rtype(self):
+ if not self.doc:
+ return False
+
+ return bool(self.re_rtype_in_docstring.search(self.doc))
+
+ def has_property_returns(self):
+ if not self.doc:
+ return False
+
+ # The summary line is the return doc,
+ # so the first line must not be a known directive.
+ return not self.doc.lstrip().startswith(":")
+
+ def has_property_type(self):
+ if not self.doc:
+ return False
+
+ return bool(self.re_property_type_in_docstring.search(self.doc))
+
+ def match_param_docs(self):
+ params_with_doc = set()
+ params_with_type = set()
+
+ for match in re.finditer(self.re_param_in_docstring, self.doc):
+ name = match.group(2)
+ params_with_doc.add(name)
+ param_type = match.group(1)
+ if param_type is not None:
+ params_with_type.add(name)
+
+ params_with_type.update(re.findall(self.re_type_in_docstring, self.doc))
+ return params_with_doc, params_with_type
+
+
+class EpytextDocstring(SphinxDocstring):
+ """
+ Epytext is similar to Sphinx. See the docs:
+ http://epydoc.sourceforge.net/epytext.html
+ http://epydoc.sourceforge.net/fields.html#fields
+
+ It's used in PyCharm:
+ https://www.jetbrains.com/help/pycharm/2016.1/creating-documentation-comments.html#d848203e314
+ https://www.jetbrains.com/help/pycharm/2016.1/using-docstrings-to-specify-types.html
+ """
+
+ re_param_in_docstring = re.compile(
+ SphinxDocstring.re_param_raw.replace(":", "@", 1), re.X | re.S
+ )
+
+ re_type_in_docstring = re.compile(
+ SphinxDocstring.re_type_raw.replace(":", "@", 1), re.X | re.S
+ )
+
+ re_property_type_in_docstring = re.compile(
+ SphinxDocstring.re_property_type_raw.replace(":", "@", 1), re.X | re.S
+ )
+
+ re_raise_in_docstring = re.compile(
+ SphinxDocstring.re_raise_raw.replace(":", "@", 1), re.X | re.S
+ )
+
+ re_rtype_in_docstring = re.compile(
+ r"""
+ @ # initial "at" symbol
+ (?: # Epytext keyword
+ rtype|returntype
+ )
+ : # final colon
+ """,
+ re.X | re.S,
+ )
+
+ re_returns_in_docstring = re.compile(r"@returns?:")
+
+ def has_property_returns(self):
+ if not self.doc:
+ return False
+
+ # If this is a property docstring, the summary is the return doc.
+ if self.has_property_type():
+ # The summary line is the return doc,
+ # so the first line must not be a known directive.
+ return not self.doc.lstrip().startswith("@")
+
+ return False
+
+
+class GoogleDocstring(Docstring):
+ re_type = SphinxDocstring.re_type
+
+ re_xref = SphinxDocstring.re_xref
+
+ re_container_type = r"""
+ (?:{type}|{xref}) # a container type
+ [\(\[] [^\n]+ [\)\]] # with the contents of the container
+ """.format(
+ type=re_type, xref=re_xref
+ )
+
+ re_multiple_type = r"""
+ (?:{container_type}|{type}|{xref})
+ (?:\s+(?:of|or)\s+(?:{container_type}|{type}|{xref}))*
+ """.format(
+ type=re_type, xref=re_xref, container_type=re_container_type
+ )
+
+ _re_section_template = r"""
+ ^([ ]*) {0} \s*: \s*$ # Google parameter header
+ ( .* ) # section
+ """
+
+ re_param_section = re.compile(
+ _re_section_template.format(r"(?:Args|Arguments|Parameters)"),
+ re.X | re.S | re.M,
+ )
+
+ re_keyword_param_section = re.compile(
+ _re_section_template.format(r"Keyword\s(?:Args|Arguments|Parameters)"),
+ re.X | re.S | re.M,
+ )
+
+ re_param_line = re.compile(
+ r"""
+ \s* \*{{0,2}}(\w+) # identifier potentially with asterisks
+ \s* ( [(]
+ {type}
+ (?:,\s+optional)?
+ [)] )? \s* : # optional type declaration
+ \s* (.*) # beginning of optional description
+ """.format(
+ type=re_multiple_type
+ ),
+ re.X | re.S | re.M,
+ )
+
+ re_raise_section = re.compile(
+ _re_section_template.format(r"Raises"), re.X | re.S | re.M
+ )
+
+ re_raise_line = re.compile(
+ r"""
+ \s* ({type}) \s* : # identifier
+ \s* (.*) # beginning of optional description
+ """.format(
+ type=re_type
+ ),
+ re.X | re.S | re.M,
+ )
+
+ re_returns_section = re.compile(
+ _re_section_template.format(r"Returns?"), re.X | re.S | re.M
+ )
+
+ re_returns_line = re.compile(
+ r"""
+ \s* ({type}:)? # identifier
+ \s* (.*) # beginning of description
+ """.format(
+ type=re_multiple_type
+ ),
+ re.X | re.S | re.M,
+ )
+
+ re_property_returns_line = re.compile(
+ r"""
+ ^{type}: # indentifier
+ \s* (.*) # Summary line / description
+ """.format(
+ type=re_multiple_type
+ ),
+ re.X | re.S | re.M,
+ )
+
+ re_yields_section = re.compile(
+ _re_section_template.format(r"Yields?"), re.X | re.S | re.M
+ )
+
+ re_yields_line = re_returns_line
+
+ supports_yields = True
+
+ def is_valid(self):
+ return bool(
+ self.re_param_section.search(self.doc)
+ or self.re_raise_section.search(self.doc)
+ or self.re_returns_section.search(self.doc)
+ or self.re_yields_section.search(self.doc)
+ or self.re_property_returns_line.search(self._first_line())
+ )
+
+ def has_params(self):
+ if not self.doc:
+ return False
+
+ return self.re_param_section.search(self.doc) is not None
+
+ def has_returns(self):
+ if not self.doc:
+ return False
+
+ entries = self._parse_section(self.re_returns_section)
+ for entry in entries:
+ match = self.re_returns_line.match(entry)
+ if not match:
+ continue
+
+ return_desc = match.group(2)
+ if return_desc:
+ return True
+
+ return False
+
+ def has_rtype(self):
+ if not self.doc:
+ return False
+
+ entries = self._parse_section(self.re_returns_section)
+ for entry in entries:
+ match = self.re_returns_line.match(entry)
+ if not match:
+ continue
+
+ return_type = match.group(1)
+ if return_type:
+ return True
+
+ return False
+
+ def has_property_returns(self):
+ # The summary line is the return doc,
+ # so the first line must not be a known directive.
+ first_line = self._first_line()
+ return not bool(
+ self.re_param_section.search(first_line)
+ or self.re_raise_section.search(first_line)
+ or self.re_returns_section.search(first_line)
+ or self.re_yields_section.search(first_line)
+ )
+
+ def has_property_type(self):
+ if not self.doc:
+ return False
+
+ return bool(self.re_property_returns_line.match(self._first_line()))
+
+ def has_yields(self):
+ if not self.doc:
+ return False
+
+ entries = self._parse_section(self.re_yields_section)
+ for entry in entries:
+ match = self.re_yields_line.match(entry)
+ if not match:
+ continue
+
+ yield_desc = match.group(2)
+ if yield_desc:
+ return True
+
+ return False
+
+ def has_yields_type(self):
+ if not self.doc:
+ return False
+
+ entries = self._parse_section(self.re_yields_section)
+ for entry in entries:
+ match = self.re_yields_line.match(entry)
+ if not match:
+ continue
+
+ yield_type = match.group(1)
+ if yield_type:
+ return True
+
+ return False
+
+ def exceptions(self):
+ types = set()
+
+ entries = self._parse_section(self.re_raise_section)
+ for entry in entries:
+ match = self.re_raise_line.match(entry)
+ if not match:
+ continue
+
+ exc_type = match.group(1)
+ exc_desc = match.group(2)
+ if exc_desc:
+ types.add(exc_type)
+
+ return types
+
+ def match_param_docs(self):
+ params_with_doc = set()
+ params_with_type = set()
+
+ entries = self._parse_section(self.re_param_section)
+ entries.extend(self._parse_section(self.re_keyword_param_section))
+ for entry in entries:
+ match = self.re_param_line.match(entry)
+ if not match:
+ continue
+
+ param_name = match.group(1)
+ param_type = match.group(2)
+ param_desc = match.group(3)
+ if param_type:
+ params_with_type.add(param_name)
+
+ if param_desc:
+ params_with_doc.add(param_name)
+
+ return params_with_doc, params_with_type
+
+ def _first_line(self):
+ return self.doc.lstrip().split("\n", 1)[0]
+
+ @staticmethod
+ def min_section_indent(section_match):
+ return len(section_match.group(1)) + 1
+
+ @staticmethod
+ def _is_section_header(_):
+ # Google parsing does not need to detect section headers,
+ # because it works off of indentation level only
+ return False
+
+ def _parse_section(self, section_re):
+ section_match = section_re.search(self.doc)
+ if section_match is None:
+ return []
+
+ min_indentation = self.min_section_indent(section_match)
+
+ entries = []
+ entry = []
+ is_first = True
+ for line in section_match.group(2).splitlines():
+ if not line.strip():
+ continue
+ indentation = space_indentation(line)
+ if indentation < min_indentation:
+ break
+
+ # The first line after the header defines the minimum
+ # indentation.
+ if is_first:
+ min_indentation = indentation
+ is_first = False
+
+ if indentation == min_indentation:
+ if self._is_section_header(line):
+ break
+ # Lines with minimum indentation must contain the beginning
+ # of a new parameter documentation.
+ if entry:
+ entries.append("\n".join(entry))
+ entry = []
+
+ entry.append(line)
+
+ if entry:
+ entries.append("\n".join(entry))
+
+ return entries
+
+
+class NumpyDocstring(GoogleDocstring):
+ _re_section_template = r"""
+ ^([ ]*) {0} \s*?$ # Numpy parameters header
+ \s* [-=]+ \s*?$ # underline
+ ( .* ) # section
+ """
+
+ re_param_section = re.compile(
+ _re_section_template.format(r"(?:Args|Arguments|Parameters)"),
+ re.X | re.S | re.M,
+ )
+
+ re_param_line = re.compile(
+ r"""
+ \s* (\w+) # identifier
+ \s* :
+ \s* (?:({type})(?:,\s+optional)?)? # optional type declaration
+ \n # description starts on a new line
+ \s* (.*) # description
+ """.format(
+ type=GoogleDocstring.re_multiple_type
+ ),
+ re.X | re.S,
+ )
+
+ re_raise_section = re.compile(
+ _re_section_template.format(r"Raises"), re.X | re.S | re.M
+ )
+
+ re_raise_line = re.compile(
+ r"""
+ \s* ({type})$ # type declaration
+ \s* (.*) # optional description
+ """.format(
+ type=GoogleDocstring.re_type
+ ),
+ re.X | re.S | re.M,
+ )
+
+ re_returns_section = re.compile(
+ _re_section_template.format(r"Returns?"), re.X | re.S | re.M
+ )
+
+ re_returns_line = re.compile(
+ r"""
+ \s* (?:\w+\s+:\s+)? # optional name
+ ({type})$ # type declaration
+ \s* (.*) # optional description
+ """.format(
+ type=GoogleDocstring.re_multiple_type
+ ),
+ re.X | re.S | re.M,
+ )
+
+ re_yields_section = re.compile(
+ _re_section_template.format(r"Yields?"), re.X | re.S | re.M
+ )
+
+ re_yields_line = re_returns_line
+
+ supports_yields = True
+
+ @staticmethod
+ def min_section_indent(section_match):
+ return len(section_match.group(1))
+
+ @staticmethod
+ def _is_section_header(line):
+ return bool(re.match(r"\s*-+$", line))
+
+
+DOCSTRING_TYPES = {
+ "sphinx": SphinxDocstring,
+ "epytext": EpytextDocstring,
+ "google": GoogleDocstring,
+ "numpy": NumpyDocstring,
+ "default": Docstring,
+}
+"""A map of the name of the docstring type to its class.
+
+:type: dict(str, type)
+"""
diff --git a/venv/Lib/site-packages/pylint/extensions/bad_builtin.py b/venv/Lib/site-packages/pylint/extensions/bad_builtin.py
new file mode 100644
index 0000000..754c409
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/bad_builtin.py
@@ -0,0 +1,69 @@
+# Copyright (c) 2016 Claudiu Popa <pcmanticore@gmail.com>
+
+# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# For details: https://github.com/PyCQA/pylint/blob/master/COPYING
+
+"""Checker for deprecated builtins."""
+import astroid
+
+from pylint.checkers import BaseChecker
+from pylint.checkers.utils import check_messages
+from pylint.interfaces import IAstroidChecker
+
+BAD_FUNCTIONS = ["map", "filter"]
+# Some hints regarding the use of bad builtins.
+BUILTIN_HINTS = {"map": "Using a list comprehension can be clearer."}
+BUILTIN_HINTS["filter"] = BUILTIN_HINTS["map"]
+
+
+class BadBuiltinChecker(BaseChecker):
+
+ __implements__ = (IAstroidChecker,)
+ name = "deprecated_builtins"
+ msgs = {
+ "W0141": (
+ "Used builtin function %s",
+ "bad-builtin",
+ "Used when a black listed builtin function is used (see the "
+ "bad-function option). Usual black listed functions are the ones "
+ "like map, or filter , where Python offers now some cleaner "
+ "alternative like list comprehension.",
+ )
+ }
+
+ options = (
+ (
+ "bad-functions",
+ {
+ "default": BAD_FUNCTIONS,
+ "type": "csv",
+ "metavar": "<builtin function names>",
+ "help": "List of builtins function names that should not be "
+ "used, separated by a comma",
+ },
+ ),
+ )
+
+ @check_messages("bad-builtin")
+ def visit_call(self, node):
+ if isinstance(node.func, astroid.Name):
+ name = node.func.name
+ # ignore the name if it's not a builtin (i.e. not defined in the
+ # locals nor globals scope)
+ if not (name in node.frame() or name in node.root()):
+ if name in self.config.bad_functions:
+ hint = BUILTIN_HINTS.get(name)
+ if hint:
+ args = "%r. %s" % (name, hint)
+ else:
+ args = repr(name)
+ self.add_message("bad-builtin", node=node, args=args)
+
+
+def register(linter):
+ """Required method to auto register this checker.
+
+ :param linter: Main interface object for Pylint plugins
+ :type linter: Pylint object
+ """
+ linter.register_checker(BadBuiltinChecker(linter))
diff --git a/venv/Lib/site-packages/pylint/extensions/broad_try_clause.py b/venv/Lib/site-packages/pylint/extensions/broad_try_clause.py
new file mode 100644
index 0000000..9a61fb6
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/broad_try_clause.py
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2019 Tyler N. Thieding <python@thieding.com>
+
+# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# For details: https://github.com/PyCQA/pylint/blob/master/COPYING
+
+"""Looks for try/except statements with too much code in the try clause."""
+
+from pylint import checkers, interfaces
+
+
+class BroadTryClauseChecker(checkers.BaseChecker):
+ """Checks for try clauses with too many lines.
+
+ According to PEP 8, ``try`` clauses shall contain the absolute minimum
+ amount of code. This checker enforces a maximum number of statements within
+ ``try`` clauses.
+
+ """
+
+ __implements__ = interfaces.IAstroidChecker
+
+ # configuration section name
+ name = "broad_try_clause"
+ msgs = {
+ "W0717": (
+ "%s",
+ "too-many-try-statements",
+ "Try clause contains too many statements.",
+ )
+ }
+
+ priority = -2
+ options = (
+ (
+ "max-try-statements",
+ {
+ "default": 1,
+ "type": "int",
+ "metavar": "<int>",
+ "help": "Maximum number of statements allowed in a try clause",
+ },
+ ),
+ )
+
+ def visit_tryexcept(self, node):
+ try_clause_statements = len(node.body)
+ if try_clause_statements > self.config.max_try_statements:
+ msg = "try clause contains {0} statements, expected at most {1}".format(
+ try_clause_statements, self.config.max_try_statements
+ )
+ self.add_message(
+ "too-many-try-statements", node.lineno, node=node, args=msg
+ )
+
+
+def register(linter):
+ """Required method to auto register this checker."""
+ linter.register_checker(BroadTryClauseChecker(linter))
diff --git a/venv/Lib/site-packages/pylint/extensions/check_docs.py b/venv/Lib/site-packages/pylint/extensions/check_docs.py
new file mode 100644
index 0000000..7f7f643
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/check_docs.py
@@ -0,0 +1,23 @@
+# Copyright (c) 2014-2015 Bruno Daniel <bruno.daniel@blue-yonder.com>
+# Copyright (c) 2015-2016 Claudiu Popa <pcmanticore@gmail.com>
+# Copyright (c) 2016 Ashley Whetter <ashley@awhetter.co.uk>
+
+# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# For details: https://github.com/PyCQA/pylint/blob/master/COPYING
+
+import warnings
+
+from pylint.extensions import docparams
+
+
+def register(linter):
+ """Required method to auto register this checker.
+
+ :param linter: Main interface object for Pylint plugins
+ :type linter: Pylint object
+ """
+ warnings.warn(
+ "This plugin is deprecated, use pylint.extensions.docparams instead.",
+ DeprecationWarning,
+ )
+ linter.register_checker(docparams.DocstringParameterChecker(linter))
diff --git a/venv/Lib/site-packages/pylint/extensions/check_elif.py b/venv/Lib/site-packages/pylint/extensions/check_elif.py
new file mode 100644
index 0000000..67555b1
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/check_elif.py
@@ -0,0 +1,77 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
+# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com>
+# Copyright (c) 2016 Glenn Matthews <glmatthe@cisco.com>
+# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com>
+
+# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# For details: https://github.com/PyCQA/pylint/blob/master/COPYING
+
+import astroid
+
+from pylint.checkers import BaseTokenChecker
+from pylint.checkers.utils import check_messages
+from pylint.interfaces import IAstroidChecker, ITokenChecker
+
+
+class ElseifUsedChecker(BaseTokenChecker):
+ """Checks for use of "else if" when an "elif" could be used
+ """
+
+ __implements__ = (ITokenChecker, IAstroidChecker)
+ name = "else_if_used"
+ msgs = {
+ "R5501": (
+ 'Consider using "elif" instead of "else if"',
+ "else-if-used",
+ "Used when an else statement is immediately followed by "
+ "an if statement and does not contain statements that "
+ "would be unrelated to it.",
+ )
+ }
+
+ def __init__(self, linter=None):
+ BaseTokenChecker.__init__(self, linter)
+ self._init()
+
+ def _init(self):
+ self._elifs = []
+ self._if_counter = 0
+
+ def process_tokens(self, tokens):
+ # Process tokens and look for 'if' or 'elif'
+ for _, token, _, _, _ in tokens:
+ if token == "elif":
+ self._elifs.append(True)
+ elif token == "if":
+ self._elifs.append(False)
+
+ def leave_module(self, _):
+ self._init()
+
+ def visit_ifexp(self, node):
+ if isinstance(node.parent, astroid.FormattedValue):
+ return
+ self._if_counter += 1
+
+ def visit_comprehension(self, node):
+ self._if_counter += len(node.ifs)
+
+ @check_messages("else-if-used")
+ def visit_if(self, node):
+ if isinstance(node.parent, astroid.If):
+ orelse = node.parent.orelse
+ # current if node must directly follow an "else"
+ if orelse and orelse == [node]:
+ if not self._elifs[self._if_counter]:
+ self.add_message("else-if-used", node=node)
+ self._if_counter += 1
+
+
+def register(linter):
+ """Required method to auto register this checker.
+
+ :param linter: Main interface object for Pylint plugins
+ :type linter: Pylint object
+ """
+ linter.register_checker(ElseifUsedChecker(linter))
diff --git a/venv/Lib/site-packages/pylint/extensions/comparetozero.py b/venv/Lib/site-packages/pylint/extensions/comparetozero.py
new file mode 100644
index 0000000..e31f488
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/comparetozero.py
@@ -0,0 +1,74 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2016 Alexander Todorov <atodorov@otb.bg>
+# Copyright (c) 2017 Claudiu Popa <pcmanticore@gmail.com>
+
+# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# For details: https://github.com/PyCQA/pylint/blob/master/COPYING
+
+"""Looks for comparisons to empty string."""
+
+import itertools
+
+import astroid
+
+from pylint import checkers, interfaces
+from pylint.checkers import utils
+
+
+def _is_constant_zero(node):
+ return isinstance(node, astroid.Const) and node.value == 0
+
+
+class CompareToZeroChecker(checkers.BaseChecker):
+ """Checks for comparisons to zero.
+ Most of the times you should use the fact that integers with a value of 0 are false.
+ An exception to this rule is when 0 is allowed in the program and has a
+ different meaning than None!
+ """
+
+ __implements__ = (interfaces.IAstroidChecker,)
+
+ # configuration section name
+ name = "compare-to-zero"
+ msgs = {
+ "C2001": (
+ "Avoid comparisons to zero",
+ "compare-to-zero",
+ "Used when Pylint detects comparison to a 0 constant.",
+ )
+ }
+
+ priority = -2
+ options = ()
+
+ @utils.check_messages("compare-to-zero")
+ def visit_compare(self, node):
+ _operators = ["!=", "==", "is not", "is"]
+ # note: astroid.Compare has the left most operand in node.left
+ # while the rest are a list of tuples in node.ops
+ # the format of the tuple is ('compare operator sign', node)
+ # here we squash everything into `ops` to make it easier for processing later
+ ops = [("", node.left)]
+ ops.extend(node.ops)
+ ops = list(itertools.chain(*ops))
+
+ for ops_idx in range(len(ops) - 2):
+ op_1 = ops[ops_idx]
+ op_2 = ops[ops_idx + 1]
+ op_3 = ops[ops_idx + 2]
+ error_detected = False
+
+ # 0 ?? X
+ if _is_constant_zero(op_1) and op_2 in _operators:
+ error_detected = True
+ # X ?? 0
+ elif op_2 in _operators and _is_constant_zero(op_3):
+ error_detected = True
+
+ if error_detected:
+ self.add_message("compare-to-zero", node=node)
+
+
+def register(linter):
+ """Required method to auto register this checker."""
+ linter.register_checker(CompareToZeroChecker(linter))
diff --git a/venv/Lib/site-packages/pylint/extensions/docparams.py b/venv/Lib/site-packages/pylint/extensions/docparams.py
new file mode 100644
index 0000000..d5a15a4
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/docparams.py
@@ -0,0 +1,536 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2014-2015 Bruno Daniel <bruno.daniel@blue-yonder.com>
+# Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com>
+# Copyright (c) 2016-2018 Ashley Whetter <ashley@awhetter.co.uk>
+# Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net>
+# Copyright (c) 2016 Glenn Matthews <glmatthe@cisco.com>
+# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com>
+# Copyright (c) 2017 Ville Skyttä <ville.skytta@iki.fi>
+# Copyright (c) 2017 John Paraskevopoulos <io.paraskev@gmail.com>
+# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu>
+# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com>
+# Copyright (c) 2018 Adam Dangoor <adamdangoor@gmail.com>
+
+# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# For details: https://github.com/PyCQA/pylint/blob/master/COPYING
+
+"""Pylint plugin for checking in Sphinx, Google, or Numpy style docstrings
+"""
+import astroid
+
+import pylint.extensions._check_docs_utils as utils
+from pylint.checkers import BaseChecker
+from pylint.checkers import utils as checker_utils
+from pylint.interfaces import IAstroidChecker
+
+
+class DocstringParameterChecker(BaseChecker):
+ """Checker for Sphinx, Google, or Numpy style docstrings
+
+ * Check that all function, method and constructor parameters are mentioned
+ in the params and types part of the docstring. Constructor parameters
+ can be documented in either the class docstring or ``__init__`` docstring,
+ but not both.
+ * Check that there are no naming inconsistencies between the signature and
+ the documentation, i.e. also report documented parameters that are missing
+ in the signature. This is important to find cases where parameters are
+ renamed only in the code, not in the documentation.
+ * Check that all explicitly raised exceptions in a function are documented
+ in the function docstring. Caught exceptions are ignored.
+
+ Activate this checker by adding the line::
+
+ load-plugins=pylint.extensions.docparams
+
+ to the ``MASTER`` section of your ``.pylintrc``.
+
+ :param linter: linter object
+ :type linter: :class:`pylint.lint.PyLinter`
+ """
+
+ __implements__ = IAstroidChecker
+
+ 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", "old-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", "old-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", "old-missing-param-doc")]},
+ ),
+ "W9016": (
+ '"%s" missing in parameter type documentation',
+ "missing-type-doc",
+ "Please add parameter type declarations for all parameters.",
+ {"old_names": [("W9004", "old-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.",
+ },
+ ),
+ )
+
+ priority = -2
+
+ constructor_names = {"__init__", "__new__"}
+ not_needed_param_in_docstring = {"self", "cls"}
+
+ def visit_functiondef(self, node):
+ """Called for function and method definitions (def).
+
+ :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)
+ self.check_functiondef_params(node, node_doc)
+ self.check_functiondef_returns(node, node_doc)
+ self.check_functiondef_yields(node, node_doc)
+
+ def check_functiondef_params(self, node, node_doc):
+ node_allow_no_param = None
+ if node.name in self.constructor_names:
+ 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
+ )
+ 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_allow_no_param = (
+ 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
+ )
+
+ self.check_arguments_in_docstring(
+ 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():
+ 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)
+
+ 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)
+
+ def visit_raise(self, node):
+ func_node = node.frame()
+ if not isinstance(func_node, astroid.FunctionDef):
+ return
+
+ expected_excs = utils.possible_exc_types(node)
+
+ if not expected_excs:
+ return
+
+ if not func_node.doc:
+ # If this is a property setter,
+ # the property should have the docstring instead.
+ property_ = utils.get_setters_property(func_node)
+ if property_:
+ func_node = property_
+
+ 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)
+ return
+
+ found_excs_full_names = doc.exceptions()
+
+ # Extract just the class name, e.g. "error" from "re.error"
+ found_excs_class_names = {exc.split(".")[-1] for exc in found_excs_full_names}
+ missing_excs = expected_excs - found_excs_class_names
+ self._add_raise_message(missing_excs, func_node)
+
+ def visit_return(self, node):
+ if not utils.returns_something(node):
+ return
+
+ func_node = node.frame()
+ if not isinstance(func_node, astroid.FunctionDef):
+ return
+
+ 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 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)
+
+ 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)
+ if not doc.is_valid() and self.config.accept_no_yields_doc:
+ return
+
+ if doc.supports_yields:
+ doc_has_yields = doc.has_yields()
+ doc_has_yields_type = doc.has_yields_type()
+ else:
+ doc_has_yields = doc.has_returns()
+ doc_has_yields_type = doc.has_rtype()
+
+ if not doc_has_yields:
+ self.add_message("missing-yield-doc", node=func_node)
+
+ if not (doc_has_yields_type or func_node.returns):
+ self.add_message("missing-yield-type-doc", node=func_node)
+
+ def visit_yieldfrom(self, node):
+ self.visit_yield(node)
+
+ def _compare_missing_args(
+ self,
+ found_argument_names,
+ message_id,
+ not_needed_names,
+ expected_argument_names,
+ warning_node,
+ ):
+ """Compare the found argument names with the expected ones and
+ generate a message if there are arguments missing.
+
+ :param set found_argument_names: argument names found in the
+ docstring
+
+ :param str message_id: pylint message id
+
+ :param not_needed_names: names that may be omitted
+ :type not_needed_names: set of str
+
+ :param set expected_argument_names: Expected argument names
+ :param NodeNG warning_node: The node to be analyzed
+ """
+ missing_argument_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,
+ )
+
+ def _compare_different_args(
+ self,
+ found_argument_names,
+ message_id,
+ not_needed_names,
+ expected_argument_names,
+ warning_node,
+ ):
+ """Compare the found argument names with the expected ones and
+ generate a message if there are extra arguments found.
+
+ :param set found_argument_names: argument names found in the
+ docstring
+
+ :param str message_id: pylint message id
+
+ :param not_needed_names: names that may be omitted
+ :type not_needed_names: set of str
+
+ :param set expected_argument_names: Expected argument names
+ :param NodeNG warning_node: The node to be analyzed
+ """
+ differing_argument_names = (
+ (expected_argument_names ^ found_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,
+ )
+
+ 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
+ hand are consistent with each other.
+
+ * Undocumented parameters except 'self' are noticed.
+ * Undocumented parameter types except for 'self' and the ``*<args>``
+ and ``**<kwargs>`` parameters are noticed.
+ * Parameters mentioned in the parameter documentation that don't or no
+ longer exist in the function parameter list are noticed.
+ * If the text "For the parameters, see" or "For the other parameters,
+ see" (ignoring additional whitespace) is mentioned in the docstring,
+ missing parameter documentation is tolerated.
+ * If there's no Sphinx style, Google style or NumPy style parameter
+ documentation at all, i.e. ``:param`` is never mentioned etc., the
+ checker assumes that the parameters are documented in another format
+ and the absence is tolerated.
+
+ :param doc: Docstring for the function, method or class.
+ :type doc: :class:`Docstring`
+
+ :param arguments_node: Arguments node for the function, method or
+ class constructor.
+ :type arguments_node: :class:`astroid.scoped_nodes.Arguments`
+
+ :param warning_node: The node to assign the warnings to
+ :type warning_node: :class:`astroid.scoped_nodes.Node`
+
+ :param accept_no_param_doc: Whether or not to allow no parameters
+ to be documented.
+ If None then this value is read from the configuration.
+ :type accept_no_param_doc: bool or None
+ """
+ # Tolerate missing param or type declarations if there is a link to
+ # another method carrying the same name.
+ if not doc.doc:
+ return
+
+ if accept_no_param_doc is None:
+ accept_no_param_doc = self.config.accept_no_param_doc
+ tolerate_missing_params = doc.params_documented_elsewhere()
+
+ # 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()
+
+ if arguments_node.vararg is not None:
+ expected_argument_names.add(arguments_node.vararg)
+ not_needed_type_in_docstring.add(arguments_node.vararg)
+ if arguments_node.kwarg is not None:
+ expected_argument_names.add(arguments_node.kwarg)
+ not_needed_type_in_docstring.add(arguments_node.kwarg)
+ 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:
+ tolerate_missing_params = True
+
+ if not tolerate_missing_params:
+ self._compare_missing_args(
+ params_with_doc,
+ "missing-param-doc",
+ self.not_needed_param_in_docstring,
+ expected_argument_names,
+ warning_node,
+ )
+
+ for index, arg_name in enumerate(arguments_node.args):
+ if arguments_node.annotations[index]:
+ params_with_type.add(arg_name.name)
+ for index, arg_name in enumerate(arguments_node.kwonlyargs):
+ if arguments_node.kwonlyargs_annotations[index]:
+ params_with_type.add(arg_name.name)
+
+ if not tolerate_missing_params:
+ self._compare_missing_args(
+ params_with_type,
+ "missing-type-doc",
+ not_needed_type_in_docstring,
+ expected_argument_names,
+ warning_node,
+ )
+
+ self._compare_different_args(
+ params_with_doc,
+ "differing-param-doc",
+ self.not_needed_param_in_docstring,
+ expected_argument_names,
+ warning_node,
+ )
+ self._compare_different_args(
+ params_with_type,
+ "differing-type-doc",
+ not_needed_type_in_docstring,
+ expected_argument_names,
+ warning_node,
+ )
+
+ 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
+ )
+
+ def _handle_no_raise_doc(self, excs, node):
+ if self.config.accept_no_raise_doc:
+ return
+
+ self._add_raise_message(excs, node)
+
+ def _add_raise_message(self, missing_excs, node):
+ """
+ Adds a message on :param:`node` for the missing exception type.
+
+ :param missing_excs: A list of missing exception types.
+ :type missing_excs: set(str)
+
+ :param node: The node show the message on.
+ :type node: astroid.node_classes.NodeNG
+ """
+ if node.is_abstract():
+ try:
+ missing_excs.remove("NotImplementedError")
+ except KeyError:
+ pass
+
+ if not missing_excs:
+ return
+
+ self.add_message(
+ "missing-raises-doc", args=(", ".join(sorted(missing_excs)),), node=node
+ )
+
+
+def register(linter):
+ """Required method to auto register this checker.
+
+ :param linter: Main interface object for Pylint plugins
+ :type linter: Pylint object
+ """
+ linter.register_checker(DocstringParameterChecker(linter))
diff --git a/venv/Lib/site-packages/pylint/extensions/docstyle.py b/venv/Lib/site-packages/pylint/extensions/docstyle.py
new file mode 100644
index 0000000..36f506f
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/docstyle.py
@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com>
+# Copyright (c) 2016 Łukasz Rogalski <rogalski.91@gmail.com>
+# Copyright (c) 2016 Luis Escobar <lescobar@vauxoo.com>
+
+# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# For details: https://github.com/PyCQA/pylint/blob/master/COPYING
+
+import linecache
+
+from pylint import checkers
+from pylint.checkers.utils import check_messages
+from pylint.interfaces import HIGH, IAstroidChecker
+
+
+class DocStringStyleChecker(checkers.BaseChecker):
+ """Checks format of docstrings based on PEP 0257"""
+
+ __implements__ = IAstroidChecker
+ name = "docstyle"
+
+ msgs = {
+ "C0198": (
+ 'Bad docstring quotes in %s, expected """, given %s',
+ "bad-docstring-quotes",
+ "Used when a docstring does not have triple double quotes.",
+ ),
+ "C0199": (
+ "First line empty in %s docstring",
+ "docstring-first-line-empty",
+ "Used when a blank line is found at the beginning of a docstring.",
+ ),
+ }
+
+ @check_messages("docstring-first-line-empty", "bad-docstring-quotes")
+ def visit_module(self, node):
+ self._check_docstring("module", node)
+
+ def visit_classdef(self, node):
+ self._check_docstring("class", node)
+
+ def visit_functiondef(self, node):
+ ftype = "method" if node.is_method() else "function"
+ self._check_docstring(ftype, node)
+
+ visit_asyncfunctiondef = visit_functiondef
+
+ def _check_docstring(self, node_type, node):
+ docstring = node.doc
+ if docstring and docstring[0] == "\n":
+ self.add_message(
+ "docstring-first-line-empty",
+ node=node,
+ args=(node_type,),
+ confidence=HIGH,
+ )
+
+ # Use "linecache", instead of node.as_string(), because the latter
+ # looses the original form of the docstrings.
+
+ if docstring:
+ lineno = node.fromlineno + 1
+ line = linecache.getline(node.root().file, lineno).lstrip()
+ if line and line.find('"""') == 0:
+ return
+ if line and "'''" in line:
+ quotes = "'''"
+ elif line and line[0] == '"':
+ quotes = '"'
+ elif line and line[0] == "'":
+ quotes = "'"
+ else:
+ quotes = False
+ if quotes:
+ self.add_message(
+ "bad-docstring-quotes",
+ node=node,
+ args=(node_type, quotes),
+ confidence=HIGH,
+ )
+
+
+def register(linter):
+ """Required method to auto register this checker.
+
+ :param linter: Main interface object for Pylint plugins
+ :type linter: Pylint object
+ """
+ linter.register_checker(DocStringStyleChecker(linter))
diff --git a/venv/Lib/site-packages/pylint/extensions/emptystring.py b/venv/Lib/site-packages/pylint/extensions/emptystring.py
new file mode 100644
index 0000000..04021d5
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/emptystring.py
@@ -0,0 +1,74 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2016 Alexander Todorov <atodorov@otb.bg>
+# Copyright (c) 2017 Claudiu Popa <pcmanticore@gmail.com>
+
+# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# For details: https://github.com/PyCQA/pylint/blob/master/COPYING
+
+"""Looks for comparisons to empty string."""
+
+import itertools
+
+import astroid
+
+from pylint import checkers, interfaces
+from pylint.checkers import utils
+
+
+def _is_constant_empty_str(node):
+ return isinstance(node, astroid.Const) and node.value == ""
+
+
+class CompareToEmptyStringChecker(checkers.BaseChecker):
+ """Checks for comparisons to empty string.
+ Most of the times you should use the fact that empty strings are false.
+ An exception to this rule is when an empty string value is allowed in the program
+ and has a different meaning than None!
+ """
+
+ __implements__ = (interfaces.IAstroidChecker,)
+
+ # configuration section name
+ name = "compare-to-empty-string"
+ msgs = {
+ "C1901": (
+ "Avoid comparisons to empty string",
+ "compare-to-empty-string",
+ "Used when Pylint detects comparison to an empty string constant.",
+ )
+ }
+
+ priority = -2
+ options = ()
+
+ @utils.check_messages("compare-to-empty-string")
+ def visit_compare(self, node):
+ _operators = ["!=", "==", "is not", "is"]
+ # note: astroid.Compare has the left most operand in node.left
+ # while the rest are a list of tuples in node.ops
+ # the format of the tuple is ('compare operator sign', node)
+ # here we squash everything into `ops` to make it easier for processing later
+ ops = [("", node.left)]
+ ops.extend(node.ops)
+ ops = list(itertools.chain(*ops))
+
+ for ops_idx in range(len(ops) - 2):
+ op_1 = ops[ops_idx]
+ op_2 = ops[ops_idx + 1]
+ op_3 = ops[ops_idx + 2]
+ error_detected = False
+
+ # x ?? ""
+ if _is_constant_empty_str(op_1) and op_2 in _operators:
+ error_detected = True
+ # '' ?? X
+ elif op_2 in _operators and _is_constant_empty_str(op_3):
+ error_detected = True
+
+ if error_detected:
+ self.add_message("compare-to-empty-string", node=node)
+
+
+def register(linter):
+ """Required method to auto register this checker."""
+ linter.register_checker(CompareToEmptyStringChecker(linter))
diff --git a/venv/Lib/site-packages/pylint/extensions/mccabe.py b/venv/Lib/site-packages/pylint/extensions/mccabe.py
new file mode 100644
index 0000000..cafac97
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/mccabe.py
@@ -0,0 +1,196 @@
+# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com>
+# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com>
+# Copyright (c) 2017 hippo91 <guillaume.peillex@gmail.com>
+
+# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# For details: https://github.com/PyCQA/pylint/blob/master/COPYING
+
+"""Module to add McCabe checker class for pylint. """
+
+from mccabe import PathGraph as Mccabe_PathGraph
+from mccabe import PathGraphingAstVisitor as Mccabe_PathGraphingAstVisitor
+
+from pylint import checkers
+from pylint.checkers.utils import check_messages
+from pylint.interfaces import HIGH, IAstroidChecker
+
+
+class PathGraph(Mccabe_PathGraph):
+ def __init__(self, node):
+ super(PathGraph, self).__init__(name="", entity="", lineno=1)
+ self.root = node
+
+
+class PathGraphingAstVisitor(Mccabe_PathGraphingAstVisitor):
+ def __init__(self):
+ super(PathGraphingAstVisitor, self).__init__()
+ self._bottom_counter = 0
+
+ def default(self, node, *args):
+ for child in node.get_children():
+ self.dispatch(child, *args)
+
+ def dispatch(self, node, *args):
+ self.node = node
+ klass = node.__class__
+ meth = self._cache.get(klass)
+ if meth is None:
+ class_name = klass.__name__
+ meth = getattr(self.visitor, "visit" + class_name, self.default)
+ self._cache[klass] = meth
+ return meth(node, *args)
+
+ def visitFunctionDef(self, node):
+ if self.graph is not None:
+ # closure
+ pathnode = self._append_node(node)
+ self.tail = pathnode
+ self.dispatch_list(node.body)
+ bottom = "%s" % self._bottom_counter
+ self._bottom_counter += 1
+ self.graph.connect(self.tail, bottom)
+ self.graph.connect(node, bottom)
+ self.tail = bottom
+ else:
+ self.graph = PathGraph(node)
+ self.tail = node
+ self.dispatch_list(node.body)
+ self.graphs["%s%s" % (self.classname, node.name)] = self.graph
+ self.reset()
+
+ visitAsyncFunctionDef = visitFunctionDef
+
+ def visitSimpleStatement(self, node):
+ self._append_node(node)
+
+ visitAssert = (
+ visitAssign
+ ) = (
+ visitAugAssign
+ ) = (
+ visitDelete
+ ) = (
+ visitPrint
+ ) = (
+ visitRaise
+ ) = (
+ visitYield
+ ) = (
+ visitImport
+ ) = (
+ visitCall
+ ) = (
+ visitSubscript
+ ) = (
+ visitPass
+ ) = (
+ visitContinue
+ ) = (
+ visitBreak
+ ) = visitGlobal = visitReturn = visitExpr = visitAwait = visitSimpleStatement
+
+ def visitWith(self, node):
+ self._append_node(node)
+ self.dispatch_list(node.body)
+
+ visitAsyncWith = visitWith
+
+ def _append_node(self, node):
+ if not self.tail:
+ return None
+ self.graph.connect(self.tail, node)
+ self.tail = node
+ return node
+
+ def _subgraph(self, node, name, extra_blocks=()):
+ """create the subgraphs representing any `if` and `for` statements"""
+ if self.graph is None:
+ # global loop
+ self.graph = PathGraph(node)
+ self._subgraph_parse(node, node, extra_blocks)
+ self.graphs["%s%s" % (self.classname, name)] = self.graph
+ self.reset()
+ else:
+ self._append_node(node)
+ self._subgraph_parse(node, node, extra_blocks)
+
+ def _subgraph_parse(self, node, pathnode, extra_blocks):
+ """parse the body and any `else` block of `if` and `for` statements"""
+ loose_ends = []
+ self.tail = node
+ self.dispatch_list(node.body)
+ loose_ends.append(self.tail)
+ for extra in extra_blocks:
+ self.tail = node
+ self.dispatch_list(extra.body)
+ loose_ends.append(self.tail)
+ if node.orelse:
+ self.tail = node
+ self.dispatch_list(node.orelse)
+ loose_ends.append(self.tail)
+ else:
+ loose_ends.append(node)
+ if node:
+ bottom = "%s" % self._bottom_counter
+ self._bottom_counter += 1
+ for end in loose_ends:
+ self.graph.connect(end, bottom)
+ self.tail = bottom
+
+
+class McCabeMethodChecker(checkers.BaseChecker):
+ """Checks McCabe complexity cyclomatic threshold in methods and functions
+ to validate a too complex code.
+ """
+
+ __implements__ = IAstroidChecker
+ name = "design"
+
+ msgs = {
+ "R1260": (
+ "%s is too complex. The McCabe rating is %d",
+ "too-complex",
+ "Used when a method or function is too complex based on "
+ "McCabe Complexity Cyclomatic",
+ )
+ }
+ options = (
+ (
+ "max-complexity",
+ {
+ "default": 10,
+ "type": "int",
+ "metavar": "<int>",
+ "help": "McCabe complexity cyclomatic threshold",
+ },
+ ),
+ )
+
+ @check_messages("too-complex")
+ def visit_module(self, node):
+ """visit an astroid.Module node to check too complex rating and
+ add message if is greather than max_complexity stored from options"""
+ visitor = PathGraphingAstVisitor()
+ for child in node.body:
+ visitor.preorder(child, visitor)
+ for graph in visitor.graphs.values():
+ complexity = graph.complexity()
+ node = graph.root
+ if hasattr(node, "name"):
+ node_name = "'%s'" % node.name
+ else:
+ node_name = "This '%s'" % node.__class__.__name__.lower()
+ if complexity <= self.config.max_complexity:
+ continue
+ self.add_message(
+ "too-complex", node=node, confidence=HIGH, args=(node_name, complexity)
+ )
+
+
+def register(linter):
+ """Required method to auto register this checker.
+
+ :param linter: Main interface object for Pylint plugins
+ :type linter: Pylint object
+ """
+ linter.register_checker(McCabeMethodChecker(linter))
diff --git a/venv/Lib/site-packages/pylint/extensions/overlapping_exceptions.py b/venv/Lib/site-packages/pylint/extensions/overlapping_exceptions.py
new file mode 100644
index 0000000..be2208c
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/overlapping_exceptions.py
@@ -0,0 +1,88 @@
+# -*- coding: utf-8 -*-
+
+# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# For details: https://github.com/PyCQA/pylint/blob/master/COPYING
+
+"""Looks for overlapping exceptions."""
+
+import astroid
+
+from pylint import checkers, interfaces
+from pylint.checkers import utils
+from pylint.checkers.exceptions import _annotated_unpack_infer
+
+
+class OverlappingExceptionsChecker(checkers.BaseChecker):
+ """Checks for two or more exceptions in the same exception handler
+ clause that are identical or parts of the same inheritance hierarchy
+ (i.e. overlapping)."""
+
+ __implements__ = interfaces.IAstroidChecker
+
+ name = "overlap-except"
+ msgs = {
+ "W0714": (
+ "Overlapping exceptions (%s)",
+ "overlapping-except",
+ "Used when exceptions in handler overlap or are identical",
+ )
+ }
+ priority = -2
+ options = ()
+
+ @utils.check_messages("overlapping-except")
+ def visit_tryexcept(self, node):
+ """check for empty except"""
+ for handler in node.handlers:
+ if handler.type is None:
+ continue
+ if isinstance(handler.type, astroid.BoolOp):
+ continue
+ try:
+ excs = list(_annotated_unpack_infer(handler.type))
+ except astroid.InferenceError:
+ continue
+
+ handled_in_clause = []
+ for part, exc in excs:
+ if exc is astroid.Uninferable:
+ continue
+ if isinstance(exc, astroid.Instance) and utils.inherit_from_std_ex(exc):
+ # pylint: disable=protected-access
+ exc = exc._proxied
+
+ if not isinstance(exc, astroid.ClassDef):
+ continue
+
+ exc_ancestors = [
+ anc for anc in exc.ancestors() if isinstance(anc, astroid.ClassDef)
+ ]
+
+ for prev_part, prev_exc in handled_in_clause:
+ prev_exc_ancestors = [
+ anc
+ for anc in prev_exc.ancestors()
+ if isinstance(anc, astroid.ClassDef)
+ ]
+ if exc == prev_exc:
+ self.add_message(
+ "overlapping-except",
+ node=handler.type,
+ args="%s and %s are the same"
+ % (prev_part.as_string(), part.as_string()),
+ )
+ elif prev_exc in exc_ancestors or exc in prev_exc_ancestors:
+ ancestor = part if exc in prev_exc_ancestors else prev_part
+ descendant = part if prev_exc in exc_ancestors else prev_part
+ self.add_message(
+ "overlapping-except",
+ node=handler.type,
+ args="%s is an ancestor class of %s"
+ % (ancestor.as_string(), descendant.as_string()),
+ )
+ handled_in_clause += [(part, exc)]
+
+
+def register(linter):
+ """Required method to auto register this checker."""
+ linter.register_checker(OverlappingExceptionsChecker(linter))
diff --git a/venv/Lib/site-packages/pylint/extensions/redefined_variable_type.py b/venv/Lib/site-packages/pylint/extensions/redefined_variable_type.py
new file mode 100644
index 0000000..cfe4754
--- /dev/null
+++ b/venv/Lib/site-packages/pylint/extensions/redefined_variable_type.py
@@ -0,0 +1,116 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com>
+# Copyright (c) 2016 Glenn Matthews <glmatthe@cisco.com>
+# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com>
+# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com>
+
+# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# For details: https://github.com/PyCQA/pylint/blob/master/COPYING
+
+import astroid
+
+from pylint.checkers import BaseChecker
+from pylint.checkers.utils import check_messages, is_none, node_type
+from pylint.interfaces import IAstroidChecker
+
+BUILTINS = "builtins"
+
+
+class MultipleTypesChecker(BaseChecker):
+ """Checks for variable type redefinitions (NoneType excepted)
+
+ At a function, method, class or module scope
+
+ This rule could be improved:
+
+ - Currently, if an attribute is set to different types in 2 methods of a
+ same class, it won't be detected (see functional test)
+ - One could improve the support for inference on assignment with tuples,
+ ifexpr, etc. Also it would be great to have support for inference on
+ str.split()
+ """
+
+ __implements__ = IAstroidChecker
+
+ name = "multiple_types"
+ msgs = {
+ "R0204": (
+ "Redefinition of %s type from %s to %s",
+ "redefined-variable-type",
+ "Used when the type of a variable changes inside a "
+ "method or a function.",
+ )
+ }
+
+ def visit_classdef(self, _):
+ self._assigns.append({})
+
+ @check_messages("redefined-variable-type")
+ def leave_classdef(self, _):
+ self._check_and_add_messages()
+
+ visit_functiondef = visit_classdef
+ leave_functiondef = leave_module = leave_classdef
+
+ def visit_module(self, _):
+ self._assigns = [{}]
+
+ def _check_and_add_messages(self):
+ assigns = self._assigns.pop()
+ for name, args in assigns.items():
+ if len(args) <= 1:
+ continue
+ orig_node, orig_type = args[0]
+ # Check if there is a type in the following nodes that would be
+ # different from orig_type.
+ for redef_node, redef_type in args[1:]:
+ if redef_type == orig_type:
+ continue
+ # if a variable is defined to several types in an if node,
+ # this is not actually redefining.
+ orig_parent = orig_node.parent
+ redef_parent = redef_node.parent
+ if isinstance(orig_parent, astroid.If):
+ if orig_parent == redef_parent:
+ if (
+ redef_node in orig_parent.orelse
+ and orig_node not in orig_parent.orelse
+ ):
+ orig_node, orig_type = redef_node, redef_type
+ continue
+ elif isinstance(
+ redef_parent, astroid.If
+ ) and redef_parent in orig_parent.nodes_of_class(astroid.If):
+ orig_node, orig_type = redef_node, redef_type
+ continue
+ orig_type = orig_type.replace(BUILTINS + ".", "")
+ redef_type = redef_type.replace(BUILTINS + ".", "")
+ self.add_message(
+ "redefined-variable-type",
+ node=redef_node,
+ args=(name, orig_type, redef_type),
+ )
+ break
+
+ def visit_assign(self, node):
+ # we don't handle multiple assignment nor slice assignment
+ target = node.targets[0]
+ if isinstance(target, (astroid.Tuple, astroid.Subscript)):
+ return
+ # ignore NoneType
+ if is_none(node):
+ return
+ _type = node_type(node.value)
+ if _type:
+ self._assigns[-1].setdefault(target.as_string(), []).append(
+ (node, _type.pytype())
+ )
+
+
+def register(linter):
+ """Required method to auto register this checker.
+
+ :param linter: Main interface object for Pylint plugins
+ :type linter: Pylint object
+ """
+ linter.register_checker(MultipleTypesChecker(linter))