diff options
author | Sylvain Th?nault <sylvain.thenault@logilab.fr> | 2014-11-19 09:50:28 +0100 |
---|---|---|
committer | Sylvain Th?nault <sylvain.thenault@logilab.fr> | 2014-11-19 09:50:28 +0100 |
commit | 51af5e9c258e66445366309c89c55d6db464af53 (patch) | |
tree | f3a684773bfd24426ab903137a341dbf03a3f4a3 | |
parent | 9904ce2f5f81cc4b4175d8cd322ee376c91b2f18 (diff) | |
download | pylint-51af5e9c258e66445366309c89c55d6db464af53.tar.gz |
pylint pylint
-rw-r--r-- | checkers/__init__.py | 2 | ||||
-rw-r--r-- | checkers/base.py | 38 | ||||
-rw-r--r-- | checkers/exceptions.py | 6 | ||||
-rw-r--r-- | checkers/format.py | 24 | ||||
-rw-r--r-- | checkers/imports.py | 11 | ||||
-rw-r--r-- | checkers/logging.py | 61 | ||||
-rw-r--r-- | checkers/newstyle.py | 4 | ||||
-rw-r--r-- | checkers/spelling.py | 4 | ||||
-rw-r--r-- | checkers/strings.py | 14 | ||||
-rw-r--r-- | checkers/utils.py | 8 | ||||
-rw-r--r-- | checkers/variables.py | 60 | ||||
-rw-r--r-- | config.py | 2 | ||||
-rw-r--r-- | gui.py | 10 | ||||
-rw-r--r-- | lint.py | 44 | ||||
-rw-r--r-- | pyreverse/diadefslib.py | 2 | ||||
-rw-r--r-- | pyreverse/utils.py | 2 | ||||
-rw-r--r-- | reporters/__init__.py | 2 | ||||
-rw-r--r-- | reporters/guireporter.py | 1 | ||||
-rw-r--r-- | reporters/html.py | 1 | ||||
-rw-r--r-- | reporters/text.py | 2 | ||||
-rw-r--r-- | testutils.py | 10 | ||||
-rw-r--r-- | utils.py | 19 |
22 files changed, 167 insertions, 160 deletions
diff --git a/checkers/__init__.py b/checkers/__init__.py index 181a2b2..51adb4d 100644 --- a/checkers/__init__.py +++ b/checkers/__init__.py @@ -59,7 +59,7 @@ def table_lines_from_stats(stats, old_stats, columns): lines = [] for m_type in columns: new = stats[m_type] - format = str + format = str # pylint: disable=redefined-builtin if isinstance(new, float): format = lambda num: '%.3f' % num old = old_stats.get(m_type) diff --git a/checkers/base.py b/checkers/base.py index 32edee2..8198d16 100644 --- a/checkers/base.py +++ b/checkers/base.py @@ -19,10 +19,16 @@ import collections import itertools import sys -import astroid +import re + +import six +from six.moves import zip # pylint: disable=redefined-builtin + from logilab.common.ureports import Table -from astroid import are_exclusive, InferenceError + +import astroid import astroid.bases +from astroid import are_exclusive, InferenceError from pylint.interfaces import IAstroidChecker, INFERENCE, INFERENCE_FAILURE, HIGH from pylint.utils import EmptyReport @@ -42,10 +48,6 @@ from pylint.checkers.utils import ( ) -import re -import six -from six.moves import zip - # regex for class/function/variable/constant name CLASS_NAME_RGX = re.compile('[A-Z_][a-zA-Z0-9]+$') MOD_NAME_RGX = re.compile('(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$') @@ -126,6 +128,7 @@ def _loop_exits_early(loop): for child in loop.body: if isinstance(child, loop_nodes): # break statement may be in orelse of child loop. + # pylint: disable=superfluous-parens for orelse in (child.orelse or ()): for _ in orelse.nodes_of_class(astroid.Break, skip_klass=loop_nodes): return True @@ -134,6 +137,13 @@ def _loop_exits_early(loop): return True return False +def _is_multi_naming_match(match, node_type, confidence): + return (match is not None and + match.lastgroup is not None and + match.lastgroup not in EXEMPT_NAME_CATEGORIES + and (node_type != 'method' or confidence != INFERENCE_FAILURE)) + + if sys.version_info < (3, 0): PROPERTY_CLASSES = set(('__builtin__.property', 'abc.abstractproperty')) else: @@ -559,7 +569,7 @@ functions, methods if attr not in node: self.add_message('missing-module-attribute', node=node, args=attr) - def visit_class(self, node): + def visit_class(self, node): # pylint: disable=unused-argument """check module name, docstring and redefinition increment branch counter """ @@ -789,7 +799,7 @@ functions, methods """update try...finally flag""" self._tryfinallys.append(node) - def leave_tryfinally(self, node): + def leave_tryfinally(self, node): # pylint: disable=unused-argument """update try...finally flag""" self._tryfinallys.pop() @@ -958,8 +968,8 @@ class NameChecker(_BasicChecker): self._check_name('module', node.name.split('.')[-1], node) self._bad_names = {} - def leave_module(self, node): - for category, all_groups in six.iteritems(self._bad_names): + def leave_module(self, node): # pylint: disable=unused-argument + for all_groups in six.itervalues(self._bad_names): if len(all_groups) < 2: continue groups = collections.defaultdict(list) @@ -1044,12 +1054,6 @@ class NameChecker(_BasicChecker): def _find_name_group(self, node_type): return self._name_group.get(node_type, node_type) - def _is_multi_naming_match(self, match, node_type, confidence): - return (match is not None and - match.lastgroup is not None and - match.lastgroup not in EXEMPT_NAME_CATEGORIES - and (node_type != 'method' or confidence != INFERENCE_FAILURE)) - def _raise_name_warning(self, node, node_type, name, confidence): type_label = _NAME_TYPES[node_type][1] hint = '' @@ -1074,7 +1078,7 @@ class NameChecker(_BasicChecker): regexp = getattr(self.config, node_type + '_rgx') match = regexp.match(name) - if self._is_multi_naming_match(match, node_type, confidence): + if _is_multi_naming_match(match, node_type, confidence): name_group = self._find_name_group(node_type) bad_name_group = self._bad_names.setdefault(name_group, {}) warnings = bad_name_group.setdefault(match.lastgroup, []) diff --git a/checkers/exceptions.py b/checkers/exceptions.py index 0603d88..e8e5a54 100644 --- a/checkers/exceptions.py +++ b/checkers/exceptions.py @@ -203,7 +203,7 @@ class ExceptionsChecker(BaseChecker): else: self.add_message( 'nonstandard-exception', node=node, - confidence=INFERENCE if has_known_bases(expr) else INFERENCE_FAILURE) + confidence=INFERENCE if has_known_bases(expr) else INFERENCE_FAILURE) else: value_found = False else: @@ -251,8 +251,8 @@ class ExceptionsChecker(BaseChecker): if (isinstance(exc, astroid.Const) and exc.value is None): if ((isinstance(handler.type, astroid.Const) and - handler.type.value is None) or - handler.type.parent_of(exc)): + handler.type.value is None) or + handler.type.parent_of(exc)): # If the exception handler catches None or # the exception component, which is None, is # defined by the entire exception handler, then diff --git a/checkers/format.py b/checkers/format.py index b6aa306..9828674 100644 --- a/checkers/format.py +++ b/checkers/format.py @@ -24,9 +24,10 @@ Some parts of the process_token method is based from The Tab Nanny std module. import keyword import sys import tokenize -from functools import reduce +from functools import reduce # pylint: disable=redefined-builtin + import six -from six.moves import zip, map, filter +from six.moves import zip, map, filter # pylint: disable=redefined-builtin from astroid import nodes @@ -442,7 +443,7 @@ class FormatChecker(BaseTokenChecker): {'type': 'choice', 'metavar': '<empty or LF or CRLF>', 'default': '', 'choices': ['', 'LF', 'CRLF'], 'help': 'Expected format of line ending, e.g. empty (any line ending), LF or CRLF.'}), - ) + ) def __init__(self, linter=None): BaseTokenChecker.__init__(self, linter) @@ -622,13 +623,13 @@ class FormatChecker(BaseTokenChecker): return 'No', 'allowed' def _name_construct(token): - if tokens[i][1] == ',': + if token[1] == ',': return 'comma' - elif tokens[i][1] == ':': + elif token[1] == ':': return ':' - elif tokens[i][1] in '()[]{}': + elif token[1] in '()[]{}': return 'bracket' - elif tokens[i][1] in ('<', '>', '<=', '>=', '!=', '=='): + elif token[1] in ('<', '>', '<=', '>=', '!=', '=='): return 'comparison' else: if self._inside_brackets('('): @@ -637,7 +638,8 @@ class FormatChecker(BaseTokenChecker): return 'assignment' good_space = [True, True] - pairs = [(tokens[i-1], tokens[i]), (tokens[i], tokens[i+1])] + token = tokens[i] + pairs = [(tokens[i-1], token), (token, tokens[i+1])] for other_idx, (policy, token_pair) in enumerate(zip(policies, pairs)): if token_pair[other_idx][0] in _EOL or policy == _IGNORE: @@ -658,11 +660,11 @@ class FormatChecker(BaseTokenChecker): if not ok: warnings.append((policy, position)) for policy, position in warnings: - construct = _name_construct(tokens[i]) + construct = _name_construct(token) count, state = _policy_string(policy) - self.add_message('bad-whitespace', line=tokens[i][2][0], + self.add_message('bad-whitespace', line=token[2][0], args=(count, state, position, construct, - _underline_token(tokens[i]))) + _underline_token(token))) def _inside_brackets(self, left): return self._bracket_stack[-1] == left diff --git a/checkers/imports.py b/checkers/imports.py index 1b59b29..1969eeb 100644 --- a/checkers/imports.py +++ b/checkers/imports.py @@ -18,6 +18,9 @@ import sys from collections import defaultdict +import six +from six.moves import map # pylint: disable=redefined-builtin + from logilab.common.graph import get_cycles, DotBackend from logilab.common.ureports import VerbatimText, Paragraph @@ -29,8 +32,6 @@ from pylint.interfaces import IAstroidChecker from pylint.utils import EmptyReport from pylint.checkers import BaseChecker from pylint.checkers.utils import check_messages, is_import_error -import six -from six.moves import map def _except_import_error(node): """ @@ -245,7 +246,7 @@ given file (report RP0402 must not be disabled)'} """triggered when an import statement is seen""" modnode = node.root() for name, _ in node.names: - importedmodnode = self.get_imported_module(modnode, node, name) + importedmodnode = self.get_imported_module(node, name) if importedmodnode is None: continue self._check_relative_import(modnode, node, importedmodnode, name) @@ -272,7 +273,7 @@ given file (report RP0402 must not be disabled)'} if name == '*': self.add_message('wildcard-import', args=basename, node=node) modnode = node.root() - importedmodnode = self.get_imported_module(modnode, node, basename) + importedmodnode = self.get_imported_module(node, basename) if importedmodnode is None: return self._check_relative_import(modnode, node, importedmodnode, basename) @@ -282,7 +283,7 @@ given file (report RP0402 must not be disabled)'} self._add_imported_module(node, '%s.%s' % (importedmodnode.name, name)) self._check_reimport(node, name, basename, node.level) - def get_imported_module(self, modnode, importnode, modname): + def get_imported_module(self, importnode, modname): try: return importnode.do_import_module(modname) except astroid.InferenceError as ex: diff --git a/checkers/logging.py b/checkers/logging.py index 277b8c0..897c1c7 100644 --- a/checkers/logging.py +++ b/checkers/logging.py @@ -35,14 +35,14 @@ MSGS = { 'interpolation in those cases in which no message will be ' 'logged. For more, see ' 'http://www.python.org/dev/peps/pep-0282/.'), - 'W1202': ('Use % formatting in logging functions but pass the % ' - 'parameters as arguments', - 'logging-format-interpolation', - 'Used when a logging statement has a call form of ' - '"logging.<logging method>(format_string.format(format_args...))"' - '. Such calls should use % formatting instead, but leave ' - 'interpolation to the logging function by passing the parameters ' - 'as arguments.'), + 'W1202': ('Use % formatting in logging functions but pass the % ' + 'parameters as arguments', + 'logging-format-interpolation', + 'Used when a logging statement has a call form of ' + '"logging.<logging method>(format_string.format(format_args...))"' + '. Such calls should use % formatting instead, but leave ' + 'interpolation to the logging function by passing the parameters ' + 'as arguments.'), 'E1200': ('Unsupported logging format character %r (%#02x) at index %d', 'logging-unsupported-format', 'Used when an unsupported format character is used in a logging\ @@ -64,6 +64,27 @@ CHECKED_CONVENIENCE_FUNCTIONS = set([ 'critical', 'debug', 'error', 'exception', 'fatal', 'info', 'warn', 'warning']) +def is_method_call(callfunc_node, types=(), methods=()): + """Determines if a CallFunc node represents a method call. + + Args: + callfunc_node: The CallFunc AST node to check. + types: Optional sequence of caller type names to restrict check. + methods: Optional sequence of method names to restrict check. + + Returns: + True, if the node represents a method call for the given type and + method names, False otherwise. + """ + if not isinstance(callfunc_node, astroid.CallFunc): + return False + func = utils.safe_infer(callfunc_node.func) + return (isinstance(func, astroid.BoundMethod) + and isinstance(func.bound, astroid.Instance) + and (func.bound.name in types if types else True) + and (func.name in methods if methods else True)) + + class LoggingChecker(checkers.BaseChecker): """Checks use of the logging module.""" @@ -81,7 +102,7 @@ class LoggingChecker(checkers.BaseChecker): ), ) - def visit_module(self, unused_node): + def visit_module(self, node): # pylint: disable=unused-argument """Clears any state left in this checker from last module checked.""" # The code being checked can just as easily "import logging as foo", # so it is necessary to process the imports and store in this field @@ -142,26 +163,6 @@ class LoggingChecker(checkers.BaseChecker): return self._check_log_method(node, name) - def is_method_call(self, callfunc_node, types=(), methods=()): - """Determines if a CallFunc node represents a method call. - - Args: - callfunc_node: The CallFunc AST node to check. - types: Optional sequence of caller type names to restrict check. - methods: Optional sequence of method names to restrict check. - - Returns: - True, if the node represents a method call for the given type and - method names, False otherwise. - """ - if not isinstance(callfunc_node, astroid.CallFunc): - return False - func = utils.safe_infer(callfunc_node.func) - return (isinstance(func, astroid.BoundMethod) - and isinstance(func.bound, astroid.Instance) - and (func.bound.name in types if types else True) - and (func.name in methods if methods else True)) - def _check_log_method(self, node, name): """Checks calls to logging.log(level, format, *format_args).""" if name == 'log': @@ -192,7 +193,7 @@ class LoggingChecker(checkers.BaseChecker): Args: callfunc_node: CallFunc AST node to be checked. """ - if self.is_method_call(callfunc_node, ('str', 'unicode'), ('format',)): + if is_method_call(callfunc_node, ('str', 'unicode'), ('format',)): self.add_message('logging-format-interpolation', node=callfunc_node) def _check_format_string(self, node, format_arg): diff --git a/checkers/newstyle.py b/checkers/newstyle.py index 4fae401..1656806 100644 --- a/checkers/newstyle.py +++ b/checkers/newstyle.py @@ -101,7 +101,7 @@ class NewStyleConflictChecker(BaseChecker): else INFERENCE_FAILURE) name = node.func.name if name == 'property': - self.add_message('property-on-old-class', node=node, + self.add_message('property-on-old-class', node=node, confidence=confidence) @check_messages('super-on-old-class', 'bad-super-call', 'missing-super-argument') @@ -125,7 +125,7 @@ class NewStyleConflictChecker(BaseChecker): if not klass.newstyle: # super should not be used on an old style class self.add_message('super-on-old-class', node=node, - confidence=confidence) + confidence=confidence) else: # super first arg should be the class if not call.args and sys.version_info[0] == 3: diff --git a/checkers/spelling.py b/checkers/spelling.py index ee02564..3990633 100644 --- a/checkers/spelling.py +++ b/checkers/spelling.py @@ -135,7 +135,7 @@ class SpellingChecker(BaseTokenChecker): words = [] for word in line2.split(): # Skip words with digits. - if len(re.findall("\d", word)) > 0: + if len(re.findall(r"\d", word)) > 0: continue # Skip words with mixed big and small letters, @@ -181,7 +181,7 @@ class SpellingChecker(BaseTokenChecker): # TODO: add support for customising this. suggestions = self.spelling_dict.suggest(word)[:4] - m = re.search("(\W|^)(%s)(\W|$)" % word, line.lower()) + m = re.search(r"(\W|^)(%s)(\W|$)" % word, line.lower()) if m: # Start position of second group in regex. col = m.regs[2][0] diff --git a/checkers/strings.py b/checkers/strings.py index d4b2e65..e88085d 100644 --- a/checkers/strings.py +++ b/checkers/strings.py @@ -538,17 +538,18 @@ class StringConstantChecker(BaseTokenChecker): self._unicode_literals = 'unicode_literals' in module.future_imports def process_tokens(self, tokens): - for (tok_type, token, (start_row, start_col), _, _) in tokens: + for (tok_type, token, (start_row, _), _, _) in tokens: if tok_type == tokenize.STRING: # 'token' is the whole un-parsed token; we can look at the start # of it to see whether it's a raw or unicode string etc. - self.process_string_token(token, start_row, start_col) + self.process_string_token(token, start_row) - def process_string_token(self, token, start_row, start_col): + def process_string_token(self, token, start_row): for i, c in enumerate(token): if c in '\'\"': quote_char = c break + # pylint: disable=undefined-loop-variable prefix = token[:i].lower() # markers like u, b, r. after_prefix = token[i:] if after_prefix[:3] == after_prefix[-3:] == 3 * quote_char: @@ -557,18 +558,15 @@ class StringConstantChecker(BaseTokenChecker): string_body = after_prefix[1:-1] # Chop off quotes # No special checks on raw strings at the moment. if 'r' not in prefix: - self.process_non_raw_string_token(prefix, string_body, - start_row, start_col) + self.process_non_raw_string_token(prefix, string_body, start_row) - def process_non_raw_string_token(self, prefix, string_body, start_row, - start_col): + def process_non_raw_string_token(self, prefix, string_body, start_row): """check for bad escapes in a non-raw string. prefix: lowercase string of eg 'ur' string prefix markers. string_body: the un-parsed body of the string, not including the quote marks. start_row: integer line number in the source. - start_col: integer column number in the source. """ # Walk through the string; if we see a backslash then escape the next # character, and skip over it. If we see a non-escaped character, diff --git a/checkers/utils.py b/checkers/utils.py index 4be844c..f3a7d17 100644 --- a/checkers/utils.py +++ b/checkers/utils.py @@ -157,12 +157,12 @@ def is_defined_before(var_node): if ass_node.name == varname: return True elif isinstance(_node, astroid.With): - for expr, vars in _node.items: + for expr, ids in _node.items: if expr.parent_of(var_node): break - if (vars and - isinstance(vars, astroid.AssName) and - vars.name == varname): + if (ids and + isinstance(ids, astroid.AssName) and + ids.name == varname): return True elif isinstance(_node, (astroid.Lambda, astroid.Function)): if _node.args.is_argument(varname): diff --git a/checkers/variables.py b/checkers/variables.py index 2aaa268..8f6f957 100644 --- a/checkers/variables.py +++ b/checkers/variables.py @@ -21,7 +21,7 @@ import re from copy import copy import astroid -from astroid import are_exclusive, builtin_lookup, AstroidBuildingException +from astroid import are_exclusive, builtin_lookup from astroid import modutils from pylint.interfaces import IAstroidChecker, INFERENCE, INFERENCE_FAILURE, HIGH @@ -170,6 +170,23 @@ def _fix_dot_imports(not_consumed): names[second_name] = stmt return sorted(names.items(), key=lambda a: a[1].fromlineno) +def _find_frame_imports(name, frame): + """ + Detect imports in the frame, with the required + *name*. Such imports can be considered assignments. + Returns True if an import for the given name was found. + """ + imports = frame.nodes_of_class((astroid.Import, astroid.From)) + for import_node in imports: + for import_name, import_alias in import_node.names: + # If the import uses an alias, check only that. + # Otherwise, check only the import name. + if import_alias: + if import_alias == name: + return True + elif import_name and import_name == name: + return True + MSGS = { 'E0601': ('Using variable %r before assignment', @@ -563,23 +580,6 @@ builtins. Remember that you should avoid to define new builtins when possible.' continue self.add_message('unused-variable', args=name, node=stmt) - def _find_frame_imports(self, name, frame): - """ - Detect imports in the frame, with the required - *name*. Such imports can be considered assignments. - Returns True if an import for the given name was found. - """ - imports = frame.nodes_of_class((astroid.Import, astroid.From)) - for import_node in imports: - for import_name, import_alias in import_node.names: - # If the import uses an alias, check only that. - # Otherwise, check only the import name. - if import_alias: - if import_alias == name: - return True - elif import_name and import_name == name: - return True - @check_messages('global-variable-undefined', 'global-variable-not-assigned', 'global-statement', 'global-at-module-level', 'redefined-builtin') def visit_global(self, node): @@ -605,7 +605,7 @@ builtins. Remember that you should avoid to define new builtins when possible.' # same scope level assignment break else: - if not self._find_frame_imports(name, frame): + if not _find_frame_imports(name, frame): self.add_message('global-variable-not-assigned', args=name, node=node) default_message = False @@ -625,7 +625,7 @@ builtins. Remember that you should avoid to define new builtins when possible.' if default_message: self.add_message('global-statement', node=node) - def _check_late_binding_closure(self, node, assignment_node, scope_type): + def _check_late_binding_closure(self, node, assignment_node): def _is_direct_lambda_call(): return (isinstance(node_scope.parent, astroid.CallFunc) and node_scope.parent.func is node_scope) @@ -762,7 +762,7 @@ builtins. Remember that you should avoid to define new builtins when possible.' # variable used outside the loop if name in consumed: defnode = assign_parent(consumed[name][0]) - self._check_late_binding_closure(node, defnode, scope_type) + self._check_late_binding_closure(node, defnode) self._loopvar_name(node, name) break # mark the name as consumed if it's defined in this scope @@ -774,7 +774,7 @@ builtins. Remember that you should avoid to define new builtins when possible.' # checks for use before assignment defnode = assign_parent(to_consume[name][0]) if defnode is not None: - self._check_late_binding_closure(node, defnode, scope_type) + self._check_late_binding_closure(node, defnode) defstmt = defnode.statement() defframe = defstmt.frame() maybee0601 = True @@ -801,15 +801,15 @@ builtins. Remember that you should avoid to define new builtins when possible.' annotation_return = False # The class reuses itself in the class scope. recursive_klass = (frame is defframe and - defframe.parent_of(node) and - isinstance(defframe, astroid.Class) and - node.name == defframe.name) + defframe.parent_of(node) and + isinstance(defframe, astroid.Class) and + node.name == defframe.name) if (self._to_consume[-1][-1] == 'lambda' and isinstance(frame, astroid.Class) and name in frame.locals): maybee0601 = True elif (isinstance(defframe, astroid.Class) and - isinstance(frame, astroid.Function)): + isinstance(frame, astroid.Function)): # Special rule for function return annotations, # which uses the same name as the class where # the function lives. @@ -834,8 +834,8 @@ builtins. Remember that you should avoid to define new builtins when possible.' 'Exception', 'BaseException'))): if recursive_klass or (defstmt is stmt and - isinstance(node, (astroid.DelName, - astroid.AssName))): + isinstance(node, (astroid.DelName, + astroid.AssName))): self.add_message('undefined-variable', args=name, node=node) elif annotation_return: self.add_message('undefined-variable', args=name, node=node) @@ -893,9 +893,7 @@ builtins. Remember that you should avoid to define new builtins when possible.' level = getattr(node, 'level', None) try: module = node.root().import_module(name_parts[0], level=level) - except AstroidBuildingException: - return - except Exception: + except Exception: # pylint: disable=broad-except return module = self._check_module_attrs(node, module, name_parts[1:]) if not module: @@ -53,7 +53,7 @@ def load_results(base): try: with open(data_file, _PICK_LOAD) as stream: return pickle.load(stream) - except: + except Exception: # pylint: disable=broad-except return {} if sys.version_info < (3, 0): @@ -104,7 +104,7 @@ class BasicStream(object): self.gui.tabs = self.outdict try: self.gui.rating.set(self.outdict['Global evaluation'][0]) - except: + except KeyError: self.gui.rating.set('Error') self.gui.refresh_results_window() @@ -328,7 +328,7 @@ class LintGui(object): self.txt_module.focus_set() - def select_recent_file(self, event): + def select_recent_file(self, event): # pylint: disable=unused-argument """adds the selected file in the history listbox to the Module box""" if not self.showhistory.size(): return @@ -359,7 +359,7 @@ class LintGui(object): try: for res in self.tabs[self.box.get()]: self.results.insert(END, res) - except: + except KeyError: pass def process_incoming(self): @@ -402,7 +402,7 @@ class LintGui(object): """quit the application""" self.root.quit() - def halt(self): + def halt(self): # pylint: disable=no-self-use """program halt placeholder""" return @@ -483,7 +483,7 @@ class LintGui(object): self.root.configure(cursor='') - def show_sourcefile(self, event=None): + def show_sourcefile(self, event=None): # pylint: disable=unused-argument selected = self.lb_messages.curselection() if not selected: return @@ -186,16 +186,16 @@ MSGS = { def _deprecated_option(shortname, opt_type): - def _warn_deprecated(option, optname, *args): + def _warn_deprecated(option, optname, *args): # pylint: disable=unused-argument sys.stderr.write('Warning: option %s is deprecated and ignored.\n' % (optname,)) return {'short': shortname, 'help': 'DEPRECATED', 'hide': True, 'type': opt_type, 'action': 'callback', 'callback': _warn_deprecated} if multiprocessing is not None: - class ChildLinter(multiprocessing.Process): # pylint: disable=no-member + class ChildLinter(multiprocessing.Process): # pylint: disable=no-member def run(self): - tasks_queue, results_queue, config = self._args # pylint: disable=no-member + tasks_queue, results_queue, config = self._args # pylint: disable=no-member for file_or_module in iter(tasks_queue.get, 'STOP'): result = self._run_linter(config, file_or_module[0]) @@ -225,7 +225,7 @@ if multiprocessing is not None: linter_config = {} filter_options = {"symbols", "include-ids"} for opt_providers in six.itervalues(linter._all_options): - for optname, optdict in opt_providers.options: + for optname, _ in opt_providers.options: if optname not in filter_options: linter_config[optname] = config[optname] linter_config['jobs'] = 1 # Child does not parallelize any further. @@ -238,7 +238,7 @@ if multiprocessing is not None: msgs = [_get_new_args(m) for m in linter.reporter.messages] return (file_or_module, linter.file_state.base_name, linter.current_name, - msgs, linter.stats, linter.msg_status) + msgs, linter.stats, linter.msg_status) class PyLinter(OptionsManagerMixIn, MessagesHandlerMixIn, ReportsHandlerMixIn, @@ -332,7 +332,7 @@ class PyLinter(OptionsManagerMixIn, MessagesHandlerMixIn, ReportsHandlerMixIn, 'group': 'Messages control', 'help' : 'Only show warnings with the listed confidence levels.' ' Leave empty to show all. Valid levels: %s' % ( - ', '.join(c.name for c in CONFIDENCE_LEVELS),)}), + ', '.join(c.name for c in CONFIDENCE_LEVELS),)}), ('enable', {'type' : 'csv', 'metavar': '<msg ids>', @@ -377,8 +377,8 @@ class PyLinter(OptionsManagerMixIn, MessagesHandlerMixIn, ReportsHandlerMixIn, 'short': 'j', 'default': 1, 'help' : '''Use multiple processes to speed up Pylint.''', - }), # jobs - ) + }), # jobs + ) option_groups = ( ('Messages control', 'Options controling analysis messages'), @@ -631,14 +631,14 @@ class PyLinter(OptionsManagerMixIn, MessagesHandlerMixIn, ReportsHandlerMixIn, messages = set(msg for msg in checker.msgs if msg[0] != 'F' and self.is_message_enabled(msg)) if (messages or - any(self.report_is_enabled(r[0]) for r in checker.reports)): + any(self.report_is_enabled(r[0]) for r in checker.reports)): neededcheckers.append(checker) # Sort checkers by priority neededcheckers = sorted(neededcheckers, key=attrgetter('priority'), reverse=True) return neededcheckers - def should_analyze_file(self, modname, path): # pylint: disable=unused-argument + def should_analyze_file(self, modname, path): # pylint: disable=unused-argument, no-self-use """Returns whether or not a module should be checked. This implementation returns True for all python source file, indicating @@ -682,7 +682,7 @@ class PyLinter(OptionsManagerMixIn, MessagesHandlerMixIn, ReportsHandlerMixIn, self._parallel_check(files_or_modules) finally: if mock_main: - sys.modules.pop('__main__') + sys.modules.pop('__main__') def _parallel_task(self, files_or_modules): # Prepare configuration for child linters. @@ -754,7 +754,7 @@ class PyLinter(OptionsManagerMixIn, MessagesHandlerMixIn, ReportsHandlerMixIn, all_stats.append(stats) self.msg_status |= msg_status - self.stats = _merge_stats(chain(all_stats, [self.stats])) + self.stats = _merge_stats(chain(all_stats, [self.stats])) self.current_name = last_module # Insert stats data to local checkers. @@ -839,7 +839,7 @@ class PyLinter(OptionsManagerMixIn, MessagesHandlerMixIn, ReportsHandlerMixIn, self.add_message('syntax-error', line=ex.lineno, args=ex.msg) except AstroidBuildingException as ex: self.add_message('parse-error', args=ex) - except Exception as ex: + except Exception as ex: # pylint: disable=broad-except import traceback traceback.print_exc() self.add_message('astroid-error', args=(ex.__class__, ex)) @@ -924,8 +924,8 @@ class PyLinter(OptionsManagerMixIn, MessagesHandlerMixIn, ReportsHandlerMixIn, # get a global note for the code evaluation = self.config.evaluation try: - note = eval(evaluation, {}, self.stats) - except Exception as ex: + note = eval(evaluation, {}, self.stats) # pylint: disable=eval-used + except Exception as ex: # pylint: disable=broad-except msg = 'An exception occurred while rating: %s' % ex else: stats['global_note'] = note @@ -1117,7 +1117,7 @@ group are mutually exclusive.'), ('list-conf-levels', {'action' : 'callback', - 'callback' : self.cb_list_confidence_levels, + 'callback' : cb_list_confidence_levels, 'group': 'Commands', 'level': 1, 'help' : "Generate pylint's messages."}), @@ -1299,20 +1299,20 @@ group are mutually exclusive.'), self.linter.msgs_store.list_messages() sys.exit(0) - def cb_list_confidence_levels(self, option, optname, value, parser): - for level in CONFIDENCE_LEVELS: - print('%-18s: %s' % level) - sys.exit(0) - def cb_python3_porting_mode(self, *args, **kwargs): """Activate only the python3 porting checker.""" self.linter.disable('all') self.linter.enable('python3') +def cb_list_confidence_levels(option, optname, value, parser): + for level in CONFIDENCE_LEVELS: + print('%-18s: %s' % level) + sys.exit(0) + def cb_init_hook(optname, value): """exec arbitrary code to set sys.path for instance""" - exec(value) + exec(value) # pylint: disable=exec-used if __name__ == '__main__': diff --git a/pyreverse/diadefslib.py b/pyreverse/diadefslib.py index 0b42065..e0dc8cf 100644 --- a/pyreverse/diadefslib.py +++ b/pyreverse/diadefslib.py @@ -145,7 +145,7 @@ class DefaultDiadefGenerator(LocalsVisitor, DiaDefGenerator): self.pkgdiagram = None self.classdiagram = ClassDiagram('classes %s' % node.name, mode) - def leave_project(self, node): + def leave_project(self, node): # pylint: disable=unused-argument """leave the astroid.Project node return the generated diagram definition diff --git a/pyreverse/utils.py b/pyreverse/utils.py index 58559d7..5d6d133 100644 --- a/pyreverse/utils.py +++ b/pyreverse/utils.py @@ -128,5 +128,5 @@ class FilterMixIn(object): """return true if the node should be treated """ visibility = get_visibility(getattr(node, 'name', node)) - return not (self.__mode & VIS_MOD[visibility]) + return not self.__mode & VIS_MOD[visibility] diff --git a/reporters/__init__.py b/reporters/__init__.py index 5ebb6aa..ea3281f 100644 --- a/reporters/__init__.py +++ b/reporters/__init__.py @@ -25,7 +25,7 @@ CMPS = ['=', '-', '+'] # py3k has no more cmp builtin if sys.version_info >= (3, 0): - def cmp(a, b): + def cmp(a, b): # pylint: disable=redefined-builtin return (a > b) - (a < b) def diff_string(old, new): diff --git a/reporters/guireporter.py b/reporters/guireporter.py index f908f76..4ad4ebb 100644 --- a/reporters/guireporter.py +++ b/reporters/guireporter.py @@ -4,7 +4,6 @@ import sys from pylint.interfaces import IReporter from pylint.reporters import BaseReporter -from pylint import utils from logilab.common.ureports import TextWriter diff --git a/reporters/html.py b/reporters/html.py index 3e5a1a7..1c6c260 100644 --- a/reporters/html.py +++ b/reporters/html.py @@ -18,7 +18,6 @@ from cgi import escape from logilab.common.ureports import HTMLWriter, Section, Table -from pylint import utils from pylint.interfaces import IReporter from pylint.reporters import BaseReporter diff --git a/reporters/text.py b/reporters/text.py index acb22b5..bc86313 100644 --- a/reporters/text.py +++ b/reporters/text.py @@ -133,7 +133,7 @@ class ColorizedTextReporter(TextReporter): msg = msg._replace( **{attr: colorize_ansi(getattr(msg, attr), color, style) - for attr in ('msg', 'symbol', 'category', 'C')}) + for attr in ('msg', 'symbol', 'category', 'C')}) self.write_message(msg) diff --git a/testutils.py b/testutils.py index 54e5085..2f9af4d 100644 --- a/testutils.py +++ b/testutils.py @@ -95,7 +95,8 @@ class TestReporter(BaseReporter): __implements____ = IReporter - def __init__(self): + def __init__(self): # pylint: disable=super-init-not-called + self.message_ids = {} self.reset() self.path_strip_prefix = getcwd() + sep @@ -137,6 +138,7 @@ class Message(collections.namedtuple('Message', class UnittestLinter(object): """A fake linter class to capture checker messages.""" + # pylint: disable=unused-argument, no-self-use def __init__(self): self._messages = [] @@ -148,7 +150,8 @@ class UnittestLinter(object): finally: self._messages = [] - def add_message(self, msg_id, line=None, node=None, args=None, confidence=None): + def add_message(self, msg_id, line=None, node=None, args=None, + confidence=None): self._messages.append(Message(msg_id, line, node, args)) def is_message_enabled(self, *unused_args): @@ -237,7 +240,7 @@ else: INFO_TEST_RGX = re.compile(r'^func_i\d\d\d\d$') -def exception_str(self, ex): +def exception_str(self, ex): # pylint: disable=unused-argument """function used to replace default __str__ method of exception instances""" return 'in %s\n:: %s' % (ex.file, ', '.join(ex.args)) @@ -335,6 +338,7 @@ class LintTestUpdate(LintTestUsingModule): def cb_test_gen(base_class): def call(input_dir, msg_dir, module_file, messages_file, dependencies): + # pylint: disable=no-init class LintTC(base_class): module = module_file.replace('.py', '') output = messages_file @@ -24,9 +24,11 @@ import re import sys import tokenize import warnings - from os.path import dirname, basename, splitext, exists, isdir, join, normpath +import six +from six.moves import zip # pylint: disable=redefined-builtin + from logilab.common.interface import implements from logilab.common.textutils import normalize_text from logilab.common.configuration import rest_format_section @@ -37,8 +39,6 @@ from astroid.modutils import modpath_from_file, get_module_files, \ file_from_modpath, load_module_from_file from pylint.interfaces import IRawChecker, ITokenChecker, UNDEFINED -import six -from six.moves import zip class UnknownMessage(Exception): @@ -121,11 +121,11 @@ def get_module_and_frameid(node): obj.reverse() return module, '.'.join(obj) -def category_id(id): - id = id.upper() - if id in MSG_TYPES: - return id - return MSG_TYPES_LONG.get(id) +def category_id(cid): + cid = cid.upper() + if cid in MSG_TYPES: + return cid + return MSG_TYPES_LONG.get(cid) def tokenize_module(module): @@ -557,7 +557,8 @@ class FileState(object): except KeyError: self._module_msgs_state[msg.msgid] = {line: status} - def handle_ignored_message(self, state_scope, msgid, line, node, args, confidence): + 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, |