First implementation for the BackgroundService. BgService

Tue, 31 Dec 2013 18:03:31 +0100

author
T.Rzepka <Tobias.Rzepka@gmail.com>
date
Tue, 31 Dec 2013 18:03:31 +0100
branch
BgService
changeset 3159
02cb2adb4868
parent 3146
14721e0f3b5b
child 3172
c0f78e9d0971

First implementation for the BackgroundService.

Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheck.py file | annotate | diff | comparison | revisions
Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py file | annotate | diff | comparison | revisions
Plugins/CheckerPlugins/SyntaxChecker/pyflakes/__init__.py file | annotate | diff | comparison | revisions
Plugins/CheckerPlugins/SyntaxChecker/pyflakes/checker.py file | annotate | diff | comparison | revisions
Plugins/CheckerPlugins/SyntaxChecker/pyflakes/messages.py file | annotate | diff | comparison | revisions
UI/UserInterface.py file | annotate | diff | comparison | revisions
Utilities/BackgroundClient.py file | annotate | diff | comparison | revisions
Utilities/BackgroundService.py file | annotate | diff | comparison | revisions
Utilities/SyntaxCheck.py file | annotate | diff | comparison | revisions
Utilities/py2flakes/__init__.py file | annotate | diff | comparison | revisions
Utilities/py2flakes/checker.py file | annotate | diff | comparison | revisions
Utilities/py2flakes/messages.py file | annotate | diff | comparison | revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheck.py	Tue Dec 31 18:03:31 2013 +0100
@@ -0,0 +1,181 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2011 - 2013 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the syntax check for Python 2/3.
+"""
+from __future__ import unicode_literals
+
+import re
+import sys
+import traceback
+
+from .pyflakes.checker import Checker
+from .pyflakes.messages import ImportStarUsed
+
+
+def normalizeCode(codestring):
+    """
+    Function to normalize the given code.
+    
+    @param codestring code to be normalized (string)
+    @return normalized code (string)
+    """
+    codestring = codestring.replace("\r\n", "\n").replace("\r", "\n")
+
+    if codestring and codestring[-1] != '\n':
+        codestring = codestring + '\n'
+
+    # Check type for py2: if not str it's unicode
+    if sys.version_info[0] == 2:
+        try:
+            codestring = codestring.encode('utf-8')
+        except UnicodeError:
+            pass
+    
+    return codestring
+
+
+def extractLineFlags(line, startComment="#", endComment=""):
+    """
+    Function to extract flags starting and ending with '__' from a line
+    comment.
+    
+    @param line line to extract flags from (string)
+    @keyparam startComment string identifying the start of the comment (string)
+    @keyparam endComment string identifying the end of a comment (string)
+    @return list containing the extracted flags (list of strings)
+    """
+    flags = []
+    
+    pos = line.rfind(startComment)
+    if pos >= 0:
+        comment = line[pos + len(startComment):].strip()
+        if endComment:
+            comment = comment.replace("endComment", "")
+        flags = [f.strip() for f in comment.split()
+                 if (f.startswith("__") and f.endswith("__"))]
+    return flags
+
+
+def syntaxAndPyflakesCheck(filename, codestring="", checkFlakes=True,
+                           ignoreStarImportWarnings=False):
+    """
+    Function to compile one Python source file to Python bytecode
+    and to perform a pyflakes check.
+    
+    @param filename source filename (string)
+    @keyparam codestring string containing the code to compile (string)
+    @keyparam checkFlakes flag indicating to do a pyflakes check (boolean)
+    @keyparam ignoreStarImportWarnings flag indicating to
+        ignore 'star import' warnings (boolean)
+    @return A tuple indicating status (True = an error was found), the
+        file name, the line number, the index number, the code string
+        and the error message (boolean, string, string, string, string,
+        string). If checkFlakes is True, a list of strings containing the
+        warnings (marker, file name, line number, message)
+        The values are only valid, if the status is True.
+    """
+    try:
+        import builtins
+    except ImportError:
+        import __builtin__ as builtins        #__IGNORE_WARNING__
+    
+    try:
+        if sys.version_info[0] == 2:
+            file_enc = filename.encode(sys.getfilesystemencoding())
+        else:
+            file_enc = filename
+        
+        # It also encoded the code back to avoid 'Encoding declaration in
+        # unicode string' exception on Python2
+        codestring = normalizeCode(codestring)
+        
+        if filename.endswith('.ptl'):
+            try:
+                import quixote.ptl_compile
+            except ImportError:
+                return (True, filename, 0, 0, '',
+                        'Quixote plugin not found.', [])
+            template = quixote.ptl_compile.Template(codestring, file_enc)
+            template.compile()
+        
+        # ast.PyCF_ONLY_AST = 1024, speed optimisation
+        module = builtins.compile(codestring, file_enc, 'exec',  1024)
+    except SyntaxError as detail:
+        index = 0
+        code = ""
+        error = ""
+        lines = traceback.format_exception_only(SyntaxError, detail)
+        if sys.version_info[0] == 2:
+            lines = [x.decode(sys.getfilesystemencoding()) for x in lines]
+        match = re.match('\s*File "(.+)", line (\d+)',
+                         lines[0].replace('<string>', '{0}'.format(filename)))
+        if match is not None:
+            fn, line = match.group(1, 2)
+            if lines[1].startswith('SyntaxError:'):
+                error = re.match('SyntaxError: (.+)', lines[1]).group(1)
+            else:
+                code = re.match('(.+)', lines[1]).group(1)
+                for seLine in lines[2:]:
+                    if seLine.startswith('SyntaxError:'):
+                        error = re.match('SyntaxError: (.+)', seLine).group(1)
+                    elif seLine.rstrip().endswith('^'):
+                        index = len(seLine.rstrip()) - 4
+        else:
+            fn = detail.filename
+            line = detail.lineno or 1
+            error = detail.msg
+        return (True, fn, int(line), index, code, error, [])
+    except ValueError as detail:
+        index = 0
+        code = ""
+        try:
+            fn = detail.filename
+            line = detail.lineno
+            error = detail.msg
+        except AttributeError:
+            fn = filename
+            line = 1
+            error = str(detail)
+        return (True, fn, line, index, code, error, [])
+    except Exception as detail:
+        try:
+            fn = detail.filename
+            line = detail.lineno
+            index = 0
+            code = ""
+            error = detail.msg
+            return (True, fn, line, index, code, error, [])
+        except:         # this catchall is intentional
+            pass
+    
+    # pyflakes
+    if not checkFlakes:
+        return (False, "", -1, -1, "", "", [])
+    
+    strings = []
+    lines = codestring.splitlines()
+    try:
+        warnings = Checker(module, filename)
+        warnings.messages.sort(key=lambda a: a.lineno)
+        for warning in warnings.messages:
+            if ignoreStarImportWarnings and \
+                    isinstance(warning, ImportStarUsed):
+                continue
+            
+            _fn, lineno, message, msg_args = warning.getMessageData()
+            if "__IGNORE_WARNING__" not in extractLineFlags(
+                    lines[lineno - 1].strip()):
+                strings.append([
+                    "FLAKES_WARNING", _fn, lineno, message, msg_args])
+    except SyntaxError as err:
+        if err.text.strip():
+            msg = err.text.strip()
+        else:
+            msg = err.msg
+        strings.append(["FLAKES_ERROR", filename, err.lineno, msg, ()])
+    
+    return (False, "", -1, -1, "", "", strings)
--- a/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py	Sun Dec 15 11:50:18 2013 +0100
+++ b/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py	Tue Dec 31 18:03:31 2013 +0100
@@ -66,6 +66,9 @@
         self.checkProgressLabel.setVisible(False)
         self.checkProgressLabel.setMaximumWidth(600)
         
+        self.backgroundService = e5App().getObject('BackgroundService')
+        self.backgroundService.syntaxChecked.connect(self.processResult)
+        
     def __resort(self):
         """
         Private method to resort the tree.
@@ -135,7 +138,7 @@
         @param fn file or list of files or directory to be checked
                 (string or list of strings)
         @param codestring string containing the code to be checked (string).
-            If this is given, file must be a single file name.
+            If this is given, fn must be a single file name.
         """
         if self.__project is None:
             self.__project = e5App().getObject("Project")
@@ -150,88 +153,127 @@
         self.__clearErrors()
         
         if isinstance(fn, list):
-            files = fn
+            self.files = fn
         elif os.path.isdir(fn):
-            files = []
+            self.files = []
             extensions = set(Preferences.getPython("PythonExtensions") +
                              Preferences.getPython("Python3Extensions"))
             for ext in extensions:
-                files.extend(
+                self.files.extend(
                     Utilities.direntries(fn, True, '*{0}'.format(ext), 0))
         else:
-            files = [fn]
+            self.files = [fn]
         
-        if codestring or len(files) > 0:
-            self.checkProgress.setMaximum(max(1, len(files)))
-            self.checkProgress.setVisible(len(files) > 1)
-            self.checkProgressLabel.setVisible(len(files) > 1)
+        if codestring or len(self.files) > 0:
+            self.checkProgress.setMaximum(max(1, len(self.files)))
+            self.checkProgress.setVisible(len(self.files) > 1)
+            self.checkProgressLabel.setVisible(len(self.files) > 1)
             QApplication.processEvents()
+
+            self.checkFlakes = Preferences.getFlakes("IncludeInSyntaxCheck")
+            self.ignoreStarImportWarnings = Preferences.getFlakes(
+                "IgnoreStarImportWarnings")
             
             # now go through all the files
-            progress = 0
-            for file in files:
-                self.checkProgress.setValue(progress)
-                self.checkProgressLabel.setPath(file)
-                QApplication.processEvents()
-                self.__resort()
-                
-                if self.cancelled:
-                    return
-                
-                self.__lastFileItem = None
-                
-                if codestring:
-                    source = codestring
-                else:
-                    try:
-                        source = Utilities.readEncodedFile(file)[0]
-                        source = Utilities.normalizeCode(source)
-                    except (UnicodeError, IOError) as msg:
-                        self.noResults = False
-                        self.__createResultItem(
-                            file, 1, 0,
-                            self.trUtf8("Error: {0}").format(str(msg))
-                            .rstrip()[1:-1], "")
-                        progress += 1
-                        continue
+            self.progress = 0
+            self.check(codestring)
+    
+    def check(self, codestring=''):
+        """
+        Start a check for one file.
+        
+        The results are reported to the processResult slot.
+        @param codestring optional sourcestring (str)
+        """
+        self.filename = self.files.pop(0)
+        self.checkProgress.setValue(self.progress)
+        self.checkProgressLabel.setPath(self.filename)
+        QApplication.processEvents()
+        self.__resort()
+        
+        if self.cancelled:  # ???
+            return
+        
+        self.__lastFileItem = None
+        
+        if codestring:
+            self.source = codestring
+        else:
+            try:
+                self.source = Utilities.readEncodedFile(self.filename)[0]
+                self.source = Utilities.normalizeCode(self.source)
+            except (UnicodeError, IOError) as msg:
+                self.noResults = False
+                self.__createResultItem(
+                    self.filename, 1, 0,
+                    self.trUtf8("Error: {0}").format(str(msg))
+                    .rstrip()[1:-1], "")
+                self.progress += 1
+                # Continue with next file
+                self.check()
+                return
+        
+        self.backgroundService.syntaxCheck(
+            self.filename, self.source, self.checkFlakes,
+            self.ignoreStarImportWarnings)
+
+    def processResult(
+            self, fn, nok, fname, line, index, code, error, warnings):
+        """
+        Slot which reports the resulting messages.
+        
+        If checkFlakes is True, warnings contains a list of strings containing
+        the warnings (marker, file name, line number, message)
+        The values are only valid, if nok is False.
+        
+        @param fn filename of the checked file (str)
+        @param nok flag if an error in the source was found (boolean)
+        @param fname filename of the checked file (str)  # TODO: remove dubl.
+        @param line number where the error occured (int)
+        @param index the column where the error occured (int)
+        @param code the part of the code where the error occured (str)
+        @param error the name of the error (str)
+        @param warnings a list of strings containing the warnings
+            (marker, file name, line number, message)
+        """
+        # Check if it's the requested file, otherwise ignore signal
+        if fn != self.filename:
+            return
+        
+        if nok:
+            self.noResults = False
+            self.__createResultItem(
+                fname, line, index, error, code.strip(), False)
+        else:
+            source = self.source.splitlines()
+            for warning in warnings:
+                # TODO: Move to BackgroundService
+                # Translate messages
+                msg_args = warning.pop()
+                translated = QApplication.translate(
+                    'py3Flakes', warning[-1]).format(*msg_args)
+                # Avoid leading "u" at Python2 unicode strings
+                if translated.startswith("u'"):
+                    translated = translated[1:]
+                warning[3] = translated.replace(" u'", " '")
                 
-                flags = Utilities.extractFlags(source)
-                ext = os.path.splitext(file)[1]
-                if "FileType" in flags:
-                    isPy2 = flags["FileType"] in ["Python", "Python2"]
-                elif (Preferences.getProject("DeterminePyFromProject") and
-                      self.__project.isOpen() and
-                      self.__project.isProjectFile(file)):
-                            isPy2 = self.__project.getProjectLanguage() in \
-                                ["Python", "Python2"]
-                else:
-                    isPy2 = flags.get("FileType") in ["Python", "Python2"] or \
-                        ext in Preferences.getPython("PythonExtensions")
-                
-                nok, fname, line, index, code, error, warnings = \
-                    Utilities.compile(file, source, isPy2)
-                if nok:
-                    self.noResults = False
-                    self.__createResultItem(
-                        fname, line, index, error, code.strip(), False)
-                else:
-                    source = source.splitlines()
-                    for warning in warnings:
-                        self.noResults = False
-                        scr_line = source[warning[2] - 1].strip()
-                        self.__createResultItem(
-                            warning[1], warning[2], 0,
-                            warning[3], scr_line, True)
+                self.noResults = False
+                scr_line = source[warning[2] - 1].strip()
+                self.__createResultItem(
+                    warning[1], warning[2], 0,
+                    warning[3], scr_line, True)
+        self.progress += 1
+        self.checkProgress.setValue(self.progress)
+        self.checkProgressLabel.setPath("")
+        QApplication.processEvents()
+        self.__resort()
 
-                progress += 1
-            self.checkProgress.setValue(progress)
-            self.checkProgressLabel.setPath("")
-            QApplication.processEvents()
-            self.__resort()
+        if self.files:
+            self.check()
         else:
             self.checkProgress.setMaximum(1)
             self.checkProgress.setValue(1)
-        self.__finish()
+            self.__finish()
         
     def __finish(self):
         """
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/__init__.py	Tue Dec 31 18:03:31 2013 +0100
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2010 - 2013 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Package containg the pyflakes Python2 port adapted for Qt.
+"""
+
+""" License
+Copyright 2005-2011 Divmod, Inc.
+Copyright 2013 Florent Xicluna
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""
+
+""" Changes
+0.6.1 (2013-01-29):
+  - Fix detection of variables in augmented assignments.
+
+0.6.0 (2013-01-29):
+  - Support Python 3 up to 3.3, based on the pyflakes3k project.
+  - Preserve compatibility with Python 2.5 and all recent versions of Python.
+  - Support custom reporters in addition to the default Reporter.
+  - Allow function redefinition for modern property construction via
+    property.setter/deleter.
+  - Fix spurious redefinition warnings in conditionals.
+  - Do not report undefined name in __all__ if import * is used.
+  - Add WindowsError as a known built-in name on all platforms.
+  - Support specifying additional built-ins in the `Checker` constructor.
+  - Don't issue Unused Variable warning when using locals() in current scope.
+  - Handle problems with the encoding of source files.
+  - Remove dependency on Twisted for the tests.
+  - Support `python setup.py test` and `python setup.py develop`.
+  - Create script using setuptools `entry_points` to support all platforms,
+    including Windows.
+
+0.5.0 (2011-09-02):
+  - Convert pyflakes to use newer _ast infrastructure rather than compiler.
+  - Support for new syntax in 2.7 (including set literals, set comprehensions,
+    and dictionary comprehensions).
+  - Make sure class names don't get bound until after class definition.
+"""
+
+__version__ = '0.6.1'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/checker.py	Tue Dec 31 18:03:31 2013 +0100
@@ -0,0 +1,711 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2010 - 2013 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+# Original (c) 2005-2010 Divmod, Inc.
+#
+# This module is based on pyflakes for Python2 but was modified to
+# work with eric5
+
+import os.path
+try:
+    import builtins
+    PY2 = False
+except ImportError:
+    import __builtin__ as builtins      #__IGNORE_WARNING__
+    PY2 = True
+
+try:
+    import ast
+    iter_child_nodes = ast.iter_child_nodes
+except (ImportError, AttributeError):   # Python 2.5
+    import _ast as ast
+
+    def iter_child_nodes(node, astcls=ast.AST):
+        """
+        Yield all direct child nodes of *node*, that is, all fields that are nodes
+        and all items of fields that are lists of nodes.
+        """
+        for name in node._fields:
+            field = getattr(node, name, None)
+            if isinstance(field, astcls):
+                yield field
+            elif isinstance(field, list):
+                for item in field:
+                    yield item
+# Python >= 3.3 uses ast.Try instead of (ast.TryExcept + ast.TryFinally)
+if hasattr(ast, 'Try'):
+    ast_TryExcept = ast.Try
+    ast_TryFinally = ()
+else:
+    ast_TryExcept = ast.TryExcept
+    ast_TryFinally = ast.TryFinally
+
+from . import messages
+
+
+class Binding(object):
+    """
+    Represents the binding of a value to a name.
+
+    The checker uses this to keep track of which names have been bound and
+    which names have not. See L{Assignment} for a special type of binding that
+    is checked with stricter rules.
+    """
+
+    def __init__(self, name, source):
+        self.name = name
+        self.source = source
+        self.used = False
+
+    def __str__(self):
+        return self.name
+
+    def __repr__(self):
+        return '<%s object %r from line %r at 0x%x>' % (self.__class__.__name__,
+                                                        self.name,
+                                                        self.source.lineno,
+                                                        id(self))
+
+
+class UnBinding(Binding):
+    """Created by the 'del' operator."""
+
+
+class Importation(Binding):
+    """
+    A binding created by an import statement.
+    """
+    def __init__(self, name, source):
+        self.fullName = name
+        name = name.split('.')[0]
+        super(Importation, self).__init__(name, source)
+
+
+class Argument(Binding):
+    """
+    Represents binding a name as an argument.
+    """
+
+
+class Definition(Binding):
+    """
+    A binding that defines a function or a class.
+    """
+
+
+class Assignment(Binding):
+    """
+    Represents binding a name with an explicit assignment.
+
+    The checker will raise warnings for any Assignment that isn't used. Also,
+    the checker does not consider assignments in tuple/list unpacking to be
+    Assignments, rather it treats them as simple Bindings.
+    """
+
+
+class FunctionDefinition(Definition):
+    pass
+
+
+class ClassDefinition(Definition):
+    pass
+
+
+class ExportBinding(Binding):
+    """
+    A binding created by an C{__all__} assignment.  If the names in the list
+    can be determined statically, they will be treated as names for export and
+    additional checking applied to them.
+
+    The only C{__all__} assignment that can be recognized is one which takes
+    the value of a literal list containing literal strings.  For example::
+
+        __all__ = ["foo", "bar"]
+
+    Names which are imported and not otherwise used but appear in the value of
+    C{__all__} will not have an unused import warning reported for them.
+    """
+    def names(self):
+        """
+        Return a list of the names referenced by this binding.
+        """
+        names = []
+        if isinstance(self.source, ast.List):
+            for node in self.source.elts:
+                if isinstance(node, ast.Str):
+                    names.append(node.s)
+        return names
+
+
+class Scope(dict):
+    importStarred = False       # set to True when import * is found
+    usesLocals = False
+
+    def __repr__(self):
+        return '<%s at 0x%x %s>' % (self.__class__.__name__, id(self), dict.__repr__(self))
+
+
+class ClassScope(Scope):
+    pass
+
+
+class FunctionScope(Scope):
+    """
+    I represent a name scope for a function.
+    """
+    def __init__(self):
+        super(FunctionScope, self).__init__()
+        self.globals = {}
+
+
+class ModuleScope(Scope):
+    pass
+
+
+# Globally defined names which are not attributes of the builtins module, or
+# are only present on some platforms.
+_MAGIC_GLOBALS = ['__file__', '__builtins__', 'WindowsError']
+
+
+def getNodeName(node):
+    # Returns node.id, or node.name, or None
+    if hasattr(node, 'id'):     # One of the many nodes with an id
+        return node.id
+    if hasattr(node, 'name'):   # a ExceptHandler node
+        return node.name
+
+
+class Checker(object):
+    """
+    I check the cleanliness and sanity of Python code.
+    """
+
+    nodeDepth = 0
+    traceTree = False
+    builtIns = set(dir(builtins)) | set(_MAGIC_GLOBALS)
+
+    def __init__(self, tree, filename='(none)', builtins=None):
+        self._deferredFunctions = []
+        self._deferredAssignments = []
+        self.deadScopes = []
+        self.messages = []
+        self.filename = filename
+        if builtins:
+            self.builtIns = self.builtIns.union(builtins)
+        self.scopeStack = [ModuleScope()]
+        self.futuresAllowed = True
+        self.root = tree
+        self.handleChildren(tree)
+        self.runDeferred(self._deferredFunctions)
+        # Set _deferredFunctions to None so that deferFunction will fail
+        # noisily if called after we've run through the deferred functions.
+        self._deferredFunctions = None
+        self.runDeferred(self._deferredAssignments)
+        # Set _deferredAssignments to None so that deferAssignment will fail
+        # noisily if called after we've run through the deferred assignments.
+        self._deferredAssignments = None
+        del self.scopeStack[1:]
+        self.popScope()
+        self.checkDeadScopes()
+
+    def deferFunction(self, callable):
+        """
+        Schedule a function handler to be called just before completion.
+
+        This is used for handling function bodies, which must be deferred
+        because code later in the file might modify the global scope. When
+        `callable` is called, the scope at the time this is called will be
+        restored, however it will contain any new bindings added to it.
+        """
+        self._deferredFunctions.append((callable, self.scopeStack[:]))
+
+    def deferAssignment(self, callable):
+        """
+        Schedule an assignment handler to be called just after deferred
+        function handlers.
+        """
+        self._deferredAssignments.append((callable, self.scopeStack[:]))
+
+    def runDeferred(self, deferred):
+        """
+        Run the callables in C{deferred} using their associated scope stack.
+        """
+        for handler, scope in deferred:
+            self.scopeStack = scope
+            handler()
+
+    @property
+    def scope(self):
+        return self.scopeStack[-1]
+
+    def popScope(self):
+        self.deadScopes.append(self.scopeStack.pop())
+
+    def checkDeadScopes(self):
+        """
+        Look at scopes which have been fully examined and report names in them
+        which were imported but unused.
+        """
+        for scope in self.deadScopes:
+            export = isinstance(scope.get('__all__'), ExportBinding)
+            if export:
+                all = scope['__all__'].names()
+                if not scope.importStarred and os.path.basename(self.filename) != '__init__.py':
+                    # Look for possible mistakes in the export list
+                    undefined = set(all) - set(scope)
+                    for name in undefined:
+                        self.report(messages.UndefinedExport,
+                                    scope['__all__'].source.lineno, name)
+            else:
+                all = []
+
+            # Look for imported names that aren't used.
+            for importation in scope.values():
+                if isinstance(importation, Importation):
+                    if not importation.used and importation.name not in all:
+                        self.report(messages.UnusedImport,
+                                    importation.source.lineno, importation.name)
+
+    def pushFunctionScope(self):
+        self.scopeStack.append(FunctionScope())
+
+    def pushClassScope(self):
+        self.scopeStack.append(ClassScope())
+
+    def report(self, messageClass, *args, **kwargs):
+        self.messages.append(messageClass(self.filename, *args, **kwargs))
+
+    def hasParent(self, node, kind):
+        while hasattr(node, 'parent'):
+            node = node.parent
+            if isinstance(node, kind):
+                return True
+
+    def getCommonAncestor(self, lnode, rnode, stop=None):
+        if not stop:
+            stop = self.root
+        if lnode is rnode:
+            return lnode
+        if stop in (lnode, rnode):
+            return stop
+
+        if not hasattr(lnode, 'parent') or not hasattr(rnode, 'parent'):
+            return
+        if (lnode.level > rnode.level):
+            return self.getCommonAncestor(lnode.parent, rnode, stop)
+        if (rnode.level > lnode.level):
+            return self.getCommonAncestor(lnode, rnode.parent, stop)
+        return self.getCommonAncestor(lnode.parent, rnode.parent, stop)
+
+    def descendantOf(self, node, ancestors, stop=None):
+        for a in ancestors:
+            if self.getCommonAncestor(node, a, stop) not in (stop, None):
+                return True
+        return False
+
+    def onFork(self, parent, lnode, rnode, items):
+        return (self.descendantOf(lnode, items, parent) ^
+                self.descendantOf(rnode, items, parent))
+
+    def differentForks(self, lnode, rnode):
+        """True, if lnode and rnode are located on different forks of IF/TRY"""
+        ancestor = self.getCommonAncestor(lnode, rnode)
+        if isinstance(ancestor, ast.If):
+            for fork in (ancestor.body, ancestor.orelse):
+                if self.onFork(ancestor, lnode, rnode, fork):
+                    return True
+        elif isinstance(ancestor, ast_TryExcept):
+            body = ancestor.body + ancestor.orelse
+            for fork in [body] + [[hdl] for hdl in ancestor.handlers]:
+                if self.onFork(ancestor, lnode, rnode, fork):
+                    return True
+        elif isinstance(ancestor, ast_TryFinally):
+            if self.onFork(ancestor, lnode, rnode, ancestor.body):
+                return True
+        return False
+
+    def addBinding(self, node, value, reportRedef=True):
+        """
+        Called when a binding is altered.
+
+        - `node` is the statement responsible for the change
+        - `value` is the optional new value, a Binding instance, associated
+          with the binding; if None, the binding is deleted if it exists.
+        - if `reportRedef` is True (default), rebinding while unused will be
+          reported.
+        """
+        redefinedWhileUnused = False
+        if not isinstance(self.scope, ClassScope):
+            for scope in self.scopeStack[::-1]:
+                existing = scope.get(value.name)
+                if (isinstance(existing, Importation)
+                        and not existing.used
+                        and (not isinstance(value, Importation) or value.fullName == existing.fullName)
+                        and reportRedef
+                        and not self.differentForks(node, existing.source)):
+                    redefinedWhileUnused = True
+                    self.report(messages.RedefinedWhileUnused,
+                                node.lineno, value.name, existing.source.lineno)
+
+        existing = self.scope.get(value.name)
+        if not redefinedWhileUnused and self.hasParent(value.source, ast.ListComp):
+            if (existing and reportRedef
+                    and not self.hasParent(existing.source, (ast.For, ast.ListComp))):
+                self.report(messages.RedefinedInListComp,
+                            node.lineno, value.name, existing.source.lineno)
+
+        if isinstance(value, UnBinding):
+            try:
+                del self.scope[value.name]
+            except KeyError:
+                self.report(messages.UndefinedName, node.lineno, value.name)
+        elif (isinstance(existing, Definition)
+              and not existing.used
+              and not self.differentForks(node, existing.source)):
+            self.report(messages.RedefinedWhileUnused,
+                        node.lineno, value.name, existing.source.lineno)
+        else:
+            self.scope[value.name] = value
+
+    def handleNodeLoad(self, node):
+        name = getNodeName(node)
+        if not name:
+            return
+        # try local scope
+        importStarred = self.scope.importStarred
+        try:
+            self.scope[name].used = (self.scope, node.lineno)
+        except KeyError:
+            pass
+        else:
+            return
+
+        # try enclosing function scopes
+        for scope in self.scopeStack[-2:0:-1]:
+            importStarred = importStarred or scope.importStarred
+            if not isinstance(scope, FunctionScope):
+                continue
+            try:
+                scope[name].used = (self.scope, node.lineno)
+            except KeyError:
+                pass
+            else:
+                return
+
+        # try global scope
+        importStarred = importStarred or self.scopeStack[0].importStarred
+        try:
+            self.scopeStack[0][name].used = (self.scope, node.lineno)
+        except KeyError:
+            if not importStarred and name not in self.builtIns:
+                if (os.path.basename(self.filename) == '__init__.py' and name == '__path__'):
+                    # the special name __path__ is valid only in packages
+                    pass
+                else:
+                    self.report(messages.UndefinedName, node.lineno, name)
+
+    def handleNodeStore(self, node):
+        name = getNodeName(node)
+        if not name:
+            return
+        # if the name hasn't already been defined in the current scope
+        if isinstance(self.scope, FunctionScope) and name not in self.scope:
+            # for each function or module scope above us
+            for scope in self.scopeStack[:-1]:
+                if not isinstance(scope, (FunctionScope, ModuleScope)):
+                    continue
+                # if the name was defined in that scope, and the name has
+                # been accessed already in the current scope, and hasn't
+                # been declared global
+                if (name in scope and scope[name].used and scope[name].used[0] is self.scope
+                        and name not in self.scope.globals):
+                    # then it's probably a mistake
+                    self.report(messages.UndefinedLocal,
+                                scope[name].used[1], name, scope[name].source.lineno)
+                    break
+
+        parent = getattr(node, 'parent', None)
+        if isinstance(parent, (ast.For, ast.comprehension, ast.Tuple, ast.List)):
+            binding = Binding(name, node)
+        elif parent is not None and name == '__all__' and isinstance(self.scope, ModuleScope):
+            binding = ExportBinding(name, parent.value)
+        else:
+            binding = Assignment(name, node)
+        if name in self.scope:
+            binding.used = self.scope[name].used
+        self.addBinding(node, binding)
+
+    def handleNodeDelete(self, node):
+        name = getNodeName(node)
+        if not name:
+            return
+        if isinstance(self.scope, FunctionScope) and name in self.scope.globals:
+            del self.scope.globals[name]
+        else:
+            self.addBinding(node, UnBinding(name, node))
+
+    def handleChildren(self, tree):
+        for node in iter_child_nodes(tree):
+            self.handleNode(node, tree)
+
+    def isDocstring(self, node):
+        """
+        Determine if the given node is a docstring, as long as it is at the
+        correct place in the node tree.
+        """
+        return isinstance(node, ast.Str) or (isinstance(node, ast.Expr) and
+                                             isinstance(node.value, ast.Str))
+
+    def handleNode(self, node, parent):
+        if node is None:
+            return
+        node.parent = parent
+        if self.traceTree:
+            print('  ' * self.nodeDepth + node.__class__.__name__)
+        self.nodeDepth += 1
+        if self.futuresAllowed and not (isinstance(node, ast.ImportFrom) or
+                                        self.isDocstring(node)):
+            self.futuresAllowed = False
+        nodeType = node.__class__.__name__.upper()
+        node.level = self.nodeDepth
+        try:
+            handler = getattr(self, nodeType)
+            handler(node)
+        finally:
+            self.nodeDepth -= 1
+        if self.traceTree:
+            print('  ' * self.nodeDepth + 'end ' + node.__class__.__name__)
+
+    def ignore(self, node):
+        pass
+
+    # "stmt" type nodes
+    RETURN = DELETE = PRINT = WHILE = IF = WITH = WITHITEM = RAISE = \
+        TRYEXCEPT = TRYFINALLY = TRY = ASSERT = EXEC = EXPR = handleChildren
+
+    CONTINUE = BREAK = PASS = ignore
+
+    # "expr" type nodes
+    BOOLOP = BINOP = UNARYOP = IFEXP = DICT = SET = YIELD = YIELDFROM = \
+        COMPARE = CALL = REPR = ATTRIBUTE = SUBSCRIPT = LIST = TUPLE = \
+        STARRED = handleChildren
+
+    NUM = STR = BYTES = ELLIPSIS = ignore
+
+    # "slice" type nodes
+    SLICE = EXTSLICE = INDEX = handleChildren
+
+    # expression contexts are node instances too, though being constants
+    LOAD = STORE = DEL = AUGLOAD = AUGSTORE = PARAM = ignore
+
+    # same for operators
+    AND = OR = ADD = SUB = MULT = DIV = MOD = POW = LSHIFT = RSHIFT = \
+        BITOR = BITXOR = BITAND = FLOORDIV = INVERT = NOT = UADD = USUB = \
+        EQ = NOTEQ = LT = LTE = GT = GTE = IS = ISNOT = IN = NOTIN = ignore
+
+    # additional node types
+    COMPREHENSION = KEYWORD = handleChildren
+
+    def GLOBAL(self, node):
+        """
+        Keep track of globals declarations.
+        """
+        if isinstance(self.scope, FunctionScope):
+            self.scope.globals.update(dict.fromkeys(node.names))
+
+    NONLOCAL = GLOBAL
+
+    def LISTCOMP(self, node):
+        # handle generators before element
+        for gen in node.generators:
+            self.handleNode(gen, node)
+        self.handleNode(node.elt, node)
+
+    GENERATOREXP = SETCOMP = LISTCOMP
+
+    def DICTCOMP(self, node):
+        for gen in node.generators:
+            self.handleNode(gen, node)
+        self.handleNode(node.key, node)
+        self.handleNode(node.value, node)
+
+    def FOR(self, node):
+        """
+        Process bindings for loop variables.
+        """
+        vars = []
+
+        def collectLoopVars(n):
+            if isinstance(n, ast.Name):
+                vars.append(n.id)
+            elif isinstance(n, ast.expr_context):
+                return
+            else:
+                for c in iter_child_nodes(n):
+                    collectLoopVars(c)
+
+        collectLoopVars(node.target)
+        for varn in vars:
+            if (isinstance(self.scope.get(varn), Importation)
+                    # unused ones will get an unused import warning
+                    and self.scope[varn].used):
+                self.report(messages.ImportShadowedByLoopVar,
+                            node.lineno, varn, self.scope[varn].source.lineno)
+
+        self.handleChildren(node)
+
+    def NAME(self, node):
+        """
+        Handle occurrence of Name (which can be a load/store/delete access.)
+        """
+        if node.id == 'locals' and isinstance(node.parent, ast.Call):
+            # we are doing locals() call in current scope
+            self.scope.usesLocals = True
+        # Locate the name in locals / function / globals scopes.
+        if isinstance(node.ctx, (ast.Load, ast.AugLoad)):
+            self.handleNodeLoad(node)
+        elif isinstance(node.ctx, (ast.Store, ast.AugStore)):
+            self.handleNodeStore(node)
+        elif isinstance(node.ctx, ast.Del):
+            self.handleNodeDelete(node)
+        else:
+            # must be a Param context -- this only happens for names in function
+            # arguments, but these aren't dispatched through here
+            raise RuntimeError("Got impossible expression context: %r" % (node.ctx,))
+
+    def FUNCTIONDEF(self, node):
+        if not hasattr(node, 'decorator_list'):   # Python 2.5
+            node.decorator_list = node.decorators
+        for deco in node.decorator_list:
+            self.handleNode(deco, node)
+        self.addBinding(node, FunctionDefinition(node.name, node))
+        self.LAMBDA(node)
+
+    def LAMBDA(self, node):
+        args = []
+
+        if PY2:
+            def addArgs(arglist):
+                for arg in arglist:
+                    if isinstance(arg, ast.Tuple):
+                        addArgs(arg.elts)
+                    else:
+                        if arg.id in args:
+                            self.report(messages.DuplicateArgument,
+                                        node.lineno, arg.id)
+                        args.append(arg.id)
+            addArgs(node.args.args)
+            defaults = node.args.defaults
+        else:
+            for arg in node.args.args + node.args.kwonlyargs:
+                if arg.arg in args:
+                    self.report(messages.DuplicateArgument,
+                                node.lineno, arg.arg)
+                args.append(arg.arg)
+                self.handleNode(arg.annotation, node)
+            if hasattr(node, 'returns'):    # Only for FunctionDefs
+                for annotation in (node.args.varargannotation,
+                                   node.args.kwargannotation, node.returns):
+                    self.handleNode(annotation, node)
+            defaults = node.args.defaults + node.args.kw_defaults
+
+        # vararg/kwarg identifiers are not Name nodes
+        for wildcard in (node.args.vararg, node.args.kwarg):
+            if not wildcard:
+                continue
+            if wildcard in args:
+                self.report(messages.DuplicateArgument, node.lineno, wildcard)
+            args.append(wildcard)
+        for default in defaults:
+            self.handleNode(default, node)
+
+        def runFunction():
+
+            self.pushFunctionScope()
+            for name in args:
+                self.addBinding(node, Argument(name, node), reportRedef=False)
+            if isinstance(node.body, list):
+                # case for FunctionDefs
+                for stmt in node.body:
+                    self.handleNode(stmt, node)
+            else:
+                # case for Lambdas
+                self.handleNode(node.body, node)
+
+            def checkUnusedAssignments():
+                """
+                Check to see if any assignments have not been used.
+                """
+                for name, binding in self.scope.items():
+                    if (not binding.used and name not in self.scope.globals
+                            and not self.scope.usesLocals
+                            and isinstance(binding, Assignment)):
+                        self.report(messages.UnusedVariable,
+                                    binding.source.lineno, name)
+            self.deferAssignment(checkUnusedAssignments)
+            self.popScope()
+
+        self.deferFunction(runFunction)
+
+    def CLASSDEF(self, node):
+        """
+        Check names used in a class definition, including its decorators, base
+        classes, and the body of its definition.  Additionally, add its name to
+        the current scope.
+        """
+        # no class decorator in Python 2.5
+        for deco in getattr(node, 'decorator_list', ''):
+            self.handleNode(deco, node)
+        for baseNode in node.bases:
+            self.handleNode(baseNode, node)
+        if not PY2:
+            for keywordNode in node.keywords:
+                self.handleNode(keywordNode, node)
+        self.pushClassScope()
+        for stmt in node.body:
+            self.handleNode(stmt, node)
+        self.popScope()
+        self.addBinding(node, ClassDefinition(node.name, node))
+
+    def ASSIGN(self, node):
+        self.handleNode(node.value, node)
+        for target in node.targets:
+            self.handleNode(target, node)
+
+    def AUGASSIGN(self, node):
+        self.handleNodeLoad(node.target)
+        self.handleNode(node.value, node)
+        self.handleNode(node.target, node)
+
+    def IMPORT(self, node):
+        for alias in node.names:
+            name = alias.asname or alias.name
+            importation = Importation(name, node)
+            self.addBinding(node, importation)
+
+    def IMPORTFROM(self, node):
+        if node.module == '__future__':
+            if not self.futuresAllowed:
+                self.report(messages.LateFutureImport,
+                            node.lineno, [n.name for n in node.names])
+        else:
+            self.futuresAllowed = False
+
+        for alias in node.names:
+            if alias.name == '*':
+                self.scope.importStarred = True
+                self.report(messages.ImportStarUsed, node.lineno, node.module)
+                continue
+            name = alias.asname or alias.name
+            importation = Importation(name, node)
+            if node.module == '__future__':
+                importation.used = (self.scope, node.lineno)
+            self.addBinding(node, importation)
+
+    def EXCEPTHANDLER(self, node):
+        # 3.x: in addition to handling children, we must handle the name of
+        # the exception, which is not a Name node, but a simple string.
+        if isinstance(node.name, str):
+            self.handleNodeStore(node)
+        self.handleChildren(node)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/messages.py	Tue Dec 31 18:03:31 2013 +0100
@@ -0,0 +1,298 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2010 - 2013 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+# Original (c) 2005 Divmod, Inc.  See LICENSE file for details
+#
+# This module is based on pyflakes for Python2 but was heavily hacked to
+# work within Eric5 and Qt (translatable messages)
+
+"""
+Module implementing the messages for pyflakes.
+"""
+
+# Tell 'lupdate' which strings to keep for translation.
+QT_TRANSLATE_NOOP = lambda mod, txt: txt
+
+
+class Message(object):
+    """
+    Class defining the base for all specific message classes.
+    """
+    message = ''
+    message_args = ()
+    
+    def __init__(self, filename, lineno):
+        """
+        Constructor
+        
+        @param filename name of the file (string)
+        @param lineno line number (integer)
+        """
+        self.filename = filename
+        self.lineno = lineno
+    
+    def __str__(self):
+        """
+        Special method return a string representation of the instance object.
+        
+        @return string representation of the object (string)
+        """
+        return '%s:%s: %s' % (
+            self.filename, self.lineno, self.message % self.message_args)
+    
+    def getMessageData(self):
+        """
+        Public method to get the individual message data elements.
+        
+        @return tuple containing file name, line number and message
+            (string, integer, string)
+        """
+        return (self.filename, self.lineno, self.message, self.message_args)
+
+
+class UnusedImport(Message):
+    """
+    Class defining the "Unused Import" message.
+    """
+    message = QT_TRANSLATE_NOOP(
+        'py3Flakes',
+        '{0!r} imported but unused.')
+    
+    def __init__(self, filename, lineno, name):
+        """
+        Constructor
+        
+        @param filename name of the file (string)
+        @param lineno line number (integer)
+        @param name name of the unused import (string)
+        """
+        Message.__init__(self, filename, lineno)
+        self.message_args = (name,)
+
+
+class RedefinedWhileUnused(Message):
+    """
+    Class defining the "Redefined While Unused" message.
+    """
+    message = QT_TRANSLATE_NOOP(
+        'py3Flakes',
+        'Redefinition of unused {0!r} from line {1!r}.')
+
+    def __init__(self, filename, lineno, name, orig_lineno):
+        """
+        Constructor
+        
+        @param filename name of the file (string)
+        @param lineno line number (integer)
+        @param name name of the redefined object (string)
+        @param orig_lineno line number of the original definition (integer)
+        """
+        Message.__init__(self, filename, lineno)
+        self.message_args = (name, orig_lineno)
+
+
+class RedefinedInListComp(Message):
+    """
+    Class defining the list comprehension redefinition.
+    """
+    message = QT_TRANSLATE_NOOP(
+        'py3Flakes',
+        'List comprehension redefines {0!r} from line {1!r}.')
+
+    def __init__(self, filename, lineno, name, orig_lineno):
+        """
+        Constructor
+        
+        @param filename name of the file (string)
+        @param lineno line number (integer)
+        @param name name of the redefined object (string)
+        @param orig_lineno line number of the original definition (integer)
+        """
+        Message.__init__(self, filename, lineno)
+        self.message_args = (name, orig_lineno)
+
+
+class ImportShadowedByLoopVar(Message):
+    """
+    Class defining the "Import Shadowed By Loop Var" message.
+    """
+    message = QT_TRANSLATE_NOOP(
+        'py3Flakes',
+        'Import {0!r} from line {1!r} shadowed by loop variable.')
+    
+    def __init__(self, filename, lineno, name, orig_lineno):
+        """
+        Constructor
+        
+        @param filename name of the file (string)
+        @param lineno line number (integer)
+        @param name name of the shadowed import (string)
+        @param orig_lineno line number of the import (integer)
+        """
+        Message.__init__(self, filename, lineno)
+        self.message_args = (name, orig_lineno)
+
+
+class ImportStarUsed(Message):
+    """
+    Class defining the "Import Star Used" message.
+    """
+    message = QT_TRANSLATE_NOOP(
+        'py3Flakes',
+        "'from {0} import *' used; unable to detect undefined names.")
+    
+    def __init__(self, filename, lineno, modname):
+        """
+        Constructor
+        
+        @param filename name of the file (string)
+        @param lineno line number (integer)
+        @param modname name of the module imported using star import (string)
+        """
+        Message.__init__(self, filename, lineno)
+        self.message_args = (modname,)
+
+
+class UndefinedName(Message):
+    """
+    Class defining the "Undefined Name" message.
+    """
+    message = QT_TRANSLATE_NOOP('py3Flakes', 'Undefined name {0!r}.')
+    
+    def __init__(self, filename, lineno, name):
+        """
+        Constructor
+        
+        @param filename name of the file (string)
+        @param lineno line number (integer)
+        @param name undefined name (string)
+        """
+        Message.__init__(self, filename, lineno)
+        self.message_args = (name,)
+
+
+class UndefinedExport(Message):
+    """
+    Class defining the "Undefined Export" message.
+    """
+    message = QT_TRANSLATE_NOOP(
+        'py3Flakes',
+        'Undefined name {0!r} in __all__.')
+    
+    def __init__(self, filename, lineno, name):
+        """
+        Constructor
+        
+        @param filename name of the file (string)
+        @param lineno line number (integer)
+        @param name undefined exported name (string)
+        """
+        Message.__init__(self, filename, lineno)
+        self.message_args = (name,)
+
+
+class UndefinedLocal(Message):
+    """
+    Class defining the "Undefined Local Variable" message.
+    """
+    message = QT_TRANSLATE_NOOP(
+        'py3Flakes',
+        "Local variable {0!r} (defined in enclosing scope on line {1!r})"
+        " referenced before assignment.")
+    
+    def __init__(self, filename, lineno, name, orig_lineno):
+        """
+        Constructor
+        
+        @param filename name of the file (string)
+        @param lineno line number (integer)
+        @param name name of the prematurely referenced variable (string)
+        @param orig_lineno line number of the variable definition (integer)
+        """
+        Message.__init__(self, filename, lineno)
+        self.message_args = (name, orig_lineno)
+
+
+class DuplicateArgument(Message):
+    """
+    Class defining the "Duplicate Argument" message.
+    """
+    message = QT_TRANSLATE_NOOP(
+        'py3Flakes',
+        'Duplicate argument {0!r} in function definition.')
+    
+    def __init__(self, filename, lineno, name):
+        """
+        Constructor
+        
+        @param filename name of the file (string)
+        @param lineno line number (integer)
+        @param name name of the duplicate argument (string)
+        """
+        Message.__init__(self, filename, lineno)
+        self.message_args = (name,)
+
+
+class Redefined(Message):
+    """
+    Class defining the "Redefined" message.
+    """
+    message = QT_TRANSLATE_NOOP(
+        'py3Flakes',
+        'Redefinition of {0!r} from line {1!r}.')
+    
+    def __init__(self, filename, lineno, name, orig_lineno):
+        """
+        Constructor
+        
+        @param filename name of the file (string)
+        @param lineno line number (integer)
+        @param name name of the redefined function (string)
+        @param orig_lineno line number of the original definition (integer)
+        """
+        Message.__init__(self, filename, lineno)
+        self.message_args = (name, orig_lineno)
+
+
+class LateFutureImport(Message):
+    """
+    Class defining the "Late Future Import" message.
+    """
+    message = QT_TRANSLATE_NOOP(
+        'py3Flakes',
+        'Future import(s) {0!r} after other statements.')
+    
+    def __init__(self, filename, lineno, names):
+        """
+        Constructor
+        
+        @param filename name of the file (string)
+        @param lineno line number (integer)
+        @param names names of the imported futures (string)
+        """
+        Message.__init__(self, filename, lineno)
+        self.message_args = (names,)
+
+
+class UnusedVariable(Message):
+    """
+    Class defining the "Unused Variable" message.
+    
+    Indicates that a variable has been explicitly assigned to but not actually
+    used.
+    """
+    message = QT_TRANSLATE_NOOP(
+        'py3Flakes',
+        'Local variable {0!r} is assigned to but never used.')
+    
+    def __init__(self, filename, lineno, names):
+        """
+        Constructor
+        
+        @param filename name of the file (string)
+        @param lineno line number (integer)
+        @param names names of the unused variable (string)
+        """
+        Message.__init__(self, filename, lineno)
+        self.message_args = (names,)
--- a/UI/UserInterface.py	Sun Dec 15 11:50:18 2013 +0100
+++ b/UI/UserInterface.py	Tue Dec 31 18:03:31 2013 +0100
@@ -202,6 +202,10 @@
         from Debugger.DebugServer import DebugServer
         debugServer = DebugServer()
         
+        # Create the background service object
+        from Utilities.BackgroundService import BackgroundService
+        self.backgroundService = BackgroundService()
+        
         # Generate an empty project object and multi project object
         from Project.Project import Project
         self.project = Project(self)
@@ -450,6 +454,7 @@
         e5App().registerObject("UserInterface", self)
         e5App().registerObject("DebugUI", self.debuggerUI)
         e5App().registerObject("DebugServer", debugServer)
+        e5App().registerObject("BackgroundService", self.backgroundService)
         e5App().registerObject("ViewManager", self.viewmanager)
         e5App().registerObject("Project", self.project)
         e5App().registerObject("ProjectBrowser", self.projectBrowser)
@@ -5741,6 +5746,8 @@
             return False
         self.debuggerUI.shutdown()
         
+        self.backgroundService.shutdown()
+        
         self.cooperation.shutdown()
         
         self.pluginManager.doShutdown()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Utilities/BackgroundClient.py	Tue Dec 31 18:03:31 2013 +0100
@@ -0,0 +1,130 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2013 - 2014 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a Qt free version of a background client for the various
+checkers and other python interpreter dependent functions.
+"""
+
+from __future__ import unicode_literals
+try:
+    bytes = unicode  #__IGNORE_WARNING__
+except NameError:
+    pass
+
+import json
+import os
+import socket
+import struct
+import sys
+from zlib import adler32
+
+if __name__ == '__main__':
+    # Add Eric basepath to sys.path to be able to import modules which are
+    # laying not only below Utilities
+    path = os.path.dirname(sys.argv[0])
+    path = os.path.dirname(path)
+    sys.path.append(path)
+
+from Plugins.CheckerPlugins.SyntaxChecker import SyntaxCheck
+
+
+class BackgroundClient(object):
+    """
+    Class implementing the main part of the background client.
+    """
+    def __init__(self, host, port):
+        """
+        Constructor of the BackgroundClient class.
+        
+        @param host ip address the background service is listening
+        @param port port of the background service
+        """
+        self.connection = socket.create_connection((host, port))
+        ver = b'2' if sys.version_info[0] == 2 else b'3'
+        self.connection.sendall(ver)
+        self.connection.settimeout(0.25)
+
+    def __send(self, fx, fn, data):
+        """
+        Private method to send a job response back to the BackgroundService.
+        
+        @param fx remote function name to execute (str)
+        @param fn filename for identification (str)
+        @param data return value(s) (any basic datatype)
+        """
+        packedData = json.dumps([fx, fn, data])
+        if sys.version_info[0] == 3:
+            packedData = bytes(packedData, 'utf-8')
+        header = struct.pack(
+            b'!II', len(packedData), adler32(packedData) & 0xffffffff)
+        self.connection.sendall(header)
+        self.connection.sendall(packedData)
+
+    def run(self):
+        """
+        Implement the main loop of the client.
+        """
+        while True:
+            try:
+                header = self.connection.recv(8)  # __IGNORE_EXCEPTION__
+            except socket.timeout:
+                continue
+            except socket.error:
+                # Leave main loop if connection was closed.
+                break
+            # Leave main loop if connection was closed.
+            if not header:
+                break
+            
+            length, datahash = struct.unpack(b'!II', header)
+            
+            packedData = b''
+            while len(packedData) < length:
+                packedData += self.connection.recv(length - len(packedData))
+            
+            assert adler32(packedData) & 0xffffffff == datahash, \
+                'Hashes not equal'
+            if sys.version_info[0] == 3:
+                packedData = packedData.decode('utf-8')
+            fx, fn, data = json.loads(packedData)
+            if fx == 'syntax':
+                ret = SyntaxCheck.syntaxAndPyflakesCheck(fn, *data)
+            elif fx == 'style':
+                print(data)
+            elif fx == 'indent':
+                pass
+            else:
+                continue
+            
+            self.__send(fx, fn, ret)
+            
+        self.connection.close()
+        sys.exit()
+
+    def __unhandled_exception(self, exctype, excval, exctb):
+        """
+        Private method called to report an uncaught exception.
+        
+        @param exctype the type of the exception
+        @param excval data about the exception
+        @param exctb traceback for the exception
+        """
+        # TODO: Wrap arguments so they can be serialized by JSON
+        self.__send(
+            'exception', '?', [str(exctype), str(excval), str(exctb)])
+
+if __name__ == '__main__':
+    if len(sys.argv) != 3:
+        print('Host and port parameters are missing. Abort.')
+        sys.exit(1)
+    
+    host, port = sys.argv[1:]
+    backgroundClient = BackgroundClient(host, int(port))
+    # set the system exception handling function to ensure, that
+    # we report on all unhandled exceptions
+    sys.excepthook = backgroundClient._BackgroundClient__unhandled_exception
+    # Start the main loop
+    backgroundClient.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Utilities/BackgroundService.py	Tue Dec 31 18:03:31 2013 +0100
@@ -0,0 +1,248 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2013 - 2014 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a background service for the various checkers and other
+python interpreter dependent functions.
+"""
+
+from __future__ import unicode_literals
+
+import json
+import os
+import struct
+import sys
+import threading
+from zlib import adler32
+
+from PyQt4.QtCore import QProcess, pyqtSignal
+from PyQt4.QtGui import QApplication
+from PyQt4.QtNetwork import QTcpServer, QHostAddress
+
+from E5Gui.E5Application import e5App
+
+import Preferences
+import Utilities
+from Utilities.BackgroundClient import BackgroundClient
+
+from eric5config import getConfig
+
+
+class BackgroundService(QTcpServer):
+    """
+    Class implementing the main part of the background service.
+    """
+    syntaxChecked = pyqtSignal(str, bool, str, int, int, str, str, list)
+    #styleChecked = pyqtSignal(TBD)
+    #indentChecked = pyqtSignal(TBD)
+    
+    def __init__(self):
+        """
+        Constructor of the BackgroundService class.
+        """
+        self.processes = [None, None]
+        self.connections = [None, None]
+
+        super(BackgroundService, self).__init__()
+
+        networkInterface = Preferences.getDebugger("NetworkInterface")
+        if networkInterface == "all" or '.' in networkInterface:
+            self.hostAddress = '127.0.0.1'
+        else:
+            self.hostAddress = '::1'
+        self.listen(QHostAddress(self.hostAddress))
+
+        self.newConnection.connect(self.on_newConnection)
+        port = self.serverPort()
+        ## NOTE: Need the port if started external in debugger:
+        print('BackgroundService listening on: %i' % port)
+        for pyIdx, pyName in enumerate(['Python', 'Python3']):
+            interpreter = Preferences.getDebugger(
+                pyName + "Interpreter")
+            
+            if Utilities.samefilepath(interpreter, sys.executable):
+                process = self.__startInternalClient(port)
+            else:
+                process = self.__startExternalClient(interpreter, port)
+            self.processes[pyIdx] = process
+
+    def on_newConnection(self):
+        """
+        Slot for new incomming connections from the clients.
+        """
+        connection = self.nextPendingConnection()
+        if not connection.waitForReadyRead(1000):
+            return
+        ch = 0 if connection.read(1) == b'2' else 1
+        self.connections[ch] = connection
+        connection.readyRead.connect(
+            lambda x=ch: self.__receive(x))
+
+    def shutdown(self):
+        """
+        Cleanup the connections and processes when Eric is shuting down.
+        """
+        for connection in self.connections:
+            if connection:
+                connection.close()
+        
+        for process in self.processes:
+            if isinstance(process, QProcess):
+                process.close()
+                process = None
+            elif isinstance(process, threading.Thread):
+                process.join(0.1)
+                process = None
+
+    def __startExternalClient(self, interpreter, port):
+        """
+        Private method to start the background client as external process.
+        
+        @param interpreter path and name of the executable to start (string)
+        @param port socket port to which the interpreter should connect (int)
+        @return the process object (QProcess) or None
+        """
+        if interpreter == "" or not Utilities.isinpath(interpreter):
+            return None
+        
+        backgroundClient = os.path.join(
+            getConfig('ericDir'),
+            "Utilities", "BackgroundClient.py")
+        proc = QProcess()
+        args = [backgroundClient, self.hostAddress, str(port)]
+        proc.start(interpreter, args)
+        if not proc.waitForStarted(10000):
+            proc = None
+        return proc
+
+    def __startInternalClient(self, port):
+        """
+        Private method to start the background client as internal thread.
+        
+        @param port socket port to which the interpreter should connect (int)
+        @return the thread object (Thread) or None
+        """
+        self.backgroundClient = BackgroundClient(
+            self.hostAddress, port)
+        thread = threading.Thread(target=self.backgroundClient.run)
+        thread.start()
+        return thread
+
+    # TODO: Implement a queued processing of incomming events. Dublicate file
+    # checks should update an older request to avoid overrun or starving of
+    # the check.
+    def __send(self, fx, fn, data, isPy3):
+        """
+        Private method to send a job request to one of the clients.
+        
+        @param fx remote function name to execute (str)
+        @param fn filename for identification (str)
+        @param data function argument(s) (any basic datatype)
+        @param isPy3 flag for the required interpreter (boolean)
+        """
+        packedData = json.dumps([fx, fn, data])
+        if sys.version_info[0] == 3:
+            packedData = bytes(packedData, 'utf-8')
+        connection = self.connections[int(isPy3)]
+        if connection is None:
+            self.__postResult(
+                fx, fn, [
+                    True, fn, 0, 0, '',
+                    'No connection to Python{0} interpreter. '
+                    'Check your debugger settings.'.format(int(isPy3) + 2)])
+        else:
+            header = struct.pack(
+                b'!II', len(packedData), adler32(packedData) & 0xffffffff)
+            connection.write(header)
+            connection.write(packedData)
+
+    def __receive(self, channel):
+        """
+        Private method to receive the response from the clients.
+        
+        @param channel of the incomming connection (int: 0 or 1)
+        """
+        connection = self.connections[channel]
+        header = connection.read(8)
+        length, datahash = struct.unpack(b'!II', header)
+        
+        packedData = b''
+        while len(packedData) < length:
+            connection.waitForReadyRead(50)
+            packedData += connection.read(length - len(packedData))
+
+        assert adler32(packedData) & 0xffffffff == datahash, 'Hashes not equal'
+        if sys.version_info[0] == 3:
+            packedData = packedData.decode('utf-8')
+        # "check" if is's a tuple of 3 values
+        try:
+            fx, fn, data = json.loads(packedData)
+            self.__postResult(fx, fn, data)
+        except:
+            pass
+
+    def __postResult(self, fx, fn, data):
+        """
+        Private method to emit the correspondig signal for the returned
+        function.
+        
+        @param fx remote function name to execute (str)
+        @param fn filename for identification (str)
+        @param data function argument(s) (any basic datatype)
+        """
+        if fx == 'syntax':
+            self.syntaxChecked.emit(fn, *data)
+        elif fx == 'style':
+            pass
+        elif fx == 'indent':
+            pass
+        elif fx == 'exception':
+            # Call sys.excepthook(type, value, traceback) to emulate the
+            # exception which was caught on the client
+            sys.excepthook(*data)
+        
+        #QApplication.translate(packedData)
+        
+    # ggf. nach Utilities verschieben
+    def determinePythonVersion(self, filename, source):
+        """
+        Determine the python version of a given file.
+        
+        @param filename name of the file with extension (str)
+        @param source of the file (str)
+        @return flag if file is Python2 or Python3 (boolean)
+        """
+        flags = Utilities.extractFlags(source)
+        ext = os.path.splitext(filename)[1]
+        project = e5App().getObject('Project')
+        if "FileType" in flags:
+            isPy3 = flags["FileType"] not in ["Python", "Python2"]
+        elif (Preferences.getProject("DeterminePyFromProject") and
+              project.isOpen() and
+              project.isProjectFile(filename)):
+                    isPy3 = project.getProjectLanguage() == "Python3"
+        else:
+            isPy3 = ext in Preferences.getPython("PythonExtensions")
+        return isPy3
+
+    def syntaxCheck(self, filename, source="", checkFlakes=True,
+                    ignoreStarImportWarnings=False, isPy3=None):
+        """
+        Function to compile one Python source file to Python bytecode
+        and to perform a pyflakes check.
+        
+        @param filename source filename (string)
+        @keyparam source string containing the code to check (string)
+        @keyparam checkFlakes flag indicating to do a pyflakes check (boolean)
+        @keyparam ignoreStarImportWarnings flag indicating to
+            ignore 'star import' warnings (boolean)
+        @keyparam isPy3 flag sets the interpreter to use or None for autodetect
+            corresponding interpreter (boolean or None)
+        """
+        if isPy3 is None:
+            isPy3 = self.determinePythonVersion(filename, source)
+        
+        data = [source, checkFlakes, ignoreStarImportWarnings]
+        self.__send('syntax', filename, data, isPy3)
--- a/Utilities/SyntaxCheck.py	Sun Dec 15 11:50:18 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,356 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2011 - 2013 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing the syntax check for Python 2/3.
-"""
-
-import sys
-if sys.version_info[0] >= 3:
-    if __name__ == '__main__':
-        from py3flakes.checker import Checker
-        from py3flakes.messages import ImportStarUsed
-    else:
-        from .py3flakes.checker import Checker      #__IGNORE_WARNING__
-        from .py3flakes.messages import ImportStarUsed      #__IGNORE_WARNING__
-else:
-    str = unicode      #__IGNORE_WARNING__
-    if __name__ == '__main__':
-        from py2flakes.checker import Checker      #__IGNORE_WARNING__
-        from py2flakes.messages import ImportStarUsed      #__IGNORE_WARNING__
-    else:
-        from .py2flakes.checker import Checker      #__IGNORE_WARNING__
-        from .py2flakes.messages import ImportStarUsed      #__IGNORE_WARNING__
-
-import re
-import traceback
-from codecs import BOM_UTF8, BOM_UTF16, BOM_UTF32
-
-try:
-    import Preferences
-except (ImportError):
-    pass
-
-codingBytes_regexps = [
-    (2, re.compile(br'''coding[:=]\s*([-\w_.]+)''')),
-    (1, re.compile(br'''<\?xml.*\bencoding\s*=\s*['"]([-\w_.]+)['"]\?>''')),
-]
-
-
-def get_codingBytes(text):
-    """
-    Function to get the coding of a bytes text.
-    
-    @param text bytes text to inspect (bytes)
-    @return coding string
-    """
-    lines = text.splitlines()
-    for coding in codingBytes_regexps:
-        coding_re = coding[1]
-        head = lines[:coding[0]]
-        for l in head:
-            m = coding_re.search(l)
-            if m:
-                return str(m.group(1), "ascii").lower()
-    return None
-
-
-def decode(text):
-    """
-    Function to decode some byte text into a string.
-    
-    @param text byte text to decode (bytes)
-    @return tuple of decoded text and encoding (string, string)
-    """
-    try:
-        if text.startswith(BOM_UTF8):
-            # UTF-8 with BOM
-            return str(text[len(BOM_UTF8):], 'utf-8'), 'utf-8-bom'
-        elif text.startswith(BOM_UTF16):
-            # UTF-16 with BOM
-            return str(text[len(BOM_UTF16):], 'utf-16'), 'utf-16'
-        elif text.startswith(BOM_UTF32):
-            # UTF-32 with BOM
-            return str(text[len(BOM_UTF32):], 'utf-32'), 'utf-32'
-        coding = get_codingBytes(text)
-        if coding:
-            return str(text, coding), coding
-    except (UnicodeError, LookupError):
-        pass
-    
-    # Assume UTF-8
-    try:
-        return str(text, 'utf-8'), 'utf-8-guessed'
-    except (UnicodeError, LookupError):
-        pass
-    
-    try:
-        guess = None
-        if Preferences.getEditor("AdvancedEncodingDetection"):
-            # Try the universal character encoding detector
-            try:
-                import ThirdParty.CharDet.chardet
-                guess = ThirdParty.CharDet.chardet.detect(text)
-                if guess and guess['confidence'] > 0.95 \
-                        and guess['encoding'] is not None:
-                    codec = guess['encoding'].lower()
-                    return str(text, codec), '{0}-guessed'.format(codec)
-            except (UnicodeError, LookupError, ImportError):
-                pass
-    except (NameError):
-        pass
-    
-    # Try default encoding
-    try:
-        codec = Preferences.getEditor("DefaultEncoding")
-        return str(text, codec), '{0}-default'.format(codec)
-    except (UnicodeError, LookupError, NameError):
-        pass
-    
-    try:
-        if Preferences.getEditor("AdvancedEncodingDetection"):
-            # Use the guessed one even if confifence level is low
-            if guess and guess['encoding'] is not None:
-                try:
-                    codec = guess['encoding'].lower()
-                    return str(text, codec), '{0}-guessed'.format(codec)
-                except (UnicodeError, LookupError):
-                    pass
-    except (NameError):
-        pass
-    
-    # Assume UTF-8 loosing information
-    return str(text, "utf-8", "ignore"), 'utf-8-ignore'
-
-
-def readEncodedFile(filename):
-    """
-    Function to read a file and decode it's contents into proper text.
-    
-    @param filename name of the file to read (string)
-    @return tuple of decoded text and encoding (string, string)
-    """
-    try:
-        filename = filename.encode(sys.getfilesystemencoding())
-    except (UnicodeDecodeError):
-        pass
-    f = open(filename, "rb")
-    text = f.read()
-    f.close()
-    return decode(text)
-
-
-def normalizeCode(codestring):
-    """
-    Function to normalize the given code.
-    
-    @param codestring code to be normalized (string)
-    @return normalized code (string)
-    """
-    codestring = codestring.replace("\r\n", "\n").replace("\r", "\n")
-
-    if codestring and codestring[-1] != '\n':
-        codestring = codestring + '\n'
-
-    # Check type for py2: if not str it's unicode
-    if sys.version_info[0] == 2:
-        try:
-            codestring = codestring.encode('utf-8')
-        except:
-            pass
-    
-    return codestring
-
-
-def extractLineFlags(line, startComment="#", endComment=""):
-    """
-    Function to extract flags starting and ending with '__' from a line
-    comment.
-    
-    @param line line to extract flags from (string)
-    @keyparam startComment string identifying the start of the comment (string)
-    @keyparam endComment string identifying the end of a comment (string)
-    @return list containing the extracted flags (list of strings)
-    """
-    flags = []
-    
-    pos = line.rfind(startComment)
-    if pos >= 0:
-        comment = line[pos + len(startComment):].strip()
-        if endComment:
-            comment = comment.replace("endComment", "")
-        flags = [f.strip() for f in comment.split()
-                 if (f.startswith("__") and f.endswith("__"))]
-    return flags
-
-
-def compile_and_check(file_, codestring="", checkFlakes=True,
-                      ignoreStarImportWarnings=False):
-    """
-    Function to compile one Python source file to Python bytecode
-    and to perform a pyflakes check.
-    
-    @param file_ source filename (string)
-    @param codestring string containing the code to compile (string)
-    @keyparam checkFlakes flag indicating to do a pyflakes check (boolean)
-    @keyparam ignoreStarImportWarnings flag indicating to
-        ignore 'star import' warnings (boolean)
-    @return A tuple indicating status (True = an error was found), the
-        file name, the line number, the index number, the code string
-        and the error message (boolean, string, string, string, string,
-        string). If checkFlakes is True, a list of strings containing the
-        warnings (marker, file name, line number, message)
-        The values are only valid, if the status is True.
-    """
-    try:
-        import builtins
-    except ImportError:
-        import __builtin__ as builtins        #__IGNORE_WARNING__
-    
-    try:
-        if sys.version_info[0] == 2:
-            file_enc = file_.encode(sys.getfilesystemencoding())
-        else:
-            file_enc = file_
-        
-        if not codestring:
-            try:
-                codestring = readEncodedFile(file_)[0]
-            except (UnicodeDecodeError, IOError):
-                return (False, None, None, None, None, None, [])
-        
-        codestring = normalizeCode(codestring)
-        
-        if file_.endswith('.ptl'):
-            try:
-                import quixote.ptl_compile
-            except ImportError:
-                return (False, None, None, None, None, None, [])
-            template = quixote.ptl_compile.Template(codestring, file_enc)
-            template.compile()
-        
-        # ast.PyCF_ONLY_AST = 1024, speed optimisation
-        module = builtins.compile(codestring, file_enc, 'exec',  1024)
-    except SyntaxError as detail:
-        index = 0
-        code = ""
-        error = ""
-        lines = traceback.format_exception_only(SyntaxError, detail)
-        match = re.match('\s*File "(.+)", line (\d+)',
-                         lines[0].replace('<string>', '{0}'.format(file_)))
-        if match is not None:
-            fn, line = match.group(1, 2)
-            if lines[1].startswith('SyntaxError:'):
-                error = re.match('SyntaxError: (.+)', lines[1]).group(1)
-            else:
-                code = re.match('(.+)', lines[1]).group(1)
-                for seLine in lines[2:]:
-                    if seLine.startswith('SyntaxError:'):
-                        error = re.match('SyntaxError: (.+)', seLine).group(1)
-                    elif seLine.rstrip().endswith('^'):
-                        index = len(seLine.rstrip()) - 4
-        else:
-            fn = detail.filename
-            line = detail.lineno or 1
-            error = detail.msg
-        return (True, fn, int(line), index, code, error, [])
-    except ValueError as detail:
-        index = 0
-        code = ""
-        try:
-            fn = detail.filename
-            line = detail.lineno
-            error = detail.msg
-        except AttributeError:
-            fn = file_
-            line = 1
-            error = str(detail)
-        return (True, fn, line, index, code, error, [])
-    except Exception as detail:
-        try:
-            fn = detail.filename
-            line = detail.lineno
-            index = 0
-            code = ""
-            error = detail.msg
-            return (True, fn, line, index, code, error, [])
-        except:         # this catchall is intentional
-            pass
-    
-    # pyflakes
-    if not checkFlakes:
-        return (False, "", -1, -1, "", "", [])
-    
-    strings = []
-    lines = codestring.splitlines()
-    try:
-        warnings = Checker(module, file_)
-        warnings.messages.sort(key=lambda a: a.lineno)
-        for warning in warnings.messages:
-            if ignoreStarImportWarnings and \
-                    isinstance(warning, ImportStarUsed):
-                continue
-            
-            _fn, lineno, message, msg_args = warning.getMessageData()
-            if "__IGNORE_WARNING__" not in extractLineFlags(
-                    lines[lineno - 1].strip()):
-                strings.append([
-                    "FLAKES_WARNING", _fn, lineno, message, msg_args])
-    except SyntaxError as err:
-        if err.text.strip():
-            msg = err.text.strip()
-        else:
-            msg = err.msg
-        strings.append(["FLAKES_ERROR", file_, err.lineno, msg, ()])
-    
-    return (False, "", -1, -1, "", "", strings)
-
-
-if __name__ == "__main__":
-    if len(sys.argv) < 2 or \
-       len(sys.argv) > 3 or \
-       (len(sys.argv) == 3 and sys.argv[1] not in ["-fi", "-fs"]):
-        print("ERROR")
-        print("")
-        print("")
-        print("")
-        print("")
-        print("No file name given.")
-    else:
-        filename = sys.argv[-1]
-        checkFlakes = len(sys.argv) == 3
-        # Setting is ignored if checkFlakes is False
-        ignoreStarImportWarnings = sys.argv[1] == "-fi"
-        
-        try:
-            codestring = readEncodedFile(filename)[0]
-            
-            syntaxerror, fname, line, index, code, error, warnings = \
-                compile_and_check(filename, codestring, checkFlakes,
-                                  ignoreStarImportWarnings)
-        except IOError as msg:
-            # fake a syntax error
-            syntaxerror, fname, line, index, code, error, warnings = \
-                True, filename, 1, 0, "", "I/O Error: %s" % str(msg), []
-        
-        if syntaxerror:
-            print("ERROR")
-        else:
-            print("NO_ERROR")
-        print(fname)
-        print(line)
-        print(index)
-        print(code)
-        print(error)
-        
-        if not syntaxerror:
-            for warningLine in warnings:
-                msg_args = warningLine.pop()
-                for warning in warningLine:
-                    print(warning)
-                msg_args = [str(x) for x in msg_args]
-                print('#'.join(msg_args))
-    
-    sys.exit(0)
--- a/Utilities/py2flakes/__init__.py	Sun Dec 15 11:50:18 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2010 - 2013 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Package containg the pyflakes Python2 port adapted for Qt.
-"""
-
-""" License
-Copyright 2005-2011 Divmod, Inc.
-Copyright 2013 Florent Xicluna
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-"""
-
-""" Changes
-0.6.1 (2013-01-29):
-  - Fix detection of variables in augmented assignments.
-
-0.6.0 (2013-01-29):
-  - Support Python 3 up to 3.3, based on the pyflakes3k project.
-  - Preserve compatibility with Python 2.5 and all recent versions of Python.
-  - Support custom reporters in addition to the default Reporter.
-  - Allow function redefinition for modern property construction via
-    property.setter/deleter.
-  - Fix spurious redefinition warnings in conditionals.
-  - Do not report undefined name in __all__ if import * is used.
-  - Add WindowsError as a known built-in name on all platforms.
-  - Support specifying additional built-ins in the `Checker` constructor.
-  - Don't issue Unused Variable warning when using locals() in current scope.
-  - Handle problems with the encoding of source files.
-  - Remove dependency on Twisted for the tests.
-  - Support `python setup.py test` and `python setup.py develop`.
-  - Create script using setuptools `entry_points` to support all platforms,
-    including Windows.
-
-0.5.0 (2011-09-02):
-  - Convert pyflakes to use newer _ast infrastructure rather than compiler.
-  - Support for new syntax in 2.7 (including set literals, set comprehensions,
-    and dictionary comprehensions).
-  - Make sure class names don't get bound until after class definition.
-"""
-
-__version__ = '0.6.1'
--- a/Utilities/py2flakes/checker.py	Sun Dec 15 11:50:18 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,711 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2010 - 2013 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-# Original (c) 2005-2010 Divmod, Inc.
-#
-# This module is based on pyflakes for Python2 but was modified to
-# work with eric5
-
-import os.path
-try:
-    import builtins
-    PY2 = False
-except ImportError:
-    import __builtin__ as builtins      #__IGNORE_WARNING__
-    PY2 = True
-
-try:
-    import ast
-    iter_child_nodes = ast.iter_child_nodes
-except (ImportError, AttributeError):   # Python 2.5
-    import _ast as ast
-
-    def iter_child_nodes(node, astcls=ast.AST):
-        """
-        Yield all direct child nodes of *node*, that is, all fields that are nodes
-        and all items of fields that are lists of nodes.
-        """
-        for name in node._fields:
-            field = getattr(node, name, None)
-            if isinstance(field, astcls):
-                yield field
-            elif isinstance(field, list):
-                for item in field:
-                    yield item
-# Python >= 3.3 uses ast.Try instead of (ast.TryExcept + ast.TryFinally)
-if hasattr(ast, 'Try'):
-    ast_TryExcept = ast.Try
-    ast_TryFinally = ()
-else:
-    ast_TryExcept = ast.TryExcept
-    ast_TryFinally = ast.TryFinally
-
-from . import messages
-
-
-class Binding(object):
-    """
-    Represents the binding of a value to a name.
-
-    The checker uses this to keep track of which names have been bound and
-    which names have not. See L{Assignment} for a special type of binding that
-    is checked with stricter rules.
-    """
-
-    def __init__(self, name, source):
-        self.name = name
-        self.source = source
-        self.used = False
-
-    def __str__(self):
-        return self.name
-
-    def __repr__(self):
-        return '<%s object %r from line %r at 0x%x>' % (self.__class__.__name__,
-                                                        self.name,
-                                                        self.source.lineno,
-                                                        id(self))
-
-
-class UnBinding(Binding):
-    """Created by the 'del' operator."""
-
-
-class Importation(Binding):
-    """
-    A binding created by an import statement.
-    """
-    def __init__(self, name, source):
-        self.fullName = name
-        name = name.split('.')[0]
-        super(Importation, self).__init__(name, source)
-
-
-class Argument(Binding):
-    """
-    Represents binding a name as an argument.
-    """
-
-
-class Definition(Binding):
-    """
-    A binding that defines a function or a class.
-    """
-
-
-class Assignment(Binding):
-    """
-    Represents binding a name with an explicit assignment.
-
-    The checker will raise warnings for any Assignment that isn't used. Also,
-    the checker does not consider assignments in tuple/list unpacking to be
-    Assignments, rather it treats them as simple Bindings.
-    """
-
-
-class FunctionDefinition(Definition):
-    pass
-
-
-class ClassDefinition(Definition):
-    pass
-
-
-class ExportBinding(Binding):
-    """
-    A binding created by an C{__all__} assignment.  If the names in the list
-    can be determined statically, they will be treated as names for export and
-    additional checking applied to them.
-
-    The only C{__all__} assignment that can be recognized is one which takes
-    the value of a literal list containing literal strings.  For example::
-
-        __all__ = ["foo", "bar"]
-
-    Names which are imported and not otherwise used but appear in the value of
-    C{__all__} will not have an unused import warning reported for them.
-    """
-    def names(self):
-        """
-        Return a list of the names referenced by this binding.
-        """
-        names = []
-        if isinstance(self.source, ast.List):
-            for node in self.source.elts:
-                if isinstance(node, ast.Str):
-                    names.append(node.s)
-        return names
-
-
-class Scope(dict):
-    importStarred = False       # set to True when import * is found
-    usesLocals = False
-
-    def __repr__(self):
-        return '<%s at 0x%x %s>' % (self.__class__.__name__, id(self), dict.__repr__(self))
-
-
-class ClassScope(Scope):
-    pass
-
-
-class FunctionScope(Scope):
-    """
-    I represent a name scope for a function.
-    """
-    def __init__(self):
-        super(FunctionScope, self).__init__()
-        self.globals = {}
-
-
-class ModuleScope(Scope):
-    pass
-
-
-# Globally defined names which are not attributes of the builtins module, or
-# are only present on some platforms.
-_MAGIC_GLOBALS = ['__file__', '__builtins__', 'WindowsError']
-
-
-def getNodeName(node):
-    # Returns node.id, or node.name, or None
-    if hasattr(node, 'id'):     # One of the many nodes with an id
-        return node.id
-    if hasattr(node, 'name'):   # a ExceptHandler node
-        return node.name
-
-
-class Checker(object):
-    """
-    I check the cleanliness and sanity of Python code.
-    """
-
-    nodeDepth = 0
-    traceTree = False
-    builtIns = set(dir(builtins)) | set(_MAGIC_GLOBALS)
-
-    def __init__(self, tree, filename='(none)', builtins=None):
-        self._deferredFunctions = []
-        self._deferredAssignments = []
-        self.deadScopes = []
-        self.messages = []
-        self.filename = filename
-        if builtins:
-            self.builtIns = self.builtIns.union(builtins)
-        self.scopeStack = [ModuleScope()]
-        self.futuresAllowed = True
-        self.root = tree
-        self.handleChildren(tree)
-        self.runDeferred(self._deferredFunctions)
-        # Set _deferredFunctions to None so that deferFunction will fail
-        # noisily if called after we've run through the deferred functions.
-        self._deferredFunctions = None
-        self.runDeferred(self._deferredAssignments)
-        # Set _deferredAssignments to None so that deferAssignment will fail
-        # noisily if called after we've run through the deferred assignments.
-        self._deferredAssignments = None
-        del self.scopeStack[1:]
-        self.popScope()
-        self.checkDeadScopes()
-
-    def deferFunction(self, callable):
-        """
-        Schedule a function handler to be called just before completion.
-
-        This is used for handling function bodies, which must be deferred
-        because code later in the file might modify the global scope. When
-        `callable` is called, the scope at the time this is called will be
-        restored, however it will contain any new bindings added to it.
-        """
-        self._deferredFunctions.append((callable, self.scopeStack[:]))
-
-    def deferAssignment(self, callable):
-        """
-        Schedule an assignment handler to be called just after deferred
-        function handlers.
-        """
-        self._deferredAssignments.append((callable, self.scopeStack[:]))
-
-    def runDeferred(self, deferred):
-        """
-        Run the callables in C{deferred} using their associated scope stack.
-        """
-        for handler, scope in deferred:
-            self.scopeStack = scope
-            handler()
-
-    @property
-    def scope(self):
-        return self.scopeStack[-1]
-
-    def popScope(self):
-        self.deadScopes.append(self.scopeStack.pop())
-
-    def checkDeadScopes(self):
-        """
-        Look at scopes which have been fully examined and report names in them
-        which were imported but unused.
-        """
-        for scope in self.deadScopes:
-            export = isinstance(scope.get('__all__'), ExportBinding)
-            if export:
-                all = scope['__all__'].names()
-                if not scope.importStarred and os.path.basename(self.filename) != '__init__.py':
-                    # Look for possible mistakes in the export list
-                    undefined = set(all) - set(scope)
-                    for name in undefined:
-                        self.report(messages.UndefinedExport,
-                                    scope['__all__'].source.lineno, name)
-            else:
-                all = []
-
-            # Look for imported names that aren't used.
-            for importation in scope.values():
-                if isinstance(importation, Importation):
-                    if not importation.used and importation.name not in all:
-                        self.report(messages.UnusedImport,
-                                    importation.source.lineno, importation.name)
-
-    def pushFunctionScope(self):
-        self.scopeStack.append(FunctionScope())
-
-    def pushClassScope(self):
-        self.scopeStack.append(ClassScope())
-
-    def report(self, messageClass, *args, **kwargs):
-        self.messages.append(messageClass(self.filename, *args, **kwargs))
-
-    def hasParent(self, node, kind):
-        while hasattr(node, 'parent'):
-            node = node.parent
-            if isinstance(node, kind):
-                return True
-
-    def getCommonAncestor(self, lnode, rnode, stop=None):
-        if not stop:
-            stop = self.root
-        if lnode is rnode:
-            return lnode
-        if stop in (lnode, rnode):
-            return stop
-
-        if not hasattr(lnode, 'parent') or not hasattr(rnode, 'parent'):
-            return
-        if (lnode.level > rnode.level):
-            return self.getCommonAncestor(lnode.parent, rnode, stop)
-        if (rnode.level > lnode.level):
-            return self.getCommonAncestor(lnode, rnode.parent, stop)
-        return self.getCommonAncestor(lnode.parent, rnode.parent, stop)
-
-    def descendantOf(self, node, ancestors, stop=None):
-        for a in ancestors:
-            if self.getCommonAncestor(node, a, stop) not in (stop, None):
-                return True
-        return False
-
-    def onFork(self, parent, lnode, rnode, items):
-        return (self.descendantOf(lnode, items, parent) ^
-                self.descendantOf(rnode, items, parent))
-
-    def differentForks(self, lnode, rnode):
-        """True, if lnode and rnode are located on different forks of IF/TRY"""
-        ancestor = self.getCommonAncestor(lnode, rnode)
-        if isinstance(ancestor, ast.If):
-            for fork in (ancestor.body, ancestor.orelse):
-                if self.onFork(ancestor, lnode, rnode, fork):
-                    return True
-        elif isinstance(ancestor, ast_TryExcept):
-            body = ancestor.body + ancestor.orelse
-            for fork in [body] + [[hdl] for hdl in ancestor.handlers]:
-                if self.onFork(ancestor, lnode, rnode, fork):
-                    return True
-        elif isinstance(ancestor, ast_TryFinally):
-            if self.onFork(ancestor, lnode, rnode, ancestor.body):
-                return True
-        return False
-
-    def addBinding(self, node, value, reportRedef=True):
-        """
-        Called when a binding is altered.
-
-        - `node` is the statement responsible for the change
-        - `value` is the optional new value, a Binding instance, associated
-          with the binding; if None, the binding is deleted if it exists.
-        - if `reportRedef` is True (default), rebinding while unused will be
-          reported.
-        """
-        redefinedWhileUnused = False
-        if not isinstance(self.scope, ClassScope):
-            for scope in self.scopeStack[::-1]:
-                existing = scope.get(value.name)
-                if (isinstance(existing, Importation)
-                        and not existing.used
-                        and (not isinstance(value, Importation) or value.fullName == existing.fullName)
-                        and reportRedef
-                        and not self.differentForks(node, existing.source)):
-                    redefinedWhileUnused = True
-                    self.report(messages.RedefinedWhileUnused,
-                                node.lineno, value.name, existing.source.lineno)
-
-        existing = self.scope.get(value.name)
-        if not redefinedWhileUnused and self.hasParent(value.source, ast.ListComp):
-            if (existing and reportRedef
-                    and not self.hasParent(existing.source, (ast.For, ast.ListComp))):
-                self.report(messages.RedefinedInListComp,
-                            node.lineno, value.name, existing.source.lineno)
-
-        if isinstance(value, UnBinding):
-            try:
-                del self.scope[value.name]
-            except KeyError:
-                self.report(messages.UndefinedName, node.lineno, value.name)
-        elif (isinstance(existing, Definition)
-              and not existing.used
-              and not self.differentForks(node, existing.source)):
-            self.report(messages.RedefinedWhileUnused,
-                        node.lineno, value.name, existing.source.lineno)
-        else:
-            self.scope[value.name] = value
-
-    def handleNodeLoad(self, node):
-        name = getNodeName(node)
-        if not name:
-            return
-        # try local scope
-        importStarred = self.scope.importStarred
-        try:
-            self.scope[name].used = (self.scope, node.lineno)
-        except KeyError:
-            pass
-        else:
-            return
-
-        # try enclosing function scopes
-        for scope in self.scopeStack[-2:0:-1]:
-            importStarred = importStarred or scope.importStarred
-            if not isinstance(scope, FunctionScope):
-                continue
-            try:
-                scope[name].used = (self.scope, node.lineno)
-            except KeyError:
-                pass
-            else:
-                return
-
-        # try global scope
-        importStarred = importStarred or self.scopeStack[0].importStarred
-        try:
-            self.scopeStack[0][name].used = (self.scope, node.lineno)
-        except KeyError:
-            if not importStarred and name not in self.builtIns:
-                if (os.path.basename(self.filename) == '__init__.py' and name == '__path__'):
-                    # the special name __path__ is valid only in packages
-                    pass
-                else:
-                    self.report(messages.UndefinedName, node.lineno, name)
-
-    def handleNodeStore(self, node):
-        name = getNodeName(node)
-        if not name:
-            return
-        # if the name hasn't already been defined in the current scope
-        if isinstance(self.scope, FunctionScope) and name not in self.scope:
-            # for each function or module scope above us
-            for scope in self.scopeStack[:-1]:
-                if not isinstance(scope, (FunctionScope, ModuleScope)):
-                    continue
-                # if the name was defined in that scope, and the name has
-                # been accessed already in the current scope, and hasn't
-                # been declared global
-                if (name in scope and scope[name].used and scope[name].used[0] is self.scope
-                        and name not in self.scope.globals):
-                    # then it's probably a mistake
-                    self.report(messages.UndefinedLocal,
-                                scope[name].used[1], name, scope[name].source.lineno)
-                    break
-
-        parent = getattr(node, 'parent', None)
-        if isinstance(parent, (ast.For, ast.comprehension, ast.Tuple, ast.List)):
-            binding = Binding(name, node)
-        elif parent is not None and name == '__all__' and isinstance(self.scope, ModuleScope):
-            binding = ExportBinding(name, parent.value)
-        else:
-            binding = Assignment(name, node)
-        if name in self.scope:
-            binding.used = self.scope[name].used
-        self.addBinding(node, binding)
-
-    def handleNodeDelete(self, node):
-        name = getNodeName(node)
-        if not name:
-            return
-        if isinstance(self.scope, FunctionScope) and name in self.scope.globals:
-            del self.scope.globals[name]
-        else:
-            self.addBinding(node, UnBinding(name, node))
-
-    def handleChildren(self, tree):
-        for node in iter_child_nodes(tree):
-            self.handleNode(node, tree)
-
-    def isDocstring(self, node):
-        """
-        Determine if the given node is a docstring, as long as it is at the
-        correct place in the node tree.
-        """
-        return isinstance(node, ast.Str) or (isinstance(node, ast.Expr) and
-                                             isinstance(node.value, ast.Str))
-
-    def handleNode(self, node, parent):
-        if node is None:
-            return
-        node.parent = parent
-        if self.traceTree:
-            print('  ' * self.nodeDepth + node.__class__.__name__)
-        self.nodeDepth += 1
-        if self.futuresAllowed and not (isinstance(node, ast.ImportFrom) or
-                                        self.isDocstring(node)):
-            self.futuresAllowed = False
-        nodeType = node.__class__.__name__.upper()
-        node.level = self.nodeDepth
-        try:
-            handler = getattr(self, nodeType)
-            handler(node)
-        finally:
-            self.nodeDepth -= 1
-        if self.traceTree:
-            print('  ' * self.nodeDepth + 'end ' + node.__class__.__name__)
-
-    def ignore(self, node):
-        pass
-
-    # "stmt" type nodes
-    RETURN = DELETE = PRINT = WHILE = IF = WITH = WITHITEM = RAISE = \
-        TRYEXCEPT = TRYFINALLY = TRY = ASSERT = EXEC = EXPR = handleChildren
-
-    CONTINUE = BREAK = PASS = ignore
-
-    # "expr" type nodes
-    BOOLOP = BINOP = UNARYOP = IFEXP = DICT = SET = YIELD = YIELDFROM = \
-        COMPARE = CALL = REPR = ATTRIBUTE = SUBSCRIPT = LIST = TUPLE = \
-        STARRED = handleChildren
-
-    NUM = STR = BYTES = ELLIPSIS = ignore
-
-    # "slice" type nodes
-    SLICE = EXTSLICE = INDEX = handleChildren
-
-    # expression contexts are node instances too, though being constants
-    LOAD = STORE = DEL = AUGLOAD = AUGSTORE = PARAM = ignore
-
-    # same for operators
-    AND = OR = ADD = SUB = MULT = DIV = MOD = POW = LSHIFT = RSHIFT = \
-        BITOR = BITXOR = BITAND = FLOORDIV = INVERT = NOT = UADD = USUB = \
-        EQ = NOTEQ = LT = LTE = GT = GTE = IS = ISNOT = IN = NOTIN = ignore
-
-    # additional node types
-    COMPREHENSION = KEYWORD = handleChildren
-
-    def GLOBAL(self, node):
-        """
-        Keep track of globals declarations.
-        """
-        if isinstance(self.scope, FunctionScope):
-            self.scope.globals.update(dict.fromkeys(node.names))
-
-    NONLOCAL = GLOBAL
-
-    def LISTCOMP(self, node):
-        # handle generators before element
-        for gen in node.generators:
-            self.handleNode(gen, node)
-        self.handleNode(node.elt, node)
-
-    GENERATOREXP = SETCOMP = LISTCOMP
-
-    def DICTCOMP(self, node):
-        for gen in node.generators:
-            self.handleNode(gen, node)
-        self.handleNode(node.key, node)
-        self.handleNode(node.value, node)
-
-    def FOR(self, node):
-        """
-        Process bindings for loop variables.
-        """
-        vars = []
-
-        def collectLoopVars(n):
-            if isinstance(n, ast.Name):
-                vars.append(n.id)
-            elif isinstance(n, ast.expr_context):
-                return
-            else:
-                for c in iter_child_nodes(n):
-                    collectLoopVars(c)
-
-        collectLoopVars(node.target)
-        for varn in vars:
-            if (isinstance(self.scope.get(varn), Importation)
-                    # unused ones will get an unused import warning
-                    and self.scope[varn].used):
-                self.report(messages.ImportShadowedByLoopVar,
-                            node.lineno, varn, self.scope[varn].source.lineno)
-
-        self.handleChildren(node)
-
-    def NAME(self, node):
-        """
-        Handle occurrence of Name (which can be a load/store/delete access.)
-        """
-        if node.id == 'locals' and isinstance(node.parent, ast.Call):
-            # we are doing locals() call in current scope
-            self.scope.usesLocals = True
-        # Locate the name in locals / function / globals scopes.
-        if isinstance(node.ctx, (ast.Load, ast.AugLoad)):
-            self.handleNodeLoad(node)
-        elif isinstance(node.ctx, (ast.Store, ast.AugStore)):
-            self.handleNodeStore(node)
-        elif isinstance(node.ctx, ast.Del):
-            self.handleNodeDelete(node)
-        else:
-            # must be a Param context -- this only happens for names in function
-            # arguments, but these aren't dispatched through here
-            raise RuntimeError("Got impossible expression context: %r" % (node.ctx,))
-
-    def FUNCTIONDEF(self, node):
-        if not hasattr(node, 'decorator_list'):   # Python 2.5
-            node.decorator_list = node.decorators
-        for deco in node.decorator_list:
-            self.handleNode(deco, node)
-        self.addBinding(node, FunctionDefinition(node.name, node))
-        self.LAMBDA(node)
-
-    def LAMBDA(self, node):
-        args = []
-
-        if PY2:
-            def addArgs(arglist):
-                for arg in arglist:
-                    if isinstance(arg, ast.Tuple):
-                        addArgs(arg.elts)
-                    else:
-                        if arg.id in args:
-                            self.report(messages.DuplicateArgument,
-                                        node.lineno, arg.id)
-                        args.append(arg.id)
-            addArgs(node.args.args)
-            defaults = node.args.defaults
-        else:
-            for arg in node.args.args + node.args.kwonlyargs:
-                if arg.arg in args:
-                    self.report(messages.DuplicateArgument,
-                                node.lineno, arg.arg)
-                args.append(arg.arg)
-                self.handleNode(arg.annotation, node)
-            if hasattr(node, 'returns'):    # Only for FunctionDefs
-                for annotation in (node.args.varargannotation,
-                                   node.args.kwargannotation, node.returns):
-                    self.handleNode(annotation, node)
-            defaults = node.args.defaults + node.args.kw_defaults
-
-        # vararg/kwarg identifiers are not Name nodes
-        for wildcard in (node.args.vararg, node.args.kwarg):
-            if not wildcard:
-                continue
-            if wildcard in args:
-                self.report(messages.DuplicateArgument, node.lineno, wildcard)
-            args.append(wildcard)
-        for default in defaults:
-            self.handleNode(default, node)
-
-        def runFunction():
-
-            self.pushFunctionScope()
-            for name in args:
-                self.addBinding(node, Argument(name, node), reportRedef=False)
-            if isinstance(node.body, list):
-                # case for FunctionDefs
-                for stmt in node.body:
-                    self.handleNode(stmt, node)
-            else:
-                # case for Lambdas
-                self.handleNode(node.body, node)
-
-            def checkUnusedAssignments():
-                """
-                Check to see if any assignments have not been used.
-                """
-                for name, binding in self.scope.items():
-                    if (not binding.used and name not in self.scope.globals
-                            and not self.scope.usesLocals
-                            and isinstance(binding, Assignment)):
-                        self.report(messages.UnusedVariable,
-                                    binding.source.lineno, name)
-            self.deferAssignment(checkUnusedAssignments)
-            self.popScope()
-
-        self.deferFunction(runFunction)
-
-    def CLASSDEF(self, node):
-        """
-        Check names used in a class definition, including its decorators, base
-        classes, and the body of its definition.  Additionally, add its name to
-        the current scope.
-        """
-        # no class decorator in Python 2.5
-        for deco in getattr(node, 'decorator_list', ''):
-            self.handleNode(deco, node)
-        for baseNode in node.bases:
-            self.handleNode(baseNode, node)
-        if not PY2:
-            for keywordNode in node.keywords:
-                self.handleNode(keywordNode, node)
-        self.pushClassScope()
-        for stmt in node.body:
-            self.handleNode(stmt, node)
-        self.popScope()
-        self.addBinding(node, ClassDefinition(node.name, node))
-
-    def ASSIGN(self, node):
-        self.handleNode(node.value, node)
-        for target in node.targets:
-            self.handleNode(target, node)
-
-    def AUGASSIGN(self, node):
-        self.handleNodeLoad(node.target)
-        self.handleNode(node.value, node)
-        self.handleNode(node.target, node)
-
-    def IMPORT(self, node):
-        for alias in node.names:
-            name = alias.asname or alias.name
-            importation = Importation(name, node)
-            self.addBinding(node, importation)
-
-    def IMPORTFROM(self, node):
-        if node.module == '__future__':
-            if not self.futuresAllowed:
-                self.report(messages.LateFutureImport,
-                            node.lineno, [n.name for n in node.names])
-        else:
-            self.futuresAllowed = False
-
-        for alias in node.names:
-            if alias.name == '*':
-                self.scope.importStarred = True
-                self.report(messages.ImportStarUsed, node.lineno, node.module)
-                continue
-            name = alias.asname or alias.name
-            importation = Importation(name, node)
-            if node.module == '__future__':
-                importation.used = (self.scope, node.lineno)
-            self.addBinding(node, importation)
-
-    def EXCEPTHANDLER(self, node):
-        # 3.x: in addition to handling children, we must handle the name of
-        # the exception, which is not a Name node, but a simple string.
-        if isinstance(node.name, str):
-            self.handleNodeStore(node)
-        self.handleChildren(node)
--- a/Utilities/py2flakes/messages.py	Sun Dec 15 11:50:18 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,309 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2010 - 2013 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-# Original (c) 2005 Divmod, Inc.  See LICENSE file for details
-#
-# This module is based on pyflakes for Python2 but was heavily hacked to
-# work within Eric5 and Qt (translatable messages)
-
-"""
-Module implementing the messages for py2flakes.
-"""
-
-
-def QT_TRANSLATE_NOOP(mod, txt):
-    """
-    Function to tell 'lupdate' which strings to keep for translation.
-    
-    @param mod module name
-    @param txt translatable string
-    @return the untranslated! string
-    """
-    return txt
-
-
-class Message(object):
-    """
-    Class defining the base for all specific message classes.
-    """
-    message = ''
-    message_args = ()
-    
-    def __init__(self, filename, lineno):
-        """
-        Constructor
-        
-        @param filename name of the file (string)
-        @param lineno line number (integer)
-        """
-        self.filename = filename
-        self.lineno = lineno
-    
-    def __str__(self):
-        """
-        Special method return a string representation of the instance object.
-        
-        @return string representation of the object (string)
-        """
-        return '%s:%s: %s' % (
-            self.filename, self.lineno, self.message % self.message_args)
-    
-    def getMessageData(self):
-        """
-        Public method to get the individual message data elements.
-        
-        @return tuple containing file name, line number and message
-            (string, integer, string)
-        """
-        return (self.filename, self.lineno, self.message, self.message_args)
-
-
-class UnusedImport(Message):
-    """
-    Class defining the "Unused Import" message.
-    """
-    message = QT_TRANSLATE_NOOP(
-        'py3Flakes',
-        '{0!r} imported but unused.')
-    
-    def __init__(self, filename, lineno, name):
-        """
-        Constructor
-        
-        @param filename name of the file (string)
-        @param lineno line number (integer)
-        @param name name of the unused import (string)
-        """
-        Message.__init__(self, filename, lineno)
-        self.message_args = (name,)
-
-
-class RedefinedWhileUnused(Message):
-    """
-    Class defining the "Redefined While Unused" message.
-    """
-    message = QT_TRANSLATE_NOOP(
-        'py3Flakes',
-        'Redefinition of unused {0!r} from line {1!r}.')
-
-    def __init__(self, filename, lineno, name, orig_lineno):
-        """
-        Constructor
-        
-        @param filename name of the file (string)
-        @param lineno line number (integer)
-        @param name name of the redefined object (string)
-        @param orig_lineno line number of the original definition (integer)
-        """
-        Message.__init__(self, filename, lineno)
-        self.message_args = (name, orig_lineno)
-
-
-class RedefinedInListComp(Message):
-    """
-    Class defining the list comprehension redefinition.
-    """
-    message = QT_TRANSLATE_NOOP(
-        'py3Flakes',
-        'List comprehension redefines {0!r} from line {1!r}.')
-
-    def __init__(self, filename, lineno, name, orig_lineno):
-        """
-        Constructor
-        
-        @param filename name of the file (string)
-        @param lineno line number (integer)
-        @param name name of the redefined object (string)
-        @param orig_lineno line number of the original definition (integer)
-        """
-        Message.__init__(self, filename, lineno)
-        self.message_args = (name, orig_lineno)
-
-
-class ImportShadowedByLoopVar(Message):
-    """
-    Class defining the "Import Shadowed By Loop Var" message.
-    """
-    message = QT_TRANSLATE_NOOP(
-        'py3Flakes',
-        'Import {0!r} from line {1!r} shadowed by loop variable.')
-    
-    def __init__(self, filename, lineno, name, orig_lineno):
-        """
-        Constructor
-        
-        @param filename name of the file (string)
-        @param lineno line number (integer)
-        @param name name of the shadowed import (string)
-        @param orig_lineno line number of the import (integer)
-        """
-        Message.__init__(self, filename, lineno)
-        self.message_args = (name, orig_lineno)
-
-
-class ImportStarUsed(Message):
-    """
-    Class defining the "Import Star Used" message.
-    """
-    message = QT_TRANSLATE_NOOP(
-        'py3Flakes',
-        "'from {0} import *' used; unable to detect undefined names.")
-    
-    def __init__(self, filename, lineno, modname):
-        """
-        Constructor
-        
-        @param filename name of the file (string)
-        @param lineno line number (integer)
-        @param modname name of the module imported using star import (string)
-        """
-        Message.__init__(self, filename, lineno)
-        self.message_args = (modname,)
-
-
-class UndefinedName(Message):
-    """
-    Class defining the "Undefined Name" message.
-    """
-    message = QT_TRANSLATE_NOOP('py3Flakes', 'Undefined name {0!r}.')
-    
-    def __init__(self, filename, lineno, name):
-        """
-        Constructor
-        
-        @param filename name of the file (string)
-        @param lineno line number (integer)
-        @param name undefined name (string)
-        """
-        Message.__init__(self, filename, lineno)
-        self.message_args = (name,)
-
-
-class UndefinedExport(Message):
-    """
-    Class defining the "Undefined Export" message.
-    """
-    message = QT_TRANSLATE_NOOP(
-        'py3Flakes',
-        'Undefined name {0!r} in __all__.')
-    
-    def __init__(self, filename, lineno, name):
-        """
-        Constructor
-        
-        @param filename name of the file (string)
-        @param lineno line number (integer)
-        @param name undefined exported name (string)
-        """
-        Message.__init__(self, filename, lineno)
-        self.message_args = (name,)
-
-
-class UndefinedLocal(Message):
-    """
-    Class defining the "Undefined Local Variable" message.
-    """
-    message = QT_TRANSLATE_NOOP(
-        'py3Flakes',
-        "Local variable {0!r} (defined in enclosing scope on line {1!r})"
-        " referenced before assignment.")
-    
-    def __init__(self, filename, lineno, name, orig_lineno):
-        """
-        Constructor
-        
-        @param filename name of the file (string)
-        @param lineno line number (integer)
-        @param name name of the prematurely referenced variable (string)
-        @param orig_lineno line number of the variable definition (integer)
-        """
-        Message.__init__(self, filename, lineno)
-        self.message_args = (name, orig_lineno)
-
-
-class DuplicateArgument(Message):
-    """
-    Class defining the "Duplicate Argument" message.
-    """
-    message = QT_TRANSLATE_NOOP(
-        'py3Flakes',
-        'Duplicate argument {0!r} in function definition.')
-    
-    def __init__(self, filename, lineno, name):
-        """
-        Constructor
-        
-        @param filename name of the file (string)
-        @param lineno line number (integer)
-        @param name name of the duplicate argument (string)
-        """
-        Message.__init__(self, filename, lineno)
-        self.message_args = (name,)
-
-
-class Redefined(Message):
-    """
-    Class defining the "Redefined" message.
-    """
-    message = QT_TRANSLATE_NOOP(
-        'py3Flakes',
-        'Redefinition of {0!r} from line {1!r}.')
-    
-    def __init__(self, filename, lineno, name, orig_lineno):
-        """
-        Constructor
-        
-        @param filename name of the file (string)
-        @param lineno line number (integer)
-        @param name name of the redefined function (string)
-        @param orig_lineno line number of the original definition (integer)
-        """
-        Message.__init__(self, filename, lineno)
-        self.message_args = (name, orig_lineno)
-
-
-class LateFutureImport(Message):
-    """
-    Class defining the "Late Future Import" message.
-    """
-    message = QT_TRANSLATE_NOOP(
-        'py3Flakes',
-        'Future import(s) {0!r} after other statements.')
-    
-    def __init__(self, filename, lineno, names):
-        """
-        Constructor
-        
-        @param filename name of the file (string)
-        @param lineno line number (integer)
-        @param names names of the imported futures (string)
-        """
-        Message.__init__(self, filename, lineno)
-        self.message_args = (names,)
-
-
-class UnusedVariable(Message):
-    """
-    Class defining the "Unused Variable" message.
-    
-    Indicates that a variable has been explicitly assigned to but not actually
-    used.
-    """
-    message = QT_TRANSLATE_NOOP(
-        'py3Flakes',
-        'Local variable {0!r} is assigned to but never used.')
-    
-    def __init__(self, filename, lineno, names):
-        """
-        Constructor
-        
-        @param filename name of the file (string)
-        @param lineno line number (integer)
-        @param names names of the unused variable (string)
-        """
-        Message.__init__(self, filename, lineno)
-        self.message_args = (names,)
-    
-#
-# eflag: FileType = Python2

eric ide

mercurial