--- a/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheck.py Tue Apr 21 19:47:31 2015 +0200 +++ b/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheck.py Wed Apr 22 19:53:58 2015 +0200 @@ -11,6 +11,7 @@ import re import sys import traceback +import multiprocessing try: from pyflakes.checker import Checker @@ -32,6 +33,15 @@ return syntaxAndPyflakesCheck +def initBatchService(): + """ + Initialize the batch service and return the entry point. + + @return the entry point for the background client (function) + """ + return syntaxAndPyflakesBatchCheck + + def normalizeCode(codestring): """ Function to normalize the given code. @@ -92,6 +102,88 @@ (file name, line number, column, codestring (only at syntax errors), the message, a list with arguments for the message) """ + return __syntaxAndPyflakesCheck(filename, codestring, checkFlakes, + ignoreStarImportWarnings) + + +def syntaxAndPyflakesBatchCheck(argumentsList, send, fx, cancelled): + """ + Module function to check syntax for a batch of files. + + @param argumentsList list of arguments tuples as given for + syntaxAndPyflakesCheck + @param send reference to send function (function) + @param fx registered service name (string) + @param cancelled reference to function checking for a cancellation + (function) + """ + try: + NumberOfProcesses = multiprocessing.cpu_count() + if NumberOfProcesses >= 1: + NumberOfProcesses -= 1 + except NotImplementedError: + NumberOfProcesses = 1 + + # Create queues + taskQueue = multiprocessing.Queue() + doneQueue = multiprocessing.Queue() + + # Submit tasks (initially two time number of processes + initialTasks = 2 * NumberOfProcesses + for task in argumentsList[:initialTasks]: + taskQueue.put(task) + + # Start worker processes + for i in range(NumberOfProcesses): + multiprocessing.Process(target=worker, args=(taskQueue, doneQueue))\ + .start() + + # Get and send results + endIndex = len(argumentsList) - initialTasks + for i in range(len(argumentsList)): + filename, result = doneQueue.get() + send(fx, filename, result) + if cancelled(): + # just exit the loop ignoring the results of queued tasks + break + if i < endIndex: + taskQueue.put(argumentsList[i + initialTasks]) + + # Tell child processes to stop + for i in range(NumberOfProcesses): + taskQueue.put('STOP') + + +def worker(input, output): + """ + Module function acting as the parallel worker for the style check. + + @param input input queue (multiprocessing.Queue) + @param output output queue (multiprocessing.Queue) + """ + for filename, args in iter(input.get, 'STOP'): + source, checkFlakes, ignoreStarImportWarnings = args + result = __syntaxAndPyflakesCheck(filename, source, checkFlakes, + ignoreStarImportWarnings) + output.put((filename, result)) + + +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) + @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 dictionary with the keys 'error' and 'warnings' which + hold a list containing details about the error/ warnings + (file name, line number, column, codestring (only at syntax + errors), the message, a list with arguments for the message) + """ try: import builtins except ImportError: