eric6/DebugClients/Python/DebugClientBase.py

branch
multi_processing
changeset 7871
eb65864ca038
parent 7870
ab8f95bc7d2d
child 7872
433dacbfa456
diff -r ab8f95bc7d2d -r eb65864ca038 eric6/DebugClients/Python/DebugClientBase.py
--- a/eric6/DebugClients/Python/DebugClientBase.py	Mon Dec 07 19:53:15 2020 +0100
+++ b/eric6/DebugClients/Python/DebugClientBase.py	Thu Dec 10 20:16:21 2020 +0100
@@ -31,7 +31,7 @@
 from FlexCompleter import Completer
 from DebugUtilities import prepareJsonCommand
 from BreakpointWatch import Breakpoint, Watch
-##from MultiProcessDebugExtension import patchNewProcessFunctions
+from MultiProcessDebugExtension import patchNewProcessFunctions
 
 from DebugUtilities import getargvalues, formatargvalues
 
@@ -68,25 +68,6 @@
 ###############################################################################
 
 
-def DebugClientFork():
-    """
-    Replacement for the standard os.fork().
-    
-    @return result of the fork() call
-    """
-    if DebugClientInstance is None:
-        return DebugClientOrigFork()
-    
-    return DebugClientInstance.fork()
-
-# use our own fork().
-if 'fork' in dir(os):
-    DebugClientOrigFork = os.fork
-    os.fork = DebugClientFork
-
-###############################################################################
-
-
 def DebugClientClose(fd):
     """
     Replacement for the standard os.close(fd).
@@ -182,9 +163,6 @@
         self.debugging = False
         self.multiprocessSupport = False
         self.noDebugList = []
-        
-        self.fork_auto = False
-        self.fork_child = False
 
         self.readstream = None
         self.writestream = None
@@ -284,13 +262,29 @@
         """
         Private method to compile source code read from a file.
         
-        @param filename name of the source file (string)
-        @param mode kind of code to be generated (string, exec or eval)
+        @param filename name of the source file
+        @type str
+        @param mode kind of code to be generated (exec or eval)
+        @type str
         @return compiled code object (None in case of errors)
         """
         with codecs.open(filename, encoding=self.__coding) as fp:
             statement = fp.read()
         
+        return self.__compileCommand(statement, filename=filename, mode=mode)
+    
+    def __compileCommand(self, statement, filename="<string>", mode="exec"):
+        """
+        Private method to compile source code.
+        
+        @param statement source code string to be compiled
+        @type str
+        @param filename name of the source file
+        @type str
+        @param mode kind of code to be generated (exec or eval)
+        @type str
+        @return compiled code object (None in case of errors)
+        """
         try:
             code = compile(statement + '\n', filename, mode)
         except SyntaxError:
@@ -432,9 +426,6 @@
             self.debugging = True
             self.multiprocessSupport = params["multiprocess"]
             
-            self.fork_auto = params["autofork"]
-            self.fork_child = params["forkChild"]
-            
             self.threads.clear()
             self.attachThread(mainThread=True)
             
@@ -473,9 +464,6 @@
             self.running = sys.argv[0]
             self.botframe = None
             
-            self.fork_auto = params["autofork"]
-            self.fork_child = params["forkChild"]
-            
             self.threads.clear()
             self.attachThread(mainThread=True)
             
@@ -932,11 +920,6 @@
         
         elif method == "RequestUTStop":
             self.testResult.stop()
-        
-        elif method == "ResponseForkTo":
-            # this results from a separate event loop
-            self.fork_child = (params["target"] == 'child')
-            self.eventExit = True
     
     def __assembleTestCasesList(self, suite, start):
         """
@@ -2054,7 +2037,7 @@
     def startProgInDebugger(self, progargs, wd='', host=None,
                             port=None, exceptions=True, tracePython=False,
                             redirect=True, passive=True,
-                            multiprocessSupport=False):
+                            multiprocessSupport=False, codeStr=""):
         """
         Public method used to start the remote debugger.
         
@@ -2074,6 +2057,8 @@
         @param multiprocessSupport flag indicating to enable multiprocess
             debugging support
         @type bool
+        @param codeStr string containing Python code to execute
+        @type str
         @return exit code of the debugged program
         @rtype int
         """
@@ -2088,15 +2073,19 @@
         
         self._fncache = {}
         self.dircache = []
-        sys.argv = progargs[:]
-        sys.argv[0] = os.path.abspath(sys.argv[0])
-        sys.path = self.__getSysPath(os.path.dirname(sys.argv[0]))
-        if wd == '':
-            os.chdir(sys.path[1])
+        if codeStr:
+            self.running = "<string>"
+            sys.argv = ["<string>"] + progargs[:]
         else:
-            os.chdir(wd)
-        self.running = sys.argv[0]
-        self.__setCoding(self.running)
+            sys.argv = progargs[:]
+            sys.argv[0] = os.path.abspath(sys.argv[0])
+            sys.path = self.__getSysPath(os.path.dirname(sys.argv[0]))
+            if wd == '':
+                os.chdir(sys.path[1])
+            else:
+                os.chdir(wd)
+            self.running = sys.argv[0]
+            self.__setCoding(self.running)
         self.debugging = True
         self.multiprocessSupport = multiprocessSupport
         
@@ -2116,7 +2105,10 @@
         # 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 codeStr:
+            code = self.__compileCommand(codeStr)
+        else:
+            code = self.__compileFileSource(self.running)
         if code:
             res = self.mainThread.run(code, self.debugMod.__dict__, debug=True)
         else:
@@ -2179,6 +2171,7 @@
             redirect = True
             passive = True
             multiprocess = False
+            hasCode = False
             while args[0]:
                 if args[0] == '-h':
                     host = args[1]
@@ -2204,20 +2197,15 @@
                 elif args[0] == '--no-encoding':
                     self.noencoding = True
                     del args[0]
-                elif args[0] == '--fork-child':
-                    self.fork_auto = True
-                    self.fork_child = True
-                    del args[0]
-                elif args[0] == '--fork-parent':
-                    self.fork_auto = True
-                    self.fork_child = False
-                    del args[0]
                 elif args[0] == '--no-passive':
                     passive = False
                     del args[0]
                 elif args[0] == '--multiprocess':
                     multiprocess = True
                     del args[0]
+                elif args[0] == '--code':
+                    hasCode = True
+                    del args[0]
                 elif args[0] == '--':
                     del args[0]
                     break
@@ -2234,15 +2222,20 @@
                 # TODO: check which ones are really needed
                 self.startOptions = (
                     wd, host, port, exceptions, tracePython, redirect,
-                    self.noencoding, self.fork_auto, self.fork_child,
+                    self.noencoding,
                 )
                 if not self.noencoding:
                     self.__coding = self.defaultCoding
-##                patchNewProcessFunctions(multiprocess, self)
+                patchNewProcessFunctions(multiprocess, self)
+                if hasCode:
+                    codeStr = args.pop(0)
+                else:
+                    codeStr=""
                 res = self.startProgInDebugger(
                     args, wd, host, port, exceptions=exceptions,
                     tracePython=tracePython, redirect=redirect,
-                    passive=passive, multiprocessSupport=multiprocess
+                    passive=passive, multiprocessSupport=multiprocess,
+                    codeStr=codeStr
                 )
                 sys.exit(res)
         else:
@@ -2291,49 +2284,17 @@
                 # TODO: check which ones are really needed
                 self.startOptions = (
                     '', remoteAddress, port, True, False, redirect,
-                    self.noencoding, self.fork_auto, self.fork_child,
+                    self.noencoding,
                 )
                 if not self.noencoding:
                     self.__coding = self.defaultCoding
+                patchNewProcessFunctions(self.multiprocessSupport, self)
                 self.connectDebugger(port, remoteAddress, redirect)
-##                patchNewProcessFunctions(self.multiprocessSupport, self)
                 self.__interact()
             else:
                 print("No network port given. Aborting...")
                 # __IGNORE_WARNING_M801__
         
-    def fork(self):
-        """
-        Public method implementing a fork routine deciding which branch
-        to follow.
-        
-        @return process ID (integer)
-        """
-##        if not self.fork_auto:
-##            self.sendJsonCommand("RequestForkTo", {})
-##            self.eventLoop(True)
-        pid = DebugClientOrigFork()
-        if pid == 0:
-            # child
-##            if not self.fork_child:
-            sys.settrace(None)
-            sys.setprofile(None)
-            self.sessionClose(False)
-##                (wd, host, port, exceptions, tracePython, redirect,
-##                 noencoding, fork_auto, fork_child) = self.startOptions
-##                self.startDebugger(sys.argv[0], host, port,
-##                                   exceptions=exceptions,
-##                                   tracePython=tracePython,
-##                                   redirect=redirect,
-##                                   passive=False)
-        else:
-            # parent
-            if self.fork_child:
-                sys.settrace(None)
-                sys.setprofile(None)
-                self.sessionClose(False)
-        return pid
-        
     def close(self, fd):
         """
         Public method implementing a close method as a replacement for

eric ide

mercurial