8 """ |
8 """ |
9 |
9 |
10 import contextlib |
10 import contextlib |
11 import copy |
11 import copy |
12 import os |
12 import os |
|
13 import shlex |
13 |
14 |
14 from PyQt6.QtCore import QKeyCombination, QObject, Qt, pyqtSignal, pyqtSlot |
15 from PyQt6.QtCore import QKeyCombination, QObject, Qt, pyqtSignal, pyqtSlot |
15 from PyQt6.QtGui import QKeySequence |
16 from PyQt6.QtGui import QKeySequence |
16 from PyQt6.QtWidgets import QApplication, QDialog, QMenu, QToolBar |
17 from PyQt6.QtWidgets import QApplication, QDialog, QMenu, QToolBar |
17 |
18 |
38 |
39 |
39 @signal clientStack(stack, debuggerId) emitted at breaking after a reported |
40 @signal clientStack(stack, debuggerId) emitted at breaking after a reported |
40 exception |
41 exception |
41 @signal debuggingStarted(filename) emitted when a debugging session was |
42 @signal debuggingStarted(filename) emitted when a debugging session was |
42 started |
43 started |
|
44 @signal debuggingFinished emitted to signal the end of a debugging session |
43 @signal resetUI(full) emitted to reset the UI partially or fully |
45 @signal resetUI(full) emitted to reset the UI partially or fully |
44 @signal exceptionInterrupt() emitted after the execution was interrupted |
46 @signal exceptionInterrupt() emitted after the execution was interrupted |
45 by an exception and acknowledged by the user |
47 by an exception and acknowledged by the user |
46 @signal appendStdout(msg) emitted when the client program has terminated |
48 @signal appendStdout(msg) emitted when the client program has terminated |
47 and the display of the termination dialog is suppressed |
49 and the display of the termination dialog is suppressed |
51 |
53 |
52 clientStack = pyqtSignal(list, str) |
54 clientStack = pyqtSignal(list, str) |
53 resetUI = pyqtSignal(bool) |
55 resetUI = pyqtSignal(bool) |
54 exceptionInterrupt = pyqtSignal() |
56 exceptionInterrupt = pyqtSignal() |
55 debuggingStarted = pyqtSignal(str) |
57 debuggingStarted = pyqtSignal(str) |
|
58 debuggingFinished = pyqtSignal() |
56 appendStdout = pyqtSignal(str) |
59 appendStdout = pyqtSignal(str) |
57 processChangedProjectFiles = pyqtSignal() |
60 processChangedProjectFiles = pyqtSignal() |
58 |
61 |
59 def __init__(self, ui, vm, debugServer, debugViewer, project): |
62 def __init__(self, ui, vm, debugServer, debugViewer, project): |
60 """ |
63 """ |
154 # Connect the signals emitted by the debug-server |
157 # Connect the signals emitted by the debug-server |
155 debugServer.clientGone.connect(self.__clientGone) |
158 debugServer.clientGone.connect(self.__clientGone) |
156 debugServer.clientLine.connect(self.__clientLine) |
159 debugServer.clientLine.connect(self.__clientLine) |
157 debugServer.clientDisconnected.connect(self.__clientDisconnected) |
160 debugServer.clientDisconnected.connect(self.__clientDisconnected) |
158 debugServer.clientExit.connect(self.__clientExit) |
161 debugServer.clientExit.connect(self.__clientExit) |
159 debugServer.lastClientExited.connect(self.__lastClientExited) |
162 debugServer.mainClientExit.connect(self.__mainClientExit) |
160 debugServer.clientSyntaxError.connect(self.__clientSyntaxError) |
163 debugServer.clientSyntaxError.connect(self.__clientSyntaxError) |
161 debugServer.clientException.connect(self.__clientException) |
164 debugServer.clientException.connect(self.__clientException) |
162 debugServer.clientSignal.connect(self.__clientSignal) |
165 debugServer.clientSignal.connect(self.__clientSignal) |
163 debugServer.clientVariables.connect(self.__clientVariables) |
166 debugServer.clientVariables.connect(self.__clientVariables) |
164 debugServer.clientVariable.connect(self.__clientVariable) |
167 debugServer.clientVariable.connect(self.__clientVariable) |
1341 msg, |
1344 msg, |
1342 kind=kind, |
1345 kind=kind, |
1343 timeout=timeout, |
1346 timeout=timeout, |
1344 ) |
1347 ) |
1345 |
1348 |
1346 def __lastClientExited(self): |
1349 def __mainClientExit(self): |
1347 """ |
1350 """ |
1348 Private slot handling the exit of the last client. |
1351 Private slot handling the exit of the last client. |
1349 """ |
1352 """ |
1350 self.viewmanager.exit() |
1353 self.viewmanager.exit() |
1351 self.__resetUI() |
1354 self.__resetUI() |
|
1355 |
|
1356 self.debuggingFinished.emit() |
1352 |
1357 |
1353 def __clientSyntaxError(self, message, filename, lineNo, characterNo): |
1358 def __clientSyntaxError(self, message, filename, lineNo, characterNo): |
1354 """ |
1359 """ |
1355 Private method to handle a syntax error in the debugged program. |
1360 Private method to handle a syntax error in the debugged program. |
1356 |
1361 |
2703 self.setArgvHistory("", history=argvHistory) |
2708 self.setArgvHistory("", history=argvHistory) |
2704 self.setWdHistory("", history=wdHistory) |
2709 self.setWdHistory("", history=wdHistory) |
2705 self.setEnvHistory("", history=envHistory) |
2710 self.setEnvHistory("", history=envHistory) |
2706 self.setMultiprocessNoDebugHistory("", history=noDebugHistory) |
2711 self.setMultiprocessNoDebugHistory("", history=noDebugHistory) |
2707 |
2712 |
|
2713 def debugInternalScript( |
|
2714 self, venvName, scriptName, argv, workDir, environment, clientType, forProject |
|
2715 ): |
|
2716 """ |
|
2717 Public method to run an internal script with debugger support. |
|
2718 |
|
2719 @param venvName name of the environment for the debug tests run |
|
2720 @type str |
|
2721 @param scriptName name of the internal script to be run |
|
2722 @type str |
|
2723 @param argv string or list containing the parameters for the script |
|
2724 @type str or list of str |
|
2725 @param workDir working directory for the script |
|
2726 @type str |
|
2727 @param environment string defining the additional or changed environment |
|
2728 variables |
|
2729 @type str |
|
2730 @param clientType type (language) of the debug client to be used |
|
2731 @type str |
|
2732 @param forProject flag indicating a project related debug session |
|
2733 @type bool |
|
2734 """ |
|
2735 self.__resetUI() |
|
2736 |
|
2737 # Hide all error highlights |
|
2738 self.viewmanager.unhighlight() |
|
2739 |
|
2740 self.debugViewer.initCallStackViewer(forProject) |
|
2741 |
|
2742 # Ask the client to send call trace info |
|
2743 enableCallTrace = self.debugViewer.isCallTraceEnabled() |
|
2744 self.debugViewer.clearCallTrace() |
|
2745 self.debugViewer.setCallTraceToProjectMode(forProject) |
|
2746 |
|
2747 args = shlex.join(argv) if isinstance(argv, list) else argv |
|
2748 # Ask the client to open the new program. |
|
2749 self.debugServer.remoteLoad( |
|
2750 venvName, |
|
2751 scriptName, |
|
2752 args, |
|
2753 workDir, |
|
2754 environment, |
|
2755 clientType=clientType, |
|
2756 enableCallTrace=enableCallTrace, |
|
2757 ) |
|
2758 |
|
2759 if ( |
|
2760 self.debugServer.isClientProcessUp() |
|
2761 and self.debugServer.getClientType() == clientType |
|
2762 ): |
|
2763 # Signal that we have started a debugging session |
|
2764 self.debuggingStarted.emit(scriptName) |
|
2765 |
|
2766 self.stopAct.setEnabled(True) |
|
2767 |
2708 def __doRestart(self): |
2768 def __doRestart(self): |
2709 """ |
2769 """ |
2710 Private slot to handle the restart action to restart the last |
2770 Private slot to handle the restart action to restart the last |
2711 debugged file. |
2771 debugged file. |
2712 """ |
2772 """ |