48 |
48 |
49 self.__isNetworked = True |
49 self.__isNetworked = True |
50 self.__autoContinue = False |
50 self.__autoContinue = False |
51 self.__autoContinued = [] |
51 self.__autoContinued = [] |
52 self.__isStepCommand = False |
52 self.__isStepCommand = False |
|
53 |
|
54 self.__ericServerDebugging = False # are we debugging via the eric-ide server? |
|
55 try: |
|
56 self.__ericServerDebuggerInterface = ( |
|
57 ericApp().getObject("EricServer").getServiceInterface("Debugger") |
|
58 ) |
|
59 self.__ericServerDebuggerInterface.debugClientResponse.connect( |
|
60 lambda jsonStr: self.handleJsonCommand(jsonStr, None) |
|
61 ) |
|
62 self.__ericServerDebuggerInterface.debugClientDisconnected.connect( |
|
63 self.__handleServerDebugClientDisconnected |
|
64 ) |
|
65 self.__ericServerDebuggerInterface.lastClientExited.connect( |
|
66 self.__handleServerLastClientExited |
|
67 ) |
|
68 except KeyError: |
|
69 self.__ericServerDebuggerInterface = None |
53 |
70 |
54 self.debugServer = debugServer |
71 self.debugServer = debugServer |
55 self.passive = passive |
72 self.passive = passive |
56 self.process = None |
73 self.process = None |
57 self.__startedVenv = "" |
74 self.__startedVenv = "" |
117 if not self.translateRemoteWindows: |
135 if not self.translateRemoteWindows: |
118 path = path.replace("\\", "/") |
136 path = path.replace("\\", "/") |
119 |
137 |
120 return path |
138 return path |
121 |
139 |
122 def __startProcess(self, program, arguments, environment=None, workingDir=None): |
140 def __ericServerTranslation(self, fn, remote2local=True): |
|
141 """ |
|
142 Private method to perform the eric-ide server path translation. |
|
143 |
|
144 @param fn filename to be translated |
|
145 @type str |
|
146 @param remote2local flag indicating the direction of translation |
|
147 (False = local to remote, True = remote to local) (defaults to True) |
|
148 @type bool (optional) |
|
149 @return translated filename |
|
150 @rtype str |
|
151 """ |
|
152 if remote2local: |
|
153 return FileSystemUtilities.remoteFileName(fn) |
|
154 else: |
|
155 return FileSystemUtilities.plainFileName(fn) |
|
156 |
|
157 def __startProcess(self, program, arguments, environment=None, workingDir=""): |
123 """ |
158 """ |
124 Private method to start the debugger client process. |
159 Private method to start the debugger client process. |
125 |
160 |
126 @param program name of the executable to start |
161 @param program name of the executable to start |
127 @type str |
162 @type str |
168 @type bool |
204 @type bool |
169 @param venvName name of the virtual environment to be used |
205 @param venvName name of the virtual environment to be used |
170 @type str |
206 @type str |
171 @param originalPathString original PATH environment variable |
207 @param originalPathString original PATH environment variable |
172 @type str |
208 @type str |
173 @param workingDir directory to start the debugger client in |
209 @param workingDir directory to start the debugger client in (defaults to "") |
174 @type str |
210 @type str (optional) |
175 @param configOverride dictionary containing the global config override |
211 @param configOverride dictionary containing the global config override data |
176 data |
212 (defaults to None) |
177 @type dict |
213 @type dict (optional) |
|
214 @param startRemote flag indicating to start the client via an eric-ide server |
|
215 (defaults to None) |
|
216 @type bool (optional) |
178 @return client process object, a flag to indicate a network connection |
217 @return client process object, a flag to indicate a network connection |
179 and the name of the interpreter in case of a local execution |
218 and the name of the interpreter in case of a local execution |
180 @rtype tuple of (QProcess, bool, str) |
219 @rtype tuple of (QProcess, bool, str) |
181 """ |
220 """ |
182 global origPathEnv |
221 global origPathEnv |
183 |
222 |
184 if not venvName: |
223 if ( |
185 venvName = Preferences.getDebugger("Python3VirtualEnv") |
224 startRemote is True |
186 if venvName == self.debugServer.getProjectEnvironmentString(): |
225 or ( |
187 project = ericApp().getObject("Project") |
226 startRemote is None |
188 venvName = project.getProjectVenv() |
227 and ( |
189 execPath = project.getProjectExecPath() |
228 venvName == self.debugServer.getEricServerEnvironmentString() |
190 interpreter = project.getProjectInterpreter() |
229 or self.__ericServerDebugging |
|
230 ) |
|
231 ) |
|
232 ) and ericApp().getObject("EricServer").isServerConnected(): |
|
233 # TODO change this once server environment definitions are supported |
|
234 startRemote = True |
|
235 if venvName: |
|
236 venvManager = ericApp().getObject("VirtualEnvManager") |
|
237 interpreter = venvManager.getVirtualenvInterpreter(venvName) |
|
238 else: |
|
239 venvName = self.debugServer.getEricServerEnvironmentString() |
|
240 interpreter = "" # use the interpreter of the server |
191 else: |
241 else: |
192 venvManager = ericApp().getObject("VirtualEnvManager") |
242 if not venvName: |
193 interpreter = venvManager.getVirtualenvInterpreter(venvName) |
243 venvName = Preferences.getDebugger("Python3VirtualEnv") |
194 execPath = venvManager.getVirtualenvExecPath(venvName) |
244 if venvName == self.debugServer.getProjectEnvironmentString(): |
195 if interpreter == "": |
245 project = ericApp().getObject("Project") |
196 # use the interpreter used to run eric for identical variants |
246 venvName = project.getProjectVenv() |
197 interpreter = PythonUtilities.getPythonExecutable() |
247 execPath = project.getProjectExecPath() |
198 if interpreter == "": |
248 interpreter = project.getProjectInterpreter() |
199 EricMessageBox.critical( |
249 else: |
200 None, |
250 venvManager = ericApp().getObject("VirtualEnvManager") |
201 self.tr("Start Debugger"), |
251 interpreter = venvManager.getVirtualenvInterpreter(venvName) |
202 self.tr("""<p>No suitable Python3 environment configured.</p>"""), |
252 execPath = venvManager.getVirtualenvExecPath(venvName) |
203 ) |
253 if interpreter == "": |
204 return None, False, "" |
254 # use the interpreter used to run eric for identical variants |
|
255 interpreter = PythonUtilities.getPythonExecutable() |
|
256 if interpreter == "": |
|
257 EricMessageBox.critical( |
|
258 None, |
|
259 self.tr("Start Debugger"), |
|
260 self.tr("""<p>No suitable Python3 environment configured.</p>"""), |
|
261 ) |
|
262 return None, False, "" |
205 |
263 |
206 self.__inShutdown = False |
264 self.__inShutdown = False |
|
265 |
|
266 self.__ericServerDebugging = False |
207 |
267 |
208 redirect = ( |
268 redirect = ( |
209 str(configOverride["redirect"]) |
269 str(configOverride["redirect"]) |
210 if configOverride and configOverride["enable"] |
270 if configOverride and configOverride["enable"] |
211 else str(Preferences.getDebugger("Python3Redirect")) |
271 else str(Preferences.getDebugger("Python3Redirect")) |
289 " login was given.</p>" |
349 " login was given.</p>" |
290 ), |
350 ), |
291 ) |
351 ) |
292 return None, False, "" |
352 return None, False, "" |
293 |
353 |
|
354 elif startRemote and self.__ericServerDebuggerInterface is not None: |
|
355 # debugging via an eric-ide server |
|
356 self.translate = self.__ericServerTranslation |
|
357 self.__ericServerDebugging = True |
|
358 |
|
359 args = [] |
|
360 if noencoding: |
|
361 args.append(noencoding) |
|
362 if multiprocessEnabled: |
|
363 args.append(multiprocessEnabled) |
|
364 if callTraceOptimization: |
|
365 args.append(callTraceOptimization) |
|
366 self.__ericServerDebuggerInterface.startClient( |
|
367 interpreter, |
|
368 originalPathString, |
|
369 args, |
|
370 workingDir=workingDir, |
|
371 ) |
|
372 self.__startedVenv = venvName |
|
373 |
|
374 return None, self.__isNetworked, "" |
|
375 |
294 else: |
376 else: |
295 # local debugging code below |
377 # local debugging code below |
296 debugClient = self.__determineDebugClient() |
378 debugClient = self.__determineDebugClient() |
297 |
379 |
298 # set translation function |
380 # set translation function |
415 @param workingDir directory to start the debugger client in |
498 @param workingDir directory to start the debugger client in |
416 @type str |
499 @type str |
417 @param configOverride dictionary containing the global config override |
500 @param configOverride dictionary containing the global config override |
418 data |
501 data |
419 @type dict |
502 @type dict |
|
503 @param startRemote flag indicating to start the client via an eric-ide server |
|
504 (defaults to False) |
|
505 @type bool (optional) |
420 @return client process object, a flag to indicate a network connection |
506 @return client process object, a flag to indicate a network connection |
421 and the name of the interpreter in case of a local execution |
507 and the name of the interpreter in case of a local execution |
422 @rtype tuple of (QProcess, bool, str) |
508 @rtype tuple of (QProcess, bool, str) |
423 """ |
509 """ |
424 global origPathEnv |
510 global origPathEnv |
441 "--call-trace-optimization" |
527 "--call-trace-optimization" |
442 if Preferences.getDebugger("PythonCallTraceOptimization") |
528 if Preferences.getDebugger("PythonCallTraceOptimization") |
443 else "" |
529 else "" |
444 ) |
530 ) |
445 |
531 |
446 if venvName and venvName != self.debugServer.getProjectEnvironmentString(): |
532 if ( |
447 venvManager = ericApp().getObject("VirtualEnvManager") |
533 startRemote is True |
448 interpreter = venvManager.getVirtualenvInterpreter(venvName) |
534 or ( |
449 execPath = venvManager.getVirtualenvExecPath(venvName) |
535 startRemote is None |
|
536 and ( |
|
537 venvName == self.debugServer.getEricServerEnvironmentString() |
|
538 or self.__ericServerDebugging |
|
539 ) |
|
540 ) |
|
541 ) and ericApp().getObject("EricServer").isServerConnected(): |
|
542 # TODO change this once server environment definitions are supported |
|
543 startRemote = True |
|
544 if venvName and venvName != self.debugServer.getProjectEnvironmentString(): |
|
545 venvManager = ericApp().getObject("VirtualEnvManager") |
|
546 interpreter = venvManager.getVirtualenvInterpreter(venvName) |
|
547 else: |
|
548 venvName = project.getProjectVenv() |
|
549 interpreter = project.getProjectInterpreter() |
|
550 if not venvName: |
|
551 venvName = self.debugServer.getEricServerEnvironmentString() |
|
552 interpreter = "" # use the interpreter of the server |
450 else: |
553 else: |
451 venvName = project.getProjectVenv() |
554 if venvName and venvName != self.debugServer.getProjectEnvironmentString(): |
452 execPath = project.getProjectExecPath() |
555 venvManager = ericApp().getObject("VirtualEnvManager") |
453 interpreter = project.getProjectInterpreter() |
556 interpreter = venvManager.getVirtualenvInterpreter(venvName) |
454 if interpreter == "": |
557 execPath = venvManager.getVirtualenvExecPath(venvName) |
455 EricMessageBox.critical( |
558 else: |
456 None, |
559 venvName = project.getProjectVenv() |
457 self.tr("Start Debugger"), |
560 execPath = project.getProjectExecPath() |
458 self.tr("""<p>No suitable Python3 environment configured.</p>"""), |
561 interpreter = project.getProjectInterpreter() |
459 ) |
562 if interpreter == "": |
460 return None, self.__isNetworked, "" |
563 EricMessageBox.critical( |
|
564 None, |
|
565 self.tr("Start Debugger"), |
|
566 self.tr("""<p>No suitable Python3 environment configured.</p>"""), |
|
567 ) |
|
568 return None, self.__isNetworked, "" |
461 |
569 |
462 self.__inShutdown = False |
570 self.__inShutdown = False |
|
571 |
|
572 self.__ericServerDebugging = False |
463 |
573 |
464 if project.getDebugProperty("REMOTEDEBUGGER"): |
574 if project.getDebugProperty("REMOTEDEBUGGER"): |
465 # remote debugging code |
575 # remote debugging code |
466 ipaddr = self.debugServer.getHostAddress(False) |
576 ipaddr = self.debugServer.getHostAddress(False) |
467 rexec = project.getDebugProperty("REMOTECOMMAND") |
577 rexec = project.getDebugProperty("REMOTECOMMAND") |
516 return process, self.__isNetworked, "" |
626 return process, self.__isNetworked, "" |
517 else: |
627 else: |
518 # remote shell command is missing |
628 # remote shell command is missing |
519 return None, self.__isNetworked, "" |
629 return None, self.__isNetworked, "" |
520 |
630 |
|
631 elif startRemote and self.__ericServerDebuggerInterface is not None: |
|
632 # debugging via an eric-ide server |
|
633 self.translate = self.__ericServerTranslation |
|
634 self.__ericServerDebugging = True |
|
635 |
|
636 args = [] |
|
637 if noencoding: |
|
638 args.append(noencoding) |
|
639 if multiprocessEnabled: |
|
640 args.append(multiprocessEnabled) |
|
641 if callTraceOptimization: |
|
642 args.append(callTraceOptimization) |
|
643 self.__ericServerDebuggerInterface.startClient( |
|
644 interpreter, |
|
645 originalPathString, |
|
646 args, |
|
647 workingDir=workingDir, |
|
648 ) |
|
649 self.__startedVenv = venvName |
|
650 |
|
651 return None, self.__isNetworked, "" |
|
652 |
521 else: |
653 else: |
522 # local debugging code below |
654 # local debugging code below |
523 debugClient = project.getDebugProperty("DEBUGCLIENT") |
655 debugClient = project.getDebugProperty("DEBUGCLIENT") |
524 if not bool(debugClient) or not os.path.exists(debugClient): |
656 if not bool(debugClient) or not os.path.exists(debugClient): |
525 debugClient = self.__determineDebugClient() |
657 debugClient = self.__determineDebugClient() |
633 @param sock reference to the socket object |
765 @param sock reference to the socket object |
634 @type QTcpSocket |
766 @type QTcpSocket |
635 @param debuggerId id of the connected debug client |
767 @param debuggerId id of the connected debug client |
636 @type str |
768 @type str |
637 """ |
769 """ |
638 if sock in self.__pendingConnections: |
770 if sock and sock in self.__pendingConnections: |
639 self.__connections[debuggerId] = sock |
771 self.__connections[debuggerId] = sock |
640 self.__pendingConnections.remove(sock) |
772 self.__pendingConnections.remove(sock) |
641 |
773 |
642 if self.__mainDebugger is None: |
774 if self.__mainDebugger is None: |
643 self.__mainDebugger = debuggerId |
775 self.__mainDebugger = debuggerId |
644 # Get the remote clients capabilities |
776 # Get the remote clients capabilities |
645 self.remoteCapabilities(debuggerId) |
777 self.remoteCapabilities(debuggerId) |
646 |
778 |
647 self.debugServer.signalClientDebuggerId(debuggerId) |
779 self.debugServer.signalClientDebuggerId(debuggerId) |
648 |
780 |
649 if debuggerId == self.__mainDebugger: |
781 if debuggerId == self.__mainDebugger: |
650 self.__flush() |
782 self.__flush() |
651 self.debugServer.mainClientConnected() |
783 self.debugServer.mainClientConnected() |
652 |
784 |
653 self.debugServer.initializeClient(debuggerId) |
785 self.debugServer.initializeClient(debuggerId) |
654 |
786 |
655 # perform auto-continue except for main |
787 # perform auto-continue except for main |
656 if ( |
788 if ( |
657 debuggerId != self.__mainDebugger |
789 debuggerId != self.__mainDebugger |
658 and self.__autoContinue |
790 and self.__autoContinue |
659 and not self.__isStepCommand |
791 and not self.__isStepCommand |
660 ): |
792 ): |
661 QTimer.singleShot(0, lambda: self.remoteContinue(debuggerId)) |
793 QTimer.singleShot(0, lambda: self.remoteContinue(debuggerId)) |
662 |
794 |
663 def __socketDisconnected(self, sock): |
795 def __socketDisconnected(self, sock): |
664 """ |
796 """ |
665 Private slot handling a socket disconnecting. |
797 Private slot handling a socket disconnecting. |
666 |
798 |
668 @type QTcpSocket |
800 @type QTcpSocket |
669 """ |
801 """ |
670 for debuggerId in list(self.__connections): |
802 for debuggerId in list(self.__connections): |
671 if self.__connections[debuggerId] is sock: |
803 if self.__connections[debuggerId] is sock: |
672 del self.__connections[debuggerId] |
804 del self.__connections[debuggerId] |
673 if debuggerId == self.__mainDebugger: |
805 self.__handleServerDebugClientDisconnected(debuggerId) |
674 self.__mainDebugger = None |
|
675 if debuggerId in self.__autoContinued: |
|
676 self.__autoContinued.remove(debuggerId) |
|
677 if not self.__inShutdown: |
|
678 with contextlib.suppress(RuntimeError): |
|
679 # can be ignored during a shutdown |
|
680 self.debugServer.signalClientDisconnected(debuggerId) |
|
681 break |
806 break |
682 else: |
807 else: |
683 if sock in self.__pendingConnections: |
808 if sock in self.__pendingConnections: |
684 self.__pendingConnections.remove(sock) |
809 self.__pendingConnections.remove(sock) |
685 |
810 |
686 if not self.__connections: |
811 if not self.__connections: |
687 # no active connections anymore |
812 # no active connections anymore |
|
813 self.__handleServerLastClientExited() |
|
814 |
|
815 @pyqtSlot(str) |
|
816 def __handleServerDebugClientDisconnected(self, debuggerId): |
|
817 """ |
|
818 Private slot handling the disconnect of a debug client. |
|
819 |
|
820 @param debuggerId ID of the disconnected debugger |
|
821 @type str |
|
822 """ |
|
823 if debuggerId == self.__mainDebugger: |
|
824 self.__mainDebugger = None |
|
825 if debuggerId in self.__autoContinued: |
|
826 self.__autoContinued.remove(debuggerId) |
|
827 if not self.__inShutdown: |
688 with contextlib.suppress(RuntimeError): |
828 with contextlib.suppress(RuntimeError): |
689 # debug server object might have been deleted already |
829 # can be ignored during a shutdown |
690 # ignore this |
830 self.debugServer.signalClientDisconnected(debuggerId) |
|
831 |
|
832 @pyqtSlot() |
|
833 def __handleServerLastClientExited(self): |
|
834 """ |
|
835 Private slot to handle the exit of the last debug client connected. |
|
836 """ |
|
837 with contextlib.suppress(RuntimeError): |
|
838 # debug server object might have been deleted already |
|
839 # ignore this |
|
840 self.__autoContinued.clear() |
|
841 if not self.__inShutdown: |
691 self.debugServer.signalLastClientExited() |
842 self.debugServer.signalLastClientExited() |
692 self.__autoContinued.clear() |
843 self.debugServer.startClient() |
693 if not self.__inShutdown: |
|
694 self.debugServer.startClient() |
|
695 |
844 |
696 def getDebuggerIds(self): |
845 def getDebuggerIds(self): |
697 """ |
846 """ |
698 Public method to return the IDs of the connected debugger backends. |
847 Public method to return the IDs of the connected debugger backends. |
699 |
848 |
706 """ |
855 """ |
707 Private slot to flush the queue. |
856 Private slot to flush the queue. |
708 """ |
857 """ |
709 if self.__mainDebugger: |
858 if self.__mainDebugger: |
710 # Send commands that were waiting for the connection. |
859 # Send commands that were waiting for the connection. |
711 conn = self.__connections[self.__mainDebugger] |
860 if self.__ericServerDebugging: |
712 for jsonStr in self.__commandQueue: |
861 for jsonStr in self.__commandQueue: |
713 self.__writeJsonCommandToSocket(jsonStr, conn) |
862 self.__ericServerDebuggerInterface.sendClientCommand( |
|
863 self.__mainDebugger, jsonStr |
|
864 ) |
|
865 else: |
|
866 conn = self.__connections[self.__mainDebugger] |
|
867 for jsonStr in self.__commandQueue: |
|
868 self.__writeJsonCommandToSocket(jsonStr, conn) |
714 |
869 |
715 self.__commandQueue.clear() |
870 self.__commandQueue.clear() |
716 |
871 |
717 def shutdown(self): |
872 def shutdown(self): |
718 """ |
873 """ |
809 @type bool |
966 @type bool |
810 @param reportAllExceptions flag indicating to report all exceptions |
967 @param reportAllExceptions flag indicating to report all exceptions |
811 instead of unhandled exceptions only |
968 instead of unhandled exceptions only |
812 @type bool |
969 @type bool |
813 """ |
970 """ |
|
971 if FileSystemUtilities.isPlainFileName(fn): |
|
972 fn = os.path.abspath(fn) |
|
973 |
814 self.__autoContinue = autoContinue |
974 self.__autoContinue = autoContinue |
815 self.__scriptName = os.path.abspath(fn) |
975 self.__scriptName = fn |
816 self.__isStepCommand = False |
976 self.__isStepCommand = False |
817 |
977 |
818 wd = self.translate(wd, False) |
978 wd = self.translate(wd, False) |
819 fn = self.translate(os.path.abspath(fn), False) |
979 fn = self.translate(fn, False) |
820 self.__sendJsonCommand( |
980 self.__sendJsonCommand( |
821 "RequestLoad", |
981 "RequestLoad", |
822 { |
982 { |
823 "workdir": wd, |
983 "workdir": wd, |
824 "filename": fn, |
984 "filename": fn, |
1041 @param cond condition of the breakpoint |
1210 @param cond condition of the breakpoint |
1042 @type str |
1211 @type str |
1043 @param temp flag indicating a temporary breakpoint |
1212 @param temp flag indicating a temporary breakpoint |
1044 @type bool |
1213 @type bool |
1045 """ |
1214 """ |
1046 debuggerList = [debuggerId] if debuggerId else list(self.__connections) |
1215 if debuggerId: |
|
1216 debuggerList = [debuggerId] |
|
1217 elif self.__ericServerDebugging: |
|
1218 debuggerList = ["<<all>>"] |
|
1219 else: |
|
1220 debuggerList = list(self.__connections) |
1047 for debuggerId in debuggerList: |
1221 for debuggerId in debuggerList: |
1048 self.__sendJsonCommand( |
1222 self.__sendJsonCommand( |
1049 "RequestBreakpoint", |
1223 "RequestBreakpoint", |
1050 { |
1224 { |
1051 "filename": self.translate(fn, False), |
1225 "filename": self.translate(fn, False), |
1068 @param line line number of the breakpoint |
1242 @param line line number of the breakpoint |
1069 @type int |
1243 @type int |
1070 @param enable flag indicating enabling or disabling a breakpoint |
1244 @param enable flag indicating enabling or disabling a breakpoint |
1071 @type bool |
1245 @type bool |
1072 """ |
1246 """ |
1073 debuggerList = [debuggerId] if debuggerId else list(self.__connections) |
1247 if debuggerId: |
|
1248 debuggerList = [debuggerId] |
|
1249 elif self.__ericServerDebugging: |
|
1250 debuggerList = ["<<all>>"] |
|
1251 else: |
|
1252 debuggerList = list(self.__connections) |
1074 for debuggerId in debuggerList: |
1253 for debuggerId in debuggerList: |
1075 self.__sendJsonCommand( |
1254 self.__sendJsonCommand( |
1076 "RequestBreakpointEnable", |
1255 "RequestBreakpointEnable", |
1077 { |
1256 { |
1078 "filename": self.translate(fn, False), |
1257 "filename": self.translate(fn, False), |
1093 @param line line number of the breakpoint |
1272 @param line line number of the breakpoint |
1094 @type int |
1273 @type int |
1095 @param count number of occurrences to ignore |
1274 @param count number of occurrences to ignore |
1096 @type int |
1275 @type int |
1097 """ |
1276 """ |
1098 debuggerList = [debuggerId] if debuggerId else list(self.__connections) |
1277 if debuggerId: |
|
1278 debuggerList = [debuggerId] |
|
1279 elif self.__ericServerDebugging: |
|
1280 debuggerList = ["<<all>>"] |
|
1281 else: |
|
1282 debuggerList = list(self.__connections) |
1099 for debuggerId in debuggerList: |
1283 for debuggerId in debuggerList: |
1100 self.__sendJsonCommand( |
1284 self.__sendJsonCommand( |
1101 "RequestBreakpointIgnore", |
1285 "RequestBreakpointIgnore", |
1102 { |
1286 { |
1103 "filename": self.translate(fn, False), |
1287 "filename": self.translate(fn, False), |
1143 @param cond expression of the watch expression |
1332 @param cond expression of the watch expression |
1144 @type str |
1333 @type str |
1145 @param enable flag indicating enabling or disabling a watch expression |
1334 @param enable flag indicating enabling or disabling a watch expression |
1146 @type bool |
1335 @type bool |
1147 """ |
1336 """ |
1148 debuggerList = [debuggerId] if debuggerId else list(self.__connections) |
1337 if debuggerId: |
|
1338 debuggerList = [debuggerId] |
|
1339 elif self.__ericServerDebugging: |
|
1340 debuggerList = ["<<all>>"] |
|
1341 else: |
|
1342 debuggerList = list(self.__connections) |
1149 for debuggerId in debuggerList: |
1343 for debuggerId in debuggerList: |
1150 # cond is combination of cond and special (s. watch expression |
1344 # cond is combination of cond and special (s. watch expression |
1151 # viewer) |
1345 # viewer) |
1152 self.__sendJsonCommand( |
1346 self.__sendJsonCommand( |
1153 "RequestWatchEnable", |
1347 "RequestWatchEnable", |
1168 @param cond expression of the watch expression |
1362 @param cond expression of the watch expression |
1169 @type str |
1363 @type str |
1170 @param count number of occurrences to ignore |
1364 @param count number of occurrences to ignore |
1171 @type int |
1365 @type int |
1172 """ |
1366 """ |
1173 debuggerList = [debuggerId] if debuggerId else list(self.__connections) |
1367 if debuggerId: |
|
1368 debuggerList = [debuggerId] |
|
1369 elif self.__ericServerDebugging: |
|
1370 debuggerList = ["<<all>>"] |
|
1371 else: |
|
1372 debuggerList = list(self.__connections) |
1174 for debuggerId in debuggerList: |
1373 for debuggerId in debuggerList: |
1175 # cond is combination of cond and special (s. watch expression |
1374 # cond is combination of cond and special (s. watch expression |
1176 # viewer) |
1375 # viewer) |
1177 self.__sendJsonCommand( |
1376 self.__sendJsonCommand( |
1178 "RequestWatchIgnore", |
1377 "RequestWatchIgnore", |
1432 # corrupted data -> discard and continue |
1631 # corrupted data -> discard and continue |
1433 continue |
1632 continue |
1434 |
1633 |
1435 jsonStr = data.decode("utf-8", "backslashreplace") |
1634 jsonStr = data.decode("utf-8", "backslashreplace") |
1436 |
1635 |
1437 logging.debug("<Debug-Server> %s", jsonStr) |
1636 logging.getLogger(__name__).debug("<Debug-Server> %s", jsonStr) |
1438 ##print("Server: ", jsonStr) ## debug # __IGNORE_WARNING_M891__ |
1637 ##print("Server: ", jsonStr) ## debug # __IGNORE_WARNING_M891__ |
1439 |
1638 |
1440 self.__handleJsonCommand(jsonStr, sock) |
1639 self.handleJsonCommand(jsonStr, sock) |
1441 |
1640 |
1442 def __handleJsonCommand(self, jsonStr, sock): |
1641 def handleJsonCommand(self, jsonStr, sock): |
1443 """ |
1642 """ |
1444 Private method to handle a command or response serialized as a |
1643 Public method to handle a command or response serialized as a |
1445 JSON string. |
1644 JSON string. |
1446 |
1645 |
1447 @param jsonStr string containing the command or response received |
1646 @param jsonStr string containing the command or response received |
1448 from the debug backend |
1647 from the debug backend |
1449 @type str |
1648 @type str |
1565 |
1764 |
1566 elif method == "RequestRaw": |
1765 elif method == "RequestRaw": |
1567 self.debugServer.signalClientRawInput( |
1766 self.debugServer.signalClientRawInput( |
1568 params["prompt"], params["echo"], params["debuggerId"] |
1767 params["prompt"], params["echo"], params["debuggerId"] |
1569 ) |
1768 ) |
|
1769 pass |
1570 |
1770 |
1571 elif method == "ResponseBPConditionError": |
1771 elif method == "ResponseBPConditionError": |
1572 fn = self.translate(params["filename"], True) |
1772 fn = self.translate(params["filename"], True) |
1573 self.debugServer.signalClientBreakConditionError( |
1773 self.debugServer.signalClientBreakConditionError( |
1574 fn, params["line"], params["debuggerId"] |
1774 fn, params["line"], params["debuggerId"] |
1675 "method": command, |
1875 "method": command, |
1676 "params": params, |
1876 "params": params, |
1677 } |
1877 } |
1678 jsonStr = json.dumps(commandDict) |
1878 jsonStr = json.dumps(commandDict) |
1679 |
1879 |
1680 if debuggerId and debuggerId in self.__connections: |
1880 if self.__ericServerDebugging: |
1681 sock = self.__connections[debuggerId] |
1881 # Debugging via the eric-ide server -> pass the command on to it |
1682 elif sock is None and self.__mainDebugger is not None: |
1882 if self.__mainDebugger is None: |
1683 sock = self.__connections[self.__mainDebugger] |
1883 # debugger has not connected yet -> queue the command |
1684 if sock is not None: |
1884 self.__commandQueue.append(jsonStr) |
1685 self.__writeJsonCommandToSocket(jsonStr, sock) |
1885 else: |
|
1886 self.__ericServerDebuggerInterface.sendClientCommand( |
|
1887 debuggerId, jsonStr |
|
1888 ) |
1686 else: |
1889 else: |
1687 self.__commandQueue.append(jsonStr) |
1890 # Local debugging -> send the command to the client |
|
1891 if debuggerId and debuggerId in self.__connections: |
|
1892 sock = self.__connections[debuggerId] |
|
1893 elif sock is None and self.__mainDebugger is not None: |
|
1894 with contextlib.suppress(KeyError): |
|
1895 sock = self.__connections[self.__mainDebugger] |
|
1896 if sock is not None: |
|
1897 self.__writeJsonCommandToSocket(jsonStr, sock) |
|
1898 else: |
|
1899 self.__commandQueue.append(jsonStr) |
1688 |
1900 |
1689 def __writeJsonCommandToSocket(self, jsonCommand, sock): |
1901 def __writeJsonCommandToSocket(self, jsonCommand, sock): |
1690 """ |
1902 """ |
1691 Private method to write a JSON command to the socket. |
1903 Private method to write a JSON command to the socket. |
1692 |
1904 |