diff -r 556528860c7a -r 684f5ba04f0b DebugClients/Python/DebugBase.py --- a/DebugClients/Python/DebugBase.py Thu Jun 23 19:24:09 2016 +0200 +++ b/DebugClients/Python/DebugBase.py Sun Jun 26 16:32:01 2016 +0200 @@ -48,6 +48,13 @@ Provides simple wrapper methods around bdb for the 'owning' client to call to step etc. """ + # Don't thrust distutils.sysconfig.get_python_lib: possible case mismatch + # on Windows + lib = os.path.dirname(bdb.__file__) + # tuple required because it's accessed a lot of times by startswith method + pathsToSkip = ('<', os.path.dirname(__file__), bdb.__file__[:-1]) + filesToSkip = {} + def __init__(self, dbgClient): """ Constructor @@ -60,6 +67,7 @@ self._mainThread = 1 self.breaks = self._dbgClient.breakpoints + self.tracePythonLibs(0) self.__event = "" self.__isBroken = "" @@ -197,7 +205,8 @@ @param toFrame destination frame (frame) """ if self._dbgClient.callTraceEnabled: - if not self.__skip_it(fromFrame) and not self.__skip_it(toFrame): + if (not self.__skipFrame(fromFrame) and + not self.__skipFrame(toFrame)): if event in ["call", "return"]: fr = fromFrame fromStr = "%s:%s:%s" % ( @@ -248,7 +257,7 @@ return self.trace_dispatch if event == 'c_return': return self.trace_dispatch - print 'DebugBase.trace_dispatch: unknown debugging event:', repr(event) # __IGNORE_WARNING__ + print 'DebugBase.trace_dispatch: unknown debugging event:', repr(event) # __IGNORE_WARNING__ return self.trace_dispatch def dispatch_line(self, frame): @@ -293,7 +302,7 @@ @return local trace function @exception bdb.BdbQuit raised to indicate the end of the debug session """ - if not self.__skip_it(frame): + if not self.__skipFrame(frame): self.user_exception(frame, arg) if self.quitting: raise bdb.BdbQuit @@ -534,8 +543,8 @@ Because eric6 supports only one breakpoint per line, this overwritten method will return this one and only breakpoint. - @param filename filename of the bp to retrieve (string) - @param lineno linenumber of the bp to retrieve (integer) + @param filename the filename of the bp to retrieve (string) + @param lineno the linenumber of the bp to retrieve (integer) @return breakpoint or None, if there is no bp """ filename = self.canonic(filename) @@ -772,8 +781,8 @@ def user_return(self, frame, retval): """ - Public method reimplemented to report program termination to the - debug server. + Public method reimplemented to report program termination to the debug + server. @param frame the frame object @param retval the return value of the program @@ -797,11 +806,30 @@ @param frame the frame object @return flag indicating whether the debugger should stop here """ - if self.__skip_it(frame): + if self.__skipFrame(frame): return 0 return bdb.Bdb.stop_here(self, frame) - def __skip_it(self, frame): + def tracePythonLibs(self, enable): + """ + Public methode to update the settings to trace into Python libraries. + + @param enable let's debug into Python libraries (int) + """ + pathsToSkip = list(self.pathsToSkip) + # don't trace into Python library? + if enable: + pathsToSkip = [x for x in pathsToSkip if not x.endswith( + ("site-packages", "dist-packages", self.lib))] + else: + pathsToSkip.append(self.lib) + localLib = [x for x in sys.path if x.endswith(("site-packages", + "dist-packages")) and not x.startswith(self.lib)] + pathsToSkip.extend(localLib) + + self.pathsToSkip = tuple(pathsToSkip) + + def __skipFrame(self, frame): """ Private method to filter out debugger files. @@ -811,33 +839,15 @@ @param frame the frame object @return flag indicating whether the debugger should skip this frame """ - if frame is None: - return 1 - - fn = self.fix_frame_filename(frame) - - # Eliminate things like <string> and <stdin>. - if fn[0] == '<': - return 1 - - #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', - 'PyProfile.py'] or \ - os.path.dirname(fn).endswith("coverage"): - return 1 - - if self._dbgClient.shouldSkip(fn): - return 1 - - return 0 + try: + return self.filesToSkip[frame.f_code.co_filename] + except KeyError: + ret = frame.f_code.co_filename.startswith(self.pathsToSkip) + self.filesToSkip[frame.f_code.co_filename] = ret + return ret + except AttributeError: + # if frame is None + return True def isBroken(self): """