DebugClients/Python3/DebugClientBase.py

branch
jsonrpc
changeset 5119
80bd41498eef
parent 5115
ed2f37c1f6b6
child 5120
c5189d404cc7
--- a/DebugClients/Python3/DebugClientBase.py	Wed Aug 31 18:30:40 2016 +0200
+++ b/DebugClients/Python3/DebugClientBase.py	Wed Aug 31 18:31:57 2016 +0200
@@ -399,6 +399,9 @@
             line = line[:-1]
 
 ##        printerr(line)          ##debug
+        
+        if "jsonrpc" in line:
+            return self.__handleJsonCommand(line)
 
         eoc = line.find('<')
 
@@ -477,66 +480,61 @@
                     # remember for later
                 return
             
-            if cmd == DebugProtocol.RequestEnv:
-                env = eval(arg.replace("u'", "'"))
-                for key, value in env.items():
-                    if key.endswith("+"):
-                        if key[:-1] in os.environ:
-                            os.environ[key[:-1]] += value
-                        else:
-                            os.environ[key[:-1]] = value
-                    else:
-                        os.environ[key] = value
-                return
-
-            if cmd == DebugProtocol.RequestLoad:
-                self._fncache = {}
-                self.dircache = []
-                sys.argv = []
-                wd, fn, args, tracePython = arg.split('|')
-                self.__setCoding(fn)
-                sys.argv.append(fn)
-                sys.argv.extend(eval(args))
-                sys.path = self.__getSysPath(os.path.dirname(sys.argv[0]))
-                if wd == '':
-                    os.chdir(sys.path[1])
-                else:
-                    os.chdir(wd)
-                tracePython = int(tracePython)
-                self.running = sys.argv[0]
-                self.mainFrame = None
-                self.inRawMode = False
-                self.debugging = True
-                
-                self.threads.clear()
-                self.attachThread(mainThread=True)
-                
-                # set the system exception handling function to ensure, that
-                # we report on all unhandled exceptions
-                sys.excepthook = self.__unhandled_exception
-                self.__interceptSignals()
-                
-                # clear all old breakpoints, they'll get set after we have
-                # started
-                self.mainThread.clear_all_breaks()
-                
-                self.mainThread.tracePython = tracePython
-                
-                # This will eventually enter a local event loop.
-                # Note the use of backquotes to cause a repr of self.running.
-                # The need for this is on Windows os where backslash is the
-                # path separator. They will get inadvertantly stripped away
-                # during the eval causing IOErrors, if self.running is passed
-                # as a normal str.
-                self.debugMod.__dict__['__file__'] = self.running
-                sys.modules['__main__'] = self.debugMod
-                code = self.__compileFileSource(self.running)
-                if code:
-                    self.callTraceEnabled = self.__newCallTraceEnabled
-                    res = self.mainThread.run(code, self.debugMod.__dict__)
-                    self.progTerminated(res)
-                return
-
+##            if cmd == DebugProtocol.RequestEnv:
+##                env = eval(arg.replace("u'", "'"))
+##                for key, value in env.items():
+##                    if key.endswith("+"):
+##                        if key[:-1] in os.environ:
+##                            os.environ[key[:-1]] += value
+##                        else:
+##                            os.environ[key[:-1]] = value
+##                    else:
+##                        os.environ[key] = value
+##                return
+##
+##            if cmd == DebugProtocol.RequestLoad:
+##                self._fncache = {}
+##                self.dircache = []
+##                sys.argv = []
+##                wd, fn, args, tracePython = arg.split('|')
+##                self.__setCoding(fn)
+##                sys.argv.append(fn)
+##                sys.argv.extend(eval(args))
+##                sys.path = self.__getSysPath(os.path.dirname(sys.argv[0]))
+##                if wd == '':
+##                    os.chdir(sys.path[1])
+##                else:
+##                    os.chdir(wd)
+##                tracePython = int(tracePython)
+##                self.running = sys.argv[0]
+##                self.mainFrame = None
+##                self.inRawMode = False
+##                self.debugging = True
+##                
+##                self.threads.clear()
+##                self.attachThread(mainThread=True)
+##                
+##                # set the system exception handling function to ensure, that
+##                # we report on all unhandled exceptions
+##                sys.excepthook = self.__unhandled_exception
+##                self.__interceptSignals()
+##                
+##                # clear all old breakpoints, they'll get set after we have
+##                # started
+##                self.mainThread.clear_all_breaks()
+##                
+##                self.mainThread.tracePython = tracePython
+##                
+##                # This will eventually enter a local event loop.
+##                self.debugMod.__dict__['__file__'] = self.running
+##                sys.modules['__main__'] = self.debugMod
+##                code = self.__compileFileSource(self.running)
+##                if code:
+##                    self.callTraceEnabled = self.__newCallTraceEnabled
+##                    res = self.mainThread.run(code, self.debugMod.__dict__)
+##                    self.progTerminated(res)
+##                return
+##
             if cmd == DebugProtocol.RequestRun:
                 sys.argv = []
                 wd, fn, args = arg.split('|')
@@ -836,18 +834,18 @@
                 
                 return
             
-            if cmd == DebugProtocol.RequestBanner:
-                self.write('{0}{1}\n'.format(DebugProtocol.ResponseBanner,
-                           str(("Python {0}".format(sys.version),
-                                socket.gethostname(), self.variant))))
-                return
-            
-            if cmd == DebugProtocol.RequestCapabilities:
-                self.write('{0}{1:d}, "Python3"\n'.format(
-                    DebugProtocol.ResponseCapabilities,
-                    self.__clientCapabilities()))
-                return
-            
+##            if cmd == DebugProtocol.RequestBanner:
+##                self.write('{0}{1}\n'.format(DebugProtocol.ResponseBanner,
+##                           str(("Python {0}".format(sys.version),
+##                                socket.gethostname(), self.variant))))
+##                return
+##            
+##            if cmd == DebugProtocol.RequestCapabilities:
+##                self.write('{0}{1:d}, "Python3"\n'.format(
+##                    DebugProtocol.ResponseCapabilities,
+##                    self.__clientCapabilities()))
+##                return
+##            
             if cmd == DebugProtocol.RequestCompletion:
                 self.__completionList(arg.replace("u'", "'"))
                 return
@@ -1021,7 +1019,113 @@
 
                     for l in list:
                         self.write(l)
+    
+    def __handleJsonCommand(self, jsonStr):
+        """
+        Private method to handle a command serialized as a JSON string.
+        """
+        import json
+        
+        try:
+            commandDict = json.loads(jsonStr.strip())
+        except json.JSONDecodeError as err:
+            printerr(str(err))
+            return
+        
+        method = commandDict["method"]
+        params = commandDict["params"]
+        
+        if method == "RequestCapabilities":
+            self.__sendJsonCommand("ResponseCapabilities", {
+                "capabilities": self.__clientCapabilities(),
+                "clientType": "Python3"
+            })
+            return
+        
+        if method == "RequestBanner":
+            self.__sendJsonCommand("ResponseBanner", {
+                "version": "Python {0}".format(sys.version),
+                "platform": socket.gethostname(),
+                "dbgclient": self.variant,
+            })
+            return
+        
+        if method == "RequestEnvironment":
+            for key, value in params["environment"].items():
+                if key.endswith("+"):
+                    if key[:-1] in os.environ:
+                        os.environ[key[:-1]] += value
+                    else:
+                        os.environ[key[:-1]] = value
+                else:
+                    os.environ[key] = value
+            return
+        
+        if method == "RequestLoad":
+            printerr(method)
+            self._fncache = {}
+            self.dircache = []
+            sys.argv = []
+            self.__setCoding(params["filename"])
+            sys.argv.append(params["filename"])
+            sys.argv.extend(params["argv"])
+            sys.path = self.__getSysPath(os.path.dirname(sys.argv[0]))
+            if params["workdir"] == '':
+                os.chdir(sys.path[1])
+            else:
+                os.chdir(params["workdir"])
+            self.running = sys.argv[0]
+            self.mainFrame = None
+            self.inRawMode = False
+            self.debugging = True
+            
+            self.fork_auto = params["autofork"]
+            self.fork_child = params["forkChild"]
+            
+            self.threads.clear()
+            self.attachThread(mainThread=True)
+            
+            # set the system exception handling function to ensure, that
+            # we report on all unhandled exceptions
+            sys.excepthook = self.__unhandled_exception
+            self.__interceptSignals()
+            
+            # clear all old breakpoints, they'll get set after we have
+            # started
+            self.mainThread.clear_all_breaks()
+            
+            self.mainThread.tracePython = params["traceInterpreter"]
+            
+            # This will eventually enter a local event loop.
+            self.debugMod.__dict__['__file__'] = self.running
+            sys.modules['__main__'] = self.debugMod
+            code = self.__compileFileSource(self.running)
+            if code:
+                self.callTraceEnabled = self.__newCallTraceEnabled
+                res = self.mainThread.run(code, self.debugMod.__dict__)
+                self.progTerminated(res)
+            return
 
+    
+    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'
+        self.write(cmd)
+    
     def __clientCapabilities(self):
         """
         Private method to determine the clients capabilities.

eric ide

mercurial