diff -r 4c45d163c6ac -r 613e37fabd96 Debugger/DebugServer.py --- a/Debugger/DebugServer.py Sat Jun 02 12:46:57 2018 +0200 +++ b/Debugger/DebugServer.py Mon Jul 02 18:59:30 2018 +0200 @@ -218,10 +218,10 @@ # Change clientType if dependent interpreter not exist anymore # (maybe deinstalled,...) elif self.clientType == 'Python2' and Preferences.getDebugger( - "PythonInterpreter") == '': + "Python2VirtualEnv") == '': self.clientType = 'Python3' elif self.clientType == 'Python3' and Preferences.getDebugger( - "Python3Interpreter") == '': + "Python3VirtualEnv") == '': self.clientType = 'Python2' self.lastClientType = '' @@ -301,14 +301,15 @@ registeredInterfaces[interfaceName] = \ self.__debuggerInterfaces[interfaceName] - self.__debuggerInterfaces = {} self.__debuggerInterfaceRegistry = {} for interfaceName, getRegistryData in registeredInterfaces.items(): - self.registerDebuggerInterface(interfaceName, getRegistryData) + self.registerDebuggerInterface(interfaceName, getRegistryData, + reregister=True) self.__maxVariableSize = Preferences.getDebugger("MaxVariableSize") - def registerDebuggerInterface(self, interfaceName, getRegistryData): + def registerDebuggerInterface(self, interfaceName, getRegistryData, + reregister=False): """ Public method to register a debugger interface. @@ -320,8 +321,10 @@ list of associated file extensions and a function reference to create the debugger interface (see __createDebuggerInterface()) @type function + @param reregister flag indicating to re-register the interface + @type bool """ - if interfaceName in self.__debuggerInterfaces: + if interfaceName in self.__debuggerInterfaces and not reregister: E5MessageBox.warning( None, self.tr("Register Debugger Interface"), @@ -329,9 +332,10 @@ """ been registered. Ignoring this request.</p>""")) return + if not reregister: + self.__debuggerInterfaces[interfaceName] = getRegistryData registryDataList = getRegistryData() if registryDataList: - self.__debuggerInterfaces[interfaceName] = getRegistryData for clientLanguage, clientCapabilities, clientExtensions, \ interfaceCreator in registryDataList: self.__debuggerInterfaceRegistry[clientLanguage] = [ @@ -449,17 +453,21 @@ 'DebugClient/Type', self.clientType) def startClient(self, unplanned=True, clType=None, forProject=False, - runInConsole=False, interpreter=""): + runInConsole=False, venvName=""): """ Public method to start a debug client. - @keyparam unplanned flag indicating that the client has died (boolean) - @keyparam clType type of client to be started (string) - @keyparam forProject flag indicating a project related action (boolean) + @keyparam unplanned flag indicating that the client has died + @type bool + @keyparam clType type of client to be started + @type str + @keyparam forProject flag indicating a project related action + @type bool @keyparam runInConsole flag indicating to start the debugger in a - console window (boolean) - @keyparam interpreter interpreter to be used to execute the remote - side (string) + console window + @type bool + @keyparam venvName name of the virtual environment to be used + @type str """ self.running = False @@ -469,6 +477,10 @@ self.clientGone.emit(unplanned and self.debugging) if clType: + if clType not in self.getSupportedLanguages(): + # a not supported client language was requested + return + self.__setClientType(clType) # only start the client, if we are not in passive mode @@ -485,15 +497,15 @@ if not project.isDebugPropertiesLoaded(): self.clientProcess, isNetworked, clientInterpreter = \ self.debuggerInterface.startRemote( - self.serverPort(), runInConsole, interpreter) + self.serverPort(), runInConsole, venvName) else: self.clientProcess, isNetworked, clientInterpreter = \ self.debuggerInterface.startRemoteForProject( - self.serverPort(), runInConsole, interpreter) + self.serverPort(), runInConsole, venvName) else: self.clientProcess, isNetworked, clientInterpreter = \ self.debuggerInterface.startRemote( - self.serverPort(), runInConsole, interpreter) + self.serverPort(), runInConsole, venvName) if self.clientProcess: self.clientProcess.readyReadStandardError.connect( @@ -733,7 +745,25 @@ @return interpreter of the debug client (string) """ return self.clientInterpreter + + def getClientType(self): + """ + Public method to get the currently running debug client type. + @return debug client type + @rtype str + """ + return self.clientType + + def isClientProcessUp(self): + """ + Public method to check, if the debug client process is up. + + @return flag indicating a running debug client process + @rtype bool + """ + return self.clientProcess is not None + def __newConnection(self): """ Private slot to handle a new connection. @@ -804,38 +834,61 @@ pass self.debuggerInterface.remoteEnvironment(envdict) - def remoteLoad(self, interpreter, fn, argv, wd, env, autoClearShell=True, + def remoteLoad(self, venvName, fn, argv, wd, env, autoClearShell=True, tracePython=False, autoContinue=True, forProject=False, runInConsole=False, autoFork=False, forkChild=False, clientType="", enableCallTrace=False): """ Public method to load a new program to debug. - @param interpreter interpreter to be used to execute the remote - side (string) - @param fn the filename to debug (string) - @param argv the commandline arguments to pass to the program (string) - @param wd the working directory for the program (string) - @param env environment settings (string) + @param venvName name of the virtual environment to be used + @type str + @param fn the filename to debug + @type str + @param argv the command line arguments to pass to the program + @type str + @param wd the working directory for the program + @type str + @param env environment parameter settings + @type str @keyparam autoClearShell flag indicating, that the interpreter window - should be cleared (boolean) + should be cleared + @type bool @keyparam tracePython flag indicating if the Python library should be - traced as well (boolean) + traced as well + @type bool @keyparam autoContinue flag indicating, that the debugger should not - stop at the first executable line (boolean) - @keyparam forProject flag indicating a project related action (boolean) + stop at the first executable line + @type bool + @keyparam forProject flag indicating a project related action + @type bool @keyparam runInConsole flag indicating to start the debugger in a - console window (boolean) - @keyparam autoFork flag indicating the automatic fork mode (boolean) + console window + @type bool + @keyparam autoFork flag indicating the automatic fork mode + @type bool @keyparam forkChild flag indicating to debug the child after forking - (boolean) - @keyparam clientType client type to be used (string) + @type bool + @keyparam clientType client type to be used + @type str @keyparam enableCallTrace flag indicating to enable the call trace - function (boolean) + function + @type bool """ self.__autoClearShell = autoClearShell self.__autoContinue = autoContinue + if clientType not in self.getSupportedLanguages(): + # a not supported client language was requested + E5MessageBox.critical( + None, + self.tr("Start Debugger"), + self.tr( + """<p>The debugger type <b>{0}</b> is not supported""" + """ or not configured.</p>""").format(clientType) + ) + return + # Restart the client try: if clientType: @@ -846,7 +899,7 @@ except KeyError: self.__setClientType('Python3') # assume it is a Python3 file self.startClient(False, forProject=forProject, - runInConsole=runInConsole, interpreter=interpreter) + runInConsole=runInConsole, venvName=venvName) self.setCallTraceEnabled(enableCallTrace) self.remoteEnvironment(env) @@ -858,30 +911,50 @@ self.__restoreBreakpoints() self.__restoreWatchpoints() - def remoteRun(self, interpreter, fn, argv, wd, env, autoClearShell=True, + def remoteRun(self, venvName, fn, argv, wd, env, autoClearShell=True, forProject=False, runInConsole=False, autoFork=False, forkChild=False, clientType=""): """ Public method to load a new program to run. - @param interpreter interpreter to be used to execute the remote - side (string) - @param fn the filename to run (string) - @param argv the commandline arguments to pass to the program (string) - @param wd the working directory for the program (string) - @param env environment settings (string) + @param venvName name of the virtual environment to be used + @type str + @param fn the filename to debug + @type str + @param argv the command line arguments to pass to the program + @type str + @param wd the working directory for the program + @type str + @param env environment parameter settings + @type str @keyparam autoClearShell flag indicating, that the interpreter window - should be cleared (boolean) - @keyparam forProject flag indicating a project related action (boolean) + should be cleared + @type bool + @keyparam forProject flag indicating a project related action + @type bool @keyparam runInConsole flag indicating to start the debugger in a - console window (boolean) - @keyparam autoFork flag indicating the automatic fork mode (boolean) + console window + @type bool + @keyparam autoFork flag indicating the automatic fork mode + @type bool @keyparam forkChild flag indicating to debug the child after forking - (boolean) - @keyparam clientType client type to be used (string) + @type bool + @keyparam clientType client type to be used + @type str """ self.__autoClearShell = autoClearShell + if clientType not in self.getSupportedLanguages(): + E5MessageBox.critical( + None, + self.tr("Start Debugger"), + self.tr( + """<p>The debugger type <b>{0}</b> is not supported""" + """ or not configured.</p>""").format(clientType) + ) + # a not supported client language was requested + return + # Restart the client try: if clientType: @@ -892,7 +965,7 @@ except KeyError: self.__setClientType('Python3') # assume it is a Python3 file self.startClient(False, forProject=forProject, - runInConsole=runInConsole, interpreter=interpreter) + runInConsole=runInConsole, venvName=venvName) self.remoteEnvironment(env) @@ -900,29 +973,49 @@ self.debugging = False self.running = True - def remoteCoverage(self, interpreter, fn, argv, wd, env, + def remoteCoverage(self, venvName, fn, argv, wd, env, autoClearShell=True, erase=False, forProject=False, runInConsole=False, clientType=""): """ Public method to load a new program to collect coverage data. - @param interpreter interpreter to be used to execute the remote - side (string) - @param fn the filename to run (string) - @param argv the commandline arguments to pass to the program (string) - @param wd the working directory for the program (string) - @param env environment settings (string) + @param venvName name of the virtual environment to be used + @type str + @param fn the filename to debug + @type str + @param argv the command line arguments to pass to the program + @type str + @param wd the working directory for the program + @type str + @param env environment parameter settings + @type str @keyparam autoClearShell flag indicating, that the interpreter window - should be cleared (boolean) + should be cleared + @type bool @keyparam erase flag indicating that coverage info should be - cleared first (boolean) - @keyparam forProject flag indicating a project related action (boolean) + cleared first + @type bool + @keyparam forProject flag indicating a project related action + @type bool @keyparam runInConsole flag indicating to start the debugger in a - console window (boolean) - @keyparam clientType client type to be used (string) + console window + @type bool + @keyparam clientType client type to be used + @type str """ self.__autoClearShell = autoClearShell + if clientType not in self.getSupportedLanguages(): + # a not supported client language was requested + E5MessageBox.critical( + None, + self.tr("Start Debugger"), + self.tr( + """<p>The debugger type <b>{0}</b> is not supported""" + """ or not configured.</p>""").format(clientType) + ) + return + # Restart the client try: if clientType: @@ -933,7 +1026,7 @@ except KeyError: self.__setClientType('Python3') # assume it is a Python3 file self.startClient(False, forProject=forProject, - runInConsole=runInConsole, interpreter=interpreter) + runInConsole=runInConsole, venvName=venvName) self.remoteEnvironment(env) @@ -941,29 +1034,49 @@ self.debugging = False self.running = True - def remoteProfile(self, interpreter, fn, argv, wd, env, + def remoteProfile(self, venvName, fn, argv, wd, env, autoClearShell=True, erase=False, forProject=False, runInConsole=False, clientType=""): """ Public method to load a new program to collect profiling data. - @param interpreter interpreter to be used to execute the remote - side (string) - @param fn the filename to run (string) - @param argv the commandline arguments to pass to the program (string) - @param wd the working directory for the program (string) - @param env environment settings (string) + @param venvName name of the virtual environment to be used + @type str + @param fn the filename to debug + @type str + @param argv the command line arguments to pass to the program + @type str + @param wd the working directory for the program + @type str + @param env environment parameter settings + @type str @keyparam autoClearShell flag indicating, that the interpreter window - should be cleared (boolean) - @keyparam erase flag indicating that timing info should be cleared - first (boolean) - @keyparam forProject flag indicating a project related action (boolean) + should be cleared + @type bool + @keyparam erase flag indicating that coverage info should be + cleared first + @type bool + @keyparam forProject flag indicating a project related action + @type bool @keyparam runInConsole flag indicating to start the debugger in a - console window (boolean) - @keyparam clientType client type to be used (string) + console window + @type bool + @keyparam clientType client type to be used + @type str """ self.__autoClearShell = autoClearShell + if clientType not in self.getSupportedLanguages(): + # a not supported client language was requested + E5MessageBox.critical( + None, + self.tr("Start Debugger"), + self.tr( + """<p>The debugger type <b>{0}</b> is not supported""" + """ or not configured.</p>""").format(clientType) + ) + return + # Restart the client try: if clientType: @@ -974,7 +1087,7 @@ except KeyError: self.__setClientType('Python3') # assume it is a Python3 file self.startClient(False, forProject=forProject, - runInConsole=runInConsole, interpreter=interpreter) + runInConsole=runInConsole, venvName=venvName) self.remoteEnvironment(env) @@ -1203,6 +1316,17 @@ (boolean) @keyparam clientType client type to be used (string) """ + if clientType not in self.getSupportedLanguages(): + # a not supported client language was requested + E5MessageBox.critical( + None, + self.tr("Start Debugger"), + self.tr( + """<p>The debugger type <b>{0}</b> is not supported""" + """ or not configured.</p>""").format(clientType) + ) + return + # Restart the client if there is already a program loaded. try: if clientType: @@ -1432,8 +1556,12 @@ @param capabilities bitmaks with the client capabilities (integer) @param clientType type of the debug client (string) """ - self.__debuggerInterfaceRegistry[clientType][0] = capabilities - self.clientCapabilities.emit(capabilities, clientType) + try: + self.__debuggerInterfaceRegistry[clientType][0] = capabilities + self.clientCapabilities.emit(capabilities, clientType) + except KeyError: + # ignore silently + pass def signalClientCompletionList(self, completionList, text): """