bdb.py

来自「mallet是自然语言处理、机器学习领域的一个开源项目。」· Python 代码 · 共 564 行 · 第 1/2 页

PY
564
字号
            return []    def get_all_breaks(self):        return self.breaks    # Derived classes and clients can call the following method    # to get a data structure representing a stack trace.    def get_stack(self, f, t):        stack = []        if t and t.tb_frame is f:            t = t.tb_next        while f is not None:            stack.append((f, f.f_lineno))            if f is self.botframe:                break            f = f.f_back        stack.reverse()        i = max(0, len(stack) - 1)        while t is not None:            stack.append((t.tb_frame, t.tb_lineno))            t = t.tb_next        return stack, i    #    def format_stack_entry(self, frame_lineno, lprefix=': '):        import linecache, repr        frame, lineno = frame_lineno        filename = self.canonic(frame.f_code.co_filename)        s = filename + '(' + `lineno` + ')'        if frame.f_code.co_name:            s = s + frame.f_code.co_name        else:            s = s + "<lambda>"        if frame.f_locals.has_key('__args__'):            args = frame.f_locals['__args__']        else:            args = None        if args:            s = s + repr.repr(args)        else:            s = s + '()'        if frame.f_locals.has_key('__return__'):            rv = frame.f_locals['__return__']            s = s + '->'            s = s + repr.repr(rv)        line = linecache.getline(filename, lineno)        if line: s = s + lprefix + line.strip()        return s    # The following two methods can be called by clients to use    # a debugger to debug a statement, given as a string.    def run(self, cmd, globals=None, locals=None):        if globals is None:            import __main__            globals = __main__.__dict__        if locals is None:            locals = globals        self.reset()        sys.settrace(self.trace_dispatch)        if not isinstance(cmd, types.CodeType):            cmd = cmd+'\n'        try:            try:                exec cmd in globals, locals            except BdbQuit:                pass        finally:            self.quitting = 1            sys.settrace(None)    def runeval(self, expr, globals=None, locals=None):        if globals is None:            import __main__            globals = __main__.__dict__        if locals is None:            locals = globals        self.reset()        sys.settrace(self.trace_dispatch)        if not isinstance(expr, types.CodeType):            expr = expr+'\n'        try:            try:                return eval(expr, globals, locals)            except BdbQuit:                pass        finally:            self.quitting = 1            sys.settrace(None)    def runctx(self, cmd, globals, locals):        # B/W compatibility        self.run(cmd, globals, locals)    # This method is more useful to debug a single function call.    def runcall(self, func, *args):        self.reset()        sys.settrace(self.trace_dispatch)        res = None        try:            try:                res = apply(func, args)            except BdbQuit:                pass        finally:            self.quitting = 1            sys.settrace(None)        return resdef set_trace():    Bdb().set_trace()class Breakpoint:    """Breakpoint class    Implements temporary breakpoints, ignore counts, disabling and    (re)-enabling, and conditionals.    Breakpoints are indexed by number through bpbynumber and by    the file,line tuple using bplist.  The former points to a    single instance of class Breakpoint.  The latter points to a    list of such instances since there may be more than one    breakpoint per line.    """    # XXX Keeping state in the class is a mistake -- this means    # you cannot have more than one active Bdb instance.    next = 1        # Next bp to be assigned    bplist = {}     # indexed by (file, lineno) tuple    bpbynumber = [None] # Each entry is None or an instance of Bpt                # index 0 is unused, except for marking an                # effective break .... see effective()    def __init__(self, file, line, temporary=0, cond = None):        self.file = file    # This better be in canonical form!        self.line = line        self.temporary = temporary        self.cond = cond        self.enabled = 1        self.ignore = 0        self.hits = 0        self.number = Breakpoint.next        Breakpoint.next = Breakpoint.next + 1        # Build the two lists        self.bpbynumber.append(self)        if self.bplist.has_key((file, line)):            self.bplist[file, line].append(self)        else:            self.bplist[file, line] = [self]    def deleteMe(self):        index = (self.file, self.line)        self.bpbynumber[self.number] = None   # No longer in list        self.bplist[index].remove(self)        if not self.bplist[index]:            # No more bp for this f:l combo            del self.bplist[index]    def enable(self):        self.enabled = 1    def disable(self):        self.enabled = 0    def bpprint(self):        if self.temporary:            disp = 'del  '        else:            disp = 'keep '        if self.enabled:            disp = disp + 'yes'        else:            disp = disp + 'no '        print '%-4dbreakpoint    %s at %s:%d' % (self.number, disp,                             self.file, self.line)        if self.cond:            print '\tstop only if %s' % (self.cond,)        if self.ignore:            print '\tignore next %d hits' % (self.ignore)        if (self.hits):            if (self.hits > 1): ss = 's'            else: ss = ''            print ('\tbreakpoint already hit %d time%s' %                   (self.hits, ss))# -----------end of Breakpoint class----------# Determines if there is an effective (active) breakpoint at this# line of code.  Returns breakpoint number or 0 if nonedef effective(file, line, frame):    """Determine which breakpoint for this file:line is to be acted upon.    Called only if we know there is a bpt at this    location.  Returns breakpoint that was triggered and a flag    that indicates if it is ok to delete a temporary bp.    """    possibles = Breakpoint.bplist[file,line]    for i in range(0, len(possibles)):        b = possibles[i]        if b.enabled == 0:            continue        # Count every hit when bp is enabled        b.hits = b.hits + 1        if not b.cond:            # If unconditional, and ignoring,            # go on to next, else break            if b.ignore > 0:                b.ignore = b.ignore -1                continue            else:                # breakpoint and marker that's ok                # to delete if temporary                return (b,1)        else:            # Conditional bp.            # Ignore count applies only to those bpt hits where the            # condition evaluates to true.            try:                val = eval(b.cond, frame.f_globals,                       frame.f_locals)                if val:                    if b.ignore > 0:                        b.ignore = b.ignore -1                        # continue                    else:                        return (b,1)                # else:                #   continue            except:                # if eval fails, most conservative                # thing is to stop on breakpoint                # regardless of ignore count.                # Don't delete temporary,                # as another hint to user.                return (b,0)    return (None, None)# -------------------- testing --------------------class Tdb(Bdb):    def user_call(self, frame, args):        name = frame.f_code.co_name        if not name: name = '???'        print '+++ call', name, args    def user_line(self, frame):        import linecache        name = frame.f_code.co_name        if not name: name = '???'        fn = self.canonic(frame.f_code.co_filename)        line = linecache.getline(fn, frame.f_lineno)        print '+++', fn, frame.f_lineno, name, ':', line.strip()    def user_return(self, frame, retval):        print '+++ return', retval    def user_exception(self, frame, exc_stuff):        print '+++ exception', exc_stuff        self.set_continue()def foo(n):    print 'foo(', n, ')'    x = bar(n*10)    print 'bar returned', xdef bar(a):    print 'bar(', a, ')'    return a/2def test():    t = Tdb()    t.run('import bdb; bdb.foo(10)')# end

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?