def _is_name_used_as_variadic(name, variadics):
    """Check if the given name is used as a variadic argument."""
    return any(
        variadic.value == name or variadic.value.parent_of(name)
        for variadic in variadics
    )

def _is_name_used_as_variadic ( name , variadics ) : return any ( variadic . value == name or variadic . value . parent_of ( name ) for variadic in variadics )

Check if the given name is used as a variadic argument .


def _no_context_variadic(node, variadic_name, variadic_type, variadics):
    """Verify if the given call node has variadic nodes without context

    This is a workaround for handling cases of nested call functions
    which don't have the specific call context at hand.
    Variadic arguments (variable positional arguments and variable
    keyword arguments) are inferred, inherently wrong, by astroid
    as a Tuple, respectively a Dict with empty elements.
    This can lead pylint to believe that a function call receives
    too few arguments.
    """
    statement = node.statement()
    for name in statement.nodes_of_class(astroid.Name):
        if name.name != variadic_name:
            continue

        inferred = safe_infer(name)
        if isinstance(inferred, (astroid.List, astroid.Tuple)):
            length = len(inferred.elts)
        elif isinstance(inferred, astroid.Dict):
            length = len(inferred.items)
        else:
            continue

        inferred_statement = inferred.statement()
        if not length and isinstance(inferred_statement, astroid.FunctionDef):
            is_in_starred_context = _has_parent_of_type(node, variadic_type, statement)
            used_as_starred_argument = _is_name_used_as_variadic(name, variadics)
            if is_in_starred_context or used_as_starred_argument:
                return True
    return False

def _no_context_variadic ( node , variadic_name , variadic_type , variadics ) : statement = node . statement ( ) for name in statement . nodes_of_class ( astroid . Name ) : if name . name != variadic_name : continue inferred = safe_infer ( name ) if isinstance ( inferred , ( astroid . List , astroid . Tuple ) ) : length = len ( inferred . elts ) elif isinstance ( inferred , astroid . Dict ) : length = len ( inferred . items ) else : continue inferred_statement = inferred . statement ( ) if not length and isinstance ( inferred_statement , astroid . FunctionDef ) : is_in_starred_context = _has_parent_of_type ( node , variadic_type , statement ) used_as_starred_argument = _is_name_used_as_variadic ( name , variadics ) if is_in_starred_context or used_as_starred_argument : return True return False


def visit_attribute(self, node):
        """check that the accessed attribute exists

        to avoid too much false positives for now, we'll consider the code as
        correct if a single of the inferred nodes has the accessed attribute.

        function/method, super call and metaclasses are ignored
        """
        for pattern in self.config.generated_members:
            # attribute is marked as generated, stop here
            if re.match(pattern, node.attrname):
                return
            if re.match(pattern, node.as_string()):
                return

        try:
            inferred = list(node.expr.infer())
        except exceptions.InferenceError:
            return

        # list of (node, nodename) which are missing the attribute
        missingattr = set()

        non_opaque_inference_results = [
            owner
            for owner in inferred
            if owner is not astroid.Uninferable
            and not isinstance(owner, astroid.nodes.Unknown)
        ]
        if (
            len(non_opaque_inference_results) != len(inferred)
            and self.config.ignore_on_opaque_inference
        ):
            # There is an ambiguity in the inference. Since we can't
            # make sure that we won't emit a false positive, we just stop
            # whenever the inference returns an opaque inference object.
            return

        for owner in non_opaque_inference_results:
            name = getattr(owner, "name", None)
            if _is_owner_ignored(
                owner, name, self.config.ignored_classes, self.config.ignored_modules
            ):
                continue

            try:
                if not [
                    n
                    for n in owner.getattr(node.attrname)
                    if not isinstance(n.statement(), astroid.AugAssign)
                ]:
                    missingattr.add((owner, name))
                    continue
            except AttributeError:
                # XXX method / function
                continue
            except exceptions.NotFoundError:
                # This can't be moved before the actual .getattr call,
                # because there can be more values inferred and we are
                # stopping after the first one which has the attribute in question.
                # The problem is that if the first one has the attribute,
                # but we continue to the next values which doesn't have the
                # attribute, then we'll have a false positive.
                # So call this only after the call has been made.
                if not _emit_no_member(
                    node,
                    owner,
                    name,
                    ignored_mixins=self.config.ignore_mixin_members,
                    ignored_none=self.config.ignore_none,
                ):
                    continue
                missingattr.add((owner, name))
                continue
            # stop on the first found
            break
        else:
            # we have not found any node with the attributes, display the
            # message for infered nodes
            done = set()
            for owner, name in missingattr:
                if isinstance(owner, astroid.Instance):
                    actual = owner._proxied
                else:
                    actual = owner
                if actual in done:
                    continue
                done.add(actual)

                msg, hint = self._get_nomember_msgid_hint(node, owner)
                self.add_message(
                    msg,
                    node=node,
                    args=(owner.display_type(), name, node.attrname, hint),
                    confidence=INFERENCE,
                )


def visit_assign(self, node):
        """check that if assigning to a function call, the function is
        possibly returning something valuable
        """
        if not isinstance(node.value, astroid.Call):
            return
        function_node = safe_infer(node.value.func)
        # skip class, generator and incomplete function definition
        funcs = (astroid.FunctionDef, astroid.UnboundMethod, astroid.BoundMethod)
        if not (
            isinstance(function_node, funcs)
            and function_node.root().fully_defined()
            and not function_node.decorators
        ):
            return
        if (
            function_node.is_generator()
            or function_node.is_abstract(pass_is_abstract=False)
            or isinstance(function_node, astroid.AsyncFunctionDef)
        ):
            return
        returns = list(
            function_node.nodes_of_class(astroid.Return, skip_klass=astroid.FunctionDef)
        )
        if not returns:
            self.add_message("assignment-from-no-return", node=node)
        else:
            for rnode in returns:
                if not (
                    isinstance(rnode.value, astroid.Const)
                    and rnode.value.value is None
                    or rnode.value is None
                ):
                    break
            else:
                self.add_message("assignment-from-none", node=node)

check that if assigning to a function call the function is possibly returning something valuable


def _check_uninferable_call(self, node):
        """
        Check that the given uninferable Call node does not
        call an actual function.
        """
        if not isinstance(node.func, astroid.Attribute):
            return

        # Look for properties. First, obtain
        # the lhs of the Attribute node and search the attribute
        # there. If that attribute is a property or a subclass of properties,
        # then most likely it's not callable.

        # TODO: since astroid doesn't understand descriptors very well
        # we will not handle them here, right now.

        expr = node.func.expr
        klass = safe_infer(expr)
        if (
            klass is None
            or klass is astroid.Uninferable
            or not isinstance(klass, astroid.Instance)
        ):
            return

        try:
            attrs = klass._proxied.getattr(node.func.attrname)
        except exceptions.NotFoundError:
            return

        for attr in attrs:
            if attr is astroid.Uninferable:
                continue
            if not isinstance(attr, astroid.FunctionDef):
                continue

            # Decorated, see if it is decorated with a property.
            # Also, check the returns and see if they are callable.
            if decorated_with_property(attr):

                try:
                    all_returns_are_callable = all(
                        return_node.callable() or return_node is astroid.Uninferable
                        for return_node in attr.infer_call_result(node)
                    )
                except astroid.InferenceError:
                    continue

                if not all_returns_are_callable:
                    self.add_message(
                        "not-callable", node=node, args=node.func.as_string()
                    )
                    break

Check that the given uninferable Call node does not call an actual function .


def visit_unaryop(self, node):
        """Detect TypeErrors for unary operands."""

        for error in node.type_errors():
            # Let the error customize its output.
            self.add_message("invalid-unary-operand-type", args=str(error), node=node)

def
visit_unaryop
(
self
,
node
)
:
for
error
in
node
.
type_errors
(
)
:
# Let the error customize its output.
self
.
add_message
(
"invalid-unary-operand-type"
,
args
=
str
(
error
)
,
node
=
node
)


def interfaces(node, herited=True, handler_func=_iface_hdlr):
    """Return an iterator on interfaces implemented by the given class node."""
    # FIXME: what if __implements__ = (MyIFace, MyParent.__implements__)...
    try:
        implements = bases.Instance(node).getattr("__implements__")[0]
    except exceptions.NotFoundError:
        return
    if not herited and implements.frame() is not node:
        return
    found = set()
    missing = False
    for iface in node_classes.unpack_infer(implements):
        if iface is astroid.Uninferable:
            missing = True
            continue
        if iface not in found and handler_func(iface):
            found.add(iface)
            yield iface
    if missing:
        raise exceptions.InferenceError()

Return an iterator on interfaces implemented by the given class node .


def project_from_files(
    files, func_wrapper=_astroid_wrapper, project_name="no name", black_list=("CVS",)
):
    """return a Project from a list of files or modules"""
    # build the project representation
    astroid_manager = manager.AstroidManager()
    project = Project(project_name)
    for something in files:
        if not os.path.exists(something):
            fpath = modutils.file_from_modpath(something.split("."))
        elif os.path.isdir(something):
            fpath = os.path.join(something, "__init__.py")
        else:
            fpath = something
        ast = func_wrapper(astroid_manager.ast_from_file, fpath)
        if ast is None:
            continue
        # XXX why is first file defining the project.path ?
        project.path = project.path or ast.file
        project.add_module(ast)
        base_name = ast.name
        # recurse in package except if __init__ was explicitly given
        if ast.package and something.find("__init__") == -1:
            # recurse on others packages / modules if this is a package
            for fpath in modutils.get_module_files(
                os.path.dirname(ast.file), black_list
            ):
                ast = func_wrapper(astroid_manager.ast_from_file, fpath)
                if ast is None or ast.name == base_name:
                    continue
                project.add_module(ast)
    return project


def visit_package(self, node):
        """visit an astroid.Package node

         * optionally tag the node with a unique id
        """
        if self.tag:
            node.uid = self.generate_id()
        for subelmt in node.values():
            self.visit(subelmt)

def visit_package ( self , node ) : if self . tag : node . uid = self . generate_id ( ) for subelmt in node . values ( ) : self . visit ( subelmt )


def visit_functiondef(self, node):
        """visit an astroid.Function node

         * set the locals_type mapping
         * optionally tag the node with a unique id
        """
        if hasattr(node, "locals_type"):
            return
        node.locals_type = collections.defaultdict(list)
        if self.tag:
            node.uid = self.generate_id()

def visit_functiondef ( self , node ) : if hasattr ( node , "locals_type" ) : return node . locals_type = collections . defaultdict ( list ) if self . tag : node . uid = self . generate_id ( )


def visit_assignname(self, node):
        """visit an astroid.AssignName node

        handle locals_type
        """
        # avoid double parsing done by different Linkers.visit
        # running over the same project:
        if hasattr(node, "_handled"):
            return
        node._handled = True
        if node.name in node.frame():
            frame = node.frame()
        else:
            # the name has been defined as 'global' in the frame and belongs
            # there.
            frame = node.root()
        try:
            if not hasattr(frame, "locals_type"):
                # If the frame doesn't have a locals_type yet,
                # it means it wasn't yet visited. Visit it now
                # to add what's missing from it.
                if isinstance(frame, astroid.ClassDef):
                    self.visit_classdef(frame)
                elif isinstance(frame, astroid.FunctionDef):
                    self.visit_functiondef(frame)
                else:
                    self.visit_module(frame)

            current = frame.locals_type[node.name]
            values = set(node.infer())
            frame.locals_type[node.name] = list(set(current) | values)
        except astroid.InferenceError:
            pass


def handle_assignattr_type(node, parent):
        """handle an astroid.assignattr node

        handle instance_attrs_type
        """
        try:
            values = set(node.infer())
            current = set(parent.instance_attrs_type[node.attrname])
            parent.instance_attrs_type[node.attrname] = list(current | values)
        except astroid.InferenceError:
            pass

def handle_assignattr_type ( node , parent ) : try : values = set ( node . infer ( ) ) current = set ( parent . instance_attrs_type [ node . attrname ] ) parent . instance_attrs_type [ node . attrname ] = list ( current | values ) except astroid . InferenceError : pass


def visit_import(self, node):
        """visit an astroid.Import node

        resolve module dependencies
        """
        context_file = node.root().file
        for name in node.names:
            relative = modutils.is_relative(name[0], context_file)
            self._imported_module(node, name[0], relative)

def visit_import ( self , node ) : context_file = node . root ( ) . file for name in node . names : relative = modutils . is_relative ( name [ 0 ] , context_file ) self . _imported_module ( node , name [ 0 ] , relative )


def visit_importfrom(self, node):
        """visit an astroid.ImportFrom node

        resolve module dependencies
        """
        basename = node.modname
        context_file = node.root().file
        if context_file is not None:
            relative = modutils.is_relative(basename, context_file)
        else:
            relative = False
        for name in node.names:
            if name[0] == "*":
                continue
            # analyze dependencies
            fullname = "%s.%s" % (basename, name[0])
            if fullname.find(".") > -1:
                try:
                    # TODO: don't use get_module_part,
                    # missing package precedence
                    fullname = modutils.get_module_part(fullname, context_file)
                except ImportError:
                    continue
            if fullname != basename:
                self._imported_module(node, fullname, relative)

def
visit_importfrom
(
self
,
node
)
:
basename
=
node
.
modname
context_file
=
node
.
root
(
)
.
file
if
context_file
is
not
:
relative
=
modutils
.
is_relative
(
basename
,
context_file
)
else
:
relative
=
False
for
name
in
node
.
names
:
if
name
[
0
]
==
"*"
:
continue
# analyze dependencies
fullname
=
"%s.%s"
%
(
basename
,
name
[
0
]
)
if
fullname
.
find
(
"."
)
>
1
:
try
:
# TODO: don't use get_module_part,
# missing package precedence
fullname
=
modutils
.
get_module_part
(
fullname
,
context_file
)
except
ImportError
:
continue
if
fullname
!=
basename
:
self
.
_imported_module
(
node
,
fullname
,
relative
)


def compute_module(self, context_name, mod_path):
        """return true if the module should be added to dependencies"""
        package_dir = os.path.dirname(self.project.path)
        if context_name == mod_path:
            return 0
        if modutils.is_standard_module(mod_path, (package_dir,)):
            return 1
        return 0

def compute_module ( self , context_name , mod_path ) : package_dir = os . path . dirname ( self . project . path ) if context_name == mod_path : return 0 if modutils . is_standard_module ( mod_path , ( package_dir , ) ) : return 1 return 0


def _imported_module(self, node, mod_path, relative):
        """Notify an imported module, used to analyze dependencies"""
        module = node.root()
        context_name = module.name
        if relative:
            mod_path = "%s.%s" % (".".join(context_name.split(".")[:-1]), mod_path)
        if self.compute_module(context_name, mod_path):
            # handle dependencies
            if not hasattr(module, "depends"):
                module.depends = []
            mod_paths = module.depends
            if mod_path not in mod_paths:
                mod_paths.append(mod_path)

def
_imported_module
(
self
,
node
,
mod_path
,
relative
)
:
module
=
node
.
root
(
)
context_name
=
module
.
name
if
relative
:
mod_path
=
"%s.%s"
%
(
"."
.
join
(
context_name
.
split
(
"."
)
[
:
1
]
)
,
mod_path
)
if
self
.
compute_module
(
context_name
,
mod_path
)
:
# handle dependencies
if
not
hasattr
(
module
,
"depends"
)
:
module
.
depends
=
[
]
mod_paths
=
module
.
depends
if
mod_path
not
in
mod_paths
:
mod_paths
.
append
(
mod_path
)

Notify an imported module used to analyze dependencies


def _get_ansi_code(color=None, style=None):
    """return ansi escape code corresponding to color and style

    :type color: str or None
    :param color:
      the color name (see `ANSI_COLORS` for available values)
      or the color number when 256 colors are available

    :type style: str or None
    :param style:
      style string (see `ANSI_COLORS` for available values). To get
      several style effects at the same time, use a coma as separator.

    :raise KeyError: if an unexistent color or style identifier is given

    :rtype: str
    :return: the built escape code
    """
    ansi_code = []
    if style:
        style_attrs = utils._splitstrip(style)
        for effect in style_attrs:
            ansi_code.append(ANSI_STYLES[effect])
    if color:
        if color.isdigit():
            ansi_code.extend(["38", "5"])
            ansi_code.append(color)
        else:
            ansi_code.append(ANSI_COLORS[color])
    if ansi_code:
        return ANSI_PREFIX + ";".join(ansi_code) + ANSI_END
    return ""

def _get_ansi_code ( color = None , style = None ) : ansi_code = [ ] if style : style_attrs = utils . _splitstrip ( style ) for effect in style_attrs : ansi_code . append ( ANSI_STYLES [ effect ] ) if color : if color . isdigit ( ) : ansi_code . extend ( [ "38" , "5" ] ) ansi_code . append ( color ) else : ansi_code . append ( ANSI_COLORS [ color ] ) if ansi_code : return ANSI_PREFIX + ";" . join ( ansi_code ) + ANSI_END return ""


def colorize_ansi(msg, color=None, style=None):
    """colorize message by wrapping it with ansi escape codes

    :type msg: str or unicode
    :param msg: the message string to colorize

    :type color: str or None
    :param color:
      the color identifier (see `ANSI_COLORS` for available values)

    :type style: str or None
    :param style:
      style string (see `ANSI_COLORS` for available values). To get
      several style effects at the same time, use a coma as separator.

    :raise KeyError: if an unexistent color or style identifier is given

    :rtype: str or unicode
    :return: the ansi escaped string
    """
    # If both color and style are not defined, then leave the text as is
    if color is None and style is None:
        return msg
    escape_code = _get_ansi_code(color, style)
    # If invalid (or unknown) color, don't wrap msg with ansi codes
    if escape_code:
        return "%s%s%s" % (escape_code, msg, ANSI_RESET)
    return msg


def register(linter):
    """Register the reporter classes with the linter."""
    linter.register_reporter(TextReporter)
    linter.register_reporter(ParseableTextReporter)
    linter.register_reporter(VSTextReporter)
    linter.register_reporter(ColorizedTextReporter)

def register ( linter ) : linter . register_reporter ( TextReporter ) linter . register_reporter ( ParseableTextReporter ) linter . register_reporter ( VSTextReporter ) linter . register_reporter ( ColorizedTextReporter )

Register the reporter classes with the linter .


def handle_message(self, msg):
        """manage message of different type and in the context of path"""
        if msg.module not in self._modules:
            if msg.module:
                self.writeln("************* Module %s" % msg.module)
                self._modules.add(msg.module)
            else:
                self.writeln("************* ")
        self.write_message(msg)

def
handle_message
(
self
,
msg
)
:
if
msg
.
module
not
in
self
.
_modules
:
if
msg
.
module
:
self
.
writeln
(
"************* Module %s"
%
msg
.
module
)
self
.
_modules
.
add
(
msg
.
module
)
else
:
self
.
writeln
(
"************* "
)
self
.
write_message
(
msg
)


def _display(self, layout):
        """launch layouts display"""
        print(file=self.out)
        TextWriter().format(layout, self.out)

def _display ( self , layout ) : print ( file = self . out ) TextWriter ( ) . format ( layout , self . out )


def handle_message(self, msg):
        """manage message of different types, and colorize output
        using ansi escape codes
        """
        if msg.module not in self._modules:
            color, style = self._get_decoration("S")
            if msg.module:
                modsep = colorize_ansi(
                    "************* Module %s" % msg.module, color, style
                )
            else:
                modsep = colorize_ansi("************* %s" % msg.module, color, style)
            self.writeln(modsep)
            self._modules.add(msg.module)
        color, style = self._get_decoration(msg.C)

        msg = msg._replace(
            **{
                attr: colorize_ansi(getattr(msg, attr), color, style)
                for attr in ("msg", "symbol", "category", "C")
            }
        )
        self.write_message(msg)

def
handle_message
(
self
,
msg
)
:
if
msg
.
module
not
in
self
.
_modules
:
color
,
style
=
self
.
_get_decoration
(
"S"
)
if
msg
.
module
:
modsep
=
colorize_ansi
(
"************* Module %s"
%
msg
.
module
,
color
,
style
)
else
:
modsep
=
colorize_ansi
(
"************* %s"
%
msg
.
module
,
color
,
style
)
self
.
writeln
(
modsep
)
self
.
_modules
.
add
(
msg
.
module
)
color
,
style
=
self
.
_get_decoration
(
msg
.
C
)
msg
=
msg
.
_replace
(
*
*
{
attr
:
colorize_ansi
(
getattr
(
msg
,
attr
)
,
color
,
style
)
for
attr
in
(
"msg"
,
"symbol"
,
"category"
,
"C"
)
}
)
self
.
write_message
(
msg
)

manage message of different types and colorize output using ansi escape codes


def open_graph(self, **args):
        """open a vcg graph
        """
        self._stream.write("%sgraph:{\n" % self._indent)
        self._inc_indent()
        self._write_attributes(GRAPH_ATTRS, **args)

def open_graph ( self , * * args ) : self . _stream . write ( "%sgraph:{\n" % self . _indent ) self . _inc_indent ( ) self . _write_attributes ( GRAPH_ATTRS , * * args )


def node(self, title, **args):
        """draw a node
        """
        self._stream.write('%snode: {title:"%s"' % (self._indent, title))
        self._write_attributes(NODE_ATTRS, **args)
        self._stream.write("}\n")

def
node
(
self
,
title
,
*
*
args
)
:
self
.
_stream
.
write
(
'%snode: {title:"%s"'
%
(
self
.
_indent
,
title
)
)
self
.
_write_attributes
(
NODE_ATTRS
,
*
*
args
)
self
.
_stream
.
write
(
"}\n"
)


def edge(self, from_node, to_node, edge_type="", **args):
        """draw an edge from a node to another.
        """
        self._stream.write(
            '%s%sedge: {sourcename:"%s" targetname:"%s"'
            % (self._indent, edge_type, from_node, to_node)
        )
        self._write_attributes(EDGE_ATTRS, **args)
        self._stream.write("}\n")


def _check_new_format(self, node, func):
        """ Check the new string formatting. """
        # TODO: skip (for now) format nodes which don't have
        #       an explicit string on the left side of the format operation.
        #       We do this because our inference engine can't properly handle
        #       redefinitions of the original string.
        #       For more details, see issue 287.
        #
        # Note that there may not be any left side at all, if the format method
        # has been assigned to another variable. See issue 351. For example:
        #
        #    fmt = 'some string {}'.format
        #    fmt('arg')
        if isinstance(node.func, astroid.Attribute) and not isinstance(
            node.func.expr, astroid.Const
        ):
            return
        if node.starargs or node.kwargs:
            return
        try:
            strnode = next(func.bound.infer())
        except astroid.InferenceError:
            return
        if not (isinstance(strnode, astroid.Const) and isinstance(strnode.value, str)):
            return
        try:
            call_site = CallSite.from_call(node)
        except astroid.InferenceError:
            return

        try:
            fields, num_args, manual_pos = utils.parse_format_method_string(
                strnode.value
            )
        except utils.IncompleteFormatString:
            self.add_message("bad-format-string", node=node)
            return

        positional_arguments = call_site.positional_arguments
        named_arguments = call_site.keyword_arguments
        named_fields = {field[0] for field in fields if isinstance(field[0], str)}
        if num_args and manual_pos:
            self.add_message("format-combined-specification", node=node)
            return

        check_args = False
        # Consider "{[0]} {[1]}" as num_args.
        num_args += sum(1 for field in named_fields if field == "")
        if named_fields:
            for field in named_fields:
                if field and field not in named_arguments:
                    self.add_message(
                        "missing-format-argument-key", node=node, args=(field,)
                    )
            for field in named_arguments:
                if field not in named_fields:
                    self.add_message(
                        "unused-format-string-argument", node=node, args=(field,)
                    )
            # num_args can be 0 if manual_pos is not.
            num_args = num_args or manual_pos
            if positional_arguments or num_args:
                empty = any(True for field in named_fields if field == "")
                if named_arguments or empty:
                    # Verify the required number of positional arguments
                    # only if the .format got at least one keyword argument.
                    # This means that the format strings accepts both
                    # positional and named fields and we should warn
                    # when one of the them is missing or is extra.
                    check_args = True
        else:
            check_args = True
        if check_args:
            # num_args can be 0 if manual_pos is not.
            num_args = num_args or manual_pos
            if len(positional_arguments) > num_args:
                self.add_message("too-many-format-args", node=node)
            elif len(positional_arguments) < num_args:
                self.add_message("too-few-format-args", node=node)

        self._detect_vacuous_formatting(node, positional_arguments)
        self._check_new_format_specifiers(node, fields, named_arguments)

#       redefinitions of the original string.

#       For more details, see issue 287.


def process_non_raw_string_token(self, prefix, string_body, start_row):
        """check for bad escapes in a non-raw string.

        prefix: lowercase string of eg 'ur' string prefix markers.
        string_body: the un-parsed body of the string, not including the quote
        marks.
        start_row: integer line number in the source.
        """
        # Walk through the string; if we see a backslash then escape the next
        # character, and skip over it.  If we see a non-escaped character,
        # alert, and continue.
        #
        # Accept a backslash when it escapes a backslash, or a quote, or
        # end-of-line, or one of the letters that introduce a special escape
        # sequence <http://docs.python.org/reference/lexical_analysis.html>
        #
        # TODO(mbp): Maybe give a separate warning about the rarely-used
        # \a \b \v \f?
        #
        # TODO(mbp): We could give the column of the problem character, but
        # add_message doesn't seem to have a way to pass it through at present.
        i = 0
        while True:
            i = string_body.find("\\", i)
            if i == -1:
                break
            # There must be a next character; having a backslash at the end
            # of the string would be a SyntaxError.
            next_char = string_body[i + 1]
            match = string_body[i : i + 2]
            if next_char in self.UNICODE_ESCAPE_CHARACTERS:
                if "u" in prefix:
                    pass
                elif (_PY3K or self._unicode_literals) and "b" not in prefix:
                    pass  # unicode by default
                else:
                    self.add_message(
                        "anomalous-unicode-escape-in-string",
                        line=start_row,
                        args=(match,),
                    )
            elif next_char not in self.ESCAPE_CHARACTERS:
                self.add_message(
                    "anomalous-backslash-in-string", line=start_row, args=(match,)
                )
            # Whether it was a valid escape or not, backslash followed by
            # another character can always be consumed whole: the second
            # character can never be the start of a new backslash escape.
            i += 2

check for bad escapes in a non - raw string .


def visit_section(self, layout):
        """display a section as text
        """
        self.section += 1
        self.writeln()
        self.format_children(layout)
        self.section -= 1
        self.writeln()

def visit_section ( self , layout ) : self . section += 1 self . writeln ( ) self . format_children ( layout ) self . section -= 1 self . writeln ( )


def visit_evaluationsection(self, layout):
        """Display an evaluation section as a text."""
        self.section += 1
        self.format_children(layout)
        self.section -= 1
        self.writeln()

def visit_evaluationsection ( self , layout ) : self . section += 1 self . format_children ( layout ) self . section -= 1 self . writeln ( )

Display an evaluation section as a text .


def visit_table(self, layout):
        """display a table as text"""
        table_content = self.get_table_content(layout)
        # get columns width
        cols_width = [0] * len(table_content[0])
        for row in table_content:
            for index, col in enumerate(row):
                cols_width[index] = max(cols_width[index], len(col))
        self.default_table(layout, table_content, cols_width)
        self.writeln()

def
visit_table
(
self
,
layout
)
:
table_content
=
self
.
get_table_content
(
layout
)
# get columns width
cols_width
=
[
0
]
*
len
(
table_content
[
0
]
)
for
row
in
table_content
:
for
index
,
col
in
enumerate
(
row
)
:
cols_width
[
index
]
=
max
(
cols_width
[
index
]
,
len
(
col
)
)
self
.
default_table
(
layout
,
table_content
,
cols_width
)
self
.
writeln
(
)


def default_table(self, layout, table_content, cols_width):
        """format a table"""
        cols_width = [size + 1 for size in cols_width]
        format_strings = " ".join(["%%-%ss"] * len(cols_width))
        format_strings = format_strings % tuple(cols_width)
        format_strings = format_strings.split(" ")
        table_linesep = "\n+" + "+".join(["-" * w for w in cols_width]) + "+\n"
        headsep = "\n+" + "+".join(["=" * w for w in cols_width]) + "+\n"
        # FIXME: layout.cheaders
        self.write(table_linesep)
        for index, line in enumerate(table_content):
            self.write("|")
            for line_index, at_index in enumerate(line):
                self.write(format_strings[line_index] % at_index)
                self.write("|")
            if index == 0 and layout.rheaders:
                self.write(headsep)
            else:
                self.write(table_linesep)

def
default_table
(
self
,
layout
,
table_content
,
cols_width
)
:
cols_width
=
[
size
+
1
for
size
in
cols_width
]
format_strings
=
" "
.
join
(
[
"%%-%ss"
]
*
len
(
cols_width
)
)
format_strings
=
format_strings
%
tuple
(
cols_width
)
format_strings
=
format_strings
.
split
(
" "
)
table_linesep
=
"\n+"
+
"+"
.
join
(
[
"-"
*
w
for
w
in
cols_width
]
)
+
"+\n"
headsep
=
"\n+"
+
"+"
.
join
(
[
"="
*
w
for
w
in
cols_width
]
)
+
"+\n"
# FIXME: layout.cheaders
self
.
write
(
table_linesep
)
for
index
,
line
in
enumerate
(
table_content
)
:
self
.
write
(
"|"
)
for
line_index
,
at_index
in
enumerate
(
line
)
:
self
.
write
(
format_strings
[
line_index
]
%
at_index
)
self
.
write
(
"|"
)
if
index
==
0
and
layout
.
rheaders
:
self
.
write
(
headsep
)
else
:
self
.
write
(
table_linesep
)


def add_renamed_message(self, old_id, old_symbol, new_symbol):
        """Register the old ID and symbol for a warning that was renamed.

        This allows users to keep using the old ID/symbol in suppressions.
        """
        message_definition = self.get_message_definitions(new_symbol)[0]
        message_definition.old_names.append((old_id, old_symbol))
        self._register_alternative_name(message_definition, old_id, old_symbol)

Register the old ID and symbol for a warning that was renamed .


def register_messages_from_checker(self, checker):
        """Register all messages from a checker.

        :param BaseChecker checker:
        """
        checker.check_consistency()
        for message in checker.messages:
            self.register_message(message)

def register_messages_from_checker ( self , checker ) : checker . check_consistency ( ) for message in checker . messages : self . register_message ( message )


def register_message(self, message):
        """Register a MessageDefinition with consistency in mind.

        :param MessageDefinition message: The message definition being added.
        """
        self._check_id_and_symbol_consistency(message.msgid, message.symbol)
        self._check_symbol(message.msgid, message.symbol)
        self._check_msgid(message.msgid, message.symbol)
        for old_name in message.old_names:
            self._check_symbol(message.msgid, old_name[1])
        self._messages_definitions[message.symbol] = message
        self._register_alternative_name(message, message.msgid, message.symbol)
        for old_id, old_symbol in message.old_names:
            self._register_alternative_name(message, old_id, old_symbol)
        self._msgs_by_category[message.msgid[0]].append(message.msgid)

def register_message ( self , message ) : self . _check_id_and_symbol_consistency ( message . msgid , message . symbol ) self . _check_symbol ( message . msgid , message . symbol ) self . _check_msgid ( message . msgid , message . symbol ) for old_name in message . old_names : self . _check_symbol ( message . msgid , old_name [ 1 ] ) self . _messages_definitions [ message . symbol ] = message self . _register_alternative_name ( message , message . msgid , message . symbol ) for old_id , old_symbol in message . old_names : self . _register_alternative_name ( message , old_id , old_symbol ) self . _msgs_by_category [ message . msgid [ 0 ] ] . append ( message . msgid )

Register a MessageDefinition with consistency in mind .


def _check_symbol(self, msgid, symbol):
        """Check that a symbol is not already used. """
        other_message = self._messages_definitions.get(symbol)
        if other_message:
            self._raise_duplicate_msg_id(symbol, msgid, other_message.msgid)
        else:
            alternative_msgid = None
        alternative_message = self._alternative_names.get(symbol)
        if alternative_message:
            if alternative_message.symbol == symbol:
                alternative_msgid = alternative_message.msgid
            else:
                for old_msgid, old_symbol in alternative_message.old_names:
                    if old_symbol == symbol:
                        alternative_msgid = old_msgid
                        break
            if msgid != alternative_msgid:
                self._raise_duplicate_msg_id(symbol, msgid, alternative_msgid)

def _check_symbol ( self , msgid , symbol ) : other_message = self . _messages_definitions . get ( symbol ) if other_message : self . _raise_duplicate_msg_id ( symbol , msgid , other_message . msgid ) else : alternative_msgid = None alternative_message = self . _alternative_names . get ( symbol ) if alternative_message : if alternative_message . symbol == symbol : alternative_msgid = alternative_message . msgid else : for old_msgid , old_symbol in alternative_message . old_names : if old_symbol == symbol : alternative_msgid = old_msgid break if msgid != alternative_msgid : self . _raise_duplicate_msg_id ( symbol , msgid , alternative_msgid )

Check that a symbol is not already used .


def _raise_duplicate_symbol(msgid, symbol, other_symbol):
        """Raise an error when a symbol is duplicated.

        :param str msgid: The msgid corresponding to the symbols
        :param str symbol: Offending symbol
        :param str other_symbol: Other offending symbol
        :raises InvalidMessageError: when a symbol is duplicated.
        """
        symbols = [symbol, other_symbol]
        symbols.sort()
        error_message = "Message id '{msgid}' cannot have both ".format(msgid=msgid)
        error_message += "'{other_symbol}' and '{symbol}' as symbolic name.".format(
            other_symbol=symbols[0], symbol=symbols[1]
        )
        raise InvalidMessageError(error_message)

Raise an error when a symbol is duplicated .


def _raise_duplicate_msg_id(symbol, msgid, other_msgid):
        """Raise an error when a msgid is duplicated.

        :param str symbol: The symbol corresponding to the msgids
        :param str msgid: Offending msgid
        :param str other_msgid: Other offending msgid
        :raises InvalidMessageError: when a msgid is duplicated.
        """
        msgids = [msgid, other_msgid]
        msgids.sort()
        error_message = "Message symbol '{symbol}' cannot be used for ".format(
            symbol=symbol
        )
        error_message += "'{other_msgid}' and '{msgid}' at the same time.".format(
            other_msgid=msgids[0], msgid=msgids[1]
        )
        raise InvalidMessageError(error_message)

Raise an error when a msgid is duplicated .


def get_message_definitions(self, msgid_or_symbol: str) -> list:
        """Returns the Message object for this message.

        :param str msgid_or_symbol: msgid_or_symbol may be either a numeric or symbolic id.
        :raises UnknownMessageError: if the message id is not defined.
        :rtype: List of MessageDefinition
        :return: A message definition corresponding to msgid_or_symbol
        """
        if msgid_or_symbol[1:].isdigit():
            msgid_or_symbol = msgid_or_symbol.upper()
        for source in (self._alternative_names, self._messages_definitions):
            try:
                return [source[msgid_or_symbol]]
            except KeyError:
                pass
        error_msg = "No such message id or symbol '{msgid_or_symbol}'.".format(
            msgid_or_symbol=msgid_or_symbol
        )
        raise UnknownMessageError(error_msg)

Returns the Message object for this message .


def get_msg_display_string(self, msgid):
        """Generates a user-consumable representation of a message.

        Can be just the message ID or the ID and the symbol.
        """
        message_definitions = self.get_message_definitions(msgid)
        if len(message_definitions) == 1:
            return repr(message_definitions[0].symbol)
        return repr([md.symbol for md in message_definitions])

def get_msg_display_string ( self , msgid ) : message_definitions = self . get_message_definitions ( msgid ) if len ( message_definitions ) == 1 : return repr ( message_definitions [ 0 ] . symbol ) return repr ( [ md . symbol for md in message_definitions ] )

Generates a user - consumable representation of a message .


def help_message(self, msgids):
        """Display help messages for the given message identifiers"""
        for msgid in msgids:
            try:
                for message_definition in self.get_message_definitions(msgid):
                    print(message_definition.format_help(checkerref=True))
                    print("")
            except UnknownMessageError as ex:
                print(ex)
                print("")
                continue

def help_message ( self , msgids ) : for msgid in msgids : try : for message_definition in self . get_message_definitions ( msgid ) : print ( message_definition . format_help ( checkerref = True ) ) print ( "" ) except UnknownMessageError as ex : print ( ex ) print ( "" ) continue


def list_messages(self):
        """Output full messages list documentation in ReST format. """
        messages = sorted(self._messages_definitions.values(), key=lambda m: m.msgid)
        for message in messages:
            if not message.may_be_emitted():
                continue
            print(message.format_help(checkerref=False))
        print("")

def list_messages ( self ) : messages = sorted ( self . _messages_definitions . values ( ) , key = lambda m : m . msgid ) for message in messages : if not message . may_be_emitted ( ) : continue print ( message . format_help ( checkerref = False ) ) print ( "" )

Output full messages list documentation in ReST format .


def builder_inited(app):
    """Output full documentation in ReST format for all extension modules"""
    # PACKAGE/docs/exts/pylint_extensions.py --> PACKAGE/
    base_path = os.path.dirname(
        os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    )
    # PACKAGE/ --> PACKAGE/pylint/extensions
    ext_path = os.path.join(base_path, "pylint", "extensions")
    modules = []
    doc_files = {}
    for filename in os.listdir(ext_path):
        name, ext = os.path.splitext(filename)
        if name[0] == "_" or name in DEPRECATED_MODULES:
            continue
        if ext == ".py":
            modules.append("pylint.extensions.%s" % name)
        elif ext == ".rst":
            doc_files["pylint.extensions." + name] = os.path.join(ext_path, filename)
    modules.sort()
    if not modules:
        sys.exit("No Pylint extensions found?")

    linter = PyLinter()
    linter.load_plugin_modules(modules)

    extensions_doc = os.path.join(
        base_path, "doc", "technical_reference", "extensions.rst"
    )
    with open(extensions_doc, "w") as stream:
        stream.write("Optional Pylint checkers in the extensions module\n")
        stream.write("=================================================\n\n")
        stream.write("Pylint provides the following optional plugins:\n\n")
        for module in modules:
            stream.write("- :ref:`{}`\n".format(module))
        stream.write("\n")
        stream.write(
            "You can activate any or all of these extensions "
            "by adding a ``load-plugins`` line to the ``MASTER`` "
            "section of your ``.pylintrc``, for example::\n"
        )
        stream.write(
            "\n    load-plugins=pylint.extensions.docparams,"
            "pylint.extensions.docstyle\n\n"
        )
        by_module = get_plugins_info(linter, doc_files)
        for module, info in sorted(by_module.items()):
            linter._print_checker_doc(info["name"], info, stream=stream)


def _cpu_count() -> int:
    """Use sched_affinity if available for virtualized or containerized environments."""
    sched_getaffinity = getattr(os, "sched_getaffinity", None)
    # pylint: disable=not-callable,using-constant-test
    if sched_getaffinity:
        return len(sched_getaffinity(0))
    if multiprocessing:
        return multiprocessing.cpu_count()
    return 1

Use sched_affinity if available for virtualized or containerized environments .


def report_messages_stats(sect, stats, _):
    """make messages type report"""
    if not stats["by_msg"]:
        # don't print this report when we didn't detected any errors
        raise exceptions.EmptyReportError()
    in_order = sorted(
        [
            (value, msg_id)
            for msg_id, value in stats["by_msg"].items()
            if not msg_id.startswith("I")
        ]
    )
    in_order.reverse()
    lines = ("message id", "occurrences")
    for value, msg_id in in_order:
        lines += (msg_id, str(value))
    sect.append(report_nodes.Table(children=lines, cols=2, rheaders=1))


def fix_import_path(args):
    """Prepare sys.path for running the linter checks.

    Within this context, each of the given arguments is importable.
    Paths are added to sys.path in corresponding order to the arguments.
    We avoid adding duplicate directories to sys.path.
    `sys.path` is reset to its original value upon exiting this context.
    """
    orig = list(sys.path)
    changes = []
    for arg in args:
        path = _get_python_path(arg)
        if path in changes:
            continue
        else:
            changes.append(path)
    sys.path[:] = changes + ["."] + sys.path
    try:
        yield
    finally:
        sys.path[:] = orig

def fix_import_path ( args ) : orig = list ( sys . path ) changes = [ ] for arg in args : path = _get_python_path ( arg ) if path in changes : continue else : changes . append ( path ) sys . path [ : ] = changes + [ "." ] + sys . path try : yield finally : sys . path [ : ] = orig

Prepare sys . path for running the linter checks .


def load_plugin_modules(self, modnames):
        """take a list of module names which are pylint plugins and load
        and register them
        """
        for modname in modnames:
            if modname in self._dynamic_plugins:
                continue
            self._dynamic_plugins.add(modname)
            module = modutils.load_module_from_name(modname)
            module.register(self)

def load_plugin_modules ( self , modnames ) : for modname in modnames : if modname in self . _dynamic_plugins : continue self . _dynamic_plugins . add ( modname ) module = modutils . load_module_from_name ( modname ) module . register ( self )


def load_plugin_configuration(self):
        """Call the configuration hook for plugins

        This walks through the list of plugins, grabs the "load_configuration"
        hook, if exposed, and calls it to allow plugins to configure specific
        settings.
        """
        for modname in self._dynamic_plugins:
            module = modutils.load_module_from_name(modname)
            if hasattr(module, "load_configuration"):
                module.load_configuration(self)

def load_plugin_configuration ( self ) : for modname in self . _dynamic_plugins : module = modutils . load_module_from_name ( modname ) if hasattr ( module , "load_configuration" ) : module . load_configuration ( self )


def set_option(self, optname, value, action=None, optdict=None):
        """overridden from config.OptionsProviderMixin to handle some
        special options
        """
        if optname in self._options_methods or optname in self._bw_options_methods:
            if value:
                try:
                    meth = self._options_methods[optname]
                except KeyError:
                    meth = self._bw_options_methods[optname]
                    warnings.warn(
                        "%s is deprecated, replace it by %s"
                        % (optname, optname.split("-")[0]),
                        DeprecationWarning,
                    )
                value = utils._check_csv(value)
                if isinstance(value, (list, tuple)):
                    for _id in value:
                        meth(_id, ignore_unknown=True)
                else:
                    meth(value)
                return  # no need to call set_option, disable/enable methods do it
        elif optname == "output-format":
            self._reporter_name = value
            # If the reporters are already available, load
            # the reporter class.
            if self._reporters:
                self._load_reporter()

        try:
            checkers.BaseTokenChecker.set_option(self, optname, value, action, optdict)
        except config.UnsupportedAction:
            print("option %s can't be read from config file" % optname, file=sys.stderr)

overridden from config . OptionsProviderMixin to handle some special options


def register_checker(self, checker):
        """register a new checker

        checker is an object implementing IRawChecker or / and IAstroidChecker
        """
        assert checker.priority <= 0, "checker priority can't be >= 0"
        self._checkers[checker.name].append(checker)
        for r_id, r_title, r_cb in checker.reports:
            self.register_report(r_id, r_title, r_cb, checker)
        self.register_options_provider(checker)
        if hasattr(checker, "msgs"):
            self.msgs_store.register_messages_from_checker(checker)
        checker.load_defaults()

        # Register the checker, but disable all of its messages.
        # TODO(cpopa): we should have a better API for this.
        if not getattr(checker, "enabled", True):
            self.disable(checker.name)


def disable_reporters(self):
        """disable all reporters"""
        for _reporters in self._reports.values():
            for report_id, _, _ in _reporters:
                self.disable_report(report_id)

def disable_reporters ( self ) : for _reporters in self . _reports . values ( ) : for report_id , _ , _ in _reporters : self . disable_report ( report_id )


def python3_porting_mode(self):
        """Disable all other checkers and enable Python 3 warnings."""
        self.disable("all")
        self.enable("python3")
        if self._error_mode:
            # The error mode was activated, using the -E flag.
            # So we'll need to enable only the errors from the
            # Python 3 porting checker.
            for msg_id in self._checker_messages("python3"):
                if msg_id.startswith("E"):
                    self.enable(msg_id)
                else:
                    self.disable(msg_id)
        config_parser = self.cfgfile_parser
        if config_parser.has_option("MESSAGES CONTROL", "disable"):
            value = config_parser.get("MESSAGES CONTROL", "disable")
            self.global_set_option("disable", value)
        self._python3_porting_mode = True

Disable all other checkers and enable Python 3 warnings .


def get_checkers(self):
        """return all available checkers as a list"""
        return [self] + [
            c
            for _checkers in self._checkers.values()
            for c in _checkers
            if c is not self
        ]

def get_checkers ( self ) : return [ self ] + [ c for _checkers in self . _checkers . values ( ) for c in _checkers if c is not self ]


def get_checker_names(self):
        """Get all the checker names that this linter knows about."""
        current_checkers = self.get_checkers()
        return sorted(
            {check.name for check in current_checkers if check.name != "master"}
        )

def get_checker_names ( self ) : current_checkers = self . get_checkers ( ) return sorted ( { check . name for check in current_checkers if check . name != "master" } )

Get all the checker names that this linter knows about .


def prepare_checkers(self):
        """return checkers needed for activated messages and reports"""
        if not self.config.reports:
            self.disable_reporters()
        # get needed checkers
        neededcheckers = [self]
        for checker in self.get_checkers()[1:]:
            messages = {msg for msg in checker.msgs if self.is_message_enabled(msg)}
            if messages or any(self.report_is_enabled(r[0]) for r in checker.reports):
                neededcheckers.append(checker)
        # Sort checkers by priority
        neededcheckers = sorted(
            neededcheckers, key=operator.attrgetter("priority"), reverse=True
        )
        return neededcheckers

def
prepare_checkers
(
self
)
:
if
not
self
.
config
.
reports
:
self
.
disable_reporters
(
)
# get needed checkers
neededcheckers
=
[
self
]
for
checker
in
self
.
get_checkers
(
)
[
1
:
]
:
messages
=
{
msg
for
msg
in
checker
.
msgs
if
self
.
is_message_enabled
(
msg
)
}
if
messages
or
any
(
self
.
report_is_enabled
(
r
[
0
]
)
for
r
in
checker
.
reports
)
:
neededcheckers
.
append
(
checker
)
# Sort checkers by priority
neededcheckers
=
sorted
(
neededcheckers
,
key
=
operator
.
attrgetter
(
"priority"
)
,
reverse
=
True
)
return
neededcheckers


def expand_files(self, modules):
        """get modules and errors from a list of modules and handle errors
        """
        result, errors = utils.expand_modules(
            modules, self.config.black_list, self.config.black_list_re
        )
        for error in errors:
            message = modname = error["mod"]
            key = error["key"]
            self.set_current_module(modname)
            if key == "fatal":
                message = str(error["ex"]).replace(os.getcwd() + os.sep, "")
            self.add_message(key, args=message)
        return result

def expand_files ( self , modules ) : result , errors = utils . expand_modules ( modules , self . config . black_list , self . config . black_list_re ) for error in errors : message = modname = error [ "mod" ] key = error [ "key" ] self . set_current_module ( modname ) if key == "fatal" : message = str ( error [ "ex" ] ) . replace ( os . getcwd ( ) + os . sep , "" ) self . add_message ( key , args = message ) return result


def set_current_module(self, modname, filepath=None):
        """set the name of the currently analyzed module and
        init statistics for it
        """
        if not modname and filepath is None:
            return
        self.reporter.on_set_current_module(modname, filepath)
        self.current_name = modname
        self.current_file = filepath or modname
        self.stats["by_module"][modname] = {}
        self.stats["by_module"][modname]["statement"] = 0
        for msg_cat in MSG_TYPES.values():
            self.stats["by_module"][modname][msg_cat] = 0

def set_current_module ( self , modname , filepath = None ) : if not modname and filepath is None : return self . reporter . on_set_current_module ( modname , filepath ) self . current_name = modname self . current_file = filepath or modname self . stats [ "by_module" ] [ modname ] = { } self . stats [ "by_module" ] [ modname ] [ "statement" ] = 0 for msg_cat in MSG_TYPES . values ( ) : self . stats [ "by_module" ] [ modname ] [ msg_cat ] = 0


def check_astroid_module(self, ast_node, walker, rawcheckers, tokencheckers):
        """Check a module from its astroid representation."""
        try:
            tokens = utils.tokenize_module(ast_node)
        except tokenize.TokenError as ex:
            self.add_message("syntax-error", line=ex.args[1][0], args=ex.args[0])
            return None

        if not ast_node.pure_python:
            self.add_message("raw-checker-failed", args=ast_node.name)
        else:
            # assert astroid.file.endswith('.py')
            # invoke ITokenChecker interface on self to fetch module/block
            # level options
            self.process_tokens(tokens)
            if self._ignore_file:
                return False
            # walk ast to collect line numbers
            self.file_state.collect_block_lines(self.msgs_store, ast_node)
            # run raw and tokens checkers
            for checker in rawcheckers:
                checker.process_module(ast_node)
            for checker in tokencheckers:
                checker.process_tokens(tokens)
        # generate events to astroid checkers
        walker.walk(ast_node)
        return True

Check a module from its astroid representation .


def _report_evaluation(self):
        """make the global evaluation report"""
        # check with at least check 1 statements (usually 0 when there is a
        # syntax error preventing pylint from further processing)
        previous_stats = config.load_results(self.file_state.base_name)
        if self.stats["statement"] == 0:
            return

        # get a global note for the code
        evaluation = self.config.evaluation
        try:
            note = eval(evaluation, {}, self.stats)  # pylint: disable=eval-used
        except Exception as ex:
            msg = "An exception occurred while rating: %s" % ex
        else:
            self.stats["global_note"] = note
            msg = "Your code has been rated at %.2f/10" % note
            pnote = previous_stats.get("global_note")
            if pnote is not None:
                msg += " (previous run: %.2f/10, %+.2f)" % (pnote, note - pnote)

        if self.config.score:
            sect = report_nodes.EvaluationSection(msg)
            self.reporter.display_reports(sect)


def cb_help_message(self, option, optname, value, parser):
        """optik callback for printing some help about a particular message"""
        self.linter.msgs_store.help_message(utils._splitstrip(value))
        sys.exit(0)

def cb_help_message ( self , option , optname , value , parser ) : self . linter . msgs_store . help_message ( utils . _splitstrip ( value ) ) sys . exit ( 0 )


def cb_full_documentation(self, option, optname, value, parser):
        """optik callback for printing full documentation"""
        self.linter.print_full_documentation()
        sys.exit(0)

def cb_full_documentation ( self , option , optname , value , parser ) : self . linter . print_full_documentation ( ) sys . exit ( 0 )


def cb_list_messages(self, option, optname, value, parser):  # FIXME
        """optik callback for printing available messages"""
        self.linter.msgs_store.list_messages()
        sys.exit(0)

def
cb_list_messages
(
self
,
option
,
optname
,
value
,
parser
)
:
# FIXME
self
.
linter
.
msgs_store
.
list_messages
(
)
sys
.
exit
(
0
)


def cb_list_groups(self, *args, **kwargs):
        """List all the check groups that pylint knows about

        These should be useful to know what check groups someone can disable
        or enable.
        """
        for check in self.linter.get_checker_names():
            print(check)
        sys.exit(0)

def cb_list_groups ( self , * args , * * kwargs ) : for check in self . linter . get_checker_names ( ) : print ( check ) sys . exit ( 0 )


def normalize_text(text, line_len=80, indent=""):
    """Wrap the text on the given line length."""
    return "\n".join(
        textwrap.wrap(
            text, width=line_len, initial_indent=indent, subsequent_indent=indent
        )
    )

def normalize_text ( text , line_len = 80 , indent = "" ) : return "\n" . join ( textwrap . wrap ( text , width = line_len , initial_indent = indent , subsequent_indent = indent ) )

Wrap the text on the given line length .


def get_module_and_frameid(node):
    """return the module name and the frame id in the module"""
    frame = node.frame()
    module, obj = "", []
    while frame:
        if isinstance(frame, Module):
            module = frame.name
        else:
            obj.append(getattr(frame, "name", "<lambda>"))
        try:
            frame = frame.parent.frame()
        except AttributeError:
            frame = None
    obj.reverse()
    return module, ".".join(obj)

def get_module_and_frameid ( node ) : frame = node . frame ( ) module , obj = "" , [ ] while frame : if isinstance ( frame , Module ) : module = frame . name else : obj . append ( getattr ( frame , "name" , "<lambda>" ) ) try : frame = frame . parent . frame ( ) except AttributeError : frame = None obj . reverse ( ) return module , "." . join ( obj )


def safe_decode(line, encoding, *args, **kwargs):
    """return decoded line from encoding or decode with default encoding"""
    try:
        return line.decode(encoding or sys.getdefaultencoding(), *args, **kwargs)
    except LookupError:
        return line.decode(sys.getdefaultencoding(), *args, **kwargs)

def safe_decode ( line , encoding , * args , * * kwargs ) : try : return line . decode ( encoding or sys . getdefaultencoding ( ) , * args , * * kwargs ) except LookupError : return line . decode ( sys . getdefaultencoding ( ) , * args , * * kwargs )


def _basename_in_blacklist_re(base_name, black_list_re):
    """Determines if the basename is matched in a regex blacklist

    :param str base_name: The basename of the file
    :param list black_list_re: A collection of regex patterns to match against.
        Successful matches are blacklisted.

    :returns: `True` if the basename is blacklisted, `False` otherwise.
    :rtype: bool
    """
    for file_pattern in black_list_re:
        if file_pattern.match(base_name):
            return True
    return False

def _basename_in_blacklist_re ( base_name , black_list_re ) : for file_pattern in black_list_re : if file_pattern . match ( base_name ) : return True return False


def register_plugins(linter, directory):
    """load all module and package in the given directory, looking for a
    'register' function in each one, used to register pylint checkers
    """
    imported = {}
    for filename in listdir(directory):
        base, extension = splitext(filename)
        if base in imported or base == "__pycache__":
            continue
        if (
            extension in PY_EXTS
            and base != "__init__"
            or (not extension and isdir(join(directory, base)))
        ):
            try:
                module = modutils.load_module_from_file(join(directory, filename))
            except ValueError:
                # empty module name (usually emacs auto-save files)
                continue
            except ImportError as exc:
                print(
                    "Problem importing module %s: %s" % (filename, exc), file=sys.stderr
                )
            else:
                if hasattr(module, "register"):
                    module.register(linter)
                    imported[base] = 1

load all module and package in the given directory looking for a register function in each one used to register pylint checkers


def _comment(string):
    """return string as a comment"""
    lines = [line.strip() for line in string.splitlines()]
    return "# " + ("%s# " % linesep).join(lines)

def
_comment
(
string
)
:
lines
=
[
line
.
strip
(
)
for
line
in
string
.
splitlines
(
)
]
return
"# "
+
(
"%s# "
%
linesep
)
.
join
(
lines
)


def _format_option_value(optdict, value):
    """return the user input's value from a 'compiled' value"""
    if isinstance(value, (list, tuple)):
        value = ",".join(_format_option_value(optdict, item) for item in value)
    elif isinstance(value, dict):
        value = ",".join("%s:%s" % (k, v) for k, v in value.items())
    elif hasattr(value, "match"):  # optdict.get('type') == 'regexp'
        # compiled regexp
        value = value.pattern
    elif optdict.get("type") == "yn":
        value = "yes" if value else "no"
    elif isinstance(value, str) and value.isspace():
        value = "'%s'" % value
    return value

def
_format_option_value
(
optdict
,
value
)
:
if
isinstance
(
value
,
(
list
,
tuple
)
)
:
value
=
","
.
join
(
_format_option_value
(
optdict
,
item
)
for
item
in
value
)
elif
isinstance
(
value
,
dict
)
:
value
=
","
.
join
(
"%s:%s"
%
(
k
,
v
)
for
k
,
v
in
value
.
items
(
)
)
elif
hasattr
(
value
,
"match"
)
:
# optdict.get('type') == 'regexp'
# compiled regexp
value
=
value
.
pattern
elif
optdict
.
get
(
"type"
)
==
"yn"
:
value
=
"yes"
if
value
else
"no"
elif
isinstance
(
value
,
str
)
and
value
.
isspace
(
)
:
value
=
"'%s'"
%
value
return
value

return the user input s value from a compiled value


def format_section(stream, section, options, doc=None):
    """format an options section using the INI format"""
    if doc:
        print(_comment(doc), file=stream)
    print("[%s]" % section, file=stream)
    _ini_format(stream, options)

def format_section ( stream , section , options , doc = None ) : if doc : print ( _comment ( doc ) , file = stream ) print ( "[%s]" % section , file = stream ) _ini_format ( stream , options )


def _ini_format(stream, options):
    """format options using the INI format"""
    for optname, optdict, value in options:
        value = _format_option_value(optdict, value)
        help_opt = optdict.get("help")
        if help_opt:
            help_opt = normalize_text(help_opt, line_len=79, indent="# ")
            print(file=stream)
            print(help_opt, file=stream)
        else:
            print(file=stream)
        if value is None:
            print("#%s=" % optname, file=stream)
        else:
            value = str(value).strip()
            if re.match(r"^([\w-]+,)+[\w-]+$", str(value)):
                separator = "\n " + " " * len(optname)
                value = separator.join(x + "," for x in str(value).split(","))
                # remove trailing ',' from last element of the list
                value = value[:-1]
            print("%s=%s" % (optname, value), file=stream)


def insert(self, index, child):
        """insert a child node"""
        self.children.insert(index, child)
        child.parent = self

def insert ( self , index , child ) : self . children . insert ( index , child ) child . parent = self


def append(self, child):
        """overridden to detect problems easily"""
        assert child not in self.parents()
        VNode.append(self, child)

def append ( self , child ) : assert child not in self . parents ( ) VNode . append ( self , child )


def parents(self):
        """return the ancestor nodes"""
        assert self.parent is not self
        if self.parent is None:
            return []
        return [self.parent] + self.parent.parents()

def parents ( self ) : assert self . parent is not self if self . parent is None : return [ ] return [ self . parent ] + self . parent . parents ( )


def format(self, layout, stream=None, encoding=None):
        """format and write the given layout into the stream object

        unicode policy: unicode strings may be found in the layout;
        try to call stream.write with it, but give it back encoded using
        the given encoding if it fails
        """
        if stream is None:
            stream = sys.stdout
        if not encoding:
            encoding = getattr(stream, "encoding", "UTF-8")
        self.encoding = encoding or "UTF-8"
        self.out = stream
        self.begin_format()
        layout.accept(self)
        self.end_format()

def format ( self , layout , stream = None , encoding = None ) : if stream is None : stream = sys . stdout if not encoding : encoding = getattr ( stream , "encoding" , "UTF-8" ) self . encoding = encoding or "UTF-8" self . out = stream self . begin_format ( ) layout . accept ( self ) self . end_format ( )


def get_table_content(self, table):
        """trick to get table content without actually writing it

        return an aligned list of lists containing table cells values as string
        """
        result = [[]]
        cols = table.cols
        for cell in self.compute_content(table):
            if cols == 0:
                result.append([])
                cols = table.cols
            cols -= 1
            result[-1].append(cell)
        # fill missing cells
        while len(result[-1]) < cols:
            result[-1].append("")
        return result

def
get_table_content
(
self
,
table
)
:
result
=
[
[
]
]
cols
=
table
.
cols
for
cell
in
self
.
compute_content
(
table
)
:
if
cols
==
0
:
result
.
append
(
[
]
)
cols
=
table
.
cols
cols
-=
1
result
[
1
]
.
append
(
cell
)
# fill missing cells
while
len
(
result
[
1
]
)
<
cols
:
result
[
1
]
.
append
(
""
)
return
result


def compute_content(self, layout):
        """trick to compute the formatting of children layout before actually
        writing it

        return an iterator on strings (one for each child element)
        """
        # Patch the underlying output stream with a fresh-generated stream,
        # which is used to store a temporary representation of a child
        # node.
        out = self.out
        try:
            for child in layout.children:
                stream = StringIO()
                self.out = stream
                child.accept(self)
                yield stream.getvalue()
        finally:
            self.out = out


def collect_block_lines(self, msgs_store, module_node):
        """Walk the AST to collect block level options line numbers."""
        for msg, lines in self._module_msgs_state.items():
            self._raw_module_msgs_state[msg] = lines.copy()
        orig_state = self._module_msgs_state.copy()
        self._module_msgs_state = {}
        self._suppression_mapping = {}
        self._effective_max_line_number = module_node.tolineno
        self._collect_block_lines(msgs_store, module_node, orig_state)

def collect_block_lines ( self , msgs_store , module_node ) : for msg , lines in self . _module_msgs_state . items ( ) : self . _raw_module_msgs_state [ msg ] = lines . copy ( ) orig_state = self . _module_msgs_state . copy ( ) self . _module_msgs_state = { } self . _suppression_mapping = { } self . _effective_max_line_number = module_node . tolineno self . _collect_block_lines ( msgs_store , module_node , orig_state )

Walk the AST to collect block level options line numbers .


def handle_ignored_message(
        self, state_scope, msgid, line, node, args, confidence
    ):  # pylint: disable=unused-argument
        """Report an ignored message.

        state_scope is either MSG_STATE_SCOPE_MODULE or MSG_STATE_SCOPE_CONFIG,
        depending on whether the message was disabled locally in the module,
        or globally. The other arguments are the same as for add_message.
        """
        if state_scope == MSG_STATE_SCOPE_MODULE:
            try:
                orig_line = self._suppression_mapping[(msgid, line)]
                self._ignored_msgs[(msgid, orig_line)].add(line)
            except KeyError:
                pass

def
handle_ignored_message
(
self
,
state_scope
,
msgid
,
line
,
node
,
args
,
confidence
)
:
# pylint: disable=unused-argument
if
state_scope
==
MSG_STATE_SCOPE_MODULE
:
try
:
orig_line
=
self
.
_suppression_mapping
[
(
msgid
,
line
)
]
self
.
_ignored_msgs
[
(
msgid
,
orig_line
)
]
.
add
(
line
)
except
KeyError
:
pass


def register_report(self, reportid, r_title, r_cb, checker):
        """register a report

        reportid is the unique identifier for the report
        r_title the report's title
        r_cb the method to call to make the report
        checker is the checker defining the report
        """
        reportid = reportid.upper()
        self._reports[checker].append((reportid, r_title, r_cb))

def register_report ( self , reportid , r_title , r_cb , checker ) : reportid = reportid . upper ( ) self . _reports [ checker ] . append ( ( reportid , r_title , r_cb ) )


def make_reports(self, stats, old_stats):
        """render registered reports"""
        sect = Section("Report", "%s statements analysed." % (self.stats["statement"]))
        for checker in self.report_order():
            for reportid, r_title, r_cb in self._reports[checker]:
                if not self.report_is_enabled(reportid):
                    continue
                report_sect = Section(r_title)
                try:
                    r_cb(report_sect, stats, old_stats)
                except EmptyReportError:
                    continue
                report_sect.report_id = reportid
                sect.append(report_sect)
        return sect

def
make_reports
(
self
,
stats
,
old_stats
)
:
sect
=
Section
(
"Report"
,
"%s statements analysed."
%
(
self
.
stats
[
"statement"
]
)
)
for
checker
in
self
.
report_order
(
)
:
for
reportid
,
r_title
,
r_cb
in
self
.
_reports
[
checker
]
:
if
not
self
.
report_is_enabled
(
reportid
)
:
continue
report_sect
=
Section
(
r_title
)
try
:
r_cb
(
report_sect
,
stats
,
old_stats
)
except
EmptyReportError
:
continue
report_sect
.
report_id
=
reportid
sect
.
append
(
report_sect
)
return
sect


def add_stats(self, **kwargs):
        """add some stats entries to the statistic dictionary
        raise an AssertionError if there is a key conflict
        """
        for key, value in kwargs.items():
            if key[-1] == "_":
                key = key[:-1]
            assert key not in self.stats
            self.stats[key] = value
        return self.stats

def add_stats ( self , * * kwargs ) : for key , value in kwargs . items ( ) : if key [ - 1 ] == "_" : key = key [ : - 1 ] assert key not in self . stats self . stats [ key ] = value return self . stats


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_name ( node ) : 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

Get the name of the property that the given node is a setter for .


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 get_setters_property ( node ) : 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_

Get the property node for the given setter node .


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 returns_something ( return_node ) : returns = return_node . value if returns is None : return False return not ( isinstance ( returns , astroid . Const ) and returns . value is None )

Check if a return node returns a value other than 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()

Gets all of the possible raised exception types for the given raise node .


def process_module(self, module):
        """inspect the source file to find messages activated or deactivated by id."""
        managed_msgs = MessagesHandlerMixIn.get_by_id_managed_msgs()
        for (mod_name, msg_id, msg_symbol, lineno, is_disabled) in managed_msgs:
            if mod_name == module.name:
                if is_disabled:
                    txt = "Id '{ident}' is used to disable '{symbol}' message emission".format(
                        ident=msg_id, symbol=msg_symbol
                    )
                else:
                    txt = "Id '{ident}' is used to enable '{symbol}' message emission".format(
                        ident=msg_id, symbol=msg_symbol
                    )
                self.add_message("use-symbolic-message-instead", line=lineno, args=txt)
        MessagesHandlerMixIn.clear_by_id_managed_msgs()

inspect the source file to find messages activated or deactivated by id .


def process_module(self, module):
        """inspect the source file to find encoding problem"""
        if module.file_encoding:
            encoding = module.file_encoding
        else:
            encoding = "ascii"

        with module.stream() as stream:
            for lineno, line in enumerate(stream):
                self._check_encoding(lineno + 1, line, encoding)

def process_module ( self , module ) : if module . file_encoding : encoding = module . file_encoding else : encoding = "ascii" with module . stream ( ) as stream : for lineno , line in enumerate ( stream ) : self . _check_encoding ( lineno + 1 , line , encoding )


def process_tokens(self, tokens):
        """inspect the source to find fixme problems"""
        if not self.config.notes:
            return
        comments = (
            token_info for token_info in tokens if token_info.type == tokenize.COMMENT
        )
        for comment in comments:
            comment_text = comment.string[1:].lstrip()  # trim '#' and whitespaces

            # handle pylint disable clauses
            disable_option_match = OPTION_RGX.search(comment_text)
            if disable_option_match:
                try:
                    _, value = disable_option_match.group(1).split("=", 1)
                    values = [_val.strip().upper() for _val in value.split(",")]
                    if set(values) & set(self.config.notes):
                        continue
                except ValueError:
                    self.add_message(
                        "bad-inline-option",
                        args=disable_option_match.group(1).strip(),
                        line=comment.string,
                    )
                    continue

            # emit warnings if necessary
            match = self._fixme_pattern.search("#" + comment_text.lower())
            if match:
                note = match.group(1)
                self.add_message(
                    "fixme",
                    col_offset=comment.string.lower().index(note.lower()),
                    args=comment_text,
                    line=comment.start[0],
                )

def
process_tokens
(
self
,
tokens
)
:
if
not
self
.
config
.
notes
:
return
comments
=
(
token_info
for
token_info
in
tokens
if
token_info
.
type
==
tokenize
.
COMMENT
)
for
comment
in
comments
:
comment_text
=
comment
.
string
[
1
:
]
.
lstrip
(
)
# trim '#' and whitespaces
# handle pylint disable clauses
disable_option_match
=
OPTION_RGX
.
search
(
comment_text
)
if
disable_option_match
:
try
:
_
,
value
=
disable_option_match
.
group
(
1
)
.
split
(
"="
,
1
)
values
=
[
_val
.
strip
(
)
.
upper
(
)
for
_val
in
value
.
split
(
","
)
]
if
set
(
values
)
&
set
(
self
.
config
.
notes
)
:
continue
except
ValueError
:
self
.
add_message
(
"bad-inline-option"
,
args
=
disable_option_match
.
group
(
1
)
.
strip
(
)
,
line
=
comment
.
string
,
)
continue
# emit warnings if necessary
match
=
self
.
_fixme_pattern
.
search
(
"#"
+
comment_text
.
lower
(
)
)
if
match
:
note
=
match
.
group
(
1
)
self
.
add_message
(
"fixme"
,
col_offset
=
comment
.
string
.
lower
(
)
.
index
(
note
.
lower
(
)
)
,
args
=
comment_text
,
line
=
comment
.
start
[
0
]
,
)


def _is_from_future_import(stmt, name):
    """Check if the name is a future import from another module."""
    try:
        module = stmt.do_import_module(stmt.modname)
    except astroid.AstroidBuildingException:
        return None

    for local_node in module.locals.get(name, []):
        if isinstance(local_node, astroid.ImportFrom) and local_node.modname == FUTURE:
            return True
    return None

def _is_from_future_import ( stmt , name ) : try : module = stmt . do_import_module ( stmt . modname ) except astroid . AstroidBuildingException : return None for local_node in module . locals . get ( name , [ ] ) : if isinstance ( local_node , astroid . ImportFrom ) and local_node . modname == FUTURE : return True return None

Check if the name is a future import from another module .


def in_for_else_branch(parent, stmt):
    """Returns True if stmt in inside the else branch for a parent For stmt."""
    return isinstance(parent, astroid.For) and any(
        else_stmt.parent_of(stmt) or else_stmt == stmt for else_stmt in parent.orelse
    )

def in_for_else_branch ( parent , stmt ) : return isinstance ( parent , astroid . For ) and any ( else_stmt . parent_of ( stmt ) or else_stmt == stmt for else_stmt in parent . orelse )

Returns True if stmt in inside the else branch for a parent For stmt .


def overridden_method(klass, name):
    """get overridden method if any"""
    try:
        parent = next(klass.local_attr_ancestors(name))
    except (StopIteration, KeyError):
        return None
    try:
        meth_node = parent[name]
    except KeyError:
        # We have found an ancestor defining <name> but it's not in the local
        # dictionary. This may happen with astroid built from living objects.
        return None
    if isinstance(meth_node, astroid.FunctionDef):
        return meth_node
    return None


def _get_unpacking_extra_info(node, infered):
    """return extra information to add to the message for unpacking-non-sequence
    and unbalanced-tuple-unpacking errors
    """
    more = ""
    infered_module = infered.root().name
    if node.root().name == infered_module:
        if node.lineno == infered.lineno:
            more = " %s" % infered.as_string()
        elif infered.lineno:
            more = " defined at line %s" % infered.lineno
    elif infered.lineno:
        more = " defined at line %s of %s" % (infered.lineno, infered_module)
    return more

def
_get_unpacking_extra_info
(
node
,
infered
)
:
more
=
""
infered_module
=
infered
.
root
(
)
.
name
if
node
.
root
(
)
.
name
==
infered_module
:
if
node
.
lineno
==
infered
.
lineno
:
more
=
" %s"
%
infered
.
as_string
(
)
elif
infered
.
lineno
:
more
=
" defined at line %s"
%
infered
.
lineno
elif
infered
.
lineno
:
more
=
" defined at line %s of %s"
%
(
infered
.
lineno
,
infered_module
)
return
more

return extra information to add to the message for unpacking - non - sequence and unbalanced - tuple - unpacking errors


def _detect_global_scope(node, frame, defframe):
    """ Detect that the given frames shares a global
    scope.

    Two frames shares a global scope when neither
    of them are hidden under a function scope, as well
    as any of parent scope of them, until the root scope.
    In this case, depending from something defined later on
    will not work, because it is still undefined.

    Example:
        class A:
            # B has the same global scope as `C`, leading to a NameError.
            class B(C): ...
        class C: ...

    """
    def_scope = scope = None
    if frame and frame.parent:
        scope = frame.parent.scope()
    if defframe and defframe.parent:
        def_scope = defframe.parent.scope()
    if isinstance(frame, astroid.FunctionDef):
        # If the parent of the current node is a
        # function, then it can be under its scope
        # (defined in, which doesn't concern us) or
        # the `->` part of annotations. The same goes
        # for annotations of function arguments, they'll have
        # their parent the Arguments node.
        if not isinstance(node.parent, (astroid.FunctionDef, astroid.Arguments)):
            return False
    elif any(
        not isinstance(f, (astroid.ClassDef, astroid.Module)) for f in (frame, defframe)
    ):
        # Not interested in other frames, since they are already
        # not in a global scope.
        return False

    break_scopes = []
    for s in (scope, def_scope):
        # Look for parent scopes. If there is anything different
        # than a module or a class scope, then they frames don't
        # share a global scope.
        parent_scope = s
        while parent_scope:
            if not isinstance(parent_scope, (astroid.ClassDef, astroid.Module)):
                break_scopes.append(parent_scope)
                break
            if parent_scope.parent:
                parent_scope = parent_scope.parent.scope()
            else:
                break
    if break_scopes and len(set(break_scopes)) != 1:
        # Store different scopes than expected.
        # If the stored scopes are, in fact, the very same, then it means
        # that the two frames (frame and defframe) shares the same scope,
        # and we could apply our lineno analysis over them.
        # For instance, this works when they are inside a function, the node
        # that uses a definition and the definition itself.
        return False
    # At this point, we are certain that frame and defframe shares a scope
    # and the definition of the first depends on the second.
    return frame.lineno < defframe.lineno

Detect that the given frames shares a global scope .


def _assigned_locally(name_node):
    """
    Checks if name_node has corresponding assign statement in same scope
    """
    assign_stmts = name_node.scope().nodes_of_class(astroid.AssignName)
    return any(a.name == name_node.name for a in assign_stmts)

def _assigned_locally ( name_node ) : assign_stmts = name_node . scope ( ) . nodes_of_class ( astroid . AssignName ) return any ( a . name == name_node . name for a in assign_stmts )


def mark_as_consumed(self, name, new_node):
        """
        Mark the name as consumed and delete it from
        the to_consume dictionary
        """
        self.consumed[name] = new_node
        del self.to_consume[name]

def mark_as_consumed ( self , name , new_node ) : self . consumed [ name ] = new_node del self . to_consume [ name ]


def visit_global(self, node):
        """check names imported exists in the global scope"""
        frame = node.frame()
        if isinstance(frame, astroid.Module):
            self.add_message("global-at-module-level", node=node)
            return

        module = frame.root()
        default_message = True
        locals_ = node.scope().locals
        for name in node.names:
            try:
                assign_nodes = module.getattr(name)
            except astroid.NotFoundError:
                # unassigned global, skip
                assign_nodes = []

            not_defined_locally_by_import = not any(
                isinstance(local, astroid.node_classes.Import)
                for local in locals_.get(name, ())
            )
            if not assign_nodes and not_defined_locally_by_import:
                self.add_message("global-variable-not-assigned", args=name, node=node)
                default_message = False
                continue

            for anode in assign_nodes:
                if (
                    isinstance(anode, astroid.AssignName)
                    and anode.name in module.special_attributes
                ):
                    self.add_message("redefined-builtin", args=name, node=node)
                    break
                if anode.frame() is module:
                    # module level assignment
                    break
            else:
                if not_defined_locally_by_import:
                    # global undefined at the module scope
                    self.add_message("global-variable-undefined", args=name, node=node)
                    default_message = False

        if default_message:
            self.add_message("global-statement", node=node)

def
visit_global
(
self
,
node
)
:
frame
=
node
.
frame
(
)
if
isinstance
(
frame
,
astroid
.
Module
)
:
self
.
add_message
(
"global-at-module-level"
,
node
=
node
)
return
module
=
frame
.
root
(
)
default_message
=
True
locals_
=
node
.
scope
(
)
.
locals
for
name
in
node
.
names
:
try
:
assign_nodes
=
module
.
getattr
(
name
)
except
astroid
.
NotFoundError
:
# unassigned global, skip
assign_nodes
=
[
]
not_defined_locally_by_import
=
not
any
(
isinstance
(
local
,
astroid
.
node_classes
.
Import
)
for
local
in
locals_
.
get
(
name
,
(
)
)
)
if
not
assign_nodes
and
not_defined_locally_by_import
:
self
.
add_message
(
"global-variable-not-assigned"
,
args
=
name
,
node
=
node
)
default_message
=
False
continue
for
anode
in
assign_nodes
:
if
(
isinstance
(
anode
,
astroid
.
AssignName
)
and
anode
.
name
in
module
.
special_attributes
)
:
self
.
add_message
(
"redefined-builtin"
,
args
=
name
,
node
=
node
)
break
if
anode
.
frame
(
)
is
module
:
# module level assignment
break
else
:
if
not_defined_locally_by_import
:
# global undefined at the module scope
self
.
add_message
(
"global-variable-undefined"
,
args
=
name
,
node
=
node
)
default_message
=
False
if
default_message
:
self
.
add_message
(
"global-statement"
,
node
=
node
)


def _ignore_class_scope(self, node):
        """
        Return True if the node is in a local class scope, as an assignment.

        :param node: Node considered
        :type node: astroid.Node
        :return: True if the node is in a local class scope, as an assignment. False otherwise.
        :rtype: bool
        """
        # Detect if we are in a local class scope, as an assignment.
        # For example, the following is fair game.
        #
        # class A:
        #    b = 1
        #    c = lambda b=b: b * b
        #
        # class B:
        #    tp = 1
        #    def func(self, arg: tp):
        #        ...
        # class C:
        #    tp = 2
        #    def func(self, arg=tp):
        #        ...

        name = node.name
        frame = node.statement().scope()
        in_annotation_or_default = self._defined_in_function_definition(node, frame)
        if in_annotation_or_default:
            frame_locals = frame.parent.scope().locals
        else:
            frame_locals = frame.locals
        return not (
            (isinstance(frame, astroid.ClassDef) or in_annotation_or_default)
            and name in frame_locals
        )

Return True if the node is in a local class scope as an assignment .


def _has_homonym_in_upper_function_scope(self, node, index):
        """
        Return True if there is a node with the same name in the to_consume dict of an upper scope
        and if that scope is a function

        :param node: node to check for
        :type node: astroid.Node
        :param index: index of the current consumer inside self._to_consume
        :type index: int
        :return: True if there is a node with the same name in the to_consume dict of an upper scope
                 and if that scope is a function
        :rtype: bool
        """
        for _consumer in self._to_consume[index - 1 :: -1]:
            if _consumer.scope_type == "function" and node.name in _consumer.to_consume:
                return True
        return False

def _has_homonym_in_upper_function_scope ( self , node , index ) : for _consumer in self . _to_consume [ index - 1 : : - 1 ] : if _consumer . scope_type == "function" and node . name in _consumer . to_consume : return True return False


def _check_unpacking(self, infered, node, targets):
        """ Check for unbalanced tuple unpacking
        and unpacking non sequences.
        """
        if utils.is_inside_abstract_class(node):
            return
        if utils.is_comprehension(node):
            return
        if infered is astroid.Uninferable:
            return
        if (
            isinstance(infered.parent, astroid.Arguments)
            and isinstance(node.value, astroid.Name)
            and node.value.name == infered.parent.vararg
        ):
            # Variable-length argument, we can't determine the length.
            return
        if isinstance(infered, (astroid.Tuple, astroid.List)):
            # attempt to check unpacking is properly balanced
            values = infered.itered()
            if len(targets) != len(values):
                # Check if we have starred nodes.
                if any(isinstance(target, astroid.Starred) for target in targets):
                    return
                self.add_message(
                    "unbalanced-tuple-unpacking",
                    node=node,
                    args=(
                        _get_unpacking_extra_info(node, infered),
                        len(targets),
                        len(values),
                    ),
                )
        # attempt to check unpacking may be possible (ie RHS is iterable)
        else:
            if not utils.is_iterable(infered):
                self.add_message(
                    "unpacking-non-sequence",
                    node=node,
                    args=(_get_unpacking_extra_info(node, infered),),
                )

Check for unbalanced tuple unpacking and unpacking non sequences .


def _check_metaclasses(self, node):
        """ Update consumption analysis for metaclasses. """
        consumed = []  # [(scope_locals, consumed_key)]

        for child_node in node.get_children():
            if isinstance(child_node, astroid.ClassDef):
                consumed.extend(self._check_classdef_metaclasses(child_node, node))

        # Pop the consumed items, in order to avoid having
        # unused-import and unused-variable false positives
        for scope_locals, name in consumed:
            scope_locals.pop(name, None)

Update consumption analysis for metaclasses .


def get_packages(directory, prefix):
    """return a list of subpackages for the given directory"""
    result = []
    for package in os.listdir(directory):
        absfile = join(directory, package)
        if isdir(absfile):
            if exists(join(absfile, "__init__.py")):
                if prefix:
                    result.append("%s.%s" % (prefix, package))
                else:
                    result.append(package)
                result += get_packages(absfile, result[-1])
    return result

def get_packages ( directory , prefix ) : result = [ ] for package in os . listdir ( directory ) : absfile = join ( directory , package ) if isdir ( absfile ) : if exists ( join ( absfile , "__init__.py" ) ) : if prefix : result . append ( "%s.%s" % ( prefix , package ) ) else : result . append ( package ) result += get_packages ( absfile , result [ - 1 ] ) return result