eric6/Debugger/DebugServer.py

branch
maintenance
changeset 8043
0acf98cd089a
parent 7924
8a96736d465e
parent 7986
2971d5d19951
child 8142
43248bafe9b2
equal deleted inserted replaced
7991:866adc8c315b 8043:0acf98cd089a
7 Module implementing the debug server. 7 Module implementing the debug server.
8 """ 8 """
9 9
10 import os 10 import os
11 11
12 from PyQt5.QtCore import pyqtSignal, QModelIndex 12 from PyQt5.QtCore import pyqtSignal, pyqtSlot, QModelIndex
13 from PyQt5.QtNetwork import ( 13 from PyQt5.QtNetwork import (
14 QTcpServer, QHostAddress, QHostInfo, QNetworkInterface 14 QTcpServer, QHostAddress, QHostInfo, QNetworkInterface
15 ) 15 )
16 16
17 from E5Gui.E5Application import e5App 17 from E5Gui.E5Application import e5App
38 @signal clientProcessStdout(str) emitted after the client has sent some 38 @signal clientProcessStdout(str) emitted after the client has sent some
39 output via stdout 39 output via stdout
40 @signal clientProcessStderr(str) emitted after the client has sent some 40 @signal clientProcessStderr(str) emitted after the client has sent some
41 output via stderr 41 output via stderr
42 @signal clientOutput(str) emitted after the client has sent some output 42 @signal clientOutput(str) emitted after the client has sent some output
43 @signal clientRawInputSent() emitted after the data was sent to the 43 @signal clientRawInputSent(debuggerId) emitted after the data was sent
44 debug client 44 to the indicated debug client
45 @signal clientLine(filename, lineno, forStack) emitted after the 45 @signal clientLine(filename, lineno, debuggerId, threadName, forStack)
46 emitted after the debug client has executed a line of code
47 @signal clientStack(stack, debuggerId, threadName) emitted after the
46 debug client has executed a line of code 48 debug client has executed a line of code
47 @signal clientStack(stack) emitted after the debug client has executed a 49 @signal clientThreadList(currentId, threadList, debuggerId) emitted after
48 line of code 50 a thread list has been received
49 @signal clientThreadList(currentId, threadList) emitted after a thread list 51 @signal clientThreadSet(debuggerId) emitted after the client has
50 has been received 52 acknowledged the change of the current thread
51 @signal clientThreadSet() emitted after the client has acknowledged the 53 @signal clientVariables(scope, variables, debuggerId) emitted after a
52 change of the current thread 54 variables dump has been received
53 @signal clientVariables(scope, variables) emitted after a variables dump 55 @signal clientVariable(scope, variables, debuggerId) emitted after a dump
54 has been received 56 for one class variable has been received
55 @signal clientVariable(scope, variables) emitted after a dump for one class 57 @signal clientStatement(continue, debuggerId) emitted after an interactive
56 variable has been received 58 command has been executed. The parameter is False to indicate that the
57 @signal clientStatement(bool) emitted after an interactive command has 59 command is complete and True if it needs more input.
58 been executed. The parameter is 0 to indicate that the command is 60 @signal clientDisassembly(disassembly, debuggerId) emitted after the client
59 complete and 1 if it needs more input. 61 has sent a disassembly of the code raising an exception
60 @signal clientDisassembly(disassembly) emitted after the client has sent 62 @signal clientException(exceptionType, exceptionMessage, stackTrace,
61 a disassembly of the code raising an exception 63 debuggerId, threadName) emitted after an exception occured on the
62 @signal clientException(exception) emitted after an exception occured on 64 client side
63 the client side 65 @signal clientSyntaxError(message, filename, linenumber, characternumber,
64 @signal clientSyntaxError(exception) emitted after a syntax error has been 66 debuggerId, threadName) emitted after a syntax error has been detected
65 detected on the client side 67 on the client side
66 @signal clientSignal(signal) emitted after a signal has been generated on 68 @signal clientSignal(message, filename, linenumber, function name,
67 the client side 69 function arguments, debuggerId) emitted after a signal has been
68 @signal clientExit(int, str, bool) emitted after the client has exited 70 generated on the client side
69 giving the exit status, an exit message and an indication to be quiet 71 @signal clientDisconnected(str) emitted after a debug client has
70 @signal clientClearBreak(filename, lineno) emitted after the debug client 72 disconnected (i.e. closed the network socket)
71 has decided to clear a temporary breakpoint 73 @signal clientExit(str, int, str, bool, str) emitted after the client has
72 @signal clientBreakConditionError(fn, lineno) emitted after the client has 74 exited giving the program name, the exit status, an exit message, an
73 signaled a syntax error in a breakpoint condition 75 indication to be quiet and the ID of the exited client
74 @signal clientClearWatch(condition) emitted after the debug client 76 @signal lastClientExited() emitted to indicate that the last connected
75 has decided to clear a temporary watch expression 77 debug client has terminated
76 @signal clientWatchConditionError(condition) emitted after the client has 78 @signal clientClearBreak(filename, lineno, debuggerId) emitted after the
77 signaled a syntax error in a watch expression 79 debug client has decided to clear a temporary breakpoint
78 @signal clientRawInput(prompt, echo) emitted after a raw input request was 80 @signal clientBreakConditionError(fn, lineno, debuggerId) emitted after the
79 received 81 client has signaled a syntax error in a breakpoint condition
80 @signal clientBanner(version, platform, dbgclient, venvname) emitted after 82 @signal clientClearWatch(condition, debuggerId) emitted after the debug
83 client has decided to clear a temporary watch expression
84 @signal clientWatchConditionError(condition, debuggerId) emitted after the
85 client has signaled a syntax error in a watch expression
86 @signal clientRawInput(prompt, echo, debuggerId) emitted after a raw input
87 request was received
88 @signal clientBanner(version, platform, venvname) emitted after
81 the client banner data was received 89 the client banner data was received
82 @signal clientCapabilities(capabilities, cltype, venvname) emitted after 90 @signal clientCapabilities(capabilities, cltype, venvname) emitted after
83 the clients capabilities were received 91 the clients capabilities were received
84 @signal clientCompletionList(completionList, text) emitted after the client 92 @signal clientCompletionList(completionList, text) emitted after the
85 the commandline completion list and the reworked searchstring was 93 commandline completion list and the reworked search string was
86 received from the client 94 received from the client
87 @signal passiveDebugStarted(str, bool) emitted after the debug client has 95 @signal passiveDebugStarted(str, bool) emitted after the debug client has
88 connected in passive debug mode 96 connected in passive debug mode
89 @signal clientGone(bool) emitted if the client went away (planned or 97 @signal clientGone(bool) emitted if the client went away (planned or
90 unplanned) 98 unplanned)
109 client reported an expected test failure 117 client reported an expected test failure
110 @signal utTestSucceededUnexpected(testname, id) emitted after the client 118 @signal utTestSucceededUnexpected(testname, id) emitted after the client
111 reported an unexpected test success 119 reported an unexpected test success
112 @signal callTraceInfo emitted after the client reported the call trace 120 @signal callTraceInfo emitted after the client reported the call trace
113 data (isCall, fromFile, fromLine, fromFunction, toFile, toLine, 121 data (isCall, fromFile, fromLine, fromFunction, toFile, toLine,
114 toFunction) 122 toFunction, debuggerId)
115 @signal appendStdout(msg) emitted when a passive debug connection is 123 @signal appendStdout(msg) emitted when a passive debug connection is
116 established or lost 124 established or lost
125 @signal clientDebuggerId(debuggerId) emitted to indicate a newly connected
126 debugger backend
117 """ 127 """
118 clientClearBreak = pyqtSignal(str, int) 128 clientClearBreak = pyqtSignal(str, int, str)
119 clientClearWatch = pyqtSignal(str) 129 clientClearWatch = pyqtSignal(str, str)
120 clientGone = pyqtSignal(bool) 130 clientGone = pyqtSignal(bool)
121 clientProcessStdout = pyqtSignal(str) 131 clientProcessStdout = pyqtSignal(str)
122 clientProcessStderr = pyqtSignal(str) 132 clientProcessStderr = pyqtSignal(str)
123 clientRawInputSent = pyqtSignal() 133 clientRawInputSent = pyqtSignal(str)
124 clientOutput = pyqtSignal(str) 134 clientOutput = pyqtSignal(str)
125 clientLine = pyqtSignal(str, int, bool) 135 clientLine = pyqtSignal(str, int, str, str, bool)
126 clientStack = pyqtSignal(list) 136 clientStack = pyqtSignal(list, str, str)
127 clientThreadList = pyqtSignal('PyQt_PyObject', list) 137 clientThreadList = pyqtSignal('PyQt_PyObject', list, str)
128 clientThreadSet = pyqtSignal() 138 clientThreadSet = pyqtSignal(str)
129 clientVariables = pyqtSignal(int, list) 139 clientVariables = pyqtSignal(int, list, str)
130 clientVariable = pyqtSignal(int, list) 140 clientVariable = pyqtSignal(int, list, str)
131 clientStatement = pyqtSignal(bool) 141 clientStatement = pyqtSignal(bool, str)
132 clientDisassembly = pyqtSignal(dict) 142 clientDisassembly = pyqtSignal(dict, str)
133 clientException = pyqtSignal(str, str, list) 143 clientException = pyqtSignal(str, str, list, str, str)
134 clientSyntaxError = pyqtSignal(str, str, int, int) 144 clientSyntaxError = pyqtSignal(str, str, int, int, str, str)
135 clientSignal = pyqtSignal(str, str, int, str, str) 145 clientSignal = pyqtSignal(str, str, int, str, str, str)
136 clientExit = pyqtSignal(int, str, bool) 146 clientDisconnected = pyqtSignal(str)
137 clientBreakConditionError = pyqtSignal(str, int) 147 clientExit = pyqtSignal(str, int, str, bool, str)
138 clientWatchConditionError = pyqtSignal(str) 148 lastClientExited = pyqtSignal()
139 clientRawInput = pyqtSignal(str, bool) 149 clientBreakConditionError = pyqtSignal(str, int, str)
140 clientBanner = pyqtSignal(str, str, str, str) 150 clientWatchConditionError = pyqtSignal(str, str)
151 clientRawInput = pyqtSignal(str, bool, str)
152 clientBanner = pyqtSignal(str, str, str)
141 clientCapabilities = pyqtSignal(int, str, str) 153 clientCapabilities = pyqtSignal(int, str, str)
142 clientCompletionList = pyqtSignal(list, str) 154 clientCompletionList = pyqtSignal(list, str)
143 clientInterpreterChanged = pyqtSignal(str) 155 clientInterpreterChanged = pyqtSignal(str)
156 clientDebuggerId = pyqtSignal(str)
144 utDiscovered = pyqtSignal(list, str, str) 157 utDiscovered = pyqtSignal(list, str, str)
145 utPrepared = pyqtSignal(int, str, str) 158 utPrepared = pyqtSignal(int, str, str)
146 utStartTest = pyqtSignal(str, str) 159 utStartTest = pyqtSignal(str, str)
147 utStopTest = pyqtSignal() 160 utStopTest = pyqtSignal()
148 utTestFailed = pyqtSignal(str, str, str) 161 utTestFailed = pyqtSignal(str, str, str)
150 utTestSkipped = pyqtSignal(str, str, str) 163 utTestSkipped = pyqtSignal(str, str, str)
151 utTestFailedExpected = pyqtSignal(str, str, str) 164 utTestFailedExpected = pyqtSignal(str, str, str)
152 utTestSucceededUnexpected = pyqtSignal(str, str) 165 utTestSucceededUnexpected = pyqtSignal(str, str)
153 utFinished = pyqtSignal() 166 utFinished = pyqtSignal()
154 passiveDebugStarted = pyqtSignal(str, bool) 167 passiveDebugStarted = pyqtSignal(str, bool)
155 callTraceInfo = pyqtSignal(bool, str, str, str, str, str, str) 168 callTraceInfo = pyqtSignal(bool, str, str, str, str, str, str, str)
156 appendStdout = pyqtSignal(str) 169 appendStdout = pyqtSignal(str)
157 170
158 def __init__(self, originalPathString, preventPassiveDebugging=False): 171 def __init__(self, originalPathString, preventPassiveDebugging=False):
159 """ 172 """
160 Constructor 173 Constructor
184 self.watchpointModel = WatchPointModel(self) 197 self.watchpointModel = WatchPointModel(self)
185 self.watchSpecialCreated = self.tr( 198 self.watchSpecialCreated = self.tr(
186 "created", "must be same as in EditWatchpointDialog") 199 "created", "must be same as in EditWatchpointDialog")
187 self.watchSpecialChanged = self.tr( 200 self.watchSpecialChanged = self.tr(
188 "changed", "must be same as in EditWatchpointDialog") 201 "changed", "must be same as in EditWatchpointDialog")
202
203 # arrays to track already reported issues
204 self.__reportedBreakpointIssues = []
205 self.__reportedWatchpointIssues = []
189 206
190 self.networkInterface = Preferences.getDebugger("NetworkInterface") 207 self.networkInterface = Preferences.getDebugger("NetworkInterface")
191 if self.networkInterface == "all": 208 if self.networkInterface == "all":
192 hostAddress = QHostAddress("0.0.0.0") # QHostAddress.Any) # secok 209 hostAddress = QHostAddress("0.0.0.0") # QHostAddress.Any) # secok
193 elif self.networkInterface == "allv6": 210 elif self.networkInterface == "allv6":
240 self.watchpointModel.dataChanged.connect(self.__changeWatchPoints) 257 self.watchpointModel.dataChanged.connect(self.__changeWatchPoints)
241 self.watchpointModel.rowsInserted.connect(self.__addWatchPoints) 258 self.watchpointModel.rowsInserted.connect(self.__addWatchPoints)
242 259
243 self.__maxVariableSize = Preferences.getDebugger("MaxVariableSize") 260 self.__maxVariableSize = Preferences.getDebugger("MaxVariableSize")
244 261
262 self.__multiprocessNoDebugList = []
263
245 self.__registerDebuggerInterfaces() 264 self.__registerDebuggerInterfaces()
246 265
247 def getHostAddress(self, localhost): 266 def getHostAddress(self, localhost):
248 """ 267 """
249 Public method to get the IP address or hostname the debug server is 268 Public method to get the IP address or hostname the debug server is
250 listening. 269 listening.
251 270
252 @param localhost flag indicating to return the address for localhost 271 @param localhost flag indicating to return the address for localhost
253 (boolean) 272 @type bool
254 @return IP address or hostname (string) 273 @return IP address or hostname
274 @rtype str
255 """ 275 """
256 if self.networkInterface == "all": 276 if self.networkInterface == "all":
257 if localhost: 277 if localhost:
258 return "127.0.0.1" 278 return "127.0.0.1"
259 else: 279 else:
264 else: 284 else:
265 return "{0}@@v6".format(QHostInfo.localHostName()) 285 return "{0}@@v6".format(QHostInfo.localHostName())
266 else: 286 else:
267 return "{0}@@i{1}".format(self.networkInterface, 287 return "{0}@@i{1}".format(self.networkInterface,
268 self.networkInterfaceIndex) 288 self.networkInterfaceIndex)
269 289
270 def __getNetworkInterfaceAndIndex(self, address): 290 def __getNetworkInterfaceAndIndex(self, address):
271 """ 291 """
272 Private method to determine the network interface and the interface 292 Private method to determine the network interface and the interface
273 index. 293 index.
274 294
275 @param address address to determine the info for (string) 295 @param address address to determine the info for
276 @return tuple of network interface name (string) and index (integer) 296 @type str
297 @return tuple of network interface name and index
298 @rtype tuple of (str, int)
277 """ 299 """
278 if address not in ["all", "allv6"]: 300 if address not in ["all", "allv6"]:
279 for networkInterface in QNetworkInterface.allInterfaces(): 301 for networkInterface in QNetworkInterface.allInterfaces():
280 addressEntries = networkInterface.addressEntries() 302 addressEntries = networkInterface.addressEntries()
281 if len(addressEntries) > 0: 303 if len(addressEntries) > 0:
284 address.lower()): 306 address.lower()):
285 return (networkInterface.humanReadableName(), 307 return (networkInterface.humanReadableName(),
286 networkInterface.index()) 308 networkInterface.index())
287 309
288 return "", 0 310 return "", 0
289 311
290 def preferencesChanged(self): 312 def preferencesChanged(self):
291 """ 313 """
292 Public slot to handle the preferencesChanged signal. 314 Public slot to handle the preferencesChanged signal.
293 """ 315 """
294 registeredInterfaces = {} 316 registeredInterfaces = {}
300 for interfaceName, getRegistryData in registeredInterfaces.items(): 322 for interfaceName, getRegistryData in registeredInterfaces.items():
301 self.registerDebuggerInterface(interfaceName, getRegistryData, 323 self.registerDebuggerInterface(interfaceName, getRegistryData,
302 reregister=True) 324 reregister=True)
303 325
304 self.__maxVariableSize = Preferences.getDebugger("MaxVariableSize") 326 self.__maxVariableSize = Preferences.getDebugger("MaxVariableSize")
305 327
306 def registerDebuggerInterface(self, interfaceName, getRegistryData, 328 def registerDebuggerInterface(self, interfaceName, getRegistryData,
307 reregister=False): 329 reregister=False):
308 """ 330 """
309 Public method to register a debugger interface. 331 Public method to register a debugger interface.
310 332
334 for (clientLanguage, clientCapabilities, clientExtensions, 356 for (clientLanguage, clientCapabilities, clientExtensions,
335 interfaceCreator) in registryDataList: 357 interfaceCreator) in registryDataList:
336 self.__debuggerInterfaceRegistry[clientLanguage] = [ 358 self.__debuggerInterfaceRegistry[clientLanguage] = [
337 clientCapabilities, clientExtensions, interfaceCreator, 359 clientCapabilities, clientExtensions, interfaceCreator,
338 interfaceName] 360 interfaceName]
339 361
340 def unregisterDebuggerInterface(self, interfaceName): 362 def unregisterDebuggerInterface(self, interfaceName):
341 """ 363 """
342 Public method to unregister a debugger interface. 364 Public method to unregister a debugger interface.
343 365
344 @param interfaceName interfaceName of the debugger interface 366 @param interfaceName interfaceName of the debugger interface
351 if interfaceName == registryData[-1]: 373 if interfaceName == registryData[-1]:
352 clientLanguages.append(clientLanguage) 374 clientLanguages.append(clientLanguage)
353 for clientLanguage in clientLanguages: 375 for clientLanguage in clientLanguages:
354 del self.__debuggerInterfaceRegistry[clientLanguage] 376 del self.__debuggerInterfaceRegistry[clientLanguage]
355 del self.__debuggerInterfaces[interfaceName] 377 del self.__debuggerInterfaces[interfaceName]
356 378
357 def __findLanguageForExtension(self, ext): 379 def __findLanguageForExtension(self, ext):
358 """ 380 """
359 Private method to get the language associated with a file extension. 381 Private method to get the language associated with a file extension.
360 382
361 @param ext file extension 383 @param ext file extension
366 for language in self.__debuggerInterfaceRegistry: 388 for language in self.__debuggerInterfaceRegistry:
367 if ext in self.__debuggerInterfaceRegistry[language][1]: 389 if ext in self.__debuggerInterfaceRegistry[language][1]:
368 return language 390 return language
369 391
370 return "" 392 return ""
371 393
372 def __registerDebuggerInterfaces(self): 394 def __registerDebuggerInterfaces(self):
373 """ 395 """
374 Private method to register the available internal debugger interfaces. 396 Private method to register the available internal debugger interfaces.
375 """ 397 """
376 for name, interface in DebuggerInterfaces.items(): 398 for name, interface in DebuggerInterfaces.items():
379 components = modName.split('.') 401 components = modName.split('.')
380 for comp in components[1:]: 402 for comp in components[1:]:
381 mod = getattr(mod, comp) 403 mod = getattr(mod, comp)
382 404
383 self.registerDebuggerInterface(name, mod.getRegistryData) 405 self.registerDebuggerInterface(name, mod.getRegistryData)
384 406
385 def getSupportedLanguages(self, shellOnly=False): 407 def getSupportedLanguages(self, shellOnly=False):
386 """ 408 """
387 Public slot to return the supported programming languages. 409 Public slot to return the supported programming languages.
388 410
389 @param shellOnly flag indicating only languages supporting an 411 @param shellOnly flag indicating only languages supporting an
390 interactive shell should be returned 412 interactive shell should be returned
391 @return list of supported languages (list of strings) 413 @type bool
414 @return list of supported languages
415 @rtype list of str
392 """ 416 """
393 languages = list(self.__debuggerInterfaceRegistry.keys()) 417 languages = list(self.__debuggerInterfaceRegistry.keys())
394 try: 418 try:
395 languages.remove("None") 419 languages.remove("None")
396 except ValueError: 420 except ValueError:
400 languages = [lang for lang in languages 424 languages = [lang for lang in languages
401 if self.__debuggerInterfaceRegistry[lang][0] & 425 if self.__debuggerInterfaceRegistry[lang][0] &
402 DebugClientCapabilities.HasShell] 426 DebugClientCapabilities.HasShell]
403 427
404 return languages[:] 428 return languages[:]
405 429
406 def getExtensions(self, language): 430 def getExtensions(self, language):
407 """ 431 """
408 Public slot to get the extensions associated with the given language. 432 Public slot to get the extensions associated with the given language.
409 433
410 @param language language to get extensions for (string) 434 @param language language to get extensions for
435 @type str
411 @return tuple of extensions associated with the language 436 @return tuple of extensions associated with the language
412 (tuple of strings) 437 @rtype tuple of str
413 """ 438 """
414 if language in self.__debuggerInterfaceRegistry: 439 if language in self.__debuggerInterfaceRegistry:
415 return tuple(self.__debuggerInterfaceRegistry[language][1]) 440 return tuple(self.__debuggerInterfaceRegistry[language][1])
416 else: 441 else:
417 return () 442 return ()
418 443
419 def __createDebuggerInterface(self, clientType=None): 444 def __createDebuggerInterface(self, clientType=None):
420 """ 445 """
421 Private slot to create the debugger interface object. 446 Private slot to create the debugger interface object.
422 447
423 @param clientType type of the client interface to be created (string) 448 @param clientType type of the client interface to be created
449 @type str
424 """ 450 """
425 if self.lastClientType != self.clientType or clientType is not None: 451 if self.lastClientType != self.clientType or clientType is not None:
426 if clientType is None: 452 if clientType is None:
427 clientType = self.clientType 453 clientType = self.clientType
428 if clientType in self.__debuggerInterfaceRegistry: 454 if clientType in self.__debuggerInterfaceRegistry:
432 else: 458 else:
433 self.debuggerInterface = ( 459 self.debuggerInterface = (
434 self.__debuggerInterfaceRegistry["None"][2]( 460 self.__debuggerInterfaceRegistry["None"][2](
435 self, self.passive)) 461 self, self.passive))
436 self.clientType = "None" 462 self.clientType = "None"
437 463
438 def __setClientType(self, clType): 464 def __setClientType(self, clType):
439 """ 465 """
440 Private method to set the client type. 466 Private method to set the client type.
441 467
442 @param clType type of client to be started (string) 468 @param clType type of client to be started
469 @type str
443 """ 470 """
444 if clType is not None and clType in self.getSupportedLanguages(): 471 if clType is not None and clType in self.getSupportedLanguages():
445 self.clientType = clType 472 self.clientType = clType
446 Preferences.Prefs.settings.setValue( 473 Preferences.Prefs.settings.setValue(
447 'DebugClient/Type', self.clientType) 474 'DebugClient/Type', self.clientType)
448 475
449 def startClient(self, unplanned=True, clType=None, forProject=False, 476 def startClient(self, unplanned=True, clType=None, forProject=False,
450 runInConsole=False, venvName="", workingDir=None): 477 runInConsole=False, venvName="", workingDir=None):
451 """ 478 """
452 Public method to start a debug client. 479 Public method to start a debug client.
453 480
454 @keyparam unplanned flag indicating that the client has died 481 @param unplanned flag indicating that the client has died
455 @type bool 482 @type bool
456 @keyparam clType type of client to be started 483 @param clType type of client to be started
457 @type str 484 @type str
458 @keyparam forProject flag indicating a project related action 485 @param forProject flag indicating a project related action
459 @type bool 486 @type bool
460 @keyparam runInConsole flag indicating to start the debugger in a 487 @param runInConsole flag indicating to start the debugger in a
461 console window 488 console window
462 @type bool 489 @type bool
463 @keyparam venvName name of the virtual environment to be used 490 @param venvName name of the virtual environment to be used
464 @type str 491 @type str
465 @keyparam workingDir directory to start the debugger client in 492 @param workingDir directory to start the debugger client in
466 @type str 493 @type str
467 """ 494 """
468 self.running = False 495 self.running = False
469 496
470 if not self.passive or not self.passiveClientExited: 497 if not self.passive or not self.passiveClientExited:
519 self.lastClientType = self.clientType 546 self.lastClientType = self.clientType
520 self.remoteBanner() 547 self.remoteBanner()
521 elif self.__autoClearShell: 548 elif self.__autoClearShell:
522 self.__autoClearShell = False 549 self.__autoClearShell = False
523 self.remoteBanner() 550 self.remoteBanner()
524 ## self.remoteClientVariables(0, [], 0)
525 ## self.remoteClientVariables(1, [], 0)
526 else: 551 else:
527 if clType and self.lastClientType: 552 if clType and self.lastClientType:
528 self.__setClientType(self.lastClientType) 553 self.__setClientType(self.lastClientType)
529 else: 554 else:
530 self.__createDebuggerInterface("None") 555 self.__createDebuggerInterface("None")
531 clientInterpreter = "" 556 clientInterpreter = ""
532 557
533 if clientInterpreter != self.clientInterpreter: 558 if clientInterpreter != self.clientInterpreter:
534 self.clientInterpreter = clientInterpreter 559 self.clientInterpreter = clientInterpreter
535 self.clientInterpreterChanged.emit(clientInterpreter) 560 self.clientInterpreterChanged.emit(clientInterpreter)
536 561
537 def __clientProcessOutput(self): 562 def __clientProcessOutput(self):
538 """ 563 """
539 Private slot to process client output received via stdout. 564 Private slot to process client output received via stdout.
540 """ 565 """
541 output = str(self.clientProcess.readAllStandardOutput(), 566 output = str(self.clientProcess.readAllStandardOutput(),
542 Preferences.getSystem("IOEncoding"), 567 Preferences.getSystem("IOEncoding"),
543 'replace') 568 'replace')
544 self.clientProcessStdout.emit(output) 569 self.clientProcessStdout.emit(output)
545 570
546 def __clientProcessError(self): 571 def __clientProcessError(self):
547 """ 572 """
548 Private slot to process client output received via stderr. 573 Private slot to process client output received via stderr.
549 """ 574 """
550 error = str(self.clientProcess.readAllStandardError(), 575 error = str(self.clientProcess.readAllStandardError(),
551 Preferences.getSystem("IOEncoding"), 576 Preferences.getSystem("IOEncoding"),
552 'replace') 577 'replace')
553 self.clientProcessStderr.emit(error) 578 self.clientProcessStderr.emit(error)
554 579
580 @pyqtSlot(str, int)
555 def __clientClearBreakPoint(self, fn, lineno): 581 def __clientClearBreakPoint(self, fn, lineno):
556 """ 582 """
557 Private slot to handle the clientClearBreak signal. 583 Private slot to handle the clientClearBreak signal.
558 584
559 @param fn filename of breakpoint to clear (string) 585 @param fn filename of breakpoint to clear
560 @param lineno line number of breakpoint to clear (integer) 586 @type str
587 @param lineno line number of breakpoint to clear
588 @type int
561 """ 589 """
562 if self.debugging: 590 if self.debugging:
563 index = self.breakpointModel.getBreakPointIndex(fn, lineno) 591 index = self.breakpointModel.getBreakPointIndex(fn, lineno)
564 self.breakpointModel.deleteBreakPointByIndex(index) 592 self.breakpointModel.deleteBreakPointByIndex(index)
565 593 if (fn, lineno) in self.__reportedBreakpointIssues:
594 self.__reportedBreakpointIssues.remove((fn, lineno))
595
566 def __deleteBreakPoints(self, parentIndex, start, end): 596 def __deleteBreakPoints(self, parentIndex, start, end):
567 """ 597 """
568 Private slot to delete breakpoints. 598 Private slot to delete breakpoints.
569 599
570 @param parentIndex index of parent item (QModelIndex) 600 @param parentIndex index of parent item
571 @param start start row (integer) 601 @type QModelIndex
572 @param end end row (integer) 602 @param start start row
603 @type int
604 @param end end row
605 @type int
573 """ 606 """
574 if self.debugging: 607 if self.debugging:
575 for row in range(start, end + 1): 608 for row in range(start, end + 1):
576 index = self.breakpointModel.index(row, 0, parentIndex) 609 index = self.breakpointModel.index(row, 0, parentIndex)
577 fn, lineno = ( 610 fn, lineno = (
578 self.breakpointModel.getBreakPointByIndex(index)[0:2]) 611 self.breakpointModel.getBreakPointByIndex(index)[0:2])
579 self.remoteBreakpoint(fn, lineno, False) 612 # delete the breakpoints of all connected backends
580 613 self.remoteBreakpoint("", fn, lineno, False)
614 if (fn, lineno) in self.__reportedBreakpointIssues:
615 self.__reportedBreakpointIssues.remove((fn, lineno))
616
581 def __changeBreakPoints(self, startIndex, endIndex): 617 def __changeBreakPoints(self, startIndex, endIndex):
582 """ 618 """
583 Private slot to set changed breakpoints. 619 Private slot to set changed breakpoints.
584 620
585 @param startIndex starting index of the change breakpoins (QModelIndex) 621 @param startIndex starting index of the change breakpoins
586 @param endIndex ending index of the change breakpoins (QModelIndex) 622 @type QModelIndex
623 @param endIndex ending index of the change breakpoins
624 @type QModelIndex
587 """ 625 """
588 if self.debugging: 626 if self.debugging:
589 self.__addBreakPoints( 627 self.__addBreakPoints(
590 QModelIndex(), startIndex.row(), endIndex.row()) 628 QModelIndex(), startIndex.row(), endIndex.row())
591 629
592 def __breakPointDataAboutToBeChanged(self, startIndex, endIndex): 630 def __breakPointDataAboutToBeChanged(self, startIndex, endIndex):
593 """ 631 """
594 Private slot to handle the dataAboutToBeChanged signal of the 632 Private slot to handle the dataAboutToBeChanged signal of the
595 breakpoint model. 633 breakpoint model.
596 634
597 @param startIndex start index of the rows to be changed (QModelIndex) 635 @param startIndex start index of the rows to be changed
598 @param endIndex end index of the rows to be changed (QModelIndex) 636 @type QModelIndex
637 @param endIndex end index of the rows to be changed
638 @type QModelIndex
599 """ 639 """
600 if self.debugging: 640 if self.debugging:
601 self.__deleteBreakPoints( 641 self.__deleteBreakPoints(
602 QModelIndex(), startIndex.row(), endIndex.row()) 642 QModelIndex(), startIndex.row(), endIndex.row())
603 643
604 def __addBreakPoints(self, parentIndex, start, end): 644 def __addBreakPoints(self, parentIndex, start, end, debuggerId=""):
605 """ 645 """
606 Private slot to add breakpoints. 646 Private slot to add breakpoints.
607 647
608 @param parentIndex index of parent item (QModelIndex) 648 @param parentIndex index of parent item
609 @param start start row (integer) 649 @type QModelIndex
610 @param end end row (integer) 650 @param start start row
651 @type int
652 @param end end row
653 @type int
654 @param debuggerId ID of the debugger backend to send to. If this is
655 empty, they will be broadcast to all connected backends.
656 @type str
611 """ 657 """
612 if self.debugging: 658 if self.debugging:
613 for row in range(start, end + 1): 659 for row in range(start, end + 1):
614 index = self.breakpointModel.index(row, 0, parentIndex) 660 index = self.breakpointModel.index(row, 0, parentIndex)
615 fn, line, cond, temp, enabled, ignorecount = ( 661 fn, lineno, cond, temp, enabled, ignorecount = (
616 self.breakpointModel.getBreakPointByIndex(index)[:6]) 662 self.breakpointModel.getBreakPointByIndex(index)[:6])
617 self.remoteBreakpoint(fn, line, True, cond, temp) 663
664 if (fn, lineno) in self.__reportedBreakpointIssues:
665 self.__reportedBreakpointIssues.remove((fn, lineno))
666
667 self.remoteBreakpoint(debuggerId, fn, lineno, True, cond, temp)
618 if not enabled: 668 if not enabled:
619 self.__remoteBreakpointEnable(fn, line, False) 669 self.__remoteBreakpointEnable(
670 debuggerId, fn, lineno, False)
620 if ignorecount: 671 if ignorecount:
621 self.__remoteBreakpointIgnore(fn, line, ignorecount) 672 self.__remoteBreakpointIgnore(
622 673 debuggerId, fn, lineno, ignorecount)
674
623 def __makeWatchCondition(self, cond, special): 675 def __makeWatchCondition(self, cond, special):
624 """ 676 """
625 Private method to construct the condition string. 677 Private method to construct the condition string.
626 678
627 @param cond condition (string) 679 @param cond condition
628 @param special special condition (string) 680 @type str
629 @return condition string (string) 681 @param special special condition
682 @type str
683 @return condition string
684 @rtype str
630 """ 685 """
631 if special == "": 686 if special == "":
632 _cond = cond 687 _cond = cond
633 else: 688 else:
634 if special == self.watchSpecialCreated: 689 if special == self.watchSpecialCreated:
635 _cond = "{0} ??created??".format(cond) 690 _cond = "{0} ??created??".format(cond)
636 elif special == self.watchSpecialChanged: 691 elif special == self.watchSpecialChanged:
637 _cond = "{0} ??changed??".format(cond) 692 _cond = "{0} ??changed??".format(cond)
638 return _cond 693 return _cond
639 694
640 def __splitWatchCondition(self, cond): 695 def __splitWatchCondition(self, cond):
641 """ 696 """
642 Private method to split a remote watch expression. 697 Private method to split a remote watch expression.
643 698
644 @param cond remote expression (string) 699 @param cond remote expression
700 @type str
645 @return tuple of local expression (string) and special condition 701 @return tuple of local expression (string) and special condition
646 (string) 702 @rtype str
647 """ 703 """
648 if cond.endswith(" ??created??"): 704 if cond.endswith(" ??created??"):
649 cond, special = cond.split() 705 cond, special = cond.split()
650 special = self.watchSpecialCreated 706 special = self.watchSpecialCreated
651 elif cond.endswith(" ??changed??"): 707 elif cond.endswith(" ??changed??"):
654 else: 710 else:
655 cond = cond 711 cond = cond
656 special = "" 712 special = ""
657 713
658 return cond, special 714 return cond, special
659 715
716 @pyqtSlot(str)
660 def __clientClearWatchPoint(self, condition): 717 def __clientClearWatchPoint(self, condition):
661 """ 718 """
662 Private slot to handle the clientClearWatch signal. 719 Private slot to handle the clientClearWatch signal.
663 720
664 @param condition expression of watch expression to clear (string) 721 @param condition expression of watch expression to clear
722 @type str
665 """ 723 """
666 if self.debugging: 724 if self.debugging:
667 cond, special = self.__splitWatchCondition(condition) 725 cond, special = self.__splitWatchCondition(condition)
668 index = self.watchpointModel.getWatchPointIndex(cond, special) 726 index = self.watchpointModel.getWatchPointIndex(cond, special)
669 self.watchpointModel.deleteWatchPointByIndex(index) 727 self.watchpointModel.deleteWatchPointByIndex(index)
670 728 if condition in self.__reportedWatchpointIssues:
729 self.__reportedWatchpointIssues.remove(condition)
730
671 def __deleteWatchPoints(self, parentIndex, start, end): 731 def __deleteWatchPoints(self, parentIndex, start, end):
672 """ 732 """
673 Private slot to delete watch expressions. 733 Private slot to delete watch expressions.
674 734
675 @param parentIndex index of parent item (QModelIndex) 735 @param parentIndex index of parent item
676 @param start start row (integer) 736 @type QModelIndex
677 @param end end row (integer) 737 @param start start row
738 @type int
739 @param end end row
740 @type int
678 """ 741 """
679 if self.debugging: 742 if self.debugging:
680 for row in range(start, end + 1): 743 for row in range(start, end + 1):
681 index = self.watchpointModel.index(row, 0, parentIndex) 744 index = self.watchpointModel.index(row, 0, parentIndex)
682 cond, special = ( 745 cond, special = (
683 self.watchpointModel.getWatchPointByIndex(index)[0:2]) 746 self.watchpointModel.getWatchPointByIndex(index)[0:2])
684 cond = self.__makeWatchCondition(cond, special) 747 cond = self.__makeWatchCondition(cond, special)
685 self.__remoteWatchpoint(cond, False) 748 self.__remoteWatchpoint("", cond, False)
686 749 if cond in self.__reportedWatchpointIssues:
750 self.__reportedWatchpointIssues.remove(cond)
751
687 def __watchPointDataAboutToBeChanged(self, startIndex, endIndex): 752 def __watchPointDataAboutToBeChanged(self, startIndex, endIndex):
688 """ 753 """
689 Private slot to handle the dataAboutToBeChanged signal of the 754 Private slot to handle the dataAboutToBeChanged signal of the
690 watch expression model. 755 watch expression model.
691 756
692 @param startIndex start index of the rows to be changed (QModelIndex) 757 @param startIndex start index of the rows to be changed
693 @param endIndex end index of the rows to be changed (QModelIndex) 758 @type QModelIndex
759 @param endIndex end index of the rows to be changed
760 @type QModelIndex
694 """ 761 """
695 if self.debugging: 762 if self.debugging:
696 self.__deleteWatchPoints( 763 self.__deleteWatchPoints(
697 QModelIndex(), startIndex.row(), endIndex.row()) 764 QModelIndex(), startIndex.row(), endIndex.row())
698 765
699 def __addWatchPoints(self, parentIndex, start, end): 766 def __addWatchPoints(self, parentIndex, start, end, debuggerId=""):
700 """ 767 """
701 Private slot to set a watch expression. 768 Private slot to set a watch expression.
702 769
703 @param parentIndex index of parent item (QModelIndex) 770 @param parentIndex index of parent item
704 @param start start row (integer) 771 @type QModelIndex
705 @param end end row (integer) 772 @param start start row
773 @type int
774 @param end end row
775 @type int
776 @param debuggerId ID of the debugger backend to send to. If this is
777 empty, they will be broadcast to all connected backends.
778 @type str
706 """ 779 """
707 if self.debugging: 780 if self.debugging:
708 for row in range(start, end + 1): 781 for row in range(start, end + 1):
709 index = self.watchpointModel.index(row, 0, parentIndex) 782 index = self.watchpointModel.index(row, 0, parentIndex)
710 cond, special, temp, enabled, ignorecount = ( 783 cond, special, temp, enabled, ignorecount = (
711 self.watchpointModel.getWatchPointByIndex(index)[:5]) 784 self.watchpointModel.getWatchPointByIndex(index)[:5])
712 cond = self.__makeWatchCondition(cond, special) 785 cond = self.__makeWatchCondition(cond, special)
713 self.__remoteWatchpoint(cond, True, temp) 786
787 if cond in self.__reportedWatchpointIssues:
788 self.__reportedWatchpointIssues.remove(cond)
789
790 self.__remoteWatchpoint(debuggerId, cond, True, temp)
714 if not enabled: 791 if not enabled:
715 self.__remoteWatchpointEnable(cond, False) 792 self.__remoteWatchpointEnable(debuggerId, cond, False)
716 if ignorecount: 793 if ignorecount:
717 self.__remoteWatchpointIgnore(cond, ignorecount) 794 self.__remoteWatchpointIgnore(debuggerId, cond,
718 795 ignorecount)
796
719 def __changeWatchPoints(self, startIndex, endIndex): 797 def __changeWatchPoints(self, startIndex, endIndex):
720 """ 798 """
721 Private slot to set changed watch expressions. 799 Private slot to set changed watch expressions.
722 800
723 @param startIndex start index of the rows to be changed (QModelIndex) 801 @param startIndex start index of the rows to be changed
724 @param endIndex end index of the rows to be changed (QModelIndex) 802 @type QModelIndex
803 @param endIndex end index of the rows to be changed
804 @type QModelIndex
725 """ 805 """
726 if self.debugging: 806 if self.debugging:
727 self.__addWatchPoints( 807 self.__addWatchPoints(
728 QModelIndex(), startIndex.row(), endIndex.row()) 808 QModelIndex(), startIndex.row(), endIndex.row())
729 809
730 def getClientCapabilities(self, clientType): 810 def getClientCapabilities(self, clientType):
731 """ 811 """
732 Public method to retrieve the debug clients capabilities. 812 Public method to retrieve the debug clients capabilities.
733 813
734 @param clientType debug client type (string) 814 @param clientType debug client type
735 @return debug client capabilities (integer) 815 @type str
816 @return debug client capabilities
817 @rtype int
736 """ 818 """
737 try: 819 try:
738 return self.__debuggerInterfaceRegistry[clientType][0] 820 return self.__debuggerInterfaceRegistry[clientType][0]
739 except KeyError: 821 except KeyError:
740 return 0 # no capabilities 822 return 0 # no capabilities
741 823
742 def getClientInterpreter(self): 824 def getClientInterpreter(self):
743 """ 825 """
744 Public method to get the interpreter of the debug client. 826 Public method to get the interpreter of the debug client.
745 827
746 @return interpreter of the debug client (string) 828 @return interpreter of the debug client
829 @rtype str
747 """ 830 """
748 return self.clientInterpreter 831 return self.clientInterpreter
749 832
750 def getClientType(self): 833 def getClientType(self):
751 """ 834 """
791 874
792 if self.passive: 875 if self.passive:
793 self.__createDebuggerInterface( 876 self.__createDebuggerInterface(
794 Preferences.getDebugger("PassiveDbgType")) 877 Preferences.getDebugger("PassiveDbgType"))
795 878
796 accepted = self.debuggerInterface.newConnection(sock) 879 self.debuggerInterface.newConnection(sock)
797 if accepted: 880
798 # Perform actions necessary, if client type has changed 881 def masterClientConnected(self):
799 if self.lastClientType != self.clientType: 882 """
800 self.lastClientType = self.clientType 883 Public method to perform actions after the master client has finally
801 self.remoteBanner() 884 established the connection.
802 elif self.__autoClearShell: 885 """
803 self.__autoClearShell = False 886 # Perform actions necessary, if client type has changed
804 self.remoteBanner() 887 if self.lastClientType != self.clientType:
805 elif self.passive: 888 self.lastClientType = self.clientType
806 self.remoteBanner() 889 self.remoteBanner()
807 890 elif self.__autoClearShell:
808 self.debuggerInterface.flush() 891 self.__autoClearShell = False
809 892 self.remoteBanner()
893 elif self.passive:
894 self.remoteBanner()
895
810 def shutdownServer(self): 896 def shutdownServer(self):
811 """ 897 """
812 Public method to cleanly shut down. 898 Public method to cleanly shut down.
813 899
814 It closes our socket and shuts down 900 It closes our socket and shuts down
815 the debug client. (Needed on Win OS) 901 the debug client. (Needed on Win OS)
816 """ 902 """
817 if self.debuggerInterface is not None: 903 if self.debuggerInterface is not None:
818 self.debuggerInterface.shutdown() 904 self.debuggerInterface.shutdown()
819 905
820 def remoteEnvironment(self, env): 906 def remoteEnvironment(self, env):
821 """ 907 """
822 Public method to set the environment for a program to debug, run, ... 908 Public method to set the environment for a program to debug, run, ...
823 909
824 @param env environment settings (string) 910 @param env environment settings
911 @type str
825 """ 912 """
826 envlist = Utilities.parseEnvironmentString(env) 913 envlist = Utilities.parseEnvironmentString(env)
827 envdict = {} 914 envdict = {}
828 for el in envlist: 915 for el in envlist:
829 try: 916 try:
832 value = value[1:-1] 919 value = value[1:-1]
833 envdict[key] = value 920 envdict[key] = value
834 except ValueError: 921 except ValueError:
835 pass 922 pass
836 self.debuggerInterface.remoteEnvironment(envdict) 923 self.debuggerInterface.remoteEnvironment(envdict)
837 924
838 def remoteLoad(self, venvName, fn, argv, wd, env, autoClearShell=True, 925 def remoteLoad(self, venvName, fn, argv, wd, env, autoClearShell=True,
839 tracePython=False, autoContinue=True, forProject=False, 926 tracePython=False, autoContinue=True, forProject=False,
840 runInConsole=False, autoFork=False, forkChild=False, 927 runInConsole=False, clientType="", enableCallTrace=False,
841 clientType="", enableCallTrace=False): 928 enableMultiprocess=False, multiprocessNoDebug=""):
842 """ 929 """
843 Public method to load a new program to debug. 930 Public method to load a new program to debug.
844 931
845 @param venvName name of the virtual environment to be used 932 @param venvName name of the virtual environment to be used
846 @type str 933 @type str
850 @type str 937 @type str
851 @param wd the working directory for the program 938 @param wd the working directory for the program
852 @type str 939 @type str
853 @param env environment parameter settings 940 @param env environment parameter settings
854 @type str 941 @type str
855 @keyparam autoClearShell flag indicating, that the interpreter window 942 @param autoClearShell flag indicating, that the interpreter window
856 should be cleared 943 should be cleared
857 @type bool 944 @type bool
858 @keyparam tracePython flag indicating if the Python library should be 945 @param tracePython flag indicating if the Python library should be
859 traced as well 946 traced as well
860 @type bool 947 @type bool
861 @keyparam autoContinue flag indicating, that the debugger should not 948 @param autoContinue flag indicating, that the debugger should not
862 stop at the first executable line 949 stop at the first executable line
863 @type bool 950 @type bool
864 @keyparam forProject flag indicating a project related action 951 @param forProject flag indicating a project related action
865 @type bool 952 @type bool
866 @keyparam runInConsole flag indicating to start the debugger in a 953 @param runInConsole flag indicating to start the debugger in a
867 console window 954 console window
868 @type bool 955 @type bool
869 @keyparam autoFork flag indicating the automatic fork mode 956 @param clientType client type to be used
870 @type bool 957 @type str
871 @keyparam forkChild flag indicating to debug the child after forking 958 @param enableCallTrace flag indicating to enable the call trace
872 @type bool
873 @keyparam clientType client type to be used
874 @type str
875 @keyparam enableCallTrace flag indicating to enable the call trace
876 function 959 function
877 @type bool 960 @type bool
961 @param enableMultiprocess flag indicating to perform multiprocess
962 debugging
963 @type bool
964 @param multiprocessNoDebug space separated list of programs not to be
965 debugged
966 @type str
878 """ 967 """
879 self.__autoClearShell = autoClearShell 968 self.__autoClearShell = autoClearShell
880 self.__autoContinue = autoContinue 969 self.__multiprocessNoDebugList = [
970 s.strip() for s in multiprocessNoDebug.split(os.pathsep)
971 ]
881 972
882 if clientType not in self.getSupportedLanguages(): 973 if clientType not in self.getSupportedLanguages():
883 # a not supported client language was requested 974 # a not supported client language was requested
884 E5MessageBox.critical( 975 E5MessageBox.critical(
885 None, 976 None,
900 except KeyError: 991 except KeyError:
901 self.__setClientType('Python3') # assume it is a Python3 file 992 self.__setClientType('Python3') # assume it is a Python3 file
902 self.startClient(False, forProject=forProject, 993 self.startClient(False, forProject=forProject,
903 runInConsole=runInConsole, venvName=venvName) 994 runInConsole=runInConsole, venvName=venvName)
904 995
905 self.setCallTraceEnabled(enableCallTrace) 996 self.setCallTraceEnabled("", enableCallTrace)
906 self.remoteEnvironment(env) 997 self.remoteEnvironment(env)
907 998
908 self.debuggerInterface.remoteLoad(fn, argv, wd, tracePython, 999 self.debuggerInterface.remoteLoad(
909 autoContinue, autoFork, forkChild) 1000 fn, argv, wd, tracePython, autoContinue,
1001 enableMultiprocess=enableMultiprocess
1002 )
910 self.debugging = True 1003 self.debugging = True
911 self.running = True 1004 self.running = True
912 self.__restoreBreakpoints() 1005 self.__restoreBreakpoints()
913 self.__restoreWatchpoints() 1006 self.__restoreWatchpoints()
914 1007 self.__restoreNoDebugList()
1008
915 def remoteRun(self, venvName, fn, argv, wd, env, autoClearShell=True, 1009 def remoteRun(self, venvName, fn, argv, wd, env, autoClearShell=True,
916 forProject=False, runInConsole=False, autoFork=False, 1010 forProject=False, runInConsole=False, clientType=""):
917 forkChild=False, clientType=""):
918 """ 1011 """
919 Public method to load a new program to run. 1012 Public method to load a new program to run.
920 1013
921 @param venvName name of the virtual environment to be used 1014 @param venvName name of the virtual environment to be used
922 @type str 1015 @type str
926 @type str 1019 @type str
927 @param wd the working directory for the program 1020 @param wd the working directory for the program
928 @type str 1021 @type str
929 @param env environment parameter settings 1022 @param env environment parameter settings
930 @type str 1023 @type str
931 @keyparam autoClearShell flag indicating, that the interpreter window 1024 @param autoClearShell flag indicating, that the interpreter window
932 should be cleared 1025 should be cleared
933 @type bool 1026 @type bool
934 @keyparam forProject flag indicating a project related action 1027 @param forProject flag indicating a project related action
935 @type bool 1028 @type bool
936 @keyparam runInConsole flag indicating to start the debugger in a 1029 @param runInConsole flag indicating to start the debugger in a
937 console window 1030 console window
938 @type bool 1031 @type bool
939 @keyparam autoFork flag indicating the automatic fork mode 1032 @param clientType client type to be used
940 @type bool
941 @keyparam forkChild flag indicating to debug the child after forking
942 @type bool
943 @keyparam clientType client type to be used
944 @type str 1033 @type str
945 """ 1034 """
946 self.__autoClearShell = autoClearShell 1035 self.__autoClearShell = autoClearShell
947 1036
948 if clientType not in self.getSupportedLanguages(): 1037 if clientType not in self.getSupportedLanguages():
968 self.startClient(False, forProject=forProject, 1057 self.startClient(False, forProject=forProject,
969 runInConsole=runInConsole, venvName=venvName) 1058 runInConsole=runInConsole, venvName=venvName)
970 1059
971 self.remoteEnvironment(env) 1060 self.remoteEnvironment(env)
972 1061
973 self.debuggerInterface.remoteRun(fn, argv, wd, autoFork, forkChild) 1062 self.debuggerInterface.remoteRun(fn, argv, wd)
974 self.debugging = False 1063 self.debugging = False
975 self.running = True 1064 self.running = True
976 1065
977 def remoteCoverage(self, venvName, fn, argv, wd, env, 1066 def remoteCoverage(self, venvName, fn, argv, wd, env,
978 autoClearShell=True, erase=False, forProject=False, 1067 autoClearShell=True, erase=False, forProject=False,
979 runInConsole=False, clientType=""): 1068 runInConsole=False, clientType=""):
980 """ 1069 """
981 Public method to load a new program to collect coverage data. 1070 Public method to load a new program to collect coverage data.
988 @type str 1077 @type str
989 @param wd the working directory for the program 1078 @param wd the working directory for the program
990 @type str 1079 @type str
991 @param env environment parameter settings 1080 @param env environment parameter settings
992 @type str 1081 @type str
993 @keyparam autoClearShell flag indicating, that the interpreter window 1082 @param autoClearShell flag indicating, that the interpreter window
994 should be cleared 1083 should be cleared
995 @type bool 1084 @type bool
996 @keyparam erase flag indicating that coverage info should be 1085 @param erase flag indicating that coverage info should be
997 cleared first 1086 cleared first
998 @type bool 1087 @type bool
999 @keyparam forProject flag indicating a project related action 1088 @param forProject flag indicating a project related action
1000 @type bool 1089 @type bool
1001 @keyparam runInConsole flag indicating to start the debugger in a 1090 @param runInConsole flag indicating to start the debugger in a
1002 console window 1091 console window
1003 @type bool 1092 @type bool
1004 @keyparam clientType client type to be used 1093 @param clientType client type to be used
1005 @type str 1094 @type str
1006 """ 1095 """
1007 self.__autoClearShell = autoClearShell 1096 self.__autoClearShell = autoClearShell
1008 1097
1009 if clientType not in self.getSupportedLanguages(): 1098 if clientType not in self.getSupportedLanguages():
1032 self.remoteEnvironment(env) 1121 self.remoteEnvironment(env)
1033 1122
1034 self.debuggerInterface.remoteCoverage(fn, argv, wd, erase) 1123 self.debuggerInterface.remoteCoverage(fn, argv, wd, erase)
1035 self.debugging = False 1124 self.debugging = False
1036 self.running = True 1125 self.running = True
1037 1126
1038 def remoteProfile(self, venvName, fn, argv, wd, env, 1127 def remoteProfile(self, venvName, fn, argv, wd, env,
1039 autoClearShell=True, erase=False, forProject=False, 1128 autoClearShell=True, erase=False, forProject=False,
1040 runInConsole=False, clientType=""): 1129 runInConsole=False, clientType=""):
1041 """ 1130 """
1042 Public method to load a new program to collect profiling data. 1131 Public method to load a new program to collect profiling data.
1049 @type str 1138 @type str
1050 @param wd the working directory for the program 1139 @param wd the working directory for the program
1051 @type str 1140 @type str
1052 @param env environment parameter settings 1141 @param env environment parameter settings
1053 @type str 1142 @type str
1054 @keyparam autoClearShell flag indicating, that the interpreter window 1143 @param autoClearShell flag indicating, that the interpreter window
1055 should be cleared 1144 should be cleared
1056 @type bool 1145 @type bool
1057 @keyparam erase flag indicating that coverage info should be 1146 @param erase flag indicating that coverage info should be
1058 cleared first 1147 cleared first
1059 @type bool 1148 @type bool
1060 @keyparam forProject flag indicating a project related action 1149 @param forProject flag indicating a project related action
1061 @type bool 1150 @type bool
1062 @keyparam runInConsole flag indicating to start the debugger in a 1151 @param runInConsole flag indicating to start the debugger in a
1063 console window 1152 console window
1064 @type bool 1153 @type bool
1065 @keyparam clientType client type to be used 1154 @param clientType client type to be used
1066 @type str 1155 @type str
1067 """ 1156 """
1068 self.__autoClearShell = autoClearShell 1157 self.__autoClearShell = autoClearShell
1069 1158
1070 if clientType not in self.getSupportedLanguages(): 1159 if clientType not in self.getSupportedLanguages():
1093 self.remoteEnvironment(env) 1182 self.remoteEnvironment(env)
1094 1183
1095 self.debuggerInterface.remoteProfile(fn, argv, wd, erase) 1184 self.debuggerInterface.remoteProfile(fn, argv, wd, erase)
1096 self.debugging = False 1185 self.debugging = False
1097 self.running = True 1186 self.running = True
1098 1187
1099 def remoteStatement(self, stmt): 1188 def remoteStatement(self, debuggerId, stmt):
1100 """ 1189 """
1101 Public method to execute a Python statement. 1190 Public method to execute a Python statement.
1102 1191
1103 @param stmt the Python statement to execute (string). It 1192 @param debuggerId ID of the debugger backend
1104 should not have a trailing newline. 1193 @type str
1105 """ 1194 @param stmt the Python statement to execute.
1106 self.debuggerInterface.remoteStatement(stmt) 1195 @type str
1107 1196 """
1108 def remoteStep(self): 1197 self.debuggerInterface.remoteStatement(debuggerId, stmt.rstrip())
1198
1199 def remoteStep(self, debuggerId):
1109 """ 1200 """
1110 Public method to single step the debugged program. 1201 Public method to single step the debugged program.
1111 """ 1202
1112 self.debuggerInterface.remoteStep() 1203 @param debuggerId ID of the debugger backend
1113 1204 @type str
1114 def remoteStepOver(self): 1205 """
1206 self.debuggerInterface.remoteStep(debuggerId)
1207
1208 def remoteStepOver(self, debuggerId):
1115 """ 1209 """
1116 Public method to step over the debugged program. 1210 Public method to step over the debugged program.
1117 """ 1211
1118 self.debuggerInterface.remoteStepOver() 1212 @param debuggerId ID of the debugger backend
1119 1213 @type str
1120 def remoteStepOut(self): 1214 """
1215 self.debuggerInterface.remoteStepOver(debuggerId)
1216
1217 def remoteStepOut(self, debuggerId):
1121 """ 1218 """
1122 Public method to step out the debugged program. 1219 Public method to step out the debugged program.
1123 """ 1220
1124 self.debuggerInterface.remoteStepOut() 1221 @param debuggerId ID of the debugger backend
1125 1222 @type str
1126 def remoteStepQuit(self): 1223 """
1224 self.debuggerInterface.remoteStepOut(debuggerId)
1225
1226 def remoteStepQuit(self, debuggerId):
1127 """ 1227 """
1128 Public method to stop the debugged program. 1228 Public method to stop the debugged program.
1129 """ 1229
1130 self.debuggerInterface.remoteStepQuit() 1230 @param debuggerId ID of the debugger backend
1131 1231 @type str
1132 def remoteContinue(self, special=False): 1232 """
1233 self.debuggerInterface.remoteStepQuit(debuggerId)
1234
1235 def remoteContinue(self, debuggerId, special=False):
1133 """ 1236 """
1134 Public method to continue the debugged program. 1237 Public method to continue the debugged program.
1135 1238
1239 @param debuggerId ID of the debugger backend
1240 @type str
1136 @param special flag indicating a special continue operation 1241 @param special flag indicating a special continue operation
1137 """ 1242 """
1138 self.debuggerInterface.remoteContinue(special) 1243 self.debuggerInterface.remoteContinue(debuggerId, special)
1139 1244
1140 def remoteMoveIP(self, line): 1245 def remoteContinueUntil(self, debuggerId, line):
1246 """
1247 Public method to continue the debugged program to the given line
1248 or until returning from the current frame.
1249
1250 @param debuggerId ID of the debugger backend
1251 @type str
1252 @param line the new line, where execution should be continued to
1253 @type int
1254 """
1255 self.debuggerInterface.remoteContinueUntil(debuggerId, line)
1256
1257 def remoteMoveIP(self, debuggerId, line):
1141 """ 1258 """
1142 Public method to move the instruction pointer to a different line. 1259 Public method to move the instruction pointer to a different line.
1143 1260
1261 @param debuggerId ID of the debugger backend
1262 @type str
1144 @param line the new line, where execution should be continued 1263 @param line the new line, where execution should be continued
1145 """ 1264 @type int
1146 self.debuggerInterface.remoteMoveIP(line) 1265 """
1147 1266 self.debuggerInterface.remoteMoveIP(debuggerId, line)
1148 def remoteBreakpoint(self, fn, line, setBreakpoint, cond=None, temp=False): 1267
1268 def remoteBreakpoint(self, debuggerId, fn, line, setBreakpoint, cond=None,
1269 temp=False):
1149 """ 1270 """
1150 Public method to set or clear a breakpoint. 1271 Public method to set or clear a breakpoint.
1151 1272
1152 @param fn filename the breakpoint belongs to (string) 1273 @param debuggerId ID of the debugger backend
1153 @param line linenumber of the breakpoint (int) 1274 @type str
1275 @param fn filename the breakpoint belongs to
1276 @type str
1277 @param line linenumber of the breakpoint
1278 @type int
1154 @param setBreakpoint flag indicating setting or resetting a breakpoint 1279 @param setBreakpoint flag indicating setting or resetting a breakpoint
1155 (boolean) 1280 @type bool
1156 @param cond condition of the breakpoint (string) 1281 @param cond condition of the breakpoint
1157 @param temp flag indicating a temporary breakpoint (boolean) 1282 @type str
1158 """ 1283 @param temp flag indicating a temporary breakpoint
1159 self.debuggerInterface.remoteBreakpoint(fn, line, setBreakpoint, cond, 1284 @type bool
1285 """
1286 self.debuggerInterface.remoteBreakpoint(
1287 debuggerId, fn, line, setBreakpoint, cond, temp)
1288
1289 def __remoteBreakpointEnable(self, debuggerId, fn, line, enable):
1290 """
1291 Private method to enable or disable a breakpoint.
1292
1293 @param debuggerId ID of the debugger backend
1294 @type str
1295 @param fn filename the breakpoint belongs to
1296 @type str
1297 @param line linenumber of the breakpoint
1298 @type int
1299 @param enable flag indicating enabling or disabling a breakpoint
1300 @type bool
1301 """
1302 self.debuggerInterface.remoteBreakpointEnable(
1303 debuggerId, fn, line, enable)
1304
1305 def __remoteBreakpointIgnore(self, debuggerId, fn, line, count):
1306 """
1307 Private method to ignore a breakpoint the next couple of occurrences.
1308
1309 @param debuggerId ID of the debugger backend
1310 @type str
1311 @param fn filename the breakpoint belongs to
1312 @type str
1313 @param line linenumber of the breakpoint
1314 @type int
1315 @param count number of occurrences to ignore
1316 @type int
1317 """
1318 self.debuggerInterface.remoteBreakpointIgnore(
1319 debuggerId, fn, line, count)
1320
1321 def __remoteWatchpoint(self, debuggerId, cond, setWatch, temp=False):
1322 """
1323 Private method to set or clear a watch expression.
1324
1325 @param debuggerId ID of the debugger backend
1326 @type str
1327 @param cond expression of the watch expression
1328 @type str
1329 @param setWatch flag indicating setting or resetting a watch expression
1330 @type bool
1331 @param temp flag indicating a temporary watch expression
1332 @type bool
1333 """
1334 # cond is combination of cond and special (s. watch expression viewer)
1335 self.debuggerInterface.remoteWatchpoint(debuggerId, cond, setWatch,
1160 temp) 1336 temp)
1161 1337
1162 def __remoteBreakpointEnable(self, fn, line, enable): 1338 def __remoteWatchpointEnable(self, debuggerId, cond, enable):
1163 """ 1339 """
1164 Private method to enable or disable a breakpoint. 1340 Private method to enable or disable a watch expression.
1165 1341
1166 @param fn filename the breakpoint belongs to (string) 1342 @param debuggerId ID of the debugger backend
1167 @param line linenumber of the breakpoint (int) 1343 @type str
1168 @param enable flag indicating enabling or disabling a breakpoint 1344 @param cond expression of the watch expression
1169 (boolean) 1345 @type str
1170 """ 1346 @param enable flag indicating enabling or disabling a watch expression
1171 self.debuggerInterface.remoteBreakpointEnable(fn, line, enable) 1347 @type bool
1172
1173 def __remoteBreakpointIgnore(self, fn, line, count):
1174 """
1175 Private method to ignore a breakpoint the next couple of occurrences.
1176
1177 @param fn filename the breakpoint belongs to (string)
1178 @param line linenumber of the breakpoint (int)
1179 @param count number of occurrences to ignore (int)
1180 """
1181 self.debuggerInterface.remoteBreakpointIgnore(fn, line, count)
1182
1183 def __remoteWatchpoint(self, cond, setWatch, temp=False):
1184 """
1185 Private method to set or clear a watch expression.
1186
1187 @param cond expression of the watch expression (string)
1188 @param setWatch flag indicating setting or resetting a watch expression
1189 (boolean)
1190 @param temp flag indicating a temporary watch expression (boolean)
1191 """ 1348 """
1192 # cond is combination of cond and special (s. watch expression viewer) 1349 # cond is combination of cond and special (s. watch expression viewer)
1193 self.debuggerInterface.remoteWatchpoint(cond, setWatch, temp) 1350 self.debuggerInterface.remoteWatchpointEnable(debuggerId, cond, enable)
1194 1351
1195 def __remoteWatchpointEnable(self, cond, enable): 1352 def __remoteWatchpointIgnore(self, debuggerId, cond, count):
1196 """
1197 Private method to enable or disable a watch expression.
1198
1199 @param cond expression of the watch expression (string)
1200 @param enable flag indicating enabling or disabling a watch expression
1201 (boolean)
1202 """
1203 # cond is combination of cond and special (s. watch expression viewer)
1204 self.debuggerInterface.remoteWatchpointEnable(cond, enable)
1205
1206 def __remoteWatchpointIgnore(self, cond, count):
1207 """ 1353 """
1208 Private method to ignore a watch expression the next couple of 1354 Private method to ignore a watch expression the next couple of
1209 occurrences. 1355 occurrences.
1210 1356
1211 @param cond expression of the watch expression (string) 1357 @param debuggerId ID of the debugger backend
1212 @param count number of occurrences to ignore (int) 1358 @type str
1359 @param cond expression of the watch expression
1360 @type str
1361 @param count number of occurrences to ignore
1362 @type int
1213 """ 1363 """
1214 # cond is combination of cond and special (s. watch expression viewer) 1364 # cond is combination of cond and special (s. watch expression viewer)
1215 self.debuggerInterface.remoteWatchpointIgnore(cond, count) 1365 self.debuggerInterface.remoteWatchpointIgnore(debuggerId, cond, count)
1216 1366
1217 def remoteRawInput(self, s): 1367 def remoteRawInput(self, debuggerId, inputString):
1218 """ 1368 """
1219 Public method to send the raw input to the debugged program. 1369 Public method to send the raw input to the debugged program.
1220 1370
1221 @param s the raw input (string) 1371 @param debuggerId ID of the debugger backend
1222 """ 1372 @type str
1223 self.debuggerInterface.remoteRawInput(s) 1373 @param inputString the raw input
1224 self.clientRawInputSent.emit() 1374 @type str
1225 1375 """
1226 def remoteThreadList(self): 1376 self.debuggerInterface.remoteRawInput(debuggerId, inputString)
1377 self.clientRawInputSent.emit(debuggerId)
1378
1379 def remoteThreadList(self, debuggerId):
1227 """ 1380 """
1228 Public method to request the list of threads from the client. 1381 Public method to request the list of threads from the client.
1229 """ 1382
1230 self.debuggerInterface.remoteThreadList() 1383 @param debuggerId ID of the debugger backend
1231 1384 @type str
1232 def remoteSetThread(self, tid): 1385 """
1386 self.debuggerInterface.remoteThreadList(debuggerId)
1387
1388 def remoteSetThread(self, debuggerId, tid):
1233 """ 1389 """
1234 Public method to request to set the given thread as current thread. 1390 Public method to request to set the given thread as current thread.
1235 1391
1236 @param tid id of the thread (integer) 1392 @param debuggerId ID of the debugger backend
1237 """ 1393 @type str
1238 self.debuggerInterface.remoteSetThread(tid) 1394 @param tid id of the thread
1239 1395 @type int
1240 def remoteClientVariables(self, scope, filterList, framenr=0): 1396 """
1397 self.debuggerInterface.remoteSetThread(debuggerId, tid)
1398
1399 def remoteClientStack(self, debuggerId):
1400 """
1401 Public method to request the stack of the main thread.
1402
1403 @param debuggerId ID of the debugger backend
1404 @type str
1405 """
1406 self.debuggerInterface.remoteClientStack(debuggerId)
1407
1408 def remoteClientVariables(self, debuggerId, scope, filterList, framenr=0):
1241 """ 1409 """
1242 Public method to request the variables of the debugged program. 1410 Public method to request the variables of the debugged program.
1243 1411
1412 @param debuggerId ID of the debugger backend
1413 @type str
1244 @param scope the scope of the variables (0 = local, 1 = global) 1414 @param scope the scope of the variables (0 = local, 1 = global)
1245 @param filterList list of variable types to filter out (list of int) 1415 @type int
1246 @param framenr framenumber of the variables to retrieve (int) 1416 @param filterList list of variable types to filter out
1417 @type list of str
1418 @param framenr framenumber of the variables to retrieve
1419 @type int
1247 """ 1420 """
1248 self.debuggerInterface.remoteClientVariables( 1421 self.debuggerInterface.remoteClientVariables(
1249 scope, filterList, framenr, self.__maxVariableSize) 1422 debuggerId, scope, filterList, framenr, self.__maxVariableSize)
1250 1423
1251 def remoteClientVariable(self, scope, filterList, var, framenr=0): 1424 def remoteClientVariable(self, debuggerId, scope, filterList, var,
1425 framenr=0, maxSize=0):
1252 """ 1426 """
1253 Public method to request the variables of the debugged program. 1427 Public method to request the variables of the debugged program.
1254 1428
1429 @param debuggerId ID of the debugger backend
1430 @type str
1255 @param scope the scope of the variables (0 = local, 1 = global) 1431 @param scope the scope of the variables (0 = local, 1 = global)
1256 @param filterList list of variable types to filter out (list of int) 1432 @type int
1257 @param var list encoded name of variable to retrieve (string) 1433 @param filterList list of variable types to filter out
1258 @param framenr framenumber of the variables to retrieve (int) 1434 @type list of str
1435 @param var list encoded name of variable to retrieve
1436 @type list of str
1437 @param framenr framenumber of the variables to retrieve
1438 @type int
1439 @param maxSize maximum size the formatted value of a variable will
1440 be shown. If it is bigger than that, a 'too big' indication will
1441 be given (@@TOO_BIG_TO_SHOW@@).
1442 @type int
1259 """ 1443 """
1260 self.debuggerInterface.remoteClientVariable( 1444 self.debuggerInterface.remoteClientVariable(
1261 scope, filterList, var, framenr, self.__maxVariableSize) 1445 debuggerId, scope, filterList, var, framenr,
1262 1446 self.__maxVariableSize)
1263 def remoteClientDisassembly(self): 1447
1448 def remoteClientDisassembly(self, debuggerId):
1264 """ 1449 """
1265 Public method to ask the client for the latest traceback disassembly. 1450 Public method to ask the client for the latest traceback disassembly.
1451
1452 @param debuggerId ID of the debugger backend
1453 @type str
1266 """ 1454 """
1267 try: 1455 try:
1268 self.debuggerInterface.remoteClientDisassembly() 1456 self.debuggerInterface.remoteClientDisassembly(debuggerId)
1269 except AttributeError: 1457 except AttributeError:
1270 # remote client doesn't support that 1458 # remote client doesn't support that
1271 pass 1459 pass
1272 1460
1273 def remoteClientSetFilter(self, scope, filterStr): 1461 def remoteClientSetFilter(self, debuggerId, scope, filterStr):
1274 """ 1462 """
1275 Public method to set a variables filter list. 1463 Public method to set a variables filter list.
1276 1464
1465 @param debuggerId ID of the debugger backend
1466 @type str
1277 @param scope the scope of the variables (0 = local, 1 = global) 1467 @param scope the scope of the variables (0 = local, 1 = global)
1468 @type int
1278 @param filterStr regexp string for variable names to filter out 1469 @param filterStr regexp string for variable names to filter out
1279 (string) 1470 @type str
1280 """ 1471 """
1281 self.debuggerInterface.remoteClientSetFilter(scope, filterStr) 1472 self.debuggerInterface.remoteClientSetFilter(
1282 1473 debuggerId, scope, filterStr)
1283 def setCallTraceEnabled(self, on): 1474
1475 def setCallTraceEnabled(self, debuggerId, on):
1284 """ 1476 """
1285 Public method to set the call trace state. 1477 Public method to set the call trace state.
1286 1478
1287 @param on flag indicating to enable the call trace function (boolean) 1479 @param debuggerId ID of the debugger backend
1288 """ 1480 @type str
1289 self.debuggerInterface.setCallTraceEnabled(on) 1481 @param on flag indicating to enable the call trace function
1290 1482 @type bool
1483 """
1484 self.debuggerInterface.setCallTraceEnabled(debuggerId, on)
1485
1291 def remoteBanner(self): 1486 def remoteBanner(self):
1292 """ 1487 """
1293 Public slot to get the banner info of the remote client. 1488 Public slot to get the banner info of the remote client.
1294 """ 1489 """
1295 self.debuggerInterface.remoteBanner() 1490 self.debuggerInterface.remoteBanner()
1296 1491
1297 def remoteCapabilities(self): 1492 def remoteCapabilities(self):
1298 """ 1493 """
1299 Public slot to get the debug clients capabilities. 1494 Public slot to get the debug clients capabilities.
1300 """ 1495 """
1301 self.debuggerInterface.remoteCapabilities() 1496 self.debuggerInterface.remoteCapabilities()
1302 1497
1303 def remoteCompletion(self, text): 1498 def remoteCompletion(self, debuggerId, text):
1304 """ 1499 """
1305 Public slot to get the a list of possible commandline completions 1500 Public slot to get the a list of possible commandline completions
1306 from the remote client. 1501 from the remote client.
1307 1502
1308 @param text the text to be completed (string) 1503 @param debuggerId ID of the debugger backend
1309 """ 1504 @type str
1310 self.debuggerInterface.remoteCompletion(text) 1505 @param text the text to be completed
1506 @type str
1507 """
1508 self.debuggerInterface.remoteCompletion(debuggerId, text)
1311 1509
1312 def remoteUTDiscover(self, clientType, forProject, venvName, syspath, 1510 def remoteUTDiscover(self, clientType, forProject, venvName, syspath,
1313 workdir, discoveryStart): 1511 workdir, discoveryStart):
1314 """ 1512 """
1315 Public method to perform a test case discovery. 1513 Public method to perform a test case discovery.
1420 self.running = True 1618 self.running = True
1421 self.debugging = debug 1619 self.debugging = debug
1422 if debug: 1620 if debug:
1423 self.__restoreBreakpoints() 1621 self.__restoreBreakpoints()
1424 self.__restoreWatchpoints() 1622 self.__restoreWatchpoints()
1425 1623
1426 def remoteUTRun(self, debug=False, failfast=False): 1624 def remoteUTRun(self, debug=False, failfast=False):
1427 """ 1625 """
1428 Public method to start a unittest run. 1626 Public method to start a unittest run.
1429 1627
1430 @param debug flag indicating to run unittest with debugging 1628 @param debug flag indicating to run unittest with debugging
1431 @type bool 1629 @type bool
1432 @param failfast flag indicating to stop at the first error 1630 @param failfast flag indicating to stop at the first error
1433 @type bool 1631 @type bool
1434 """ 1632 """
1435 self.debuggerInterface.remoteUTRun(debug, failfast) 1633 self.debuggerInterface.remoteUTRun(debug, failfast)
1436 1634
1437 def remoteUTStop(self): 1635 def remoteUTStop(self):
1438 """ 1636 """
1439 public method to stop a unittest run. 1637 public method to stop a unittest run.
1440 """ 1638 """
1441 self.debuggerInterface.remoteUTStop() 1639 self.debuggerInterface.remoteUTStop()
1442 1640
1443 def signalClientOutput(self, line): 1641 def signalClientOutput(self, line, debuggerId):
1444 """ 1642 """
1445 Public method to process a line of client output. 1643 Public method to process a line of client output.
1446 1644
1447 @param line client output (string) 1645 @param line client output
1448 """ 1646 @type str
1449 self.clientOutput.emit(line) 1647 @param debuggerId ID of the debugger backend
1450 1648 @type str
1451 def signalClientLine(self, filename, lineno, forStack=False): 1649 """
1650 if debuggerId:
1651 self.clientOutput.emit("{0}: {1}".format(debuggerId, line))
1652 else:
1653 self.clientOutput.emit(line)
1654
1655 def signalClientLine(self, filename, lineno, debuggerId, forStack=False,
1656 threadName=""):
1452 """ 1657 """
1453 Public method to process client position feedback. 1658 Public method to process client position feedback.
1454 1659
1455 @param filename name of the file currently being executed (string) 1660 @param filename name of the file currently being executed
1456 @param lineno line of code currently being executed (integer) 1661 @type str
1457 @param forStack flag indicating this is for a stack dump (boolean) 1662 @param lineno line of code currently being executed
1458 """ 1663 @type int
1459 self.clientLine.emit(filename, lineno, forStack) 1664 @param debuggerId ID of the debugger backend
1460 1665 @type str
1461 def signalClientStack(self, stack): 1666 @param forStack flag indicating this is for a stack dump
1667 @type bool
1668 @param threadName name of the thread signaling the event
1669 @type str
1670 """
1671 self.clientLine.emit(filename, lineno, debuggerId, threadName,
1672 forStack)
1673
1674 def signalClientStack(self, stack, debuggerId, threadName=""):
1462 """ 1675 """
1463 Public method to process a client's stack information. 1676 Public method to process a client's stack information.
1464 1677
1465 @param stack list of stack entries. Each entry is a tuple of three 1678 @param stack list of stack entries. Each entry is a tuple of three
1466 values giving the filename, linenumber and method 1679 values giving the filename, linenumber and method
1467 (list of lists of (string, integer, string)) 1680 @type list of lists of (string, integer, string)
1468 """ 1681 @param debuggerId ID of the debugger backend
1469 self.clientStack.emit(stack) 1682 @type str
1470 1683 @param threadName name of the thread signaling the event
1471 def signalClientThreadList(self, currentId, threadList): 1684 @type str
1685 """
1686 self.clientStack.emit(stack, debuggerId, threadName)
1687
1688 def signalClientThreadList(self, currentId, threadList, debuggerId):
1472 """ 1689 """
1473 Public method to process the client thread list info. 1690 Public method to process the client thread list info.
1474 1691
1475 @param currentId id of the current thread (integer) 1692 @param currentId id of the current thread
1693 @type int
1476 @param threadList list of dictionaries containing the thread data 1694 @param threadList list of dictionaries containing the thread data
1477 """ 1695 @type list of dict
1478 self.clientThreadList.emit(currentId, threadList) 1696 @param debuggerId ID of the debugger backend
1479 1697 @type str
1480 def signalClientThreadSet(self): 1698 """
1699 self.clientThreadList.emit(currentId, threadList, debuggerId)
1700
1701 def signalClientThreadSet(self, debuggerId):
1481 """ 1702 """
1482 Public method to handle the change of the client thread. 1703 Public method to handle the change of the client thread.
1483 """ 1704
1484 self.clientThreadSet.emit() 1705 @param debuggerId ID of the debugger backend
1485 1706 @type str
1486 def signalClientVariables(self, scope, variables): 1707 """
1708 self.clientThreadSet.emit(debuggerId)
1709
1710 def signalClientVariables(self, scope, variables, debuggerId):
1487 """ 1711 """
1488 Public method to process the client variables info. 1712 Public method to process the client variables info.
1489 1713
1490 @param scope scope of the variables (-1 = empty global, 1 = global, 1714 @param scope scope of the variables (-1 = empty global, 1 = global,
1491 0 = local) 1715 0 = local)
1716 @type int
1492 @param variables the list of variables from the client 1717 @param variables the list of variables from the client
1493 """ 1718 @type list
1494 self.clientVariables.emit(scope, variables) 1719 @param debuggerId ID of the debugger backend
1495 1720 @type str
1496 def signalClientVariable(self, scope, variables): 1721 """
1722 self.clientVariables.emit(scope, variables, debuggerId)
1723
1724 def signalClientVariable(self, scope, variables, debuggerId):
1497 """ 1725 """
1498 Public method to process the client variable info. 1726 Public method to process the client variable info.
1499 1727
1500 @param scope scope of the variables (-1 = empty global, 1 = global, 1728 @param scope scope of the variables (-1 = empty global, 1 = global,
1501 0 = local) 1729 0 = local)
1730 @type int
1502 @param variables the list of members of a classvariable from the client 1731 @param variables the list of members of a classvariable from the client
1503 """ 1732 @type list
1504 self.clientVariable.emit(scope, variables) 1733 @param debuggerId ID of the debugger backend
1505 1734 @type str
1506 def signalClientStatement(self, more): 1735 """
1736 self.clientVariable.emit(scope, variables, debuggerId)
1737
1738 def signalClientStatement(self, more, debuggerId):
1507 """ 1739 """
1508 Public method to process the input response from the client. 1740 Public method to process the input response from the client.
1509 1741
1510 @param more flag indicating that more user input is required 1742 @param more flag indicating that more user input is required
1511 """ 1743 @type bool
1512 self.clientStatement.emit(more) 1744 @param debuggerId ID of the debugger backend
1513 1745 @type str
1514 def signalClientDisassembly(self, disassembly): 1746 """
1747 self.clientStatement.emit(more, debuggerId)
1748
1749 def signalClientDisassembly(self, disassembly, debuggerId):
1515 """ 1750 """
1516 Public method to process the disassembly info from the client. 1751 Public method to process the disassembly info from the client.
1517 1752
1518 @param disassembly dictionary containing the disassembly information 1753 @param disassembly dictionary containing the disassembly information
1519 @type dict 1754 @type dict
1755 @param debuggerId ID of the debugger backend
1756 @type str
1520 """ 1757 """
1521 if self.running: 1758 if self.running:
1522 self.clientDisassembly.emit(disassembly) 1759 self.clientDisassembly.emit(disassembly, debuggerId)
1523 1760
1524 def signalClientException(self, exceptionType, exceptionMessage, 1761 def signalClientException(self, exceptionType, exceptionMessage,
1525 stackTrace): 1762 stackTrace, debuggerId, threadName=""):
1526 """ 1763 """
1527 Public method to process the exception info from the client. 1764 Public method to process the exception info from the client.
1528 1765
1529 @param exceptionType type of exception raised (string) 1766 @param exceptionType type of exception raised
1530 @param exceptionMessage message given by the exception (string) 1767 @type str
1768 @param exceptionMessage message given by the exception
1769 @type str
1531 @param stackTrace list of stack entries with the exception position 1770 @param stackTrace list of stack entries with the exception position
1532 first. Each stack entry is a list giving the filename and the 1771 first. Each stack entry is a list giving the filename and the
1533 linenumber. 1772 linenumber.
1773 @type list
1774 @param debuggerId ID of the debugger backend
1775 @type str
1776 @param threadName name of the thread signaling the event
1777 @type str
1534 """ 1778 """
1535 if self.running: 1779 if self.running:
1536 self.clientException.emit(exceptionType, exceptionMessage, 1780 self.clientException.emit(exceptionType, exceptionMessage,
1537 stackTrace) 1781 stackTrace, debuggerId, threadName)
1538 1782
1539 def signalClientSyntaxError(self, message, filename, lineNo, characterNo): 1783 def signalClientSyntaxError(self, message, filename, lineNo, characterNo,
1540 """ 1784 debuggerId, threadName=""):
1541 Public method to process the syntax error info from the client. 1785 """
1542 1786 Public method to process a syntax error info from the client.
1543 @param message message of the syntax error (string) 1787
1788 @param message message of the syntax error
1789 @type str
1544 @param filename translated filename of the syntax error position 1790 @param filename translated filename of the syntax error position
1545 (string) 1791 @type str
1546 @param lineNo line number of the syntax error position (integer) 1792 @param lineNo line number of the syntax error position
1793 @type int
1547 @param characterNo character number of the syntax error position 1794 @param characterNo character number of the syntax error position
1548 (integer) 1795 @type int
1796 @param debuggerId ID of the debugger backend
1797 @type str
1798 @param threadName name of the thread signaling the event
1799 @type str
1549 """ 1800 """
1550 if self.running: 1801 if self.running:
1551 self.clientSyntaxError.emit(message, filename, lineNo, characterNo) 1802 self.clientSyntaxError.emit(message, filename, lineNo, characterNo,
1552 1803 debuggerId, threadName)
1804
1553 def signalClientSignal(self, message, filename, lineNo, 1805 def signalClientSignal(self, message, filename, lineNo,
1554 funcName, funcArgs): 1806 funcName, funcArgs, debuggerId):
1555 """ 1807 """
1556 Public method to process a signal generated on the client side. 1808 Public method to process a signal generated on the client side.
1557 1809
1558 @param message message of the syntax error 1810 @param message message of the syntax error
1559 @type str 1811 @type str
1562 @param lineNo line number of the syntax error position 1814 @param lineNo line number of the syntax error position
1563 @type int 1815 @type int
1564 @param funcName name of the function causing the signal 1816 @param funcName name of the function causing the signal
1565 @type str 1817 @type str
1566 @param funcArgs function arguments 1818 @param funcArgs function arguments
1819 @type str
1820 @param debuggerId ID of the debugger backend
1567 @type str 1821 @type str
1568 """ 1822 """
1569 if self.running: 1823 if self.running:
1570 self.clientSignal.emit(message, filename, lineNo, 1824 self.clientSignal.emit(message, filename, lineNo,
1571 funcName, funcArgs) 1825 funcName, funcArgs, debuggerId)
1572 1826
1573 def signalClientExit(self, status, message=""): 1827 def signalClientDisconnected(self, debuggerId):
1828 """
1829 Public method to send a signal when a debug client has closed its
1830 connection.
1831
1832 @param debuggerId ID of the debugger backend
1833 @type str
1834 """
1835 self.clientDisconnected.emit(debuggerId)
1836
1837 def signalClientExit(self, program, status, message, debuggerId):
1574 """ 1838 """
1575 Public method to process the client exit status. 1839 Public method to process the client exit status.
1576 1840
1841 @param program name of the exited program
1842 @type str
1577 @param status exit code 1843 @param status exit code
1578 @type int 1844 @type int
1579 @param message message sent with the exit 1845 @param message message sent with the exit
1580 @type str 1846 @type str
1847 @param debuggerId ID of the debugger backend
1848 @type str
1849 """
1850 self.clientExit.emit(program, int(status), message, False, debuggerId)
1851
1852 def signalLastClientExited(self):
1853 """
1854 Public method to process the last client exit event.
1581 """ 1855 """
1582 if self.passive: 1856 if self.passive:
1583 self.__passiveShutDown() 1857 self.__passiveShutDown()
1584 self.clientExit.emit(int(status), message, False) 1858 self.lastClientExited.emit()
1585 if Preferences.getDebugger("AutomaticReset") or (self.running and 1859 if Preferences.getDebugger("AutomaticReset") or (self.running and
1586 not self.debugging): 1860 not self.debugging):
1587 self.debugging = False 1861 self.debugging = False
1588 self.startClient(False, forProject=self.__forProject) 1862 self.startClient(False, forProject=self.__forProject)
1589 if self.passive: 1863 if self.passive:
1590 self.__createDebuggerInterface("None") 1864 self.__createDebuggerInterface("None")
1591 self.signalClientOutput(self.tr('\nNot connected\n')) 1865 self.signalClientOutput(self.tr('\nNot connected\n'))
1592 self.signalClientStatement(False) 1866 self.signalClientStatement(False, "")
1593 self.running = False 1867 self.running = False
1594 1868
1595 def signalClientClearBreak(self, filename, lineno): 1869 def signalClientClearBreak(self, filename, lineno, debuggerId):
1596 """ 1870 """
1597 Public method to process the client clear breakpoint command. 1871 Public method to process the client clear breakpoint command.
1598 1872
1599 @param filename filename of the breakpoint (string) 1873 @param filename filename of the breakpoint
1600 @param lineno line umber of the breakpoint (integer) 1874 @type str
1601 """ 1875 @param lineno line umber of the breakpoint
1602 self.clientClearBreak.emit(filename, lineno) 1876 @type int
1603 1877 @param debuggerId ID of the debugger backend
1604 def signalClientBreakConditionError(self, filename, lineno): 1878 @type str
1879 """
1880 self.clientClearBreak.emit(filename, lineno, debuggerId)
1881
1882 def signalClientBreakConditionError(self, filename, lineno, debuggerId):
1605 """ 1883 """
1606 Public method to process the client breakpoint condition error info. 1884 Public method to process the client breakpoint condition error info.
1607 1885
1608 @param filename filename of the breakpoint (string) 1886 @param filename filename of the breakpoint
1609 @param lineno line umber of the breakpoint (integer) 1887 @type str
1610 """ 1888 @param lineno line umber of the breakpoint
1611 self.clientBreakConditionError.emit(filename, lineno) 1889 @type int
1612 1890 @param debuggerId ID of the debugger backend
1613 def signalClientClearWatch(self, condition): 1891 @type str
1892 """
1893 if (filename, lineno) not in self.__reportedBreakpointIssues:
1894 self.__reportedBreakpointIssues.append((filename, lineno))
1895 self.clientBreakConditionError.emit(filename, lineno, debuggerId)
1896
1897 def signalClientClearWatch(self, condition, debuggerId):
1614 """ 1898 """
1615 Public slot to handle the clientClearWatch signal. 1899 Public slot to handle the clientClearWatch signal.
1616 1900
1617 @param condition expression of watch expression to clear (string) 1901 @param condition expression of watch expression to clear
1618 """ 1902 @type str
1619 self.clientClearWatch.emit(condition) 1903 @param debuggerId ID of the debugger backend
1620 1904 @type str
1621 def signalClientWatchConditionError(self, condition): 1905 """
1906 self.clientClearWatch.emit(condition, debuggerId)
1907
1908 def signalClientWatchConditionError(self, condition, debuggerId):
1622 """ 1909 """
1623 Public method to process the client watch expression error info. 1910 Public method to process the client watch expression error info.
1624 1911
1625 @param condition expression of watch expression to clear (string) 1912 @param condition expression of watch expression to clear
1626 """ 1913 @type str
1627 self.clientWatchConditionError.emit(condition) 1914 @param debuggerId ID of the debugger backend
1628 1915 @type str
1629 def signalClientRawInput(self, prompt, echo): 1916 """
1917 if condition not in self.__reportedWatchpointIssues:
1918 self.__reportedWatchpointIssues.append(condition)
1919 self.clientWatchConditionError.emit(condition, debuggerId)
1920
1921 def signalClientRawInput(self, prompt, echo, debuggerId):
1630 """ 1922 """
1631 Public method to process the client raw input command. 1923 Public method to process the client raw input command.
1632 1924
1633 @param prompt the input prompt (string) 1925 @param prompt the input prompt
1634 @param echo flag indicating an echoing of the input (boolean) 1926 @type str
1635 """ 1927 @param echo flag indicating an echoing of the input
1636 self.clientRawInput.emit(prompt, echo) 1928 @type bool
1637 1929 @param debuggerId ID of the debugger backend
1638 def signalClientBanner(self, version, platform, debugClient, venvName): 1930 @type str
1931 """
1932 self.clientRawInput.emit(prompt, echo, debuggerId)
1933
1934 def signalClientBanner(self, version, platform, venvName):
1639 """ 1935 """
1640 Public method to process the client banner info. 1936 Public method to process the client banner info.
1641 1937
1642 @param version interpreter version info 1938 @param version interpreter version info
1643 @type str 1939 @type str
1644 @param platform hostname of the client 1940 @param platform hostname of the client
1645 @type str 1941 @type str
1646 @param debugClient additional debugger type info
1647 @type str
1648 @param venvName name of the virtual environment 1942 @param venvName name of the virtual environment
1649 @type str 1943 @type str
1650 """ 1944 """
1651 self.clientBanner.emit(version, platform, debugClient, venvName) 1945 self.clientBanner.emit(version, platform, venvName)
1652 1946
1653 def signalClientCapabilities(self, capabilities, clientType, venvName): 1947 def signalClientCapabilities(self, capabilities, clientType, venvName):
1654 """ 1948 """
1655 Public method to process the client capabilities info. 1949 Public method to process the client capabilities info.
1656 1950
1665 self.__debuggerInterfaceRegistry[clientType][0] = capabilities 1959 self.__debuggerInterfaceRegistry[clientType][0] = capabilities
1666 self.clientCapabilities.emit(capabilities, clientType, venvName) 1960 self.clientCapabilities.emit(capabilities, clientType, venvName)
1667 except KeyError: 1961 except KeyError:
1668 # ignore silently 1962 # ignore silently
1669 pass 1963 pass
1670 1964
1671 def signalClientCompletionList(self, completionList, text): 1965 def signalClientCompletionList(self, completionList, text, debuggerId):
1672 """ 1966 """
1673 Public method to process the client auto completion info. 1967 Public method to process the client auto completion info.
1674 1968
1675 @param completionList list of possible completions (list of strings) 1969 @param completionList list of possible completions
1676 @param text the text to be completed (string) 1970 @type list of str
1971 @param text the text to be completed
1972 @type str
1973 @param debuggerId ID of the debugger backend
1974 @type str
1677 """ 1975 """
1678 self.clientCompletionList.emit(completionList, text) 1976 self.clientCompletionList.emit(completionList, text)
1679 1977
1680 def signalClientCallTrace(self, isCall, fromFile, fromLine, fromFunction, 1978 def signalClientCallTrace(self, isCall, fromFile, fromLine, fromFunction,
1681 toFile, toLine, toFunction): 1979 toFile, toLine, toFunction, debuggerId):
1682 """ 1980 """
1683 Public method to process the client call trace data. 1981 Public method to process the client call trace data.
1684 1982
1685 @param isCall flag indicating a 'call' (boolean) 1983 @param isCall flag indicating a 'call'
1686 @param fromFile name of the originating file (string) 1984 @type bool
1687 @param fromLine line number in the originating file (string) 1985 @param fromFile name of the originating file
1688 @param fromFunction name of the originating function (string) 1986 @type str
1689 @param toFile name of the target file (string) 1987 @param fromLine line number in the originating file
1690 @param toLine line number in the target file (string) 1988 @type str
1691 @param toFunction name of the target function (string) 1989 @param fromFunction name of the originating function
1990 @type str
1991 @param toFile name of the target file
1992 @type str
1993 @param toLine line number in the target file
1994 @type str
1995 @param toFunction name of the target function
1996 @type str
1997 @param debuggerId ID of the debugger backend
1998 @type str
1692 """ 1999 """
1693 self.callTraceInfo.emit( 2000 self.callTraceInfo.emit(
1694 isCall, fromFile, fromLine, fromFunction, 2001 isCall, fromFile, fromLine, fromFunction,
1695 toFile, toLine, toFunction) 2002 toFile, toLine, toFunction, debuggerId)
1696 2003
1697 def clientUtDiscovered(self, testCases, exceptionType, exceptionValue): 2004 def clientUtDiscovered(self, testCases, exceptionType, exceptionValue):
1698 """ 2005 """
1699 Public method to process the client unittest discover info. 2006 Public method to process the client unittest discover info.
1700 2007
1701 @param testCases list of detected test cases 2008 @param testCases list of detected test cases
1704 @type str 2011 @type str
1705 @param exceptionValue exception message 2012 @param exceptionValue exception message
1706 @type str 2013 @type str
1707 """ 2014 """
1708 self.utDiscovered.emit(testCases, exceptionType, exceptionValue) 2015 self.utDiscovered.emit(testCases, exceptionType, exceptionValue)
1709 2016
1710 def clientUtPrepared(self, result, exceptionType, exceptionValue): 2017 def clientUtPrepared(self, result, exceptionType, exceptionValue):
1711 """ 2018 """
1712 Public method to process the client unittest prepared info. 2019 Public method to process the client unittest prepared info.
1713 2020
1714 @param result number of test cases (0 = error) (integer) 2021 @param result number of test cases (0 = error)
1715 @param exceptionType exception type (string) 2022 @type int
1716 @param exceptionValue exception message (string) 2023 @param exceptionType exception type
2024 @type str
2025 @param exceptionValue exception message
2026 @type str
1717 """ 2027 """
1718 self.utPrepared.emit(result, exceptionType, exceptionValue) 2028 self.utPrepared.emit(result, exceptionType, exceptionValue)
1719 2029
1720 def clientUtStartTest(self, testname, doc): 2030 def clientUtStartTest(self, testname, doc):
1721 """ 2031 """
1722 Public method to process the client start test info. 2032 Public method to process the client start test info.
1723 2033
1724 @param testname name of the test (string) 2034 @param testname name of the test
1725 @param doc short description of the test (string) 2035 @type str
2036 @param doc short description of the test
2037 @type str
1726 """ 2038 """
1727 self.utStartTest.emit(testname, doc) 2039 self.utStartTest.emit(testname, doc)
1728 2040
1729 def clientUtStopTest(self): 2041 def clientUtStopTest(self):
1730 """ 2042 """
1731 Public method to process the client stop test info. 2043 Public method to process the client stop test info.
1732 """ 2044 """
1733 self.utStopTest.emit() 2045 self.utStopTest.emit()
1734 2046
1735 def clientUtTestFailed(self, testname, traceback, testId): 2047 def clientUtTestFailed(self, testname, traceback, testId):
1736 """ 2048 """
1737 Public method to process the client test failed info. 2049 Public method to process the client test failed info.
1738 2050
1739 @param testname name of the test (string) 2051 @param testname name of the test
1740 @param traceback lines of traceback info (list of strings) 2052 @type str
1741 @param testId id of the test (string) 2053 @param traceback lines of traceback info
2054 @type list of str
2055 @param testId id of the test
2056 @type str
1742 """ 2057 """
1743 self.utTestFailed.emit(testname, traceback, testId) 2058 self.utTestFailed.emit(testname, traceback, testId)
1744 2059
1745 def clientUtTestErrored(self, testname, traceback, testId): 2060 def clientUtTestErrored(self, testname, traceback, testId):
1746 """ 2061 """
1747 Public method to process the client test errored info. 2062 Public method to process the client test errored info.
1748 2063
1749 @param testname name of the test (string) 2064 @param testname name of the test
1750 @param traceback lines of traceback info (list of strings) 2065 @type str
1751 @param testId id of the test (string) 2066 @param traceback lines of traceback info
2067 @type list of str
2068 @param testId id of the test
2069 @type str
1752 """ 2070 """
1753 self.utTestErrored.emit(testname, traceback, testId) 2071 self.utTestErrored.emit(testname, traceback, testId)
1754 2072
1755 def clientUtTestSkipped(self, testname, reason, testId): 2073 def clientUtTestSkipped(self, testname, reason, testId):
1756 """ 2074 """
1757 Public method to process the client test skipped info. 2075 Public method to process the client test skipped info.
1758 2076
1759 @param testname name of the test (string) 2077 @param testname name of the test
1760 @param reason reason for skipping the test (string) 2078 @type str
1761 @param testId id of the test (string) 2079 @param reason reason for skipping the test
2080 @type str
2081 @param testId id of the test
2082 @type str
1762 """ 2083 """
1763 self.utTestSkipped.emit(testname, reason, testId) 2084 self.utTestSkipped.emit(testname, reason, testId)
1764 2085
1765 def clientUtTestFailedExpected(self, testname, traceback, testId): 2086 def clientUtTestFailedExpected(self, testname, traceback, testId):
1766 """ 2087 """
1767 Public method to process the client test failed expected info. 2088 Public method to process the client test failed expected info.
1768 2089
1769 @param testname name of the test (string) 2090 @param testname name of the test
1770 @param traceback lines of traceback info (list of strings) 2091 @type str
1771 @param testId id of the test (string) 2092 @param traceback lines of traceback info
2093 @type list of str
2094 @param testId id of the test
2095 @type str
1772 """ 2096 """
1773 self.utTestFailedExpected.emit(testname, traceback, testId) 2097 self.utTestFailedExpected.emit(testname, traceback, testId)
1774 2098
1775 def clientUtTestSucceededUnexpected(self, testname, testId): 2099 def clientUtTestSucceededUnexpected(self, testname, testId):
1776 """ 2100 """
1777 Public method to process the client test succeeded unexpected info. 2101 Public method to process the client test succeeded unexpected info.
1778 2102
1779 @param testname name of the test (string) 2103 @param testname name of the test
1780 @param testId id of the test (string) 2104 @type str
2105 @param testId id of the test
2106 @type str
1781 """ 2107 """
1782 self.utTestSucceededUnexpected.emit(testname, testId) 2108 self.utTestSucceededUnexpected.emit(testname, testId)
1783 2109
1784 def clientUtFinished(self, status): 2110 def clientUtFinished(self, status):
1785 """ 2111 """
1786 Public method to process the client unit test finished info. 2112 Public method to process the client unit test finished info.
1787 2113
1788 @param status exit status of the unit test 2114 @param status exit status of the unit test
1789 @type int 2115 @type int
1790 """ 2116 """
1791 self.utFinished.emit() 2117 self.utFinished.emit()
1792 2118
1793 self.clientExit.emit(int(status), "", True) 2119 self.clientExit.emit("", int(status), "", True, "")
1794 self.debugging = False 2120 self.debugging = False
1795 self.running = False 2121 self.running = False
1796 2122
1797 def passiveStartUp(self, fn, exc): 2123 def passiveStartUp(self, fn, exc, debuggerId):
1798 """ 2124 """
1799 Public method to handle a passive debug connection. 2125 Public method to handle a passive debug connection.
1800 2126
1801 @param fn filename of the debugged script (string) 2127 @param fn filename of the debugged script
1802 @param exc flag to enable exception reporting of the IDE (boolean) 2128 @type str
2129 @param exc flag to enable exception reporting of the IDE
2130 @type bool
2131 @param debuggerId ID of the debugger backend
2132 @type str
1803 """ 2133 """
1804 self.appendStdout.emit(self.tr("Passive debug connection received\n")) 2134 self.appendStdout.emit(self.tr("Passive debug connection received\n"))
1805 self.passiveClientExited = False 2135 self.passiveClientExited = False
1806 self.debugging = True 2136 self.debugging = True
1807 self.running = True 2137 self.running = True
1808 self.__restoreBreakpoints() 2138 self.__restoreBreakpoints(debuggerId)
1809 self.__restoreWatchpoints() 2139 self.__restoreWatchpoints(debuggerId)
1810 self.passiveDebugStarted.emit(fn, exc) 2140 self.passiveDebugStarted.emit(fn, exc)
1811 2141
1812 def __passiveShutDown(self): 2142 def __passiveShutDown(self):
1813 """ 2143 """
1814 Private method to shut down a passive debug connection. 2144 Private method to shut down a passive debug connection.
1815 """ 2145 """
1816 self.passiveClientExited = True 2146 self.passiveClientExited = True
1817 self.shutdownServer() 2147 self.shutdownServer()
1818 self.appendStdout.emit(self.tr("Passive debug connection closed\n")) 2148 self.appendStdout.emit(self.tr("Passive debug connection closed\n"))
1819 2149
1820 def __restoreBreakpoints(self): 2150 def __restoreBreakpoints(self, debuggerId=""):
1821 """ 2151 """
1822 Private method to restore the breakpoints after a restart. 2152 Private method to restore the breakpoints after a restart.
2153
2154 @param debuggerId ID of the debugger backend to send to. If this is
2155 empty, they will be broadcast to all connected backends.
2156 @type str
1823 """ 2157 """
1824 if self.debugging: 2158 if self.debugging:
1825 self.__addBreakPoints( 2159 self.__addBreakPoints(
1826 QModelIndex(), 0, self.breakpointModel.rowCount() - 1) 2160 QModelIndex(), 0, self.breakpointModel.rowCount() - 1,
1827 2161 debuggerId)
1828 def __restoreWatchpoints(self): 2162
2163 def __restoreWatchpoints(self, debuggerId=""):
1829 """ 2164 """
1830 Private method to restore the watch expressions after a restart. 2165 Private method to restore the watch expressions after a restart.
2166
2167 @param debuggerId ID of the debugger backend to send to. If this is
2168 empty, they will be broadcast to all connected backends.
2169 @type str
1831 """ 2170 """
1832 if self.debugging: 2171 if self.debugging:
1833 self.__addWatchPoints( 2172 self.__addWatchPoints(
1834 QModelIndex(), 0, self.watchpointModel.rowCount() - 1) 2173 QModelIndex(), 0, self.watchpointModel.rowCount() - 1,
2174 debuggerId)
1835 2175
1836 def getBreakPointModel(self): 2176 def getBreakPointModel(self):
1837 """ 2177 """
1838 Public slot to get a reference to the breakpoint model object. 2178 Public slot to get a reference to the breakpoint model object.
1839 2179
1840 @return reference to the breakpoint model object (BreakPointModel) 2180 @return reference to the breakpoint model object
2181 @rtype BreakPointModel
1841 """ 2182 """
1842 return self.breakpointModel 2183 return self.breakpointModel
1843 2184
1844 def getWatchPointModel(self): 2185 def getWatchPointModel(self):
1845 """ 2186 """
1846 Public slot to get a reference to the watch expression model object. 2187 Public slot to get a reference to the watch expression model object.
1847 2188
1848 @return reference to the watch expression model object 2189 @return reference to the watch expression model object
1849 (WatchPointModel) 2190 @rtype WatchPointModel
1850 """ 2191 """
1851 return self.watchpointModel 2192 return self.watchpointModel
1852 2193
1853 def isConnected(self): 2194 def isConnected(self):
1854 """ 2195 """
1855 Public method to test, if the debug server is connected to a backend. 2196 Public method to test, if the debug server is connected to a backend.
1856 2197
1857 @return flag indicating a connection (boolean) 2198 @return flag indicating a connection
2199 @rtype bool
1858 """ 2200 """
1859 return self.debuggerInterface and self.debuggerInterface.isConnected() 2201 return self.debuggerInterface and self.debuggerInterface.isConnected()
1860 2202
1861 def isDebugging(self): 2203 def isDebugging(self):
1862 """ 2204 """
1873 2215
1874 @param on flag indicating the new debugging state 2216 @param on flag indicating the new debugging state
1875 @type bool 2217 @type bool
1876 """ 2218 """
1877 self.debugging = on 2219 self.debugging = on
2220
2221 def signalClientDebuggerId(self, debuggerId):
2222 """
2223 Public method to signal the receipt of a new debugger ID.
2224
2225 This signal indicates, that a new debugger backend has connected.
2226
2227 @param debuggerId ID of the newly connected debugger backend
2228 @type str
2229 """
2230 self.clientDebuggerId.emit(debuggerId)
2231
2232 def getDebuggerIds(self):
2233 """
2234 Public method to return the IDs of the connected debugger backends.
2235
2236 @return list of connected debugger backend IDs
2237 @rtype list of str
2238 """
2239 if self.debuggerInterface:
2240 return self.debuggerInterface.getDebuggerIds()
2241 else:
2242 return []
2243
2244 def initializeClient(self, debuggerId):
2245 """
2246 Public method to initialize a freshly connected debug client.
2247
2248 @param debuggerId ID of the connected debugger
2249 @type str
2250 """
2251 self.__restoreBreakpoints(debuggerId)
2252 self.__restoreWatchpoints(debuggerId)
2253 self.__restoreNoDebugList(debuggerId)
2254
2255 def __restoreNoDebugList(self, debuggerId=""):
2256 """
2257 Private method to restore the list of scripts not to be debugged after
2258 a restart.
2259
2260 @param debuggerId ID of the debugger backend to send to. If this is
2261 empty, they will be broadcast to all connected backends.
2262 @type str
2263 """
2264 if self.debugging:
2265 self.debuggerInterface.remoteNoDebugList(
2266 debuggerId, self.__multiprocessNoDebugList)

eric ide

mercurial