home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pyos2bin.zip / Lib / traceback.py < prev    next >
Text File  |  1997-09-26  |  5KB  |  202 lines

  1. # Format and print Python stack traces
  2.  
  3. import linecache
  4. import string
  5. import sys
  6. import types
  7.  
  8. def _print(file, str='', terminator='\n'):
  9.     file.write(str+terminator)
  10.  
  11.  
  12. def print_list(extracted_list, file=None):
  13.     if not file:
  14.         file = sys.stderr
  15.     for filename, lineno, name, line in extracted_list:
  16.         _print(file,
  17.                '  File "%s", line %d, in %s' % (filename,lineno,name))
  18.         if line:
  19.             _print(file, '    %s' % string.strip(line))
  20.  
  21. def format_list(extracted_list):
  22.     list = []
  23.     for filename, lineno, name, line in extracted_list:
  24.         item = '  File "%s", line %d, in %s\n' % (filename,lineno,name)
  25.         if line:
  26.             item = item + '    %s\n' % string.strip(line)
  27.         list.append(item)
  28.     return list
  29.     
  30.  
  31. def print_tb(tb, limit=None, file=None):
  32.     if not file:
  33.         file = sys.stderr
  34.     if limit is None:
  35.         if hasattr(sys, 'tracebacklimit'):
  36.             limit = sys.tracebacklimit
  37.     n = 0
  38.     while tb is not None and (limit is None or n < limit):
  39.         f = tb.tb_frame
  40.         lineno = tb_lineno(tb)
  41.         co = f.f_code
  42.         filename = co.co_filename
  43.         name = co.co_name
  44.         _print(file,
  45.                '  File "%s", line %d, in %s' % (filename,lineno,name))
  46.         line = linecache.getline(filename, lineno)
  47.         if line: _print(file, '    ' + string.strip(line))
  48.         tb = tb.tb_next
  49.         n = n+1
  50.  
  51. def format_tb(tb, limit = None):
  52.     return format_list(extract_tb(tb, limit))
  53.  
  54. def extract_tb(tb, limit = None):
  55.     if limit is None:
  56.         if hasattr(sys, 'tracebacklimit'):
  57.             limit = sys.tracebacklimit
  58.     list = []
  59.     n = 0
  60.     while tb is not None and (limit is None or n < limit):
  61.         f = tb.tb_frame
  62.         lineno = tb_lineno(tb)
  63.         co = f.f_code
  64.         filename = co.co_filename
  65.         name = co.co_name
  66.         line = linecache.getline(filename, lineno)
  67.         if line: line = string.strip(line)
  68.         else: line = None
  69.         list.append((filename, lineno, name, line))
  70.         tb = tb.tb_next
  71.         n = n+1
  72.     return list
  73.  
  74.  
  75. def print_exception(etype, value, tb, limit=None, file=None):
  76.     if not file:
  77.         file = sys.stderr
  78.     if tb:
  79.         _print(file, 'Traceback (innermost last):')
  80.         print_tb(tb, limit, file)
  81.     lines = format_exception_only(etype, value)
  82.     for line in lines[:-1]:
  83.         _print(file, line, ' ')
  84.     _print(file, lines[-1], '')
  85.  
  86. def format_exception(etype, value, tb, limit = None):
  87.     if tb:
  88.         list = ['Traceback (innermost last):\n']
  89.         list = list + format_tb(tb, limit)
  90.     list = list + format_exception_only(etype, value)
  91.     return list
  92.  
  93. def format_exception_only(etype, value):
  94.     list = []
  95.     if type(etype) == types.ClassType:
  96.         stype = etype.__name__
  97.     else:
  98.         stype = etype
  99.     if value is None:
  100.         list.append(str(stype) + '\n')
  101.     else:
  102.         if etype is SyntaxError:
  103.             try:
  104.                 msg, (filename, lineno, offset, line) = value
  105.             except:
  106.                 pass
  107.             else:
  108.                 if not filename: filename = "<string>"
  109.                 list.append('  File "%s", line %d\n' %
  110.                         (filename, lineno))
  111.                 i = 0
  112.                 while i < len(line) and \
  113.                       line[i] in string.whitespace:
  114.                     i = i+1
  115.                 list.append('    %s\n' % string.strip(line))
  116.                 s = '    '
  117.                 for c in line[i:offset-1]:
  118.                     if c in string.whitespace:
  119.                         s = s + c
  120.                     else:
  121.                         s = s + ' '
  122.                 list.append('%s^\n' % s)
  123.                 value = msg
  124.         list.append('%s: %s\n' % (str(stype), str(value)))
  125.     return list
  126.  
  127.  
  128. def print_exc(limit=None, file=None):
  129.     if not file:
  130.         file = sys.stderr
  131.     try:
  132.         etype, value, tb = sys.exc_info()
  133.         print_exception(etype, value, tb, limit, file)
  134.     finally:
  135.         etype = value = tb = None
  136.  
  137. def print_last(limit=None, file=None):
  138.     if not file:
  139.         file = sys.stderr
  140.     print_exception(sys.last_type, sys.last_value, sys.last_traceback,
  141.             limit, file)
  142.  
  143.  
  144. def print_stack(f=None, limit=None, file=None):
  145.     if f is None:
  146.         try:
  147.             raise ZeroDivisionError
  148.         except ZeroDivisionError:
  149.             f = sys.exc_info()[2].tb_frame.f_back
  150.     print_list(extract_stack(f, limit), file)
  151.  
  152. def format_stack(f=None, limit=None):
  153.     if f is None:
  154.         try:
  155.             raise ZeroDivisionError
  156.         except ZeroDivisionError:
  157.             f = sys.exc_info()[2].tb_frame.f_back
  158.     return format_list(extract_stack(f, limit))
  159.  
  160. def extract_stack(f=None, limit = None):
  161.     if f is None:
  162.         try:
  163.             raise ZeroDivisionError
  164.         except ZeroDivisionError:
  165.             f = sys.exc_info()[2].tb_frame.f_back
  166.     if limit is None:
  167.         if hasattr(sys, 'tracebacklimit'):
  168.             limit = sys.tracebacklimit
  169.     list = []
  170.     n = 0
  171.     while f is not None and (limit is None or n < limit):
  172.         lineno = f.f_lineno    # XXX Too bad if -O is used
  173.         co = f.f_code
  174.         filename = co.co_filename
  175.         name = co.co_name
  176.         line = linecache.getline(filename, lineno)
  177.         if line: line = string.strip(line)
  178.         else: line = None
  179.         list.append((filename, lineno, name, line))
  180.         f = f.f_back
  181.         n = n+1
  182.     list.reverse()
  183.     return list
  184.  
  185. # Calculate the correct line number of the traceback given in tb (even
  186. # with -O on).
  187. # Coded by Marc-Andre Lemburg from the example of PyCode_Addr2Line()
  188. # in compile.c.
  189.  
  190. def tb_lineno(tb):
  191.     c = tb.tb_frame.f_code
  192.     tab = c.co_lnotab
  193.     line = c.co_firstlineno
  194.     stopat = tb.tb_lasti
  195.     addr = 0
  196.     for i in range(0, len(tab), 2):
  197.         addr = addr + ord(tab[i])
  198.         if addr > stopat:
  199.             break
  200.         line = line + ord(tab[i+1])
  201.     return line
  202.