Debugger/DebuggerInterfacePython2.py

branch
maintenance
changeset 5863
0752bdd8db77
parent 5826
ea0f0f066b1d
parent 5862
0a88812e43bf
child 5864
86ccabe751ac
diff -r ea0f0f066b1d -r 0752bdd8db77 Debugger/DebuggerInterfacePython2.py
--- a/Debugger/DebuggerInterfacePython2.py	Thu Aug 03 14:50:59 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1102 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2007 - 2017 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing the Python debugger interface for the debug server.
-"""
-
-from __future__ import unicode_literals
-
-import sys
-import os
-
-from PyQt5.QtCore import QObject, QTextCodec, QProcess, QProcessEnvironment, \
-    QTimer
-from PyQt5.QtWidgets import QInputDialog
-
-from E5Gui.E5Application import e5App
-from E5Gui import E5MessageBox
-
-from . import DebugClientCapabilities
-
-import Preferences
-import Utilities
-
-from eric6config import getConfig
-
-
-ClientDefaultCapabilities = DebugClientCapabilities.HasAll
-
-
-class DebuggerInterfacePython2(QObject):
-    """
-    Class implementing the Python 2 debugger interface for the debug server.
-    """
-    def __init__(self, debugServer, passive):
-        """
-        Constructor
-        
-        @param debugServer reference to the debug server (DebugServer)
-        @param passive flag indicating passive connection mode (boolean)
-        """
-        super(DebuggerInterfacePython2, self).__init__()
-        
-        self.__isNetworked = True
-        self.__autoContinue = False
-        
-        self.debugServer = debugServer
-        self.passive = passive
-        self.process = None
-        
-        self.qsock = None
-        self.queue = []
-        
-        # set default values for capabilities of clients
-        self.clientCapabilities = ClientDefaultCapabilities
-        
-        # set translation function
-        self.translate = self.__identityTranslation
-        
-        self.codec = QTextCodec.codecForName(
-            Preferences.getSystem("StringEncoding"))
-        
-        if passive:
-            # set translation function
-            if Preferences.getDebugger("PathTranslation"):
-                self.translateRemote = \
-                    Preferences.getDebugger("PathTranslationRemote")
-                self.translateLocal = \
-                    Preferences.getDebugger("PathTranslationLocal")
-                self.translate = self.__remoteTranslation
-            else:
-                self.translate = self.__identityTranslation
-        
-        # attribute to remember the name of the executed script
-        self.__scriptName = ""
-
-    def __identityTranslation(self, fn, remote2local=True):
-        """
-        Private method to perform the identity path translation.
-        
-        @param fn filename to be translated (string)
-        @param remote2local flag indicating the direction of translation
-            (False = local to remote, True = remote to local [default])
-        @return translated filename (string)
-        """
-        return fn
-        
-    def __remoteTranslation(self, fn, remote2local=True):
-        """
-        Private method to perform the path translation.
-        
-        @param fn filename to be translated (string)
-        @param remote2local flag indicating the direction of translation
-            (False = local to remote, True = remote to local [default])
-        @return translated filename (string)
-        """
-        if remote2local:
-            return fn.replace(self.translateRemote, self.translateLocal)
-        else:
-            return fn.replace(self.translateLocal, self.translateRemote)
-        
-    def __startProcess(self, program, arguments, environment=None):
-        """
-        Private method to start the debugger client process.
-        
-        @param program name of the executable to start (string)
-        @param arguments arguments to be passed to the program (list of string)
-        @param environment dictionary of environment settings to pass
-            (dict of string)
-        @return the process object (QProcess) or None
-        """
-        proc = QProcess()
-        if environment is not None:
-            env = QProcessEnvironment()
-            for key, value in list(environment.items()):
-                env.insert(key, value)
-            proc.setProcessEnvironment(env)
-        args = []
-        for arg in arguments:
-            args.append(arg)
-        proc.start(program, args)
-        if not proc.waitForStarted(10000):
-            proc = None
-        
-        return proc
-        
-    def startRemote(self, port, runInConsole):
-        """
-        Public method to start a remote Python interpreter.
-        
-        @param port portnumber the debug server is listening on (integer)
-        @param runInConsole flag indicating to start the debugger in a
-            console window (boolean)
-        @return client process object (QProcess), a flag to indicate
-            a network connection (boolean) and the name of the interpreter
-            in case of a local execution (string)
-        """
-        interpreter = Preferences.getDebugger("PythonInterpreter")
-        if interpreter == "":
-            E5MessageBox.critical(
-                None,
-                self.tr("Start Debugger"),
-                self.tr(
-                    """<p>No Python2 interpreter configured.</p>"""))
-            return None, False, ""
-        
-        debugClientType = Preferences.getDebugger("DebugClientType")
-        if debugClientType == "standard":
-            debugClient = os.path.join(getConfig('ericDir'),
-                                       "DebugClients", "Python",
-                                       "DebugClient.py")
-        else:
-            debugClient = Preferences.getDebugger("DebugClient")
-            if debugClient == "":
-                debugClient = os.path.join(sys.path[0],
-                                           "DebugClients", "Python",
-                                           "DebugClient.py")
-        
-        redirect = str(Preferences.getDebugger("PythonRedirect"))
-        noencoding = Preferences.getDebugger("PythonNoEncoding") and \
-            '--no-encoding' or ''
-        
-        if Preferences.getDebugger("RemoteDbgEnabled"):
-            ipaddr = self.debugServer.getHostAddress(False)
-            rexec = Preferences.getDebugger("RemoteExecution")
-            rhost = Preferences.getDebugger("RemoteHost")
-            if rhost == "":
-                rhost = "localhost"
-            if rexec:
-                args = Utilities.parseOptionString(rexec) + \
-                    [rhost, interpreter, debugClient,
-                        noencoding, str(port), redirect, ipaddr]
-                args[0] = Utilities.getExecutablePath(args[0])
-                process = self.__startProcess(args[0], args[1:])
-                if process is None:
-                    E5MessageBox.critical(
-                        None,
-                        self.tr("Start Debugger"),
-                        self.tr(
-                            """<p>The debugger backend could not be"""
-                            """ started.</p>"""))
-                
-                # set translation function
-                if Preferences.getDebugger("PathTranslation"):
-                    self.translateRemote = \
-                        Preferences.getDebugger("PathTranslationRemote")
-                    self.translateLocal = \
-                        Preferences.getDebugger("PathTranslationLocal")
-                    self.translate = self.__remoteTranslation
-                else:
-                    self.translate = self.__identityTranslation
-                return process, self.__isNetworked, ""
-        
-        # set translation function
-        self.translate = self.__identityTranslation
-        
-        # setup the environment for the debugger
-        if Preferences.getDebugger("DebugEnvironmentReplace"):
-            clientEnv = {}
-        else:
-            clientEnv = os.environ.copy()
-        envlist = Utilities.parseEnvironmentString(
-            Preferences.getDebugger("DebugEnvironment"))
-        for el in envlist:
-            try:
-                key, value = el.split('=', 1)
-                if value.startswith('"') or value.startswith("'"):
-                    value = value[1:-1]
-                clientEnv[str(key)] = str(value)
-            except ValueError:
-                pass
-        
-        ipaddr = self.debugServer.getHostAddress(True)
-        if runInConsole or Preferences.getDebugger("ConsoleDbgEnabled"):
-            ccmd = Preferences.getDebugger("ConsoleDbgCommand")
-            if ccmd:
-                args = Utilities.parseOptionString(ccmd) + \
-                    [interpreter, os.path.abspath(debugClient),
-                        noencoding, str(port), '0', ipaddr]
-                args[0] = Utilities.getExecutablePath(args[0])
-                process = self.__startProcess(args[0], args[1:], clientEnv)
-                if process is None:
-                    E5MessageBox.critical(
-                        None,
-                        self.tr("Start Debugger"),
-                        self.tr(
-                            """<p>The debugger backend could not be"""
-                            """ started.</p>"""))
-                return process, self.__isNetworked, interpreter
-        
-        process = self.__startProcess(
-            interpreter,
-            [debugClient, noencoding, str(port), redirect, ipaddr],
-            clientEnv)
-        if process is None:
-            E5MessageBox.critical(
-                None,
-                self.tr("Start Debugger"),
-                self.tr(
-                    """<p>The debugger backend could not be started.</p>"""))
-        return process, self.__isNetworked, interpreter
-
-    def startRemoteForProject(self, port, runInConsole):
-        """
-        Public method to start a remote Python interpreter for a project.
-        
-        @param port portnumber the debug server is listening on (integer)
-        @param runInConsole flag indicating to start the debugger in a
-            console window (boolean)
-        @return client process object (QProcess), a flag to indicate
-            a network connection (boolean) and the name of the interpreter
-            in case of a local execution (string)
-        """
-        project = e5App().getObject("Project")
-        if not project.isDebugPropertiesLoaded():
-            return None, self.__isNetworked, ""
-        
-        # start debugger with project specific settings
-        interpreter = project.getDebugProperty("INTERPRETER")
-        debugClient = project.getDebugProperty("DEBUGCLIENT")
-        
-        redirect = str(project.getDebugProperty("REDIRECT"))
-        noencoding = \
-            project.getDebugProperty("NOENCODING") and '--no-encoding' or ''
-        
-        if project.getDebugProperty("REMOTEDEBUGGER"):
-            ipaddr = self.debugServer.getHostAddress(False)
-            rexec = project.getDebugProperty("REMOTECOMMAND")
-            rhost = project.getDebugProperty("REMOTEHOST")
-            if rhost == "":
-                rhost = "localhost"
-            if rexec:
-                args = Utilities.parseOptionString(rexec) + \
-                    [rhost, interpreter, os.path.abspath(debugClient),
-                        noencoding, str(port), redirect, ipaddr]
-                args[0] = Utilities.getExecutablePath(args[0])
-                process = self.__startProcess(args[0], args[1:])
-                if process is None:
-                    E5MessageBox.critical(
-                        None,
-                        self.tr("Start Debugger"),
-                        self.tr(
-                            """<p>The debugger backend could not be"""
-                            """ started.</p>"""))
-                # set translation function
-                if project.getDebugProperty("PATHTRANSLATION"):
-                    self.translateRemote = \
-                        project.getDebugProperty("REMOTEPATH")
-                    self.translateLocal = \
-                        project.getDebugProperty("LOCALPATH")
-                    self.translate = self.__remoteTranslation
-                else:
-                    self.translate = self.__identityTranslation
-                return process, self.__isNetworked, ""
-        
-        # set translation function
-        self.translate = self.__identityTranslation
-        
-        # setup the environment for the debugger
-        if project.getDebugProperty("ENVIRONMENTOVERRIDE"):
-            clientEnv = {}
-        else:
-            clientEnv = os.environ.copy()
-        envlist = Utilities.parseEnvironmentString(
-            project.getDebugProperty("ENVIRONMENTSTRING"))
-        for el in envlist:
-            try:
-                key, value = el.split('=', 1)
-                if value.startswith('"') or value.startswith("'"):
-                    value = value[1:-1]
-                clientEnv[str(key)] = str(value)
-            except ValueError:
-                pass
-        
-        ipaddr = self.debugServer.getHostAddress(True)
-        if runInConsole or project.getDebugProperty("CONSOLEDEBUGGER"):
-            ccmd = project.getDebugProperty("CONSOLECOMMAND") or \
-                Preferences.getDebugger("ConsoleDbgCommand")
-            if ccmd:
-                args = Utilities.parseOptionString(ccmd) + \
-                    [interpreter, os.path.abspath(debugClient),
-                        noencoding, str(port), '0', ipaddr]
-                args[0] = Utilities.getExecutablePath(args[0])
-                process = self.__startProcess(args[0], args[1:], clientEnv)
-                if process is None:
-                    E5MessageBox.critical(
-                        None,
-                        self.tr("Start Debugger"),
-                        self.tr(
-                            """<p>The debugger backend could not be"""
-                            """ started.</p>"""))
-                return process, self.__isNetworked, interpreter
-        
-        process = self.__startProcess(
-            interpreter,
-            [debugClient, noencoding, str(port), redirect, ipaddr],
-            clientEnv)
-        if process is None:
-            E5MessageBox.critical(
-                None,
-                self.tr("Start Debugger"),
-                self.tr(
-                    """<p>The debugger backend could not be started.</p>"""))
-        return process, self.__isNetworked, interpreter
-
-    def getClientCapabilities(self):
-        """
-        Public method to retrieve the debug clients capabilities.
-        
-        @return debug client capabilities (integer)
-        """
-        return self.clientCapabilities
-        
-    def newConnection(self, sock):
-        """
-        Public slot to handle a new connection.
-        
-        @param sock reference to the socket object (QTcpSocket)
-        @return flag indicating success (boolean)
-        """
-        # If we already have a connection, refuse this one.  It will be closed
-        # automatically.
-        if self.qsock is not None:
-            return False
-        
-        sock.disconnected.connect(self.debugServer.startClient)
-        sock.readyRead.connect(self.__parseClientLine)
-        
-        self.qsock = sock
-        
-        # Get the remote clients capabilities
-        self.remoteCapabilities()
-        return True
-        
-    def flush(self):
-        """
-        Public slot to flush the queue.
-        """
-        # Send commands that were waiting for the connection.
-        for cmd in self.queue:
-            self.qsock.write(cmd.encode('utf8', 'backslashreplace'))
-        
-        self.queue = []
-        
-    def shutdown(self):
-        """
-        Public method to cleanly shut down.
-        
-        It closes our socket and shuts down
-        the debug client. (Needed on Win OS)
-        """
-        if self.qsock is None:
-            return
-        
-        # do not want any slots called during shutdown
-        self.qsock.disconnected.disconnect(self.debugServer.startClient)
-        self.qsock.readyRead.disconnect(self.__parseClientLine)
-        
-        # close down socket, and shut down client as well.
-        self.__sendJsonCommand("RequestShutdown", {})
-        self.qsock.flush()
-        self.qsock.close()
-        
-        # reinitialize
-        self.qsock = None
-        self.queue = []
-        
-    def isConnected(self):
-        """
-        Public method to test, if a debug client has connected.
-        
-        @return flag indicating the connection status (boolean)
-        """
-        return self.qsock is not None
-        
-    def remoteEnvironment(self, env):
-        """
-        Public method to set the environment for a program to debug, run, ...
-        
-        @param env environment settings (dictionary)
-        """
-        self.__sendJsonCommand("RequestEnvironment", {"environment": env})
-        
-    def remoteLoad(self, fn, argv, wd, traceInterpreter=False,
-                   autoContinue=True, autoFork=False, forkChild=False):
-        """
-        Public method to load a new program to debug.
-        
-        @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)
-        @keyparam traceInterpreter flag indicating if the interpreter library
-            should be traced as well (boolean)
-        @keyparam autoContinue flag indicating, that the debugger should not
-            stop at the first executable line (boolean)
-        @keyparam autoFork flag indicating the automatic fork mode (boolean)
-        @keyparam forkChild flag indicating to debug the child after forking
-            (boolean)
-        """
-        self.__autoContinue = autoContinue
-        self.__scriptName = os.path.abspath(fn)
-        
-        wd = self.translate(wd, False)
-        fn = self.translate(os.path.abspath(fn), False)
-        self.__sendJsonCommand("RequestLoad", {
-            "workdir": wd,
-            "filename": fn,
-            "argv": Utilities.parseOptionString(argv),
-            "traceInterpreter": traceInterpreter,
-            "autofork": autoFork,
-            "forkChild": forkChild,
-        })
-        
-    def remoteRun(self, fn, argv, wd, autoFork=False, forkChild=False):
-        """
-        Public method to load a new program to run.
-        
-        @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)
-        @keyparam autoFork flag indicating the automatic fork mode (boolean)
-        @keyparam forkChild flag indicating to debug the child after forking
-            (boolean)
-        """
-        self.__scriptName = os.path.abspath(fn)
-        
-        wd = self.translate(wd, False)
-        fn = self.translate(os.path.abspath(fn), False)
-        self.__sendJsonCommand("RequestRun", {
-            "workdir": wd,
-            "filename": fn,
-            "argv": Utilities.parseOptionString(argv),
-            "autofork": autoFork,
-            "forkChild": forkChild,
-        })
-        
-    def remoteCoverage(self, fn, argv, wd, erase=False):
-        """
-        Public method to load a new program to collect coverage data.
-        
-        @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)
-        @keyparam erase flag indicating that coverage info should be
-            cleared first (boolean)
-        """
-        self.__scriptName = os.path.abspath(fn)
-        
-        wd = self.translate(wd, False)
-        fn = self.translate(os.path.abspath(fn), False)
-        self.__sendJsonCommand("RequestCoverage", {
-            "workdir": wd,
-            "filename": fn,
-            "argv": Utilities.parseOptionString(argv),
-            "erase": erase,
-        })
-
-    def remoteProfile(self, fn, argv, wd, erase=False):
-        """
-        Public method to load a new program to collect profiling data.
-        
-        @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)
-        @keyparam erase flag indicating that timing info should be cleared
-            first (boolean)
-        """
-        self.__scriptName = os.path.abspath(fn)
-        
-        wd = self.translate(wd, False)
-        fn = self.translate(os.path.abspath(fn), False)
-        self.__sendJsonCommand("RequestProfile", {
-            "workdir": wd,
-            "filename": fn,
-            "argv": Utilities.parseOptionString(argv),
-            "erase": erase,
-        })
-
-    def remoteStatement(self, stmt):
-        """
-        Public method to execute a Python statement.
-        
-        @param stmt the Python statement to execute (string). It
-              should not have a trailing newline.
-        """
-        self.__sendJsonCommand("ExecuteStatement", {
-            "statement": stmt,
-        })
-
-    def remoteStep(self):
-        """
-        Public method to single step the debugged program.
-        """
-        self.__sendJsonCommand("RequestStep", {})
-
-    def remoteStepOver(self):
-        """
-        Public method to step over the debugged program.
-        """
-        self.__sendJsonCommand("RequestStepOver", {})
-
-    def remoteStepOut(self):
-        """
-        Public method to step out the debugged program.
-        """
-        self.__sendJsonCommand("RequestStepOut", {})
-
-    def remoteStepQuit(self):
-        """
-        Public method to stop the debugged program.
-        """
-        self.__sendJsonCommand("RequestStepQuit", {})
-
-    def remoteContinue(self, special=False):
-        """
-        Public method to continue the debugged program.
-        
-        @param special flag indicating a special continue operation (boolean)
-        """
-        self.__sendJsonCommand("RequestContinue", {
-            "special": special,
-        })
-
-    def remoteMoveIP(self, line):
-        """
-        Public method to move the instruction pointer to a different line.
-        
-        @param line the new line, where execution should be continued
-        """
-        self.__sendJsonCommand("RequestMoveIP", {
-            "newLine": line,
-        })
-
-    def remoteBreakpoint(self, fn, line, setBreakpoint, cond=None, temp=False):
-        """
-        Public method to set or clear a breakpoint.
-        
-        @param fn filename the breakpoint belongs to (string)
-        @param line linenumber of the breakpoint (int)
-        @param setBreakpoint flag indicating setting or resetting a
-            breakpoint (boolean)
-        @param cond condition of the breakpoint (string)
-        @param temp flag indicating a temporary breakpoint (boolean)
-        """
-        self.__sendJsonCommand("RequestBreakpoint", {
-            "filename": self.translate(fn, False),
-            "line": line,
-            "temporary": temp,
-            "setBreakpoint": setBreakpoint,
-            "condition": cond,
-        })
-        
-    def remoteBreakpointEnable(self, fn, line, enable):
-        """
-        Public method to enable or disable a breakpoint.
-        
-        @param fn filename the breakpoint belongs to (string)
-        @param line linenumber of the breakpoint (int)
-        @param enable flag indicating enabling or disabling a breakpoint
-            (boolean)
-        """
-        self.__sendJsonCommand("RequestBreakpointEnable", {
-            "filename": self.translate(fn, False),
-            "line": line,
-            "enable": enable,
-        })
-        
-    def remoteBreakpointIgnore(self, fn, line, count):
-        """
-        Public method to ignore a breakpoint the next couple of occurrences.
-        
-        @param fn filename the breakpoint belongs to (string)
-        @param line linenumber of the breakpoint (int)
-        @param count number of occurrences to ignore (int)
-        """
-        self.__sendJsonCommand("RequestBreakpointIgnore", {
-            "filename": self.translate(fn, False),
-            "line": line,
-            "count": count,
-        })
-        
-    def remoteWatchpoint(self, cond, setWatch, temp=False):
-        """
-        Public method to set or clear a watch expression.
-        
-        @param cond expression of the watch expression (string)
-        @param setWatch flag indicating setting or resetting a watch expression
-            (boolean)
-        @param temp flag indicating a temporary watch expression (boolean)
-        """
-        # cond is combination of cond and special (s. watch expression viewer)
-        self.__sendJsonCommand("RequestWatch", {
-            "temporary": temp,
-            "setWatch": setWatch,
-            "condition": cond,
-        })
-    
-    def remoteWatchpointEnable(self, cond, enable):
-        """
-        Public method to enable or disable a watch expression.
-        
-        @param cond expression of the watch expression (string)
-        @param enable flag indicating enabling or disabling a watch expression
-            (boolean)
-        """
-        # cond is combination of cond and special (s. watch expression viewer)
-        self.__sendJsonCommand("RequestWatchEnable", {
-            "condition": cond,
-            "enable": enable,
-        })
-    
-    def remoteWatchpointIgnore(self, cond, count):
-        """
-        Public method to ignore a watch expression the next couple of
-        occurrences.
-        
-        @param cond expression of the watch expression (string)
-        @param count number of occurrences to ignore (int)
-        """
-        # cond is combination of cond and special (s. watch expression viewer)
-        self.__sendJsonCommand("RequestWatchIgnore", {
-            "condition": cond,
-            "count": count,
-        })
-    
-    def remoteRawInput(self, s):
-        """
-        Public method to send the raw input to the debugged program.
-        
-        @param s the raw input (string)
-        """
-        self.__sendJsonCommand("RawInput", {
-            "input": s,
-        })
-        
-    def remoteThreadList(self):
-        """
-        Public method to request the list of threads from the client.
-        """
-        self.__sendJsonCommand("RequestThreadList", {})
-        
-    def remoteSetThread(self, tid):
-        """
-        Public method to request to set the given thread as current thread.
-        
-        @param tid id of the thread (integer)
-        """
-        self.__sendJsonCommand("RequestThreadSet", {
-            "threadID": tid,
-        })
-        
-    def remoteClientVariables(self, scope, filterList, framenr=0):
-        """
-        Public method to request the variables of the debugged program.
-        
-        @param scope the scope of the variables (0 = local, 1 = global)
-        @param filterList list of variable types to filter out (list of int)
-        @param framenr framenumber of the variables to retrieve (int)
-        """
-        self.__sendJsonCommand("RequestVariables", {
-            "frameNumber": framenr,
-            "scope": scope,
-            "filters": filterList,
-        })
-        
-    def remoteClientVariable(self, scope, filterList, var, framenr=0):
-        """
-        Public method to request the variables of the debugged program.
-        
-        @param scope the scope of the variables (0 = local, 1 = global)
-        @param filterList list of variable types to filter out (list of int)
-        @param var list encoded name of variable to retrieve (string)
-        @param framenr framenumber of the variables to retrieve (int)
-        """
-        self.__sendJsonCommand("RequestVariable", {
-            "variable": var,
-            "frameNumber": framenr,
-            "scope": scope,
-            "filters": filterList,
-        })
-        
-    def remoteClientSetFilter(self, scope, filterStr):
-        """
-        Public method to set a variables filter list.
-        
-        @param scope the scope of the variables (0 = local, 1 = global)
-        @param filterStr regexp string for variable names to filter out
-            (string)
-        """
-        self.__sendJsonCommand("RequestSetFilter", {
-            "scope": scope,
-            "filter": filterStr,
-        })
-        
-    def setCallTraceEnabled(self, on):
-        """
-        Public method to set the call trace state.
-        
-        @param on flag indicating to enable the call trace function (boolean)
-        """
-        self.__sendJsonCommand("RequestCallTrace", {
-            "enable": on,
-        })
-    
-    def remoteBanner(self):
-        """
-        Public slot to get the banner info of the remote client.
-        """
-        self.__sendJsonCommand("RequestBanner", {})
-        
-    def remoteCapabilities(self):
-        """
-        Public slot to get the debug clients capabilities.
-        """
-        self.__sendJsonCommand("RequestCapabilities", {})
-        
-    def remoteCompletion(self, text):
-        """
-        Public slot to get the a list of possible commandline completions
-        from the remote client.
-        
-        @param text the text to be completed (string)
-        """
-        self.__sendJsonCommand("RequestCompletion", {
-            "text": text,
-        })
-        
-    def remoteUTPrepare(self, fn, tn, tfn, failed, cov, covname, coverase):
-        """
-        Public method to prepare a new unittest run.
-        
-        @param fn the filename to load (string)
-        @param tn the testname to load (string)
-        @param tfn the test function name to load tests from (string)
-        @param failed list of failed test, if only failed test should be run
-            (list of strings)
-        @param cov flag indicating collection of coverage data is requested
-            (boolean)
-        @param covname filename to be used to assemble the coverage caches
-            filename (string)
-        @param coverase flag indicating erasure of coverage data is requested
-            (boolean)
-        """
-        self.__scriptName = os.path.abspath(fn)
-        
-        fn = self.translate(os.path.abspath(fn), False)
-        self.__sendJsonCommand("RequestUTPrepare", {
-            "filename": fn,
-            "testname": tn,
-            "testfunctionname": tfn,
-            "failed": failed,
-            "coverage": cov,
-            "coveragefile": covname,
-            "coverageerase": coverase,
-        })
-        
-    def remoteUTRun(self):
-        """
-        Public method to start a unittest run.
-        """
-        self.__sendJsonCommand("RequestUTRun", {})
-        
-    def remoteUTStop(self):
-        """
-        Public method to stop a unittest run.
-        """
-        self.__sendJsonCommand("RequestUTStop", {})
-        
-    def __askForkTo(self):
-        """
-        Private method to ask the user which branch of a fork to follow.
-        """
-        selections = [self.tr("Parent Process"),
-                      self.tr("Child process")]
-        res, ok = QInputDialog.getItem(
-            None,
-            self.tr("Client forking"),
-            self.tr("Select the fork branch to follow."),
-            selections,
-            0, False)
-        if not ok or res == selections[0]:
-            self.__sendJsonCommand("ResponseForkTo", {
-                "target": "parent",
-            })
-        else:
-            self.__sendJsonCommand("ResponseForkTo", {
-                "target": "child",
-            })
-        
-    def __parseClientLine(self):
-        """
-        Private method to handle data from the client.
-        """
-        while self.qsock and self.qsock.canReadLine():
-            qs = self.qsock.readLine()
-            if self.codec is not None:
-                line = self.codec.toUnicode(qs)
-            else:
-                line = bytes(qs).decode()
-            
-##            print("Server: ", line)          ##debug
-            
-            self.__handleJsonCommand(line)
-            continue
-    
-    def __handleJsonCommand(self, jsonStr):
-        """
-        Private method to handle a command or response serialized as a
-        JSON string.
-        
-        @param jsonStr string containing the command or response received
-            from the debug backend
-        @type str
-        """
-        import json
-        
-        try:
-            commandDict = json.loads(jsonStr.strip())
-        except (TypeError, ValueError) as err:
-            E5MessageBox.critical(
-                None,
-                self.tr("Debug Protocol Error"),
-                self.tr("""<p>The response received from the debugger"""
-                        """ backend could not be decoded. Please report"""
-                        """ this issue with the received data to the"""
-                        """ eric bugs email address.</p>"""
-                        """<p>Error: {0}</p>"""
-                        """<p>Data:<br/>{0}</p>""").format(
-                    str(err), Utilities.html_encode(jsonStr.strip())),
-                E5MessageBox.StandardButtons(
-                    E5MessageBox.Ok))
-            return
-        
-        method = commandDict["method"]
-        params = commandDict["params"]
-        
-        if method == "ClientOutput":
-            self.debugServer.signalClientOutput(params["text"])
-        
-        elif method in ["ResponseLine", "ResponseStack"]:
-            # Check if obsolet thread was clicked
-            if params["stack"] == []:
-                # Request updated list
-                self.remoteThreadList()
-                return
-            for s in params["stack"]:
-                s[0] = self.translate(s[0], True)
-            cf = params["stack"][0]
-            if self.__autoContinue:
-                self.__autoContinue = False
-                QTimer.singleShot(0, self.remoteContinue)
-            else:
-                self.debugServer.signalClientLine(
-                    cf[0], int(cf[1]),
-                    method == "ResponseStack")
-                self.debugServer.signalClientStack(params["stack"])
-        
-        elif method == "CallTrace":
-            isCall = params["event"].lower() == "c"
-            fromInfo = params["from"]
-            toInfo = params["to"]
-            self.debugServer.signalClientCallTrace(
-                isCall,
-                fromInfo["filename"], str(fromInfo["linenumber"]),
-                fromInfo["codename"],
-                toInfo["filename"], str(toInfo["linenumber"]),
-                toInfo["codename"])
-        
-        elif method == "ResponseVariables":
-            self.debugServer.signalClientVariables(
-                params["scope"], params["variables"])
-        
-        elif method == "ResponseVariable":
-            self.debugServer.signalClientVariable(
-                params["scope"], [params["variable"]] + params["variables"])
-        
-        elif method == "ResponseThreadList":
-            self.debugServer.signalClientThreadList(
-                params["currentID"], params["threadList"])
-        
-        elif method == "ResponseThreadSet":
-            self.debugServer.signalClientThreadSet()
-        
-        elif method == "ResponseCapabilities":
-            self.clientCapabilities = params["capabilities"]
-            self.debugServer.signalClientCapabilities(
-                params["capabilities"], params["clientType"])
-        
-        elif method == "ResponseBanner":
-            self.debugServer.signalClientBanner(
-                params["version"],
-                params["platform"],
-                params["dbgclient"])
-        
-        elif method == "ResponseOK":
-            self.debugServer.signalClientStatement(False)
-        
-        elif method == "ResponseContinue":
-            self.debugServer.signalClientStatement(True)
-        
-        elif method == "RequestRaw":
-            self.debugServer.signalClientRawInput(
-                params["prompt"], params["echo"])
-        
-        elif method == "ResponseBPConditionError":
-            fn = self.translate(params["filename"], True)
-            self.debugServer.signalClientBreakConditionError(
-                fn, params["line"])
-        
-        elif method == "ResponseClearBreakpoint":
-            fn = self.translate(params["filename"], True)
-            self.debugServer.signalClientClearBreak(fn, params["line"])
-        
-        elif method == "ResponseWatchConditionError":
-            self.debugServer.signalClientWatchConditionError(
-                params["condition"])
-        
-        elif method == "ResponseClearWatch":
-            self.debugServer.signalClientClearWatch(params["condition"])
-        
-        elif method == "ResponseException":
-            if params:
-                exctype = params["type"]
-                excmessage = params["message"]
-                stack = params["stack"]
-                if stack:
-                    for stackEntry in stack:
-                        stackEntry[0] = self.translate(stackEntry[0], True)
-                    if stack[0] and stack[0][0] == "<string>":
-                        for stackEntry in stack:
-                            if stackEntry[0] == "<string>":
-                                stackEntry[0] = self.__scriptName
-                            else:
-                                break
-            else:
-                exctype = ''
-                excmessage = ''
-                stack = []
-            
-            self.debugServer.signalClientException(
-                exctype, excmessage, stack)
-        
-        elif method == "ResponseSyntax":
-            self.debugServer.signalClientSyntaxError(
-                params["message"], self.translate(params["filename"], True),
-                params["linenumber"], params["characternumber"])
-        
-        elif method == "ResponseSignal":
-            self.debugServer.signalClientSignal(
-                params["message"], self.translate(params["filename"], True),
-                params["linenumber"], params["function"], params["arguments"])
-        
-        elif method == "ResponseExit":
-            self.__scriptName = ""
-            self.debugServer.signalClientExit(
-                params["status"], params["message"])
-        
-        elif method == "PassiveStartup":
-            self.debugServer.passiveStartUp(
-                self.translate(params["filename"], True), params["exceptions"])
-        
-        elif method == "ResponseCompletion":
-            self.debugServer.signalClientCompletionList(
-                params["completions"], params["text"])
-        
-        elif method == "ResponseUTPrepared":
-            self.debugServer.clientUtPrepared(
-                params["count"], params["exception"], params["message"])
-        
-        elif method == "ResponseUTFinished":
-            self.debugServer.clientUtFinished()
-        
-        elif method == "ResponseUTStartTest":
-            self.debugServer.clientUtStartTest(
-                params["testname"], params["description"])
-        
-        elif method == "ResponseUTStopTest":
-            self.debugServer.clientUtStopTest()
-        
-        elif method == "ResponseUTTestFailed":
-            self.debugServer.clientUtTestFailed(
-                params["testname"], params["traceback"], params["id"])
-        
-        elif method == "ResponseUTTestErrored":
-            self.debugServer.clientUtTestErrored(
-                params["testname"], params["traceback"], params["id"])
-        
-        elif method == "ResponseUTTestSkipped":
-            self.debugServer.clientUtTestSkipped(
-                params["testname"], params["reason"], params["id"])
-        
-        elif method == "ResponseUTTestFailedExpected":
-            self.debugServer.clientUtTestFailedExpected(
-                params["testname"], params["traceback"], params["id"])
-        
-        elif method == "ResponseUTTestSucceededUnexpected":
-            self.debugServer.clientUtTestSucceededUnexpected(
-                params["testname"], params["id"])
-        
-        elif method == "RequestForkTo":
-            self.__askForkTo()
-
-    def __sendJsonCommand(self, command, params):
-        """
-        Private method to send a single command to the client.
-        
-        @param command command name to be sent
-        @type str
-        @param params dictionary of named parameters for the command
-        @type dict
-        """
-        import json
-        
-        commandDict = {
-            "jsonrpc": "2.0",
-            "method": command,
-            "params": params,
-        }
-        cmd = json.dumps(commandDict) + '\n'
-        if self.qsock is not None:
-            self.qsock.write(cmd.encode('utf8', 'backslashreplace'))
-        else:
-            self.queue.append(cmd)
-    
-
-def createDebuggerInterfacePython2(debugServer, passive):
-    """
-    Module function to create a debugger interface instance.
-    
-        
-    @param debugServer reference to the debug server
-    @type DebugServer
-    @param passive flag indicating passive connection mode
-    @type bool
-    @return instantiated debugger interface
-    @rtype DebuggerInterfacePython
-    """
-    return DebuggerInterfacePython2(debugServer, passive)
-
-
-def getRegistryData():
-    """
-    Module function to get characterizing data for the debugger interface.
-    
-    @return tuple containing  client type, client capabilities, client file
-        type associations and reference to creation function
-    @rtype tuple of (str, int, list of str, function)
-    """
-    exts = []
-    for ext in Preferences.getDebugger("PythonExtensions").split():
-        if ext.startswith("."):
-            exts.append(ext)
-        else:
-            exts.append(".{0}".format(ext))
-    
-    if exts and Preferences.getDebugger("PythonInterpreter"):
-        return ["Python2", ClientDefaultCapabilities, exts,
-                createDebuggerInterfacePython2]
-    else:
-        return ["", 0, [], None]

eric ide

mercurial