Little extension to Pdb

Alex cut_me_out at hotmail.com
Tue Sep 5 17:57:59 EDT 2000


Hi.  I like to set a Pdb trace when I'm testing my programs, so that I
drop into the debugger if an exception gets thrown.  The only problem
with that is that when you use Pdb.set_trace, it goes straight into
interactive mode, and goes back into interactive mode when the program's
finished.  So I wrote a subclass that only goes interactive when an
exception is thrown.  I've been using it for a bit now, and it seems to
work correctly, but I make no promises.

Alex.

import pdb, sys, traceback

class PhonyError(Exception):

    '''Phony error to induce traceback.'''

    pass

class my_Pdb(pdb.Pdb):

    '''Attempt at a Pdb that doesn\'t go interactive when a trace is
    first set, or the end of the script is reached.'''

    def __init__(self):

        self.return_count = 0
        pdb.Pdb.__init__(self)

    def trace_dispatch(self, frame, event, arg):

        if event == 'return':

            # Check whether this is at the top level.  If so, ignore
            # it.  This check might be unnecessary; I only put it in
            # because I was too lazy to figure out exactly when a
            # 'return' event can occur.
            try:
                raise PhonyError
            except PhonyError:
                tb = sys.exc_info()[2]
                if len(traceback.extract_tb(tb)) == 1:

                    # At the top of the traceback, must be about to
                    # finish, so don't drop into the debugger.
                    return
                    
        # Pass it on to the usual pdb routines.
        pdb.Pdb.trace_dispatch(self, frame, event, arg)

    def set_trace(self):

        '''Set a trace which does not immediately drop into the
        debugger.  This was rather heavy-handedly copied from
        bdb.Bdb.set_trace.  Simply replaced the self.set_step call
        from that routine with self.set_continue.'''

        try:
            raise PhonyError
        except PhonyError:
            tb = sys.exc_info()[2]
            frame = tb.tb_frame.f_back
        self.reset()
        while frame:
            frame.f_trace = self.trace_dispatch
            self.botframe = frame
            frame = frame.f_back

        # Indicate that we don't want to step through the code at this
        # point.
        self.set_continue()
        sys.settrace(self.trace_dispatch)

def set_trace():
    my_Pdb().set_trace()

def test_function():
    set_trace()
    
if __name__ == '__main__':
    test_function()

-- 
The chain of destiny can only be grasped one link at a time.  
-- Sir Winston Churchill



More information about the Python-list mailing list