eric6/DebugClients/Python/MultiprocessingExtension.py

Sun, 18 Oct 2020 12:35:30 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sun, 18 Oct 2020 12:35:30 +0200
branch
multi_processing
changeset 7802
eefe954f01e8
parent 7646
39e3db2b4936
child 7872
433dacbfa456
permissions
-rw-r--r--

Merged with default branch.

# -*- coding: utf-8 -*-

# Copyright (c) 2020 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing a function to patch multiprocessing.Process to support
debugging of the process.
"""

import sys
import traceback

_debugClient = None
_originalProcess = None
_originalBootstrap = None


def patchMultiprocessing(module, debugClient):
    """
    Function to patch the multiprocessing module.
    
    @param module reference to the imported module to be patched
    @type module
    @param debugClient reference to the debug client object
    @type DebugClient
    """     # __IGNORE_WARNING_D234__
    global _debugClient, _originalProcess, _originalBootstrap
    
    _debugClient = debugClient
    
    if sys.version_info >= (3, 4):
        _originalProcess = module.process.BaseProcess
    else:
        _originalProcess = module.Process
    _originalBootstrap = _originalProcess._bootstrap
    
    class ProcessWrapper(_originalProcess):
        """
        Wrapper class for multiprocessing.Process.
        """
        def _bootstrap(self, *args, **kwargs):
            """
            Wrapper around _bootstrap to start debugger.
            
            @param args function arguments
            @type list
            @param kwargs keyword only arguments
            @type dict
            @return exit code of the process
            @rtype int
            """
            if (
                _debugClient.debugging and
                _debugClient.multiprocessSupport
            ):
                try:
                    (wd, host, port, exceptions, tracePython, redirect,
                     noencoding) = _debugClient.startOptions[:7]
                    _debugClient.startDebugger(
                        sys.argv[0], host=host, port=port,
                        exceptions=exceptions, tracePython=tracePython,
                        redirect=redirect, passive=False,
                        multiprocessSupport=True
                    )
                except Exception:
                    print("Exception during multiprocessing bootstrap init:")
                    # __IGNORE_WARNING_M801__
                    traceback.print_exc(file=sys.stdout)
                    sys.stdout.flush()
                    raise
            
            return _originalBootstrap(self, *args, **kwargs)
    
    if sys.version_info >= (3, 4):
        _originalProcess._bootstrap = ProcessWrapper._bootstrap
    else:
        module.Process = ProcessWrapper
    
##    if sys.version_info >= (3, 4):
##        _originalProcess = module.Process
####        _originalProcess = module.process.BaseProcess
##    else:
##        _originalProcess = module.Process
##    class ProcessWrapper(_originalProcess):
##        def __init__(self, *args, **kwargs):
##            super(ProcessWrapper, self).__init__(*args, **kwargs)
##            self._run = self.run
##            self.run = self._bootstrap_eric6
##            # Class attributes are not transfered to new process. Therefore make a
##            # copy as instance attribute
##            self._options = _debugClient.startOptions
##        
##        def _bootstrap_eric6(self):
##            """
##            Bootstrap for threading, which reports exceptions correctly.
##            
##            @param run the run method of threading.Thread
##            @type method pointer
##            """
##            from DebugClient import DebugClient
##            self.debugClient = DebugClient()
##            
##            (_wd, host, port, exceptions, tracePython, redirect,
##             noencoding) = self._options[:7]
##            
##            args = sys.argv
##            self.debugClient.name = self.name
##            
##            self.debugClient.startDebugger(args[0], host, port,
##                                     exceptions=exceptions,
##                                     tracePython=tracePython,
##                                     redirect=redirect)
##
##            try:
##                self._run()
##            except Exception:
##                excinfo = sys.exc_info()
##                self.debugClient.user_exception(excinfo, True)
##            finally:
##                sys.settrace(None)
##    
##    if sys.version_info >= (3, 4):
##        module.Process = ProcessWrapper
####        module.process.BaseProcess = ProcessWrapper
##    else:
##        module.Process = ProcessWrapper

eric ide

mercurial