src/eric7/DebugClients/Python/MultiProcessDebugExtension.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9473
3f23dbf37dbe
diff -r e9e7eca7efee -r bf71ee032bb4 src/eric7/DebugClients/Python/MultiProcessDebugExtension.py
--- a/src/eric7/DebugClients/Python/MultiProcessDebugExtension.py	Wed Jul 13 11:16:20 2022 +0200
+++ b/src/eric7/DebugClients/Python/MultiProcessDebugExtension.py	Wed Jul 13 14:55:47 2022 +0200
@@ -11,8 +11,10 @@
 import contextlib
 
 from DebugUtilities import (
-    patchArguments, patchArgumentStringWindows, isPythonProgram,
-    isWindowsPlatform
+    patchArguments,
+    patchArgumentStringWindows,
+    isPythonProgram,
+    isWindowsPlatform,
 )
 
 _debugClient = None
@@ -21,7 +23,7 @@
 def _shallPatch():
     """
     Function to determine, if the multiprocessing patches should be done.
-    
+
     @return flag indicating patching should be performed
     @rtype bool
     """
@@ -31,7 +33,7 @@
 def patchModule(module, functionName, createFunction):
     """
     Function to replace a function of a module with a modified one.
-    
+
     @param module reference to the module
     @type types.ModuleType
     @param functionName name of the function to be replaced
@@ -40,7 +42,7 @@
     @type types.FunctionType
     """
     if hasattr(module, functionName):
-        originalName = 'original_' + functionName
+        originalName = "original_" + functionName
         if not hasattr(module, originalName):
             setattr(module, originalName, getattr(module, functionName))
             setattr(module, functionName, createFunction(originalName))
@@ -49,236 +51,261 @@
 def createExecl(originalName):
     """
     Function to patch the 'execl' process creation functions.
-    
+
     <ul>
         <li>os.execl(path, arg0, arg1, ...)</li>
         <li>os.execle(path, arg0, arg1, ..., env)</li>
         <li>os.execlp(file, arg0, arg1, ...)</li>
         <li>os.execlpe(file, arg0, arg1, ..., env)</li>
     </ul>
-    
+
     @param originalName original name of the function to be patched
     @type str
     @return function replacing the original one
     @rtype function
     """
+
     def newExecl(path, *args):
         """
         Function replacing the 'execl' functions of the os module.
         """
         import os
+
         if _shallPatch():
             args = patchArguments(_debugClient, args)
             if isPythonProgram(args[0]):
                 path = args[0]
         return getattr(os, originalName)(path, *args)
+
     return newExecl
 
 
 def createExecv(originalName):
     """
     Function to patch the 'execv' process creation functions.
-    
+
     <ul>
         <li>os.execv(path, args)</li>
         <li>os.execvp(file, args)</li>
     </ul>
-    
+
     @param originalName original name of the function to be patched
     @type str
     @return function replacing the original one
     @rtype function
     """
+
     def newExecv(path, args):
         """
         Function replacing the 'execv' functions of the os module.
         """
         import os
+
         if _shallPatch():
             args = patchArguments(_debugClient, args)
             if isPythonProgram(args[0]):
                 path = args[0]
         return getattr(os, originalName)(path, args)
+
     return newExecv
 
 
 def createExecve(originalName):
     """
     Function to patch the 'execve' process creation functions.
-    
+
     <ul>
         <li>os.execve(path, args, env)</li>
         <li>os.execvpe(file, args, env)</li>
     </ul>
-    
+
     @param originalName original name of the function to be patched
     @type str
     @return function replacing the original one
     @rtype function
     """
+
     def newExecve(path, args, env):
         """
         Function replacing the 'execve' functions of the os module.
         """
         import os
+
         if _shallPatch():
             args = patchArguments(_debugClient, args)
             if isPythonProgram(args[0]):
                 path = args[0]
         return getattr(os, originalName)(path, args, env)
+
     return newExecve
 
 
 def createSpawnl(originalName):
     """
     Function to patch the 'spawnl' process creation functions.
-    
+
     <ul>
         <li>os.spawnl(mode, path, arg0, arg1, ...)</li>
         <li>os.spawnlp(mode, file, arg0, arg1, ...)</li>
     </ul>
-    
+
     @param originalName original name of the function to be patched
     @type str
     @return function replacing the original one
     @rtype function
     """
+
     def newSpawnl(mode, path, *args):
         """
         Function replacing the 'spawnl' functions of the os module.
         """
         import os
+
         args = patchArguments(_debugClient, args)
         return getattr(os, originalName)(mode, path, *args)
+
     return newSpawnl
 
 
 def createSpawnv(originalName):
     """
     Function to patch the 'spawnv' process creation functions.
-    
+
     <ul>
         <li>os.spawnv(mode, path, args)</li>
         <li>os.spawnvp(mode, file, args)</li>
     </ul>
-    
+
     @param originalName original name of the function to be patched
     @type str
     @return function replacing the original one
     @rtype function
     """
+
     def newSpawnv(mode, path, args):
         """
         Function replacing the 'spawnv' functions of the os module.
         """
         import os
+
         args = patchArguments(_debugClient, args)
         return getattr(os, originalName)(mode, path, args)
+
     return newSpawnv
 
 
 def createSpawnve(originalName):
     """
     Function to patch the 'spawnve' process creation functions.
-    
+
     <ul>
         <li>os.spawnve(mode, path, args, env)</li>
         <li>os.spawnvpe(mode, file, args, env)</li>
     </ul>
-    
+
     @param originalName original name of the function to be patched
     @type str
     @return function replacing the original one
     @rtype function
     """
+
     def newSpawnve(mode, path, args, env):
         """
         Function replacing the 'spawnve' functions of the os module.
         """
         import os
+
         args = patchArguments(_debugClient, args)
         return getattr(os, originalName)(mode, path, args, env)
+
     return newSpawnve
 
 
 def createPosixSpawn(originalName):
     """
     Function to patch the 'posix_spawn' process creation functions.
-    
+
     <ul>
         <li>os.posix_spawn(path, argv, env, *, file_actions=None, ...
             (6 more))</li>
         <li>os.posix_spawnp(path, argv, env, *, file_actions=None, ...
             (6 more))</li>
     </ul>
-    
+
     @param originalName original name of the function to be patched
     @type str
     @return function replacing the original one
     @rtype function
     """
+
     def newPosixSpawn(path, argv, env, **kwargs):
         """
         Function replacing the 'posix_spawn' functions of the os module.
         """
         import os
+
         argv = patchArguments(_debugClient, argv)
         return getattr(os, originalName)(path, argv, env, **kwargs)
+
     return newPosixSpawn
 
 
 def createForkExec(originalName):
     """
     Function to patch the 'fork_exec' process creation functions.
-    
+
     <ul>
         <li>_posixsubprocess.fork_exec(args, executable_list, close_fds,
             ... (13 more))</li>
     </ul>
-    
+
     @param originalName original name of the function to be patched
     @type str
     @return function replacing the original one
     @rtype function
     """
+
     def newForkExec(args, *other_args):
         """
         Function replacing the 'fork_exec' functions of the _posixsubprocess
         module.
         """
         import _posixsubprocess
+
         if _shallPatch():
             args = patchArguments(_debugClient, args)
         return getattr(_posixsubprocess, originalName)(args, *other_args)
+
     return newForkExec
 
 
 def createFork(originalName):
     """
     Function to patch the 'fork' process creation functions.
-    
+
     <ul>
         <li>os.fork()</li>
     </ul>
-    
+
     @param originalName original name of the function to be patched
     @type str
     @return function replacing the original one
     @rtype function
     """
+
     def newFork():
         """
         Function replacing the 'fork' function of the os module.
         """
         import os
         import sys
-        
+
         # A simple fork will result in a new python process
         isNewPythonProcess = True
         frame = sys._getframe()
-        
+
         multiprocess = _shallPatch()
-        
+
         isSubprocessFork = False
         isMultiprocessingPopen = False
         while frame is not None:
@@ -287,33 +314,36 @@
                 # because it is handled in 'MultiprocessingExtension.py'.
                 isMultiprocessingPopen = True
                 break
-            
+
             elif (
-                frame.f_code.co_name == '_execute_child' and
-                'subprocess' in frame.f_code.co_filename
+                frame.f_code.co_name == "_execute_child"
+                and "subprocess" in frame.f_code.co_filename
             ):
                 isSubprocessFork = True
                 # If we're actually in subprocess.Popen creating a child, it
                 # may result in something which is not a Python process, (so,
                 # we don't want to connect with it in the forked version).
-                executable = frame.f_locals.get('executable')
+                executable = frame.f_locals.get("executable")
                 if executable is not None:
                     isNewPythonProcess = False
                     if isPythonProgram(executable):
                         isNewPythonProcess = True
                 break
-            
+
             frame = frame.f_back
-        frame = None    # Just make sure we don't hold on to it.
-        
-        childProcess = getattr(os, originalName)()     # fork
-        if (
-            not childProcess and
-            not isMultiprocessingPopen and
-            isNewPythonProcess
-        ):
-            (wd, host, port, exceptions, tracePython, redirect,
-             noencoding) = _debugClient.startOptions
+        frame = None  # Just make sure we don't hold on to it.
+
+        childProcess = getattr(os, originalName)()  # fork
+        if not childProcess and not isMultiprocessingPopen and isNewPythonProcess:
+            (
+                wd,
+                host,
+                port,
+                exceptions,
+                tracePython,
+                redirect,
+                noencoding,
+            ) = _debugClient.startOptions
             _debugClient.startDebugger(
                 filename=sys.argv[0],
                 host=host,
@@ -323,9 +353,10 @@
                 tracePython=tracePython,
                 redirect=redirect,
                 passive=False,
-                multiprocessSupport=multiprocess)
+                multiprocessSupport=multiprocess,
+            )
         return childProcess
-    
+
     return newFork
 
 
@@ -333,12 +364,13 @@
     """
     Function to patch the 'CreateProcess' process creation function of
     Windows.
-    
+
     @param originalName original name of the function to be patched
     @type str
     @return function replacing the original one
     @rtype function
     """
+
     def newCreateProcess(appName, cmdline, *args):
         """
         Function replacing the 'CreateProcess' function of the _subprocess
@@ -349,7 +381,9 @@
         except ImportError:
             import _winapi as _subprocess
         return getattr(_subprocess, originalName)(
-            appName, patchArgumentStringWindows(_debugClient, cmdline), *args)
+            appName, patchArgumentStringWindows(_debugClient, cmdline), *args
+        )
+
     return newCreateProcess
 
 
@@ -357,31 +391,31 @@
     """
     Function to patch the process creation functions to support multiprocess
     debugging.
-    
+
     @param multiprocessEnabled flag indicating multiprocess support
     @type bool
     @param debugClient reference to the debug client object
     @type DebugClient
     """
     global _debugClient
-    
+
     if not multiprocessEnabled:
         # return without patching
         return
-    
+
     import os
     import sys
-    
+
     # patch 'os.exec...()' functions
-#-    patchModule(os, "execl", createExecl)
-#-    patchModule(os, "execle", createExecl)
-#-    patchModule(os, "execlp", createExecl)
-#-    patchModule(os, "execlpe", createExecl)
-#-    patchModule(os, "execv", createExecv)
-#-    patchModule(os, "execve", createExecve)
-#-    patchModule(os, "execvp", createExecv)
-#-    patchModule(os, "execvpe", createExecve)
-    
+    # -    patchModule(os, "execl", createExecl)
+    # -    patchModule(os, "execle", createExecl)
+    # -    patchModule(os, "execlp", createExecl)
+    # -    patchModule(os, "execlpe", createExecl)
+    # -    patchModule(os, "execv", createExecv)
+    # -    patchModule(os, "execve", createExecve)
+    # -    patchModule(os, "execvp", createExecv)
+    # -    patchModule(os, "execvpe", createExecve)
+
     # patch 'os.spawn...()' functions
     patchModule(os, "spawnl", createSpawnl)
     patchModule(os, "spawnle", createSpawnl)
@@ -391,22 +425,23 @@
     patchModule(os, "spawnve", createSpawnve)
     patchModule(os, "spawnvp", createSpawnv)
     patchModule(os, "spawnvpe", createSpawnve)
-    
+
     # patch 'os.posix_spawn...()' functions
     if sys.version_info >= (3, 8) and not isWindowsPlatform():
         patchModule(os, "posix_spawn", createPosixSpawn)
         patchModule(os, "posix_spawnp", createPosixSpawn)
-    
+
     if isWindowsPlatform():
         try:
             import _subprocess
         except ImportError:
             import _winapi as _subprocess
-        patchModule(_subprocess, 'CreateProcess', createCreateProcess)
+        patchModule(_subprocess, "CreateProcess", createCreateProcess)
     else:
         patchModule(os, "fork", createFork)
         with contextlib.suppress(ImportError):
             import _posixsubprocess
+
             patchModule(_posixsubprocess, "fork_exec", createForkExec)
-    
+
     _debugClient = debugClient

eric ide

mercurial