Hello community, here is the log from the commit of package python3-pylint for openSUSE:Factory checked in at 2015-12-17 15:54:42 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python3-pylint (Old) and /work/SRC/openSUSE:Factory/.python3-pylint.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python3-pylint" Changes: -------- --- /work/SRC/openSUSE:Factory/python3-pylint/python3-pylint.changes 2015-12-03 13:32:06.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.python3-pylint.new/python3-pylint.changes 2015-12-17 15:54:44.000000000 +0100 @@ -1,0 +2,20 @@ +Sat Dec 5 22:32:03 UTC 2015 - arun@gmx.de + +- update to version 1.5.1: + * Fix a crash which occurred when old visit methods are encountered + in plugin modules. Closes issue #711. + * Add wrong-import-position to check_messages's decorator arguments + for ImportChecker.leave_module This fixes an esoteric bug which + occurs when ungrouped-imports and wrong-import-order are disabled + and pylint is executed on multiple files. What happens is that + without wrong-import-position in check_messages, leave_module will + never be called, which means that the first non-import node from + other files might leak into the current file, leading to + wrong-import-position being emitted by pylint. + * Fix a crash which occurred when old visit methods are encountered + in plugin modules. Closes issue #711. + * Don't emit import-self and cyclic-import for relative imports of + modules with the same name as the package itself. Closes issues + #708 and #706. + +------------------------------------------------------------------- Old: ---- pylint-1.5.0.tar.gz New: ---- pylint-1.5.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python3-pylint.spec ++++++ --- /var/tmp/diff_new_pack.DhOuXn/_old 2015-12-17 15:54:45.000000000 +0100 +++ /var/tmp/diff_new_pack.DhOuXn/_new 2015-12-17 15:54:45.000000000 +0100 @@ -17,7 +17,7 @@ Name: python3-pylint -Version: 1.5.0 +Version: 1.5.1 Release: 0 Summary: Syntax and style checker for Python code License: GPL-2.0+ ++++++ pylint-1.5.0.tar.gz -> pylint-1.5.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/ChangeLog new/pylint-1.5.1/ChangeLog --- old/pylint-1.5.0/ChangeLog 2015-11-29 17:29:27.000000000 +0100 +++ new/pylint-1.5.1/ChangeLog 2015-12-02 16:51:44.000000000 +0100 @@ -1,6 +1,29 @@ ChangeLog for Pylint -------------------- +2015-12-02 -- 1.5.1 + + * Don't emit unsubscriptable-object if the node is found + inside an abstract class. Closes issue #685. + + * Add wrong-import-position to check_messages's decorator arguments + for ImportChecker.leave_module + + This fixes an esoteric bug which occurs when ungrouped-imports and + wrong-import-order are disabled and pylint is executed on multiple files. + What happens is that without wrong-import-position in check_messages, + leave_module will never be called, which means that the first non-import node + from other files might leak into the current file, + leading to wrong-import-position being emitted by pylint. + + * Fix a crash which occurred when old visit methods are encountered + in plugin modules. Closes issue #711. + + * Don't emit import-self and cyclic-import for relative imports + of modules with the same name as the package itself. + Closes issues #708 and #706. + + 2015-11-29 -- 1.5.0 * Added multiple warnings related to imports. 'wrong-import-order' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/PKG-INFO new/pylint-1.5.1/PKG-INFO --- old/pylint-1.5.0/PKG-INFO 2015-11-29 18:40:19.000000000 +0100 +++ new/pylint-1.5.1/PKG-INFO 2015-12-02 16:57:04.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: pylint -Version: 1.5.0 +Version: 1.5.1 Summary: python code static checker Home-page: http://www.pylint.org Author: Logilab diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint/__pkginfo__.py new/pylint-1.5.1/pylint/__pkginfo__.py --- old/pylint-1.5.0/pylint/__pkginfo__.py 2015-11-29 17:09:05.000000000 +0100 +++ new/pylint-1.5.1/pylint/__pkginfo__.py 2015-12-02 16:51:44.000000000 +0100 @@ -23,11 +23,11 @@ modname = distname = 'pylint' -numversion = (1, 5, 0) +numversion = (1, 5, 1) version = '.'.join([str(num) for num in numversion]) install_requires = [ - 'astroid>=1.4.0', + 'astroid>=1.4.1', 'six', ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint/checkers/imports.py new/pylint-1.5.1/pylint/checkers/imports.py --- old/pylint-1.5.0/pylint/checkers/imports.py 2015-11-29 15:57:39.000000000 +0100 +++ new/pylint-1.5.1/pylint/checkers/imports.py 2015-12-02 15:27:25.000000000 +0100 @@ -15,9 +15,9 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """imports checkers for Python code""" +import collections import os import sys -from collections import defaultdict, Counter import six @@ -34,6 +34,18 @@ from pylint.reporters.ureports.nodes import VerbatimText, Paragraph +def _qualified_names(modname): + """Split the names of the given module into subparts + + For example, + _qualified_names('pylint.checkers.ImportsChecker') + returns + ['pylint', 'pylint.checkers', 'pylint.checkers.ImportsChecker'] + """ + names = modname.split('.') + return ['.'.join(names[0:i+1]) for i in range(len(names))] + + def _get_import_name(importnode, modname): """Get a prepared module name from the given import node @@ -51,7 +63,7 @@ return modname -def get_first_import(node, context, name, base, level): +def _get_first_import(node, context, name, base, level): """return the node where [base.]<name> is imported or None if not found """ fullname = '%s.%s' % (base, name) if base else name @@ -78,7 +90,7 @@ # utilities to represents import dependencies as tree and dot graph ########### -def make_tree_defs(mod_files_list): +def _make_tree_defs(mod_files_list): """get a list of 2-uple (module, list_of_files_which_import_this_module), it will return a dictionary to represent this as a tree """ @@ -90,7 +102,8 @@ node[1] += files return tree_defs -def repr_tree_defs(data, indent_str=None): + +def _repr_tree_defs(data, indent_str=None): """return a string which represents imports as a tree""" lines = [] nodes = data.items() @@ -109,11 +122,11 @@ else: sub_indent_str = '%s| ' % indent_str if sub: - lines.append(repr_tree_defs(sub, sub_indent_str)) + lines.append(_repr_tree_defs(sub, sub_indent_str)) return '\n'.join(lines) -def dependencies_graph(filename, dep_info): +def _dependencies_graph(filename, dep_info): """write dependencies as a dot (graphviz) file """ done = {} @@ -132,11 +145,11 @@ printer.generate(filename) -def make_graph(filename, dep_info, sect, gtype): +def _make_graph(filename, dep_info, sect, gtype): """generate a dependencies graph and add some information about it in the report's section """ - dependencies_graph(filename, dep_info) + _dependencies_graph(filename, dep_info) sect.append(Paragraph('%simports graph has been written to %s' % (gtype, filename))) @@ -207,7 +220,7 @@ msgs = MSGS priority = -2 - if sys.version_info < (3,): + if six.PY2: deprecated_modules = ('regsub', 'TERMIOS', 'Bastion', 'rexec') else: deprecated_modules = ('optparse', ) @@ -250,9 +263,9 @@ self._first_non_import_node = None self.__int_dep_info = self.__ext_dep_info = None self.reports = (('RP0401', 'External dependencies', - self.report_external_dependencies), + self._report_external_dependencies), ('RP0402', 'Modules dependencies graph', - self.report_dependencies_graph), + self._report_dependencies_graph), ) def open(self): @@ -260,7 +273,7 @@ self.linter.add_stats(dependencies={}) self.linter.add_stats(cycles=[]) self.stats = self.linter.stats - self.import_graph = defaultdict(set) + self.import_graph = collections.defaultdict(set) self._ignored_modules = get_global_option( self, 'ignored-modules', default=[]) @@ -272,44 +285,40 @@ for cycle in get_cycles(self.import_graph, vertices=vertices): self.add_message('cyclic-import', args=' -> '.join(cycle)) - @check_messages('wrong-import-position') + @check_messages('wrong-import-position', 'multiple-imports', + 'relative-import', 'reimported') def visit_import(self, node): """triggered when an import statement is seen""" + self._check_reimport(node) + modnode = node.root() names = [name for name, _ in node.names] if len(names) >= 2: self.add_message('multiple-imports', args=', '.join(names), node=node) + for name in names: self._check_deprecated_module(node, name) importedmodnode = self.get_imported_module(node, name) if isinstance(node.scope(), astroid.Module): self._check_position(node) self._record_import(node, importedmodnode) + if importedmodnode is None: continue + self._check_relative_import(modnode, node, importedmodnode, name) self._add_imported_module(node, importedmodnode.name) - self._check_reimport(node, name) - # TODO This appears to be the list of all messages of the checker... - # @check_messages('W0410', 'W0401', 'W0403', 'W0402', 'W0404', 'W0406', 'E0401') @check_messages(*(MSGS.keys())) def visit_importfrom(self, node): """triggered when a from statement is seen""" basename = node.modname - if basename == '__future__': - # check if this is the first non-docstring statement in the module - prev = node.previous_sibling() - if prev: - # consecutive future statements are possible - if not (isinstance(prev, astroid.ImportFrom) - and prev.modname == '__future__'): - self.add_message('misplaced-future', node=node) - return + self._check_misplaced_future(node) self._check_deprecated_module(node, basename) - for name, _ in node.names: - if name == '*': - self.add_message('wildcard-import', args=basename, node=node) + self._check_wildcard_imports(node) + self._check_same_line_imports(node) + self._check_reimport(node, basename=basename, level=node.level) + modnode = node.root() importedmodnode = self.get_imported_module(node, basename) if isinstance(node.scope(), astroid.Module): @@ -322,17 +331,9 @@ for name, _ in node.names: if name != '*': self._add_imported_module(node, '%s.%s' % (importedmodnode.name, name)) - self._check_reimport(node, name, basename, node.level) - # Detect duplicate imports on the same line. - names = (name for name, _ in node.names) - counter = Counter(names) - for name, count in counter.items(): - if count > 1: - self.add_message('reimported', node=node, - args=(name, node.fromlineno)) - - @check_messages('wrong-import-order', 'ungrouped-imports') + @check_messages('wrong-import-order', 'ungrouped-imports', + 'wrong-import-position') def leave_module(self, node): # Check imports are grouped by category (standard, 3rd party, local) std_imports, ext_imports, loc_imports = self._check_imports_order(node) @@ -374,6 +375,27 @@ visit_classdef = visit_for = visit_while = visit_functiondef + def _check_misplaced_future(self, node): + basename = node.modname + if basename == '__future__': + # check if this is the first non-docstring statement in the module + prev = node.previous_sibling() + if prev: + # consecutive future statements are possible + if not (isinstance(prev, astroid.ImportFrom) + and prev.modname == '__future__'): + self.add_message('misplaced-future', node=node) + return + + def _check_same_line_imports(self, node): + # Detect duplicate imports on the same line. + names = (name for name, _ in node.names) + counter = collections.Counter(names) + for name, count in counter.items(): + if count > 1: + self.add_message('reimported', node=node, + args=(name, node.fromlineno)) + def _check_position(self, node): """Check `node` import or importfrom node position is correct @@ -446,25 +468,13 @@ else: args = repr(dotted_modname) - for submodule in self._qualified_names(modname): + for submodule in _qualified_names(modname): if submodule in self._ignored_modules: return None if not node_ignores_exception(importnode, ImportError): self.add_message("import-error", args=args, node=importnode) - @staticmethod - def _qualified_names(modname): - """Split the names of the given module into subparts - - For example, - _qualified_names('pylint.checkers.ImportsChecker') - returns - ['pylint', 'pylint.checkers', 'pylint.checkers.ImportsChecker'] - """ - names = modname.split('.') - return ['.'.join(names[0:i+1]) for i in range(len(names))] - def _check_relative_import(self, modnode, importnode, importedmodnode, importedasname): """check relative import. node is either an Import or From node, modname @@ -486,14 +496,26 @@ def _add_imported_module(self, node, importedmodname): """notify an imported module, used to analyze dependencies""" + module_file = node.root().file + context_name = node.root().name + base = os.path.splitext(os.path.basename(module_file))[0] + + # Determine if we have a `from .something import` in a package's + # __init__. This means the module will never be able to import + # itself using this condition (the level will be bigger or + # if the same module is named as the package, it will be different + # anyway). + if isinstance(node, astroid.ImportFrom): + if node.level and node.level > 0 and base == '__init__': + return + try: importedmodname = get_module_part(importedmodname, - node.root().file) + module_file) except ImportError: pass - context_name = node.root().name + if context_name == importedmodname: - # module importing itself ! self.add_message('import-self', node=node) elif not is_standard_module(importedmodname): # handle dependencies @@ -512,7 +534,7 @@ if mod_path == mod_name or mod_path.startswith(mod_name + '.'): self.add_message('deprecated-module', node=node, args=mod_path) - def _check_reimport(self, node, name, basename=None, level=None): + def _check_reimport(self, node, basename=None, level=None): """check if the import is necessary (i.e. not already done)""" if not self.linter.is_message_enabled('reimported'): return @@ -522,22 +544,23 @@ contexts = [(frame, level)] if root is not frame: contexts.append((root, None)) - for context, level in contexts: - first = get_first_import(node, context, name, basename, level) - if first is not None: - self.add_message('reimported', node=node, - args=(name, first.fromlineno)) + for context, level in contexts: + for name, _ in node.names: + first = _get_first_import(node, context, name, basename, level) + if first is not None: + self.add_message('reimported', node=node, + args=(name, first.fromlineno)) - def report_external_dependencies(self, sect, _, dummy): + def _report_external_dependencies(self, sect, _, dummy): """return a verbatim layout for displaying dependencies""" - dep_info = make_tree_defs(six.iteritems(self._external_dependencies_info())) + dep_info = _make_tree_defs(six.iteritems(self._external_dependencies_info())) if not dep_info: raise EmptyReport() - tree_str = repr_tree_defs(dep_info) + tree_str = _repr_tree_defs(dep_info) sect.append(VerbatimText(tree_str)) - def report_dependencies_graph(self, sect, _, dummy): + def _report_dependencies_graph(self, sect, _, dummy): """write dependencies as a dot (graphviz) file""" dep_info = self.stats['dependencies'] if not dep_info or not (self.config.import_graph @@ -546,15 +569,15 @@ raise EmptyReport() filename = self.config.import_graph if filename: - make_graph(filename, dep_info, sect, '') + _make_graph(filename, dep_info, sect, '') filename = self.config.ext_import_graph if filename: - make_graph(filename, self._external_dependencies_info(), - sect, 'external ') + _make_graph(filename, self._external_dependencies_info(), + sect, 'external ') filename = self.config.int_import_graph if filename: - make_graph(filename, self._internal_dependencies_info(), - sect, 'internal ') + _make_graph(filename, self._internal_dependencies_info(), + sect, 'internal ') def _external_dependencies_info(self): """return cached external dependencies information or build and @@ -580,6 +603,11 @@ result[importee] = importers return self.__int_dep_info + def _check_wildcard_imports(self, node): + for name, _ in node.names: + if name == '*': + self.add_message('wildcard-import', args=node.modname, node=node) + def register(linter): """required method to auto register this checker """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint/checkers/typecheck.py new/pylint-1.5.1/pylint/checkers/typecheck.py --- old/pylint-1.5.0/pylint/checkers/typecheck.py 2015-11-29 17:09:05.000000000 +0100 +++ new/pylint-1.5.1/pylint/checkers/typecheck.py 2015-12-02 16:51:44.000000000 +0100 @@ -834,9 +834,15 @@ self.add_message('unsubscriptable-object', args=node.value.as_string(), node=node.value) + return + infered = safe_infer(node.value) if infered is None or infered is astroid.YES: return + + if is_inside_abstract_class(node): + return + if not supports_subscript(infered): self.add_message('unsubscriptable-object', args=node.value.as_string(), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint/extensions/check_elif.py new/pylint-1.5.1/pylint/extensions/check_elif.py --- old/pylint-1.5.0/pylint/extensions/check_elif.py 2015-11-29 16:34:16.000000000 +0100 +++ new/pylint-1.5.1/pylint/extensions/check_elif.py 2015-12-02 15:27:25.000000000 +0100 @@ -25,27 +25,13 @@ self._elifs = [] self._if_counter = 0 - def _is_actual_elif(self, node): - """Check if the given node is an actual elif - - This is a problem we're having with the builtin ast module, - which splits `elif` branches into a separate if statement. - Unfortunately we need to know the exact type in certain - cases. - """ - - if isinstance(node.parent, astroid.If): - orelse = node.parent.orelse - # current if node must directly follow a "else" - if orelse and orelse == [node]: - if self._elifs[self._if_counter]: - return True - return False - def process_tokens(self, tokens): # Process tokens and look for 'if' or 'elif' for _, token, _, _, _ in tokens: - self._elifs.append(True if token == 'elif' else False) + if token == 'elif': + self._elifs.append(True) + elif token == 'if': + self._elifs.append(False) def leave_module(self, _): self._init() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint/gui.py new/pylint-1.5.1/pylint/gui.py --- old/pylint-1.5.0/pylint/gui.py 2015-11-29 15:57:39.000000000 +0100 +++ new/pylint-1.5.1/pylint/gui.py 2015-12-02 15:27:25.000000000 +0100 @@ -27,7 +27,7 @@ Tk, Frame, Listbox, Entry, Label, Button, Scrollbar, Checkbutton, Radiobutton, IntVar, StringVar, PanedWindow, TOP, LEFT, RIGHT, BOTTOM, END, X, Y, BOTH, SUNKEN, W, - HORIZONTAL, DISABLED, NORMAL, W, + HORIZONTAL, DISABLED, NORMAL, ) from six.moves.tkinter_tkfiledialog import ( askopenfilename, askdirectory, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint/test/extensions/data/elif.py new/pylint-1.5.1/pylint/test/extensions/data/elif.py --- old/pylint-1.5.0/pylint/test/extensions/data/elif.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pylint-1.5.1/pylint/test/extensions/data/elif.py 2015-12-02 15:27:25.000000000 +0100 @@ -0,0 +1,26 @@ +"""Checks use of "else if" triggers a refactor message""" + +def my_function(): + """docstring""" + myint = 2 + if myint > 5: + pass + else: + if myint <= 5: + pass + else: + myint = 3 + if myint > 2: + if myint > 3: + pass + elif myint == 3: + pass + elif myint < 3: + pass + else: + if myint: + pass + else: + if myint: + pass + myint = 4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint/test/extensions/test_elseif_used.py new/pylint-1.5.1/pylint/test/extensions/test_elseif_used.py --- old/pylint-1.5.0/pylint/test/extensions/test_elseif_used.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pylint-1.5.1/pylint/test/extensions/test_elseif_used.py 2015-12-02 16:51:36.000000000 +0100 @@ -0,0 +1,47 @@ +"""Tests for the pylint checker in :mod:`pylint.extensions.check_elif +""" + +import os +import os.path as osp +import unittest + +from pylint import checkers +from pylint.extensions.check_elif import ElseifUsedChecker +from pylint.lint import PyLinter +from pylint.reporters import BaseReporter + + +class TestReporter(BaseReporter): + + def handle_message(self, msg): + self.messages.append(msg) + + def on_set_current_module(self, module, filepath): + self.messages = [] + + +class CheckElseIfUsedTC(unittest.TestCase): + + @classmethod + def setUpClass(cls): + cls._linter = PyLinter() + cls._linter.set_reporter(TestReporter()) + checkers.initialize(cls._linter) + cls._linter.register_checker(ElseifUsedChecker(cls._linter)) + + def test_elseif_message(self): + elif_test = osp.join(osp.dirname(osp.abspath(__file__)), 'data', + 'elif.py') + self._linter.check([elif_test]) + msgs = self._linter.reporter.messages + self.assertEqual(len(msgs), 2) + for msg in msgs: + self.assertEqual(msg.symbol, 'else-if-used') + self.assertEqual(msg.msg, + 'Consider using "elif" instead of "else if"') + self.assertEqual(msgs[0].line, 9) + self.assertEqual(msgs[1].line, 21) + + +if __name__ == '__main__': + unittest.main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint/test/functional/reimported.py new/pylint-1.5.1/pylint/test/functional/reimported.py --- old/pylint-1.5.0/pylint/test/functional/reimported.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pylint-1.5.1/pylint/test/functional/reimported.py 2015-12-02 15:27:25.000000000 +0100 @@ -0,0 +1,7 @@ +# pylint: disable=missing-docstring,unused-import,import-error + +from time import sleep, sleep # [reimported] +from lala import missing, missing # [reimported] + +import missing1 +import missing1 # [reimported] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint/test/functional/reimported.txt new/pylint-1.5.1/pylint/test/functional/reimported.txt --- old/pylint-1.5.0/pylint/test/functional/reimported.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/pylint-1.5.1/pylint/test/functional/reimported.txt 2015-12-02 15:27:25.000000000 +0100 @@ -0,0 +1,3 @@ +reimported:3::"Reimport 'sleep' (imported line 3)" +reimported:4::"Reimport 'missing' (imported line 4)" +reimported:7::"Reimport 'missing1' (imported line 6)" \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint/test/functional/unsubscriptable_value.py new/pylint-1.5.1/pylint/test/functional/unsubscriptable_value.py --- old/pylint-1.5.0/pylint/test/functional/unsubscriptable_value.py 2015-11-29 15:57:39.000000000 +0100 +++ new/pylint-1.5.1/pylint/test/functional/unsubscriptable_value.py 2015-12-02 15:27:25.000000000 +0100 @@ -88,3 +88,28 @@ deq = deque(maxlen=10) deq.append(42) deq[0] + + +class AbstractClass(object): + + def __init__(self): + self.ala = {i for i in range(10)} + self.bala = [i for i in range(10)] + self.portocala = None + + def test_unsubscriptable(self): + self.bala[0] + self.portocala[0] + + +class ClassMixin(object): + + def __init__(self): + self.ala = {i for i in range(10)} + self.bala = [i for i in range(10)] + self.portocala = None + + def test_unsubscriptable(self): + self.bala[0] + self.portocala[0] + \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint/test/regrtest_data/dummy/__init__.py new/pylint-1.5.1/pylint/test/regrtest_data/dummy/__init__.py --- old/pylint-1.5.0/pylint/test/regrtest_data/dummy/__init__.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pylint-1.5.1/pylint/test/regrtest_data/dummy/__init__.py 2015-12-02 15:27:25.000000000 +0100 @@ -0,0 +1,3 @@ +# pylint: disable=missing-docstring +from .dummy import DUMMY +from .another import ANOTHER diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint/test/regrtest_data/dummy/another.py new/pylint-1.5.1/pylint/test/regrtest_data/dummy/another.py --- old/pylint-1.5.0/pylint/test/regrtest_data/dummy/another.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pylint-1.5.1/pylint/test/regrtest_data/dummy/another.py 2015-12-02 15:27:25.000000000 +0100 @@ -0,0 +1,4 @@ +# pylint: disable=missing-docstring + +ANOTHER = 42 + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint/test/regrtest_data/dummy/dummy.py new/pylint-1.5.1/pylint/test/regrtest_data/dummy/dummy.py --- old/pylint-1.5.0/pylint/test/regrtest_data/dummy/dummy.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pylint-1.5.1/pylint/test/regrtest_data/dummy/dummy.py 2015-12-02 15:27:25.000000000 +0100 @@ -0,0 +1,2 @@ +# pylint: disable=missing-docstring +DUMMY = 42 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint/test/regrtest_data/import_something.py new/pylint-1.5.1/pylint/test/regrtest_data/import_something.py --- old/pylint-1.5.0/pylint/test/regrtest_data/import_something.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pylint-1.5.1/pylint/test/regrtest_data/import_something.py 2015-12-02 15:27:25.000000000 +0100 @@ -0,0 +1,4 @@ +# pylint: disable=missing-docstring,unused-import + +import os +import sys diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint/test/regrtest_data/wrong_import_position.py new/pylint-1.5.1/pylint/test/regrtest_data/wrong_import_position.py --- old/pylint-1.5.0/pylint/test/regrtest_data/wrong_import_position.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pylint-1.5.1/pylint/test/regrtest_data/wrong_import_position.py 2015-12-02 15:27:25.000000000 +0100 @@ -0,0 +1,11 @@ +"""Test that wrong-import-position is properly reset when +other errors are disabled. +""" +# pylint: disable=unused-import, too-few-public-methods + + +class Something(object): + """A class before an import.""" + + +import os diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint/test/test_import_graph.py new/pylint-1.5.1/pylint/test/test_import_graph.py --- old/pylint-1.5.0/pylint/test/test_import_graph.py 2015-11-29 15:57:00.000000000 +0100 +++ new/pylint-1.5.1/pylint/test/test_import_graph.py 2015-12-02 15:27:25.000000000 +0100 @@ -18,8 +18,8 @@ os.remove(self.dest) def test_dependencies_graph(self): - imports.dependencies_graph(self.dest, {'labas': ['hoho', 'yep'], - 'hoho': ['yep']}) + imports._dependencies_graph(self.dest, {'labas': ['hoho', 'yep'], + 'hoho': ['yep']}) with open(self.dest) as stream: self.assertEqual(stream.read().strip(), ''' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint/test/test_self.py new/pylint-1.5.1/pylint/test/test_self.py --- old/pylint-1.5.0/pylint/test/test_self.py 2015-11-29 15:57:00.000000000 +0100 +++ new/pylint-1.5.1/pylint/test/test_self.py 2015-12-02 16:51:36.000000000 +0100 @@ -92,9 +92,12 @@ self.assertEqual(pylint_code, code, msg) def _run_pylint(self, args, out, reporter=None): + args = args + ['--persistent=no'] with _patch_streams(out): with self.assertRaises(SystemExit) as cm: - Run(args, reporter=reporter) + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + Run(args, reporter=reporter) return cm.exception.code def _test_output(self, args, expected_output): @@ -270,6 +273,29 @@ module = join(HERE, 'regrtest_data', 'html_crash_420.py') self._runtest([module], code=16, reporter=HTMLReporter(out)) + def test_wrong_import_position_when_others_disabled(self): + expected_output = textwrap.dedent(''' + No config file found, using default configuration + ************* Module wrong_import_position + C: 11, 0: Import "import os" should be placed at the top of the module (wrong-import-position) + ''') + module1 = join(HERE, 'regrtest_data', 'import_something.py') + module2 = join(HERE, 'regrtest_data', 'wrong_import_position.py') + args = [module2, module1, + "--disable=all", "--enable=wrong-import-position", + "-rn"] + out = six.StringIO() + self._run_pylint(args, out=out) + actual_output = out.getvalue() + self.assertEqual(expected_output.strip(), actual_output.strip()) + + def test_import_itself_not_accounted_for_relative_imports(self): + expected = 'No config file found, using default configuration' + package = join(HERE, 'regrtest_data', 'dummy') + self._test_output([package, '--disable=locally-disabled', '-rn'], + expected_output=expected) + + if __name__ == '__main__': unittest.main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint/test/unittest_lint.py new/pylint-1.5.1/pylint/test/unittest_lint.py --- old/pylint-1.5.0/pylint/test/unittest_lint.py 2015-11-29 15:57:00.000000000 +0100 +++ new/pylint-1.5.1/pylint/test/unittest_lint.py 2015-12-02 15:27:25.000000000 +0100 @@ -33,6 +33,7 @@ from pylint.testutils import TestReporter from pylint.reporters import text, html from pylint import checkers +from pylint.checkers.utils import check_messages from pylint import interfaces if os.name == 'java': @@ -217,6 +218,22 @@ linter.file_state = FileState('toto') return linter + def test_pylint_visit_method_taken_in_account(self): + class CustomChecker(checkers.BaseChecker): + __implements__ = interfaces.IAstroidChecker + name = 'custom' + msgs = {'W9999': ('', 'custom', '')} + + @check_messages('custom') + def visit_class(self, _): + pass + + self.linter.register_checker(CustomChecker(self.linter)) + self.linter.open() + out = six.moves.StringIO() + self.linter.set_reporter(text.TextReporter(out)) + self.linter.check('abc') + def test_enable_message(self): linter = self.init_linter() self.assertTrue(linter.is_message_enabled('W0101')) @@ -669,6 +686,6 @@ self.assertEqual('msg-symbol', self.store.check_message_id('old-symbol').symbol) - + if __name__ == '__main__': unittest.main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint/utils.py new/pylint-1.5.1/pylint/utils.py --- old/pylint-1.5.0/pylint/utils.py 2015-11-29 15:57:39.000000000 +0100 +++ new/pylint-1.5.1/pylint/utils.py 2015-12-02 15:27:25.000000000 +0100 @@ -19,6 +19,7 @@ from __future__ import print_function import collections +import itertools import os from os.path import dirname, basename, splitext, exists, isdir, join, normpath import re @@ -904,15 +905,14 @@ # Detect if the node is a new name for a deprecated alias. # In this case, favour the methods for the deprecated # alias if any, in order to maintain backwards - # compatibility. If both of them are present, - # only the old ones will be called. + # compatibility. old_cid = DEPRECATED_ALIASES.get(cid) visit_events = () leave_events = () if old_cid: - visit_events = self.visit_events.get(old_cid) - leave_events = self.leave_events.get(old_cid) + visit_events = self.visit_events.get(old_cid, ()) + leave_events = self.leave_events.get(old_cid, ()) if visit_events or leave_events: msg = ("Implemented method {meth}_{old} instead of {meth}_{new}. " "This will be supported until Pylint 2.0.") @@ -923,10 +923,10 @@ warnings.warn(msg.format(meth="leave", old=old_cid, new=cid), PendingDeprecationWarning) - if not visit_events: - visit_events = self.visit_events.get(cid) - if not leave_events: - leave_events = self.leave_events.get(cid) + visit_events = itertools.chain(visit_events, + self.visit_events.get(cid, ())) + leave_events = itertools.chain(leave_events, + self.leave_events.get(cid, ())) if astroid.is_statement: self.nbstatements += 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint.egg-info/PKG-INFO new/pylint-1.5.1/pylint.egg-info/PKG-INFO --- old/pylint-1.5.0/pylint.egg-info/PKG-INFO 2015-11-29 18:40:16.000000000 +0100 +++ new/pylint-1.5.1/pylint.egg-info/PKG-INFO 2015-12-02 16:56:54.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: pylint -Version: 1.5.0 +Version: 1.5.1 Summary: python code static checker Home-page: http://www.pylint.org Author: Logilab diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint.egg-info/SOURCES.txt new/pylint-1.5.1/pylint.egg-info/SOURCES.txt --- old/pylint-1.5.0/pylint.egg-info/SOURCES.txt 2015-11-29 18:40:17.000000000 +0100 +++ new/pylint-1.5.1/pylint.egg-info/SOURCES.txt 2015-12-02 16:56:55.000000000 +0100 @@ -138,6 +138,8 @@ pylint/test/data/suppliermodule_test.py pylint/test/extensions/__init__.py pylint/test/extensions/test_check_docs.py +pylint/test/extensions/test_elseif_used.py +pylint/test/extensions/data/elif.py pylint/test/functional/__init__.py pylint/test/functional/abstract_abc_methods.py pylint/test/functional/abstract_class_instantiated_in_class.py @@ -438,6 +440,8 @@ pylint/test/functional/redefined_variable_type.txt pylint/test/functional/redundant_unittest_assert.py pylint/test/functional/redundant_unittest_assert.txt +pylint/test/functional/reimported.py +pylint/test/functional/reimported.txt pylint/test/functional/repeated_keyword.py pylint/test/functional/repeated_keyword.txt pylint/test/functional/return_in_init.py @@ -772,6 +776,7 @@ pylint/test/regrtest_data/html_crash_420.py pylint/test/regrtest_data/import_assign.py pylint/test/regrtest_data/import_package_subpackage_module.py +pylint/test/regrtest_data/import_something.py pylint/test/regrtest_data/module_global.py pylint/test/regrtest_data/no_stdout_encoding.py pylint/test/regrtest_data/numarray_import.py @@ -780,10 +785,14 @@ pylint/test/regrtest_data/py3k_error_flag.py pylint/test/regrtest_data/special_attr_scope_lookup_crash.py pylint/test/regrtest_data/try_finally_disable_msg_crash.py +pylint/test/regrtest_data/wrong_import_position.py pylint/test/regrtest_data/absimp/__init__.py pylint/test/regrtest_data/absimp/string.py pylint/test/regrtest_data/bad_package/__init__.py pylint/test/regrtest_data/bad_package/wrong.py +pylint/test/regrtest_data/dummy/__init__.py +pylint/test/regrtest_data/dummy/another.py +pylint/test/regrtest_data/dummy/dummy.py pylint/test/regrtest_data/package/AudioTime.py pylint/test/regrtest_data/package/__init__.py pylint/test/regrtest_data/package/subpackage/__init__.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pylint-1.5.0/pylint.egg-info/requires.txt new/pylint-1.5.1/pylint.egg-info/requires.txt --- old/pylint-1.5.0/pylint.egg-info/requires.txt 2015-11-29 18:40:16.000000000 +0100 +++ new/pylint-1.5.1/pylint.egg-info/requires.txt 2015-12-02 16:56:54.000000000 +0100 @@ -1,3 +1,3 @@ -astroid>=1.4.0 +astroid>=1.4.1 six colorama