Sat, 03 Sep 2016 18:01:19 +0200
Fixed a few issues in the modernized Python 3 debugger.
--- a/DebugClients/Python3/AsyncFile.py Fri Sep 02 19:08:02 2016 +0200 +++ b/DebugClients/Python3/AsyncFile.py Sat Sep 03 18:01:19 2016 +0200 @@ -51,9 +51,6 @@ self.nWriteErrors = 0 self.encoding = "utf-8" - self.line_buffering = True - self.errors = None - self.wpending = '' def __checkMode(self, mode): @@ -155,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): """ @@ -200,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): """ @@ -316,8 +313,7 @@ if not self.wpending: self.wpending = s elif len(self.wpending) + len(s) > self.maxbuffersize: - # flush wpending so that different string types are not - # concatenated + # 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
--- a/DebugClients/Python3/DCTestResult.py Fri Sep 02 19:08:02 2016 +0200 +++ b/DebugClients/Python3/DCTestResult.py Sat Sep 03 18:01:19 2016 +0200 @@ -124,7 +124,7 @@ [self.__dbgClient.readstream], [], [], 0.01) if self.__dbgClient.readstream in rrdy: - self.__dbgClient.readReady(self.__dbgClient.readstream.fileno()) + self.__dbgClient.readReady(self.__dbgClient.readstream) # # eflag: noqa = M702
--- a/DebugClients/Python3/DebugBase.py Fri Sep 02 19:08:02 2016 +0200 +++ b/DebugClients/Python3/DebugBase.py Sat Sep 03 18:01:19 2016 +0200 @@ -199,6 +199,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 = "{0}:{1}:{2}".format( self._dbgClient.absPath(self.fix_frame_filename(fr)), fr.f_lineno, @@ -306,6 +307,7 @@ 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 @@ -523,7 +525,7 @@ # 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 @@ -532,7 +534,7 @@ 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 @@ -707,18 +709,35 @@ if exctype in [SystemExit, bdb.BdbQuit]: atexit._run_exitfuncs() if excval is None: - excval = 0 + exitcode = 0 message = "" elif isinstance(excval, str): - excval = 1 + exitcode = 1 message = excval elif isinstance(excval, bytes): - excval = 1 + exitcode = 1 message = excval.decode() - if isinstance(excval, int): - self._dbgClient.progTerminated(excval, message) + elif isinstance(excval, int): + exitcode = excval + message = "" + elif isinstance(excval, SystemExit): + code = excval.code + if isinstance(code, str): + exitcode = 1 + message = code + elif isinstance(code, bytes): + exitcode = 1 + message = code.decode() + 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]:
--- a/DebugClients/Python3/DebugClientBase.py Fri Sep 02 19:08:02 2016 +0200 +++ b/DebugClients/Python3/DebugClientBase.py Sat Sep 03 18:01:19 2016 +0200 @@ -722,9 +722,8 @@ if tlist: tlist.insert( 0, "Traceback (innermost last):\n") - tlist[len(tlist):] = \ - traceback.format_exception_only( - exc_type, exc_value) + tlist.extend(traceback.format_exception_only( + exc_type, exc_value)) finally: tblist = exc_tb = None @@ -823,7 +822,6 @@ wp = self.mainThread.get_watch(params["condition"]) if wp is not None: wp.ignore = params["count"] - return elif method == "RequestShutdown": self.sessionClose() @@ -832,6 +830,10 @@ self.__completionList(params["text"]) elif method == "RequestUTPrepare": + 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 @@ -1345,11 +1347,9 @@ """ 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()
--- a/DebugClients/Python3/DebugThread.py Fri Sep 02 19:08:02 2016 +0200 +++ b/DebugClients/Python3/DebugThread.py Sat Sep 03 18:01:19 2016 +0200 @@ -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)
--- a/Debugger/DebuggerInterfacePython3.py Fri Sep 02 19:08:02 2016 +0200 +++ b/Debugger/DebuggerInterfacePython3.py Sat Sep 03 18:01:19 2016 +0200 @@ -32,7 +32,7 @@ class DebuggerInterfacePython3(QObject): """ - Class implementing the Python debugger interface for the debug server. + Class implementing the Python 3 debugger interface for the debug server. """ def __init__(self, debugServer, passive): """ @@ -405,7 +405,6 @@ # close down socket, and shut down client as well. self.__sendJsonCommand("RequestShutdown", {}) self.qsock.flush() - self.qsock.close() # reinitialize @@ -922,14 +921,13 @@ params["prompt"], params["echo"]) elif method == "ResponseBPConditionError": - params["filename"] = self.translate(params["filename"], True) + fn = self.translate(params["filename"], True) self.debugServer.signalClientBreakConditionError( - params["filename"], params["line"]) + fn, params["line"]) elif method == "ResponseClearBreakpoint": - params["filename"] = self.translate(params["filename"], True) - self.debugServer.signalClientClearBreak( - params["filename"], params["line"]) + fn = self.translate(params["filename"], True) + self.debugServer.signalClientClearBreak(fn, params["line"]) elif method == "ResponseWatchConditionError": self.debugServer.signalClientWatchConditionError( @@ -972,6 +970,7 @@ elif method == "ResponseExit": self.__scriptName = "" + # TODO: combine these into signalClientExit self.debugServer.signalClientExit(params["status"]) if params["message"]: self.debugServer.signalClientOutput(params["message"]) @@ -1021,17 +1020,6 @@ elif method == "RequestForkTo": self.__askForkTo() - 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', 'backslashreplace')) - else: - self.queue.append(cmd) - def __sendJsonCommand(self, command, params): """ Private method to send a single command to the client. @@ -1085,7 +1073,7 @@ else: exts.append(".{0}".format(ext)) - if exts: + if exts and Preferences.getDebugger("Python3Interpreter"): return ["Python3", ClientDefaultCapabilities, exts, createDebuggerInterfacePython3] else: