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
register_checker
(
self
,
checker
)
:
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
(
)
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

def
python3_porting_mode
(
self
)
:
self
.
disable
(
"all"
)
self
.
enable
(
"python3"
)
if
self
.
_error_mode
:
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 ( ) 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 ) 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

def check_astroid_module ( self , ast_node , walker , rawcheckers , tokencheckers ) : 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 : self . process_tokens ( tokens ) if self . _ignore_file : return False self . file_state . collect_block_lines ( self . msgs_store , ast_node ) for checker in rawcheckers : checker . process_module ( ast_node ) for checker in tokencheckers : checker . process_tokens ( tokens ) 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 ) : 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

def
register_plugins
(
linter
,
directory
)
:
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
:
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" ) : 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
_ini_format
(
stream
,
options
)
:
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
:
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
(
","
)
)
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 ) 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 compute_content ( self , layout ) : 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 ) : 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()

def possible_exc_types ( node ) : 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 : 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 ( ) 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 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 overridden_method ( klass , name ) : try : parent = next ( klass . local_attr_ancestors ( name ) ) except ( StopIteration , KeyError ) : return None try : meth_node = parent [ name ] except KeyError : 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

def _detect_global_scope ( node , frame , defframe ) : 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 not isinstance ( node . parent , ( astroid . FunctionDef , astroid . Arguments ) ) : return False elif any ( not isinstance ( f , ( astroid . ClassDef , astroid . Module ) ) for f in ( frame , defframe ) ) : return False break_scopes = [ ] for s in ( scope , def_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 : return False 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 : 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 : break else : if not_defined_locally_by_import : 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
        )

def _ignore_class_scope ( self , node ) : 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),),
                )

def _check_unpacking ( self , infered , node , targets ) : 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 ) : return if isinstance ( infered , ( astroid . Tuple , astroid . List ) ) : values = infered . itered ( ) if len ( targets ) != len ( values ) : 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 ) , ) , ) 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)

def _check_metaclasses ( self , node ) : consumed = [ ] for child_node in node . get_children ( ) : if isinstance ( child_node , astroid . ClassDef ) : consumed . extend ( self . _check_classdef_metaclasses ( child_node , node ) ) 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


def install(**kwargs):
    """setup entry point"""
    if USE_SETUPTOOLS:
        if "--force-manifest" in sys.argv:
            sys.argv.remove("--force-manifest")
    packages = [modname] + get_packages(join(base_dir, "pylint"), modname)
    if USE_SETUPTOOLS:
        if install_requires:
            kwargs["install_requires"] = install_requires
            kwargs["dependency_links"] = dependency_links
        kwargs["entry_points"] = {
            "console_scripts": [
                "pylint = pylint:run_pylint",
                "epylint = pylint:run_epylint",
                "pyreverse = pylint:run_pyreverse",
                "symilar = pylint:run_symilar",
            ]
        }
    kwargs["packages"] = packages
    cmdclass = {"install_lib": MyInstallLib, "build_py": build_py}
    if easy_install_lib:
        cmdclass["easy_install"] = easy_install
    return setup(
        name=distname,
        version=__pkginfo__["version"],
        license=__pkginfo__["license"],
        description=__pkginfo__["description"],
        long_description=long_description,
        author=__pkginfo__["author"],
        author_email=__pkginfo__["author_email"],
        url=__pkginfo__["web"],
        scripts=ensure_scripts(scripts),
        classifiers=__pkginfo__["classifiers"],
        data_files=data_files,
        ext_modules=ext_modules,
        cmdclass=cmdclass,
        extras_require=extras_require,
        test_suite="test",
        python_requires=">=3.4.*",
        setup_requires=["pytest-runner"],
        tests_require=["pytest"],
        **kwargs
    )

def
install
(
**
kwargs
)
:
if
USE_SETUPTOOLS
:
if
"--force-manifest"
in
sys
.
argv
:
sys
.
argv
.
remove
(
"--force-manifest"
)
packages
=
[
modname
]
+
get_packages
(
join
(
base_dir
,
"pylint"
)
,
modname
)
if
USE_SETUPTOOLS
:
if
install_requires
:
kwargs
[
"install_requires"
]
=
install_requires
kwargs
[
"dependency_links"
]
=
dependency_links
kwargs
[
"entry_points"
]
=
{
"console_scripts"
:
[
"pylint = pylint:run_pylint"
,
"epylint = pylint:run_epylint"
,
"pyreverse = pylint:run_pyreverse"
,
"symilar = pylint:run_symilar"
,
]
}
kwargs
[
"packages"
]
=
packages
cmdclass
=
{
"install_lib"
:
MyInstallLib
,
"build_py"
:
build_py
}
if
easy_install_lib
:
cmdclass
[
"easy_install"
]
=
easy_install
return
setup
(
name
=
distname
,
version
=
__pkginfo__
[
"version"
]
,
license
=
__pkginfo__
[
"license"
]
,
description
=
__pkginfo__
[
"description"
]
,
long_description
=
long_description
,
author
=
__pkginfo__
[
"author"
]
,
author_email
=
__pkginfo__
[
"author_email"
]
,
url
=
__pkginfo__
[
"web"
]
,
scripts
=
ensure_scripts
(
scripts
)
,
classifiers
=
__pkginfo__
[
"classifiers"
]
,
data_files
=
data_files
,
ext_modules
=
ext_modules
,
cmdclass
=
cmdclass
,
extras_require
=
extras_require
,
test_suite
=
"test"
,
python_requires
=
">=3.4.*"
,
setup_requires
=
[
"pytest-runner"
]
,
tests_require
=
[
"pytest"
]
,
**
kwargs
)


def run(self):
        """overridden from install_lib class"""
        install_lib.install_lib.run(self)
        # manually install included directories if any
        if include_dirs:
            for directory in include_dirs:
                dest = join(self.install_dir, directory)
                if sys.version_info >= (3, 0):
                    exclude = {"invalid_encoded_data*", "unknown_encoding*"}
                else:
                    exclude = set()
                shutil.rmtree(dest, ignore_errors=True)
                shutil.copytree(
                    directory, dest, ignore=shutil.ignore_patterns(*exclude)
                )

def run ( self ) : install_lib . install_lib . run ( self ) if include_dirs : for directory in include_dirs : dest = join ( self . install_dir , directory ) if sys . version_info >= ( 3 , 0 ) : exclude = { "invalid_encoded_data*" , "unknown_encoding*" } else : exclude = set ( ) shutil . rmtree ( dest , ignore_errors = True ) shutil . copytree ( directory , dest , ignore = shutil . ignore_patterns ( * exclude ) )


def report_similarities(sect, stats, old_stats):
    """make a layout with some stats about duplication"""
    lines = ["", "now", "previous", "difference"]
    lines += table_lines_from_stats(
        stats, old_stats, ("nb_duplicated_lines", "percent_duplicated_lines")
    )
    sect.append(Table(children=lines, cols=4, rheaders=1, cheaders=1))

def report_similarities ( sect , stats , old_stats ) : lines = [ "" , "now" , "previous" , "difference" ] lines += table_lines_from_stats ( stats , old_stats , ( "nb_duplicated_lines" , "percent_duplicated_lines" ) ) sect . append ( Table ( children = lines , cols = 4 , rheaders = 1 , cheaders = 1 ) )


def Run(argv=None):
    """standalone command line access point"""
    if argv is None:
        argv = sys.argv[1:]
    from getopt import getopt

    s_opts = "hdi"
    l_opts = (
        "help",
        "duplicates=",
        "ignore-comments",
        "ignore-imports",
        "ignore-docstrings",
    )
    min_lines = 4
    ignore_comments = False
    ignore_docstrings = False
    ignore_imports = False
    opts, args = getopt(argv, s_opts, l_opts)
    for opt, val in opts:
        if opt in ("-d", "--duplicates"):
            min_lines = int(val)
        elif opt in ("-h", "--help"):
            usage()
        elif opt in ("-i", "--ignore-comments"):
            ignore_comments = True
        elif opt in ("--ignore-docstrings",):
            ignore_docstrings = True
        elif opt in ("--ignore-imports",):
            ignore_imports = True
    if not args:
        usage(1)
    sim = Similar(min_lines, ignore_comments, ignore_docstrings, ignore_imports)
    for filename in args:
        with open(filename) as stream:
            sim.append_stream(filename, stream)
    sim.run()
    sys.exit(0)

def Run ( argv = None ) : if argv is None : argv = sys . argv [ 1 : ] from getopt import getopt s_opts = "hdi" l_opts = ( "help" , "duplicates=" , "ignore-comments" , "ignore-imports" , "ignore-docstrings" , ) min_lines = 4 ignore_comments = False ignore_docstrings = False ignore_imports = False opts , args = getopt ( argv , s_opts , l_opts ) for opt , val in opts : if opt in ( "-d" , "--duplicates" ) : min_lines = int ( val ) elif opt in ( "-h" , "--help" ) : usage ( ) elif opt in ( "-i" , "--ignore-comments" ) : ignore_comments = True elif opt in ( "--ignore-docstrings" , ) : ignore_docstrings = True elif opt in ( "--ignore-imports" , ) : ignore_imports = True if not args : usage ( 1 ) sim = Similar ( min_lines , ignore_comments , ignore_docstrings , ignore_imports ) for filename in args : with open ( filename ) as stream : sim . append_stream ( filename , stream ) sim . run ( ) sys . exit ( 0 )


def append_stream(self, streamid, stream, encoding=None):
        """append a file to search for similarities"""
        if encoding is None:
            readlines = stream.readlines
        else:
            readlines = decoding_stream(stream, encoding).readlines
        try:
            self.linesets.append(
                LineSet(
                    streamid,
                    readlines(),
                    self.ignore_comments,
                    self.ignore_docstrings,
                    self.ignore_imports,
                )
            )
        except UnicodeDecodeError:
            pass

def append_stream ( self , streamid , stream , encoding = None ) : if encoding is None : readlines = stream . readlines else : readlines = decoding_stream ( stream , encoding ) . readlines try : self . linesets . append ( LineSet ( streamid , readlines ( ) , self . ignore_comments , self . ignore_docstrings , self . ignore_imports , ) ) except UnicodeDecodeError : pass


def _compute_sims(self):
        """compute similarities in appended files"""
        no_duplicates = defaultdict(list)
        for num, lineset1, idx1, lineset2, idx2 in self._iter_sims():
            duplicate = no_duplicates[num]
            for couples in duplicate:
                if (lineset1, idx1) in couples or (lineset2, idx2) in couples:
                    couples.add((lineset1, idx1))
                    couples.add((lineset2, idx2))
                    break
            else:
                duplicate.append({(lineset1, idx1), (lineset2, idx2)})
        sims = []
        for num, ensembles in no_duplicates.items():
            for couples in ensembles:
                sims.append((num, couples))
        sims.sort()
        sims.reverse()
        return sims

def _compute_sims ( self ) : no_duplicates = defaultdict ( list ) for num , lineset1 , idx1 , lineset2 , idx2 in self . _iter_sims ( ) : duplicate = no_duplicates [ num ] for couples in duplicate : if ( lineset1 , idx1 ) in couples or ( lineset2 , idx2 ) in couples : couples . add ( ( lineset1 , idx1 ) ) couples . add ( ( lineset2 , idx2 ) ) break else : duplicate . append ( { ( lineset1 , idx1 ) , ( lineset2 , idx2 ) } ) sims = [ ] for num , ensembles in no_duplicates . items ( ) : for couples in ensembles : sims . append ( ( num , couples ) ) sims . sort ( ) sims . reverse ( ) return sims


def _display_sims(self, sims):
        """display computed similarities on stdout"""
        nb_lignes_dupliquees = 0
        for num, couples in sims:
            print()
            print(num, "similar lines in", len(couples), "files")
            couples = sorted(couples)
            for lineset, idx in couples:
                print("==%s:%s" % (lineset.name, idx))
            # pylint: disable=W0631
            for line in lineset._real_lines[idx : idx + num]:
                print("  ", line.rstrip())
            nb_lignes_dupliquees += num * (len(couples) - 1)
        nb_total_lignes = sum([len(lineset) for lineset in self.linesets])
        print(
            "TOTAL lines=%s duplicates=%s percent=%.2f"
            % (
                nb_total_lignes,
                nb_lignes_dupliquees,
                nb_lignes_dupliquees * 100.0 / nb_total_lignes,
            )
        )


def _find_common(self, lineset1, lineset2):
        """find similarities in the two given linesets"""
        lines1 = lineset1.enumerate_stripped
        lines2 = lineset2.enumerate_stripped
        find = lineset2.find
        index1 = 0
        min_lines = self.min_lines
        while index1 < len(lineset1):
            skip = 1
            num = 0
            for index2 in find(lineset1[index1]):
                non_blank = 0
                for num, ((_, line1), (_, line2)) in enumerate(
                    zip(lines1(index1), lines2(index2))
                ):
                    if line1 != line2:
                        if non_blank > min_lines:
                            yield num, lineset1, index1, lineset2, index2
                        skip = max(skip, num)
                        break
                    if line1:
                        non_blank += 1
                else:
                    # we may have reach the end
                    num += 1
                    if non_blank > min_lines:
                        yield num, lineset1, index1, lineset2, index2
                    skip = max(skip, num)
            index1 += skip

def _find_common ( self , lineset1 , lineset2 ) : lines1 = lineset1 . enumerate_stripped lines2 = lineset2 . enumerate_stripped find = lineset2 . find index1 = 0 min_lines = self . min_lines while index1 < len ( lineset1 ) : skip = 1 num = 0 for index2 in find ( lineset1 [ index1 ] ) : non_blank = 0 for num , ( ( _ , line1 ) , ( _ , line2 ) ) in enumerate ( zip ( lines1 ( index1 ) , lines2 ( index2 ) ) ) : if line1 != line2 : if non_blank > min_lines : yield num , lineset1 , index1 , lineset2 , index2 skip = max ( skip , num ) break if line1 : non_blank += 1 else : num += 1 if non_blank > min_lines : yield num , lineset1 , index1 , lineset2 , index2 skip = max ( skip , num ) index1 += skip


def _iter_sims(self):
        """iterate on similarities among all files, by making a cartesian
        product
        """
        for idx, lineset in enumerate(self.linesets[:-1]):
            for lineset2 in self.linesets[idx + 1 :]:
                for sim in self._find_common(lineset, lineset2):
                    yield sim

def _iter_sims ( self ) : for idx , lineset in enumerate ( self . linesets [ : - 1 ] ) : for lineset2 in self . linesets [ idx + 1 : ] : for sim in self . _find_common ( lineset , lineset2 ) : yield sim

iterate on similarities among all files by making a cartesian product


def enumerate_stripped(self, start_at=0):
        """return an iterator on stripped lines, starting from a given index
        if specified, else 0
        """
        idx = start_at
        if start_at:
            lines = self._stripped_lines[start_at:]
        else:
            lines = self._stripped_lines
        for line in lines:
            # if line:
            yield idx, line
            idx += 1

def enumerate_stripped ( self , start_at = 0 ) : idx = start_at if start_at : lines = self . _stripped_lines [ start_at : ] else : lines = self . _stripped_lines for line in lines : yield idx , line idx += 1

return an iterator on stripped lines starting from a given index if specified else 0


def _mk_index(self):
        """create the index for this set"""
        index = defaultdict(list)
        for line_no, line in enumerate(self._stripped_lines):
            if line:
                index[line].append(line_no)
        return index

def _mk_index ( self ) : index = defaultdict ( list ) for line_no , line in enumerate ( self . _stripped_lines ) : if line : index [ line ] . append ( line_no ) return index


def _definition_equivalent_to_call(definition, call):
    """Check if a definition signature is equivalent to a call."""
    if definition.kwargs:
        same_kw_variadics = definition.kwargs in call.starred_kws
    else:
        same_kw_variadics = not call.starred_kws
    if definition.varargs:
        same_args_variadics = definition.varargs in call.starred_args
    else:
        same_args_variadics = not call.starred_args
    same_kwonlyargs = all(kw in call.kws for kw in definition.kwonlyargs)
    same_args = definition.args == call.args

    no_additional_kwarg_arguments = True
    if call.kws:
        for keyword in call.kws:
            is_arg = keyword in call.args
            is_kwonly = keyword in definition.kwonlyargs
            if not is_arg and not is_kwonly:
                # Maybe this argument goes into **kwargs,
                # or it is an extraneous argument.
                # In any case, the signature is different than
                # the call site, which stops our search.
                no_additional_kwarg_arguments = False
                break

    return all(
        (
            same_args,
            same_kwonlyargs,
            same_args_variadics,
            same_kw_variadics,
            no_additional_kwarg_arguments,
        )
    )

def _definition_equivalent_to_call ( definition , call ) : if definition . kwargs : same_kw_variadics = definition . kwargs in call . starred_kws else : same_kw_variadics = not call . starred_kws if definition . varargs : same_args_variadics = definition . varargs in call . starred_args else : same_args_variadics = not call . starred_args same_kwonlyargs = all ( kw in call . kws for kw in definition . kwonlyargs ) same_args = definition . args == call . args no_additional_kwarg_arguments = True if call . kws : for keyword in call . kws : is_arg = keyword in call . args is_kwonly = keyword in definition . kwonlyargs if not is_arg and not is_kwonly : no_additional_kwarg_arguments = False break return all ( ( same_args , same_kwonlyargs , same_args_variadics , same_kw_variadics , no_additional_kwarg_arguments , ) )

Check if a definition signature is equivalent to a call .


def _check_arg_equality(node_a, node_b, attr_name):
    """
    Check equality of nodes based on the comparison of their attributes named attr_name.

    Args:
        node_a (astroid.node): first node to compare.
        node_b (astroid.node): second node to compare.
        attr_name (str): name of the nodes attribute to use for comparison.

    Returns:
        bool: True if node_a.attr_name == node_b.attr_name, False otherwise.
    """
    return getattr(node_a, attr_name) == getattr(node_b, attr_name)

def _check_arg_equality ( node_a , node_b , attr_name ) : return getattr ( node_a , attr_name ) == getattr ( node_b , attr_name )

Check equality of nodes based on the comparison of their attributes named attr_name .


def _has_different_parameters_default_value(original, overridden):
    """
    Check if original and overridden methods arguments have different default values

    Return True if one of the overridden arguments has a default
    value different from the default value of the original argument
    If one of the method doesn't have argument (.args is None)
    return False
    """
    if original.args is None or overridden.args is None:
        return False

    all_args = chain(original.args, original.kwonlyargs)
    original_param_names = [param.name for param in all_args]
    default_missing = object()
    for param_name in original_param_names:
        try:
            original_default = original.default_value(param_name)
        except astroid.exceptions.NoDefault:
            original_default = default_missing
        try:
            overridden_default = overridden.default_value(param_name)
        except astroid.exceptions.NoDefault:
            overridden_default = default_missing

        default_list = [
            arg == default_missing for arg in (original_default, overridden_default)
        ]
        if any(default_list) and not all(default_list):
            # Only one arg has no default value
            return True

        astroid_type_compared_attr = {
            astroid.Const: "value",
            astroid.ClassDef: "name",
            astroid.Tuple: "elts",
            astroid.List: "elts",
        }
        handled_types = tuple(
            astroid_type for astroid_type in astroid_type_compared_attr
        )
        original_type = _get_node_type(original_default, handled_types)
        if original_type:
            #  We handle only astroid types that are inside the dict astroid_type_compared_attr
            if not isinstance(overridden_default, original_type):
                #  Two args with same name but different types
                return True
            if not _check_arg_equality(
                original_default,
                overridden_default,
                astroid_type_compared_attr[original_type],
            ):
                # Two args with same type but different values
                return True
    return False

def _has_different_parameters_default_value ( original , overridden ) : if original . args is None or overridden . args is None : return False all_args = chain ( original . args , original . kwonlyargs ) original_param_names = [ param . name for param in all_args ] default_missing = object ( ) for param_name in original_param_names : try : original_default = original . default_value ( param_name ) except astroid . exceptions . NoDefault : original_default = default_missing try : overridden_default = overridden . default_value ( param_name ) except astroid . exceptions . NoDefault : overridden_default = default_missing default_list = [ arg == default_missing for arg in ( original_default , overridden_default ) ] if any ( default_list ) and not all ( default_list ) : return True astroid_type_compared_attr = { astroid . Const : "value" , astroid . ClassDef : "name" , astroid . Tuple : "elts" , astroid . List : "elts" , } handled_types = tuple ( astroid_type for astroid_type in astroid_type_compared_attr ) original_type = _get_node_type ( original_default , handled_types ) if original_type : if not isinstance ( overridden_default , original_type ) : return True if not _check_arg_equality ( original_default , overridden_default , astroid_type_compared_attr [ original_type ] , ) : return True return False


def _different_parameters(original, overridden, dummy_parameter_regex):
    """Determine if the two methods have different parameters

    They are considered to have different parameters if:

       * they have different positional parameters, including different names

       * one of the methods is having variadics, while the other is not

       * they have different keyword only parameters.

    """
    original_parameters = _positional_parameters(original)
    overridden_parameters = _positional_parameters(overridden)

    different_positional = _has_different_parameters(
        original_parameters, overridden_parameters, dummy_parameter_regex
    )
    different_kwonly = _has_different_parameters(
        original.args.kwonlyargs, overridden.args.kwonlyargs, dummy_parameter_regex
    )
    if original.name in PYMETHODS:
        # Ignore the difference for special methods. If the parameter
        # numbers are different, then that is going to be caught by
        # unexpected-special-method-signature.
        # If the names are different, it doesn't matter, since they can't
        # be used as keyword arguments anyway.
        different_positional = different_kwonly = False

    # Both or none should have extra variadics, otherwise the method
    # loses or gains capabilities that are not reflected into the parent method,
    # leading to potential inconsistencies in the code.
    different_kwarg = (
        sum(1 for param in (original.args.kwarg, overridden.args.kwarg) if not param)
        == 1
    )
    different_vararg = (
        sum(1 for param in (original.args.vararg, overridden.args.vararg) if not param)
        == 1
    )

    return any(
        (different_positional, different_kwarg, different_vararg, different_kwonly)
    )

def _different_parameters ( original , overridden , dummy_parameter_regex ) : original_parameters = _positional_parameters ( original ) overridden_parameters = _positional_parameters ( overridden ) different_positional = _has_different_parameters ( original_parameters , overridden_parameters , dummy_parameter_regex ) different_kwonly = _has_different_parameters ( original . args . kwonlyargs , overridden . args . kwonlyargs , dummy_parameter_regex ) if original . name in PYMETHODS : different_positional = different_kwonly = False different_kwarg = ( sum ( 1 for param in ( original . args . kwarg , overridden . args . kwarg ) if not param ) == 1 ) different_vararg = ( sum ( 1 for param in ( original . args . vararg , overridden . args . vararg ) if not param ) == 1 ) return any ( ( different_positional , different_kwarg , different_vararg , different_kwonly ) )


def _safe_infer_call_result(node, caller, context=None):
    """
    Safely infer the return value of a function.

    Returns None if inference failed or if there is some ambiguity (more than
    one node has been inferred). Otherwise returns infered value.
    """
    try:
        inferit = node.infer_call_result(caller, context=context)
        value = next(inferit)
    except astroid.InferenceError:
        return None  # inference failed
    except StopIteration:
        return None  # no values infered
    try:
        next(inferit)
        return None  # there is ambiguity on the inferred node
    except astroid.InferenceError:
        return None  # there is some kind of ambiguity
    except StopIteration:
        return value

def _safe_infer_call_result ( node , caller , context = None ) : try : inferit = node . infer_call_result ( caller , context = context ) value = next ( inferit ) except astroid . InferenceError : return None except StopIteration : return None try : next ( inferit ) return None except astroid . InferenceError : return None except StopIteration : return value

Safely infer the return value of a function .


def set_accessed(self, node):
        """Set the given node as accessed."""

        frame = node_frame_class(node)
        if frame is None:
            # The node does not live in a class.
            return
        self._scopes[frame][node.attrname].append(node)

def set_accessed ( self , node ) : frame = node_frame_class ( node ) if frame is None : return self . _scopes [ frame ] [ node . attrname ] . append ( node )


def visit_classdef(self, node):
        """init visit variable _accessed
        """
        self._check_bases_classes(node)
        # if not an exception or a metaclass
        if node.type == "class" and has_known_bases(node):
            try:
                node.local_attr("__init__")
            except astroid.NotFoundError:
                self.add_message("no-init", args=node, node=node)
        self._check_slots(node)
        self._check_proper_bases(node)
        self._check_consistent_mro(node)

def visit_classdef ( self , node ) : self . _check_bases_classes ( node ) if node . type == "class" and has_known_bases ( node ) : try : node . local_attr ( "__init__" ) except astroid . NotFoundError : self . add_message ( "no-init" , args = node , node = node ) self . _check_slots ( node ) self . _check_proper_bases ( node ) self . _check_consistent_mro ( node )


def _check_consistent_mro(self, node):
        """Detect that a class has a consistent mro or duplicate bases."""
        try:
            node.mro()
        except InconsistentMroError:
            self.add_message("inconsistent-mro", args=node.name, node=node)
        except DuplicateBasesError:
            self.add_message("duplicate-bases", args=node.name, node=node)
        except NotImplementedError:
            # Old style class, there's no mro so don't do anything.
            pass

def _check_consistent_mro ( self , node ) : try : node . mro ( ) except InconsistentMroError : self . add_message ( "inconsistent-mro" , args = node . name , node = node ) except DuplicateBasesError : self . add_message ( "duplicate-bases" , args = node . name , node = node ) except NotImplementedError : pass

Detect that a class has a consistent mro or duplicate bases .


def _check_proper_bases(self, node):
        """
        Detect that a class inherits something which is not
        a class or a type.
        """
        for base in node.bases:
            ancestor = safe_infer(base)
            if ancestor in (astroid.Uninferable, None):
                continue
            if isinstance(ancestor, astroid.Instance) and ancestor.is_subtype_of(
                "%s.type" % (BUILTINS,)
            ):
                continue

            if not isinstance(ancestor, astroid.ClassDef) or _is_invalid_base_class(
                ancestor
            ):
                self.add_message("inherit-non-class", args=base.as_string(), node=node)

            if ancestor.name == object.__name__:
                self.add_message(
                    "useless-object-inheritance", args=node.name, node=node
                )

def _check_proper_bases ( self , node ) : for base in node . bases : ancestor = safe_infer ( base ) if ancestor in ( astroid . Uninferable , None ) : continue if isinstance ( ancestor , astroid . Instance ) and ancestor . is_subtype_of ( "%s.type" % ( BUILTINS , ) ) : continue if not isinstance ( ancestor , astroid . ClassDef ) or _is_invalid_base_class ( ancestor ) : self . add_message ( "inherit-non-class" , args = base . as_string ( ) , node = node ) if ancestor . name == object . __name__ : self . add_message ( "useless-object-inheritance" , args = node . name , node = node )

Detect that a class inherits something which is not a class or a type .


def visit_functiondef(self, node):
        """check method arguments, overriding"""
        # ignore actual functions
        if not node.is_method():
            return

        self._check_useless_super_delegation(node)

        klass = node.parent.frame()
        self._meth_could_be_func = True
        # check first argument is self if this is actually a method
        self._check_first_arg_for_type(node, klass.type == "metaclass")
        if node.name == "__init__":
            self._check_init(node)
            return
        # check signature if the method overloads inherited method
        for overridden in klass.local_attr_ancestors(node.name):
            # get astroid for the searched method
            try:
                meth_node = overridden[node.name]
            except KeyError:
                # we have found the method but it's not in the local
                # dictionary.
                # This may happen with astroid build from living objects
                continue
            if not isinstance(meth_node, astroid.FunctionDef):
                continue
            self._check_signature(node, meth_node, "overridden", klass)
            break
        if node.decorators:
            for decorator in node.decorators.nodes:
                if isinstance(decorator, astroid.Attribute) and decorator.attrname in (
                    "getter",
                    "setter",
                    "deleter",
                ):
                    # attribute affectation will call this method, not hiding it
                    return
                if isinstance(decorator, astroid.Name):
                    if decorator.name == "property":
                        # attribute affectation will either call a setter or raise
                        # an attribute error, anyway not hiding the function
                        return

                # Infer the decorator and see if it returns something useful
                inferred = safe_infer(decorator)
                if not inferred:
                    return
                if isinstance(inferred, astroid.FunctionDef):
                    # Okay, it's a decorator, let's see what it can infer.
                    try:
                        inferred = next(inferred.infer_call_result(inferred))
                    except astroid.InferenceError:
                        return
                try:
                    if (
                        isinstance(inferred, (astroid.Instance, astroid.ClassDef))
                        and inferred.getattr("__get__")
                        and inferred.getattr("__set__")
                    ):
                        return
                except astroid.AttributeInferenceError:
                    pass

        # check if the method is hidden by an attribute
        try:
            overridden = klass.instance_attr(node.name)[0]  # XXX
            overridden_frame = overridden.frame()
            if (
                isinstance(overridden_frame, astroid.FunctionDef)
                and overridden_frame.type == "method"
            ):
                overridden_frame = overridden_frame.parent.frame()
            if isinstance(overridden_frame, astroid.ClassDef) and klass.is_subtype_of(
                overridden_frame.qname()
            ):
                args = (overridden.root().name, overridden.fromlineno)
                self.add_message("method-hidden", args=args, node=node)
        except astroid.NotFoundError:
            pass

def visit_functiondef ( self , node ) : if not node . is_method ( ) : return self . _check_useless_super_delegation ( node ) klass = node . parent . frame ( ) self . _meth_could_be_func = True self . _check_first_arg_for_type ( node , klass . type == "metaclass" ) if node . name == "__init__" : self . _check_init ( node ) return for overridden in klass . local_attr_ancestors ( node . name ) : try : meth_node = overridden [ node . name ] except KeyError : continue if not isinstance ( meth_node , astroid . FunctionDef ) : continue self . _check_signature ( node , meth_node , "overridden" , klass ) break if node . decorators : for decorator in node . decorators . nodes : if isinstance ( decorator , astroid . Attribute ) and decorator . attrname in ( "getter" , "setter" , "deleter" , ) : return if isinstance ( decorator , astroid . Name ) : if decorator . name == "property" : return inferred = safe_infer ( decorator ) if not inferred : return if isinstance ( inferred , astroid . FunctionDef ) : try : inferred = next ( inferred . infer_call_result ( inferred ) ) except astroid . InferenceError : return try : if ( isinstance ( inferred , ( astroid . Instance , astroid . ClassDef ) ) and inferred . getattr ( "__get__" ) and inferred . getattr ( "__set__" ) ) : return except astroid . AttributeInferenceError : pass try : overridden = klass . instance_attr ( node . name ) [ 0 ] overridden_frame = overridden . frame ( ) if ( isinstance ( overridden_frame , astroid . FunctionDef ) and overridden_frame . type == "method" ) : overridden_frame = overridden_frame . parent . frame ( ) if isinstance ( overridden_frame , astroid . ClassDef ) and klass . is_subtype_of ( overridden_frame . qname ( ) ) : args = ( overridden . root ( ) . name , overridden . fromlineno ) self . add_message ( "method-hidden" , args = args , node = node ) except astroid . NotFoundError : pass


def _check_useless_super_delegation(self, function):
        """Check if the given function node is an useless method override

        We consider it *useless* if it uses the super() builtin, but having
        nothing additional whatsoever than not implementing the method at all.
        If the method uses super() to delegate an operation to the rest of the MRO,
        and if the method called is the same as the current one, the arguments
        passed to super() are the same as the parameters that were passed to
        this method, then the method could be removed altogether, by letting
        other implementation to take precedence.
        """

        if (
            not function.is_method()
            # With decorators is a change of use
            or function.decorators
        ):
            return

        body = function.body
        if len(body) != 1:
            # Multiple statements, which means this overridden method
            # could do multiple things we are not aware of.
            return

        statement = body[0]
        if not isinstance(statement, (astroid.Expr, astroid.Return)):
            # Doing something else than what we are interested into.
            return

        call = statement.value
        if (
            not isinstance(call, astroid.Call)
            # Not a super() attribute access.
            or not isinstance(call.func, astroid.Attribute)
        ):
            return

        # Should be a super call.
        try:
            super_call = next(call.func.expr.infer())
        except astroid.InferenceError:
            return
        else:
            if not isinstance(super_call, objects.Super):
                return

        # The name should be the same.
        if call.func.attrname != function.name:
            return

        # Should be a super call with the MRO pointer being the
        # current class and the type being the current instance.
        current_scope = function.parent.scope()
        if (
            super_call.mro_pointer != current_scope
            or not isinstance(super_call.type, astroid.Instance)
            or super_call.type.name != current_scope.name
        ):
            return

        #  Check values of default args
        klass = function.parent.frame()
        meth_node = None
        for overridden in klass.local_attr_ancestors(function.name):
            # get astroid for the searched method
            try:
                meth_node = overridden[function.name]
            except KeyError:
                # we have found the method but it's not in the local
                # dictionary.
                # This may happen with astroid build from living objects
                continue
            if (
                not isinstance(meth_node, astroid.FunctionDef)
                # If the method have an ancestor which is not a
                # function then it is legitimate to redefine it
                or _has_different_parameters_default_value(
                    meth_node.args, function.args
                )
            ):
                return
            break

        # Detect if the parameters are the same as the call's arguments.
        params = _signature_from_arguments(function.args)
        args = _signature_from_call(call)

        if meth_node is not None:

            def form_annotations(annotations):
                return [
                    annotation.as_string() for annotation in filter(None, annotations)
                ]

            called_annotations = form_annotations(function.args.annotations)
            overridden_annotations = form_annotations(meth_node.args.annotations)
            if called_annotations and overridden_annotations:
                if called_annotations != overridden_annotations:
                    return

        if _definition_equivalent_to_call(params, args):
            self.add_message(
                "useless-super-delegation", node=function, args=(function.name,)
            )

def _check_useless_super_delegation ( self , function ) : if ( not function . is_method ( ) or function . decorators ) : return body = function . body if len ( body ) != 1 : return statement = body [ 0 ] if not isinstance ( statement , ( astroid . Expr , astroid . Return ) ) : return call = statement . value if ( not isinstance ( call , astroid . Call ) or not isinstance ( call . func , astroid . Attribute ) ) : return try : super_call = next ( call . func . expr . infer ( ) ) except astroid . InferenceError : return else : if not isinstance ( super_call , objects . Super ) : return if call . func . attrname != function . name : return current_scope = function . parent . scope ( ) if ( super_call . mro_pointer != current_scope or not isinstance ( super_call . type , astroid . Instance ) or super_call . type . name != current_scope . name ) : return klass = function . parent . frame ( ) meth_node = None for overridden in klass . local_attr_ancestors ( function . name ) : try : meth_node = overridden [ function . name ] except KeyError : continue if ( not isinstance ( meth_node , astroid . FunctionDef ) or _has_different_parameters_default_value ( meth_node . args , function . args ) ) : return break params = _signature_from_arguments ( function . args ) args = _signature_from_call ( call ) if meth_node is not None : def form_annotations ( annotations ) : return [ annotation . as_string ( ) for annotation in filter ( None , annotations ) ] called_annotations = form_annotations ( function . args . annotations ) overridden_annotations = form_annotations ( meth_node . args . annotations ) if called_annotations and overridden_annotations : if called_annotations != overridden_annotations : return if _definition_equivalent_to_call ( params , args ) : self . add_message ( "useless-super-delegation" , node = function , args = ( function . name , ) )


def leave_functiondef(self, node):
        """on method node, check if this method couldn't be a function

        ignore class, static and abstract methods, initializer,
        methods overridden from a parent class.
        """
        if node.is_method():
            if node.args.args is not None:
                self._first_attrs.pop()
            if not self.linter.is_message_enabled("no-self-use"):
                return
            class_node = node.parent.frame()
            if (
                self._meth_could_be_func
                and node.type == "method"
                and node.name not in PYMETHODS
                and not (
                    node.is_abstract()
                    or overrides_a_method(class_node, node.name)
                    or decorated_with_property(node)
                    or _has_bare_super_call(node)
                )
            ):
                self.add_message("no-self-use", node=node)

def leave_functiondef ( self , node ) : if node . is_method ( ) : if node . args . args is not None : self . _first_attrs . pop ( ) if not self . linter . is_message_enabled ( "no-self-use" ) : return class_node = node . parent . frame ( ) if ( self . _meth_could_be_func and node . type == "method" and node . name not in PYMETHODS and not ( node . is_abstract ( ) or overrides_a_method ( class_node , node . name ) or decorated_with_property ( node ) or _has_bare_super_call ( node ) ) ) : self . add_message ( "no-self-use" , node = node )

on method node check if this method couldn t be a function


def _check_in_slots(self, node):
        """ Check that the given AssignAttr node
        is defined in the class slots.
        """
        inferred = safe_infer(node.expr)
        if not isinstance(inferred, astroid.Instance):
            return

        klass = inferred._proxied
        if not has_known_bases(klass):
            return
        if "__slots__" not in klass.locals or not klass.newstyle:
            return

        slots = klass.slots()
        if slots is None:
            return
        # If any ancestor doesn't use slots, the slots
        # defined for this class are superfluous.
        if any(
            "__slots__" not in ancestor.locals and ancestor.name != "object"
            for ancestor in klass.ancestors()
        ):
            return

        if not any(slot.value == node.attrname for slot in slots):
            # If we have a '__dict__' in slots, then
            # assigning any name is valid.
            if not any(slot.value == "__dict__" for slot in slots):
                if _is_attribute_property(node.attrname, klass):
                    # Properties circumvent the slots mechanism,
                    # so we should not emit a warning for them.
                    return
                if node.attrname in klass.locals and _has_data_descriptor(
                    klass, node.attrname
                ):
                    # Descriptors circumvent the slots mechanism as well.
                    return
                if node.attrname == "__class__" and _has_same_layout_slots(
                    slots, node.parent.value
                ):
                    return
                self.add_message("assigning-non-slot", args=(node.attrname,), node=node)

def _check_in_slots ( self , node ) : inferred = safe_infer ( node . expr ) if not isinstance ( inferred , astroid . Instance ) : return klass = inferred . _proxied if not has_known_bases ( klass ) : return if "__slots__" not in klass . locals or not klass . newstyle : return slots = klass . slots ( ) if slots is None : return if any ( "__slots__" not in ancestor . locals and ancestor . name != "object" for ancestor in klass . ancestors ( ) ) : return if not any ( slot . value == node . attrname for slot in slots ) : if not any ( slot . value == "__dict__" for slot in slots ) : if _is_attribute_property ( node . attrname , klass ) : return if node . attrname in klass . locals and _has_data_descriptor ( klass , node . attrname ) : return if node . attrname == "__class__" and _has_same_layout_slots ( slots , node . parent . value ) : return self . add_message ( "assigning-non-slot" , args = ( node . attrname , ) , node = node )

Check that the given AssignAttr node is defined in the class slots .


def visit_name(self, node):
        """check if the name handle an access to a class member
        if so, register it
        """
        if self._first_attrs and (
            node.name == self._first_attrs[-1] or not self._first_attrs[-1]
        ):
            self._meth_could_be_func = False

def visit_name ( self , node ) : if self . _first_attrs and ( node . name == self . _first_attrs [ - 1 ] or not self . _first_attrs [ - 1 ] ) : self . _meth_could_be_func = False

check if the name handle an access to a class member if so register it