|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2007 - 2009 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the debug server. |
|
8 """ |
|
9 |
|
10 import sys |
|
11 import os |
|
12 import time |
|
13 import signal |
|
14 |
|
15 from PyQt4.QtCore import * |
|
16 from PyQt4.QtGui import QMessageBox |
|
17 from PyQt4.QtNetwork import QTcpServer, QHostAddress, QHostInfo |
|
18 |
|
19 from E4Gui.E4Application import e4App |
|
20 |
|
21 from BreakPointModel import BreakPointModel |
|
22 from WatchPointModel import WatchPointModel |
|
23 import DebugClientCapabilities |
|
24 |
|
25 import Preferences |
|
26 import Utilities |
|
27 |
|
28 |
|
29 DebuggerInterfaces = [ |
|
30 "DebuggerInterfacePython", |
|
31 "DebuggerInterfacePython3", |
|
32 "DebuggerInterfaceRuby", |
|
33 "DebuggerInterfaceNone", |
|
34 ] |
|
35 |
|
36 class DebugServer(QTcpServer): |
|
37 """ |
|
38 Class implementing the debug server embedded within the IDE. |
|
39 |
|
40 @signal clientProcessStdout emitted after the client has sent some output |
|
41 via stdout |
|
42 @signal clientProcessStderr emitted after the client has sent some output |
|
43 via stderr |
|
44 @signal clientOutput emitted after the client has sent some output |
|
45 @signal clientRawInputSent emitted after the data was sent to the debug client |
|
46 @signal clientLine(filename, lineno, forStack) emitted after the debug client |
|
47 has executed a line of code |
|
48 @signal clientStack(stack) emitted after the debug client has executed a |
|
49 line of code |
|
50 @signal clientThreadList(currentId, threadList) emitted after a thread list |
|
51 has been received |
|
52 @signal clientThreadSet emitted after the client has acknowledged the change |
|
53 of the current thread |
|
54 @signal clientVariables(scope, variables) emitted after a variables dump has |
|
55 been received |
|
56 @signal clientVariable(scope, variables) emitted after a dump for one class |
|
57 variable has been received |
|
58 @signal clientStatement(boolean) emitted after an interactive command has |
|
59 been executed. The parameter is 0 to indicate that the command is |
|
60 complete and 1 if it needs more input. |
|
61 @signal clientException(exception) emitted after an exception occured on the |
|
62 client side |
|
63 @signal clientSyntaxError(exception) emitted after a syntax error has been detected |
|
64 on the client side |
|
65 @signal clientExit(int) emitted with the exit status after the client has exited |
|
66 @signal clientClearBreak(filename, lineno) emitted after the debug client |
|
67 has decided to clear a temporary breakpoint |
|
68 @signal clientBreakConditionError(fn, lineno) emitted after the client has signaled |
|
69 a syntax error in a breakpoint condition |
|
70 @signal clientClearWatch(condition) emitted after the debug client |
|
71 has decided to clear a temporary watch expression |
|
72 @signal clientWatchConditionError(condition) emitted after the client has signaled |
|
73 a syntax error in a watch expression |
|
74 @signal clientRawInput(prompt, echo) emitted after a raw input request was received |
|
75 @signal clientBanner(banner) emitted after the client banner was received |
|
76 @signal clientCapabilities(int capabilities, QString cltype) emitted after the clients |
|
77 capabilities were received |
|
78 @signal clientCompletionList(completionList, text) emitted after the client |
|
79 the commandline completion list and the reworked searchstring was |
|
80 received from the client |
|
81 @signal passiveDebugStarted emitted after the debug client has connected in |
|
82 passive debug mode |
|
83 @signal clientGone emitted if the client went away (planned or unplanned) |
|
84 @signal utPrepared(nrTests, exc_type, exc_value) emitted after the client has |
|
85 loaded a unittest suite |
|
86 @signal utFinished emitted after the client signalled the end of the unittest |
|
87 @signal utStartTest(testname, testdocu) emitted after the client has started |
|
88 a test |
|
89 @signal utStopTest emitted after the client has finished a test |
|
90 @signal utTestFailed(testname, exc_info) emitted after the client reported |
|
91 a failed test |
|
92 @signal utTestErrored(testname, exc_info) emitted after the client reported |
|
93 an errored test |
|
94 """ |
|
95 def __init__(self): |
|
96 """ |
|
97 Constructor |
|
98 """ |
|
99 QTcpServer.__init__(self) |
|
100 |
|
101 # create our models |
|
102 self.breakpointModel = BreakPointModel(self) |
|
103 self.watchpointModel = WatchPointModel(self) |
|
104 self.watchSpecialCreated = \ |
|
105 self.trUtf8("created", "must be same as in EditWatchpointDialog") |
|
106 self.watchSpecialChanged = \ |
|
107 self.trUtf8("changed", "must be same as in EditWatchpointDialog") |
|
108 |
|
109 self.networkInterface = Preferences.getDebugger("NetworkInterface") |
|
110 if self.networkInterface == "all": |
|
111 hostAddress = QHostAddress("0.0.0.0")#QHostAddress.Any) |
|
112 elif self.networkInterface == "allv6": |
|
113 hostAddress = QHostAddress("::")#QHostAddress.AnyIPv6) |
|
114 else: |
|
115 hostAddress = QHostAddress(Preferences.getDebugger("NetworkInterface")) |
|
116 if Preferences.getDebugger("PassiveDbgEnabled"): |
|
117 socket = Preferences.getDebugger("PassiveDbgPort") # default: 42424 |
|
118 self.listen(hostAddress, socket) |
|
119 self.passive = True |
|
120 self.passiveClientExited = False |
|
121 else: |
|
122 self.listen(hostAddress) |
|
123 self.passive = False |
|
124 |
|
125 self.debuggerInterface = None |
|
126 self.debugging = False |
|
127 self.clientProcess = None |
|
128 self.clientType = \ |
|
129 Preferences.Prefs.settings.value('DebugClient/Type', |
|
130 QVariant('Python')).toString() |
|
131 self.lastClientType = '' |
|
132 self.__autoClearShell = False |
|
133 |
|
134 self.connect(self, SIGNAL("clientClearBreak"), self.__clientClearBreakPoint) |
|
135 self.connect(self, SIGNAL("clientClearWatch"), self.__clientClearWatchPoint) |
|
136 self.connect(self, SIGNAL("newConnection()"), self.__newConnection) |
|
137 |
|
138 self.connect(self.breakpointModel, |
|
139 SIGNAL("rowsAboutToBeRemoved(const QModelIndex &, int, int)"), |
|
140 self.__deleteBreakPoints) |
|
141 self.connect(self.breakpointModel, |
|
142 SIGNAL("dataAboutToBeChanged(const QModelIndex &, const QModelIndex &)"), |
|
143 self.__breakPointDataAboutToBeChanged) |
|
144 self.connect(self.breakpointModel, |
|
145 SIGNAL("dataChanged(const QModelIndex &, const QModelIndex &)"), |
|
146 self.__changeBreakPoints) |
|
147 self.connect(self.breakpointModel, |
|
148 SIGNAL("rowsInserted(const QModelIndex &, int, int)"), |
|
149 self.__addBreakPoints) |
|
150 |
|
151 self.connect(self.watchpointModel, |
|
152 SIGNAL("rowsAboutToBeRemoved(const QModelIndex &, int, int)"), |
|
153 self.__deleteWatchPoints) |
|
154 self.connect(self.watchpointModel, |
|
155 SIGNAL("dataAboutToBeChanged(const QModelIndex &, const QModelIndex &)"), |
|
156 self.__watchPointDataAboutToBeChanged) |
|
157 self.connect(self.watchpointModel, |
|
158 SIGNAL("dataChanged(const QModelIndex &, const QModelIndex &)"), |
|
159 self.__changeWatchPoints) |
|
160 self.connect(self.watchpointModel, |
|
161 SIGNAL("rowsInserted(const QModelIndex &, int, int)"), |
|
162 self.__addWatchPoints) |
|
163 |
|
164 self.__registerDebuggerInterfaces() |
|
165 |
|
166 def getHostAddress(self, localhost): |
|
167 """ |
|
168 Public method to get the IP address or hostname the debug server is listening. |
|
169 |
|
170 @param localhost flag indicating to return the address for localhost (boolean) |
|
171 @return IP address or hostname (string) |
|
172 """ |
|
173 if self.networkInterface == "all": |
|
174 if localhost: |
|
175 return "127.0.0.1" |
|
176 else: |
|
177 return "%s@@v4" % QHostInfo.localHostName() |
|
178 elif self.networkInterface == "allv6": |
|
179 if localhost: |
|
180 return "::1" |
|
181 else: |
|
182 return "%s@@v6" % QHostInfo.localHostName() |
|
183 else: |
|
184 return self.networkInterface |
|
185 |
|
186 def preferencesChanged(self): |
|
187 """ |
|
188 Public slot to handle the preferencesChanged signal. |
|
189 """ |
|
190 self.__registerDebuggerInterfaces() |
|
191 |
|
192 def __registerDebuggerInterfaces(self): |
|
193 """ |
|
194 Private method to register the available debugger interface modules. |
|
195 """ |
|
196 self.__clientCapabilities = {} |
|
197 self.__clientAssociations = {} |
|
198 |
|
199 for interface in DebuggerInterfaces: |
|
200 modName = "Debugger.%s" % interface |
|
201 mod = __import__(modName) |
|
202 components = modName.split('.') |
|
203 for comp in components[1:]: |
|
204 mod = getattr(mod, comp) |
|
205 |
|
206 clientLanguage, clientCapabilities, clientExtensions = \ |
|
207 mod.getRegistryData() |
|
208 if clientLanguage: |
|
209 self.__clientCapabilities[clientLanguage] = clientCapabilities |
|
210 for extension in clientExtensions: |
|
211 if extension not in self.__clientAssociations: |
|
212 self.__clientAssociations[extension] = clientLanguage |
|
213 |
|
214 def getSupportedLanguages(self, shellOnly = False): |
|
215 """ |
|
216 Public slot to return the supported programming languages. |
|
217 |
|
218 @param shellOnly flag indicating only languages supporting an |
|
219 interactive shell should be returned |
|
220 @return list of supported languages (list of strings) |
|
221 """ |
|
222 languages = self.__clientCapabilities.keys() |
|
223 try: |
|
224 del languages[languages.index("None")] |
|
225 except ValueError: |
|
226 pass # it is not in the list |
|
227 |
|
228 if shellOnly: |
|
229 languages = \ |
|
230 [lang for lang in languages \ |
|
231 if self.__clientCapabilities[lang] & DebugClientCapabilities.HasShell] |
|
232 |
|
233 return languages[:] |
|
234 |
|
235 def getExtensions(self, language): |
|
236 """ |
|
237 Public slot to get the extensions associated with the given language. |
|
238 |
|
239 @param language language to get extensions for (string) |
|
240 @return tuple of extensions associated with the language (tuple of strings) |
|
241 """ |
|
242 extensions = [] |
|
243 for ext, lang in self.__clientAssociations.items(): |
|
244 if lang == language: |
|
245 extensions.append(ext) |
|
246 |
|
247 return tuple(extensions) |
|
248 |
|
249 def __createDebuggerInterface(self, clientType = None): |
|
250 """ |
|
251 Private slot to create the debugger interface object. |
|
252 |
|
253 @param clientType type of the client interface to be created (string) |
|
254 """ |
|
255 if self.lastClientType != self.clientType or clientType is not None: |
|
256 if clientType is None: |
|
257 clientType = self.clientType |
|
258 if clientType == "Python": |
|
259 from DebuggerInterfacePython import DebuggerInterfacePython |
|
260 self.debuggerInterface = DebuggerInterfacePython(self, self.passive) |
|
261 elif clientType == "Python3": |
|
262 from DebuggerInterfacePython3 import DebuggerInterfacePython3 |
|
263 self.debuggerInterface = DebuggerInterfacePython3(self, self.passive) |
|
264 elif clientType == "Ruby": |
|
265 from DebuggerInterfaceRuby import DebuggerInterfaceRuby |
|
266 self.debuggerInterface = DebuggerInterfaceRuby(self, self.passive) |
|
267 elif clientType == "None": |
|
268 from DebuggerInterfaceNone import DebuggerInterfaceNone |
|
269 self.debuggerInterface = DebuggerInterfaceNone(self, self.passive) |
|
270 else: |
|
271 from DebuggerInterfaceNone import DebuggerInterfaceNone |
|
272 self.debuggerInterface = DebuggerInterfaceNone(self, self.passive) |
|
273 self.clientType = "None" |
|
274 |
|
275 def __setClientType(self, clType): |
|
276 """ |
|
277 Private method to set the client type. |
|
278 |
|
279 @param clType type of client to be started (string) |
|
280 """ |
|
281 if clType is not None and clType in self.getSupportedLanguages(): |
|
282 self.clientType = clType |
|
283 ok = Preferences.Prefs.settings.setValue('DebugClient/Type', |
|
284 QVariant(self.clientType)) |
|
285 |
|
286 def startClient(self, unplanned = True, clType = None, forProject = False, |
|
287 runInConsole = False): |
|
288 """ |
|
289 Public method to start a debug client. |
|
290 |
|
291 @keyparam unplanned flag indicating that the client has died (boolean) |
|
292 @keyparam clType type of client to be started (string) |
|
293 @keyparam forProject flag indicating a project related action (boolean) |
|
294 @keyparam runInConsole flag indicating to start the debugger in a |
|
295 console window (boolean) |
|
296 """ |
|
297 if not self.passive or not self.passiveClientExited: |
|
298 if self.debuggerInterface and self.debuggerInterface.isConnected(): |
|
299 self.shutdownServer() |
|
300 self.emit(SIGNAL('clientGone'), unplanned & self.debugging) |
|
301 |
|
302 if clType: |
|
303 self.__setClientType(clType) |
|
304 |
|
305 # only start the client, if we are not in passive mode |
|
306 if not self.passive: |
|
307 if self.clientProcess: |
|
308 self.disconnect(self.clientProcess, SIGNAL("readyReadStandardError()"), |
|
309 self.__clientProcessError) |
|
310 self.disconnect(self.clientProcess, SIGNAL("readyReadStandardOutput()"), |
|
311 self.__clientProcessOutput) |
|
312 self.clientProcess.close() |
|
313 self.clientProcess.kill() |
|
314 self.clientProcess.waitForFinished(10000) |
|
315 self.clientProcess = None |
|
316 |
|
317 self.__createDebuggerInterface() |
|
318 if forProject: |
|
319 project = e4App().getObject("Project") |
|
320 if not project.isDebugPropertiesLoaded(): |
|
321 self.clientProcess, isNetworked = \ |
|
322 self.debuggerInterface.startRemote(self.serverPort(), |
|
323 runInConsole) |
|
324 else: |
|
325 self.clientProcess, isNetworked = \ |
|
326 self.debuggerInterface.startRemoteForProject(self.serverPort(), |
|
327 runInConsole) |
|
328 else: |
|
329 self.clientProcess, isNetworked = \ |
|
330 self.debuggerInterface.startRemote(self.serverPort(), runInConsole) |
|
331 |
|
332 if self.clientProcess: |
|
333 self.connect(self.clientProcess, SIGNAL("readyReadStandardError()"), |
|
334 self.__clientProcessError) |
|
335 self.connect(self.clientProcess, SIGNAL("readyReadStandardOutput()"), |
|
336 self.__clientProcessOutput) |
|
337 |
|
338 if not isNetworked: |
|
339 # the client is connected through stdin and stdout |
|
340 # Perform actions necessary, if client type has changed |
|
341 if self.lastClientType != self.clientType: |
|
342 self.lastClientType = self.clientType |
|
343 self.remoteBanner() |
|
344 elif self.__autoClearShell: |
|
345 self.__autoClearShell = False |
|
346 self.remoteBanner() |
|
347 |
|
348 self.debuggerInterface.flush() |
|
349 else: |
|
350 self.__createDebuggerInterface("None") |
|
351 |
|
352 def __clientProcessOutput(self): |
|
353 """ |
|
354 Private slot to process client output received via stdout. |
|
355 """ |
|
356 output = unicode(self.clientProcess.readAllStandardOutput()) |
|
357 self.emit(SIGNAL("clientProcessStdout"), output) |
|
358 |
|
359 def __clientProcessError(self): |
|
360 """ |
|
361 Private slot to process client output received via stderr. |
|
362 """ |
|
363 error = unicode(self.clientProcess.readAllStandardError()) |
|
364 self.emit(SIGNAL("clientProcessStderr"), error) |
|
365 |
|
366 def __clientClearBreakPoint(self, fn, lineno): |
|
367 """ |
|
368 Private slot to handle the clientClearBreak signal. |
|
369 |
|
370 @param fn filename of breakpoint to clear (string) |
|
371 @param lineno line number of breakpoint to clear (integer) |
|
372 """ |
|
373 if self.debugging: |
|
374 index = self.breakpointModel.getBreakPointIndex(fn, lineno) |
|
375 self.breakpointModel.deleteBreakPointByIndex(index) |
|
376 |
|
377 def __deleteBreakPoints(self, parentIndex, start, end): |
|
378 """ |
|
379 Private slot to delete breakpoints. |
|
380 |
|
381 @param parentIndex index of parent item (QModelIndex) |
|
382 @param start start row (integer) |
|
383 @param end end row (integer) |
|
384 """ |
|
385 if self.debugging: |
|
386 for row in range(start, end+1): |
|
387 index = self.breakpointModel.index(row, 0, parentIndex) |
|
388 fn, lineno = self.breakpointModel.getBreakPointByIndex(index)[0:2] |
|
389 self.remoteBreakpoint(fn, lineno, False) |
|
390 |
|
391 def __changeBreakPoints(self, startIndex, endIndex): |
|
392 """ |
|
393 Private slot to set changed breakpoints. |
|
394 |
|
395 @param indexes indexes of changed breakpoints. |
|
396 """ |
|
397 if self.debugging: |
|
398 self.__addBreakPoints(QModelIndex(), startIndex.row(), endIndex.row()) |
|
399 |
|
400 def __breakPointDataAboutToBeChanged(self, startIndex, endIndex): |
|
401 """ |
|
402 Private slot to handle the dataAboutToBeChanged signal of the breakpoint model. |
|
403 |
|
404 @param startIndex start index of the rows to be changed (QModelIndex) |
|
405 @param endIndex end index of the rows to be changed (QModelIndex) |
|
406 """ |
|
407 if self.debugging: |
|
408 self.__deleteBreakPoints(QModelIndex(), startIndex.row(), endIndex.row()) |
|
409 |
|
410 def __addBreakPoints(self, parentIndex, start, end): |
|
411 """ |
|
412 Private slot to add breakpoints. |
|
413 |
|
414 @param parentIndex index of parent item (QModelIndex) |
|
415 @param start start row (integer) |
|
416 @param end end row (integer) |
|
417 """ |
|
418 if self.debugging: |
|
419 for row in range(start, end+1): |
|
420 index = self.breakpointModel.index(row, 0, parentIndex) |
|
421 fn, line, cond, temp, enabled, ignorecount = \ |
|
422 self.breakpointModel.getBreakPointByIndex(index)[:6] |
|
423 self.remoteBreakpoint(fn, line, True, cond, temp) |
|
424 if not enabled: |
|
425 self.__remoteBreakpointEnable(fn, line, False) |
|
426 if ignorecount: |
|
427 self.__remoteBreakpointIgnore(fn, line, ignorecount) |
|
428 |
|
429 def __makeWatchCondition(self, cond, special): |
|
430 """ |
|
431 Private method to construct the condition string. |
|
432 |
|
433 @param cond condition (string) |
|
434 @param special special condition (string) |
|
435 @return condition string (string) |
|
436 """ |
|
437 if special == "": |
|
438 _cond = cond |
|
439 else: |
|
440 if special == self.watchSpecialCreated: |
|
441 _cond = "%s ??created??" % cond |
|
442 elif special == self.watchSpecialChanged: |
|
443 _cond = "%s ??changed??" % cond |
|
444 return _cond |
|
445 |
|
446 def __splitWatchCondition(self, cond): |
|
447 """ |
|
448 Private method to split a remote watch expression. |
|
449 |
|
450 @param cond remote expression (string) |
|
451 @return tuple of local expression (string) and special condition (string) |
|
452 """ |
|
453 if cond.endswith(" ??created??"): |
|
454 cond, special = cond.split() |
|
455 special = self.watchSpecialCreated |
|
456 elif cond.endswith(" ??changed??"): |
|
457 cond, special = cond.split() |
|
458 special = self.watchSpecialChanged |
|
459 else: |
|
460 return cond, "" |
|
461 |
|
462 def __clientClearWatchPoint(self, condition): |
|
463 """ |
|
464 Private slot to handle the clientClearWatch signal. |
|
465 |
|
466 @param condition expression of watch expression to clear (string) |
|
467 """ |
|
468 if self.debugging: |
|
469 cond, special = self.__splitWatchCondition(condition) |
|
470 index = self.watchpointModel.getWatchPointIndex(cond, special) |
|
471 self.watchpointModel.deleteWatchPointByIndex(index) |
|
472 |
|
473 def __deleteWatchPoints(self, parentIndex, start, end): |
|
474 """ |
|
475 Private slot to delete watch expressions. |
|
476 |
|
477 @param parentIndex index of parent item (QModelIndex) |
|
478 @param start start row (integer) |
|
479 @param end end row (integer) |
|
480 """ |
|
481 if self.debugging: |
|
482 for row in range(start, end+1): |
|
483 index = self.watchpointModel.index(row, 0, parentIndex) |
|
484 cond, special = self.watchpointModel.getWatchPointByIndex(index)[0:2] |
|
485 cond = self.__makeWatchCondition(cond, special) |
|
486 self.__remoteWatchpoint(cond, False) |
|
487 |
|
488 def __watchPointDataAboutToBeChanged(self, startIndex, endIndex): |
|
489 """ |
|
490 Private slot to handle the dataAboutToBeChanged signal of the |
|
491 watch expression model. |
|
492 |
|
493 @param startIndex start index of the rows to be changed (QModelIndex) |
|
494 @param endIndex end index of the rows to be changed (QModelIndex) |
|
495 """ |
|
496 if self.debugging: |
|
497 self.__deleteWatchPoints(QModelIndex(), startIndex.row(), endIndex.row()) |
|
498 |
|
499 def __addWatchPoints(self, parentIndex, start, end): |
|
500 """ |
|
501 Private slot to set a watch expression. |
|
502 |
|
503 @param parentIndex index of parent item (QModelIndex) |
|
504 @param start start row (integer) |
|
505 @param end end row (integer) |
|
506 """ |
|
507 if self.debugging: |
|
508 for row in range(start, end + 1): |
|
509 index = self.watchpointModel.index(row, 0, parentIndex) |
|
510 cond, special, temp, enabled, ignorecount = \ |
|
511 self.watchpointModel.getWatchPointByIndex(index)[:5] |
|
512 cond = self.__makeWatchCondition(cond, special) |
|
513 self.__remoteWatchpoint(cond, True, temp) |
|
514 if not enabled: |
|
515 self.__remoteWatchpointEnable(cond, False) |
|
516 if ignorecount: |
|
517 self.__remoteWatchpointIgnore(cond, ignorecount) |
|
518 |
|
519 def __changeWatchPoints(self, startIndex, endIndex): |
|
520 """ |
|
521 Private slot to set changed watch expressions. |
|
522 |
|
523 @param startIndex start index of the rows to be changed (QModelIndex) |
|
524 @param endIndex end index of the rows to be changed (QModelIndex) |
|
525 """ |
|
526 if self.debugging: |
|
527 self.__addWatchPoints(QModelIndex(), startIndex.row(), endIndex.row()) |
|
528 |
|
529 def getClientCapabilities(self, type): |
|
530 """ |
|
531 Public method to retrieve the debug clients capabilities. |
|
532 |
|
533 @param type debug client type (string) |
|
534 @return debug client capabilities (integer) |
|
535 """ |
|
536 try: |
|
537 return self.__clientCapabilities[type] |
|
538 except KeyError: |
|
539 return 0 # no capabilities |
|
540 |
|
541 def __newConnection(self): |
|
542 """ |
|
543 Private slot to handle a new connection. |
|
544 """ |
|
545 sock = self.nextPendingConnection() |
|
546 peerAddress = sock.peerAddress().toString() |
|
547 if peerAddress not in Preferences.getDebugger("AllowedHosts"): |
|
548 # the peer is not allowed to connect |
|
549 res = QMessageBox.warning(None, |
|
550 self.trUtf8("Connection from illegal host"), |
|
551 self.trUtf8("""<p>A connection was attempted by the""" |
|
552 """ illegal host <b>{0}</b>. Accept this connection?</p>""")\ |
|
553 .format(peerAddress), |
|
554 QMessageBox.StandardButtons(\ |
|
555 QMessageBox.No | \ |
|
556 QMessageBox.Yes), |
|
557 QMessageBox.No) |
|
558 if res == QMessageBox.No: |
|
559 sock.abort() |
|
560 return |
|
561 else: |
|
562 allowedHosts = Preferences.getDebugger("AllowedHosts") |
|
563 allowedHosts.append(peerAddress) |
|
564 Preferences.setDebugger("AllowedHosts", allowedHosts) |
|
565 |
|
566 if self.passive: |
|
567 self.__createDebuggerInterface(Preferences.getDebugger("PassiveDbgType")) |
|
568 |
|
569 accepted = self.debuggerInterface.newConnection(sock) |
|
570 if accepted: |
|
571 # Perform actions necessary, if client type has changed |
|
572 if self.lastClientType != self.clientType: |
|
573 self.lastClientType = self.clientType |
|
574 self.remoteBanner() |
|
575 elif self.__autoClearShell: |
|
576 self.__autoClearShell = False |
|
577 self.remoteBanner() |
|
578 elif self.passive: |
|
579 self.remoteBanner() |
|
580 |
|
581 self.debuggerInterface.flush() |
|
582 |
|
583 def shutdownServer(self): |
|
584 """ |
|
585 Public method to cleanly shut down. |
|
586 |
|
587 It closes our socket and shuts down |
|
588 the debug client. (Needed on Win OS) |
|
589 """ |
|
590 if self.debuggerInterface is not None: |
|
591 self.debuggerInterface.shutdown() |
|
592 |
|
593 def remoteEnvironment(self, env): |
|
594 """ |
|
595 Public method to set the environment for a program to debug, run, ... |
|
596 |
|
597 @param env environment settings (string) |
|
598 """ |
|
599 envlist = Utilities.parseEnvironmentString(env) |
|
600 envdict = {} |
|
601 for el in envlist: |
|
602 try: |
|
603 key, value = el.split('=', 1) |
|
604 if value.startswith('"') or value.startswith("'"): |
|
605 value = value[1:-1] |
|
606 envdict[key] = value |
|
607 except UnpackError: |
|
608 pass |
|
609 self.debuggerInterface.remoteEnvironment(envdict) |
|
610 |
|
611 def remoteLoad(self, fn, argv, wd, env, autoClearShell = True, |
|
612 tracePython = False, autoContinue = True, forProject = False, |
|
613 runInConsole = False, autoFork = False, forkChild = False): |
|
614 """ |
|
615 Public method to load a new program to debug. |
|
616 |
|
617 @param fn the filename to debug (string) |
|
618 @param argv the commandline arguments to pass to the program (string) |
|
619 @param wd the working directory for the program (string) |
|
620 @param env environment settings (string) |
|
621 @keyparam autoClearShell flag indicating, that the interpreter window should |
|
622 be cleared (boolean) |
|
623 @keyparam tracePython flag indicating if the Python library should be traced |
|
624 as well (boolean) |
|
625 @keyparam autoContinue flag indicating, that the debugger should not stop |
|
626 at the first executable line (boolean) |
|
627 @keyparam forProject flag indicating a project related action (boolean) |
|
628 @keyparam runInConsole flag indicating to start the debugger in a |
|
629 console window (boolean) |
|
630 @keyparam autoFork flag indicating the automatic fork mode (boolean) |
|
631 @keyparam forkChild flag indicating to debug the child after forking (boolean) |
|
632 """ |
|
633 self.__autoClearShell = autoClearShell |
|
634 self.__autoContinue = autoContinue |
|
635 |
|
636 # Restart the client |
|
637 try: |
|
638 self.__setClientType(self.__clientAssociations[os.path.splitext(fn)[1]]) |
|
639 except KeyError: |
|
640 self.__setClientType('Python') # assume it is a Python file |
|
641 self.startClient(False, forProject = forProject, runInConsole = runInConsole) |
|
642 |
|
643 self.remoteEnvironment(env) |
|
644 |
|
645 self.debuggerInterface.remoteLoad(fn, argv, wd, tracePython, autoContinue, |
|
646 autoFork, forkChild) |
|
647 self.debugging = True |
|
648 self.__restoreBreakpoints() |
|
649 self.__restoreWatchpoints() |
|
650 |
|
651 def remoteRun(self, fn, argv, wd, env, autoClearShell = True, |
|
652 forProject = False, runInConsole = False): |
|
653 """ |
|
654 Public method to load a new program to run. |
|
655 |
|
656 @param fn the filename to run (string) |
|
657 @param argv the commandline arguments to pass to the program (string) |
|
658 @param wd the working directory for the program (string) |
|
659 @param env environment settings (string) |
|
660 @keyparam autoClearShell flag indicating, that the interpreter window should |
|
661 be cleared (boolean) |
|
662 @keyparam forProject flag indicating a project related action (boolean) |
|
663 @keyparam runInConsole flag indicating to start the debugger in a |
|
664 console window (boolean) |
|
665 """ |
|
666 self.__autoClearShell = autoClearShell |
|
667 |
|
668 # Restart the client |
|
669 try: |
|
670 self.__setClientType(self.__clientAssociations[os.path.splitext(fn)[1]]) |
|
671 except KeyError: |
|
672 self.__setClientType('Python') # assume it is a Python file |
|
673 self.startClient(False, forProject = forProject, runInConsole = runInConsole) |
|
674 |
|
675 self.remoteEnvironment(env) |
|
676 |
|
677 self.debuggerInterface.remoteRun(fn, argv, wd) |
|
678 self.debugging = False |
|
679 |
|
680 def remoteCoverage(self, fn, argv, wd, env, autoClearShell = True, |
|
681 erase = False, forProject = False, runInConsole = False): |
|
682 """ |
|
683 Public method to load a new program to collect coverage data. |
|
684 |
|
685 @param fn the filename to run (string) |
|
686 @param argv the commandline arguments to pass to the program (string) |
|
687 @param wd the working directory for the program (string) |
|
688 @param env environment settings (string) |
|
689 @keyparam autoClearShell flag indicating, that the interpreter window should |
|
690 be cleared (boolean) |
|
691 @keyparam erase flag indicating that coverage info should be |
|
692 cleared first (boolean) |
|
693 @keyparam forProject flag indicating a project related action (boolean) |
|
694 @keyparam runInConsole flag indicating to start the debugger in a |
|
695 console window (boolean) |
|
696 """ |
|
697 self.__autoClearShell = autoClearShell |
|
698 |
|
699 # Restart the client |
|
700 try: |
|
701 self.__setClientType(self.__clientAssociations[os.path.splitext(fn)[1]]) |
|
702 except KeyError: |
|
703 self.__setClientType('Python') # assume it is a Python file |
|
704 self.startClient(False, forProject = forProject, runInConsole = runInConsole) |
|
705 |
|
706 self.remoteEnvironment(env) |
|
707 |
|
708 self.debuggerInterface.remoteCoverage(fn, argv, wd, erase) |
|
709 self.debugging = False |
|
710 |
|
711 def remoteProfile(self, fn, argv, wd, env, autoClearShell = True, |
|
712 erase = False, forProject = False, |
|
713 runInConsole = False): |
|
714 """ |
|
715 Public method to load a new program to collect profiling data. |
|
716 |
|
717 @param fn the filename to run (string) |
|
718 @param argv the commandline arguments to pass to the program (string) |
|
719 @param wd the working directory for the program (string) |
|
720 @param env environment settings (string) |
|
721 @keyparam autoClearShell flag indicating, that the interpreter window should |
|
722 be cleared (boolean) |
|
723 @keyparam erase flag indicating that timing info should be cleared first (boolean) |
|
724 @keyparam forProject flag indicating a project related action (boolean) |
|
725 @keyparam runInConsole flag indicating to start the debugger in a |
|
726 console window (boolean) |
|
727 """ |
|
728 self.__autoClearShell = autoClearShell |
|
729 |
|
730 # Restart the client |
|
731 try: |
|
732 self.__setClientType(self.__clientAssociations[os.path.splitext(fn)[1]]) |
|
733 except KeyError: |
|
734 self.__setClientType('Python') # assume it is a Python file |
|
735 self.startClient(False, forProject = forProject, runInConsole = runInConsole) |
|
736 |
|
737 self.remoteEnvironment(env) |
|
738 |
|
739 self.debuggerInterface.remoteProfile(fn, argv, wd, erase) |
|
740 self.debugging = False |
|
741 |
|
742 def remoteStatement(self, stmt): |
|
743 """ |
|
744 Public method to execute a Python statement. |
|
745 |
|
746 @param stmt the Python statement to execute (string). It |
|
747 should not have a trailing newline. |
|
748 """ |
|
749 self.debuggerInterface.remoteStatement(stmt) |
|
750 |
|
751 def remoteStep(self): |
|
752 """ |
|
753 Public method to single step the debugged program. |
|
754 """ |
|
755 self.debuggerInterface.remoteStep() |
|
756 |
|
757 def remoteStepOver(self): |
|
758 """ |
|
759 Public method to step over the debugged program. |
|
760 """ |
|
761 self.debuggerInterface.remoteStepOver() |
|
762 |
|
763 def remoteStepOut(self): |
|
764 """ |
|
765 Public method to step out the debugged program. |
|
766 """ |
|
767 self.debuggerInterface.remoteStepOut() |
|
768 |
|
769 def remoteStepQuit(self): |
|
770 """ |
|
771 Public method to stop the debugged program. |
|
772 """ |
|
773 self.debuggerInterface.remoteStepQuit() |
|
774 |
|
775 def remoteContinue(self, special = False): |
|
776 """ |
|
777 Public method to continue the debugged program. |
|
778 |
|
779 @param special flag indicating a special continue operation |
|
780 """ |
|
781 self.debuggerInterface.remoteContinue(special) |
|
782 |
|
783 def remoteBreakpoint(self, fn, line, set, cond=None, temp=False): |
|
784 """ |
|
785 Public method to set or clear a breakpoint. |
|
786 |
|
787 @param fn filename the breakpoint belongs to (string) |
|
788 @param line linenumber of the breakpoint (int) |
|
789 @param set flag indicating setting or resetting a breakpoint (boolean) |
|
790 @param cond condition of the breakpoint (string) |
|
791 @param temp flag indicating a temporary breakpoint (boolean) |
|
792 """ |
|
793 self.debuggerInterface.remoteBreakpoint(fn, line, set, cond, temp) |
|
794 |
|
795 def __remoteBreakpointEnable(self, fn, line, enable): |
|
796 """ |
|
797 Private method to enable or disable a breakpoint. |
|
798 |
|
799 @param fn filename the breakpoint belongs to (string) |
|
800 @param line linenumber of the breakpoint (int) |
|
801 @param enable flag indicating enabling or disabling a breakpoint (boolean) |
|
802 """ |
|
803 self.debuggerInterface.remoteBreakpointEnable(fn, line, enable) |
|
804 |
|
805 def __remoteBreakpointIgnore(self, fn, line, count): |
|
806 """ |
|
807 Private method to ignore a breakpoint the next couple of occurrences. |
|
808 |
|
809 @param fn filename the breakpoint belongs to (string) |
|
810 @param line linenumber of the breakpoint (int) |
|
811 @param count number of occurrences to ignore (int) |
|
812 """ |
|
813 self.debuggerInterface.remoteBreakpointIgnore(fn, line, count) |
|
814 |
|
815 def __remoteWatchpoint(self, cond, set, temp = False): |
|
816 """ |
|
817 Private method to set or clear a watch expression. |
|
818 |
|
819 @param cond expression of the watch expression (string) |
|
820 @param set flag indicating setting or resetting a watch expression (boolean) |
|
821 @param temp flag indicating a temporary watch expression (boolean) |
|
822 """ |
|
823 # cond is combination of cond and special (s. watch expression viewer) |
|
824 self.debuggerInterface.remoteWatchpoint(cond, set, temp) |
|
825 |
|
826 def __remoteWatchpointEnable(self, cond, enable): |
|
827 """ |
|
828 Private method to enable or disable a watch expression. |
|
829 |
|
830 @param cond expression of the watch expression (string) |
|
831 @param enable flag indicating enabling or disabling a watch expression (boolean) |
|
832 """ |
|
833 # cond is combination of cond and special (s. watch expression viewer) |
|
834 self.debuggerInterface.remoteWatchpointEnable(cond, enable) |
|
835 |
|
836 def __remoteWatchpointIgnore(self, cond, count): |
|
837 """ |
|
838 Private method to ignore a watch expression the next couple of occurrences. |
|
839 |
|
840 @param cond expression of the watch expression (string) |
|
841 @param count number of occurrences to ignore (int) |
|
842 """ |
|
843 # cond is combination of cond and special (s. watch expression viewer) |
|
844 self.debuggerInterface.remoteWatchpointIgnore(cond, count) |
|
845 |
|
846 def remoteRawInput(self,s): |
|
847 """ |
|
848 Public method to send the raw input to the debugged program. |
|
849 |
|
850 @param s the raw input (string) |
|
851 """ |
|
852 self.debuggerInterface.remoteRawInput(s) |
|
853 self.emit(SIGNAL('clientRawInputSent')) |
|
854 |
|
855 def remoteThreadList(self): |
|
856 """ |
|
857 Public method to request the list of threads from the client. |
|
858 """ |
|
859 self.debuggerInterface.remoteThreadList() |
|
860 |
|
861 def remoteSetThread(self, tid): |
|
862 """ |
|
863 Public method to request to set the given thread as current thread. |
|
864 |
|
865 @param tid id of the thread (integer) |
|
866 """ |
|
867 self.debuggerInterface.remoteSetThread(tid) |
|
868 |
|
869 def remoteClientVariables(self, scope, filter, framenr = 0): |
|
870 """ |
|
871 Public method to request the variables of the debugged program. |
|
872 |
|
873 @param scope the scope of the variables (0 = local, 1 = global) |
|
874 @param filter list of variable types to filter out (list of int) |
|
875 @param framenr framenumber of the variables to retrieve (int) |
|
876 """ |
|
877 self.debuggerInterface.remoteClientVariables(scope, filter, framenr) |
|
878 |
|
879 def remoteClientVariable(self, scope, filter, var, framenr = 0): |
|
880 """ |
|
881 Public method to request the variables of the debugged program. |
|
882 |
|
883 @param scope the scope of the variables (0 = local, 1 = global) |
|
884 @param filter list of variable types to filter out (list of int) |
|
885 @param var list encoded name of variable to retrieve (string) |
|
886 @param framenr framenumber of the variables to retrieve (int) |
|
887 """ |
|
888 self.debuggerInterface.remoteClientVariable(scope, filter, var, framenr) |
|
889 |
|
890 def remoteClientSetFilter(self, scope, filter): |
|
891 """ |
|
892 Public method to set a variables filter list. |
|
893 |
|
894 @param scope the scope of the variables (0 = local, 1 = global) |
|
895 @param filter regexp string for variable names to filter out (string) |
|
896 """ |
|
897 self.debuggerInterface.remoteClientSetFilter(scope, filter) |
|
898 |
|
899 def remoteEval(self, arg): |
|
900 """ |
|
901 Public method to evaluate arg in the current context of the debugged program. |
|
902 |
|
903 @param arg the arguments to evaluate (string) |
|
904 """ |
|
905 self.debuggerInterface.remoteEval(arg) |
|
906 |
|
907 def remoteExec(self, stmt): |
|
908 """ |
|
909 Public method to execute stmt in the current context of the debugged program. |
|
910 |
|
911 @param stmt statement to execute (string) |
|
912 """ |
|
913 self.debuggerInterface.remoteExec(stmt) |
|
914 |
|
915 def remoteBanner(self): |
|
916 """ |
|
917 Public slot to get the banner info of the remote client. |
|
918 """ |
|
919 self.debuggerInterface.remoteBanner() |
|
920 |
|
921 def remoteCapabilities(self): |
|
922 """ |
|
923 Public slot to get the debug clients capabilities. |
|
924 """ |
|
925 self.debuggerInterface.remoteCapabilities() |
|
926 |
|
927 def remoteCompletion(self, text): |
|
928 """ |
|
929 Public slot to get the a list of possible commandline completions |
|
930 from the remote client. |
|
931 |
|
932 @param text the text to be completed (string) |
|
933 """ |
|
934 self.debuggerInterface.remoteCompletion(text) |
|
935 |
|
936 def remoteUTPrepare(self, fn, tn, tfn, cov, covname, coverase): |
|
937 """ |
|
938 Public method to prepare a new unittest run. |
|
939 |
|
940 @param fn the filename to load (string) |
|
941 @param tn the testname to load (string) |
|
942 @param tfn the test function name to load tests from (string) |
|
943 @param cov flag indicating collection of coverage data is requested |
|
944 @param covname filename to be used to assemble the coverage caches |
|
945 filename (string) |
|
946 @param coverase flag indicating erasure of coverage data is requested (boolean) |
|
947 """ |
|
948 # Restart the client if there is already a program loaded. |
|
949 try: |
|
950 self.__setClientType(self.__clientAssociations[os.path.splitext(fn)[1]]) |
|
951 except KeyError: |
|
952 self.__setClientType('Python') # assume it is a Python file |
|
953 self.startClient(False) |
|
954 |
|
955 self.debuggerInterface.remoteUTPrepare(fn, tn, tfn, cov, covname, coverase) |
|
956 self.debugging = False |
|
957 |
|
958 def remoteUTRun(self): |
|
959 """ |
|
960 Public method to start a unittest run. |
|
961 """ |
|
962 self.debuggerInterface.remoteUTRun() |
|
963 |
|
964 def remoteUTStop(self): |
|
965 """ |
|
966 public method to stop a unittest run. |
|
967 """ |
|
968 self.debuggerInterface.remoteUTStop() |
|
969 |
|
970 def clientOutput(self, line): |
|
971 """ |
|
972 Public method to process a line of client output. |
|
973 |
|
974 @param line client output (string) |
|
975 """ |
|
976 self.emit(SIGNAL('clientOutput'), line) |
|
977 |
|
978 def clientLine(self, filename, lineno, forStack = False): |
|
979 """ |
|
980 Public method to process client position feedback. |
|
981 |
|
982 @param filename name of the file currently being executed (string) |
|
983 @param lineno line of code currently being executed (integer) |
|
984 @param forStack flag indicating this is for a stack dump (boolean) |
|
985 """ |
|
986 self.emit(SIGNAL('clientLine'), filename, lineno, forStack) |
|
987 |
|
988 def clientStack(self, stack): |
|
989 """ |
|
990 Public method to process a client's stack information. |
|
991 |
|
992 @param stack list of stack entries. Each entry is a tuple of three |
|
993 values giving the filename, linenumber and method |
|
994 (list of lists of (string, integer, string)) |
|
995 """ |
|
996 self.emit(SIGNAL('clientStack'), stack) |
|
997 |
|
998 def clientThreadList(self, currentId, threadList): |
|
999 """ |
|
1000 Public method to process the client thread list info. |
|
1001 |
|
1002 @param currentID id of the current thread (integer) |
|
1003 @param threadList list of dictionaries containing the thread data |
|
1004 """ |
|
1005 self.emit(SIGNAL('clientThreadList'), currentId, threadList) |
|
1006 |
|
1007 def clientThreadSet(self): |
|
1008 """ |
|
1009 Public method to handle the change of the client thread. |
|
1010 """ |
|
1011 self.emit(SIGNAL('clientThreadSet')) |
|
1012 |
|
1013 def clientVariables(self, scope, variables): |
|
1014 """ |
|
1015 Public method to process the client variables info. |
|
1016 |
|
1017 @param scope scope of the variables (-1 = empty global, 1 = global, 0 = local) |
|
1018 @param variables the list of variables from the client |
|
1019 """ |
|
1020 self.emit(SIGNAL('clientVariables'), scope, variables) |
|
1021 |
|
1022 def clientVariable(self, scope, variables): |
|
1023 """ |
|
1024 Public method to process the client variable info. |
|
1025 |
|
1026 @param scope scope of the variables (-1 = empty global, 1 = global, 0 = local) |
|
1027 @param variables the list of members of a classvariable from the client |
|
1028 """ |
|
1029 self.emit(SIGNAL('clientVariable'), scope, variables) |
|
1030 |
|
1031 def clientStatement(self, more): |
|
1032 """ |
|
1033 Public method to process the input response from the client. |
|
1034 |
|
1035 @param more flag indicating that more user input is required |
|
1036 """ |
|
1037 self.emit(SIGNAL('clientStatement'), more) |
|
1038 |
|
1039 def clientException(self, exceptionType, exceptionMessage, stackTrace): |
|
1040 """ |
|
1041 Public method to process the exception info from the client. |
|
1042 |
|
1043 @param exceptionType type of exception raised (string) |
|
1044 @param exceptionMessage message given by the exception (string) |
|
1045 @param stackTrace list of stack entries with the exception position |
|
1046 first. Each stack entry is a list giving the filename and the linenumber. |
|
1047 """ |
|
1048 self.emit(SIGNAL('clientException'), exceptionType, exceptionMessage, stackTrace) |
|
1049 |
|
1050 def clientSyntaxError(self, message, filename, lineNo, characterNo): |
|
1051 """ |
|
1052 Public method to process the syntax error info from the client. |
|
1053 |
|
1054 @param message message of the syntax error (string) |
|
1055 @param filename translated filename of the syntax error position (string) |
|
1056 @param lineNo line number of the syntax error position (integer) |
|
1057 @param characterNo character number of the syntax error position (integer) |
|
1058 """ |
|
1059 self.emit(SIGNAL('clientSyntaxError'), message, filename, lineNo, characterNo) |
|
1060 |
|
1061 def clientExit(self, status): |
|
1062 """ |
|
1063 Public method to process the client exit status. |
|
1064 |
|
1065 @param status exit code as a string (string) |
|
1066 """ |
|
1067 if self.passive: |
|
1068 self.__passiveShutDown() |
|
1069 self.emit(SIGNAL('clientExit(int)'), int(status)) |
|
1070 if Preferences.getDebugger("AutomaticReset"): |
|
1071 self.startClient(False) |
|
1072 if self.passive: |
|
1073 self.__createDebuggerInterface("None") |
|
1074 self.clientOutput(self.trUtf8('\nNot connected\n')) |
|
1075 self.clientStatement(False) |
|
1076 |
|
1077 def clientClearBreak(self, filename, lineno): |
|
1078 """ |
|
1079 Public method to process the client clear breakpoint command. |
|
1080 |
|
1081 @param filename filename of the breakpoint (string) |
|
1082 @param lineno line umber of the breakpoint (integer) |
|
1083 """ |
|
1084 self.emit(SIGNAL('clientClearBreak'), filename, lineno) |
|
1085 |
|
1086 def clientBreakConditionError(self, filename, lineno): |
|
1087 """ |
|
1088 Public method to process the client breakpoint condition error info. |
|
1089 |
|
1090 @param filename filename of the breakpoint (string) |
|
1091 @param lineno line umber of the breakpoint (integer) |
|
1092 """ |
|
1093 self.emit(SIGNAL('clientBreakConditionError'), filename, lineno) |
|
1094 |
|
1095 def clientClearWatch(self, condition): |
|
1096 """ |
|
1097 Public slot to handle the clientClearWatch signal. |
|
1098 |
|
1099 @param condition expression of watch expression to clear (string) |
|
1100 """ |
|
1101 self.emit(SIGNAL('clientClearWatch'), condition) |
|
1102 |
|
1103 def clientWatchConditionError(self, condition): |
|
1104 """ |
|
1105 Public method to process the client watch expression error info. |
|
1106 |
|
1107 @param condition expression of watch expression to clear (string) |
|
1108 """ |
|
1109 self.emit(SIGNAL('clientWatchConditionError'), condition) |
|
1110 |
|
1111 def clientRawInput(self, prompt, echo): |
|
1112 """ |
|
1113 Public method to process the client raw input command. |
|
1114 |
|
1115 @param prompt the input prompt (string) |
|
1116 @param echo flag indicating an echoing of the input (boolean) |
|
1117 """ |
|
1118 self.emit(SIGNAL('clientRawInput'), prompt, echo) |
|
1119 |
|
1120 def clientBanner(self, version, platform, debugClient): |
|
1121 """ |
|
1122 Public method to process the client banner info. |
|
1123 |
|
1124 @param version interpreter version info (string) |
|
1125 @param platform hostname of the client (string) |
|
1126 @param debugClient additional debugger type info (string) |
|
1127 """ |
|
1128 self.emit(SIGNAL('clientBanner'), version, platform, debugClient) |
|
1129 |
|
1130 def clientCapabilities(self, capabilities, clientType): |
|
1131 """ |
|
1132 Public method to process the client capabilities info. |
|
1133 |
|
1134 @param capabilities bitmaks with the client capabilities (integer) |
|
1135 @param clientType type of the debug client (string) |
|
1136 """ |
|
1137 self.__clientCapabilities[clientType] = capabilities |
|
1138 self.emit(SIGNAL('clientCapabilities'), capabilities, clientType) |
|
1139 |
|
1140 def clientCompletionList(self, completionList, text): |
|
1141 """ |
|
1142 Public method to process the client auto completion info. |
|
1143 |
|
1144 @param completionList list of possible completions (list of strings) |
|
1145 @param text the text to be completed (string) |
|
1146 """ |
|
1147 self.emit(SIGNAL('clientCompletionList'), completionList, text) |
|
1148 |
|
1149 def clientUtPrepared(self, result, exceptionType, exceptionValue): |
|
1150 """ |
|
1151 Public method to process the client unittest prepared info. |
|
1152 |
|
1153 @param result number of test cases (0 = error) (integer) |
|
1154 @param exceptionType exception type (string) |
|
1155 @param exceptionValue exception message (string) |
|
1156 """ |
|
1157 self.emit(SIGNAL('utPrepared'), result, exceptionType, exceptionValue) |
|
1158 |
|
1159 def clientUtStartTest(self, testname, doc): |
|
1160 """ |
|
1161 Public method to process the client start test info. |
|
1162 |
|
1163 @param testname name of the test (string) |
|
1164 @param doc short description of the test (string) |
|
1165 """ |
|
1166 self.emit(SIGNAL('utStartTest'), testname, doc) |
|
1167 |
|
1168 def clientUtStopTest(self): |
|
1169 """ |
|
1170 Public method to process the client stop test info. |
|
1171 """ |
|
1172 self.emit(SIGNAL('utStopTest')) |
|
1173 |
|
1174 def clientUtTestFailed(self, testname, traceback): |
|
1175 """ |
|
1176 Public method to process the client test failed info. |
|
1177 |
|
1178 @param testname name of the test (string) |
|
1179 @param traceback lines of traceback info (string) |
|
1180 """ |
|
1181 self.emit(SIGNAL('utTestFailed'), testname, traceback) |
|
1182 |
|
1183 def clientUtTestErrored(self, testname, traceback): |
|
1184 """ |
|
1185 Public method to process the client test errored info. |
|
1186 |
|
1187 @param testname name of the test (string) |
|
1188 @param traceback lines of traceback info (string) |
|
1189 """ |
|
1190 self.emit(SIGNAL('utTestErrored'), testname, traceback) |
|
1191 |
|
1192 def clientUtFinished(self): |
|
1193 """ |
|
1194 Public method to process the client unit test finished info. |
|
1195 """ |
|
1196 self.emit(SIGNAL('utFinished')) |
|
1197 |
|
1198 def passiveStartUp(self, fn, exc): |
|
1199 """ |
|
1200 Public method to handle a passive debug connection. |
|
1201 |
|
1202 @param fn filename of the debugged script (string) |
|
1203 @param exc flag to enable exception reporting of the IDE (boolean) |
|
1204 """ |
|
1205 print self.trUtf8("Passive debug connection received") |
|
1206 self.passiveClientExited = False |
|
1207 self.debugging = True |
|
1208 self.__restoreBreakpoints() |
|
1209 self.__restoreWatchpoints() |
|
1210 self.emit(SIGNAL('passiveDebugStarted'), fn, exc) |
|
1211 |
|
1212 def __passiveShutDown(self): |
|
1213 """ |
|
1214 Private method to shut down a passive debug connection. |
|
1215 """ |
|
1216 self.passiveClientExited = True |
|
1217 self.shutdownServer() |
|
1218 print self.trUtf8("Passive debug connection closed") |
|
1219 |
|
1220 def __restoreBreakpoints(self): |
|
1221 """ |
|
1222 Private method to restore the breakpoints after a restart. |
|
1223 """ |
|
1224 if self.debugging: |
|
1225 self.__addBreakPoints(QModelIndex(), 0, self.breakpointModel.rowCount()-1) |
|
1226 |
|
1227 def __restoreWatchpoints(self): |
|
1228 """ |
|
1229 Private method to restore the watch expressions after a restart. |
|
1230 """ |
|
1231 if self.debugging: |
|
1232 self.__addWatchPoints(QModelIndex(), 0, self.watchpointModel.rowCount()-1) |
|
1233 |
|
1234 def getBreakPointModel(self): |
|
1235 """ |
|
1236 Public slot to get a reference to the breakpoint model object. |
|
1237 |
|
1238 @return reference to the breakpoint model object (BreakPointModel) |
|
1239 """ |
|
1240 return self.breakpointModel |
|
1241 |
|
1242 def getWatchPointModel(self): |
|
1243 """ |
|
1244 Public slot to get a reference to the watch expression model object. |
|
1245 |
|
1246 @return reference to the watch expression model object (WatchPointModel) |
|
1247 """ |
|
1248 return self.watchpointModel |
|
1249 |
|
1250 def isConnected(self): |
|
1251 """ |
|
1252 Public method to test, if the debug server is connected to a backend. |
|
1253 |
|
1254 @return flag indicating a connection (boolean) |
|
1255 """ |
|
1256 return self.debuggerInterface and self.debuggerInterface.isConnected() |