Fri, 31 Jan 2014 22:11:45 +0100
Interface for adding different languages to the syntax check, background service
calls based upon language not Python version any more, refactored services.
Note: CodeStyleCheck is broken.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckService.py Fri Jan 31 22:11:45 2014 +0100 @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2013 - 2014 Detlev Offenbach <detlev@die-offenbachs.de> +# +# pylint: disable=C0103 + +""" +Module implementing an interface to add different languages to do a syntax +check. +""" + +from __future__ import unicode_literals + +from PyQt4.QtCore import QObject, pyqtSignal + +from E5Gui.E5Application import e5App +from Utilities import determinePythonVersion + + +class SyntaxCheckService(QObject): + """ + Implement the syntax check service. + + Plugins can add other languages to the syntax check by calling addLanguage + and support of an extra checker module on the client side which has to + connect directly to the background service. + """ + syntaxChecked = pyqtSignal(str, bool, int, int, str, str, list) + + def __init__(self): + """ + Contructor of SyntaxCheckService. + + @param backgroundService to connect to (BackgroundService class) + """ + super(SyntaxCheckService, self).__init__() + self.backgroundService = e5App().getObject("BackgroundService") + self.__supportedLanguages = {} + + def __determineLanguage(self, filename, source): + """ + Private methode to determine the language of the file. + + @return language of the file or None if not found (str or None) + """ + pyVer = determinePythonVersion(filename, source) + if pyVer: + return 'Python{0}'.format(pyVer) + + for lang, (getArgs, getExt) in self.__supportedLanguages.items(): + if filename.endswith(getExt()): + return lang + + return None + + def addLanguage( + self, lang, path, module, getArgs, getExt, callback, onError): + """ + Register the new language to the supported languages. + + @param lang new language to check syntax (str) + @param path full path to the module (str) + @param module name to import (str) + @param getArgs function to collect the required arguments to call the + syntax checker on client side (function) + @param getExt function that returns the supported file extensions of + the syntax checker (function) + @param callback function on service response (function) + @param onError callback function if client or service isn't available + (function) + """ + self.__supportedLanguages[lang] = getArgs, getExt + # Connect to the background service + self.backgroundService.serviceConnect( + 'syntax', lang, path, module, callback, onError) + + def getLanguages(self): + """ + Return the supported language names. + + @return list of languanges supported (list of str) + """ + return list(self.__supportedLanguages.keys()) + + def removeLanguage(self, lang): + """ + Remove the language from syntax check. + + @param lang language to remove (str) + """ + self.__supportedLanguages.pop(lang, None) + self.backgroundService.serviceDisconnect('syntax', lang) + + def getExtensions(self): + """ + Return all supported file extensions for the syntax checker dialog. + + @return set of all supported file extensions (set of str) + """ + extensions = set() + for getArgs, getExt in self.__supportedLanguages.values(): + for ext in getExt(): + extensions.add(ext) + return extensions + + def syntaxCheck(self, lang, filename, source=""): + """ + Method to prepare to compile one Python source file to Python bytecode + and to perform a pyflakes check in another task. + + @param lang language of the file or None to determine by internal + algorithm (str or None) + @param filename source filename (string) + @keyparam source string containing the code to check (string) + """ + if not lang: + lang = self.__determineLanguage(filename, source) + if lang not in self.getLanguages(): + return + data = [source] + # Call the getArgs function to get the required arguments + args = self.__supportedLanguages[lang][0]() + data.extend(args) + self.backgroundService.enqueueRequest('syntax', lang, filename, data)
--- a/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py Fri Jan 17 23:38:29 2014 +0100 +++ b/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py Fri Jan 31 22:11:45 2014 +0100 @@ -21,7 +21,6 @@ from .Ui_SyntaxCheckerDialog import Ui_SyntaxCheckerDialog import Utilities -import Preferences import UI.PixmapCache @@ -66,8 +65,8 @@ self.checkProgressLabel.setVisible(False) self.checkProgressLabel.setMaximumWidth(600) - self.internalServices = e5App().getObject('InternalServices') - self.internalServices.syntaxChecked.connect(self.__processResult) + self.syntaxCheckService = e5App().getObject('SyntaxCheckService') + self.syntaxCheckService.syntaxChecked.connect(self.__processResult) def __resort(self): """ @@ -154,9 +153,7 @@ self.files = fn elif os.path.isdir(fn): self.files = [] - extensions = set(Preferences.getPython("PythonExtensions") + - Preferences.getPython("Python3Extensions")) - for ext in extensions: + for ext in self.syntaxCheckService.getExtensions(): self.files.extend( Utilities.direntries(fn, True, '*{0}'.format(ext), 0)) else: @@ -177,10 +174,6 @@ 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 self.progress = 0 self.check(codestring) @@ -220,12 +213,10 @@ self.check() return - self.internalServices.syntaxCheck( - self.filename, self.source, self.checkFlakes, - self.ignoreStarImportWarnings) + self.syntaxCheckService.syntaxCheck(None, self.filename, self.source) def __processResult( - self, fn, nok, fname, line, index, code, error, warnings): + self, fn, nok, line, index, code, error, warnings): """ Slot to display the reported messages. @@ -235,7 +226,6 @@ @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) @@ -250,7 +240,7 @@ if nok: self.noResults = False self.__createResultItem( - fname, line, index, error, code.strip(), False) + fn, line, index, error, code.strip(), False) else: source = self.source.splitlines() for marker, _fn, lineno, col, msg in warnings:
--- a/Plugins/PluginSyntaxChecker.py Fri Jan 17 23:38:29 2014 +0100 +++ b/Plugins/PluginSyntaxChecker.py Fri Jan 31 22:11:45 2014 +0100 @@ -12,10 +12,11 @@ import os from PyQt4.QtCore import QObject - -from E5Gui.E5Application import e5App +from PyQt4.QtGui import QApplication from E5Gui.E5Action import E5Action +from E5Gui.E5Application import e5App +from eric5config import getConfig import Preferences @@ -51,6 +52,31 @@ self.__ui = ui self.__initialize() + from Plugins.CheckerPlugins.SyntaxChecker.SyntaxCheckService import \ + SyntaxCheckService + self.syntaxCheckService = SyntaxCheckService() + e5App().registerObject("SyntaxCheckService", self.syntaxCheckService) + + ericPath = getConfig('ericDir') + path = os.path.join(ericPath, 'Plugins', 'CheckerPlugins', + 'SyntaxChecker') + + self.syntaxCheckService.addLanguage('Python2', path, 'SyntaxCheck', + self.__getPythonOptions, + lambda: Preferences.getPython("PythonExtensions"), + self.__translateSyntaxCheck, + lambda fx, lng, fn, msg: \ + self.syntaxCheckService.syntaxChecked.emit( + fn, True, fn, 0, 0, '', msg, [])) + + self.syntaxCheckService.addLanguage('Python3', path, 'SyntaxCheck', + self.__getPythonOptions, + lambda: Preferences.getPython("Python3Extensions"), + self.__translateSyntaxCheck, + lambda fx, lng, fn, msg: \ + self.syntaxCheckService.syntaxChecked.emit( + fn, True, fn, 0, 0, '', msg, [])) + def __initialize(self): """ Private slot to (re)initialize the plugin. @@ -66,6 +92,49 @@ self.__editorAct = None self.__editorSyntaxCheckerDialog = None + def __getPythonOptions(self): + """ + Private methode to determine the syntax check options. + + @return state of checkFlakes and ignoreStarImportWarnings (bool, bool) + """ + checkFlakes = Preferences.getFlakes("IncludeInSyntaxCheck") + ignoreStarImportWarnings = Preferences.getFlakes( + "IgnoreStarImportWarnings") + return checkFlakes, ignoreStarImportWarnings + + def __translateSyntaxCheck( + self, fn, nok, fname, line, index, code, error, warnings): + """ + Slot to translate 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, col, message, list(msg_args)) + """ + for warning in warnings: + # Translate messages + msg_args = warning.pop() + translated = QApplication.translate( + 'py3Flakes', warning[4]).format(*msg_args) + # Avoid leading "u" at Python2 unicode strings + if translated.startswith("u'"): + translated = translated[1:] + warning[4] = translated.replace(" u'", " '") + + self.syntaxCheckService.syntaxChecked.emit( + fn, nok, line, index, code, error, warnings) + def activate(self): """ Public method to activate this plugin. @@ -152,7 +221,7 @@ if menuName == "Checks" and self.__projectAct is not None: self.__projectAct.setEnabled( e5App().getObject("Project").getProjectLanguage() in - ["Python3", "Python2", "Python"]) + self.syntaxCheckService.getLanguages()) def __projectBrowserShowMenu(self, menuName, menu): """ @@ -164,7 +233,7 @@ """ if menuName == "Checks" and \ e5App().getObject("Project").getProjectLanguage() in \ - ["Python3", "Python2", "Python"]: + self.syntaxCheckService.getLanguages(): self.__projectBrowserMenu = menu if self.__projectBrowserAct is None: self.__projectBrowserAct = E5Action( @@ -187,11 +256,10 @@ project = e5App().getObject("Project") project.saveAllScripts() ppath = project.getProjectPath() + extensions = tuple(self.syntaxCheckService.getExtensions()) files = [os.path.join(ppath, file) for file in project.pdata["SOURCES"] - if file.endswith( - tuple(Preferences.getPython("Python3Extensions")) + - tuple(Preferences.getPython("PythonExtensions")))] + if file.endswith(extensions)] from CheckerPlugins.SyntaxChecker.SyntaxCheckerDialog import \ SyntaxCheckerDialog @@ -254,7 +322,7 @@ if not self.__editorAct in menu.actions(): menu.addAction(self.__editorAct) self.__editorAct.setEnabled( - editor.isPy3File() or editor.isPy2File()) + editor.getLanguage() in self.syntaxCheckService.getLanguages()) def __editorSyntaxCheck(self): """
--- a/QScintilla/Editor.py Fri Jan 17 23:38:29 2014 +0100 +++ b/QScintilla/Editor.py Fri Jan 31 22:11:45 2014 +0100 @@ -312,8 +312,8 @@ self.__setTextDisplay() # initialize the online syntax check timer - self.internalServices = e5App().getObject('InternalServices') - self.internalServices.syntaxChecked.connect(self.__processResult) + self.syntaxCheckService = e5App().getObject('SyntaxCheckService') + self.syntaxCheckService.syntaxChecked.connect(self.__processResult) self.__initOnlineSyntaxCheck() self.isResourcesFile = False @@ -4962,23 +4962,18 @@ """ Private method to perform an automatic syntax check of the file. """ - if (self.isPy2File() or self.isPy3File()) is False: + if self.filetype not in self.syntaxCheckService.getLanguages(): return if Preferences.getEditor("AutoCheckSyntax"): if Preferences.getEditor("OnlineSyntaxCheck"): self.__onlineSyntaxCheckTimer.stop() - checkFlakes = Preferences.getFlakes("IncludeInSyntaxCheck") - ignoreStarImportWarnings = Preferences.getFlakes( - "IgnoreStarImportWarnings") - - self.internalServices.syntaxCheck( - self.fileName or "(Unnamed)", self.text(), checkFlakes, - ignoreStarImportWarnings, editor=self) + self.syntaxCheckService.syntaxCheck( + self.filetype, self.fileName or "(Unnamed)", self.text()) def __processResult( - self, fn, nok, fname, line, index, code, error, warnings): + self, fn, nok, line, index, code, error, warnings): """ Slot to report the resulting messages. @@ -4988,7 +4983,6 @@ @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) @@ -5885,7 +5879,7 @@ self.breakpointModel.rowsInserted.disconnect( self.__addBreakPoints) - self.internalServices.syntaxChecked.disconnect(self.__processResult) + self.syntaxCheckService.syntaxChecked.disconnect(self.__processResult) if self.spell: self.spell.stopIncrementalCheck()
--- a/UI/UserInterface.py Fri Jan 17 23:38:29 2014 +0100 +++ b/UI/UserInterface.py Fri Jan 31 22:11:45 2014 +0100 @@ -205,9 +205,6 @@ # Create the background service object from Utilities.BackgroundService import BackgroundService self.backgroundService = BackgroundService() - # And initialize the standard services - from Utilities.InternalServices import InternalServices - self.internalServices = InternalServices(self.backgroundService) # Generate an empty project object and multi project object from Project.Project import Project @@ -458,7 +455,6 @@ e5App().registerObject("DebugUI", self.debuggerUI) e5App().registerObject("DebugServer", debugServer) e5App().registerObject("BackgroundService", self.backgroundService) - e5App().registerObject("InternalServices", self.internalServices) e5App().registerObject("ViewManager", self.viewmanager) e5App().registerObject("Project", self.project) e5App().registerObject("ProjectBrowser", self.projectBrowser)
--- a/Utilities/BackgroundClient.py Fri Jan 17 23:38:29 2014 +0100 +++ b/Utilities/BackgroundClient.py Fri Jan 31 22:11:45 2014 +0100 @@ -36,7 +36,7 @@ self.services = {} self.connection = socket.create_connection((host, port)) - ver = b'2' if sys.version_info[0] == 2 else b'3' + ver = b'Python2' if sys.version_info[0] == 2 else b'Python3' self.connection.sendall(ver) self.connection.settimeout(0.25) @@ -124,7 +124,7 @@ """ # TODO: Wrap arguments so they can be serialized by JSON self.__send( - 'exception', '?', [str(exctype), str(excval), str(exctb)]) + 'EXCEPTION', '?', [str(exctype), str(excval), str(exctb)]) if __name__ == '__main__': if len(sys.argv) != 3:
--- a/Utilities/BackgroundService.py Fri Jan 17 23:38:29 2014 +0100 +++ b/Utilities/BackgroundService.py Fri Jan 31 22:11:45 2014 +0100 @@ -32,14 +32,14 @@ """ Class implementing the main part of the background service. """ - serviceNotAvailable = pyqtSignal(str, str, int, str) + serviceNotAvailable = pyqtSignal(str, str, str, str) def __init__(self): """ Constructor of the BackgroundService class. """ - self.processes = [None, None] - self.connections = [None, None] + self.processes = [] + self.connections = {} self.isWorking = None self.__queue = [] self.services = {} @@ -58,19 +58,20 @@ ## NOTE: Need the port if started external in debugger: print('BackgroundService listening on: %i' % port) if sys.platform == 'win32': - pyCompare = Utilities.samefilepath + interpreterCompare = Utilities.samefilepath else: - pyCompare = Utilities.samepath + interpreterCompare = Utilities.samepath - for pyIdx, pyName in enumerate(['Python', 'Python3']): + for pyName in ['Python', 'Python3']: interpreter = Preferences.getDebugger( pyName + "Interpreter") - if pyCompare(interpreter, sys.executable): + if interpreterCompare(interpreter, sys.executable): process = self.__startInternalClient(port) else: process = self.__startExternalClient(interpreter, port) - self.processes[pyIdx] = process + if process: + self.processes.append(process) def __startExternalClient(self, interpreter, port): """ @@ -78,7 +79,7 @@ @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 + @return the process object (QProcess or None) """ if interpreter == "" or not Utilities.isinpath(interpreter): return None @@ -112,44 +113,44 @@ client. """ if self.__queue and self.isWorking is None: - fx, fn, pyVer, data = self.__queue.pop(0) - self.isWorking = pyVer - self.__send(fx, fn, pyVer, data) + fx, lang, fn, data = self.__queue.pop(0) + self.isWorking = lang + self.__send(fx, lang, fn, data) - def __send(self, fx, fn, pyVer, data): + def __send(self, fx, lang, fn, data): """ Private method to send a job request to one of the clients. @param fx remote function name to execute (str) + @param lang language to connect to (str) @param fn filename for identification (str) - @param pyVer version for the required interpreter (int) @param data function argument(s) (any basic datatype) """ - packedData = json.dumps([fx, fn, data]) - if sys.version_info[0] == 3: - packedData = bytes(packedData, 'utf-8') - connection = self.connections[pyVer - 2] + connection = self.connections.get(lang) if connection is None: if fx != 'INIT': self.serviceNotAvailable.emit( - fx, fn, pyVer, self.trUtf8( - 'Python{0} interpreter not configured.').format(pyVer)) + fx, lang, fn, self.trUtf8( + '{0} not configured.').format(lang)) # Reset flag and continue processing queue self.isWorking = None self.__processQueue() else: + 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) connection.write(header) connection.write(packedData) - def __receive(self, channel): + def __receive(self, lang): """ Private method to receive the response from the clients. - @param channel of the incomming connection (int: 0 or 1) + @param lang language of the incomming connection (str) """ - connection = self.connections[channel] + connection = self.connections[lang] header = connection.read(8) length, datahash = struct.unpack(b'!II', header) @@ -163,49 +164,45 @@ packedData = packedData.decode('utf-8') # "check" if is's a tuple of 3 values fx, fn, data = json.loads(packedData) - self.__postResult(fx, fn, data) - 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 == 'INIT': pass - elif fx == 'exception': + elif fx == 'EXCEPTION': # Call sys.excepthook(type, value, traceback) to emulate the # exception which was caught on the client #sys.excepthook(*data) print(data) + elif data == 'Unknown service.': + callback = self.services.get((fx, lang)) + if callback: + callback[3](fx, lang, fn, data) else: - callback = self.services.get(fx) + callback = self.services.get((fx, lang)) if callback: callback[2](fn, *data) self.isWorking = None self.__processQueue() - def enqueueRequest(self, fx, fn, pyVer, data): + def enqueueRequest(self, fx, lang, fn, data): """ Implement a queued processing of incomming events. - Dublicate file checks update an older request to avoid overrun or - starving of the check. + Dublicate service requests updates an older request to avoid overrun or + starving of the services. @param fx function name of the service (str) + @param lang language to connect to (str) @param fn filename for identification (str) - @param pyVer version for the required interpreter (int) - @param data function argument(s) (any basic datatype) + @param data function argument(s) (any basic datatype(s)) """ - args = [fx, fn, pyVer, data] + args = [fx, lang, fn, data] if fx == 'INIT': self.__queue.insert(0, args) else: for pendingArg in self.__queue: + # Check if it's the same service request (fx, lang, fn equal) if pendingArg[:3] == args[:3]: + # Update the data pendingArg[3] = args[3] break else: @@ -213,29 +210,34 @@ self.__processQueue() def serviceConnect( - self, fx, modulepath, module, callback, onErrorCallback=None): + self, fx, lang, modulepath, module, callback, + onErrorCallback=None): """ Announce a new service to the background service/ client. @param fx function name of the service (str) + @param lang language of the new service (str) @param modulepath full path to the module (str) @param module name to import (str) @param callback function on service response (function) @param onErrorCallback function if client isn't available (function) """ - self.services[fx] = modulepath, module, callback, onErrorCallback - self.enqueueRequest('INIT', fx, 0, [modulepath, module]) - self.enqueueRequest('INIT', fx, 1, [modulepath, module]) + self.services[(fx, lang)] = \ + modulepath, module, callback, onErrorCallback + self.enqueueRequest('INIT', lang, fx, [modulepath, module]) if onErrorCallback: self.serviceNotAvailable.connect(onErrorCallback) - def serviceDisconnect(self, fx): + def serviceDisconnect(self, fx, lang): """ Remove the service from the service list. - @param fx function name of the service + @param fx function name of the service (function) + @param lang language of the service (str) """ - self.services.pop(fx, None) + serviceArgs = self.services.pop((fx, lang), None) + if serviceArgs and serviceArgs[3]: + self.serviceNotAvailable.disconnect(serviceArgs[3]) def on_newConnection(self): """ @@ -244,24 +246,28 @@ connection = self.nextPendingConnection() if not connection.waitForReadyRead(1000): return - ch = 0 if connection.read(1) == b'2' else 1 + lang = connection.read(64) + if sys.version_info[0] == 3: + lang = lang.decode('utf-8') # Avoid hanging of eric on shutdown - if self.connections[ch]: - self.connections[ch].close() - if self.isWorking == ch + 2: + if self.connections.get(lang): + self.connections[lang].close() + if self.isWorking == lang: self.isWorking = None - self.connections[ch] = connection + self.connections[lang] = connection connection.readyRead.connect( - lambda x=ch: self.__receive(x)) + lambda x=lang: self.__receive(x)) - for fx, args in self.services.items(): - self.enqueueRequest('INIT', fx, ch, args[:2]) + for (fx, lng), args in self.services.items(): + if lng == lang: + # Register service with modulepath and module + self.enqueueRequest('INIT', lng, fx, args[:2]) def shutdown(self): """ Cleanup the connections and processes when Eric is shuting down. """ - for connection in self.connections: + for connection in self.connections.values(): if connection: connection.close()
--- a/Utilities/InternalServices.py Fri Jan 17 23:38:29 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,177 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2013 - 2014 Detlev Offenbach <detlev@die-offenbachs.de> -# -# pylint: disable=C0103 - -""" -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 - -import os - -from PyQt4.QtCore import QObject, pyqtSignal -from PyQt4.QtGui import QApplication - -from eric5config import getConfig -from Utilities import determinePythonVersion - - -class InternalServices(QObject): - """ - Implement the standard services (syntax with flakes and the style check). - """ - syntaxChecked = pyqtSignal(str, bool, str, int, int, str, str, list) - styleChecked = pyqtSignal(str, dict, int, list) - #indentChecked = pyqtSignal(TBD) - - def __init__(self, backgroundService): - """ - Contructor of InternalServices. - - @param backgroundService to connect to - """ - super(InternalServices, self).__init__() - self.backgroundService = backgroundService - - ericPath = getConfig('ericDir') - # Syntax check - path = os.path.join(ericPath, 'Plugins', 'CheckerPlugins', - 'SyntaxChecker') - self.backgroundService.serviceConnect( - 'syntax', path, 'SyntaxCheck', - self.__translateSyntaxCheck, - lambda fx, fn, ver, msg: self.syntaxChecked.emit( - fn, True, fn, 0, 0, '', msg, [])) - - # Style check - path = os.path.join(ericPath, 'Plugins', 'CheckerPlugins', - 'CodeStyleChecker') - self.backgroundService.serviceConnect( - 'style', path, 'CodeStyleChecker', - self.__translateStyleCheck, - lambda fx, fn, ver, msg: self.styleChecked.emit( - fn, {}, 0, [[0, 0, '---- ' + msg, False, False]])) - -# # Indent check -# path = os.path.join(ericPath, 'Plugins', 'CheckerPlugins', -# 'Tabnanny') -# self.backgroundService.serviceConnect( -# 'indent', path, 'Tabnanny', -# self.__translateIndentCheck) - - def syntaxCheck(self, filename, source="", checkFlakes=True, - ignoreStarImportWarnings=False, pyVer=None, editor=None): - """ - Method to prepare to compile one Python source file to Python bytecode - and to perform a pyflakes check in another task. - - @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 pyVer version of the interpreter to use or None for - autodetect corresponding interpreter (int or None) - @keyparam editor if the file is opened already (Editor object) - """ - if pyVer is None: - pyVer = determinePythonVersion(filename, source, editor) - - data = [source, checkFlakes, ignoreStarImportWarnings] - self.backgroundService.enqueueRequest('syntax', filename, pyVer, data) - - def __translateSyntaxCheck( - self, fn, nok, fname, line, index, code, error, warnings): - """ - Slot to translate 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, col, message, list(msg_args)) - """ - for warning in warnings: - # Translate messages - msg_args = warning.pop() - translated = QApplication.translate( - 'py3Flakes', warning[4]).format(*msg_args) - # Avoid leading "u" at Python2 unicode strings - if translated.startswith("u'"): - translated = translated[1:] - warning[4] = translated.replace(" u'", " '") - - self.syntaxChecked.emit( - fn, nok, fname, line, index, code, error, warnings) - - def styleCheck(self, filename, source, args, pyVer=None, editor=None): - """ - Method to prepare a style check on one Python source file in another - task. - - @param filename source filename (string) - @param source string containing the code to check (string) - @param args arguments used by the codeStyleCheck function (list of - excludeMessages (str), includeMessages (str), repeatMessages - (bool), fixCodes (str), noFixCodes (str), fixIssues (bool), - maxLineLength (int), hangClosing (bool), docType (str), errors - (list of str), eol (str), encoding (str)) - @keyparam pyVer version of the interpreter to use or None for - autodetect corresponding interpreter (int or None) - @keyparam editor if the file is opened already (Editor object) - """ - if pyVer is None: - pyVer = determinePythonVersion(filename, source, editor) - - data = [source, args] - self.backgroundService.enqueueRequest('style', filename, pyVer, data) - - def __translateStyleCheck(self, fn, codeStyleCheckerStats, results): - """ - Privat slot called after perfoming a style check on one file. - - @param fn filename of the just checked file (str) - @param codeStyleCheckerStats stats of style and name check (dict) - @param results tuple for each found violation of style (tuple of - lineno (int), position (int), text (str), fixed (bool), - autofixing (bool), fixedMsg (str)) - """ - fixes = 0 - for result in results: - msg = result[2].split('@@') - if msg[0].startswith(('W', 'E')): - msgType = 'pep8' - elif msg[0].startswith('N'): - msgType = 'NamingStyleChecker' - else: - msgType = 'DocStyleChecker' - translMsg = msg[0][:5] + QApplication.translate( - msgType, msg[0][5:]).format(*msg[1:]) - - fixedMsg = result.pop() - if fixedMsg: - fixes += 1 - if '@@' in fixedMsg: - msg, param = fixedMsg.split('@@') - fixedMsg = QApplication.translate( - 'CodeStyleFixer', msg).format(param) - else: - fixedMsg = QApplication.translate( - 'CodeStyleFixer', fixedMsg) - - translMsg += "\n" + QApplication.translate( - 'CodeStyleCheckerDialog', "Fix: {0}").format(fixedMsg) - result[2] = translMsg - self.styleChecked.emit(fn, codeStyleCheckerStats, fixes, results)
--- a/eric5.e4p Fri Jan 17 23:38:29 2014 +0100 +++ b/eric5.e4p Fri Jan 31 22:11:45 2014 +0100 @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE Project SYSTEM "Project-5.1.dtd"> <!-- eric5 project file for project eric5 --> -<!-- Saved: 2014-01-14, 23:44:35 --> +<!-- Saved: 2014-01-30, 22:41:13 --> <!-- Copyright (C) 2014 Detlev Offenbach, detlev@die-offenbachs.de --> <Project version="5.1"> <Language>en_US</Language> @@ -1106,7 +1106,7 @@ <Source>Plugins/CheckerPlugins/SyntaxChecker/pyflakes/checker.py</Source> <Source>Plugins/CheckerPlugins/SyntaxChecker/pyflakes/messages.py</Source> <Source>Plugins/CheckerPlugins/SyntaxChecker/pyflakes/__init__.py</Source> - <Source>Utilities/InternalServices.py</Source> + <Source>Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckService.py</Source> </Sources> <Forms> <Form>PyUnit/UnittestDialog.ui</Form>