src/eric7/Debugger/DebuggerInterfacePython.py

branch
server
changeset 10561
be23a662d709
parent 10560
28b14d2df6a1
child 10564
0de57f082daa
diff -r 28b14d2df6a1 -r be23a662d709 src/eric7/Debugger/DebuggerInterfacePython.py
--- a/src/eric7/Debugger/DebuggerInterfacePython.py	Sat Feb 10 11:28:58 2024 +0100
+++ b/src/eric7/Debugger/DebuggerInterfacePython.py	Sun Feb 11 18:35:44 2024 +0100
@@ -15,7 +15,7 @@
 import struct
 import zlib
 
-from PyQt6.QtCore import QObject, QProcess, QProcessEnvironment, QTimer
+from PyQt6.QtCore import QObject, QProcess, QProcessEnvironment, QTimer, pyqtSlot
 
 from eric7 import Preferences, Utilities
 from eric7.EricWidgets import EricMessageBox
@@ -58,6 +58,12 @@
             self.__ericServerDebuggerInterface.debugClientResponse.connect(
                 lambda jsonStr: self.handleJsonCommand(jsonStr, None)
             )
+            self.__ericServerDebuggerInterface.debugClientDisconnected.connect(
+                self.__handleServerDebugClientDisconnected
+            )
+            self.__ericServerDebuggerInterface.lastClientExited.connect(
+                self.__handleServerLastClientExited
+            )
         except KeyError:
             self.__ericServerDebuggerInterface = None
 
@@ -184,7 +190,7 @@
         originalPathString,
         workingDir="",
         configOverride=None,
-        startRemote=False,
+        startRemote=None,
     ):
         """
         Public method to start a remote Python interpreter.
@@ -204,7 +210,7 @@
             (defaults to None)
         @type dict (optional)
         @param startRemote flag indicating to start the client via an eric-ide server
-            (defaults to False)
+            (defaults to None)
         @type bool (optional)
         @return client process object, a flag to indicate a network connection
             and the name of the interpreter in case of a local execution
@@ -212,7 +218,18 @@
         """
         global origPathEnv
 
-        if startRemote or venvName == self.debugServer.getEricServerEnvironmentString():
+        if (
+            (
+                startRemote is True
+                or (
+                    startRemote is None and (
+                        venvName == self.debugServer.getEricServerEnvironmentString()
+                        or self.__ericServerDebugging
+                    )
+                )
+            )
+            and ericApp().getObject("EricServer").isServerConnected()
+        ):
             # TODO change this once server environment definitions are supported
             startRemote = True
             venvName = self.debugServer.getEricServerEnvironmentString()
@@ -242,8 +259,8 @@
 
         self.__inShutdown = False
 
+        self.__ericServerDebuggerInterface.stopClient()
         self.__ericServerDebugging = False
-        self.__ericServerDebuggerInterface.stopClient()
         self.__mainDebugger = None
 
         redirect = (
@@ -334,9 +351,6 @@
 
         elif startRemote and self.__ericServerDebuggerInterface is not None:
             # debugging via an eric-ide server
-            ##self.__ericServerDebuggerInterface.stopClient()
-            ##self.__mainDebugger = None
-##
             self.translate = self.__ericServerTranslation
             self.__ericServerDebugging = True
 
@@ -488,6 +502,8 @@
             and the name of the interpreter in case of a local execution
         @rtype tuple of (QProcess, bool, str)
         """
+        # TODO: 'startRemoteForProject()' - implement the 'startRemote' logic like
+        #       for 'startRemote'.
         global origPathEnv
 
         project = ericApp().getObject("Project")
@@ -528,8 +544,8 @@
 
         self.__inShutdown = False
 
+        self.__ericServerDebuggerInterface.stopClient()
         self.__ericServerDebugging = False
-        self.__ericServerDebuggerInterface.stopClient()
         self.__mainDebugger = None
 
         if project.getDebugProperty("REMOTEDEBUGGER"):
@@ -743,14 +759,7 @@
         for debuggerId in list(self.__connections):
             if self.__connections[debuggerId] is sock:
                 del self.__connections[debuggerId]
-                if debuggerId == self.__mainDebugger:
-                    self.__mainDebugger = None
-                if debuggerId in self.__autoContinued:
-                    self.__autoContinued.remove(debuggerId)
-                if not self.__inShutdown:
-                    with contextlib.suppress(RuntimeError):
-                        # can be ignored during a shutdown
-                        self.debugServer.signalClientDisconnected(debuggerId)
+                self.__handleServerDebugClientDisconnected(debuggerId)
                 break
         else:
             if sock in self.__pendingConnections:
@@ -758,13 +767,37 @@
 
         if not self.__connections:
             # no active connections anymore
+            self.__handleServerLastClientExited()
+
+    @pyqtSlot(str)
+    def __handleServerDebugClientDisconnected(self, debuggerId):
+        """
+        Private slot handling the disconnect of a debug client.
+
+        @param debuggerId ID of the disconnected debugger
+        @type str
+        """
+        if debuggerId == self.__mainDebugger:
+            self.__mainDebugger = None
+        if debuggerId in self.__autoContinued:
+            self.__autoContinued.remove(debuggerId)
+        if not self.__inShutdown:
             with contextlib.suppress(RuntimeError):
-                # debug server object might have been deleted already
-                # ignore this
-                self.debugServer.signalLastClientExited()
-                self.__autoContinued.clear()
-                if not self.__inShutdown:
-                    self.debugServer.startClient()
+                # can be ignored during a shutdown
+                self.debugServer.signalClientDisconnected(debuggerId)
+
+    @pyqtSlot()
+    def __handleServerLastClientExited(self):
+        """
+        Private slot to handle the exit of the last debug client connected.
+        """
+        with contextlib.suppress(RuntimeError):
+            # debug server object might have been deleted already
+            # ignore this
+            self.debugServer.signalLastClientExited()
+            self.__autoContinued.clear()
+            if not self.__inShutdown:
+                self.debugServer.startClient()
 
     def getDebuggerIds(self):
         """
@@ -890,12 +923,15 @@
             instead of unhandled exceptions only
         @type bool
         """
+        if FileSystemUtilities.isPlainFileName(fn):
+            fn = os.path.abspath(fn)
+
         self.__autoContinue = autoContinue
-        self.__scriptName = os.path.abspath(fn)
+        self.__scriptName = fn
         self.__isStepCommand = False
 
         wd = self.translate(wd, False)
-        fn = self.translate(os.path.abspath(fn), False)
+        fn = self.translate(fn, False)
         self.__sendJsonCommand(
             "RequestLoad",
             {
@@ -1122,7 +1158,12 @@
         @param temp flag indicating a temporary breakpoint
         @type bool
         """
-        debuggerList = [debuggerId] if debuggerId else list(self.__connections)
+        if debuggerId:
+            debuggerList = [debuggerId]
+        elif self.__ericServerDebugging:
+            debuggerList = ["<<all>>"]
+        else:
+            debuggerList = list(self.__connections)
         for debuggerId in debuggerList:
             self.__sendJsonCommand(
                 "RequestBreakpoint",
@@ -1149,7 +1190,12 @@
         @param enable flag indicating enabling or disabling a breakpoint
         @type bool
         """
-        debuggerList = [debuggerId] if debuggerId else list(self.__connections)
+        if debuggerId:
+            debuggerList = [debuggerId]
+        elif self.__ericServerDebugging:
+            debuggerList = ["<<all>>"]
+        else:
+            debuggerList = list(self.__connections)
         for debuggerId in debuggerList:
             self.__sendJsonCommand(
                 "RequestBreakpointEnable",
@@ -1174,7 +1220,12 @@
         @param count number of occurrences to ignore
         @type int
         """
-        debuggerList = [debuggerId] if debuggerId else list(self.__connections)
+        if debuggerId:
+            debuggerList = [debuggerId]
+        elif self.__ericServerDebugging:
+            debuggerList = ["<<all>>"]
+        else:
+            debuggerList = list(self.__connections)
         for debuggerId in debuggerList:
             self.__sendJsonCommand(
                 "RequestBreakpointIgnore",
@@ -1199,7 +1250,12 @@
         @param temp flag indicating a temporary watch expression
         @type bool
         """
-        debuggerList = [debuggerId] if debuggerId else list(self.__connections)
+        if debuggerId:
+            debuggerList = [debuggerId]
+        elif self.__ericServerDebugging:
+            debuggerList = ["<<all>>"]
+        else:
+            debuggerList = list(self.__connections)
         for debuggerId in debuggerList:
             # cond is combination of cond and special (s. watch expression
             # viewer)
@@ -1224,7 +1280,12 @@
         @param enable flag indicating enabling or disabling a watch expression
         @type bool
         """
-        debuggerList = [debuggerId] if debuggerId else list(self.__connections)
+        if debuggerId:
+            debuggerList = [debuggerId]
+        elif self.__ericServerDebugging:
+            debuggerList = ["<<all>>"]
+        else:
+            debuggerList = list(self.__connections)
         for debuggerId in debuggerList:
             # cond is combination of cond and special (s. watch expression
             # viewer)
@@ -1249,7 +1310,12 @@
         @param count number of occurrences to ignore
         @type int
         """
-        debuggerList = [debuggerId] if debuggerId else list(self.__connections)
+        if debuggerId:
+            debuggerList = [debuggerId]
+        elif self.__ericServerDebugging:
+            debuggerList = ["<<all>>"]
+        else:
+            debuggerList = list(self.__connections)
         for debuggerId in debuggerList:
             # cond is combination of cond and special (s. watch expression
             # viewer)
@@ -1702,7 +1768,7 @@
         elif method == "ResponseExit":
             self.__scriptName = ""
             self.debugServer.signalClientExit(
-                params["program"],
+                self.translate(params["program"], True),
                 params["status"],
                 params["message"],
                 params["debuggerId"],

eric ide

mercurial