Debugger/DebugServer.py

branch
Py2 comp.
changeset 3484
645c12de6b0c
parent 3178
f25fc1364c88
parent 3357
2390df6f42ba
child 3649
2456f04f60a8
equal deleted inserted replaced
3456:96232974dcdb 3484:645c12de6b0c
7 Module implementing the debug server. 7 Module implementing the debug server.
8 """ 8 """
9 9
10 from __future__ import unicode_literals 10 from __future__ import unicode_literals
11 try: 11 try:
12 str = unicode # __IGNORE_WARNING__ 12 str = unicode
13 except (NameError): 13 except NameError:
14 pass 14 pass
15 15
16 import os 16 import os
17 17
18 from PyQt4.QtCore import pyqtSignal, QModelIndex 18 from PyQt4.QtCore import pyqtSignal, QModelIndex
88 received from the client 88 received from the client
89 @signal passiveDebugStarted(str, bool) emitted after the debug client has 89 @signal passiveDebugStarted(str, bool) emitted after the debug client has
90 connected in passive debug mode 90 connected in passive debug mode
91 @signal clientGone(bool) emitted if the client went away (planned or 91 @signal clientGone(bool) emitted if the client went away (planned or
92 unplanned) 92 unplanned)
93 @signal clientInterpreterChanged(str) emitted to signal a change of the
94 client interpreter
93 @signal utPrepared(nrTests, exc_type, exc_value) emitted after the client 95 @signal utPrepared(nrTests, exc_type, exc_value) emitted after the client
94 has loaded a unittest suite 96 has loaded a unittest suite
95 @signal utFinished() emitted after the client signalled the end of the 97 @signal utFinished() emitted after the client signalled the end of the
96 unittest 98 unittest
97 @signal utStartTest(testname, testdocu) emitted after the client has 99 @signal utStartTest(testname, testdocu) emitted after the client has
132 clientWatchConditionError = pyqtSignal(str) 134 clientWatchConditionError = pyqtSignal(str)
133 clientRawInput = pyqtSignal(str, bool) 135 clientRawInput = pyqtSignal(str, bool)
134 clientBanner = pyqtSignal(str, str, str) 136 clientBanner = pyqtSignal(str, str, str)
135 clientCapabilities = pyqtSignal(int, str) 137 clientCapabilities = pyqtSignal(int, str)
136 clientCompletionList = pyqtSignal(list, str) 138 clientCompletionList = pyqtSignal(list, str)
139 clientInterpreterChanged = pyqtSignal(str)
137 utPrepared = pyqtSignal(int, str, str) 140 utPrepared = pyqtSignal(int, str, str)
138 utStartTest = pyqtSignal(str, str) 141 utStartTest = pyqtSignal(str, str)
139 utStopTest = pyqtSignal() 142 utStopTest = pyqtSignal()
140 utTestFailed = pyqtSignal(str, str, str) 143 utTestFailed = pyqtSignal(str, str, str)
141 utTestErrored = pyqtSignal(str, str, str) 144 utTestErrored = pyqtSignal(str, str, str)
154 157
155 # create our models 158 # create our models
156 self.breakpointModel = BreakPointModel(self) 159 self.breakpointModel = BreakPointModel(self)
157 self.watchpointModel = WatchPointModel(self) 160 self.watchpointModel = WatchPointModel(self)
158 self.watchSpecialCreated = \ 161 self.watchSpecialCreated = \
159 self.trUtf8("created", "must be same as in EditWatchpointDialog") 162 self.tr("created", "must be same as in EditWatchpointDialog")
160 self.watchSpecialChanged = \ 163 self.watchSpecialChanged = \
161 self.trUtf8("changed", "must be same as in EditWatchpointDialog") 164 self.tr("changed", "must be same as in EditWatchpointDialog")
162 165
163 self.networkInterface = Preferences.getDebugger("NetworkInterface") 166 self.networkInterface = Preferences.getDebugger("NetworkInterface")
164 if self.networkInterface == "all": 167 if self.networkInterface == "all":
165 hostAddress = QHostAddress("0.0.0.0") # QHostAddress.Any) 168 hostAddress = QHostAddress("0.0.0.0") # QHostAddress.Any)
166 elif self.networkInterface == "allv6": 169 elif self.networkInterface == "allv6":
183 186
184 self.debuggerInterface = None 187 self.debuggerInterface = None
185 self.debugging = False 188 self.debugging = False
186 self.running = False 189 self.running = False
187 self.clientProcess = None 190 self.clientProcess = None
188 191 self.clientInterpreter = ""
189 self.clientType = \ 192 self.clientType = \
190 Preferences.Prefs.settings.value('DebugClient/Type') 193 Preferences.Prefs.settings.value('DebugClient/Type')
191 if self.clientType is None: 194 if self.clientType is None:
192 import sys 195 import sys
193 if sys.version_info[0] == 2: 196 if sys.version_info[0] == 2:
206 self.lastClientType = '' 209 self.lastClientType = ''
207 self.__autoClearShell = False 210 self.__autoClearShell = False
208 211
209 self.clientClearBreak.connect(self.__clientClearBreakPoint) 212 self.clientClearBreak.connect(self.__clientClearBreakPoint)
210 self.clientClearWatch.connect(self.__clientClearWatchPoint) 213 self.clientClearWatch.connect(self.__clientClearWatchPoint)
211 self.newConnection[()].connect(self.__newConnection) 214 self.newConnection.connect(self.__newConnection)
212 215
213 self.breakpointModel.rowsAboutToBeRemoved.connect( 216 self.breakpointModel.rowsAboutToBeRemoved.connect(
214 self.__deleteBreakPoints) 217 self.__deleteBreakPoints)
215 self.breakpointModel.dataAboutToBeChanged.connect( 218 self.breakpointModel.dataAboutToBeChanged.connect(
216 self.__breakPointDataAboutToBeChanged) 219 self.__breakPointDataAboutToBeChanged)
407 410
408 self.__createDebuggerInterface() 411 self.__createDebuggerInterface()
409 if forProject: 412 if forProject:
410 project = e5App().getObject("Project") 413 project = e5App().getObject("Project")
411 if not project.isDebugPropertiesLoaded(): 414 if not project.isDebugPropertiesLoaded():
412 self.clientProcess, isNetworked = \ 415 self.clientProcess, isNetworked, clientInterpreter = \
413 self.debuggerInterface.startRemote(self.serverPort(), 416 self.debuggerInterface.startRemote(self.serverPort(),
414 runInConsole) 417 runInConsole)
415 else: 418 else:
416 self.clientProcess, isNetworked = \ 419 self.clientProcess, isNetworked, clientInterpreter = \
417 self.debuggerInterface.startRemoteForProject( 420 self.debuggerInterface.startRemoteForProject(
418 self.serverPort(), runInConsole) 421 self.serverPort(), runInConsole)
419 else: 422 else:
420 self.clientProcess, isNetworked = \ 423 self.clientProcess, isNetworked, clientInterpreter = \
421 self.debuggerInterface.startRemote( 424 self.debuggerInterface.startRemote(
422 self.serverPort(), runInConsole) 425 self.serverPort(), runInConsole)
423 426
424 if self.clientProcess: 427 if self.clientProcess:
425 self.clientProcess.readyReadStandardError.connect( 428 self.clientProcess.readyReadStandardError.connect(
426 self.__clientProcessError) 429 self.__clientProcessError)
427 self.clientProcess.readyReadStandardOutput.connect( 430 self.clientProcess.readyReadStandardOutput.connect(
428 self.__clientProcessOutput) 431 self.__clientProcessOutput)
429 432
430 if not isNetworked: 433 # Perform actions necessary, if client type has changed
431 # the client is connected through stdin and stdout 434 if self.lastClientType != self.clientType:
432 # Perform actions necessary, if client type has changed 435 self.lastClientType = self.clientType
433 if self.lastClientType != self.clientType: 436 self.remoteBanner()
434 self.lastClientType = self.clientType 437 elif self.__autoClearShell:
435 self.remoteBanner() 438 self.__autoClearShell = False
436 elif self.__autoClearShell: 439 self.remoteBanner()
437 self.__autoClearShell = False 440 else:
438 self.remoteBanner() 441 if clType and self.lastClientType:
439 442 self.__setClientType(self.lastClientType)
440 self.debuggerInterface.flush()
441 else: 443 else:
442 self.__createDebuggerInterface("None") 444 self.__createDebuggerInterface("None")
445 clientInterpreter = ""
446
447 if clientInterpreter != self.clientInterpreter:
448 self.clientInterpreter = clientInterpreter
449 self.clientInterpreterChanged.emit(clientInterpreter)
443 450
444 def __clientProcessOutput(self): 451 def __clientProcessOutput(self):
445 """ 452 """
446 Private slot to process client output received via stdout. 453 Private slot to process client output received via stdout.
447 """ 454 """
644 try: 651 try:
645 return self.__clientCapabilities[type] 652 return self.__clientCapabilities[type]
646 except KeyError: 653 except KeyError:
647 return 0 # no capabilities 654 return 0 # no capabilities
648 655
656 def getClientInterpreter(self):
657 """
658 Public method to get the interpreter of the debug client.
659
660 @return interpreter of the debug client (string)
661 """
662 return self.clientInterpreter
663
649 def __newConnection(self): 664 def __newConnection(self):
650 """ 665 """
651 Private slot to handle a new connection. 666 Private slot to handle a new connection.
652 """ 667 """
653 sock = self.nextPendingConnection() 668 sock = self.nextPendingConnection()
654 peerAddress = sock.peerAddress().toString() 669 peerAddress = sock.peerAddress().toString()
655 if peerAddress not in Preferences.getDebugger("AllowedHosts"): 670 if peerAddress not in Preferences.getDebugger("AllowedHosts"):
656 # the peer is not allowed to connect 671 # the peer is not allowed to connect
657 res = E5MessageBox.yesNo( 672 res = E5MessageBox.yesNo(
658 None, 673 None,
659 self.trUtf8("Connection from illegal host"), 674 self.tr("Connection from illegal host"),
660 self.trUtf8( 675 self.tr(
661 """<p>A connection was attempted by the illegal host""" 676 """<p>A connection was attempted by the illegal host"""
662 """ <b>{0}</b>. Accept this connection?</p>""") 677 """ <b>{0}</b>. Accept this connection?</p>""")
663 .format(peerAddress), 678 .format(peerAddress),
664 icon=E5MessageBox.Warning) 679 icon=E5MessageBox.Warning)
665 if not res: 680 if not res:
1254 self.clientExit.emit(int(status)) 1269 self.clientExit.emit(int(status))
1255 if Preferences.getDebugger("AutomaticReset"): 1270 if Preferences.getDebugger("AutomaticReset"):
1256 self.startClient(False) 1271 self.startClient(False)
1257 if self.passive: 1272 if self.passive:
1258 self.__createDebuggerInterface("None") 1273 self.__createDebuggerInterface("None")
1259 self.signalClientOutput(self.trUtf8('\nNot connected\n')) 1274 self.signalClientOutput(self.tr('\nNot connected\n'))
1260 self.signalClientStatement(False) 1275 self.signalClientStatement(False)
1261 self.running = False 1276 self.running = False
1262 1277
1263 def signalClientClearBreak(self, filename, lineno): 1278 def signalClientClearBreak(self, filename, lineno):
1264 """ 1279 """
1434 Public method to handle a passive debug connection. 1449 Public method to handle a passive debug connection.
1435 1450
1436 @param fn filename of the debugged script (string) 1451 @param fn filename of the debugged script (string)
1437 @param exc flag to enable exception reporting of the IDE (boolean) 1452 @param exc flag to enable exception reporting of the IDE (boolean)
1438 """ 1453 """
1439 print(self.trUtf8("Passive debug connection received")) 1454 print(self.tr("Passive debug connection received"))
1440 self.passiveClientExited = False 1455 self.passiveClientExited = False
1441 self.debugging = True 1456 self.debugging = True
1442 self.running = True 1457 self.running = True
1443 self.__restoreBreakpoints() 1458 self.__restoreBreakpoints()
1444 self.__restoreWatchpoints() 1459 self.__restoreWatchpoints()
1448 """ 1463 """
1449 Private method to shut down a passive debug connection. 1464 Private method to shut down a passive debug connection.
1450 """ 1465 """
1451 self.passiveClientExited = True 1466 self.passiveClientExited = True
1452 self.shutdownServer() 1467 self.shutdownServer()
1453 print(self.trUtf8("Passive debug connection closed")) 1468 print(self.tr("Passive debug connection closed"))
1454 1469
1455 def __restoreBreakpoints(self): 1470 def __restoreBreakpoints(self):
1456 """ 1471 """
1457 Private method to restore the breakpoints after a restart. 1472 Private method to restore the breakpoints after a restart.
1458 """ 1473 """

eric ide

mercurial