home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pytho152.zip / emx / lib / python1.5 / traceback.py < prev    next >
Text File  |  2000-08-10  |  5KB  |  208 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.     else:
  91.         list = []
  92.     list = list + format_exception_only(etype, value)
  93.     return list
  94.  
  95. def format_exception_only(etype, value):
  96.     list = []
  97.     if type(etype) == types.ClassType:
  98.         stype = etype.__name__
  99.     else:
  100.         stype = etype
  101.     if value is None:
  102.         list.append(str(stype) + '\n')
  103.     else:
  104.         if etype is SyntaxError:
  105.             try:
  106.                 msg, (filename, lineno, offset, line) = value
  107.             except:
  108.                 pass
  109.             else:
  110.                 if not filename: filename = "<string>"
  111.                 list.append('  File "%s", line %d\n' %
  112.                         (filename, lineno))
  113.                 i = 0
  114.                 while i < len(line) and \
  115.                       line[i] in string.whitespace:
  116.                     i = i+1
  117.                 list.append('    %s\n' % string.strip(line))
  118.                 s = '    '
  119.                 for c in line[i:offset-1]:
  120.                     if c in string.whitespace:
  121.                         s = s + c
  122.                     else:
  123.                         s = s + ' '
  124.                 list.append('%s^\n' % s)
  125.                 value = msg
  126.         list.append('%s: %s\n' % (str(stype), str(value)))
  127.     return list
  128.  
  129.  
  130. def print_exc(limit=None, file=None):
  131.     if not file:
  132.         file = sys.stderr
  133.     try:
  134.         etype, value, tb = sys.exc_info()
  135.         print_exception(etype, value, tb, limit, file)
  136.     finally:
  137.         etype = value = tb = None
  138.  
  139. def print_last(limit=None, file=None):
  140.     if not file:
  141.         file = sys.stderr
  142.     print_exception(sys.last_type, sys.last_value, sys.last_traceback,
  143.             limit, file)
  144.  
  145.  
  146. def print_stack(f=None, limit=None, file=None):
  147.     if f is None:
  148.         try:
  149.             raise ZeroDivisionError
  150.         except ZeroDivisionError:
  151.             f = sys.exc_info()[2].tb_frame.f_back
  152.     print_list(extract_stack(f, limit), file)
  153.  
  154. def format_stack(f=None, limit=None):
  155.     if f is None:
  156.         try:
  157.             raise ZeroDivisionError
  158.         except ZeroDivisionError:
  159.             f = sys.exc_info()[2].tb_frame.f_back
  160.     return format_list(extract_stack(f, limit))
  161.  
  162. def extract_stack(f=None, limit = None):
  163.     if f is None:
  164.         try:
  165.             raise ZeroDivisionError
  166.         except ZeroDivisionError:
  167.             f = sys.exc_info()[2].tb_frame.f_back
  168.     if limit is None:
  169.         if hasattr(sys, 'tracebacklimit'):
  170.             limit = sys.tracebacklimit
  171.     list = []
  172.     n = 0
  173.     while f is not None and (limit is None or n < limit):
  174.         lineno = f.f_lineno    # XXX Too bad if -O is used
  175.         co = f.f_code
  176.         filename = co.co_filename
  177.         name = co.co_name
  178.         line = linecache.getline(filename, lineno)
  179.         if line: line = string.strip(line)
  180.         else: line = None
  181.         list.append((filename, lineno, name, line))
  182.         f = f.f_back
  183.         n = n+1
  184.     list.reverse()
  185.     return list
  186.  
  187. # Calculate the correct line number of the traceback given in tb (even
  188. # with -O on).
  189. # Coded by Marc-Andre Lemburg from the example of PyCode_Addr2Line()
  190. # in compile.c.
  191. # Revised version by Jim Hugunin to work with JPython too.
  192.  
  193. def tb_lineno(tb):
  194.     c = tb.tb_frame.f_code
  195.     if not hasattr(c, 'co_lnotab'):
  196.         return tb.tb_lineno
  197.  
  198.     tab = c.co_lnotab
  199.     line = c.co_firstlineno
  200.     stopat = tb.tb_lasti
  201.     addr = 0
  202.     for i in range(0, len(tab), 2):
  203.         addr = addr + ord(tab[i])
  204.         if addr > stopat:
  205.             break
  206.         line = line + ord(tab[i+1])
  207.     return line
  208.