home *** CD-ROM | disk | FTP | other *** search
/ PC Extra 07 & 08 / pca1507.iso / Software / psp8 / Data1.cab / bdb.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2003-04-22  |  21.6 KB  |  643 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.2)
  3.  
  4. '''Debugger basics'''
  5. import sys
  6. import os
  7. import types
  8. __all__ = [
  9.     'BdbQuit',
  10.     'Bdb',
  11.     'Breakpoint']
  12. BdbQuit = 'bdb.BdbQuit'
  13.  
  14. class Bdb:
  15.     '''Generic Python debugger base class.
  16.  
  17.     This class takes care of details of the trace facility;
  18.     a derived class should implement user interaction.
  19.     The standard debugger class (pdb.Pdb) is an example.
  20.     '''
  21.     
  22.     def __init__(self):
  23.         self.breaks = { }
  24.         self.fncache = { }
  25.  
  26.     
  27.     def canonic(self, filename):
  28.         if filename == '<' + filename[1:-1] + '>':
  29.             return filename
  30.         
  31.         canonic = self.fncache.get(filename)
  32.         if not canonic:
  33.             canonic = os.path.abspath(filename)
  34.             self.fncache[filename] = canonic
  35.         
  36.         return canonic
  37.  
  38.     
  39.     def reset(self):
  40.         import linecache
  41.         linecache.checkcache()
  42.         self.botframe = None
  43.         self.stopframe = None
  44.         self.returnframe = None
  45.         self.quitting = 0
  46.  
  47.     
  48.     def trace_dispatch(self, frame, event, arg):
  49.         if self.quitting:
  50.             return None
  51.         
  52.         if event == 'line':
  53.             return self.dispatch_line(frame)
  54.         
  55.         if event == 'call':
  56.             return self.dispatch_call(frame, arg)
  57.         
  58.         if event == 'return':
  59.             return self.dispatch_return(frame, arg)
  60.         
  61.         if event == 'exception':
  62.             return self.dispatch_exception(frame, arg)
  63.         
  64.         print 'bdb.Bdb.dispatch: unknown debugging event:', `event`
  65.         return self.trace_dispatch
  66.  
  67.     
  68.     def dispatch_line(self, frame):
  69.         if self.stop_here(frame) or self.break_here(frame):
  70.             self.user_line(frame)
  71.             if self.quitting:
  72.                 raise BdbQuit
  73.             
  74.         
  75.         return self.trace_dispatch
  76.  
  77.     
  78.     def dispatch_call(self, frame, arg):
  79.         if self.botframe is None:
  80.             self.botframe = frame
  81.             return self.trace_dispatch
  82.         
  83.         if not self.stop_here(frame):
  84.             pass
  85.         if not self.break_anywhere(frame):
  86.             return None
  87.         
  88.         self.user_call(frame, arg)
  89.         if self.quitting:
  90.             raise BdbQuit
  91.         
  92.         return self.trace_dispatch
  93.  
  94.     
  95.     def dispatch_return(self, frame, arg):
  96.         if self.stop_here(frame) or frame == self.returnframe:
  97.             self.user_return(frame, arg)
  98.             if self.quitting:
  99.                 raise BdbQuit
  100.             
  101.         
  102.         return self.trace_dispatch
  103.  
  104.     
  105.     def dispatch_exception(self, frame, arg):
  106.         if self.stop_here(frame):
  107.             self.user_exception(frame, arg)
  108.             if self.quitting:
  109.                 raise BdbQuit
  110.             
  111.         
  112.         return self.trace_dispatch
  113.  
  114.     
  115.     def stop_here(self, frame):
  116.         if self.stopframe is None:
  117.             return 1
  118.         
  119.         if frame is self.stopframe:
  120.             return 1
  121.         
  122.         while frame is not None and frame is not self.stopframe:
  123.             if frame is self.botframe:
  124.                 return 1
  125.             
  126.             frame = frame.f_back
  127.         return 0
  128.  
  129.     
  130.     def break_here(self, frame):
  131.         filename = self.canonic(frame.f_code.co_filename)
  132.         if not self.breaks.has_key(filename):
  133.             return 0
  134.         
  135.         lineno = frame.f_lineno
  136.         if not (lineno in self.breaks[filename]):
  137.             return 0
  138.         
  139.         (bp, flag) = effective(filename, lineno, frame)
  140.         if bp:
  141.             self.currentbp = bp.number
  142.             if flag and bp.temporary:
  143.                 self.do_clear(str(bp.number))
  144.             
  145.             return 1
  146.         else:
  147.             return 0
  148.  
  149.     
  150.     def do_clear(self, arg):
  151.         raise NotImplementedError, 'subclass of bdb must implement do_clear()'
  152.  
  153.     
  154.     def break_anywhere(self, frame):
  155.         return self.breaks.has_key(self.canonic(frame.f_code.co_filename))
  156.  
  157.     
  158.     def user_call(self, frame, argument_list):
  159.         '''This method is called when there is the remote possibility
  160.         that we ever need to stop in this function.'''
  161.         pass
  162.  
  163.     
  164.     def user_line(self, frame):
  165.         '''This method is called when we stop or break at this line.'''
  166.         pass
  167.  
  168.     
  169.     def user_return(self, frame, return_value):
  170.         '''This method is called when a return trap is set here.'''
  171.         pass
  172.  
  173.     
  174.     def user_exception(self, frame, .4):
  175.         '''This method is called if an exception occurs,
  176.         but only if we are to stop at or just below this level.'''
  177.         (exc_type, exc_value, exc_traceback) = .4
  178.  
  179.     
  180.     def set_step(self):
  181.         '''Stop after one line of code.'''
  182.         self.stopframe = None
  183.         self.returnframe = None
  184.         self.quitting = 0
  185.  
  186.     
  187.     def set_next(self, frame):
  188.         '''Stop on the next line in or below the given frame.'''
  189.         self.stopframe = frame
  190.         self.returnframe = None
  191.         self.quitting = 0
  192.  
  193.     
  194.     def set_return(self, frame):
  195.         '''Stop when returning from the given frame.'''
  196.         self.stopframe = frame.f_back
  197.         self.returnframe = frame
  198.         self.quitting = 0
  199.  
  200.     
  201.     def set_trace(self):
  202.         '''Start debugging from here.'''
  203.         
  204.         try:
  205.             1 + ''
  206.         except:
  207.             frame = sys.exc_info()[2].tb_frame.f_back
  208.  
  209.         self.reset()
  210.         while frame:
  211.             frame.f_trace = self.trace_dispatch
  212.             self.botframe = frame
  213.             frame = frame.f_back
  214.         self.set_step()
  215.         sys.settrace(self.trace_dispatch)
  216.  
  217.     
  218.     def set_continue(self):
  219.         self.stopframe = self.botframe
  220.         self.returnframe = None
  221.         self.quitting = 0
  222.         if not (self.breaks):
  223.             sys.settrace(None)
  224.             
  225.             try:
  226.                 1 + ''
  227.             except:
  228.                 frame = sys.exc_info()[2].tb_frame.f_back
  229.  
  230.             while frame and frame is not self.botframe:
  231.                 del frame.f_trace
  232.                 frame = frame.f_back
  233.         
  234.  
  235.     
  236.     def set_quit(self):
  237.         self.stopframe = self.botframe
  238.         self.returnframe = None
  239.         self.quitting = 1
  240.         sys.settrace(None)
  241.  
  242.     
  243.     def set_break(self, filename, lineno, temporary = 0, cond = None):
  244.         filename = self.canonic(filename)
  245.         import linecache
  246.         line = linecache.getline(filename, lineno)
  247.         if not line:
  248.             return 'Line %s:%d does not exist' % (filename, lineno)
  249.         
  250.         if not self.breaks.has_key(filename):
  251.             self.breaks[filename] = []
  252.         
  253.         list = self.breaks[filename]
  254.         if not (lineno in list):
  255.             list.append(lineno)
  256.         
  257.         bp = Breakpoint(filename, lineno, temporary, cond)
  258.  
  259.     
  260.     def clear_break(self, filename, lineno):
  261.         filename = self.canonic(filename)
  262.         if not self.breaks.has_key(filename):
  263.             return 'There are no breakpoints in %s' % filename
  264.         
  265.         if lineno not in self.breaks[filename]:
  266.             return 'There is no breakpoint at %s:%d' % (filename, lineno)
  267.         
  268.         for bp in Breakpoint.bplist[(filename, lineno)][:]:
  269.             bp.deleteMe()
  270.         
  271.         if not Breakpoint.bplist.has_key((filename, lineno)):
  272.             self.breaks[filename].remove(lineno)
  273.         
  274.         if not self.breaks[filename]:
  275.             del self.breaks[filename]
  276.         
  277.  
  278.     
  279.     def clear_bpbynumber(self, arg):
  280.         
  281.         try:
  282.             number = int(arg)
  283.         except:
  284.             return 'Non-numeric breakpoint number (%s)' % arg
  285.  
  286.         
  287.         try:
  288.             bp = Breakpoint.bpbynumber[number]
  289.         except IndexError:
  290.             return 'Breakpoint number (%d) out of range' % number
  291.  
  292.         if not bp:
  293.             return 'Breakpoint (%d) already deleted' % number
  294.         
  295.         self.clear_break(bp.file, bp.line)
  296.  
  297.     
  298.     def clear_all_file_breaks(self, filename):
  299.         filename = self.canonic(filename)
  300.         if not self.breaks.has_key(filename):
  301.             return 'There are no breakpoints in %s' % filename
  302.         
  303.         for line in self.breaks[filename]:
  304.             blist = Breakpoint.bplist[(filename, line)]
  305.             for bp in blist:
  306.                 bp.deleteMe()
  307.             
  308.         
  309.         del self.breaks[filename]
  310.  
  311.     
  312.     def clear_all_breaks(self):
  313.         if not (self.breaks):
  314.             return 'There are no breakpoints'
  315.         
  316.         for bp in Breakpoint.bpbynumber:
  317.             if bp:
  318.                 bp.deleteMe()
  319.             
  320.         
  321.         self.breaks = { }
  322.  
  323.     
  324.     def get_break(self, filename, lineno):
  325.         filename = self.canonic(filename)
  326.         if self.breaks.has_key(filename):
  327.             pass
  328.         return lineno in self.breaks[filename]
  329.  
  330.     
  331.     def get_breaks(self, filename, lineno):
  332.         filename = self.canonic(filename)
  333.         if not self.breaks.has_key(filename) and lineno in self.breaks[filename] and Breakpoint.bplist[(filename, lineno)]:
  334.             pass
  335.         return []
  336.  
  337.     
  338.     def get_file_breaks(self, filename):
  339.         filename = self.canonic(filename)
  340.         if self.breaks.has_key(filename):
  341.             return self.breaks[filename]
  342.         else:
  343.             return []
  344.  
  345.     
  346.     def get_all_breaks(self):
  347.         return self.breaks
  348.  
  349.     
  350.     def get_stack(self, f, t):
  351.         stack = []
  352.         if t and t.tb_frame is f:
  353.             t = t.tb_next
  354.         
  355.         while f is not None:
  356.             stack.append((f, f.f_lineno))
  357.             if f is self.botframe:
  358.                 break
  359.             
  360.             f = f.f_back
  361.         stack.reverse()
  362.         i = max(0, len(stack) - 1)
  363.         while t is not None:
  364.             stack.append((t.tb_frame, t.tb_lineno))
  365.             t = t.tb_next
  366.         return (stack, i)
  367.  
  368.     
  369.     def format_stack_entry(self, frame_lineno, lprefix = ': '):
  370.         import linecache
  371.         import repr
  372.         (frame, lineno) = frame_lineno
  373.         filename = self.canonic(frame.f_code.co_filename)
  374.         s = filename + '(' + `lineno` + ')'
  375.         if frame.f_code.co_name:
  376.             s = s + frame.f_code.co_name
  377.         else:
  378.             s = s + '<lambda>'
  379.         if frame.f_locals.has_key('__args__'):
  380.             args = frame.f_locals['__args__']
  381.         else:
  382.             args = None
  383.         if args:
  384.             s = s + repr.repr(args)
  385.         else:
  386.             s = s + '()'
  387.         if frame.f_locals.has_key('__return__'):
  388.             rv = frame.f_locals['__return__']
  389.             s = s + '->'
  390.             s = s + repr.repr(rv)
  391.         
  392.         line = linecache.getline(filename, lineno)
  393.         if line:
  394.             s = s + lprefix + line.strip()
  395.         
  396.         return s
  397.  
  398.     
  399.     def run(self, cmd, globals = None, locals = None):
  400.         if globals is None:
  401.             import __main__
  402.             globals = __main__.__dict__
  403.         
  404.         if locals is None:
  405.             locals = globals
  406.         
  407.         self.reset()
  408.         sys.settrace(self.trace_dispatch)
  409.         if not isinstance(cmd, types.CodeType):
  410.             cmd = cmd + '\n'
  411.         
  412.         
  413.         try:
  414.             
  415.             try:
  416.                 exec cmd in globals, locals
  417.             except BdbQuit:
  418.                 pass
  419.  
  420.         finally:
  421.             self.quitting = 1
  422.             sys.settrace(None)
  423.  
  424.  
  425.     
  426.     def runeval(self, expr, globals = None, locals = None):
  427.         if globals is None:
  428.             import __main__
  429.             globals = __main__.__dict__
  430.         
  431.         if locals is None:
  432.             locals = globals
  433.         
  434.         self.reset()
  435.         sys.settrace(self.trace_dispatch)
  436.         if not isinstance(expr, types.CodeType):
  437.             expr = expr + '\n'
  438.         
  439.         
  440.         try:
  441.             
  442.             try:
  443.                 return eval(expr, globals, locals)
  444.             except BdbQuit:
  445.                 pass
  446.  
  447.         finally:
  448.             self.quitting = 1
  449.             sys.settrace(None)
  450.  
  451.  
  452.     
  453.     def runctx(self, cmd, globals, locals):
  454.         self.run(cmd, globals, locals)
  455.  
  456.     
  457.     def runcall(self, func, *args):
  458.         self.reset()
  459.         sys.settrace(self.trace_dispatch)
  460.         res = None
  461.         
  462.         try:
  463.             
  464.             try:
  465.                 res = apply(func, args)
  466.             except BdbQuit:
  467.                 pass
  468.  
  469.         finally:
  470.             self.quitting = 1
  471.             sys.settrace(None)
  472.  
  473.         return res
  474.  
  475.  
  476.  
  477. def set_trace():
  478.     Bdb().set_trace()
  479.  
  480.  
  481. class Breakpoint:
  482.     '''Breakpoint class
  483.  
  484.     Implements temporary breakpoints, ignore counts, disabling and
  485.     (re)-enabling, and conditionals.
  486.  
  487.     Breakpoints are indexed by number through bpbynumber and by
  488.     the file,line tuple using bplist.  The former points to a
  489.     single instance of class Breakpoint.  The latter points to a
  490.     list of such instances since there may be more than one
  491.     breakpoint per line.
  492.  
  493.     '''
  494.     next = 1
  495.     bplist = { }
  496.     bpbynumber = [
  497.         None]
  498.     
  499.     def __init__(self, file, line, temporary = 0, cond = None):
  500.         self.file = file
  501.         self.line = line
  502.         self.temporary = temporary
  503.         self.cond = cond
  504.         self.enabled = 1
  505.         self.ignore = 0
  506.         self.hits = 0
  507.         self.number = Breakpoint.next
  508.         Breakpoint.next = Breakpoint.next + 1
  509.         self.bpbynumber.append(self)
  510.         if self.bplist.has_key((file, line)):
  511.             self.bplist[(file, line)].append(self)
  512.         else:
  513.             self.bplist[(file, line)] = [
  514.                 self]
  515.  
  516.     
  517.     def deleteMe(self):
  518.         index = (self.file, self.line)
  519.         self.bpbynumber[self.number] = None
  520.         self.bplist[index].remove(self)
  521.         if not self.bplist[index]:
  522.             del self.bplist[index]
  523.         
  524.  
  525.     
  526.     def enable(self):
  527.         self.enabled = 1
  528.  
  529.     
  530.     def disable(self):
  531.         self.enabled = 0
  532.  
  533.     
  534.     def bpprint(self):
  535.         if self.temporary:
  536.             disp = 'del  '
  537.         else:
  538.             disp = 'keep '
  539.         if self.enabled:
  540.             disp = disp + 'yes'
  541.         else:
  542.             disp = disp + 'no '
  543.         print '%-4dbreakpoint    %s at %s:%d' % (self.number, disp, self.file, self.line)
  544.         if self.cond:
  545.             print '\tstop only if %s' % (self.cond,)
  546.         
  547.         if self.ignore:
  548.             print '\tignore next %d hits' % self.ignore
  549.         
  550.         if self.hits:
  551.             if self.hits > 1:
  552.                 ss = 's'
  553.             else:
  554.                 ss = ''
  555.             print '\tbreakpoint already hit %d time%s' % (self.hits, ss)
  556.         
  557.  
  558.  
  559.  
  560. def effective(file, line, frame):
  561.     '''Determine which breakpoint for this file:line is to be acted upon.
  562.  
  563.     Called only if we know there is a bpt at this
  564.     location.  Returns breakpoint that was triggered and a flag
  565.     that indicates if it is ok to delete a temporary bp.
  566.  
  567.     '''
  568.     possibles = Breakpoint.bplist[(file, line)]
  569.     for i in range(0, len(possibles)):
  570.         b = possibles[i]
  571.         if b.enabled == 0:
  572.             continue
  573.         
  574.         b.hits = b.hits + 1
  575.         if not (b.cond):
  576.             if b.ignore > 0:
  577.                 b.ignore = b.ignore - 1
  578.                 continue
  579.             else:
  580.                 return (b, 1)
  581.         else:
  582.             
  583.             try:
  584.                 val = eval(b.cond, frame.f_globals, frame.f_locals)
  585.                 if val:
  586.                     if b.ignore > 0:
  587.                         b.ignore = b.ignore - 1
  588.                     else:
  589.                         return (b, 1)
  590.             except:
  591.                 return (b, 0)
  592.  
  593.     
  594.     return (None, None)
  595.  
  596.  
  597. class Tdb(Bdb):
  598.     
  599.     def user_call(self, frame, args):
  600.         name = frame.f_code.co_name
  601.         if not name:
  602.             name = '???'
  603.         
  604.         print '+++ call', name, args
  605.  
  606.     
  607.     def user_line(self, frame):
  608.         import linecache
  609.         name = frame.f_code.co_name
  610.         if not name:
  611.             name = '???'
  612.         
  613.         fn = self.canonic(frame.f_code.co_filename)
  614.         line = linecache.getline(fn, frame.f_lineno)
  615.         print '+++', fn, frame.f_lineno, name, ':', line.strip()
  616.  
  617.     
  618.     def user_return(self, frame, retval):
  619.         print '+++ return', retval
  620.  
  621.     
  622.     def user_exception(self, frame, exc_stuff):
  623.         print '+++ exception', exc_stuff
  624.         self.set_continue()
  625.  
  626.  
  627.  
  628. def foo(n):
  629.     print 'foo(', n, ')'
  630.     x = bar(n * 10)
  631.     print 'bar returned', x
  632.  
  633.  
  634. def bar(a):
  635.     print 'bar(', a, ')'
  636.     return a / 2
  637.  
  638.  
  639. def test():
  640.     t = Tdb()
  641.     t.run('import bdb; bdb.foo(10)')
  642.  
  643.