diff options
Diffstat (limited to 'checkers')
-rw-r--r-- | checkers/base.py | 24 | ||||
-rw-r--r-- | checkers/classes.py | 13 | ||||
-rw-r--r-- | checkers/exceptions.py | 6 | ||||
-rw-r--r-- | checkers/format.py | 12 | ||||
-rw-r--r-- | checkers/imports.py | 14 | ||||
-rw-r--r-- | checkers/logging.py | 7 | ||||
-rw-r--r-- | checkers/misc.py | 5 | ||||
-rw-r--r-- | checkers/newstyle.py | 2 | ||||
-rw-r--r-- | checkers/similar.py | 29 | ||||
-rw-r--r-- | checkers/strings.py | 17 | ||||
-rw-r--r-- | checkers/utils.py | 6 | ||||
-rw-r--r-- | checkers/variables.py | 19 |
12 files changed, 87 insertions, 67 deletions
diff --git a/checkers/base.py b/checkers/base.py index 298ac5f..501d930 100644 --- a/checkers/base.py +++ b/checkers/base.py @@ -43,6 +43,8 @@ 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]+$') @@ -175,7 +177,7 @@ def decorated_with_abc(func): if func.decorators: for node in func.decorators.nodes: try: - infered = node.infer().next() + infered = next(node.infer()) except InferenceError: continue if infered and infered.qname() in ABC_METHODS: @@ -380,7 +382,7 @@ class BasicErrorChecker(_BasicChecker): abc.ABCMeta as metaclass. """ try: - infered = node.func.infer().next() + infered = next(node.func.infer()) except astroid.InferenceError: return if not isinstance(infered, astroid.Class): @@ -576,7 +578,7 @@ functions, methods """check for various kind of statements without effect""" expr = node.value if isinstance(expr, astroid.Const) and isinstance(expr.value, - basestring): + six.string_types): # treat string statement in a separated message # Handle PEP-257 attribute docstrings. # An attribute docstring is defined as being a string right after @@ -653,7 +655,7 @@ functions, methods # ordinary_args[i].name == call.args[i].name. if len(ordinary_args) != len(call.args): return - for i in xrange(len(ordinary_args)): + for i in range(len(ordinary_args)): if not isinstance(call.args[i], astroid.Name): return if node.args.args[i].name != call.args[i].name: @@ -674,7 +676,7 @@ functions, methods # check for dangerous default values as arguments for default in node.args.defaults: try: - value = default.infer().next() + value = next(default.infer()) except astroid.InferenceError: continue @@ -840,7 +842,7 @@ functions, methods # Try to see if we have iter(). if isinstance(node.args[0], astroid.CallFunc): try: - func = node.args[0].func.infer().next() + func = next(node.args[0].func.infer()) except InferenceError: return if (getattr(func, 'name', None) == 'iter' and @@ -893,7 +895,7 @@ _NAME_TYPES = { def _create_naming_options(): name_options = [] - for name_type, (rgx, human_readable_name) in _NAME_TYPES.iteritems(): + for name_type, (rgx, human_readable_name) in six.iteritems(_NAME_TYPES): name_type = name_type.replace('_', '-') name_options.append(( '%s-rgx' % (name_type,), @@ -968,12 +970,12 @@ class NameChecker(_BasicChecker): self._bad_names = {} def leave_module(self, node): - for category, all_groups in self._bad_names.iteritems(): + for category, all_groups in six.iteritems(self._bad_names): if len(all_groups) < 2: continue groups = collections.defaultdict(list) - min_warnings = sys.maxint - for group in all_groups.itervalues(): + min_warnings = sys.maxsize + for group in six.itervalues(all_groups): groups[len(group)].append(group) min_warnings = min(len(group), min_warnings) if len(groups[min_warnings]) > 1: @@ -988,7 +990,7 @@ class NameChecker(_BasicChecker): @check_messages('blacklisted-name', 'invalid-name') def visit_class(self, node): self._check_name('class', node.name, node) - for attr, anodes in node.instance_attrs.iteritems(): + for attr, anodes in six.iteritems(node.instance_attrs): if not list(node.instance_attr_ancestors(attr)): self._check_name('attr', attr, anodes[0]) diff --git a/checkers/classes.py b/checkers/classes.py index aa05558..d9b7581 100644 --- a/checkers/classes.py +++ b/checkers/classes.py @@ -28,6 +28,7 @@ from pylint.checkers import BaseChecker from pylint.checkers.utils import ( PYMETHODS, overrides_a_method, check_messages, is_attr_private, is_attr_protected, node_frame_class, safe_infer, is_builtin_object) +import six if sys.version_info >= (3, 0): NEXT_METHOD = '__next__' @@ -298,7 +299,7 @@ a metaclass class method.'} return defining_methods = self.config.defining_attr_methods current_module = cnode.root() - for attr, nodes in cnode.instance_attrs.iteritems(): + for attr, nodes in six.iteritems(cnode.instance_attrs): # skip nodes which are not in the current module and it may screw up # the output, while it's not worth it nodes = [n for n in nodes if not @@ -612,7 +613,7 @@ a metaclass class method.'} def _check_accessed_members(self, node, accessed): """check that accessed members are defined""" # XXX refactor, probably much simpler now that E0201 is in type checker - for attr, nodes in accessed.iteritems(): + for attr, nodes in six.iteritems(accessed): # deactivate "except doesn't do anything", that's expected # pylint: disable=W0704 try: @@ -624,7 +625,7 @@ a metaclass class method.'} pass # is it an instance attribute of a parent class ? try: - node.instance_attr_ancestors(attr).next() + next(node.instance_attr_ancestors(attr)) # yes, stop here continue except StopIteration: @@ -816,7 +817,7 @@ a metaclass class method.'} expr.expr.func.name == 'super': return try: - klass = expr.expr.infer().next() + klass = next(expr.expr.infer()) if klass is YES: continue # The infered klass can be super(), which was @@ -838,7 +839,7 @@ a metaclass class method.'} node=expr, args=klass.name) except astroid.InferenceError: continue - for klass, method in not_called_yet.iteritems(): + for klass, method in six.iteritems(not_called_yet): if klass.name == 'object' or method.parent.name == 'object': continue self.add_message('super-init-not-called', args=klass.name, node=node) @@ -880,7 +881,7 @@ def _ancestors_to_call(klass_node, method='__init__'): to_call = {} for base_node in klass_node.ancestors(recurs=False): try: - to_call[base_node] = base_node.igetattr(method).next() + to_call[base_node] = next(base_node.igetattr(method)) except astroid.InferenceError: continue return to_call diff --git a/checkers/exceptions.py b/checkers/exceptions.py index 9b1a071..f9b78bb 100644 --- a/checkers/exceptions.py +++ b/checkers/exceptions.py @@ -67,7 +67,7 @@ def infer_bases(klass): """ for base in klass.bases: try: - inferit = base.infer().next() + inferit = next(base.infer()) except astroid.InferenceError: continue if inferit is YES: @@ -178,7 +178,7 @@ class ExceptionsChecker(BaseChecker): return if PY3K and node.cause: try: - cause = node.cause.infer().next() + cause = next(node.cause.infer()) except astroid.InferenceError: pass else: @@ -197,7 +197,7 @@ class ExceptionsChecker(BaseChecker): return else: try: - value = unpack_infer(expr).next() + value = next(unpack_infer(expr)) except astroid.InferenceError: return self._check_raise_value(node, value) diff --git a/checkers/format.py b/checkers/format.py index 34da653..134999e 100644 --- a/checkers/format.py +++ b/checkers/format.py @@ -24,6 +24,9 @@ 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 +import six +from six.moves import zip if not hasattr(tokenize, 'NL'): raise ValueError("tokenize.NL doesn't exist -- tokenize module too old") @@ -342,7 +345,8 @@ class ContinuedLineState(object): # current indent level paren_align = self._cont_stack[-1].valid_outdent_offsets next_align = self._cont_stack[-1].valid_continuation_offsets.copy() - next_align[next_align.keys()[0] + self._continuation_size] = True + next_align_keys = list(next_align.keys()) + next_align[next_align_keys[0] + self._continuation_size] = True # Note that the continuation of # d = { # 'a': 'b' @@ -506,7 +510,7 @@ class FormatChecker(BaseTokenChecker): keyword_token = tokens[start][1] line_num = tokens[start][2][0] - for i in xrange(start, len(tokens) - 1): + for i in range(start, len(tokens) - 1): token = tokens[i] # If we hit a newline, then assume any parens were for continuation. @@ -812,7 +816,7 @@ class FormatChecker(BaseTokenChecker): for indent_pos, state, offsets in self._current_line.retained_warnings: block_type = offsets[tokens.start_col(indent_pos)] - hints = dict((k, v) for k, v in offsets.iteritems() + hints = dict((k, v) for k, v in six.iteritems(offsets) if v != block_type) if single_line_block_stmt and block_type == WITH_BODY: self._add_continuation_message(state, hints, tokens, indent_pos) @@ -886,7 +890,7 @@ class FormatChecker(BaseTokenChecker): tolineno = node.tolineno assert tolineno, node lines = [] - for line in xrange(line, tolineno + 1): + for line in range(line, tolineno + 1): self._visited_lines[line] = 1 try: lines.append(self._lines[line].rstrip()) diff --git a/checkers/imports.py b/checkers/imports.py index a861ce6..4369b02 100644 --- a/checkers/imports.py +++ b/checkers/imports.py @@ -28,6 +28,8 @@ 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): """ @@ -106,14 +108,14 @@ def dependencies_graph(filename, dep_info): done = {} printer = DotBackend(filename[:-4], rankdir='LR') printer.emit('URL="." node[shape="box"]') - for modname, dependencies in sorted(dep_info.iteritems()): + for modname, dependencies in sorted(six.iteritems(dep_info)): done[modname] = 1 printer.emit_node(modname) for modname in dependencies: if modname not in done: done[modname] = 1 printer.emit_node(modname) - for depmodname, dependencies in sorted(dep_info.iteritems()): + for depmodname, dependencies in sorted(six.iteritems(dep_info)): for modname in dependencies: printer.emit_edge(modname, depmodname) printer.generate(filename) @@ -281,7 +283,7 @@ given file (report RP0402 must not be disabled)'} def get_imported_module(self, modnode, importnode, modname): try: return importnode.do_import_module(modname) - except astroid.InferenceError, ex: + except astroid.InferenceError as ex: if str(ex) != modname: args = '%r (%s)' % (modname, ex) else: @@ -353,7 +355,7 @@ given file (report RP0402 must not be disabled)'} def report_external_dependencies(self, sect, _, dummy): """return a verbatim layout for displaying dependencies""" - dep_info = make_tree_defs(self._external_dependencies_info().iteritems()) + dep_info = make_tree_defs(six.iteritems(self._external_dependencies_info())) if not dep_info: raise EmptyReport() tree_str = repr_tree_defs(dep_info) @@ -385,7 +387,7 @@ given file (report RP0402 must not be disabled)'} if self.__ext_dep_info is None: package = self.linter.current_name self.__ext_dep_info = result = {} - for importee, importers in self.stats['dependencies'].iteritems(): + for importee, importers in six.iteritems(self.stats['dependencies']): if not importee.startswith(package): result[importee] = importers return self.__ext_dep_info @@ -397,7 +399,7 @@ given file (report RP0402 must not be disabled)'} if self.__int_dep_info is None: package = self.linter.current_name self.__int_dep_info = result = {} - for importee, importers in self.stats['dependencies'].iteritems(): + for importee, importers in six.iteritems(self.stats['dependencies']): if importee.startswith(package): result[importee] = importers return self.__int_dep_info diff --git a/checkers/logging.py b/checkers/logging.py index d82d74b..39c4d9c 100644 --- a/checkers/logging.py +++ b/checkers/logging.py @@ -20,6 +20,9 @@ from pylint import interfaces from pylint.checkers import utils from pylint.checkers.utils import check_messages +import six + + MSGS = { 'W1201': ('Specify string format arguments as logging function parameters', 'logging-not-lazy', @@ -166,7 +169,7 @@ class LoggingChecker(checkers.BaseChecker): # don't check any further. return format_string = node.args[format_arg].value - if not isinstance(format_string, basestring): + if not isinstance(format_string, six.string_types): # If the log format is constant non-string (e.g. logging.debug(5)), # ensure there are no arguments. required_num_args = 0 @@ -178,7 +181,7 @@ class LoggingChecker(checkers.BaseChecker): # Keyword checking on logging strings is complicated by # special keywords - out of scope. return - except utils.UnsupportedFormatCharacter, ex: + except utils.UnsupportedFormatCharacter as ex: char = format_string[ex.index] self.add_message('logging-unsupported-format', node=node, args=(char, ord(char), ex.index)) diff --git a/checkers/misc.py b/checkers/misc.py index b27b86a..d4adfd7 100644 --- a/checkers/misc.py +++ b/checkers/misc.py @@ -21,6 +21,7 @@ import re from pylint.interfaces import IRawChecker from pylint.checkers import BaseChecker +import six MSGS = { @@ -72,8 +73,8 @@ class EncodingChecker(BaseChecker): def _check_encoding(self, lineno, line, file_encoding): try: - return unicode(line, file_encoding) - except UnicodeDecodeError, ex: + return six.text_type(line, file_encoding) + except UnicodeDecodeError as ex: self.add_message('invalid-encoded-data', line=lineno, args=(file_encoding, ex.args[2])) diff --git a/checkers/newstyle.py b/checkers/newstyle.py index 1946f94..335b052 100644 --- a/checkers/newstyle.py +++ b/checkers/newstyle.py @@ -133,7 +133,7 @@ class NewStyleConflictChecker(BaseChecker): continue try: - supcls = (call.args and call.args[0].infer().next() + supcls = (call.args and next(call.args[0].infer()) or None) except astroid.InferenceError: continue diff --git a/checkers/similar.py b/checkers/similar.py index e5c9300..2cc2e00 100644 --- a/checkers/similar.py +++ b/checkers/similar.py @@ -16,14 +16,17 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """a similarities / code duplication command line tool and pylint checker """ +from __future__ import print_function import sys -from itertools import izip from logilab.common.ureports import Table from pylint.interfaces import IRawChecker from pylint.checkers import BaseChecker, table_lines_from_stats +import six +from six.moves import zip + class Similar(object): """finds copy-pasted lines of code in a project""" @@ -69,7 +72,7 @@ class Similar(object): else: duplicate.append(set([(lineset1, idx1), (lineset2, idx2)])) sims = [] - for num, ensembles in no_duplicates.iteritems(): + for num, ensembles in six.iteritems(no_duplicates): for couples in ensembles: sims.append((num, couples)) sims.sort() @@ -80,19 +83,19 @@ class Similar(object): """display computed similarities on stdout""" nb_lignes_dupliquees = 0 for num, couples in sims: - print - print num, "similar lines in", len(couples), "files" + print() + print(num, "similar lines in", len(couples), "files") couples = sorted(couples) for lineset, idx in couples: - print "==%s:%s" % (lineset.name, idx) + print("==%s:%s" % (lineset.name, idx)) # pylint: disable=W0631 for line in lineset._real_lines[idx:idx+num]: - print " ", line.rstrip() + 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" \ + print("TOTAL lines=%s duplicates=%s percent=%.2f" \ % (nb_total_lignes, nb_lignes_dupliquees, - nb_lignes_dupliquees*100. / nb_total_lignes) + nb_lignes_dupliquees*100. / nb_total_lignes)) def _find_common(self, lineset1, lineset2): """find similarities in the two given linesets""" @@ -107,7 +110,7 @@ class Similar(object): for index2 in find(lineset1[index1]): non_blank = 0 for num, ((_, line1), (_, line2)) in enumerate( - izip(lines1(index1), lines2(index2))): + zip(lines1(index1), lines2(index2))): if line1 != line2: if non_blank > min_lines: yield num, lineset1, index1, lineset2, index2 @@ -323,10 +326,10 @@ def register(linter): def usage(status=0): """display command line usage information""" - print "finds copy pasted blocks in a set of files" - print - print 'Usage: symilar [-d|--duplicates min_duplicated_lines] \ -[-i|--ignore-comments] [--ignore-docstrings] [--ignore-imports] file1...' + print("finds copy pasted blocks in a set of files") + print() + print('Usage: symilar [-d|--duplicates min_duplicated_lines] \ +[-i|--ignore-comments] [--ignore-docstrings] [--ignore-imports] file1...') sys.exit(status) def Run(argv=None): diff --git a/checkers/strings.py b/checkers/strings.py index 40995f6..03c557a 100644 --- a/checkers/strings.py +++ b/checkers/strings.py @@ -30,6 +30,9 @@ from pylint.checkers import BaseChecker, BaseTokenChecker from pylint.checkers import utils from pylint.checkers.utils import check_messages +import six + + _PY3K = sys.version_info[:2] >= (3, 0) _PY27 = sys.version_info[:2] == (2, 7) @@ -231,13 +234,13 @@ class StringFormatChecker(BaseChecker): args = node.right if not (isinstance(left, astroid.Const) - and isinstance(left.value, basestring)): + and isinstance(left.value, six.string_types)): return format_string = left.value try: required_keys, required_num_args = \ utils.parse_format_string(format_string) - except utils.UnsupportedFormatCharacter, e: + except utils.UnsupportedFormatCharacter as e: c = format_string[e.index] self.add_message('bad-format-character', node=node, args=(c, ord(c), e.index)) @@ -260,7 +263,7 @@ class StringFormatChecker(BaseChecker): for k, _ in args.items: if isinstance(k, astroid.Const): key = k.value - if isinstance(key, basestring): + if isinstance(key, six.string_types): keys.add(key) else: self.add_message('bad-format-string-key', @@ -346,7 +349,7 @@ class StringMethodsChecker(BaseChecker): if not isinstance(node.func.expr, astroid.Const): return try: - strnode = func.bound.infer().next() + strnode = next(func.bound.infer()) except astroid.InferenceError: return if not isinstance(strnode, astroid.Const): @@ -365,7 +368,7 @@ class StringMethodsChecker(BaseChecker): return named_fields = set(field[0] for field in fields - if isinstance(field[0], basestring)) + if isinstance(field[0], six.string_types)) if num_args and manual_pos: self.add_message('format-combined-specification', node=node) @@ -435,7 +438,7 @@ class StringMethodsChecker(BaseChecker): if argname in (astroid.YES, None): continue try: - argument = argname.infer().next() + argument = next(argname.infer()) except astroid.InferenceError: continue if not specifiers or argument is astroid.YES: @@ -492,7 +495,7 @@ class StringMethodsChecker(BaseChecker): break try: - previous = previous.infer().next() + previous = next(previous.infer()) except astroid.InferenceError: # can't check further if we can't infer it break diff --git a/checkers/utils.py b/checkers/utils.py index af1440d..55bcdd4 100644 --- a/checkers/utils.py +++ b/checkers/utils.py @@ -87,11 +87,11 @@ def safe_infer(node): """ try: inferit = node.infer() - value = inferit.next() + value = next(inferit) except astroid.InferenceError: return try: - inferit.next() + next(inferit) return # None if there is ambiguity on the inferred node except astroid.InferenceError: return # there is some kind of ambiguity @@ -471,7 +471,7 @@ def has_known_bases(klass): pass try: for base in klass.bases: - result = base.infer().next() + result = next(base.infer()) # TODO: check for A->B->A->B pattern in class structure too? if not isinstance(result, astroid.Class) or result is klass or not has_known_bases(result): klass._all_bases_known = False diff --git a/checkers/variables.py b/checkers/variables.py index 71b4be4..6a26f5a 100644 --- a/checkers/variables.py +++ b/checkers/variables.py @@ -33,6 +33,7 @@ from pylint.checkers.utils import ( is_defined_before, is_error, is_func_default, is_func_decorator, assign_parent, check_messages, is_inside_except, clobber_in_except, get_all_elements, has_known_bases) +import six SPECIAL_OBJ = re.compile("^_{2}[a-z]+_{2}$") @@ -45,7 +46,7 @@ def in_for_else_branch(parent, stmt): def overridden_method(klass, name): """get overridden method if any""" try: - parent = klass.local_attr_ancestors(name).next() + parent = next(klass.local_attr_ancestors(name)) except (StopIteration, KeyError): return None try: @@ -145,7 +146,7 @@ def _fix_dot_imports(not_consumed): """ # TODO: this should be improved in issue astroid #46 names = {} - for name, stmts in not_consumed.iteritems(): + for name, stmts in six.iteritems(not_consumed): if any(isinstance(stmt, astroid.AssName) and isinstance(stmt.ass_type(), astroid.AugAssign) for stmt in stmts): @@ -296,7 +297,7 @@ builtins. Remember that you should avoid to define new builtins when possible.' checks globals doesn't overrides builtins """ self._to_consume = [(copy(node.locals), {}, 'module')] - for name, stmts in node.locals.iteritems(): + for name, stmts in six.iteritems(node.locals): if is_builtin(name) and not is_inside_except(stmts[0]): # do not print Redefining builtin for additional builtins self.add_message('redefined-builtin', args=name, node=stmts[0]) @@ -311,16 +312,16 @@ builtins. Remember that you should avoid to define new builtins when possible.' not_consumed = self._to_consume.pop()[0] # attempt to check for __all__ if defined if '__all__' in node.locals: - assigned = node.igetattr('__all__').next() + assigned = next(node.igetattr('__all__')) if assigned is not astroid.YES: for elt in getattr(assigned, 'elts', ()): try: - elt_name = elt.infer().next() + elt_name = next(elt.infer()) except astroid.InferenceError: continue if not isinstance(elt_name, astroid.Const) \ - or not isinstance(elt_name.value, basestring): + or not isinstance(elt_name.value, six.string_types): self.add_message('invalid-all-object', args=elt.as_string(), node=elt) continue @@ -503,7 +504,7 @@ builtins. Remember that you should avoid to define new builtins when possible.' for nonlocal_stmt in node.nodes_of_class(astroid.Nonlocal): nonlocal_names.update(set(nonlocal_stmt.names)) - for name, stmts in not_consumed.iteritems(): + for name, stmts in six.iteritems(not_consumed): # ignore some special names specified by user configuration if authorized_rgx.match(name): continue @@ -829,7 +830,7 @@ builtins. Remember that you should avoid to define new builtins when possible.' for name, _ in node.names: parts = name.split('.') try: - module = node.infer_name_module(parts[0]).next() + module = next(node.infer_name_module(parts[0])) except astroid.ResolveError: continue self._check_module_attrs(node, module, parts[1:]) @@ -916,7 +917,7 @@ builtins. Remember that you should avoid to define new builtins when possible.' module = None break try: - module = module.getattr(name)[0].infer().next() + module = next(module.getattr(name)[0].infer()) if module is astroid.YES: return None except astroid.NotFoundError: |