Sat, 03 Sep 2016 18:02:37 +0200
Ported the debugger modernization changes to the Python 2 debugger.
--- a/DebugClients/Python/AsyncFile.py Sat Sep 03 18:01:19 2016 +0200 +++ b/DebugClients/Python/AsyncFile.py Sat Sep 03 18:02:37 2016 +0200 @@ -10,7 +10,7 @@ import socket -from DebugProtocol import EOT +from DebugUtilities import prepareJsonCommand def AsyncPendingWrite(file): @@ -44,7 +44,7 @@ @param name name of this file (string) """ # Initialise the attributes. - self.closed = 0 + self.closed = False self.sock = sock self.mode = mode self.name = name @@ -74,9 +74,9 @@ """ if n: try: - buf = "%s%s" % (self.wpending[:n], EOT) + buf = self.wpending[:n] try: - buf = buf.encode('utf-8') + buf = buf.encode('utf-8', 'backslashreplace') except (UnicodeEncodeError, UnicodeDecodeError): pass self.sock.sendall(buf) @@ -95,7 +95,7 @@ """ return self.wpending.rfind('\n') + 1 - def close(self, closeit=0): + def close(self, closeit=False): """ Public method to close the file. @@ -105,7 +105,7 @@ if closeit and not self.closed: self.flush() self.sock.close() - self.closed = 1 + self.closed = True def flush(self): """ @@ -119,7 +119,7 @@ @return always false """ - return 0 + return False def fileno(self): """ @@ -132,6 +132,14 @@ except socket.error: return -1 + def readable(self): + """ + Public method to check, if the stream is readable. + + @return flag indicating a readable stream (boolean) + """ + return self.mode == "r" + def read_p(self, size=-1): """ Public method to read bytes from this file. @@ -144,7 +152,7 @@ if size < 0: size = 20000 - return self.sock.recv(size).decode('utf8') + return self.sock.recv(size).decode('utf8', 'backslashreplace') def read(self, size=-1): """ @@ -181,7 +189,7 @@ # read a line at a time. line = self.sock.recv(size, socket.MSG_PEEK) - eol = line.find('\n') + eol = line.find(b'\n') if eol >= 0: size = eol + 1 @@ -189,7 +197,7 @@ size = len(line) # Now we know how big the line is, read it for real. - return self.sock.recv(size).decode('utf8') + return self.sock.recv(size).decode('utf8', 'backslashreplace') def readlines(self, sizehint=-1): """ @@ -234,6 +242,14 @@ line = line[:sizehint] return line + def seekable(self): + """ + Public method to check, if the stream is seekable. + + @return flag indicating a seekable stream (boolean) + """ + return False + def seek(self, offset, whence=0): """ Public method to move the filepointer. @@ -264,21 +280,40 @@ """ raise IOError('[Errno 29] Illegal seek') + def writable(self): + """ + Public method to check, if a stream is writable. + + @return flag indicating a writable stream (boolean) + """ + return self.mode == "w" + def write(self, s): """ Public method to write a string to the file. @param s bytes to be written (string) + """ + self.__checkMode('w') + + cmd = prepareJsonCommand("ClientOutput", { + "text": s, + }) + self.write_p(cmd) + + def write_p(self, s): + """ + Public method to write a string to the file. + + @param s text to be written (string) @exception socket.error raised to indicate too many send attempts """ self.__checkMode('w') tries = 0 if not self.wpending: self.wpending = s - elif type(self.wpending) != type(s) or \ - len(self.wpending) + len(s) > self.maxbuffersize: - # flush wpending so that different string types are not - # concatenated + elif len(self.wpending) + len(s) > self.maxbuffersize: + # flush wpending if it is too big while self.wpending: # if we have a persistent error in sending the data, an # exception will be raised in __nWrite @@ -291,13 +326,13 @@ self.wpending += s self.__nWrite(self.pendingWrite()) - def writelines(self, list): + def writelines(self, lines): """ Public method to write a list of strings to the file. - @param list the list to be written (list of string) + @param lines list of texts to be written (list of string) """ - map(self.write, list) + self.write("".join(lines)) # # eflag: FileType = Python2
--- a/DebugClients/Python/AsyncIO.py Sat Sep 03 18:01:19 2016 +0200 +++ b/DebugClients/Python/AsyncIO.py Sat Sep 03 18:02:37 2016 +0200 @@ -7,7 +7,7 @@ Module implementing a base class of an asynchronous interface for the debugger. """ - +# TODO: delete this file class AsyncIO(object): """ Class implementing asynchronous reading and writing.
--- a/DebugClients/Python/DCTestResult.py Sat Sep 03 18:01:19 2016 +0200 +++ b/DebugClients/Python/DCTestResult.py Sat Sep 03 18:02:37 2016 +0200 @@ -11,25 +11,21 @@ from unittest import TestResult -from DebugProtocol import ResponseUTTestFailed, ResponseUTTestErrored, \ - ResponseUTStartTest, ResponseUTStopTest, ResponseUTTestSkipped, \ - ResponseUTTestFailedExpected, ResponseUTTestSucceededUnexpected - - class DCTestResult(TestResult): """ A TestResult derivative to work with eric6's debug client. For more details see unittest.py of the standard python distribution. """ - def __init__(self, parent): + def __init__(self, dbgClient): """ Constructor - @param parent The parent widget. + @param dbgClient reference to the debug client + @type DebugClientBase """ TestResult.__init__(self) - self.parent = parent + self.__dbgClient = dbgClient def addFailure(self, test, err): """ @@ -40,10 +36,11 @@ """ TestResult.addFailure(self, test, err) tracebackLines = self._exc_info_to_string(err, test) - self.parent.write( - '%s%s\n' % ( - ResponseUTTestFailed, - unicode((unicode(test), tracebackLines, test.id())))) + self.__dbgClient.sendJsonCommand("ResponseUTTestFailed", { + "testname": str(test), + "traceback": tracebackLines, + "id": test.id(), + }) def addError(self, test, err): """ @@ -54,10 +51,11 @@ """ TestResult.addError(self, test, err) tracebackLines = self._exc_info_to_string(err, test) - self.parent.write( - '%s%s\n' % ( - ResponseUTTestErrored, - unicode((unicode(test), tracebackLines, test.id())))) + self.__dbgClient.sendJsonCommand("ResponseUTTestErrored", { + "testname": str(test), + "traceback": tracebackLines, + "id": test.id(), + }) def addSkip(self, test, reason): """ @@ -67,10 +65,11 @@ @param reason reason for skipping the test (string) """ TestResult.addSkip(self, test, reason) - self.parent.write( - '%s%s\n' % ( - ResponseUTTestSkipped, - str((str(test), reason, test.id())))) + self.__dbgClient.sendJsonCommand("ResponseUTTestSkipped", { + "testname": str(test), + "reason": reason, + "id": test.id(), + }) def addExpectedFailure(self, test, err): """ @@ -81,10 +80,11 @@ """ TestResult.addExpectedFailure(self, test, err) tracebackLines = self._exc_info_to_string(err, test) - self.parent.write( - '%s%s\n' % ( - ResponseUTTestFailedExpected, - str((str(test), tracebackLines, test.id())))) + self.__dbgClient.sendJsonCommand("ResponseUTTestFailedExpected", { + "testname": str(test), + "traceback": tracebackLines, + "id": test.id(), + }) def addUnexpectedSuccess(self, test): """ @@ -93,10 +93,10 @@ @param test reference to the test object """ TestResult.addUnexpectedSuccess(self, test) - self.parent.write( - '%s%s\n' % ( - ResponseUTTestSucceededUnexpected, - str((str(test), test.id())))) + self.__dbgClient.sendJsonCommand("ResponseUTTestSucceededUnexpected", { + "testname": str(test), + "id": test.id(), + }) def startTest(self, test): """ @@ -105,10 +105,10 @@ @param test Reference to the test object """ TestResult.startTest(self, test) - self.parent.write( - '%s%s\n' % ( - ResponseUTStartTest, - unicode((unicode(test), test.shortDescription())))) + self.__dbgClient.sendJsonCommand("ResponseUTStartTest", { + "testname": str(test), + "description": test.shortDescription(), + }) def stopTest(self, test): """ @@ -117,14 +117,14 @@ @param test Reference to the test object """ TestResult.stopTest(self, test) - self.parent.write('%s\n' % ResponseUTStopTest) + self.__dbgClient.sendJsonCommand("ResponseUTStopTest", {}) # ensure that pending input is processed - rrdy, wrdy, xrdy = select.select([self.parent.readstream], [], [], - 0.01) + rrdy, wrdy, xrdy = select.select( + [self.__dbgClient.readstream], [], [], 0.01) - if self.parent.readstream in rrdy: - self.parent.readReady(self.parent.readstream.fileno()) + if self.__dbgClient.readstream in rrdy: + self.__dbgClient.readReady(self.__dbgClient.readstream) # # eflag: FileType = Python2
--- a/DebugClients/Python/DebugBase.py Sat Sep 03 18:01:19 2016 +0200 +++ b/DebugClients/Python/DebugBase.py Sat Sep 03 18:02:37 2016 +0200 @@ -14,9 +14,7 @@ import atexit import inspect import ctypes - -from DebugProtocol import ResponseClearWatch, ResponseClearBreak, \ - ResponseLine, ResponseSyntax, ResponseException, CallTrace +from inspect import CO_GENERATOR gRecursionLimit = 64 @@ -57,7 +55,7 @@ bdb.Bdb.__init__(self) self._dbgClient = dbgClient - self._mainThread = 1 + self._mainThread = True self.breaks = self._dbgClient.breakpoints @@ -200,6 +198,7 @@ if not self.__skip_it(fromFrame) and not self.__skip_it(toFrame): if event in ["call", "return"]: fr = fromFrame + # TODO: change from and to info to a dictionary fromStr = "%s:%s:%s" % ( self._dbgClient.absPath(self.fix_frame_filename(fr)), fr.f_lineno, @@ -209,8 +208,7 @@ self._dbgClient.absPath(self.fix_frame_filename(fr)), fr.f_lineno, fr.f_code.co_name) - self._dbgClient.write("%s%s@@%s@@%s\n" % ( - CallTrace, event[0], fromStr, toStr)) + self._dbgClient.sendCallTrace(event, fromStr, toStr) def trace_dispatch(self, frame, event, arg): """ @@ -279,6 +277,9 @@ @exception bdb.BdbQuit raised to indicate the end of the debug session """ if self.stop_here(frame) or frame == self.returnframe: + # Ignore return events in generator except when stepping. + if self.stopframe and frame.f_code.co_flags & CO_GENERATOR: + return self.trace_dispatch self.user_return(frame, arg) if self.quitting and not self._dbgClient.passive: raise bdb.BdbQuit @@ -294,9 +295,27 @@ @exception bdb.BdbQuit raised to indicate the end of the debug session """ if not self.__skip_it(frame): + # When stepping with next/until/return in a generator frame, + # skip the internal StopIteration exception (with no traceback) + # triggered by a subiterator run with the 'yield from' + # statement. + if not (frame.f_code.co_flags & CO_GENERATOR and + arg[0] is StopIteration and arg[2] is None): + self.user_exception(frame, arg) + if self.quitting: + raise bdb.BdbQuit + + # Stop at the StopIteration or GeneratorExit exception when the user + # has set stopframe in a generator by issuing a return command, or a + # next/until command at the last statement in the generator before the + # exception. + elif (self.stopframe and frame is not self.stopframe and + self.stopframe.f_code.co_flags & CO_GENERATOR and + arg[0] in (StopIteration, GeneratorExit)): self.user_exception(frame, arg) if self.quitting: raise bdb.BdbQuit + return self.trace_dispatch def set_trace(self, frame=None): @@ -318,9 +337,9 @@ # Modified version of the one found in bdb.py # Here we only set a new stop frame if it is a normal continue. if not special: - self.stopframe = self.botframe - self.returnframe = None - self.quitting = 0 + self._set_stopinfo(self.botframe, None) + else: + self._set_stopinfo(self.stopframe, None) def set_quit(self): """ @@ -355,10 +374,14 @@ frame.f_globals['__file__'] and \ frame.f_globals['__file__'] == frame.f_code.co_filename: root, ext = os.path.splitext(frame.f_globals['__file__']) - if ext == '.pyc' or ext == '.py' or ext == '.pyo': + if ext in ['.pyc', '.py', '.py2', '.pyo']: fixedName = root + '.py' if os.path.exists(fixedName): return fixedName + + fixedName = root + '.py2' + if os.path.exists(fixedName): + return fixedName return frame.f_code.co_filename @@ -420,7 +443,7 @@ @param cond expression of the watch expression to be cleared (string) """ self.clear_watch(cond) - self._dbgClient.write('%s%s\n' % (ResponseClearWatch, cond)) + self._dbgClient.sendClearTemporaryWatch(cond) def __effective(self, frame): """ @@ -446,7 +469,7 @@ if b.values[frame][0] == 0: b.values[frame][0] = 1 b.values[frame][1] = val - return (b, 1) + return (b, True) else: continue b.values[frame][0] = 1 @@ -457,7 +480,7 @@ b.values[frame][2] -= 1 continue else: - return (b, 1) + return (b, True) else: continue continue @@ -474,7 +497,7 @@ except KeyError: b.values[frame] = [0, None, b.ignore] continue - return (None, None) + return (None, False) def break_here(self, frame): """ @@ -488,29 +511,34 @@ """ filename = self.canonic(self.fix_frame_filename(frame)) if filename not in self.breaks and "Watch" not in self.breaks: - return 0 + return False if filename in self.breaks: lineno = frame.f_lineno + if lineno not in self.breaks[filename]: + # The line itself has no breakpoint, but maybe the line is the + # first line of a function with breakpoint set by function + # name. + lineno = frame.f_code.co_firstlineno if lineno in self.breaks[filename]: - # flag says ok to delete temp. bp + # flag says ok to delete temp. breakpoint (bp, flag) = bdb.effective(filename, lineno, frame) if bp: self.currentbp = bp.number if (flag and bp.temporary): self.__do_clear(filename, lineno) - return 1 + return True if "Watch" in self.breaks: - # flag says ok to delete temp. bp + # flag says ok to delete temp. watch (bp, flag) = self.__effective(frame) if bp: self.currentbp = bp.number if (flag and bp.temporary): self.__do_clearWatch(bp.cond) - return 1 + return True - return 0 + return False def break_anywhere(self, frame): """ @@ -551,8 +579,7 @@ @param lineno linenumber of the bp """ self.clear_break(filename, lineno) - self._dbgClient.write('%s%s,%d\n' % (ResponseClearBreak, filename, - lineno)) + self._dbgClient.sendClearTemporaryBreakpoint(filename, lineno) def getStack(self): """ @@ -612,7 +639,9 @@ return fr = frame while (fr is not None and - fr.f_code != self._dbgClient.handleLine.func_code): + fr.f_code not in [ + self._dbgClient.handleLine.func_code, + self._dbgClient.handleJsonCommand.func_code]): self._dbgClient.mainFrame = fr fr = fr.f_back @@ -654,7 +683,7 @@ self.__isBroken = True - self._dbgClient.write('%s%s\n' % (ResponseLine, unicode(stack))) + self._dbgClient.sendResponseLine(stack) self._dbgClient.eventLoop() def user_exception(self, frame, (exctype, excval, exctb), unhandled=0): @@ -674,29 +703,44 @@ if exctype in [SystemExit, bdb.BdbQuit]: atexit._run_exitfuncs() if excval is None: - excval = 0 + exitcode = 0 + message = "" elif isinstance(excval, (unicode, str)): - self._dbgClient.write(excval) - excval = 1 - if isinstance(excval, int): - self._dbgClient.progTerminated(excval) + exitcode = 1 + message = excval + elif isinstance(excval, int): + exitcode = excval + message = "" + elif isinstance(excval, SystemExit): + code = excval.code + if isinstance(code, (unicode, str)): + exitcode = 1 + message = code + elif isinstance(code, int): + exitcode = code + message = "" + else: + exitcode = 1 + message = str(code) else: - self._dbgClient.progTerminated(excval.code) + exitcode = 1 + message = str(excval) + self._dbgClient.progTerminated(exitcode, message) return if exctype in [SyntaxError, IndentationError]: try: - message, (filename, linenr, charnr, text) = excval + message, (filename, lineno, charno, text) = excval except ValueError: - exclist = [] + message = "" + filename = "" + lineno = 0 + charno = 0 realSyntaxError = True - else: - exclist = [message, [filename, linenr, charnr]] - realSyntaxError = os.path.exists(filename) if realSyntaxError: - self._dbgClient.write("%s%s\n" % (ResponseSyntax, - unicode(exclist))) + self._dbgClient.sendSyntaxError( + message, filename, lineno, charno) self._dbgClient.eventLoop() return @@ -712,11 +756,11 @@ else: exctypetxt = unicode(exctype) try: - exclist = [exctypetxt, - unicode(excval).encode(self._dbgClient.getCoding())] + excvaltxt = unicode(excval).encode(self._dbgClient.getCoding()) except TypeError: - exclist = [exctypetxt, str(excval)] + excvaltxt = str(excval) + stack = [] if exctb: frlist = self.__extract_stack(exctb) frlist.reverse() @@ -746,9 +790,9 @@ else: fargs = "" - exclist.append([filename, linenr, ffunc, fargs]) + stack.append([filename, linenr, ffunc, fargs]) - self._dbgClient.write("%s%s\n" % (ResponseException, unicode(exclist))) + self._dbgClient.sendException(exctypetxt, excvaltxt, stack) if exctb is None: return @@ -798,7 +842,7 @@ @return flag indicating whether the debugger should stop here """ if self.__skip_it(frame): - return 0 + return False return bdb.Bdb.stop_here(self, frame) def __skip_it(self, frame): @@ -812,32 +856,33 @@ @return flag indicating whether the debugger should skip this frame """ if frame is None: - return 1 + return True fn = self.fix_frame_filename(frame) # Eliminate things like <string> and <stdin>. if fn[0] == '<': - return 1 + return True #XXX - think of a better way to do this. It's only a convenience for #debugging the debugger - when the debugger code is in the current #directory. if os.path.basename(fn) in [ - 'AsyncFile.py', 'AsyncIO.py', - 'DebugConfig.py', 'DCTestResult.py', - 'DebugBase.py', 'DebugClientBase.py', - 'DebugClientCapabilities.py', 'DebugClient.py', - 'DebugClientThreads.py', 'DebugProtocol.py', - 'DebugThread.py', 'FlexCompleter.py', + 'AsyncFile.py', 'DCTestResult.py', + 'DebugBase.py', 'DebugClient.py', + 'DebugClientBase.py', + 'DebugClientCapabilities.py', + 'DebugClientThreads.py', + 'DebugConfig.py', 'DebugThread.py', + 'DebugUtilities.py', 'FlexCompleter.py', 'PyProfile.py'] or \ os.path.dirname(fn).endswith("coverage"): - return 1 + return True if self._dbgClient.shouldSkip(fn): - return 1 + return True - return 0 + return False def isBroken(self): """
--- a/DebugClients/Python/DebugClient.py Sat Sep 03 18:01:19 2016 +0200 +++ b/DebugClients/Python/DebugClient.py Sat Sep 03 18:02:37 2016 +0200 @@ -7,12 +7,11 @@ Module implementing a Qt free version of the debug client. """ -from AsyncIO import AsyncIO from DebugBase import DebugBase import DebugClientBase -class DebugClient(DebugClientBase.DebugClientBase, AsyncIO, DebugBase): +class DebugClient(DebugClientBase.DebugClientBase, DebugBase): """ Class implementing the client side of the debugger. @@ -23,8 +22,6 @@ """ Constructor """ - AsyncIO.__init__(self) - DebugClientBase.DebugClientBase.__init__(self) DebugBase.__init__(self, self)
--- a/DebugClients/Python/DebugClientBase.py Sat Sep 03 18:01:19 2016 +0200 +++ b/DebugClients/Python/DebugClientBase.py Sat Sep 03 18:02:37 2016 +0200 @@ -21,12 +21,12 @@ import inspect -import DebugProtocol import DebugClientCapabilities from DebugBase import setRecursionLimit, printerr # __IGNORE_WARNING__ from AsyncFile import AsyncFile, AsyncPendingWrite from DebugConfig import ConfigVarTypeStrings from FlexCompleter import Completer +from DebugUtilities import prepareJsonCommand DebugClientInstance = None @@ -44,7 +44,7 @@ @param echo flag indicating echoing of the input (boolean) @return result of the raw_input() call """ - if DebugClientInstance is None or DebugClientInstance.redirect == 0: + if DebugClientInstance is None or not DebugClientInstance.redirect: return DebugClientOrigRawInput(prompt) return DebugClientInstance.raw_input(prompt, echo) @@ -185,7 +185,8 @@ Constructor """ self.breakpoints = {} - self.redirect = 1 + self.redirect = True + self.__receiveBuffer = "" # The next couple of members are needed for the threaded version. # For this base class they contain static values for the non threaded @@ -214,16 +215,14 @@ self.globalsFilterObjects = [] self.localsFilterObjects = [] - self.pendingResponse = DebugProtocol.ResponseOK self._fncache = {} self.dircache = [] - self.inRawMode = 0 self.mainProcStr = None # used for the passive mode - self.passive = 0 # used to indicate the passive mode + self.passive = False # used to indicate the passive mode self.running = None self.test = None - self.tracePython = 0 - self.debugging = 0 + self.tracePython = False + self.debugging = False self.fork_auto = False self.fork_child = False @@ -333,8 +332,10 @@ d["broken"] = False threadList.append(d) - self.write('%s%s\n' % (DebugProtocol.ResponseThreadList, - unicode((currentId, threadList)))) + self.sendJsonCommand("ResponseThreadList", { + "currentID": currentId, + "threadList": threadList, + }) def raw_input(self, prompt, echo): """ @@ -344,9 +345,10 @@ @param echo Flag indicating echoing of the input (boolean) @return the entered string """ - self.write("%s%s\n" % (DebugProtocol.ResponseRaw, - unicode((prompt, echo)))) - self.inRawMode = 1 + self.sendJsonCommand("RequestRaw", { + "prompt": prompt, + "echo": echo, + }) self.eventLoop(True) return self.rawLine @@ -359,15 +361,7 @@ """ return eval(self.raw_input(prompt, 1)) - def __exceptionRaised(self): - """ - Private method called in the case of an exception. - - It ensures that the debug server is informed of the raised exception. - """ - self.pendingResponse = DebugProtocol.ResponseException - - def sessionClose(self, exit=1): + def sessionClose(self, exit=True): """ Public method to close the session with the debugger and optionally terminate. @@ -379,16 +373,14 @@ except Exception: pass - # clean up asyncio. - self.disconnect() - self.debugging = 0 + self.debugging = False # make sure we close down our end of the socket # might be overkill as normally stdin, stdout and stderr # SHOULD be closed on exit, but it does not hurt to do it here - self.readstream.close(1) - self.writestream.close(1) - self.errorstream.close(1) + self.readstream.close(True) + self.writestream.close(True) + self.errorstream.close(True) if exit: # Ok, go away. @@ -408,616 +400,631 @@ line = line[:-1] ## printerr(line) ##debug - - eoc = line.find('<') - - if eoc >= 0 and line[0] == '>': - # Get the command part and any argument. - cmd = line[:eoc + 1] - arg = line[eoc + 1:] - - if cmd == DebugProtocol.RequestVariables: - frmnr, scope, filter = eval(arg) - self.__dumpVariables(int(frmnr), int(scope), filter) - return - - if cmd == DebugProtocol.RequestVariable: - var, frmnr, scope, filter = eval(arg) - self.__dumpVariable(var, int(frmnr), int(scope), filter) - return - - if cmd == DebugProtocol.RequestThreadList: - self.__dumpThreadList() - return - - if cmd == DebugProtocol.RequestThreadSet: - tid = eval(arg) - if tid in self.threads: - self.setCurrentThread(tid) - self.write(DebugProtocol.ResponseThreadSet + '\n') - stack = self.currentThread.getStack() - self.write('%s%s\n' % (DebugProtocol.ResponseStack, - unicode(stack))) - return - - if cmd == DebugProtocol.RequestStep: - self.currentThread.step(1) - self.eventExit = 1 - return - - if cmd == DebugProtocol.RequestStepOver: - self.currentThread.step(0) - self.eventExit = 1 - return - - if cmd == DebugProtocol.RequestStepOut: - self.currentThread.stepOut() - self.eventExit = 1 - return - - if cmd == DebugProtocol.RequestStepQuit: - if self.passive: - self.progTerminated(42) - else: - self.set_quit() - self.eventExit = 1 - return - - if cmd == DebugProtocol.RequestContinue: - special = int(arg) - self.currentThread.go(special) - self.eventExit = 1 - return - - if cmd == DebugProtocol.RequestOK: - self.write(self.pendingResponse + '\n') - self.pendingResponse = DebugProtocol.ResponseOK - return - - if cmd == DebugProtocol.RequestCallTrace: - if arg.strip().lower() == "on": - callTraceEnabled = True - else: - callTraceEnabled = False - if self.debugging: - self.callTraceEnabled = callTraceEnabled - else: - self.__newCallTraceEnabled = callTraceEnabled - # remember for later - return - - if cmd == DebugProtocol.RequestEnv: - env = eval(arg) - for key, value in env.items(): - if key.endswith("+"): - if key[:-1] in os.environ: - os.environ[key[:-1]] += value - else: - os.environ[key[:-1]] = value - else: - os.environ[key] = value - return - - if cmd == DebugProtocol.RequestLoad: - self._fncache = {} - self.dircache = [] - sys.argv = [] - wd, fn, args, tracePython = arg.split('|') - fn = fn.encode(sys.getfilesystemencoding()) - self.__setCoding(fn) - sys.argv.append(fn) - sys.argv.extend(eval(args)) - sys.path = self.__getSysPath(os.path.dirname(sys.argv[0])) - if wd == '': - os.chdir(sys.path[1]) - else: - os.chdir(wd) - tracePython = int(tracePython) - self.running = sys.argv[0] - self.mainFrame = None - self.inRawMode = 0 - self.debugging = 1 - - self.threads.clear() - self.attachThread(mainThread=1) - - # set the system exception handling function to ensure, that - # we report on all unhandled exceptions - sys.excepthook = self.__unhandled_exception - self.__interceptSignals() - - # clear all old breakpoints, they'll get set after we - # have started - self.mainThread.clear_all_breaks() - - self.mainThread.tracePython = tracePython - - # This will eventually enter a local event loop. - # Note the use of backquotes to cause a repr of self.running. - # The need for this is on Windows os where backslash is the - # path separator. They will get inadvertantly stripped away - # during the eval causing IOErrors, if self.running is passed - # as a normal str. - self.debugMod.__dict__['__file__'] = self.running - sys.modules['__main__'] = self.debugMod - self.callTraceEnabled = self.__newCallTraceEnabled - res = self.mainThread.run( - 'execfile(' + repr(self.running) + ')', - self.debugMod.__dict__) - self.progTerminated(res) - return - - if cmd == DebugProtocol.RequestRun: - sys.argv = [] - wd, fn, args = arg.split('|') - fn = fn.encode(sys.getfilesystemencoding()) - self.__setCoding(fn) - sys.argv.append(fn) - sys.argv.extend(eval(args)) - sys.path = self.__getSysPath(os.path.dirname(sys.argv[0])) - if wd == '': - os.chdir(sys.path[1]) - else: - os.chdir(wd) - - self.running = sys.argv[0] - self.mainFrame = None - self.botframe = None - self.inRawMode = 0 - - self.threads.clear() - self.attachThread(mainThread=1) - - # set the system exception handling function to ensure, that - # we report on all unhandled exceptions - sys.excepthook = self.__unhandled_exception - self.__interceptSignals() - - self.mainThread.tracePython = 0 - - self.debugMod.__dict__['__file__'] = sys.argv[0] - sys.modules['__main__'] = self.debugMod - res = 0 - try: - execfile(sys.argv[0], self.debugMod.__dict__) - except SystemExit as exc: - res = exc.code - atexit._run_exitfuncs() - self.writestream.flush() - self.progTerminated(res) - return - - if cmd == DebugProtocol.RequestCoverage: - from coverage import coverage - sys.argv = [] - wd, fn, args, erase = arg.split('@@') - fn = fn.encode(sys.getfilesystemencoding()) - self.__setCoding(fn) - sys.argv.append(fn) - sys.argv.extend(eval(args)) - sys.path = self.__getSysPath(os.path.dirname(sys.argv[0])) - if wd == '': - os.chdir(sys.path[1]) - else: - os.chdir(wd) - - # set the system exception handling function to ensure, that - # we report on all unhandled exceptions - sys.excepthook = self.__unhandled_exception - self.__interceptSignals() - - # generate a coverage object - self.cover = coverage( - auto_data=True, - data_file="%s.coverage" % os.path.splitext(sys.argv[0])[0]) - - if int(erase): - self.cover.erase() - sys.modules['__main__'] = self.debugMod - self.debugMod.__dict__['__file__'] = sys.argv[0] - self.running = sys.argv[0] - res = 0 - self.cover.start() - try: - execfile(sys.argv[0], self.debugMod.__dict__) - except SystemExit as exc: - res = exc.code - atexit._run_exitfuncs() - self.cover.stop() - self.cover.save() - self.writestream.flush() - self.progTerminated(res) - return - - if cmd == DebugProtocol.RequestProfile: - sys.setprofile(None) - import PyProfile - sys.argv = [] - wd, fn, args, erase = arg.split('|') - fn = fn.encode(sys.getfilesystemencoding()) - self.__setCoding(fn) - sys.argv.append(fn) - sys.argv.extend(eval(args)) - sys.path = self.__getSysPath(os.path.dirname(sys.argv[0])) - if wd == '': - os.chdir(sys.path[1]) - else: - os.chdir(wd) - - # set the system exception handling function to ensure, that - # we report on all unhandled exceptions - sys.excepthook = self.__unhandled_exception - self.__interceptSignals() - - # generate a profile object - self.prof = PyProfile.PyProfile(sys.argv[0]) - - if int(erase): - self.prof.erase() - self.debugMod.__dict__['__file__'] = sys.argv[0] - sys.modules['__main__'] = self.debugMod - self.running = sys.argv[0] - res = 0 - try: - self.prof.run('execfile(%r)' % sys.argv[0]) - except SystemExit as exc: - res = exc.code - atexit._run_exitfuncs() - self.prof.save() - self.writestream.flush() - self.progTerminated(res) - return - - if cmd == DebugProtocol.RequestShutdown: - self.sessionClose() - return - - if cmd == DebugProtocol.RequestBreak: - fn, line, temporary, set, cond = arg.split('@@') - fn = fn.encode(sys.getfilesystemencoding()) - line = int(line) - set = int(set) - temporary = int(temporary) - - if set: - if cond == 'None' or cond == '': - cond = None + + self.handleJsonCommand(line) + + def handleJsonCommand(self, jsonStr): + """ + Public method to handle a command serialized as a JSON string. + + @param jsonStr string containing the command received from the IDE + @type str + """ + import json + + try: + commandDict = json.loads(jsonStr.strip()) + except json.JSONDecodeError as err: + printerr(str(err)) + return + + method = commandDict["method"] + params = commandDict["params"] + + if method == "RequestVariables": + self.__dumpVariables( + params["frameNumber"], params["scope"], params["filters"]) + + elif method == "RequestVariable": + self.__dumpVariable( + params["variable"], params["frameNumber"], + params["scope"], params["filters"]) + + elif method == "RequestThreadList": + self.__dumpThreadList() + + elif method == "RequestThreadSet": + if params["threadID"] in self.threads: + self.setCurrentThread(params["threadID"]) + self.sendJsonCommand("ResponseThreadSet", {}) + stack = self.currentThread.getStack() + self.sendJsonCommand("ResponseStack", { + "stack": stack, + }) + + elif method == "RequestCapabilities": + self.sendJsonCommand("ResponseCapabilities", { + "capabilities": self.__clientCapabilities(), + "clientType": "Python3" + }) + + elif method == "RequestBanner": + self.sendJsonCommand("ResponseBanner", { + "version": "Python {0}".format(sys.version), + "platform": socket.gethostname(), + "dbgclient": self.variant, + }) + + elif method == "RequestSetFilter": + self.__generateFilterObjects(params["scope"], params["filter"]) + + elif method == "RequestCallTrace": + if self.debugging: + self.callTraceEnabled = params["enable"] + else: + self.__newCallTraceEnabled = params["enable"] + # remember for later + + elif method == "RequestEnvironment": + for key, value in params["environment"].items(): + if key.endswith("+"): + if key[:-1] in os.environ: + os.environ[key[:-1]] += value else: - try: - compile(cond, '<string>', 'eval') - except SyntaxError: - self.write( - '%s%s,%d\n' % - (DebugProtocol.ResponseBPConditionError, - fn, line)) - return - self.mainThread.set_break(fn, line, temporary, cond) + os.environ[key[:-1]] = value else: - self.mainThread.clear_break(fn, line) - - return - - if cmd == DebugProtocol.RequestBreakEnable: - fn, line, enable = arg.split(',') - fn = fn.encode(sys.getfilesystemencoding()) - line = int(line) - enable = int(enable) - - bp = self.mainThread.get_break(fn, line) - if bp is not None: - if enable: - bp.enable() - else: - bp.disable() - - return + os.environ[key] = value + + elif method == "RequestLoad": + self._fncache = {} + self.dircache = [] + sys.argv = [] + params["filename"] = params["filename"].encode( + sys.getfilesystemencoding()) + self.__setCoding(params["filename"]) + sys.argv.append(params["filename"]) + sys.argv.extend(params["argv"]) + sys.path = self.__getSysPath(os.path.dirname(sys.argv[0])) + if params["workdir"] == '': + os.chdir(sys.path[1]) + else: + os.chdir(params["workdir"]) - if cmd == DebugProtocol.RequestBreakIgnore: - fn, line, count = arg.split(',') - fn = fn.encode(sys.getfilesystemencoding()) - line = int(line) - count = int(count) - - bp = self.mainThread.get_break(fn, line) - if bp is not None: - bp.ignore = count - - return + self.running = sys.argv[0] + self.mainFrame = None + self.debugging = True + + self.fork_auto = params["autofork"] + self.fork_child = params["forkChild"] + + self.threads.clear() + self.attachThread(mainThread=True) - if cmd == DebugProtocol.RequestWatch: - cond, temporary, set = arg.split('@@') - set = int(set) - temporary = int(temporary) - - if set: - if not cond.endswith('??created??') and \ - not cond.endswith('??changed??'): - try: - compile(cond, '<string>', 'eval') - except SyntaxError: - self.write('%s%s\n' % ( - DebugProtocol.ResponseWPConditionError, cond)) - return - self.mainThread.set_watch(cond, temporary) - else: - self.mainThread.clear_watch(cond) - - return + # set the system exception handling function to ensure, that + # we report on all unhandled exceptions + sys.excepthook = self.__unhandled_exception + self.__interceptSignals() + + # clear all old breakpoints, they'll get set after we have + # started + self.mainThread.clear_all_breaks() + + self.mainThread.tracePython = params["traceInterpreter"] - if cmd == DebugProtocol.RequestWatchEnable: - cond, enable = arg.split(',') - enable = int(enable) - - bp = self.mainThread.get_watch(cond) - if bp is not None: - if enable: - bp.enable() - else: - bp.disable() - - return - - if cmd == DebugProtocol.RequestWatchIgnore: - cond, count = arg.split(',') - count = int(count) - - bp = self.mainThread.get_watch(cond) - if bp is not None: - bp.ignore = count - - return + # This will eventually enter a local event loop. + self.debugMod.__dict__['__file__'] = self.running + sys.modules['__main__'] = self.debugMod + self.callTraceEnabled = self.__newCallTraceEnabled + res = self.mainThread.run( + 'execfile(' + repr(self.running) + ')', + self.debugMod.__dict__) + self.progTerminated(res) + + elif method == "RequestRun": + sys.argv = [] + params["filename"] = params["filename"].encode( + sys.getfilesystemencoding()) + self.__setCoding(params["filename"]) + sys.argv.append(params["filename"]) + sys.argv.extend(params["argv"]) + sys.path = self.__getSysPath(os.path.dirname(sys.argv[0])) + if params["workdir"] == '': + os.chdir(sys.path[1]) + else: + os.chdir(params["workdir"]) + + self.running = sys.argv[0] + self.mainFrame = None + self.botframe = None - if cmd == DebugProtocol.RequestEval: - try: - value = eval( - arg, self.currentThread.getCurrentFrame().f_globals, - self.currentThread.getFrameLocals(self.framenr)) - self.currentThread.storeFrameLocals(self.framenr) - except Exception: - # Report the exception and the traceback - try: - type, value, tb = sys.exc_info() - sys.last_type = type - sys.last_value = value - sys.last_traceback = tb - tblist = traceback.extract_tb(tb) - del tblist[:1] - list = traceback.format_list(tblist) - if list: - list.insert(0, "Traceback (innermost last):\n") - list[len(list):] = \ - traceback.format_exception_only(type, value) - finally: - tblist = tb = None - - map(self.write, list) - - self.write(DebugProtocol.ResponseException + '\n') - - else: - self.write(unicode(value) + '\n') - self.write(DebugProtocol.ResponseOK + '\n') - - return + self.fork_auto = params["autofork"] + self.fork_child = params["forkChild"] + + self.threads.clear() + self.attachThread(mainThread=True) + + # set the system exception handling function to ensure, that + # we report on all unhandled exceptions + sys.excepthook = self.__unhandled_exception + self.__interceptSignals() - if cmd == DebugProtocol.RequestExec: - _globals = self.currentThread.getCurrentFrame().f_globals - _locals = self.currentThread.getFrameLocals(self.framenr) - try: - code = compile(arg + '\n', '<stdin>', 'single') - exec code in _globals, _locals - self.currentThread.storeFrameLocals(self.framenr) - except Exception: - # Report the exception and the traceback - try: - type, value, tb = sys.exc_info() - sys.last_type = type - sys.last_value = value - sys.last_traceback = tb - tblist = traceback.extract_tb(tb) - del tblist[:1] - list = traceback.format_list(tblist) - if list: - list.insert(0, "Traceback (innermost last):\n") - list[len(list):] = \ - traceback.format_exception_only(type, value) - finally: - tblist = tb = None - - map(self.write, list) + self.mainThread.tracePython = False + + self.debugMod.__dict__['__file__'] = sys.argv[0] + sys.modules['__main__'] = self.debugMod + res = 0 + try: + execfile(sys.argv[0], self.debugMod.__dict__) + except SystemExit as exc: + res = exc.code + atexit._run_exitfuncs() + self.writestream.flush() + self.progTerminated(res) - self.write(DebugProtocol.ResponseException + '\n') - - return + elif method == "RequestCoverage": + from coverage import coverage + sys.argv = [] + params["filename"] = params["filename"].encode( + sys.getfilesystemencoding()) + self.__setCoding(params["filename"]) + sys.argv.append(params["filename"]) + sys.argv.extend(params["argv"]) + sys.path = self.__getSysPath(os.path.dirname(sys.argv[0])) + if params["workdir"] == '': + os.chdir(sys.path[1]) + else: + os.chdir(params["workdir"]) - if cmd == DebugProtocol.RequestBanner: - self.write( - '%s%s\n' % ( - DebugProtocol.ResponseBanner, - unicode(("Python %s" % sys.version, - socket.gethostname(), - self.variant)))) - return + # set the system exception handling function to ensure, that + # we report on all unhandled exceptions + sys.excepthook = self.__unhandled_exception + self.__interceptSignals() + + # generate a coverage object + self.cover = coverage( + auto_data=True, + data_file="%s.coverage" % os.path.splitext(sys.argv[0])[0]) - if cmd == DebugProtocol.RequestCapabilities: - self.write('%s%d, "Python2"\n' % ( - DebugProtocol.ResponseCapabilities, - self.__clientCapabilities())) - return - - if cmd == DebugProtocol.RequestCompletion: - self.__completionList(arg) - return - - if cmd == DebugProtocol.RequestSetFilter: - scope, filterString = eval(arg) - self.__generateFilterObjects(int(scope), filterString) - return - - if cmd == DebugProtocol.RequestUTPrepare: - fn, tn, tfn, failed, cov, covname, erase = arg.split('|') - fn = fn.encode(sys.getfilesystemencoding()) - sys.path.insert(0, os.path.dirname(os.path.abspath(fn))) - os.chdir(sys.path[0]) - failed = eval(failed) + if params["erase"]: + self.cover.erase() + sys.modules['__main__'] = self.debugMod + self.debugMod.__dict__['__file__'] = sys.argv[0] + self.running = sys.argv[0] + res = 0 + self.cover.start() + try: + execfile(sys.argv[0], self.debugMod.__dict__) + except SystemExit as exc: + res = exc.code + atexit._run_exitfuncs() + self.cover.stop() + self.cover.save() + self.writestream.flush() + self.progTerminated(res) + + elif method == "RequestProfile": + sys.setprofile(None) + import PyProfile + sys.argv = [] + params["filename"] = params["filename"].encode( + sys.getfilesystemencoding()) + self.__setCoding(params["filename"]) + sys.argv.append(params["filename"]) + sys.argv.extend(params["argv"]) + sys.path = self.__getSysPath(os.path.dirname(sys.argv[0])) + if params["workdir"] == '': + os.chdir(sys.path[1]) + else: + os.chdir(params["workdir"]) - # set the system exception handling function to ensure, that - # we report on all unhandled exceptions - sys.excepthook = self.__unhandled_exception - self.__interceptSignals() - - try: - import unittest - utModule = __import__(tn) - try: - if failed: - self.test = unittest.defaultTestLoader\ - .loadTestsFromNames(failed, utModule) - else: - self.test = unittest.defaultTestLoader\ - .loadTestsFromName(tfn, utModule) - except AttributeError: - self.test = unittest.defaultTestLoader\ - .loadTestsFromModule(utModule) - except Exception: - exc_type, exc_value, exc_tb = sys.exc_info() - self.write( - '%s%s\n' % ( - DebugProtocol.ResponseUTPrepared, - unicode((0, str(exc_type), str(exc_value))))) - self.__exceptionRaised() + # set the system exception handling function to ensure, that + # we report on all unhandled exceptions + sys.excepthook = self.__unhandled_exception + self.__interceptSignals() + + # generate a profile object + self.prof = PyProfile.PyProfile(sys.argv[0]) + + if params["erase"]: + self.prof.erase() + self.debugMod.__dict__['__file__'] = sys.argv[0] + sys.modules['__main__'] = self.debugMod + self.running = sys.argv[0] + res = 0 + try: + self.prof.run('execfile(%r)' % sys.argv[0]) + except SystemExit as exc: + res = exc.code + atexit._run_exitfuncs() + self.prof.save() + self.writestream.flush() + self.progTerminated(res) + + elif method == "ExecuteStatement": + if self.buffer: + self.buffer = self.buffer + '\n' + params["statement"] + else: + self.buffer = params["statement"] + + try: + code = self.compile_command(self.buffer, self.readstream.name) + except (OverflowError, SyntaxError, ValueError): + # Report the exception + sys.last_type, sys.last_value, sys.last_traceback = \ + sys.exc_info() + self.sendJsonCommand("ClientOutput", { + "text": "".join(traceback.format_exception_only( + sys.last_type, sys.last_value)) + }) + self.buffer = '' + else: + if code is None: + self.sendJsonCommand("ResponseContinue", {}) return - - # generate a coverage object - if int(cov): - from coverage import coverage - self.cover = coverage( - auto_data=True, - data_file="%s.coverage" % os.path.splitext(covname)[0]) - if int(erase): - self.cover.erase() else: - self.cover = None - - self.write( - '%s%s\n' % ( - DebugProtocol.ResponseUTPrepared, - unicode((self.test.countTestCases(), "", "")))) - return - - if cmd == DebugProtocol.RequestUTRun: - from DCTestResult import DCTestResult - self.testResult = DCTestResult(self) - if self.cover: - self.cover.start() - self.test.run(self.testResult) - if self.cover: - self.cover.stop() - self.cover.save() - self.write('%s\n' % DebugProtocol.ResponseUTFinished) - return - - if cmd == DebugProtocol.RequestUTStop: - self.testResult.stop() - return - - if cmd == DebugProtocol.ResponseForkTo: - # this results from a separate event loop - self.fork_child = (arg == 'child') - self.eventExit = 1 - return - - if cmd == DebugProtocol.RequestForkMode: - self.fork_auto, self.fork_child = eval(arg) - return - - # If we are handling raw mode input then reset the mode and break out - # of the current event loop. - if self.inRawMode: - self.inRawMode = 0 - self.rawLine = line - self.eventExit = 1 - return + self.buffer = '' - if self.buffer: - self.buffer = self.buffer + '\n' + line - else: - self.buffer = line - - try: - code = self.compile_command(self.buffer, self.readstream.name) - except (OverflowError, SyntaxError, ValueError): - # Report the exception - sys.last_type, sys.last_value, sys.last_traceback = sys.exc_info() - map(self.write, traceback.format_exception_only( - sys.last_type, sys.last_value)) - self.buffer = '' - else: - if code is None: - self.pendingResponse = DebugProtocol.ResponseContinue - else: - self.buffer = '' - - try: - if self.running is None: - exec code in self.debugMod.__dict__ - else: - if self.currentThread is None: - # program has terminated - self.running = None - _globals = self.debugMod.__dict__ - _locals = _globals + try: + if self.running is None: + exec code in self.debugMod.__dict__ else: - cf = self.currentThread.getCurrentFrame() - # program has terminated - if cf is None: + if self.currentThread is None: + # program has terminated self.running = None _globals = self.debugMod.__dict__ _locals = _globals else: - frmnr = self.framenr - while cf is not None and frmnr > 0: - cf = cf.f_back - frmnr -= 1 - _globals = cf.f_globals - _locals = \ - self.currentThread.getFrameLocals( - self.framenr) - # reset sys.stdout to our redirector (unconditionally) - if "sys" in _globals: - __stdout = _globals["sys"].stdout - _globals["sys"].stdout = self.writestream - exec code in _globals, _locals - _globals["sys"].stdout = __stdout - elif "sys" in _locals: - __stdout = _locals["sys"].stdout - _locals["sys"].stdout = self.writestream - exec code in _globals, _locals - _locals["sys"].stdout = __stdout - else: - exec code in _globals, _locals - - self.currentThread.storeFrameLocals(self.framenr) - except SystemExit, exc: - self.progTerminated(exc.code) - except Exception: - # Report the exception and the traceback + cf = self.currentThread.getCurrentFrame() + # program has terminated + if cf is None: + self.running = None + _globals = self.debugMod.__dict__ + _locals = _globals + else: + frmnr = self.framenr + while cf is not None and frmnr > 0: + cf = cf.f_back + frmnr -= 1 + _globals = cf.f_globals + _locals = \ + self.currentThread.getFrameLocals( + self.framenr) + # reset sys.stdout to our redirector + # (unconditionally) + if "sys" in _globals: + __stdout = _globals["sys"].stdout + _globals["sys"].stdout = self.writestream + exec code in _globals, _locals + _globals["sys"].stdout = __stdout + elif "sys" in _locals: + __stdout = _locals["sys"].stdout + _locals["sys"].stdout = self.writestream + exec code in _globals, _locals + _locals["sys"].stdout = __stdout + else: + exec code in _globals, _locals + + self.currentThread.storeFrameLocals(self.framenr) + except SystemExit, exc: + self.progTerminated(exc.code) + except Exception: + # Report the exception and the traceback + tlist = [] + try: + exc_type, exc_value, exc_tb = sys.exc_info() + sys.last_type = exc_type + sys.last_value = exc_value + sys.last_traceback = exc_tb + tblist = traceback.extract_tb(exc_tb) + del tblist[:1] + tlist = traceback.format_list(tblist) + if tlist: + tlist.insert( + 0, "Traceback (innermost last):\n") + tlist.extend(traceback.format_exception_only( + exc_type, exc_value)) + finally: + tblist = exc_tb = None + + self.sendJsonCommand("ClientOutput", { + "text": "".join(tlist) + }) + + self.sendJsonCommand("ResponseOK", {}) + + elif method == "RequestStep": + self.currentThread.step(True) + self.eventExit = True + + elif method == "RequestStepOver": + self.currentThread.step(False) + self.eventExit = True + + elif method == "RequestStepOut": + self.currentThread.stepOut() + self.eventExit = True + + elif method == "RequestStepQuit": + if self.passive: + self.progTerminated(42) + else: + self.set_quit() + self.eventExit = True + + elif method == "RequestContinue": + self.currentThread.go(params["special"]) + self.eventExit = True + + elif method == "RawInput": + # If we are handling raw mode input then break out of the current + # event loop. + self.rawLine = params["input"] + self.eventExit = True + + elif method == "RequestBreakpoint": + params["filename"] = params["filename"].encode( + sys.getfilesystemencoding()) + if params["setBreakpoint"]: + if params["condition"] in ['None', '']: + params["condition"] = None + elif params["condition"] is not None: + try: + compile(params["condition"], '<string>', 'eval') + except SyntaxError: + self.sendJsonCommand("ResponseBPConditionError", { + "filename": params["filename"], + "line": params["line"], + }) + return + self.mainThread.set_break( + params["filename"], params["line"], params["temporary"], + params["condition"]) + else: + self.mainThread.clear_break(params["filename"], params["line"]) + + elif method == "RequestBreakpointEnable": + params["filename"] = params["filename"].encode( + sys.getfilesystemencoding()) + bp = self.mainThread.get_break(params["filename"], params["line"]) + if bp is not None: + if params["enable"]: + bp.enable() + else: + bp.disable() + + + elif method == "RequestBreakpointIgnore": + params["filename"] = params["filename"].encode( + sys.getfilesystemencoding()) + bp = self.mainThread.get_break(params["filename"], params["line"]) + if bp is not None: + bp.ignore = params["count"] + + elif method == "RequestWatch": + if params["setWatch"]: + if not params["condition"].endswith( + ('??created??', '??changed??')): try: - type, value, tb = sys.exc_info() - sys.last_type = type - sys.last_value = value - sys.last_traceback = tb - tblist = traceback.extract_tb(tb) - del tblist[:1] - list = traceback.format_list(tblist) - if list: - list.insert(0, "Traceback (innermost last):\n") - list[len(list):] = \ - traceback.format_exception_only(type, value) - finally: - tblist = tb = None - - map(self.write, list) + compile(params["condition"], '<string>', 'eval') + except SyntaxError: + self.sendJsonCommand("ResponseWatchConditionError", { + "condition": params["condition"], + }) + return + self.mainThread.set_watch( + params["condition"], params["temporary"]) + else: + self.mainThread.clear_watch(params["condition"]) + + elif method == "RequestWatchEnable": + wp = self.mainThread.get_watch(params["condition"]) + if wp is not None: + if params["enable"]: + wp.enable() + else: + wp.disable() + + elif method == "RequestWatchIgnore": + wp = self.mainThread.get_watch(params["condition"]) + if wp is not None: + wp.ignore = params["count"] + + elif method == "RequestShutdown": + self.sessionClose() + + elif method == "RequestCompletion": + self.__completionList(params["text"]) + + elif method == "RequestUTPrepare": + params["filename"] = params["filename"].encode( + sys.getfilesystemencoding()) + sys.path.insert( + 0, os.path.dirname(os.path.abspath(params["filename"]))) + os.chdir(sys.path[0]) + + # set the system exception handling function to ensure, that + # we report on all unhandled exceptions + sys.excepthook = self.__unhandled_exception + self.__interceptSignals() + + try: + import unittest + utModule = __import__(params["testname"]) + try: + if params["failed"]: + self.test = unittest.defaultTestLoader\ + .loadTestsFromNames(params["failed"], utModule) + else: + self.test = unittest.defaultTestLoader\ + .loadTestsFromName(params["testfunctionname"], + utModule) + except AttributeError: + self.test = unittest.defaultTestLoader\ + .loadTestsFromModule(utModule) + except Exception: + exc_type, exc_value, exc_tb = sys.exc_info() + self.sendJsonCommand("ResponseUTPrepared", { + "count": 0, + "exception": exc_type.__name__, + "message": str(exc_value), + }) + return + + # generate a coverage object + if params["coverage"]: + from coverage import coverage + self.cover = coverage( + auto_data=True, + data_file="%s.coverage" % \ + os.path.splitext(params["coveragefile"])[0]) + if params["coverageerase"]: + self.cover.erase() + else: + self.cover = None + + self.sendJsonCommand("ResponseUTPrepared", { + "count": self.test.countTestCases(), + "exception": "", + "message": "", + }) + + elif method == "RequestUTRun": + from DCTestResult import DCTestResult + self.testResult = DCTestResult(self) + if self.cover: + self.cover.start() + self.test.run(self.testResult) + if self.cover: + self.cover.stop() + self.cover.save() + self.sendJsonCommand("ResponseUTFinished", {}) + + elif method == "RequestUTStop": + self.testResult.stop() + + elif method == "ResponseForkTo": + # this results from a separate event loop + self.fork_child = (params["target"] == 'child') + self.eventExit = True + + def sendJsonCommand(self, method, params): + """ + Public method to send a single command or response to the IDE. + + @param method command or response command name to be sent + @type str + @param params dictionary of named parameters for the command or + response + @type dict + """ + cmd = prepareJsonCommand(method, params) + + self.writestream.write_p(cmd) + self.writestream.flush() + + def sendClearTemporaryBreakpoint(self, filename, lineno): + """ + Public method to signal the deletion of a temporary breakpoint. + + @param filename name of the file the bp belongs to + @type str + @param lineno linenumber of the bp + @type int + """ + self.sendJsonCommand("ResponseClearBreakpoint", { + "filename": filename, + "line": lineno + }) + + def sendClearTemporaryWatch(self, condition): + """ + Public method to signal the deletion of a temporary watch expression. + + @param condition condition of the watch expression to be cleared + @type str + """ + self.sendJsonCommand("ResponseClearWatch", { + "condition": condition, + }) + + def sendResponseLine(self, stack): + """ + Public method to send the current call stack. + + @param stack call stack + @type list + """ + self.sendJsonCommand("ResponseLine", { + "stack": stack, + }) + + def sendCallTrace(self, event, fromStr, toStr): + """ + Public method to send a call trace entry. + + @param event trace event (call or return) + @type str + @param fromStr pre-formatted origin info + @type str + @param toStr pre-formatted target info + @type str + """ + self.sendJsonCommand("CallTrace", { + "event": event[0], + "from": fromStr, + "to": toStr, + }) + + def sendException(self, exceptionType, exceptionMessage, stack): + """ + Public method to send information for an exception. + + @param exceptionType type of exception raised + @type str + @param exceptionMessage message of the exception + @type str + @param stack stack trace information + @type list + """ + self.sendJsonCommand("ResponseException", { + "type": exceptionType, + "message": exceptionMessage, + "stack": stack, + }) + + def sendSyntaxError(self, message, filename, lineno, charno): + """ + Public method to send information for a syntax error. + + @param message syntax error message + @type str + @param filename name of the faulty file + @type str + @param lineno line number info + @type int + @param charno character number info + @tyoe int + """ + self.sendJsonCommand("ResponseSyntax", { + "message": message, + "filename": filename, + "linenumber": lineno, + "characternumber": charno, + }) + + def sendPassiveStartup(self, filename, exceptions): + """ + Public method to send the passive start information. + + @param filename name of the script + @type str + @param exceptions flag to enable exception reporting of the IDE + @type bool + """ + self.sendJsonCommand("PassiveStartup", { + "filename": filename, + "exceptions": exceptions, + }) def __clientCapabilities(self): """ @@ -1035,15 +1042,40 @@ except ImportError: return ( self.clientCapabilities & ~DebugClientCapabilities.HasProfiler) - - def write(self, s): + + def readReady(self, stream): """ - Public method to write data to the output stream. + Public method called when there is data ready to be read. - @param s data to be written (string) + @param stream file like object that has data to be written """ - self.writestream.write(s) - self.writestream.flush() + try: + got = stream.readline_p() + except Exception: + return + + if len(got) == 0: + self.sessionClose() + return + + self.__receiveBuffer = self.__receiveBuffer + got + + # Call handleLine for the line if it is complete. + eol = self.__receiveBuffer.find('\n') + while eol >= 0: + line = self.__receiveBuffer[:eol + 1] + self.__receiveBuffer = self.__receiveBuffer[eol + 1:] + self.handleLine(line) + eol = self.__receiveBuffer.find('\n') + + def writeReady(self, stream): + """ + Public method called when we are ready to write data. + + @param stream file like object that has data to be written + """ + stream.write_p("") + stream.flush() def __interact(self): """ @@ -1051,8 +1083,8 @@ """ global DebugClientInstance - self.setDescriptors(self.readstream, self.writestream) DebugClientInstance = self + self.__receiveBuffer = "" if not self.passive: # At this point simulate an event loop. @@ -1087,13 +1119,13 @@ continue if self.readstream in rrdy: - self.readReady(self.readstream.fileno()) + self.readReady(self.readstream) if self.writestream in wrdy: - self.writeReady(self.writestream.fileno()) + self.writeReady(self.writestream) if self.errorstream in wrdy: - self.writeReady(self.errorstream.fileno()) + self.writeReady(self.errorstream) self.eventExit = None self.pollingDisabled = False @@ -1128,13 +1160,13 @@ return if self.readstream in rrdy: - self.readReady(self.readstream.fileno()) + self.readReady(self.readstream) if self.writestream in wrdy: - self.writeReady(self.writestream.fileno()) + self.writeReady(self.writestream) if self.errorstream in wrdy: - self.writeReady(self.errorstream.fileno()) + self.writeReady(self.errorstream) def connectDebugger(self, port, remoteAddress=None, redirect=1): """ @@ -1177,7 +1209,7 @@ @param excval data about the exception @param exctb traceback for the exception """ - self.mainThread.user_exception(None, (exctype, excval, exctb), 1) + self.mainThread.user_exception(None, (exctype, excval, exctb), True) def __interceptSignals(self): """ @@ -1230,10 +1262,14 @@ else: fargs = "" - siglist = [message, [filename, linenr, ffunc, fargs]] - - self.write("%s%s" % (DebugProtocol.ResponseSignal, str(siglist))) - + self.sendJsonCommand("ResponseSignal", { + "message": message, + "filename": filename, + "linenumber": linenr, + "function": ffunc, + "arguments": fargs, + }) + def absPath(self, fn): """ Public method to convert a filename to an absolute name. @@ -1284,20 +1320,20 @@ zero otherwise. """ if self.mainThread.tracePython: # trace into Python library - return 0 + return False # Eliminate anything that is part of the Python installation. afn = self.absPath(fn) for d in self.skipdirs: if afn.startswith(d): - return 1 + return True # special treatment for paths containing site-packages or dist-packages for part in ["site-packages", "dist-packages"]: if part in afn: - return 1 + return True - return 0 + return False def getRunning(self): """ @@ -1307,25 +1343,28 @@ """ return self.running - def progTerminated(self, status): + def progTerminated(self, status, message=""): """ Public method to tell the debugger that the program has terminated. @param status return status @type int + @param message status message + @type str """ if status is None: status = 0 - else: - try: - int(status) - except ValueError: - status = 1 + elif not isinstance(status, int): + message = str(status) + status = 1 if self.running: self.set_quit() self.running = None - self.write('%s%d\n' % (DebugProtocol.ResponseExit, status)) + self.sendJsonCommand("ResponseExit", { + "status": status, + "message": message, + }) # reset coding self.__coding = self.defaultCoding @@ -1364,7 +1403,7 @@ else: dict = f.f_locals - varlist = [scope] + varlist = [] if scope != -1: keylist = dict.keys() @@ -1372,8 +1411,10 @@ vlist = self.__formatVariablesList(keylist, dict, scope, filter) varlist.extend(vlist) - self.write('%s%s\n' % ( - DebugProtocol.ResponseVariables, unicode(varlist))) + self.sendJsonCommand("ResponseVariables", { + "scope": scope, + "variables": varlist, + }) def __dumpVariable(self, var, frmnr, scope, filter): """ @@ -1408,7 +1449,7 @@ else: dict = f.f_locals - varlist = [scope, var] + varlist = [] if scope != -1: # search the correct dictionary @@ -1416,8 +1457,8 @@ rvar = var[:] dictkeys = None obj = None - isDict = 0 - formatSequences = 0 + isDict = False + formatSequences = False access = "" oaccess = "" odict = dict @@ -1437,7 +1478,7 @@ dictkeys = [var[i - 1]] else: dictkeys = [var[i][:-2]] - formatSequences = 1 + formatSequences = True if not access and not oaccess: if var[i][:-2] == '...': access = '["%s"]' % var[i - 1] @@ -1458,7 +1499,7 @@ else: access = '%s[%s]' % (access, var[i][:-2]) if var[i][-2:] == "{}": # __IGNORE_WARNING__ - isDict = 1 + isDict = True break else: if not access: @@ -1623,8 +1664,11 @@ except Exception: pass - self.write('%s%s\n' % ( - DebugProtocol.ResponseVariable, unicode(varlist))) + self.sendJsonCommand("ResponseVariable", { + "scope": scope, + "variable": var, + "variables": varlist, + }) def __formatQtVariable(self, value, vtype): """ @@ -1793,10 +1837,10 @@ for key in keylist: # filter based on the filter pattern - matched = 0 + matched = False for pat in patternFilterObjects: if pat.match(unicode(key)): - matched = 1 + matched = True break if matched: continue @@ -1907,8 +1951,10 @@ pass self.__getCompletionList(text, self.complete, completions) - self.write("%s%s||%s\n" % (DebugProtocol.ResponseCompletion, - unicode(list(completions)), text)) + self.sendJsonCommand("ResponseCompletion", { + "completions": list(completions), + "text": text, + }) def __getCompletionList(self, text, completer, completions): """ @@ -1932,7 +1978,8 @@ comp = None def startDebugger(self, filename=None, host=None, port=None, - enableTrace=1, exceptions=1, tracePython=0, redirect=1): + enableTrace=True, exceptions=True, tracePython=False, + redirect=True): """ Public method used to start the remote debugger. @@ -1964,19 +2011,17 @@ self.running = None if self.running: self.__setCoding(self.running) - self.passive = 1 - self.write("%s%s|%d\n" % ( - DebugProtocol.PassiveStartup, self.running, exceptions)) + self.passive = True + self.sendPassiveStartup(self.running, exceptions) self.__interact() # setup the debugger variables self._fncache = {} self.dircache = [] self.mainFrame = None - self.inRawMode = 0 - self.debugging = 1 + self.debugging = True - self.attachThread(mainThread=1) + self.attachThread(mainThread=True) self.mainThread.tracePython = tracePython # set the system exception handling function to ensure, that @@ -1989,8 +2034,8 @@ self.mainThread.set_trace() def startProgInDebugger(self, progargs, wd='', host=None, - port=None, exceptions=1, tracePython=0, - redirect=1): + port=None, exceptions=True, tracePython=False, + redirect=True): """ Public method used to start the remote debugger. @@ -2026,12 +2071,10 @@ self.running = sys.argv[0] self.__setCoding(self.running) self.mainFrame = None - self.inRawMode = 0 - self.debugging = 1 + self.debugging = True - self.passive = 1 - self.write("%s%s|%d\n" % ( - DebugProtocol.PassiveStartup, self.running, exceptions)) + self.passive = True + self.sendPassiveStartup(self.running, exceptions) self.__interact() self.attachThread(mainThread=1) @@ -2094,9 +2137,9 @@ host = None port = None wd = '' - tracePython = 0 - exceptions = 1 - redirect = 1 + tracePython = False + exceptions = True + redirect = True while args[0]: if args[0] == '-h': host = args[1] @@ -2111,13 +2154,13 @@ del args[0] del args[0] elif args[0] == '-t': - tracePython = 1 + tracePython = True del args[0] elif args[0] == '-e': - exceptions = 0 + exceptions = False del args[0] elif args[0] == '-n': - redirect = 0 + redirect = False del args[0] elif args[0] == '--no-encoding': self.noencoding = True @@ -2157,7 +2200,7 @@ try: redirect = int(sys.argv[2]) except (ValueError, IndexError): - redirect = 1 + redirect = True try: ipOrHost = sys.argv[3] if ':' in ipOrHost: @@ -2187,7 +2230,7 @@ @return process ID (integer) """ if not self.fork_auto: - self.write(DebugProtocol.RequestForkTo + '\n') + self.sendJsonCommand("RequestForkTo", {}) self.eventLoop(True) pid = DebugClientOrigFork() if pid == 0:
--- a/DebugClients/Python/DebugClientThreads.py Sat Sep 03 18:01:19 2016 +0200 +++ b/DebugClients/Python/DebugClientThreads.py Sat Sep 03 18:02:37 2016 +0200 @@ -10,7 +10,6 @@ import thread import sys -from AsyncIO import AsyncIO from DebugThread import DebugThread import DebugClientBase @@ -49,7 +48,7 @@ from threading import RLock -class DebugClientThreads(DebugClientBase.DebugClientBase, AsyncIO): +class DebugClientThreads(DebugClientBase.DebugClientBase): """ Class implementing the client side of the debugger. @@ -60,8 +59,6 @@ """ Constructor """ - AsyncIO.__init__(self) - DebugClientBase.DebugClientBase.__init__(self) # protection lock for synchronization
--- a/DebugClients/Python/DebugProtocol.py Sat Sep 03 18:01:19 2016 +0200 +++ b/DebugClients/Python/DebugProtocol.py Sat Sep 03 18:02:37 2016 +0200 @@ -6,7 +6,7 @@ """ Module defining the debug protocol tokens. """ - +# TODO: delete this file # The address used for debugger/client communications. DebugAddress = '127.0.0.1'
--- a/DebugClients/Python/DebugThread.py Sat Sep 03 18:01:19 2016 +0200 +++ b/DebugClients/Python/DebugThread.py Sat Sep 03 18:02:37 2016 +0200 @@ -23,7 +23,7 @@ call to step etc. """ def __init__(self, dbgClient, targ=None, args=None, kwargs=None, - mainThread=0): + mainThread=False): """ Constructor @@ -31,7 +31,7 @@ @param targ the target method in the run thread @param args arguments to be passed to the thread @param kwargs arguments to be passed to the thread - @param mainThread 0 if this thread is not the mainscripts thread + @param mainThread False if this thread is not the main script's thread """ DebugBase.__init__(self, dbgClient) @@ -42,7 +42,7 @@ # thread running tracks execution state of client code # it will always be 0 for main thread as that is tracked # by DebugClientThreads and Bdb... - self._threadRunning = 0 + self._threadRunning = False self.__ident = None # id of this thread. self.__name = "" @@ -89,14 +89,14 @@ """ try: try: - self._threadRunning = 1 + self._threadRunning = True self.traceThread() self._target(*self._args, **self._kwargs) except bdb.BdbQuit: pass finally: - self._threadRunning = 0 - self.quitting = 1 + self._threadRunning = False + self.quitting = True self._dbgClient.threadTerminated(self) sys.settrace(None) sys.setprofile(None)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DebugClients/Python/DebugUtilities.py Sat Sep 03 18:02:37 2016 +0200 @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2016 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing utilities functions for the debug client. +""" + + +def prepareJsonCommand(method, params): + """ + Function to prepare a single command or response for transmission to + the IDE. + + @param method command or response name to be sent + @type str + @param params dictionary of named parameters for the command or response + @type dict + @return prepared JSON command or response string + @rtype str + """ + import json + + commandDict = { + "jsonrpc": "2.0", + "method": method, + "params": params, + } + return json.dumps(commandDict) + '\n' + +# +# eflag: FileType = Python2 +# eflag: noqa = M702
--- a/DebugClients/Python/PyProfile.py Sat Sep 03 18:01:19 2016 +0200 +++ b/DebugClients/Python/PyProfile.py Sat Sep 03 18:02:37 2016 +0200 @@ -117,10 +117,14 @@ if not isinstance(frame, profile.Profile.fake_frame) and \ '__file__' in frame.f_globals: root, ext = os.path.splitext(frame.f_globals['__file__']) - if ext == '.pyc' or ext == '.py': + if ext in ['.pyc', '.py', '.py2', '.pyo']: fixedName = root + '.py' if os.path.exists(fixedName): return fixedName + + fixedName = root + '.py2' + if os.path.exists(fixedName): + return fixedName return frame.f_code.co_filename
--- a/Debugger/DebugServer.py Sat Sep 03 18:01:19 2016 +0200 +++ b/Debugger/DebugServer.py Sat Sep 03 18:02:37 2016 +0200 @@ -31,7 +31,7 @@ DebuggerInterfaces = { - "Python": "DebuggerInterfacePython", + "Python2": "DebuggerInterfacePython2", "Python3": "DebuggerInterfacePython3", "None": "DebuggerInterfaceNone", }
--- a/Debugger/DebuggerInterfacePython.py Sat Sep 03 18:01:19 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1105 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2007 - 2016 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Module implementing the Python debugger interface for the debug server. -""" - -from __future__ import unicode_literals - -import sys -import os -import re - -from PyQt5.QtCore import QObject, QTextCodec, QProcess, QProcessEnvironment, \ - QTimer -from PyQt5.QtWidgets import QInputDialog - -from E5Gui.E5Application import e5App -from E5Gui import E5MessageBox - -from . import DebugProtocol -from . import DebugClientCapabilities - -import Preferences -import Utilities - -from eric6config import getConfig - - -ClientDefaultCapabilities = DebugClientCapabilities.HasAll - - -class DebuggerInterfacePython(QObject): - """ - Class implementing the Python debugger interface for the debug server. - """ - def __init__(self, debugServer, passive): - """ - Constructor - - @param debugServer reference to the debug server (DebugServer) - @param passive flag indicating passive connection mode (boolean) - """ - super(DebuggerInterfacePython, self).__init__() - - self.__isNetworked = True - self.__autoContinue = False - - self.debugServer = debugServer - self.passive = passive - self.process = None - - self.qsock = None - self.queue = [] - - # set default values for capabilities of clients - self.clientCapabilities = ClientDefaultCapabilities - - # set translation function - self.translate = self.__identityTranslation - - self.codec = QTextCodec.codecForName( - Preferences.getSystem("StringEncoding")) - - self.__unicodeRe = re.compile(r"""\bu(["'])""") - - if passive: - # set translation function - if Preferences.getDebugger("PathTranslation"): - self.translateRemote = \ - Preferences.getDebugger("PathTranslationRemote") - self.translateLocal = \ - Preferences.getDebugger("PathTranslationLocal") - self.translate = self.__remoteTranslation - else: - self.translate = self.__identityTranslation - - # attribute to remember the name of the executed script - self.__scriptName = "" - - def __identityTranslation(self, fn, remote2local=True): - """ - Private method to perform the identity path translation. - - @param fn filename to be translated (string) - @param remote2local flag indicating the direction of translation - (False = local to remote, True = remote to local [default]) - @return translated filename (string) - """ - return fn - - def __remoteTranslation(self, fn, remote2local=True): - """ - Private method to perform the path translation. - - @param fn filename to be translated (string) - @param remote2local flag indicating the direction of translation - (False = local to remote, True = remote to local [default]) - @return translated filename (string) - """ - if remote2local: - return fn.replace(self.translateRemote, self.translateLocal) - else: - return fn.replace(self.translateLocal, self.translateRemote) - - def __startProcess(self, program, arguments, environment=None): - """ - Private method to start the debugger client process. - - @param program name of the executable to start (string) - @param arguments arguments to be passed to the program (list of string) - @param environment dictionary of environment settings to pass - (dict of string) - @return the process object (QProcess) or None - """ - proc = QProcess() - if environment is not None: - env = QProcessEnvironment() - for key, value in list(environment.items()): - env.insert(key, value) - proc.setProcessEnvironment(env) - args = [] - for arg in arguments: - args.append(arg) - proc.start(program, args) - if not proc.waitForStarted(10000): - proc = None - - return proc - - def startRemote(self, port, runInConsole): - """ - Public method to start a remote Python interpreter. - - @param port portnumber the debug server is listening on (integer) - @param runInConsole flag indicating to start the debugger in a - console window (boolean) - @return client process object (QProcess), a flag to indicate - a network connection (boolean) and the name of the interpreter - in case of a local execution (string) - """ - interpreter = Preferences.getDebugger("PythonInterpreter") - if interpreter == "": - E5MessageBox.critical( - None, - self.tr("Start Debugger"), - self.tr( - """<p>No Python2 interpreter configured.</p>""")) - return None, False, "" - - debugClientType = Preferences.getDebugger("DebugClientType") - if debugClientType == "standard": - debugClient = os.path.join(getConfig('ericDir'), - "DebugClients", "Python", - "DebugClient.py") - elif debugClientType == "threaded": - debugClient = os.path.join(getConfig('ericDir'), - "DebugClients", "Python", - "DebugClientThreads.py") - else: - debugClient = Preferences.getDebugger("DebugClient") - if debugClient == "": - debugClient = os.path.join(sys.path[0], - "DebugClients", "Python", - "DebugClient.py") - - redirect = str(Preferences.getDebugger("PythonRedirect")) - noencoding = Preferences.getDebugger("PythonNoEncoding") and \ - '--no-encoding' or '' - - if Preferences.getDebugger("RemoteDbgEnabled"): - ipaddr = self.debugServer.getHostAddress(False) - rexec = Preferences.getDebugger("RemoteExecution") - rhost = Preferences.getDebugger("RemoteHost") - if rhost == "": - rhost = "localhost" - if rexec: - args = Utilities.parseOptionString(rexec) + \ - [rhost, interpreter, debugClient, - noencoding, str(port), redirect, ipaddr] - args[0] = Utilities.getExecutablePath(args[0]) - process = self.__startProcess(args[0], args[1:]) - if process is None: - E5MessageBox.critical( - None, - self.tr("Start Debugger"), - self.tr( - """<p>The debugger backend could not be""" - """ started.</p>""")) - - # set translation function - if Preferences.getDebugger("PathTranslation"): - self.translateRemote = \ - Preferences.getDebugger("PathTranslationRemote") - self.translateLocal = \ - Preferences.getDebugger("PathTranslationLocal") - self.translate = self.__remoteTranslation - else: - self.translate = self.__identityTranslation - return process, self.__isNetworked, "" - - # set translation function - self.translate = self.__identityTranslation - - # setup the environment for the debugger - if Preferences.getDebugger("DebugEnvironmentReplace"): - clientEnv = {} - else: - clientEnv = os.environ.copy() - envlist = Utilities.parseEnvironmentString( - Preferences.getDebugger("DebugEnvironment")) - for el in envlist: - try: - key, value = el.split('=', 1) - if value.startswith('"') or value.startswith("'"): - value = value[1:-1] - clientEnv[str(key)] = str(value) - except ValueError: - pass - - ipaddr = self.debugServer.getHostAddress(True) - if runInConsole or Preferences.getDebugger("ConsoleDbgEnabled"): - ccmd = Preferences.getDebugger("ConsoleDbgCommand") - if ccmd: - args = Utilities.parseOptionString(ccmd) + \ - [interpreter, os.path.abspath(debugClient), - noencoding, str(port), '0', ipaddr] - args[0] = Utilities.getExecutablePath(args[0]) - process = self.__startProcess(args[0], args[1:], clientEnv) - if process is None: - E5MessageBox.critical( - None, - self.tr("Start Debugger"), - self.tr( - """<p>The debugger backend could not be""" - """ started.</p>""")) - return process, self.__isNetworked, interpreter - - process = self.__startProcess( - interpreter, - [debugClient, noencoding, str(port), redirect, ipaddr], - clientEnv) - if process is None: - E5MessageBox.critical( - None, - self.tr("Start Debugger"), - self.tr( - """<p>The debugger backend could not be started.</p>""")) - return process, self.__isNetworked, interpreter - - def startRemoteForProject(self, port, runInConsole): - """ - Public method to start a remote Python interpreter for a project. - - @param port portnumber the debug server is listening on (integer) - @param runInConsole flag indicating to start the debugger in a - console window (boolean) - @return client process object (QProcess), a flag to indicate - a network connection (boolean) and the name of the interpreter - in case of a local execution (string) - """ - project = e5App().getObject("Project") - if not project.isDebugPropertiesLoaded(): - return None, self.__isNetworked, "" - - # start debugger with project specific settings - interpreter = project.getDebugProperty("INTERPRETER") - debugClient = project.getDebugProperty("DEBUGCLIENT") - - redirect = str(project.getDebugProperty("REDIRECT")) - noencoding = \ - project.getDebugProperty("NOENCODING") and '--no-encoding' or '' - - if project.getDebugProperty("REMOTEDEBUGGER"): - ipaddr = self.debugServer.getHostAddress(False) - rexec = project.getDebugProperty("REMOTECOMMAND") - rhost = project.getDebugProperty("REMOTEHOST") - if rhost == "": - rhost = "localhost" - if rexec: - args = Utilities.parseOptionString(rexec) + \ - [rhost, interpreter, os.path.abspath(debugClient), - noencoding, str(port), redirect, ipaddr] - args[0] = Utilities.getExecutablePath(args[0]) - process = self.__startProcess(args[0], args[1:]) - if process is None: - E5MessageBox.critical( - None, - self.tr("Start Debugger"), - self.tr( - """<p>The debugger backend could not be""" - """ started.</p>""")) - # set translation function - if project.getDebugProperty("PATHTRANSLATION"): - self.translateRemote = \ - project.getDebugProperty("REMOTEPATH") - self.translateLocal = \ - project.getDebugProperty("LOCALPATH") - self.translate = self.__remoteTranslation - else: - self.translate = self.__identityTranslation - return process, self.__isNetworked, "" - - # set translation function - self.translate = self.__identityTranslation - - # setup the environment for the debugger - if project.getDebugProperty("ENVIRONMENTOVERRIDE"): - clientEnv = {} - else: - clientEnv = os.environ.copy() - envlist = Utilities.parseEnvironmentString( - project.getDebugProperty("ENVIRONMENTSTRING")) - for el in envlist: - try: - key, value = el.split('=', 1) - if value.startswith('"') or value.startswith("'"): - value = value[1:-1] - clientEnv[str(key)] = str(value) - except ValueError: - pass - - ipaddr = self.debugServer.getHostAddress(True) - if runInConsole or project.getDebugProperty("CONSOLEDEBUGGER"): - ccmd = project.getDebugProperty("CONSOLECOMMAND") or \ - Preferences.getDebugger("ConsoleDbgCommand") - if ccmd: - args = Utilities.parseOptionString(ccmd) + \ - [interpreter, os.path.abspath(debugClient), - noencoding, str(port), '0', ipaddr] - args[0] = Utilities.getExecutablePath(args[0]) - process = self.__startProcess(args[0], args[1:], clientEnv) - if process is None: - E5MessageBox.critical( - None, - self.tr("Start Debugger"), - self.tr( - """<p>The debugger backend could not be""" - """ started.</p>""")) - return process, self.__isNetworked, interpreter - - process = self.__startProcess( - interpreter, - [debugClient, noencoding, str(port), redirect, ipaddr], - clientEnv) - if process is None: - E5MessageBox.critical( - None, - self.tr("Start Debugger"), - self.tr( - """<p>The debugger backend could not be started.</p>""")) - return process, self.__isNetworked, interpreter - - def getClientCapabilities(self): - """ - Public method to retrieve the debug clients capabilities. - - @return debug client capabilities (integer) - """ - return self.clientCapabilities - - def newConnection(self, sock): - """ - Public slot to handle a new connection. - - @param sock reference to the socket object (QTcpSocket) - @return flag indicating success (boolean) - """ - # If we already have a connection, refuse this one. It will be closed - # automatically. - if self.qsock is not None: - return False - - sock.disconnected.connect(self.debugServer.startClient) - sock.readyRead.connect(self.__parseClientLine) - - self.qsock = sock - - # Get the remote clients capabilities - self.remoteCapabilities() - return True - - def flush(self): - """ - Public slot to flush the queue. - """ - # Send commands that were waiting for the connection. - for cmd in self.queue: - self.qsock.write(cmd.encode('utf8')) - - self.queue = [] - - def shutdown(self): - """ - Public method to cleanly shut down. - - It closes our socket and shuts down - the debug client. (Needed on Win OS) - """ - if self.qsock is None: - return - - # do not want any slots called during shutdown - self.qsock.disconnected.disconnect(self.debugServer.startClient) - self.qsock.readyRead.disconnect(self.__parseClientLine) - - # close down socket, and shut down client as well. - self.__sendCommand('{0}\n'.format(DebugProtocol.RequestShutdown)) - self.qsock.flush() - - self.qsock.close() - - # reinitialize - self.qsock = None - self.queue = [] - - def isConnected(self): - """ - Public method to test, if a debug client has connected. - - @return flag indicating the connection status (boolean) - """ - return self.qsock is not None - - def remoteEnvironment(self, env): - """ - Public method to set the environment for a program to debug, run, ... - - @param env environment settings (dictionary) - """ - self.__sendCommand('{0}{1}\n'.format( - DebugProtocol.RequestEnv, str(env))) - - def remoteLoad(self, fn, argv, wd, traceInterpreter=False, - autoContinue=True, autoFork=False, forkChild=False): - """ - Public method to load a new program to debug. - - @param fn the filename to debug (string) - @param argv the commandline arguments to pass to the program (string) - @param wd the working directory for the program (string) - @keyparam traceInterpreter flag indicating if the interpreter library - should be traced as well (boolean) - @keyparam autoContinue flag indicating, that the debugger should not - stop at the first executable line (boolean) - @keyparam autoFork flag indicating the automatic fork mode (boolean) - @keyparam forkChild flag indicating to debug the child after forking - (boolean) - """ - self.__autoContinue = autoContinue - self.__scriptName = os.path.abspath(fn) - - wd = self.translate(wd, False) - fn = self.translate(os.path.abspath(fn), False) - self.__sendCommand('{0}{1}\n'.format( - DebugProtocol.RequestForkMode, repr((autoFork, forkChild)))) - self.__sendCommand('{0}{1}|{2}|{3}|{4:d}\n'.format( - DebugProtocol.RequestLoad, wd, fn, - str(Utilities.parseOptionString(argv)), - traceInterpreter)) - - def remoteRun(self, fn, argv, wd, autoFork=False, forkChild=False): - """ - Public method to load a new program to run. - - @param fn the filename to run (string) - @param argv the commandline arguments to pass to the program (string) - @param wd the working directory for the program (string) - @keyparam autoFork flag indicating the automatic fork mode (boolean) - @keyparam forkChild flag indicating to debug the child after forking - (boolean) - """ - self.__scriptName = os.path.abspath(fn) - - wd = self.translate(wd, False) - fn = self.translate(os.path.abspath(fn), False) - self.__sendCommand('{0}{1}\n'.format( - DebugProtocol.RequestForkMode, repr((autoFork, forkChild)))) - self.__sendCommand('{0}{1}|{2}|{3}\n'.format( - DebugProtocol.RequestRun, wd, fn, - str(Utilities.parseOptionString(argv)))) - - def remoteCoverage(self, fn, argv, wd, erase=False): - """ - Public method to load a new program to collect coverage data. - - @param fn the filename to run (string) - @param argv the commandline arguments to pass to the program (string) - @param wd the working directory for the program (string) - @keyparam erase flag indicating that coverage info should be - cleared first (boolean) - """ - self.__scriptName = os.path.abspath(fn) - - wd = self.translate(wd, False) - fn = self.translate(os.path.abspath(fn), False) - self.__sendCommand('{0}{1}@@{2}@@{3}@@{4:d}\n'.format( - DebugProtocol.RequestCoverage, wd, fn, - str(Utilities.parseOptionString(argv)), erase)) - - def remoteProfile(self, fn, argv, wd, erase=False): - """ - Public method to load a new program to collect profiling data. - - @param fn the filename to run (string) - @param argv the commandline arguments to pass to the program (string) - @param wd the working directory for the program (string) - @keyparam erase flag indicating that timing info should be cleared - first (boolean) - """ - self.__scriptName = os.path.abspath(fn) - - wd = self.translate(wd, False) - fn = self.translate(os.path.abspath(fn), False) - self.__sendCommand('{0}{1}|{2}|{3}|{4:d}\n'.format( - DebugProtocol.RequestProfile, wd, fn, - str(Utilities.parseOptionString(argv)), erase)) - - def remoteStatement(self, stmt): - """ - Public method to execute a Python statement. - - @param stmt the Python statement to execute (string). It - should not have a trailing newline. - """ - self.__sendCommand('{0}\n'.format(stmt)) - self.__sendCommand(DebugProtocol.RequestOK + '\n') - - def remoteStep(self): - """ - Public method to single step the debugged program. - """ - self.__sendCommand(DebugProtocol.RequestStep + '\n') - - def remoteStepOver(self): - """ - Public method to step over the debugged program. - """ - self.__sendCommand(DebugProtocol.RequestStepOver + '\n') - - def remoteStepOut(self): - """ - Public method to step out the debugged program. - """ - self.__sendCommand(DebugProtocol.RequestStepOut + '\n') - - def remoteStepQuit(self): - """ - Public method to stop the debugged program. - """ - self.__sendCommand(DebugProtocol.RequestStepQuit + '\n') - - def remoteContinue(self, special=False): - """ - Public method to continue the debugged program. - - @param special flag indicating a special continue operation (boolean) - """ - self.__sendCommand('{0}{1:d}\n'.format( - DebugProtocol.RequestContinue, special)) - - def remoteBreakpoint(self, fn, line, set, cond=None, temp=False): - """ - Public method to set or clear a breakpoint. - - @param fn filename the breakpoint belongs to (string) - @param line linenumber of the breakpoint (int) - @param set flag indicating setting or resetting a breakpoint (boolean) - @param cond condition of the breakpoint (string) - @param temp flag indicating a temporary breakpoint (boolean) - """ - fn = self.translate(fn, False) - self.__sendCommand('{0}{1}@@{2:d}@@{3:d}@@{4:d}@@{5}\n'.format( - DebugProtocol.RequestBreak, fn, line, temp, set, - cond)) - - def remoteBreakpointEnable(self, fn, line, enable): - """ - Public method to enable or disable a breakpoint. - - @param fn filename the breakpoint belongs to (string) - @param line linenumber of the breakpoint (int) - @param enable flag indicating enabling or disabling a breakpoint - (boolean) - """ - fn = self.translate(fn, False) - self.__sendCommand('{0}{1},{2:d},{3:d}\n'.format( - DebugProtocol.RequestBreakEnable, fn, line, enable)) - - def remoteBreakpointIgnore(self, fn, line, count): - """ - Public method to ignore a breakpoint the next couple of occurrences. - - @param fn filename the breakpoint belongs to (string) - @param line linenumber of the breakpoint (int) - @param count number of occurrences to ignore (int) - """ - fn = self.translate(fn, False) - self.__sendCommand('{0}{1},{2:d},{3:d}\n'.format( - DebugProtocol.RequestBreakIgnore, fn, line, count)) - - def remoteWatchpoint(self, cond, set, temp=False): - """ - Public method to set or clear a watch expression. - - @param cond expression of the watch expression (string) - @param set flag indicating setting or resetting a watch expression - (boolean) - @param temp flag indicating a temporary watch expression (boolean) - """ - # cond is combination of cond and special (s. watch expression viewer) - self.__sendCommand('{0}{1}@@{2:d}@@{3:d}\n'.format( - DebugProtocol.RequestWatch, cond, temp, set)) - - def remoteWatchpointEnable(self, cond, enable): - """ - Public method to enable or disable a watch expression. - - @param cond expression of the watch expression (string) - @param enable flag indicating enabling or disabling a watch expression - (boolean) - """ - # cond is combination of cond and special (s. watch expression viewer) - self.__sendCommand('{0}{1},{2:d}\n'.format( - DebugProtocol.RequestWatchEnable, cond, enable)) - - def remoteWatchpointIgnore(self, cond, count): - """ - Public method to ignore a watch expression the next couple of - occurrences. - - @param cond expression of the watch expression (string) - @param count number of occurrences to ignore (int) - """ - # cond is combination of cond and special (s. watch expression viewer) - self.__sendCommand('{0}{1},{2:d}\n'.format( - DebugProtocol.RequestWatchIgnore, cond, count)) - - def remoteRawInput(self, s): - """ - Public method to send the raw input to the debugged program. - - @param s the raw input (string) - """ - self.__sendCommand(s + '\n') - - def remoteThreadList(self): - """ - Public method to request the list of threads from the client. - """ - self.__sendCommand('{0}\n'.format(DebugProtocol.RequestThreadList)) - - def remoteSetThread(self, tid): - """ - Public method to request to set the given thread as current thread. - - @param tid id of the thread (integer) - """ - self.__sendCommand('{0}{1:d}\n'.format( - DebugProtocol.RequestThreadSet, tid)) - - def remoteClientVariables(self, scope, filter, framenr=0): - """ - Public method to request the variables of the debugged program. - - @param scope the scope of the variables (0 = local, 1 = global) - @param filter list of variable types to filter out (list of int) - @param framenr framenumber of the variables to retrieve (int) - """ - self.__sendCommand('{0}{1:d}, {2:d}, {3}\n'.format( - DebugProtocol.RequestVariables, framenr, scope, str(filter))) - - def remoteClientVariable(self, scope, filter, var, framenr=0): - """ - Public method to request the variables of the debugged program. - - @param scope the scope of the variables (0 = local, 1 = global) - @param filter list of variable types to filter out (list of int) - @param var list encoded name of variable to retrieve (string) - @param framenr framenumber of the variables to retrieve (int) - """ - self.__sendCommand('{0}{1}, {2:d}, {3:d}, {4}\n'.format( - DebugProtocol.RequestVariable, str(var), framenr, scope, - str(filter))) - - def remoteClientSetFilter(self, scope, filter): - """ - Public method to set a variables filter list. - - @param scope the scope of the variables (0 = local, 1 = global) - @param filter regexp string for variable names to filter out (string) - """ - self.__sendCommand('{0}{1:d}, "{2}"\n'.format( - DebugProtocol.RequestSetFilter, scope, filter)) - - def setCallTraceEnabled(self, on): - """ - Public method to set the call trace state. - - @param on flag indicating to enable the call trace function (boolean) - """ - if on: - cmd = "on" - else: - cmd = "off" - self.__sendCommand('{0}{1}\n'.format( - DebugProtocol.RequestCallTrace, cmd)) - - def remoteEval(self, arg): - """ - Public method to evaluate arg in the current context of the debugged - program. - - @param arg the arguments to evaluate (string) - """ - self.__sendCommand('{0}{1}\n'.format(DebugProtocol.RequestEval, arg)) - - def remoteExec(self, stmt): - """ - Public method to execute stmt in the current context of the debugged - program. - - @param stmt statement to execute (string) - """ - self.__sendCommand('{0}{1}\n'.format(DebugProtocol.RequestExec, stmt)) - - def remoteBanner(self): - """ - Public slot to get the banner info of the remote client. - """ - self.__sendCommand(DebugProtocol.RequestBanner + '\n') - - def remoteCapabilities(self): - """ - Public slot to get the debug clients capabilities. - """ - self.__sendCommand(DebugProtocol.RequestCapabilities + '\n') - - def remoteCompletion(self, text): - """ - Public slot to get the a list of possible commandline completions - from the remote client. - - @param text the text to be completed (string) - """ - self.__sendCommand("{0}{1}\n".format( - DebugProtocol.RequestCompletion, text)) - - def remoteUTPrepare(self, fn, tn, tfn, failed, cov, covname, coverase): - """ - Public method to prepare a new unittest run. - - @param fn the filename to load (string) - @param tn the testname to load (string) - @param tfn the test function name to load tests from (string) - @param failed list of failed test, if only failed test should be run - (list of strings) - @param cov flag indicating collection of coverage data is requested - (boolean) - @param covname filename to be used to assemble the coverage caches - filename (string) - @param coverase flag indicating erasure of coverage data is requested - (boolean) - """ - self.__scriptName = os.path.abspath(fn) - - fn = self.translate(os.path.abspath(fn), False) - self.__sendCommand('{0}{1}|{2}|{3}|{4}|{5:d}|{6}|{7:d}\n'.format( - DebugProtocol.RequestUTPrepare, fn, tn, tfn, str(failed), - cov, covname, coverase)) - - def remoteUTRun(self): - """ - Public method to start a unittest run. - """ - self.__sendCommand('{0}\n'.format(DebugProtocol.RequestUTRun)) - - def remoteUTStop(self): - """ - Public method to stop a unittest run. - """ - self.__sendCommand('{0}\n'.format(DebugProtocol.RequestUTStop)) - - def __askForkTo(self): - """ - Private method to ask the user which branch of a fork to follow. - """ - selections = [self.tr("Parent Process"), - self.tr("Child process")] - res, ok = QInputDialog.getItem( - None, - self.tr("Client forking"), - self.tr("Select the fork branch to follow."), - selections, - 0, False) - if not ok or res == selections[0]: - self.__sendCommand(DebugProtocol.ResponseForkTo + 'parent\n') - else: - self.__sendCommand(DebugProtocol.ResponseForkTo + 'child\n') - - def __parseClientLine(self): - """ - Private method to handle data from the client. - """ - while self.qsock and self.qsock.canReadLine(): - qs = self.qsock.readLine() - if self.codec is not None: - line = self.codec.toUnicode(qs) - else: - line = bytes(qs).decode() - if line.endswith(DebugProtocol.EOT): - line = line[:-len(DebugProtocol.EOT)] - if not line: - continue - -## print("Server: ", line) ##debug - - eoc = line.find('<') + 1 - - # Deal with case where user has written directly to stdout - # or stderr, but not line terminated and we stepped over the - # write call, in that case the >line< will not be the first - # string read from the socket... - boc = line.find('>') - if boc > 0 and eoc > boc: - self.debugServer.signalClientOutput(line[:boc]) - line = line[boc:] - eoc = line.find('<') + 1 - boc = line.find('>') - - if boc >= 0 and eoc > boc: - resp = line[boc:eoc] - evalArg = self.__unicodeRe.sub(r"\1", line[eoc:-1]) - - if resp == DebugProtocol.ResponseLine or \ - resp == DebugProtocol.ResponseStack: - stack = eval(evalArg) - for s in stack: - s[0] = self.translate(s[0], True) - cf = stack[0] - if self.__autoContinue: - self.__autoContinue = False - QTimer.singleShot(0, self.remoteContinue) - else: - self.debugServer.signalClientLine( - cf[0], int(cf[1]), - resp == DebugProtocol.ResponseStack) - self.debugServer.signalClientStack(stack) - continue - - if resp == DebugProtocol.CallTrace: - event, fromStr, toStr = line[eoc:-1].split("@@") - isCall = event.lower() == "c" - fromFile, fromLineno, fromFunc = fromStr.rsplit(":", 2) - toFile, toLineno, toFunc = toStr.rsplit(":", 2) - self.debugServer.signalClientCallTrace(isCall, fromFile, - fromLineno, - fromFunc, - toFile, toLineno, - toFunc) - continue - - if resp == DebugProtocol.ResponseThreadList: - currentId, threadList = eval(evalArg) - self.debugServer.signalClientThreadList( - currentId, threadList) - continue - - if resp == DebugProtocol.ResponseThreadSet: - self.debugServer.signalClientThreadSet() - continue - - if resp == DebugProtocol.ResponseVariables: - vlist = eval(evalArg) - scope = vlist[0] - try: - variables = vlist[1:] - except IndexError: - variables = [] - self.debugServer.signalClientVariables(scope, variables) - continue - - if resp == DebugProtocol.ResponseVariable: - vlist = eval(evalArg) - scope = vlist[0] - try: - variables = vlist[1:] - except IndexError: - variables = [] - self.debugServer.signalClientVariable(scope, variables) - continue - - if resp == DebugProtocol.ResponseOK: - self.debugServer.signalClientStatement(False) - continue - - if resp == DebugProtocol.ResponseContinue: - self.debugServer.signalClientStatement(True) - continue - - if resp == DebugProtocol.ResponseException: - exc = self.translate(evalArg, True) - try: - exclist = eval(exc) - exctype = exclist[0] - excmessage = exclist[1] - stack = exclist[2:] - if stack and stack[0] and stack[0][0] == "<string>": - for stackEntry in stack: - if stackEntry[0] == "<string>": - stackEntry[0] = self.__scriptName - else: - break - except (IndexError, ValueError, SyntaxError): - exctype = None - excmessage = '' - stack = [] - self.debugServer.signalClientException( - exctype, excmessage, stack) - continue - - if resp == DebugProtocol.ResponseSyntax: - exc = self.translate(evalArg, True) - try: - message, (fn, ln, cn) = eval(exc) - if fn is None: - fn = '' - except (IndexError, ValueError): - message = None - fn = '' - ln = 0 - cn = 0 - if cn is None: - cn = 0 - self.debugServer.signalClientSyntaxError( - message, fn, ln, cn) - continue - - if resp == DebugProtocol.ResponseSignal: - sig = self.translate(evalArg, True) - message, (fn, ln, func, args) = eval(sig) - self.debugServer.signalClientSignal( - message, fn, ln, func, args) - continue - - if resp == DebugProtocol.ResponseExit: - self.__scriptName = "" - self.debugServer.signalClientExit(evalArg) - continue - - if resp == DebugProtocol.ResponseClearBreak: - fn, lineno = evalArg.split(',') - lineno = int(lineno) - fn = self.translate(fn, True) - self.debugServer.signalClientClearBreak(fn, lineno) - continue - - if resp == DebugProtocol.ResponseBPConditionError: - fn, lineno = evalArg.split(',') - lineno = int(lineno) - fn = self.translate(fn, True) - self.debugServer.signalClientBreakConditionError( - fn, lineno) - continue - - if resp == DebugProtocol.ResponseClearWatch: - self.debugServer.signalClientClearWatch(evalArg) - continue - - if resp == DebugProtocol.ResponseWPConditionError: - self.debugServer.signalClientWatchConditionError(evalArg) - continue - - if resp == DebugProtocol.ResponseRaw: - prompt, echo = eval(evalArg) - self.debugServer.signalClientRawInput(prompt, echo) - continue - - if resp == DebugProtocol.ResponseBanner: - version, platform, dbgclient = eval(evalArg) - self.debugServer.signalClientBanner( - version, platform, dbgclient) - continue - - if resp == DebugProtocol.ResponseCapabilities: - cap, clType = eval(evalArg) - self.clientCapabilities = cap - self.debugServer.signalClientCapabilities(cap, clType) - continue - - if resp == DebugProtocol.ResponseCompletion: - clstring, text = evalArg.split('||') - cl = eval(clstring) - self.debugServer.signalClientCompletionList(cl, text) - continue - - if resp == DebugProtocol.PassiveStartup: - fn, exc = evalArg.split('|') - exc = bool(exc) - fn = self.translate(fn, True) - self.debugServer.passiveStartUp(fn, exc) - continue - - if resp == DebugProtocol.ResponseUTPrepared: - res, exc_type, exc_value = eval(evalArg) - self.debugServer.clientUtPrepared(res, exc_type, exc_value) - continue - - if resp == DebugProtocol.ResponseUTStartTest: - testname, doc = eval(evalArg) - self.debugServer.clientUtStartTest(testname, doc) - continue - - if resp == DebugProtocol.ResponseUTStopTest: - self.debugServer.clientUtStopTest() - continue - - if resp == DebugProtocol.ResponseUTTestFailed: - testname, traceback, id = eval(evalArg) - self.debugServer.clientUtTestFailed( - testname, traceback, id) - continue - - if resp == DebugProtocol.ResponseUTTestErrored: - testname, traceback, id = eval(evalArg) - self.debugServer.clientUtTestErrored( - testname, traceback, id) - continue - - if resp == DebugProtocol.ResponseUTTestSkipped: - testname, reason, id = eval(line[eoc:-1]) - self.debugServer.clientUtTestSkipped(testname, reason, id) - continue - - if resp == DebugProtocol.ResponseUTTestFailedExpected: - testname, traceback, id = eval(line[eoc:-1]) - self.debugServer.clientUtTestFailedExpected( - testname, traceback, id) - continue - - if resp == DebugProtocol.ResponseUTTestSucceededUnexpected: - testname, id = eval(line[eoc:-1]) - self.debugServer.clientUtTestSucceededUnexpected( - testname, id) - continue - - if resp == DebugProtocol.ResponseUTFinished: - self.debugServer.clientUtFinished() - continue - - if resp == DebugProtocol.RequestForkTo: - self.__askForkTo() - continue - - self.debugServer.signalClientOutput(line) - - def __sendCommand(self, cmd): - """ - Private method to send a single line command to the client. - - @param cmd command to send to the debug client (string) - """ - if self.qsock is not None: - self.qsock.write(cmd.encode('utf8')) - else: - self.queue.append(cmd) - - -def createDebuggerInterfacePython(debugServer, passive): - """ - Module function to create a debugger interface instance. - - - @param debugServer reference to the debug server - @type DebugServer - @param passive flag indicating passive connection mode - @type bool - @return instantiated debugger interface - @rtype DebuggerInterfacePython - """ - return DebuggerInterfacePython(debugServer, passive) - - -def getRegistryData(): - """ - Module function to get characterizing data for the debugger interface. - - @return tuple containing client type, client capabilities, client file - type associations and reference to creation function - @rtype tuple of (str, int, list of str, function) - """ - exts = [] - for ext in Preferences.getDebugger("PythonExtensions").split(): - if ext.startswith("."): - exts.append(ext) - else: - exts.append(".{0}".format(ext)) - - if exts and Preferences.getDebugger("PythonInterpreter"): - return ["Python2", ClientDefaultCapabilities, exts, - createDebuggerInterfacePython] - else: - return ["", 0, [], None]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Debugger/DebuggerInterfacePython2.py Sat Sep 03 18:02:37 2016 +0200 @@ -0,0 +1,1080 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2007 - 2016 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing the Python debugger interface for the debug server. +""" + +from __future__ import unicode_literals + +import sys +import os + +from PyQt5.QtCore import QObject, QTextCodec, QProcess, QProcessEnvironment, \ + QTimer +from PyQt5.QtWidgets import QInputDialog + +from E5Gui.E5Application import e5App +from E5Gui import E5MessageBox + +from . import DebugClientCapabilities + +import Preferences +import Utilities + +from eric6config import getConfig + + +ClientDefaultCapabilities = DebugClientCapabilities.HasAll + + +class DebuggerInterfacePython2(QObject): + """ + Class implementing the Python 2 debugger interface for the debug server. + """ + def __init__(self, debugServer, passive): + """ + Constructor + + @param debugServer reference to the debug server (DebugServer) + @param passive flag indicating passive connection mode (boolean) + """ + super(DebuggerInterfacePython2, self).__init__() + + self.__isNetworked = True + self.__autoContinue = False + + self.debugServer = debugServer + self.passive = passive + self.process = None + + self.qsock = None + self.queue = [] + + # set default values for capabilities of clients + self.clientCapabilities = ClientDefaultCapabilities + + # set translation function + self.translate = self.__identityTranslation + + self.codec = QTextCodec.codecForName( + Preferences.getSystem("StringEncoding")) + + if passive: + # set translation function + if Preferences.getDebugger("PathTranslation"): + self.translateRemote = \ + Preferences.getDebugger("PathTranslationRemote") + self.translateLocal = \ + Preferences.getDebugger("PathTranslationLocal") + self.translate = self.__remoteTranslation + else: + self.translate = self.__identityTranslation + + # attribute to remember the name of the executed script + self.__scriptName = "" + + def __identityTranslation(self, fn, remote2local=True): + """ + Private method to perform the identity path translation. + + @param fn filename to be translated (string) + @param remote2local flag indicating the direction of translation + (False = local to remote, True = remote to local [default]) + @return translated filename (string) + """ + return fn + + def __remoteTranslation(self, fn, remote2local=True): + """ + Private method to perform the path translation. + + @param fn filename to be translated (string) + @param remote2local flag indicating the direction of translation + (False = local to remote, True = remote to local [default]) + @return translated filename (string) + """ + if remote2local: + return fn.replace(self.translateRemote, self.translateLocal) + else: + return fn.replace(self.translateLocal, self.translateRemote) + + def __startProcess(self, program, arguments, environment=None): + """ + Private method to start the debugger client process. + + @param program name of the executable to start (string) + @param arguments arguments to be passed to the program (list of string) + @param environment dictionary of environment settings to pass + (dict of string) + @return the process object (QProcess) or None + """ + proc = QProcess() + if environment is not None: + env = QProcessEnvironment() + for key, value in list(environment.items()): + env.insert(key, value) + proc.setProcessEnvironment(env) + args = [] + for arg in arguments: + args.append(arg) + proc.start(program, args) + if not proc.waitForStarted(10000): + proc = None + + return proc + + def startRemote(self, port, runInConsole): + """ + Public method to start a remote Python interpreter. + + @param port portnumber the debug server is listening on (integer) + @param runInConsole flag indicating to start the debugger in a + console window (boolean) + @return client process object (QProcess), a flag to indicate + a network connection (boolean) and the name of the interpreter + in case of a local execution (string) + """ + interpreter = Preferences.getDebugger("PythonInterpreter") + if interpreter == "": + E5MessageBox.critical( + None, + self.tr("Start Debugger"), + self.tr( + """<p>No Python2 interpreter configured.</p>""")) + return None, False, "" + + debugClientType = Preferences.getDebugger("DebugClientType") + if debugClientType == "standard": + debugClient = os.path.join(getConfig('ericDir'), + "DebugClients", "Python", + "DebugClient.py") + elif debugClientType == "threaded": + debugClient = os.path.join(getConfig('ericDir'), + "DebugClients", "Python", + "DebugClientThreads.py") + else: + debugClient = Preferences.getDebugger("DebugClient") + if debugClient == "": + debugClient = os.path.join(sys.path[0], + "DebugClients", "Python", + "DebugClient.py") + + redirect = str(Preferences.getDebugger("PythonRedirect")) + noencoding = Preferences.getDebugger("PythonNoEncoding") and \ + '--no-encoding' or '' + + if Preferences.getDebugger("RemoteDbgEnabled"): + ipaddr = self.debugServer.getHostAddress(False) + rexec = Preferences.getDebugger("RemoteExecution") + rhost = Preferences.getDebugger("RemoteHost") + if rhost == "": + rhost = "localhost" + if rexec: + args = Utilities.parseOptionString(rexec) + \ + [rhost, interpreter, debugClient, + noencoding, str(port), redirect, ipaddr] + args[0] = Utilities.getExecutablePath(args[0]) + process = self.__startProcess(args[0], args[1:]) + if process is None: + E5MessageBox.critical( + None, + self.tr("Start Debugger"), + self.tr( + """<p>The debugger backend could not be""" + """ started.</p>""")) + + # set translation function + if Preferences.getDebugger("PathTranslation"): + self.translateRemote = \ + Preferences.getDebugger("PathTranslationRemote") + self.translateLocal = \ + Preferences.getDebugger("PathTranslationLocal") + self.translate = self.__remoteTranslation + else: + self.translate = self.__identityTranslation + return process, self.__isNetworked, "" + + # set translation function + self.translate = self.__identityTranslation + + # setup the environment for the debugger + if Preferences.getDebugger("DebugEnvironmentReplace"): + clientEnv = {} + else: + clientEnv = os.environ.copy() + envlist = Utilities.parseEnvironmentString( + Preferences.getDebugger("DebugEnvironment")) + for el in envlist: + try: + key, value = el.split('=', 1) + if value.startswith('"') or value.startswith("'"): + value = value[1:-1] + clientEnv[str(key)] = str(value) + except ValueError: + pass + + ipaddr = self.debugServer.getHostAddress(True) + if runInConsole or Preferences.getDebugger("ConsoleDbgEnabled"): + ccmd = Preferences.getDebugger("ConsoleDbgCommand") + if ccmd: + args = Utilities.parseOptionString(ccmd) + \ + [interpreter, os.path.abspath(debugClient), + noencoding, str(port), '0', ipaddr] + args[0] = Utilities.getExecutablePath(args[0]) + process = self.__startProcess(args[0], args[1:], clientEnv) + if process is None: + E5MessageBox.critical( + None, + self.tr("Start Debugger"), + self.tr( + """<p>The debugger backend could not be""" + """ started.</p>""")) + return process, self.__isNetworked, interpreter + + process = self.__startProcess( + interpreter, + [debugClient, noencoding, str(port), redirect, ipaddr], + clientEnv) + if process is None: + E5MessageBox.critical( + None, + self.tr("Start Debugger"), + self.tr( + """<p>The debugger backend could not be started.</p>""")) + return process, self.__isNetworked, interpreter + + def startRemoteForProject(self, port, runInConsole): + """ + Public method to start a remote Python interpreter for a project. + + @param port portnumber the debug server is listening on (integer) + @param runInConsole flag indicating to start the debugger in a + console window (boolean) + @return client process object (QProcess), a flag to indicate + a network connection (boolean) and the name of the interpreter + in case of a local execution (string) + """ + project = e5App().getObject("Project") + if not project.isDebugPropertiesLoaded(): + return None, self.__isNetworked, "" + + # start debugger with project specific settings + interpreter = project.getDebugProperty("INTERPRETER") + debugClient = project.getDebugProperty("DEBUGCLIENT") + + redirect = str(project.getDebugProperty("REDIRECT")) + noencoding = \ + project.getDebugProperty("NOENCODING") and '--no-encoding' or '' + + if project.getDebugProperty("REMOTEDEBUGGER"): + ipaddr = self.debugServer.getHostAddress(False) + rexec = project.getDebugProperty("REMOTECOMMAND") + rhost = project.getDebugProperty("REMOTEHOST") + if rhost == "": + rhost = "localhost" + if rexec: + args = Utilities.parseOptionString(rexec) + \ + [rhost, interpreter, os.path.abspath(debugClient), + noencoding, str(port), redirect, ipaddr] + args[0] = Utilities.getExecutablePath(args[0]) + process = self.__startProcess(args[0], args[1:]) + if process is None: + E5MessageBox.critical( + None, + self.tr("Start Debugger"), + self.tr( + """<p>The debugger backend could not be""" + """ started.</p>""")) + # set translation function + if project.getDebugProperty("PATHTRANSLATION"): + self.translateRemote = \ + project.getDebugProperty("REMOTEPATH") + self.translateLocal = \ + project.getDebugProperty("LOCALPATH") + self.translate = self.__remoteTranslation + else: + self.translate = self.__identityTranslation + return process, self.__isNetworked, "" + + # set translation function + self.translate = self.__identityTranslation + + # setup the environment for the debugger + if project.getDebugProperty("ENVIRONMENTOVERRIDE"): + clientEnv = {} + else: + clientEnv = os.environ.copy() + envlist = Utilities.parseEnvironmentString( + project.getDebugProperty("ENVIRONMENTSTRING")) + for el in envlist: + try: + key, value = el.split('=', 1) + if value.startswith('"') or value.startswith("'"): + value = value[1:-1] + clientEnv[str(key)] = str(value) + except ValueError: + pass + + ipaddr = self.debugServer.getHostAddress(True) + if runInConsole or project.getDebugProperty("CONSOLEDEBUGGER"): + ccmd = project.getDebugProperty("CONSOLECOMMAND") or \ + Preferences.getDebugger("ConsoleDbgCommand") + if ccmd: + args = Utilities.parseOptionString(ccmd) + \ + [interpreter, os.path.abspath(debugClient), + noencoding, str(port), '0', ipaddr] + args[0] = Utilities.getExecutablePath(args[0]) + process = self.__startProcess(args[0], args[1:], clientEnv) + if process is None: + E5MessageBox.critical( + None, + self.tr("Start Debugger"), + self.tr( + """<p>The debugger backend could not be""" + """ started.</p>""")) + return process, self.__isNetworked, interpreter + + process = self.__startProcess( + interpreter, + [debugClient, noencoding, str(port), redirect, ipaddr], + clientEnv) + if process is None: + E5MessageBox.critical( + None, + self.tr("Start Debugger"), + self.tr( + """<p>The debugger backend could not be started.</p>""")) + return process, self.__isNetworked, interpreter + + def getClientCapabilities(self): + """ + Public method to retrieve the debug clients capabilities. + + @return debug client capabilities (integer) + """ + return self.clientCapabilities + + def newConnection(self, sock): + """ + Public slot to handle a new connection. + + @param sock reference to the socket object (QTcpSocket) + @return flag indicating success (boolean) + """ + # If we already have a connection, refuse this one. It will be closed + # automatically. + if self.qsock is not None: + return False + + sock.disconnected.connect(self.debugServer.startClient) + sock.readyRead.connect(self.__parseClientLine) + + self.qsock = sock + + # Get the remote clients capabilities + self.remoteCapabilities() + return True + + def flush(self): + """ + Public slot to flush the queue. + """ + # Send commands that were waiting for the connection. + for cmd in self.queue: + self.qsock.write(cmd.encode('utf8', 'backslashreplace')) + + self.queue = [] + + def shutdown(self): + """ + Public method to cleanly shut down. + + It closes our socket and shuts down + the debug client. (Needed on Win OS) + """ + if self.qsock is None: + return + + # do not want any slots called during shutdown + self.qsock.disconnected.disconnect(self.debugServer.startClient) + self.qsock.readyRead.disconnect(self.__parseClientLine) + + # close down socket, and shut down client as well. + self.__sendJsonCommand("RequestShutdown", {}) + self.qsock.flush() + self.qsock.close() + + # reinitialize + self.qsock = None + self.queue = [] + + def isConnected(self): + """ + Public method to test, if a debug client has connected. + + @return flag indicating the connection status (boolean) + """ + return self.qsock is not None + + def remoteEnvironment(self, env): + """ + Public method to set the environment for a program to debug, run, ... + + @param env environment settings (dictionary) + """ + self.__sendJsonCommand("RequestEnvironment", {"environment": env}) + + def remoteLoad(self, fn, argv, wd, traceInterpreter=False, + autoContinue=True, autoFork=False, forkChild=False): + """ + Public method to load a new program to debug. + + @param fn the filename to debug (string) + @param argv the commandline arguments to pass to the program (string) + @param wd the working directory for the program (string) + @keyparam traceInterpreter flag indicating if the interpreter library + should be traced as well (boolean) + @keyparam autoContinue flag indicating, that the debugger should not + stop at the first executable line (boolean) + @keyparam autoFork flag indicating the automatic fork mode (boolean) + @keyparam forkChild flag indicating to debug the child after forking + (boolean) + """ + self.__autoContinue = autoContinue + self.__scriptName = os.path.abspath(fn) + + wd = self.translate(wd, False) + fn = self.translate(os.path.abspath(fn), False) + self.__sendJsonCommand("RequestLoad", { + "workdir": wd, + "filename": fn, + "argv": Utilities.parseOptionString(argv), + "traceInterpreter": traceInterpreter, + "autofork": autoFork, + "forkChild": forkChild, + }) + + def remoteRun(self, fn, argv, wd, autoFork=False, forkChild=False): + """ + Public method to load a new program to run. + + @param fn the filename to run (string) + @param argv the commandline arguments to pass to the program (string) + @param wd the working directory for the program (string) + @keyparam autoFork flag indicating the automatic fork mode (boolean) + @keyparam forkChild flag indicating to debug the child after forking + (boolean) + """ + self.__scriptName = os.path.abspath(fn) + + wd = self.translate(wd, False) + fn = self.translate(os.path.abspath(fn), False) + self.__sendJsonCommand("RequestRun", { + "workdir": wd, + "filename": fn, + "argv": Utilities.parseOptionString(argv), + "autofork": autoFork, + "forkChild": forkChild, + }) + + def remoteCoverage(self, fn, argv, wd, erase=False): + """ + Public method to load a new program to collect coverage data. + + @param fn the filename to run (string) + @param argv the commandline arguments to pass to the program (string) + @param wd the working directory for the program (string) + @keyparam erase flag indicating that coverage info should be + cleared first (boolean) + """ + self.__scriptName = os.path.abspath(fn) + + wd = self.translate(wd, False) + fn = self.translate(os.path.abspath(fn), False) + self.__sendJsonCommand("RequestCoverage", { + "workdir": wd, + "filename": fn, + "argv": Utilities.parseOptionString(argv), + "erase": erase, + }) + + def remoteProfile(self, fn, argv, wd, erase=False): + """ + Public method to load a new program to collect profiling data. + + @param fn the filename to run (string) + @param argv the commandline arguments to pass to the program (string) + @param wd the working directory for the program (string) + @keyparam erase flag indicating that timing info should be cleared + first (boolean) + """ + self.__scriptName = os.path.abspath(fn) + + wd = self.translate(wd, False) + fn = self.translate(os.path.abspath(fn), False) + self.__sendJsonCommand("RequestProfile", { + "workdir": wd, + "filename": fn, + "argv": Utilities.parseOptionString(argv), + "erase": erase, + }) + + def remoteStatement(self, stmt): + """ + Public method to execute a Python statement. + + @param stmt the Python statement to execute (string). It + should not have a trailing newline. + """ + self.__sendJsonCommand("ExecuteStatement", { + "statement": stmt, + }) + + def remoteStep(self): + """ + Public method to single step the debugged program. + """ + self.__sendJsonCommand("RequestStep", {}) + + def remoteStepOver(self): + """ + Public method to step over the debugged program. + """ + self.__sendJsonCommand("RequestStepOver", {}) + + def remoteStepOut(self): + """ + Public method to step out the debugged program. + """ + self.__sendJsonCommand("RequestStepOut", {}) + + def remoteStepQuit(self): + """ + Public method to stop the debugged program. + """ + self.__sendJsonCommand("RequestStepQuit", {}) + + def remoteContinue(self, special=False): + """ + Public method to continue the debugged program. + + @param special flag indicating a special continue operation (boolean) + """ + self.__sendJsonCommand("RequestContinue", { + "special": special, + }) + + def remoteBreakpoint(self, fn, line, setBreakpoint, cond=None, temp=False): + """ + Public method to set or clear a breakpoint. + + @param fn filename the breakpoint belongs to (string) + @param line linenumber of the breakpoint (int) + @param setBreakpoint flag indicating setting or resetting a + breakpoint (boolean) + @param cond condition of the breakpoint (string) + @param temp flag indicating a temporary breakpoint (boolean) + """ + self.__sendJsonCommand("RequestBreakpoint", { + "filename": self.translate(fn, False), + "line": line, + "temporary": temp, + "setBreakpoint": setBreakpoint, + "condition": cond, + }) + + def remoteBreakpointEnable(self, fn, line, enable): + """ + Public method to enable or disable a breakpoint. + + @param fn filename the breakpoint belongs to (string) + @param line linenumber of the breakpoint (int) + @param enable flag indicating enabling or disabling a breakpoint + (boolean) + """ + self.__sendJsonCommand("RequestBreakpointEnable", { + "filename": self.translate(fn, False), + "line": line, + "enable": enable, + }) + + def remoteBreakpointIgnore(self, fn, line, count): + """ + Public method to ignore a breakpoint the next couple of occurrences. + + @param fn filename the breakpoint belongs to (string) + @param line linenumber of the breakpoint (int) + @param count number of occurrences to ignore (int) + """ + self.__sendJsonCommand("RequestBreakpointIgnore", { + "filename": self.translate(fn, False), + "line": line, + "count": count, + }) + + def remoteWatchpoint(self, cond, setWatch, temp=False): + """ + Public method to set or clear a watch expression. + + @param cond expression of the watch expression (string) + @param setWatch flag indicating setting or resetting a watch expression + (boolean) + @param temp flag indicating a temporary watch expression (boolean) + """ + # cond is combination of cond and special (s. watch expression viewer) + self.__sendJsonCommand("RequestWatch", { + "temporary": temp, + "setWatch": setWatch, + "condition": cond, + }) + + def remoteWatchpointEnable(self, cond, enable): + """ + Public method to enable or disable a watch expression. + + @param cond expression of the watch expression (string) + @param enable flag indicating enabling or disabling a watch expression + (boolean) + """ + # cond is combination of cond and special (s. watch expression viewer) + self.__sendJsonCommand("RequestWatchEnable", { + "condition": cond, + "enable": enable, + }) + + def remoteWatchpointIgnore(self, cond, count): + """ + Public method to ignore a watch expression the next couple of + occurrences. + + @param cond expression of the watch expression (string) + @param count number of occurrences to ignore (int) + """ + # cond is combination of cond and special (s. watch expression viewer) + self.__sendJsonCommand("RequestWatchIgnore", { + "condition": cond, + "count": count, + }) + + def remoteRawInput(self, s): + """ + Public method to send the raw input to the debugged program. + + @param s the raw input (string) + """ + self.__sendJsonCommand("RawInput", { + "input": s, + }) + + def remoteThreadList(self): + """ + Public method to request the list of threads from the client. + """ + self.__sendJsonCommand("RequestThreadList", {}) + + def remoteSetThread(self, tid): + """ + Public method to request to set the given thread as current thread. + + @param tid id of the thread (integer) + """ + self.__sendJsonCommand("RequestThreadSet", { + "threadID": tid, + }) + + def remoteClientVariables(self, scope, filter, framenr=0): + """ + Public method to request the variables of the debugged program. + + @param scope the scope of the variables (0 = local, 1 = global) + @param filter list of variable types to filter out (list of int) + @param framenr framenumber of the variables to retrieve (int) + """ + self.__sendJsonCommand("RequestVariables", { + "frameNumber": framenr, + "scope": scope, + "filters": filter, + }) + + def remoteClientVariable(self, scope, filter, var, framenr=0): + """ + Public method to request the variables of the debugged program. + + @param scope the scope of the variables (0 = local, 1 = global) + @param filter list of variable types to filter out (list of int) + @param var list encoded name of variable to retrieve (string) + @param framenr framenumber of the variables to retrieve (int) + """ + self.__sendJsonCommand("RequestVariable", { + "variable": var, + "frameNumber": framenr, + "scope": scope, + "filters": filter, + }) + + def remoteClientSetFilter(self, scope, filter): + """ + Public method to set a variables filter list. + + @param scope the scope of the variables (0 = local, 1 = global) + @param filter regexp string for variable names to filter out (string) + """ + self.__sendJsonCommand("RequestSetFilter", { + "scope": scope, + "filter": filter, + }) + + def setCallTraceEnabled(self, on): + """ + Public method to set the call trace state. + + @param on flag indicating to enable the call trace function (boolean) + """ + self.__sendJsonCommand("RequestCallTrace", { + "enable": on, + }) + + def remoteBanner(self): + """ + Public slot to get the banner info of the remote client. + """ + self.__sendJsonCommand("RequestBanner", {}) + + def remoteCapabilities(self): + """ + Public slot to get the debug clients capabilities. + """ + self.__sendJsonCommand("RequestCapabilities", {}) + + def remoteCompletion(self, text): + """ + Public slot to get the a list of possible commandline completions + from the remote client. + + @param text the text to be completed (string) + """ + self.__sendJsonCommand("RequestCompletion", { + "text": text, + }) + + def remoteUTPrepare(self, fn, tn, tfn, failed, cov, covname, coverase): + """ + Public method to prepare a new unittest run. + + @param fn the filename to load (string) + @param tn the testname to load (string) + @param tfn the test function name to load tests from (string) + @param failed list of failed test, if only failed test should be run + (list of strings) + @param cov flag indicating collection of coverage data is requested + (boolean) + @param covname filename to be used to assemble the coverage caches + filename (string) + @param coverase flag indicating erasure of coverage data is requested + (boolean) + """ + self.__scriptName = os.path.abspath(fn) + + fn = self.translate(os.path.abspath(fn), False) + self.__sendJsonCommand("RequestUTPrepare", { + "filename": fn, + "testname": tn, + "testfunctionname": tfn, + "failed": failed, + "coverage": cov, + "coveragefile": covname, + "coverageerase": coverase, + }) + + def remoteUTRun(self): + """ + Public method to start a unittest run. + """ + self.__sendJsonCommand("RequestUTRun", {}) + + def remoteUTStop(self): + """ + Public method to stop a unittest run. + """ + self.__sendJsonCommand("RequestUTStop", {}) + + def __askForkTo(self): + """ + Private method to ask the user which branch of a fork to follow. + """ + selections = [self.tr("Parent Process"), + self.tr("Child process")] + res, ok = QInputDialog.getItem( + None, + self.tr("Client forking"), + self.tr("Select the fork branch to follow."), + selections, + 0, False) + if not ok or res == selections[0]: + self.__sendJsonCommand("ResponseForkTo", { + "target": "parent", + }) + else: + self.__sendJsonCommand("ResponseForkTo", { + "target": "child", + }) + + def __parseClientLine(self): + """ + Private method to handle data from the client. + """ + while self.qsock and self.qsock.canReadLine(): + qs = self.qsock.readLine() + if self.codec is not None: + line = self.codec.toUnicode(qs) + else: + line = bytes(qs).decode() + +## print("Server: ", line) ##debug + + self.__handleJsonCommand(line) + continue + + def __handleJsonCommand(self, jsonStr): + """ + Private method to handle a command or response serialized as a + JSON string. + + @param jsonStr string containing the command or response received + from the debug backend + @type str + """ + import json + + try: + commandDict = json.loads(jsonStr.strip()) + except json.JSONDecodeError as err: + # TODO: implement real error handling + ##print(str(err)) + return + + method = commandDict["method"] + params = commandDict["params"] + + if method == "ClientOutput": + self.debugServer.signalClientOutput(params["text"]) + + elif method in ["ResponseLine", "ResponseStack"]: + for s in params["stack"]: + s[0] = self.translate(s[0], True) + cf = params["stack"][0] + if self.__autoContinue: + self.__autoContinue = False + QTimer.singleShot(0, self.remoteContinue) + else: + self.debugServer.signalClientLine( + cf[0], int(cf[1]), + method == "ResponseStack") + self.debugServer.signalClientStack(params["stack"]) + + elif method == "CallTrace": + isCall = params["event"].lower() == "c" + fromFile, fromLineno, fromFunc = params["from"].rsplit(":", 2) + toFile, toLineno, toFunc = params["to"].rsplit(":", 2) + self.debugServer.signalClientCallTrace( + isCall, + fromFile, fromLineno, fromFunc, + toFile, toLineno, toFunc) + + elif method == "ResponseVariables": + self.debugServer.signalClientVariables( + params["scope"], params["variables"]) + + elif method == "ResponseVariable": + self.debugServer.signalClientVariable( + params["scope"], [params["variable"]] + params["variables"]) + + elif method == "ResponseThreadList": + self.debugServer.signalClientThreadList( + params["currentID"], params["threadList"]) + + elif method == "ResponseThreadSet": + self.debugServer.signalClientThreadSet() + + elif method == "ResponseCapabilities": + self.clientCapabilities = params["capabilities"] + self.debugServer.signalClientCapabilities( + params["capabilities"], params["clientType"]) + + elif method == "ResponseBanner": + self.debugServer.signalClientBanner( + params["version"], + params["platform"], + params["dbgclient"]) + + elif method == "ResponseOK": + self.debugServer.signalClientStatement(False) + + elif method == "ResponseContinue": + self.debugServer.signalClientStatement(True) + + elif method == "RequestRaw": + self.debugServer.signalClientRawInput( + params["prompt"], params["echo"]) + + elif method == "ResponseBPConditionError": + fn = self.translate(params["filename"], True) + self.debugServer.signalClientBreakConditionError( + fn, params["line"]) + + elif method == "ResponseClearBreakpoint": + fn = self.translate(params["filename"], True) + self.debugServer.signalClientClearBreak(fn, params["line"]) + + elif method == "ResponseWatchConditionError": + self.debugServer.signalClientWatchConditionError( + params["condition"]) + + elif method == "ResponseClearWatch": + self.debugServer.signalClientClearWatch(params["condition"]) + + elif method == "ResponseException": + if params: + exctype = params["type"] + excmessage = params["message"] + stack = params["stack"] + if stack: + for stackEntry in stack: + stackEntry[0] = self.translate(stackEntry[0], True) + if stack[0] and stack[0][0] == "<string>": + for stackEntry in stack: + if stackEntry[0] == "<string>": + stackEntry[0] = self.__scriptName + else: + break + else: + exctype = '' + excmessage = '' + stack = [] + + self.debugServer.signalClientException( + exctype, excmessage, stack) + + elif method == "ResponseSyntax": + self.debugServer.signalClientSyntaxError( + params["message"], self.translate(params["filename"], True), + params["linenumber"], params["characternumber"]) + + elif method == "ResponseSignal": + self.debugServer.signalClientSignal( + params["message"], self.translate(params["filename"], True), + params["linenumber"], params["function"], params["arguments"]) + + elif method == "ResponseExit": + self.__scriptName = "" + # TODO: combine these into signalClientExit + self.debugServer.signalClientExit(params["status"]) + if params["message"]: + self.debugServer.signalClientOutput(params["message"]) + + elif method == "PassiveStartup": + self.debugServer.passiveStartUp( + self.translate(params["filename"], True), params["exceptions"]) + + elif method == "ResponseCompletion": + self.debugServer.signalClientCompletionList( + params["completions"], params["text"]) + + elif method == "ResponseUTPrepared": + self.debugServer.clientUtPrepared( + params["count"], params["exception"], params["message"]) + + elif method == "ResponseUTFinished": + self.debugServer.clientUtFinished() + + elif method == "ResponseUTStartTest": + self.debugServer.clientUtStartTest( + params["testname"], params["description"]) + + elif method == "ResponseUTStopTest": + self.debugServer.clientUtStopTest() + + elif method == "ResponseUTTestFailed": + self.debugServer.clientUtTestFailed( + params["testname"], params["traceback"], params["id"]) + + elif method == "ResponseUTTestErrored": + self.debugServer.clientUtTestErrored( + params["testname"], params["traceback"], params["id"]) + + elif method == "ResponseUTTestSkipped": + self.debugServer.clientUtTestSkipped( + params["testname"], params["reason"], params["id"]) + + elif method == "ResponseUTTestFailedExpected": + self.debugServer.clientUtTestFailedExpected( + params["testname"], params["traceback"], params["id"]) + + elif method == "ResponseUTTestSucceededUnexpected": + self.debugServer.clientUtTestSucceededUnexpected( + params["testname"], params["id"]) + + elif method == "RequestForkTo": + self.__askForkTo() + + def __sendJsonCommand(self, command, params): + """ + Private method to send a single command to the client. + + @param command command name to be sent + @type str + @param params dictionary of named parameters for the command + @type dict + """ + import json + + commandDict = { + "jsonrpc": "2.0", + "method": command, + "params": params, + } + cmd = json.dumps(commandDict) + '\n' + if self.qsock is not None: + self.qsock.write(cmd.encode('utf8', 'backslashreplace')) + else: + self.queue.append(cmd) + + +def createDebuggerInterfacePython2(debugServer, passive): + """ + Module function to create a debugger interface instance. + + + @param debugServer reference to the debug server + @type DebugServer + @param passive flag indicating passive connection mode + @type bool + @return instantiated debugger interface + @rtype DebuggerInterfacePython + """ + return DebuggerInterfacePython2(debugServer, passive) + + +def getRegistryData(): + """ + Module function to get characterizing data for the debugger interface. + + @return tuple containing client type, client capabilities, client file + type associations and reference to creation function + @rtype tuple of (str, int, list of str, function) + """ + exts = [] + for ext in Preferences.getDebugger("PythonExtensions").split(): + if ext.startswith("."): + exts.append(ext) + else: + exts.append(".{0}".format(ext)) + + if exts and Preferences.getDebugger("PythonInterpreter"): + return ["Python2", ClientDefaultCapabilities, exts, + createDebuggerInterfacePython2] + else: + return ["", 0, [], None]
--- a/Documentation/Source/eric6.DebugClients.Python.AsyncIO.html Sat Sep 03 18:01:19 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,139 +0,0 @@ -<!DOCTYPE html> -<html><head> -<title>eric6.DebugClients.Python.AsyncIO</title> -<meta charset="UTF-8"> -<style> -body { - background: #EDECE6; - margin: 0em 1em 10em 1em; - color: black; -} - -h1 { color: white; background: #85774A; } -h2 { color: white; background: #85774A; } -h3 { color: white; background: #9D936E; } -h4 { color: white; background: #9D936E; } - -a { color: #BA6D36; } - -</style> -</head> -<body><a NAME="top" ID="top"></a> -<h1>eric6.DebugClients.Python.AsyncIO</h1> -<p> -Module implementing a base class of an asynchronous interface for the debugger. -</p> -<h3>Global Attributes</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Classes</h3> -<table> -<tr> -<td><a href="#AsyncIO">AsyncIO</a></td> -<td>Class implementing asynchronous reading and writing.</td> -</tr> -</table> -<h3>Functions</h3> -<table> -<tr><td>None</td></tr> -</table> -<hr /><hr /> -<a NAME="AsyncIO" ID="AsyncIO"></a> -<h2>AsyncIO</h2> -<p> - Class implementing asynchronous reading and writing. -</p> -<h3>Derived from</h3> -object -<h3>Class Attributes</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Class Methods</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Methods</h3> -<table> -<tr> -<td><a href="#AsyncIO.__init__">AsyncIO</a></td> -<td>Constructor</td> -</tr><tr> -<td><a href="#AsyncIO.disconnect">disconnect</a></td> -<td>Public method to disconnect any current connection.</td> -</tr><tr> -<td><a href="#AsyncIO.readReady">readReady</a></td> -<td>Public method called when there is data ready to be read.</td> -</tr><tr> -<td><a href="#AsyncIO.setDescriptors">setDescriptors</a></td> -<td>Public method called to set the descriptors for the connection.</td> -</tr><tr> -<td><a href="#AsyncIO.write">write</a></td> -<td>Public method to write a string.</td> -</tr><tr> -<td><a href="#AsyncIO.writeReady">writeReady</a></td> -<td>Public method called when we are ready to write data.</td> -</tr> -</table> -<h3>Static Methods</h3> -<table> -<tr><td>None</td></tr> -</table> -<a NAME="AsyncIO.__init__" ID="AsyncIO.__init__"></a> -<h4>AsyncIO (Constructor)</h4> -<b>AsyncIO</b>(<i></i>) -<p> - Constructor -</p><a NAME="AsyncIO.disconnect" ID="AsyncIO.disconnect"></a> -<h4>AsyncIO.disconnect</h4> -<b>disconnect</b>(<i></i>) -<p> - Public method to disconnect any current connection. -</p><a NAME="AsyncIO.readReady" ID="AsyncIO.readReady"></a> -<h4>AsyncIO.readReady</h4> -<b>readReady</b>(<i>fd</i>) -<p> - Public method called when there is data ready to be read. -</p><dl> -<dt><i>fd</i></dt> -<dd> -file descriptor of the file that has data to be read (int) -</dd> -</dl><a NAME="AsyncIO.setDescriptors" ID="AsyncIO.setDescriptors"></a> -<h4>AsyncIO.setDescriptors</h4> -<b>setDescriptors</b>(<i>rfd, wfd</i>) -<p> - Public method called to set the descriptors for the connection. -</p><dl> -<dt><i>rfd</i></dt> -<dd> -file descriptor of the input file (int) -</dd><dt><i>wfd</i></dt> -<dd> -file descriptor of the output file (int) -</dd> -</dl><a NAME="AsyncIO.write" ID="AsyncIO.write"></a> -<h4>AsyncIO.write</h4> -<b>write</b>(<i>s</i>) -<p> - Public method to write a string. -</p><dl> -<dt><i>s</i></dt> -<dd> -the data to be written (string) -</dd> -</dl><a NAME="AsyncIO.writeReady" ID="AsyncIO.writeReady"></a> -<h4>AsyncIO.writeReady</h4> -<b>writeReady</b>(<i>fd</i>) -<p> - Public method called when we are ready to write data. -</p><dl> -<dt><i>fd</i></dt> -<dd> -file descriptor of the file that has data to be written (int) -</dd> -</dl> -<div align="right"><a href="#top">Up</a></div> -<hr /> -</body></html> \ No newline at end of file
--- a/Documentation/Source/eric6.DebugClients.Python.DebugProtocol.html Sat Sep 03 18:01:19 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -<!DOCTYPE html> -<html><head> -<title>eric6.DebugClients.Python.DebugProtocol</title> -<meta charset="UTF-8"> -<style> -body { - background: #EDECE6; - margin: 0em 1em 10em 1em; - color: black; -} - -h1 { color: white; background: #85774A; } -h2 { color: white; background: #85774A; } -h3 { color: white; background: #9D936E; } -h4 { color: white; background: #9D936E; } - -a { color: #BA6D36; } - -</style> -</head> -<body><a NAME="top" ID="top"></a> -<h1>eric6.DebugClients.Python.DebugProtocol</h1> -<p> -Module defining the debug protocol tokens. -</p> -<h3>Global Attributes</h3> -<table> -<tr><td>CallTrace</td></tr><tr><td>DebugAddress</td></tr><tr><td>EOT</td></tr><tr><td>PassiveStartup</td></tr><tr><td>RequestBanner</td></tr><tr><td>RequestBreak</td></tr><tr><td>RequestBreakEnable</td></tr><tr><td>RequestBreakIgnore</td></tr><tr><td>RequestCallTrace</td></tr><tr><td>RequestCapabilities</td></tr><tr><td>RequestCompletion</td></tr><tr><td>RequestContinue</td></tr><tr><td>RequestCoverage</td></tr><tr><td>RequestEnv</td></tr><tr><td>RequestEval</td></tr><tr><td>RequestExec</td></tr><tr><td>RequestForkMode</td></tr><tr><td>RequestForkTo</td></tr><tr><td>RequestLoad</td></tr><tr><td>RequestOK</td></tr><tr><td>RequestProfile</td></tr><tr><td>RequestRun</td></tr><tr><td>RequestSetFilter</td></tr><tr><td>RequestShutdown</td></tr><tr><td>RequestStep</td></tr><tr><td>RequestStepOut</td></tr><tr><td>RequestStepOver</td></tr><tr><td>RequestStepQuit</td></tr><tr><td>RequestThreadList</td></tr><tr><td>RequestThreadSet</td></tr><tr><td>RequestUTPrepare</td></tr><tr><td>RequestUTRun</td></tr><tr><td>RequestUTStop</td></tr><tr><td>RequestVariable</td></tr><tr><td>RequestVariables</td></tr><tr><td>RequestWatch</td></tr><tr><td>RequestWatchEnable</td></tr><tr><td>RequestWatchIgnore</td></tr><tr><td>ResponseBPConditionError</td></tr><tr><td>ResponseBanner</td></tr><tr><td>ResponseCapabilities</td></tr><tr><td>ResponseClearBreak</td></tr><tr><td>ResponseClearWatch</td></tr><tr><td>ResponseCompletion</td></tr><tr><td>ResponseContinue</td></tr><tr><td>ResponseException</td></tr><tr><td>ResponseExit</td></tr><tr><td>ResponseForkTo</td></tr><tr><td>ResponseLine</td></tr><tr><td>ResponseOK</td></tr><tr><td>ResponseRaw</td></tr><tr><td>ResponseSignal</td></tr><tr><td>ResponseStack</td></tr><tr><td>ResponseSyntax</td></tr><tr><td>ResponseThreadList</td></tr><tr><td>ResponseThreadSet</td></tr><tr><td>ResponseUTFinished</td></tr><tr><td>ResponseUTPrepared</td></tr><tr><td>ResponseUTStartTest</td></tr><tr><td>ResponseUTStopTest</td></tr><tr><td>ResponseUTTestErrored</td></tr><tr><td>ResponseUTTestFailed</td></tr><tr><td>ResponseUTTestFailedExpected</td></tr><tr><td>ResponseUTTestSkipped</td></tr><tr><td>ResponseUTTestSucceededUnexpected</td></tr><tr><td>ResponseVariable</td></tr><tr><td>ResponseVariables</td></tr><tr><td>ResponseWPConditionError</td></tr> -</table> -<h3>Classes</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Functions</h3> -<table> -<tr><td>None</td></tr> -</table> -<hr /> -</body></html> \ No newline at end of file
--- a/Documentation/Source/eric6.Debugger.DebuggerInterfacePython.html Sat Sep 03 18:01:19 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,855 +0,0 @@ -<!DOCTYPE html> -<html><head> -<title>eric6.Debugger.DebuggerInterfacePython</title> -<meta charset="UTF-8"> -<style> -body { - background: #EDECE6; - margin: 0em 1em 10em 1em; - color: black; -} - -h1 { color: white; background: #85774A; } -h2 { color: white; background: #85774A; } -h3 { color: white; background: #9D936E; } -h4 { color: white; background: #9D936E; } - -a { color: #BA6D36; } - -</style> -</head> -<body><a NAME="top" ID="top"></a> -<h1>eric6.Debugger.DebuggerInterfacePython</h1> -<p> -Module implementing the Python debugger interface for the debug server. -</p> -<h3>Global Attributes</h3> -<table> -<tr><td>ClientDefaultCapabilities</td></tr> -</table> -<h3>Classes</h3> -<table> -<tr> -<td><a href="#DebuggerInterfacePython">DebuggerInterfacePython</a></td> -<td>Class implementing the Python debugger interface for the debug server.</td> -</tr> -</table> -<h3>Functions</h3> -<table> -<tr> -<td><a href="#createDebuggerInterfacePython">createDebuggerInterfacePython</a></td> -<td>Module function to create a debugger interface instance.</td> -</tr><tr> -<td><a href="#getRegistryData">getRegistryData</a></td> -<td>Module function to get characterizing data for the debugger interface.</td> -</tr> -</table> -<hr /><hr /> -<a NAME="DebuggerInterfacePython" ID="DebuggerInterfacePython"></a> -<h2>DebuggerInterfacePython</h2> -<p> - Class implementing the Python debugger interface for the debug server. -</p> -<h3>Derived from</h3> -QObject -<h3>Class Attributes</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Class Methods</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Methods</h3> -<table> -<tr> -<td><a href="#DebuggerInterfacePython.__init__">DebuggerInterfacePython</a></td> -<td>Constructor</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.__askForkTo">__askForkTo</a></td> -<td>Private method to ask the user which branch of a fork to follow.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.__identityTranslation">__identityTranslation</a></td> -<td>Private method to perform the identity path translation.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.__parseClientLine">__parseClientLine</a></td> -<td>Private method to handle data from the client.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.__remoteTranslation">__remoteTranslation</a></td> -<td>Private method to perform the path translation.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.__sendCommand">__sendCommand</a></td> -<td>Private method to send a single line command to the client.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.__startProcess">__startProcess</a></td> -<td>Private method to start the debugger client process.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.flush">flush</a></td> -<td>Public slot to flush the queue.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.getClientCapabilities">getClientCapabilities</a></td> -<td>Public method to retrieve the debug clients capabilities.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.isConnected">isConnected</a></td> -<td>Public method to test, if a debug client has connected.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.newConnection">newConnection</a></td> -<td>Public slot to handle a new connection.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteBanner">remoteBanner</a></td> -<td>Public slot to get the banner info of the remote client.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteBreakpoint">remoteBreakpoint</a></td> -<td>Public method to set or clear a breakpoint.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteBreakpointEnable">remoteBreakpointEnable</a></td> -<td>Public method to enable or disable a breakpoint.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteBreakpointIgnore">remoteBreakpointIgnore</a></td> -<td>Public method to ignore a breakpoint the next couple of occurrences.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteCapabilities">remoteCapabilities</a></td> -<td>Public slot to get the debug clients capabilities.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteClientSetFilter">remoteClientSetFilter</a></td> -<td>Public method to set a variables filter list.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteClientVariable">remoteClientVariable</a></td> -<td>Public method to request the variables of the debugged program.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteClientVariables">remoteClientVariables</a></td> -<td>Public method to request the variables of the debugged program.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteCompletion">remoteCompletion</a></td> -<td>Public slot to get the a list of possible commandline completions from the remote client.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteContinue">remoteContinue</a></td> -<td>Public method to continue the debugged program.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteCoverage">remoteCoverage</a></td> -<td>Public method to load a new program to collect coverage data.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteEnvironment">remoteEnvironment</a></td> -<td>Public method to set the environment for a program to debug, run, ...</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteEval">remoteEval</a></td> -<td>Public method to evaluate arg in the current context of the debugged program.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteExec">remoteExec</a></td> -<td>Public method to execute stmt in the current context of the debugged program.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteLoad">remoteLoad</a></td> -<td>Public method to load a new program to debug.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteProfile">remoteProfile</a></td> -<td>Public method to load a new program to collect profiling data.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteRawInput">remoteRawInput</a></td> -<td>Public method to send the raw input to the debugged program.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteRun">remoteRun</a></td> -<td>Public method to load a new program to run.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteSetThread">remoteSetThread</a></td> -<td>Public method to request to set the given thread as current thread.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteStatement">remoteStatement</a></td> -<td>Public method to execute a Python statement.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteStep">remoteStep</a></td> -<td>Public method to single step the debugged program.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteStepOut">remoteStepOut</a></td> -<td>Public method to step out the debugged program.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteStepOver">remoteStepOver</a></td> -<td>Public method to step over the debugged program.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteStepQuit">remoteStepQuit</a></td> -<td>Public method to stop the debugged program.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteThreadList">remoteThreadList</a></td> -<td>Public method to request the list of threads from the client.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteUTPrepare">remoteUTPrepare</a></td> -<td>Public method to prepare a new unittest run.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteUTRun">remoteUTRun</a></td> -<td>Public method to start a unittest run.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteUTStop">remoteUTStop</a></td> -<td>Public method to stop a unittest run.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteWatchpoint">remoteWatchpoint</a></td> -<td>Public method to set or clear a watch expression.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteWatchpointEnable">remoteWatchpointEnable</a></td> -<td>Public method to enable or disable a watch expression.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.remoteWatchpointIgnore">remoteWatchpointIgnore</a></td> -<td>Public method to ignore a watch expression the next couple of occurrences.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.setCallTraceEnabled">setCallTraceEnabled</a></td> -<td>Public method to set the call trace state.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.shutdown">shutdown</a></td> -<td>Public method to cleanly shut down.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.startRemote">startRemote</a></td> -<td>Public method to start a remote Python interpreter.</td> -</tr><tr> -<td><a href="#DebuggerInterfacePython.startRemoteForProject">startRemoteForProject</a></td> -<td>Public method to start a remote Python interpreter for a project.</td> -</tr> -</table> -<h3>Static Methods</h3> -<table> -<tr><td>None</td></tr> -</table> -<a NAME="DebuggerInterfacePython.__init__" ID="DebuggerInterfacePython.__init__"></a> -<h4>DebuggerInterfacePython (Constructor)</h4> -<b>DebuggerInterfacePython</b>(<i>debugServer, passive</i>) -<p> - Constructor -</p><dl> -<dt><i>debugServer</i></dt> -<dd> -reference to the debug server (DebugServer) -</dd><dt><i>passive</i></dt> -<dd> -flag indicating passive connection mode (boolean) -</dd> -</dl><a NAME="DebuggerInterfacePython.__askForkTo" ID="DebuggerInterfacePython.__askForkTo"></a> -<h4>DebuggerInterfacePython.__askForkTo</h4> -<b>__askForkTo</b>(<i></i>) -<p> - Private method to ask the user which branch of a fork to follow. -</p><a NAME="DebuggerInterfacePython.__identityTranslation" ID="DebuggerInterfacePython.__identityTranslation"></a> -<h4>DebuggerInterfacePython.__identityTranslation</h4> -<b>__identityTranslation</b>(<i>fn, remote2local=True</i>) -<p> - Private method to perform the identity path translation. -</p><dl> -<dt><i>fn</i></dt> -<dd> -filename to be translated (string) -</dd><dt><i>remote2local</i></dt> -<dd> -flag indicating the direction of translation - (False = local to remote, True = remote to local [default]) -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -translated filename (string) -</dd> -</dl><a NAME="DebuggerInterfacePython.__parseClientLine" ID="DebuggerInterfacePython.__parseClientLine"></a> -<h4>DebuggerInterfacePython.__parseClientLine</h4> -<b>__parseClientLine</b>(<i></i>) -<p> - Private method to handle data from the client. -</p><a NAME="DebuggerInterfacePython.__remoteTranslation" ID="DebuggerInterfacePython.__remoteTranslation"></a> -<h4>DebuggerInterfacePython.__remoteTranslation</h4> -<b>__remoteTranslation</b>(<i>fn, remote2local=True</i>) -<p> - Private method to perform the path translation. -</p><dl> -<dt><i>fn</i></dt> -<dd> -filename to be translated (string) -</dd><dt><i>remote2local</i></dt> -<dd> -flag indicating the direction of translation - (False = local to remote, True = remote to local [default]) -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -translated filename (string) -</dd> -</dl><a NAME="DebuggerInterfacePython.__sendCommand" ID="DebuggerInterfacePython.__sendCommand"></a> -<h4>DebuggerInterfacePython.__sendCommand</h4> -<b>__sendCommand</b>(<i>cmd</i>) -<p> - Private method to send a single line command to the client. -</p><dl> -<dt><i>cmd</i></dt> -<dd> -command to send to the debug client (string) -</dd> -</dl><a NAME="DebuggerInterfacePython.__startProcess" ID="DebuggerInterfacePython.__startProcess"></a> -<h4>DebuggerInterfacePython.__startProcess</h4> -<b>__startProcess</b>(<i>program, arguments, environment=None</i>) -<p> - Private method to start the debugger client process. -</p><dl> -<dt><i>program</i></dt> -<dd> -name of the executable to start (string) -</dd><dt><i>arguments</i></dt> -<dd> -arguments to be passed to the program (list of string) -</dd><dt><i>environment</i></dt> -<dd> -dictionary of environment settings to pass - (dict of string) -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -the process object (QProcess) or None -</dd> -</dl><a NAME="DebuggerInterfacePython.flush" ID="DebuggerInterfacePython.flush"></a> -<h4>DebuggerInterfacePython.flush</h4> -<b>flush</b>(<i></i>) -<p> - Public slot to flush the queue. -</p><a NAME="DebuggerInterfacePython.getClientCapabilities" ID="DebuggerInterfacePython.getClientCapabilities"></a> -<h4>DebuggerInterfacePython.getClientCapabilities</h4> -<b>getClientCapabilities</b>(<i></i>) -<p> - Public method to retrieve the debug clients capabilities. -</p><dl> -<dt>Returns:</dt> -<dd> -debug client capabilities (integer) -</dd> -</dl><a NAME="DebuggerInterfacePython.isConnected" ID="DebuggerInterfacePython.isConnected"></a> -<h4>DebuggerInterfacePython.isConnected</h4> -<b>isConnected</b>(<i></i>) -<p> - Public method to test, if a debug client has connected. -</p><dl> -<dt>Returns:</dt> -<dd> -flag indicating the connection status (boolean) -</dd> -</dl><a NAME="DebuggerInterfacePython.newConnection" ID="DebuggerInterfacePython.newConnection"></a> -<h4>DebuggerInterfacePython.newConnection</h4> -<b>newConnection</b>(<i>sock</i>) -<p> - Public slot to handle a new connection. -</p><dl> -<dt><i>sock</i></dt> -<dd> -reference to the socket object (QTcpSocket) -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -flag indicating success (boolean) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteBanner" ID="DebuggerInterfacePython.remoteBanner"></a> -<h4>DebuggerInterfacePython.remoteBanner</h4> -<b>remoteBanner</b>(<i></i>) -<p> - Public slot to get the banner info of the remote client. -</p><a NAME="DebuggerInterfacePython.remoteBreakpoint" ID="DebuggerInterfacePython.remoteBreakpoint"></a> -<h4>DebuggerInterfacePython.remoteBreakpoint</h4> -<b>remoteBreakpoint</b>(<i>fn, line, set, cond=None, temp=False</i>) -<p> - Public method to set or clear a breakpoint. -</p><dl> -<dt><i>fn</i></dt> -<dd> -filename the breakpoint belongs to (string) -</dd><dt><i>line</i></dt> -<dd> -linenumber of the breakpoint (int) -</dd><dt><i>set</i></dt> -<dd> -flag indicating setting or resetting a breakpoint (boolean) -</dd><dt><i>cond</i></dt> -<dd> -condition of the breakpoint (string) -</dd><dt><i>temp</i></dt> -<dd> -flag indicating a temporary breakpoint (boolean) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteBreakpointEnable" ID="DebuggerInterfacePython.remoteBreakpointEnable"></a> -<h4>DebuggerInterfacePython.remoteBreakpointEnable</h4> -<b>remoteBreakpointEnable</b>(<i>fn, line, enable</i>) -<p> - Public method to enable or disable a breakpoint. -</p><dl> -<dt><i>fn</i></dt> -<dd> -filename the breakpoint belongs to (string) -</dd><dt><i>line</i></dt> -<dd> -linenumber of the breakpoint (int) -</dd><dt><i>enable</i></dt> -<dd> -flag indicating enabling or disabling a breakpoint - (boolean) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteBreakpointIgnore" ID="DebuggerInterfacePython.remoteBreakpointIgnore"></a> -<h4>DebuggerInterfacePython.remoteBreakpointIgnore</h4> -<b>remoteBreakpointIgnore</b>(<i>fn, line, count</i>) -<p> - Public method to ignore a breakpoint the next couple of occurrences. -</p><dl> -<dt><i>fn</i></dt> -<dd> -filename the breakpoint belongs to (string) -</dd><dt><i>line</i></dt> -<dd> -linenumber of the breakpoint (int) -</dd><dt><i>count</i></dt> -<dd> -number of occurrences to ignore (int) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteCapabilities" ID="DebuggerInterfacePython.remoteCapabilities"></a> -<h4>DebuggerInterfacePython.remoteCapabilities</h4> -<b>remoteCapabilities</b>(<i></i>) -<p> - Public slot to get the debug clients capabilities. -</p><a NAME="DebuggerInterfacePython.remoteClientSetFilter" ID="DebuggerInterfacePython.remoteClientSetFilter"></a> -<h4>DebuggerInterfacePython.remoteClientSetFilter</h4> -<b>remoteClientSetFilter</b>(<i>scope, filter</i>) -<p> - Public method to set a variables filter list. -</p><dl> -<dt><i>scope</i></dt> -<dd> -the scope of the variables (0 = local, 1 = global) -</dd><dt><i>filter</i></dt> -<dd> -regexp string for variable names to filter out (string) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteClientVariable" ID="DebuggerInterfacePython.remoteClientVariable"></a> -<h4>DebuggerInterfacePython.remoteClientVariable</h4> -<b>remoteClientVariable</b>(<i>scope, filter, var, framenr=0</i>) -<p> - Public method to request the variables of the debugged program. -</p><dl> -<dt><i>scope</i></dt> -<dd> -the scope of the variables (0 = local, 1 = global) -</dd><dt><i>filter</i></dt> -<dd> -list of variable types to filter out (list of int) -</dd><dt><i>var</i></dt> -<dd> -list encoded name of variable to retrieve (string) -</dd><dt><i>framenr</i></dt> -<dd> -framenumber of the variables to retrieve (int) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteClientVariables" ID="DebuggerInterfacePython.remoteClientVariables"></a> -<h4>DebuggerInterfacePython.remoteClientVariables</h4> -<b>remoteClientVariables</b>(<i>scope, filter, framenr=0</i>) -<p> - Public method to request the variables of the debugged program. -</p><dl> -<dt><i>scope</i></dt> -<dd> -the scope of the variables (0 = local, 1 = global) -</dd><dt><i>filter</i></dt> -<dd> -list of variable types to filter out (list of int) -</dd><dt><i>framenr</i></dt> -<dd> -framenumber of the variables to retrieve (int) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteCompletion" ID="DebuggerInterfacePython.remoteCompletion"></a> -<h4>DebuggerInterfacePython.remoteCompletion</h4> -<b>remoteCompletion</b>(<i>text</i>) -<p> - Public slot to get the a list of possible commandline completions - from the remote client. -</p><dl> -<dt><i>text</i></dt> -<dd> -the text to be completed (string) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteContinue" ID="DebuggerInterfacePython.remoteContinue"></a> -<h4>DebuggerInterfacePython.remoteContinue</h4> -<b>remoteContinue</b>(<i>special=False</i>) -<p> - Public method to continue the debugged program. -</p><dl> -<dt><i>special</i></dt> -<dd> -flag indicating a special continue operation (boolean) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteCoverage" ID="DebuggerInterfacePython.remoteCoverage"></a> -<h4>DebuggerInterfacePython.remoteCoverage</h4> -<b>remoteCoverage</b>(<i>fn, argv, wd, erase=False</i>) -<p> - Public method to load a new program to collect coverage data. -</p><dl> -<dt><i>fn</i></dt> -<dd> -the filename to run (string) -</dd><dt><i>argv</i></dt> -<dd> -the commandline arguments to pass to the program (string) -</dd><dt><i>wd</i></dt> -<dd> -the working directory for the program (string) -</dd><dt><i>erase=</i></dt> -<dd> -flag indicating that coverage info should be - cleared first (boolean) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteEnvironment" ID="DebuggerInterfacePython.remoteEnvironment"></a> -<h4>DebuggerInterfacePython.remoteEnvironment</h4> -<b>remoteEnvironment</b>(<i>env</i>) -<p> - Public method to set the environment for a program to debug, run, ... -</p><dl> -<dt><i>env</i></dt> -<dd> -environment settings (dictionary) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteEval" ID="DebuggerInterfacePython.remoteEval"></a> -<h4>DebuggerInterfacePython.remoteEval</h4> -<b>remoteEval</b>(<i>arg</i>) -<p> - Public method to evaluate arg in the current context of the debugged - program. -</p><dl> -<dt><i>arg</i></dt> -<dd> -the arguments to evaluate (string) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteExec" ID="DebuggerInterfacePython.remoteExec"></a> -<h4>DebuggerInterfacePython.remoteExec</h4> -<b>remoteExec</b>(<i>stmt</i>) -<p> - Public method to execute stmt in the current context of the debugged - program. -</p><dl> -<dt><i>stmt</i></dt> -<dd> -statement to execute (string) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteLoad" ID="DebuggerInterfacePython.remoteLoad"></a> -<h4>DebuggerInterfacePython.remoteLoad</h4> -<b>remoteLoad</b>(<i>fn, argv, wd, traceInterpreter=False, autoContinue=True, autoFork=False, forkChild=False</i>) -<p> - Public method to load a new program to debug. -</p><dl> -<dt><i>fn</i></dt> -<dd> -the filename to debug (string) -</dd><dt><i>argv</i></dt> -<dd> -the commandline arguments to pass to the program (string) -</dd><dt><i>wd</i></dt> -<dd> -the working directory for the program (string) -</dd><dt><i>traceInterpreter=</i></dt> -<dd> -flag indicating if the interpreter library - should be traced as well (boolean) -</dd><dt><i>autoContinue=</i></dt> -<dd> -flag indicating, that the debugger should not - stop at the first executable line (boolean) -</dd><dt><i>autoFork=</i></dt> -<dd> -flag indicating the automatic fork mode (boolean) -</dd><dt><i>forkChild=</i></dt> -<dd> -flag indicating to debug the child after forking - (boolean) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteProfile" ID="DebuggerInterfacePython.remoteProfile"></a> -<h4>DebuggerInterfacePython.remoteProfile</h4> -<b>remoteProfile</b>(<i>fn, argv, wd, erase=False</i>) -<p> - Public method to load a new program to collect profiling data. -</p><dl> -<dt><i>fn</i></dt> -<dd> -the filename to run (string) -</dd><dt><i>argv</i></dt> -<dd> -the commandline arguments to pass to the program (string) -</dd><dt><i>wd</i></dt> -<dd> -the working directory for the program (string) -</dd><dt><i>erase=</i></dt> -<dd> -flag indicating that timing info should be cleared - first (boolean) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteRawInput" ID="DebuggerInterfacePython.remoteRawInput"></a> -<h4>DebuggerInterfacePython.remoteRawInput</h4> -<b>remoteRawInput</b>(<i>s</i>) -<p> - Public method to send the raw input to the debugged program. -</p><dl> -<dt><i>s</i></dt> -<dd> -the raw input (string) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteRun" ID="DebuggerInterfacePython.remoteRun"></a> -<h4>DebuggerInterfacePython.remoteRun</h4> -<b>remoteRun</b>(<i>fn, argv, wd, autoFork=False, forkChild=False</i>) -<p> - Public method to load a new program to run. -</p><dl> -<dt><i>fn</i></dt> -<dd> -the filename to run (string) -</dd><dt><i>argv</i></dt> -<dd> -the commandline arguments to pass to the program (string) -</dd><dt><i>wd</i></dt> -<dd> -the working directory for the program (string) -</dd><dt><i>autoFork=</i></dt> -<dd> -flag indicating the automatic fork mode (boolean) -</dd><dt><i>forkChild=</i></dt> -<dd> -flag indicating to debug the child after forking - (boolean) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteSetThread" ID="DebuggerInterfacePython.remoteSetThread"></a> -<h4>DebuggerInterfacePython.remoteSetThread</h4> -<b>remoteSetThread</b>(<i>tid</i>) -<p> - Public method to request to set the given thread as current thread. -</p><dl> -<dt><i>tid</i></dt> -<dd> -id of the thread (integer) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteStatement" ID="DebuggerInterfacePython.remoteStatement"></a> -<h4>DebuggerInterfacePython.remoteStatement</h4> -<b>remoteStatement</b>(<i>stmt</i>) -<p> - Public method to execute a Python statement. -</p><dl> -<dt><i>stmt</i></dt> -<dd> -the Python statement to execute (string). It - should not have a trailing newline. -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteStep" ID="DebuggerInterfacePython.remoteStep"></a> -<h4>DebuggerInterfacePython.remoteStep</h4> -<b>remoteStep</b>(<i></i>) -<p> - Public method to single step the debugged program. -</p><a NAME="DebuggerInterfacePython.remoteStepOut" ID="DebuggerInterfacePython.remoteStepOut"></a> -<h4>DebuggerInterfacePython.remoteStepOut</h4> -<b>remoteStepOut</b>(<i></i>) -<p> - Public method to step out the debugged program. -</p><a NAME="DebuggerInterfacePython.remoteStepOver" ID="DebuggerInterfacePython.remoteStepOver"></a> -<h4>DebuggerInterfacePython.remoteStepOver</h4> -<b>remoteStepOver</b>(<i></i>) -<p> - Public method to step over the debugged program. -</p><a NAME="DebuggerInterfacePython.remoteStepQuit" ID="DebuggerInterfacePython.remoteStepQuit"></a> -<h4>DebuggerInterfacePython.remoteStepQuit</h4> -<b>remoteStepQuit</b>(<i></i>) -<p> - Public method to stop the debugged program. -</p><a NAME="DebuggerInterfacePython.remoteThreadList" ID="DebuggerInterfacePython.remoteThreadList"></a> -<h4>DebuggerInterfacePython.remoteThreadList</h4> -<b>remoteThreadList</b>(<i></i>) -<p> - Public method to request the list of threads from the client. -</p><a NAME="DebuggerInterfacePython.remoteUTPrepare" ID="DebuggerInterfacePython.remoteUTPrepare"></a> -<h4>DebuggerInterfacePython.remoteUTPrepare</h4> -<b>remoteUTPrepare</b>(<i>fn, tn, tfn, failed, cov, covname, coverase</i>) -<p> - Public method to prepare a new unittest run. -</p><dl> -<dt><i>fn</i></dt> -<dd> -the filename to load (string) -</dd><dt><i>tn</i></dt> -<dd> -the testname to load (string) -</dd><dt><i>tfn</i></dt> -<dd> -the test function name to load tests from (string) -</dd><dt><i>failed</i></dt> -<dd> -list of failed test, if only failed test should be run - (list of strings) -</dd><dt><i>cov</i></dt> -<dd> -flag indicating collection of coverage data is requested - (boolean) -</dd><dt><i>covname</i></dt> -<dd> -filename to be used to assemble the coverage caches - filename (string) -</dd><dt><i>coverase</i></dt> -<dd> -flag indicating erasure of coverage data is requested - (boolean) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteUTRun" ID="DebuggerInterfacePython.remoteUTRun"></a> -<h4>DebuggerInterfacePython.remoteUTRun</h4> -<b>remoteUTRun</b>(<i></i>) -<p> - Public method to start a unittest run. -</p><a NAME="DebuggerInterfacePython.remoteUTStop" ID="DebuggerInterfacePython.remoteUTStop"></a> -<h4>DebuggerInterfacePython.remoteUTStop</h4> -<b>remoteUTStop</b>(<i></i>) -<p> - Public method to stop a unittest run. -</p><a NAME="DebuggerInterfacePython.remoteWatchpoint" ID="DebuggerInterfacePython.remoteWatchpoint"></a> -<h4>DebuggerInterfacePython.remoteWatchpoint</h4> -<b>remoteWatchpoint</b>(<i>cond, set, temp=False</i>) -<p> - Public method to set or clear a watch expression. -</p><dl> -<dt><i>cond</i></dt> -<dd> -expression of the watch expression (string) -</dd><dt><i>set</i></dt> -<dd> -flag indicating setting or resetting a watch expression - (boolean) -</dd><dt><i>temp</i></dt> -<dd> -flag indicating a temporary watch expression (boolean) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteWatchpointEnable" ID="DebuggerInterfacePython.remoteWatchpointEnable"></a> -<h4>DebuggerInterfacePython.remoteWatchpointEnable</h4> -<b>remoteWatchpointEnable</b>(<i>cond, enable</i>) -<p> - Public method to enable or disable a watch expression. -</p><dl> -<dt><i>cond</i></dt> -<dd> -expression of the watch expression (string) -</dd><dt><i>enable</i></dt> -<dd> -flag indicating enabling or disabling a watch expression - (boolean) -</dd> -</dl><a NAME="DebuggerInterfacePython.remoteWatchpointIgnore" ID="DebuggerInterfacePython.remoteWatchpointIgnore"></a> -<h4>DebuggerInterfacePython.remoteWatchpointIgnore</h4> -<b>remoteWatchpointIgnore</b>(<i>cond, count</i>) -<p> - Public method to ignore a watch expression the next couple of - occurrences. -</p><dl> -<dt><i>cond</i></dt> -<dd> -expression of the watch expression (string) -</dd><dt><i>count</i></dt> -<dd> -number of occurrences to ignore (int) -</dd> -</dl><a NAME="DebuggerInterfacePython.setCallTraceEnabled" ID="DebuggerInterfacePython.setCallTraceEnabled"></a> -<h4>DebuggerInterfacePython.setCallTraceEnabled</h4> -<b>setCallTraceEnabled</b>(<i>on</i>) -<p> - Public method to set the call trace state. -</p><dl> -<dt><i>on</i></dt> -<dd> -flag indicating to enable the call trace function (boolean) -</dd> -</dl><a NAME="DebuggerInterfacePython.shutdown" ID="DebuggerInterfacePython.shutdown"></a> -<h4>DebuggerInterfacePython.shutdown</h4> -<b>shutdown</b>(<i></i>) -<p> - Public method to cleanly shut down. -</p><p> - It closes our socket and shuts down - the debug client. (Needed on Win OS) -</p><a NAME="DebuggerInterfacePython.startRemote" ID="DebuggerInterfacePython.startRemote"></a> -<h4>DebuggerInterfacePython.startRemote</h4> -<b>startRemote</b>(<i>port, runInConsole</i>) -<p> - Public method to start a remote Python interpreter. -</p><dl> -<dt><i>port</i></dt> -<dd> -portnumber the debug server is listening on (integer) -</dd><dt><i>runInConsole</i></dt> -<dd> -flag indicating to start the debugger in a - console window (boolean) -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -client process object (QProcess), a flag to indicate - a network connection (boolean) and the name of the interpreter - in case of a local execution (string) -</dd> -</dl><a NAME="DebuggerInterfacePython.startRemoteForProject" ID="DebuggerInterfacePython.startRemoteForProject"></a> -<h4>DebuggerInterfacePython.startRemoteForProject</h4> -<b>startRemoteForProject</b>(<i>port, runInConsole</i>) -<p> - Public method to start a remote Python interpreter for a project. -</p><dl> -<dt><i>port</i></dt> -<dd> -portnumber the debug server is listening on (integer) -</dd><dt><i>runInConsole</i></dt> -<dd> -flag indicating to start the debugger in a - console window (boolean) -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -client process object (QProcess), a flag to indicate - a network connection (boolean) and the name of the interpreter - in case of a local execution (string) -</dd> -</dl> -<div align="right"><a href="#top">Up</a></div> -<hr /><hr /> -<a NAME="createDebuggerInterfacePython" ID="createDebuggerInterfacePython"></a> -<h2>createDebuggerInterfacePython</h2> -<b>createDebuggerInterfacePython</b>(<i>debugServer, passive</i>) -<p> - Module function to create a debugger interface instance. -</p><p> - -</p><dl> -<dt><i>debugServer</i> (DebugServer)</dt> -<dd> -reference to the debug server -</dd><dt><i>passive</i> (bool)</dt> -<dd> -flag indicating passive connection mode -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -instantiated debugger interface -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -DebuggerInterfacePython -</dd> -</dl> -<div align="right"><a href="#top">Up</a></div> -<hr /><hr /> -<a NAME="getRegistryData" ID="getRegistryData"></a> -<h2>getRegistryData</h2> -<b>getRegistryData</b>(<i></i>) -<p> - Module function to get characterizing data for the debugger interface. -</p><dl> -<dt>Returns:</dt> -<dd> -tuple containing client type, client capabilities, client file - type associations and reference to creation function -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -tuple of (str, int, list of str, function) -</dd> -</dl> -<div align="right"><a href="#top">Up</a></div> -<hr /> -</body></html> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Documentation/Source/eric6.Debugger.DebuggerInterfacePython2.html Sat Sep 03 18:02:37 2016 +0200 @@ -0,0 +1,855 @@ +<!DOCTYPE html> +<html><head> +<title>eric6.Debugger.DebuggerInterfacePython</title> +<meta charset="UTF-8"> +<style> +body { + background: #EDECE6; + margin: 0em 1em 10em 1em; + color: black; +} + +h1 { color: white; background: #85774A; } +h2 { color: white; background: #85774A; } +h3 { color: white; background: #9D936E; } +h4 { color: white; background: #9D936E; } + +a { color: #BA6D36; } + +</style> +</head> +<body><a NAME="top" ID="top"></a> +<h1>eric6.Debugger.DebuggerInterfacePython</h1> +<p> +Module implementing the Python debugger interface for the debug server. +</p> +<h3>Global Attributes</h3> +<table> +<tr><td>ClientDefaultCapabilities</td></tr> +</table> +<h3>Classes</h3> +<table> +<tr> +<td><a href="#DebuggerInterfacePython">DebuggerInterfacePython</a></td> +<td>Class implementing the Python debugger interface for the debug server.</td> +</tr> +</table> +<h3>Functions</h3> +<table> +<tr> +<td><a href="#createDebuggerInterfacePython">createDebuggerInterfacePython</a></td> +<td>Module function to create a debugger interface instance.</td> +</tr><tr> +<td><a href="#getRegistryData">getRegistryData</a></td> +<td>Module function to get characterizing data for the debugger interface.</td> +</tr> +</table> +<hr /><hr /> +<a NAME="DebuggerInterfacePython" ID="DebuggerInterfacePython"></a> +<h2>DebuggerInterfacePython</h2> +<p> + Class implementing the Python debugger interface for the debug server. +</p> +<h3>Derived from</h3> +QObject +<h3>Class Attributes</h3> +<table> +<tr><td>None</td></tr> +</table> +<h3>Class Methods</h3> +<table> +<tr><td>None</td></tr> +</table> +<h3>Methods</h3> +<table> +<tr> +<td><a href="#DebuggerInterfacePython.__init__">DebuggerInterfacePython</a></td> +<td>Constructor</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.__askForkTo">__askForkTo</a></td> +<td>Private method to ask the user which branch of a fork to follow.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.__identityTranslation">__identityTranslation</a></td> +<td>Private method to perform the identity path translation.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.__parseClientLine">__parseClientLine</a></td> +<td>Private method to handle data from the client.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.__remoteTranslation">__remoteTranslation</a></td> +<td>Private method to perform the path translation.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.__sendCommand">__sendCommand</a></td> +<td>Private method to send a single line command to the client.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.__startProcess">__startProcess</a></td> +<td>Private method to start the debugger client process.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.flush">flush</a></td> +<td>Public slot to flush the queue.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.getClientCapabilities">getClientCapabilities</a></td> +<td>Public method to retrieve the debug clients capabilities.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.isConnected">isConnected</a></td> +<td>Public method to test, if a debug client has connected.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.newConnection">newConnection</a></td> +<td>Public slot to handle a new connection.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteBanner">remoteBanner</a></td> +<td>Public slot to get the banner info of the remote client.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteBreakpoint">remoteBreakpoint</a></td> +<td>Public method to set or clear a breakpoint.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteBreakpointEnable">remoteBreakpointEnable</a></td> +<td>Public method to enable or disable a breakpoint.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteBreakpointIgnore">remoteBreakpointIgnore</a></td> +<td>Public method to ignore a breakpoint the next couple of occurrences.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteCapabilities">remoteCapabilities</a></td> +<td>Public slot to get the debug clients capabilities.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteClientSetFilter">remoteClientSetFilter</a></td> +<td>Public method to set a variables filter list.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteClientVariable">remoteClientVariable</a></td> +<td>Public method to request the variables of the debugged program.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteClientVariables">remoteClientVariables</a></td> +<td>Public method to request the variables of the debugged program.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteCompletion">remoteCompletion</a></td> +<td>Public slot to get the a list of possible commandline completions from the remote client.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteContinue">remoteContinue</a></td> +<td>Public method to continue the debugged program.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteCoverage">remoteCoverage</a></td> +<td>Public method to load a new program to collect coverage data.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteEnvironment">remoteEnvironment</a></td> +<td>Public method to set the environment for a program to debug, run, ...</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteEval">remoteEval</a></td> +<td>Public method to evaluate arg in the current context of the debugged program.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteExec">remoteExec</a></td> +<td>Public method to execute stmt in the current context of the debugged program.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteLoad">remoteLoad</a></td> +<td>Public method to load a new program to debug.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteProfile">remoteProfile</a></td> +<td>Public method to load a new program to collect profiling data.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteRawInput">remoteRawInput</a></td> +<td>Public method to send the raw input to the debugged program.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteRun">remoteRun</a></td> +<td>Public method to load a new program to run.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteSetThread">remoteSetThread</a></td> +<td>Public method to request to set the given thread as current thread.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteStatement">remoteStatement</a></td> +<td>Public method to execute a Python statement.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteStep">remoteStep</a></td> +<td>Public method to single step the debugged program.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteStepOut">remoteStepOut</a></td> +<td>Public method to step out the debugged program.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteStepOver">remoteStepOver</a></td> +<td>Public method to step over the debugged program.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteStepQuit">remoteStepQuit</a></td> +<td>Public method to stop the debugged program.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteThreadList">remoteThreadList</a></td> +<td>Public method to request the list of threads from the client.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteUTPrepare">remoteUTPrepare</a></td> +<td>Public method to prepare a new unittest run.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteUTRun">remoteUTRun</a></td> +<td>Public method to start a unittest run.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteUTStop">remoteUTStop</a></td> +<td>Public method to stop a unittest run.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteWatchpoint">remoteWatchpoint</a></td> +<td>Public method to set or clear a watch expression.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteWatchpointEnable">remoteWatchpointEnable</a></td> +<td>Public method to enable or disable a watch expression.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.remoteWatchpointIgnore">remoteWatchpointIgnore</a></td> +<td>Public method to ignore a watch expression the next couple of occurrences.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.setCallTraceEnabled">setCallTraceEnabled</a></td> +<td>Public method to set the call trace state.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.shutdown">shutdown</a></td> +<td>Public method to cleanly shut down.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.startRemote">startRemote</a></td> +<td>Public method to start a remote Python interpreter.</td> +</tr><tr> +<td><a href="#DebuggerInterfacePython.startRemoteForProject">startRemoteForProject</a></td> +<td>Public method to start a remote Python interpreter for a project.</td> +</tr> +</table> +<h3>Static Methods</h3> +<table> +<tr><td>None</td></tr> +</table> +<a NAME="DebuggerInterfacePython.__init__" ID="DebuggerInterfacePython.__init__"></a> +<h4>DebuggerInterfacePython (Constructor)</h4> +<b>DebuggerInterfacePython</b>(<i>debugServer, passive</i>) +<p> + Constructor +</p><dl> +<dt><i>debugServer</i></dt> +<dd> +reference to the debug server (DebugServer) +</dd><dt><i>passive</i></dt> +<dd> +flag indicating passive connection mode (boolean) +</dd> +</dl><a NAME="DebuggerInterfacePython.__askForkTo" ID="DebuggerInterfacePython.__askForkTo"></a> +<h4>DebuggerInterfacePython.__askForkTo</h4> +<b>__askForkTo</b>(<i></i>) +<p> + Private method to ask the user which branch of a fork to follow. +</p><a NAME="DebuggerInterfacePython.__identityTranslation" ID="DebuggerInterfacePython.__identityTranslation"></a> +<h4>DebuggerInterfacePython.__identityTranslation</h4> +<b>__identityTranslation</b>(<i>fn, remote2local=True</i>) +<p> + Private method to perform the identity path translation. +</p><dl> +<dt><i>fn</i></dt> +<dd> +filename to be translated (string) +</dd><dt><i>remote2local</i></dt> +<dd> +flag indicating the direction of translation + (False = local to remote, True = remote to local [default]) +</dd> +</dl><dl> +<dt>Returns:</dt> +<dd> +translated filename (string) +</dd> +</dl><a NAME="DebuggerInterfacePython.__parseClientLine" ID="DebuggerInterfacePython.__parseClientLine"></a> +<h4>DebuggerInterfacePython.__parseClientLine</h4> +<b>__parseClientLine</b>(<i></i>) +<p> + Private method to handle data from the client. +</p><a NAME="DebuggerInterfacePython.__remoteTranslation" ID="DebuggerInterfacePython.__remoteTranslation"></a> +<h4>DebuggerInterfacePython.__remoteTranslation</h4> +<b>__remoteTranslation</b>(<i>fn, remote2local=True</i>) +<p> + Private method to perform the path translation. +</p><dl> +<dt><i>fn</i></dt> +<dd> +filename to be translated (string) +</dd><dt><i>remote2local</i></dt> +<dd> +flag indicating the direction of translation + (False = local to remote, True = remote to local [default]) +</dd> +</dl><dl> +<dt>Returns:</dt> +<dd> +translated filename (string) +</dd> +</dl><a NAME="DebuggerInterfacePython.__sendCommand" ID="DebuggerInterfacePython.__sendCommand"></a> +<h4>DebuggerInterfacePython.__sendCommand</h4> +<b>__sendCommand</b>(<i>cmd</i>) +<p> + Private method to send a single line command to the client. +</p><dl> +<dt><i>cmd</i></dt> +<dd> +command to send to the debug client (string) +</dd> +</dl><a NAME="DebuggerInterfacePython.__startProcess" ID="DebuggerInterfacePython.__startProcess"></a> +<h4>DebuggerInterfacePython.__startProcess</h4> +<b>__startProcess</b>(<i>program, arguments, environment=None</i>) +<p> + Private method to start the debugger client process. +</p><dl> +<dt><i>program</i></dt> +<dd> +name of the executable to start (string) +</dd><dt><i>arguments</i></dt> +<dd> +arguments to be passed to the program (list of string) +</dd><dt><i>environment</i></dt> +<dd> +dictionary of environment settings to pass + (dict of string) +</dd> +</dl><dl> +<dt>Returns:</dt> +<dd> +the process object (QProcess) or None +</dd> +</dl><a NAME="DebuggerInterfacePython.flush" ID="DebuggerInterfacePython.flush"></a> +<h4>DebuggerInterfacePython.flush</h4> +<b>flush</b>(<i></i>) +<p> + Public slot to flush the queue. +</p><a NAME="DebuggerInterfacePython.getClientCapabilities" ID="DebuggerInterfacePython.getClientCapabilities"></a> +<h4>DebuggerInterfacePython.getClientCapabilities</h4> +<b>getClientCapabilities</b>(<i></i>) +<p> + Public method to retrieve the debug clients capabilities. +</p><dl> +<dt>Returns:</dt> +<dd> +debug client capabilities (integer) +</dd> +</dl><a NAME="DebuggerInterfacePython.isConnected" ID="DebuggerInterfacePython.isConnected"></a> +<h4>DebuggerInterfacePython.isConnected</h4> +<b>isConnected</b>(<i></i>) +<p> + Public method to test, if a debug client has connected. +</p><dl> +<dt>Returns:</dt> +<dd> +flag indicating the connection status (boolean) +</dd> +</dl><a NAME="DebuggerInterfacePython.newConnection" ID="DebuggerInterfacePython.newConnection"></a> +<h4>DebuggerInterfacePython.newConnection</h4> +<b>newConnection</b>(<i>sock</i>) +<p> + Public slot to handle a new connection. +</p><dl> +<dt><i>sock</i></dt> +<dd> +reference to the socket object (QTcpSocket) +</dd> +</dl><dl> +<dt>Returns:</dt> +<dd> +flag indicating success (boolean) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteBanner" ID="DebuggerInterfacePython.remoteBanner"></a> +<h4>DebuggerInterfacePython.remoteBanner</h4> +<b>remoteBanner</b>(<i></i>) +<p> + Public slot to get the banner info of the remote client. +</p><a NAME="DebuggerInterfacePython.remoteBreakpoint" ID="DebuggerInterfacePython.remoteBreakpoint"></a> +<h4>DebuggerInterfacePython.remoteBreakpoint</h4> +<b>remoteBreakpoint</b>(<i>fn, line, set, cond=None, temp=False</i>) +<p> + Public method to set or clear a breakpoint. +</p><dl> +<dt><i>fn</i></dt> +<dd> +filename the breakpoint belongs to (string) +</dd><dt><i>line</i></dt> +<dd> +linenumber of the breakpoint (int) +</dd><dt><i>set</i></dt> +<dd> +flag indicating setting or resetting a breakpoint (boolean) +</dd><dt><i>cond</i></dt> +<dd> +condition of the breakpoint (string) +</dd><dt><i>temp</i></dt> +<dd> +flag indicating a temporary breakpoint (boolean) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteBreakpointEnable" ID="DebuggerInterfacePython.remoteBreakpointEnable"></a> +<h4>DebuggerInterfacePython.remoteBreakpointEnable</h4> +<b>remoteBreakpointEnable</b>(<i>fn, line, enable</i>) +<p> + Public method to enable or disable a breakpoint. +</p><dl> +<dt><i>fn</i></dt> +<dd> +filename the breakpoint belongs to (string) +</dd><dt><i>line</i></dt> +<dd> +linenumber of the breakpoint (int) +</dd><dt><i>enable</i></dt> +<dd> +flag indicating enabling or disabling a breakpoint + (boolean) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteBreakpointIgnore" ID="DebuggerInterfacePython.remoteBreakpointIgnore"></a> +<h4>DebuggerInterfacePython.remoteBreakpointIgnore</h4> +<b>remoteBreakpointIgnore</b>(<i>fn, line, count</i>) +<p> + Public method to ignore a breakpoint the next couple of occurrences. +</p><dl> +<dt><i>fn</i></dt> +<dd> +filename the breakpoint belongs to (string) +</dd><dt><i>line</i></dt> +<dd> +linenumber of the breakpoint (int) +</dd><dt><i>count</i></dt> +<dd> +number of occurrences to ignore (int) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteCapabilities" ID="DebuggerInterfacePython.remoteCapabilities"></a> +<h4>DebuggerInterfacePython.remoteCapabilities</h4> +<b>remoteCapabilities</b>(<i></i>) +<p> + Public slot to get the debug clients capabilities. +</p><a NAME="DebuggerInterfacePython.remoteClientSetFilter" ID="DebuggerInterfacePython.remoteClientSetFilter"></a> +<h4>DebuggerInterfacePython.remoteClientSetFilter</h4> +<b>remoteClientSetFilter</b>(<i>scope, filter</i>) +<p> + Public method to set a variables filter list. +</p><dl> +<dt><i>scope</i></dt> +<dd> +the scope of the variables (0 = local, 1 = global) +</dd><dt><i>filter</i></dt> +<dd> +regexp string for variable names to filter out (string) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteClientVariable" ID="DebuggerInterfacePython.remoteClientVariable"></a> +<h4>DebuggerInterfacePython.remoteClientVariable</h4> +<b>remoteClientVariable</b>(<i>scope, filter, var, framenr=0</i>) +<p> + Public method to request the variables of the debugged program. +</p><dl> +<dt><i>scope</i></dt> +<dd> +the scope of the variables (0 = local, 1 = global) +</dd><dt><i>filter</i></dt> +<dd> +list of variable types to filter out (list of int) +</dd><dt><i>var</i></dt> +<dd> +list encoded name of variable to retrieve (string) +</dd><dt><i>framenr</i></dt> +<dd> +framenumber of the variables to retrieve (int) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteClientVariables" ID="DebuggerInterfacePython.remoteClientVariables"></a> +<h4>DebuggerInterfacePython.remoteClientVariables</h4> +<b>remoteClientVariables</b>(<i>scope, filter, framenr=0</i>) +<p> + Public method to request the variables of the debugged program. +</p><dl> +<dt><i>scope</i></dt> +<dd> +the scope of the variables (0 = local, 1 = global) +</dd><dt><i>filter</i></dt> +<dd> +list of variable types to filter out (list of int) +</dd><dt><i>framenr</i></dt> +<dd> +framenumber of the variables to retrieve (int) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteCompletion" ID="DebuggerInterfacePython.remoteCompletion"></a> +<h4>DebuggerInterfacePython.remoteCompletion</h4> +<b>remoteCompletion</b>(<i>text</i>) +<p> + Public slot to get the a list of possible commandline completions + from the remote client. +</p><dl> +<dt><i>text</i></dt> +<dd> +the text to be completed (string) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteContinue" ID="DebuggerInterfacePython.remoteContinue"></a> +<h4>DebuggerInterfacePython.remoteContinue</h4> +<b>remoteContinue</b>(<i>special=False</i>) +<p> + Public method to continue the debugged program. +</p><dl> +<dt><i>special</i></dt> +<dd> +flag indicating a special continue operation (boolean) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteCoverage" ID="DebuggerInterfacePython.remoteCoverage"></a> +<h4>DebuggerInterfacePython.remoteCoverage</h4> +<b>remoteCoverage</b>(<i>fn, argv, wd, erase=False</i>) +<p> + Public method to load a new program to collect coverage data. +</p><dl> +<dt><i>fn</i></dt> +<dd> +the filename to run (string) +</dd><dt><i>argv</i></dt> +<dd> +the commandline arguments to pass to the program (string) +</dd><dt><i>wd</i></dt> +<dd> +the working directory for the program (string) +</dd><dt><i>erase=</i></dt> +<dd> +flag indicating that coverage info should be + cleared first (boolean) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteEnvironment" ID="DebuggerInterfacePython.remoteEnvironment"></a> +<h4>DebuggerInterfacePython.remoteEnvironment</h4> +<b>remoteEnvironment</b>(<i>env</i>) +<p> + Public method to set the environment for a program to debug, run, ... +</p><dl> +<dt><i>env</i></dt> +<dd> +environment settings (dictionary) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteEval" ID="DebuggerInterfacePython.remoteEval"></a> +<h4>DebuggerInterfacePython.remoteEval</h4> +<b>remoteEval</b>(<i>arg</i>) +<p> + Public method to evaluate arg in the current context of the debugged + program. +</p><dl> +<dt><i>arg</i></dt> +<dd> +the arguments to evaluate (string) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteExec" ID="DebuggerInterfacePython.remoteExec"></a> +<h4>DebuggerInterfacePython.remoteExec</h4> +<b>remoteExec</b>(<i>stmt</i>) +<p> + Public method to execute stmt in the current context of the debugged + program. +</p><dl> +<dt><i>stmt</i></dt> +<dd> +statement to execute (string) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteLoad" ID="DebuggerInterfacePython.remoteLoad"></a> +<h4>DebuggerInterfacePython.remoteLoad</h4> +<b>remoteLoad</b>(<i>fn, argv, wd, traceInterpreter=False, autoContinue=True, autoFork=False, forkChild=False</i>) +<p> + Public method to load a new program to debug. +</p><dl> +<dt><i>fn</i></dt> +<dd> +the filename to debug (string) +</dd><dt><i>argv</i></dt> +<dd> +the commandline arguments to pass to the program (string) +</dd><dt><i>wd</i></dt> +<dd> +the working directory for the program (string) +</dd><dt><i>traceInterpreter=</i></dt> +<dd> +flag indicating if the interpreter library + should be traced as well (boolean) +</dd><dt><i>autoContinue=</i></dt> +<dd> +flag indicating, that the debugger should not + stop at the first executable line (boolean) +</dd><dt><i>autoFork=</i></dt> +<dd> +flag indicating the automatic fork mode (boolean) +</dd><dt><i>forkChild=</i></dt> +<dd> +flag indicating to debug the child after forking + (boolean) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteProfile" ID="DebuggerInterfacePython.remoteProfile"></a> +<h4>DebuggerInterfacePython.remoteProfile</h4> +<b>remoteProfile</b>(<i>fn, argv, wd, erase=False</i>) +<p> + Public method to load a new program to collect profiling data. +</p><dl> +<dt><i>fn</i></dt> +<dd> +the filename to run (string) +</dd><dt><i>argv</i></dt> +<dd> +the commandline arguments to pass to the program (string) +</dd><dt><i>wd</i></dt> +<dd> +the working directory for the program (string) +</dd><dt><i>erase=</i></dt> +<dd> +flag indicating that timing info should be cleared + first (boolean) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteRawInput" ID="DebuggerInterfacePython.remoteRawInput"></a> +<h4>DebuggerInterfacePython.remoteRawInput</h4> +<b>remoteRawInput</b>(<i>s</i>) +<p> + Public method to send the raw input to the debugged program. +</p><dl> +<dt><i>s</i></dt> +<dd> +the raw input (string) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteRun" ID="DebuggerInterfacePython.remoteRun"></a> +<h4>DebuggerInterfacePython.remoteRun</h4> +<b>remoteRun</b>(<i>fn, argv, wd, autoFork=False, forkChild=False</i>) +<p> + Public method to load a new program to run. +</p><dl> +<dt><i>fn</i></dt> +<dd> +the filename to run (string) +</dd><dt><i>argv</i></dt> +<dd> +the commandline arguments to pass to the program (string) +</dd><dt><i>wd</i></dt> +<dd> +the working directory for the program (string) +</dd><dt><i>autoFork=</i></dt> +<dd> +flag indicating the automatic fork mode (boolean) +</dd><dt><i>forkChild=</i></dt> +<dd> +flag indicating to debug the child after forking + (boolean) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteSetThread" ID="DebuggerInterfacePython.remoteSetThread"></a> +<h4>DebuggerInterfacePython.remoteSetThread</h4> +<b>remoteSetThread</b>(<i>tid</i>) +<p> + Public method to request to set the given thread as current thread. +</p><dl> +<dt><i>tid</i></dt> +<dd> +id of the thread (integer) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteStatement" ID="DebuggerInterfacePython.remoteStatement"></a> +<h4>DebuggerInterfacePython.remoteStatement</h4> +<b>remoteStatement</b>(<i>stmt</i>) +<p> + Public method to execute a Python statement. +</p><dl> +<dt><i>stmt</i></dt> +<dd> +the Python statement to execute (string). It + should not have a trailing newline. +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteStep" ID="DebuggerInterfacePython.remoteStep"></a> +<h4>DebuggerInterfacePython.remoteStep</h4> +<b>remoteStep</b>(<i></i>) +<p> + Public method to single step the debugged program. +</p><a NAME="DebuggerInterfacePython.remoteStepOut" ID="DebuggerInterfacePython.remoteStepOut"></a> +<h4>DebuggerInterfacePython.remoteStepOut</h4> +<b>remoteStepOut</b>(<i></i>) +<p> + Public method to step out the debugged program. +</p><a NAME="DebuggerInterfacePython.remoteStepOver" ID="DebuggerInterfacePython.remoteStepOver"></a> +<h4>DebuggerInterfacePython.remoteStepOver</h4> +<b>remoteStepOver</b>(<i></i>) +<p> + Public method to step over the debugged program. +</p><a NAME="DebuggerInterfacePython.remoteStepQuit" ID="DebuggerInterfacePython.remoteStepQuit"></a> +<h4>DebuggerInterfacePython.remoteStepQuit</h4> +<b>remoteStepQuit</b>(<i></i>) +<p> + Public method to stop the debugged program. +</p><a NAME="DebuggerInterfacePython.remoteThreadList" ID="DebuggerInterfacePython.remoteThreadList"></a> +<h4>DebuggerInterfacePython.remoteThreadList</h4> +<b>remoteThreadList</b>(<i></i>) +<p> + Public method to request the list of threads from the client. +</p><a NAME="DebuggerInterfacePython.remoteUTPrepare" ID="DebuggerInterfacePython.remoteUTPrepare"></a> +<h4>DebuggerInterfacePython.remoteUTPrepare</h4> +<b>remoteUTPrepare</b>(<i>fn, tn, tfn, failed, cov, covname, coverase</i>) +<p> + Public method to prepare a new unittest run. +</p><dl> +<dt><i>fn</i></dt> +<dd> +the filename to load (string) +</dd><dt><i>tn</i></dt> +<dd> +the testname to load (string) +</dd><dt><i>tfn</i></dt> +<dd> +the test function name to load tests from (string) +</dd><dt><i>failed</i></dt> +<dd> +list of failed test, if only failed test should be run + (list of strings) +</dd><dt><i>cov</i></dt> +<dd> +flag indicating collection of coverage data is requested + (boolean) +</dd><dt><i>covname</i></dt> +<dd> +filename to be used to assemble the coverage caches + filename (string) +</dd><dt><i>coverase</i></dt> +<dd> +flag indicating erasure of coverage data is requested + (boolean) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteUTRun" ID="DebuggerInterfacePython.remoteUTRun"></a> +<h4>DebuggerInterfacePython.remoteUTRun</h4> +<b>remoteUTRun</b>(<i></i>) +<p> + Public method to start a unittest run. +</p><a NAME="DebuggerInterfacePython.remoteUTStop" ID="DebuggerInterfacePython.remoteUTStop"></a> +<h4>DebuggerInterfacePython.remoteUTStop</h4> +<b>remoteUTStop</b>(<i></i>) +<p> + Public method to stop a unittest run. +</p><a NAME="DebuggerInterfacePython.remoteWatchpoint" ID="DebuggerInterfacePython.remoteWatchpoint"></a> +<h4>DebuggerInterfacePython.remoteWatchpoint</h4> +<b>remoteWatchpoint</b>(<i>cond, set, temp=False</i>) +<p> + Public method to set or clear a watch expression. +</p><dl> +<dt><i>cond</i></dt> +<dd> +expression of the watch expression (string) +</dd><dt><i>set</i></dt> +<dd> +flag indicating setting or resetting a watch expression + (boolean) +</dd><dt><i>temp</i></dt> +<dd> +flag indicating a temporary watch expression (boolean) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteWatchpointEnable" ID="DebuggerInterfacePython.remoteWatchpointEnable"></a> +<h4>DebuggerInterfacePython.remoteWatchpointEnable</h4> +<b>remoteWatchpointEnable</b>(<i>cond, enable</i>) +<p> + Public method to enable or disable a watch expression. +</p><dl> +<dt><i>cond</i></dt> +<dd> +expression of the watch expression (string) +</dd><dt><i>enable</i></dt> +<dd> +flag indicating enabling or disabling a watch expression + (boolean) +</dd> +</dl><a NAME="DebuggerInterfacePython.remoteWatchpointIgnore" ID="DebuggerInterfacePython.remoteWatchpointIgnore"></a> +<h4>DebuggerInterfacePython.remoteWatchpointIgnore</h4> +<b>remoteWatchpointIgnore</b>(<i>cond, count</i>) +<p> + Public method to ignore a watch expression the next couple of + occurrences. +</p><dl> +<dt><i>cond</i></dt> +<dd> +expression of the watch expression (string) +</dd><dt><i>count</i></dt> +<dd> +number of occurrences to ignore (int) +</dd> +</dl><a NAME="DebuggerInterfacePython.setCallTraceEnabled" ID="DebuggerInterfacePython.setCallTraceEnabled"></a> +<h4>DebuggerInterfacePython.setCallTraceEnabled</h4> +<b>setCallTraceEnabled</b>(<i>on</i>) +<p> + Public method to set the call trace state. +</p><dl> +<dt><i>on</i></dt> +<dd> +flag indicating to enable the call trace function (boolean) +</dd> +</dl><a NAME="DebuggerInterfacePython.shutdown" ID="DebuggerInterfacePython.shutdown"></a> +<h4>DebuggerInterfacePython.shutdown</h4> +<b>shutdown</b>(<i></i>) +<p> + Public method to cleanly shut down. +</p><p> + It closes our socket and shuts down + the debug client. (Needed on Win OS) +</p><a NAME="DebuggerInterfacePython.startRemote" ID="DebuggerInterfacePython.startRemote"></a> +<h4>DebuggerInterfacePython.startRemote</h4> +<b>startRemote</b>(<i>port, runInConsole</i>) +<p> + Public method to start a remote Python interpreter. +</p><dl> +<dt><i>port</i></dt> +<dd> +portnumber the debug server is listening on (integer) +</dd><dt><i>runInConsole</i></dt> +<dd> +flag indicating to start the debugger in a + console window (boolean) +</dd> +</dl><dl> +<dt>Returns:</dt> +<dd> +client process object (QProcess), a flag to indicate + a network connection (boolean) and the name of the interpreter + in case of a local execution (string) +</dd> +</dl><a NAME="DebuggerInterfacePython.startRemoteForProject" ID="DebuggerInterfacePython.startRemoteForProject"></a> +<h4>DebuggerInterfacePython.startRemoteForProject</h4> +<b>startRemoteForProject</b>(<i>port, runInConsole</i>) +<p> + Public method to start a remote Python interpreter for a project. +</p><dl> +<dt><i>port</i></dt> +<dd> +portnumber the debug server is listening on (integer) +</dd><dt><i>runInConsole</i></dt> +<dd> +flag indicating to start the debugger in a + console window (boolean) +</dd> +</dl><dl> +<dt>Returns:</dt> +<dd> +client process object (QProcess), a flag to indicate + a network connection (boolean) and the name of the interpreter + in case of a local execution (string) +</dd> +</dl> +<div align="right"><a href="#top">Up</a></div> +<hr /><hr /> +<a NAME="createDebuggerInterfacePython" ID="createDebuggerInterfacePython"></a> +<h2>createDebuggerInterfacePython</h2> +<b>createDebuggerInterfacePython</b>(<i>debugServer, passive</i>) +<p> + Module function to create a debugger interface instance. +</p><p> + +</p><dl> +<dt><i>debugServer</i> (DebugServer)</dt> +<dd> +reference to the debug server +</dd><dt><i>passive</i> (bool)</dt> +<dd> +flag indicating passive connection mode +</dd> +</dl><dl> +<dt>Returns:</dt> +<dd> +instantiated debugger interface +</dd> +</dl><dl> +<dt>Return Type:</dt> +<dd> +DebuggerInterfacePython +</dd> +</dl> +<div align="right"><a href="#top">Up</a></div> +<hr /><hr /> +<a NAME="getRegistryData" ID="getRegistryData"></a> +<h2>getRegistryData</h2> +<b>getRegistryData</b>(<i></i>) +<p> + Module function to get characterizing data for the debugger interface. +</p><dl> +<dt>Returns:</dt> +<dd> +tuple containing client type, client capabilities, client file + type associations and reference to creation function +</dd> +</dl><dl> +<dt>Return Type:</dt> +<dd> +tuple of (str, int, list of str, function) +</dd> +</dl> +<div align="right"><a href="#top">Up</a></div> +<hr /> +</body></html> \ No newline at end of file
--- a/eric6.e4p Sat Sep 03 18:01:19 2016 +0200 +++ b/eric6.e4p Sat Sep 03 18:02:37 2016 +0200 @@ -37,6 +37,7 @@ <Source>DebugClients/Python/DebugConfig.py</Source> <Source>DebugClients/Python/DebugProtocol.py</Source> <Source>DebugClients/Python/DebugThread.py</Source> + <Source>DebugClients/Python/DebugUtilities.py</Source> <Source>DebugClients/Python/FlexCompleter.py</Source> <Source>DebugClients/Python/PyProfile.py</Source> <Source>DebugClients/Python/__init__.py</Source> @@ -133,7 +134,7 @@ <Source>Debugger/DebugUI.py</Source> <Source>Debugger/DebugViewer.py</Source> <Source>Debugger/DebuggerInterfaceNone.py</Source> - <Source>Debugger/DebuggerInterfacePython.py</Source> + <Source>Debugger/DebuggerInterfacePython2.py</Source> <Source>Debugger/DebuggerInterfacePython3.py</Source> <Source>Debugger/EditBreakpointDialog.py</Source> <Source>Debugger/EditWatchpointDialog.py</Source>