# # This module was written by Ka-Ping Yee, . # """Extended CGI traceback handler by Ka-Ping Yee, . """ __docformat__ = 'restructuredtext' import sys, os, types, string, keyword, linecache, tokenize, inspect, cgi import pydoc, traceback from roundup.cgi import templating, TranslationService def get_translator(i18n=None): """Return message translation function (gettext) Parameters: i18n - translation service, such as roundup.i18n module or TranslationService object. Return ``gettext`` attribute of the ``i18n`` object, if available (must be a message translation function with one argument). If ``gettext`` cannot be obtained from ``i18n``, take default TranslationService. """ try: return i18n.gettext except: return TranslationService.get_translation().gettext def breaker(): return ('' + ' > ' + '' * 5) def niceDict(indent, dict): l = [] for k in sorted(dict): v = dict[k] l.append('%s%s'%(k, cgi.escape(repr(v)))) return '\n'.join(l) def pt_html(context=5, i18n=None): _ = get_translator(i18n) esc = cgi.escape exc_info = [esc(str(value)) for value in sys.exc_info()[:2]] l = [_('

Templating Error

\n' '

%(exc_type)s: %(exc_value)s

\n' '

Debugging information follows

' ) % {'exc_type': exc_info[0], 'exc_value': exc_info[1]}, '
    ',] from roundup.cgi.PageTemplates.Expressions import TraversalError t = inspect.trace(context) t.reverse() for frame, file, lnum, func, lines, index in t: args, varargs, varkw, locals = inspect.getargvalues(frame) if '__traceback_info__' in locals: ti = locals['__traceback_info__'] if isinstance(ti, TraversalError): s = [] for name, info in ti.path: s.append(_('
  1. "%(name)s" (%(info)s)
  2. ') % {'name': name, 'info': esc(repr(info))}) s = '\n'.join(s) l.append(_('
  3. Looking for "%(name)s", ' 'current path:
      %(path)s
  4. ' ) % {'name': ti.name, 'path': s}) else: l.append(_('
  5. In %s
  6. ') % esc(str(ti))) if '__traceback_supplement__' in locals: ts = locals['__traceback_supplement__'] if len(ts) == 2: supp, context = ts s = _('A problem occurred in your template "%s".') \ % str(context.id) if context._v_errors: s = s + '
    ' + '
    '.join( [esc(x) for x in context._v_errors]) l.append('
  7. %s
  8. '%s) elif len(ts) == 3: supp, context, info = ts l.append(_('''
  9. While evaluating the %(info)r expression on line %(line)d %(globals)s %(locals)s
    Current variables:
  10. ''') % { 'info': info, 'line': context.position[0], 'globals': niceDict(' ', context.global_vars), 'locals': niceDict(' ', context.local_vars) }) l.append('''
%s
%s
''' % (_('Full traceback:'), cgi.escape(''.join( traceback.format_exception(*sys.exc_info()) )))) l.append('

 

') return '\n'.join(l) def html(context=5, i18n=None): _ = get_translator(i18n) etype, evalue = sys.exc_info()[0], sys.exc_info()[1] if type(etype) is type: etype = etype.__name__ pyver = 'Python ' + string.split(sys.version)[0] + '
' + sys.executable head = pydoc.html.heading( _('%(exc_type)s: %(exc_value)s') % {'exc_type': etype, 'exc_value': evalue}, '#ffffff', '#777777', pyver) head = head + (_('

A problem occurred while running a Python script. ' 'Here is the sequence of function calls leading up to ' 'the error, with the most recent (innermost) call first. ' 'The exception attributes are:')) indent = '%s ' % (' ' * 5) traceback = [] for frame, file, lnum, func, lines, index in inspect.trace(context): if file is None: link = _("<file is None - probably inside eval " "or exec>") else: file = os.path.abspath(file) link = '%s' % (file, pydoc.html.escape(file)) args, varargs, varkw, locals = inspect.getargvalues(frame) if func == '?': call = '' else: call = _('in %s') % func + inspect.formatargvalues( args, varargs, varkw, locals, formatvalue=lambda value: '=' + pydoc.html.repr(value)) level = '''
%s %s
''' % (link, call) if index is None or file is None: traceback.append('

' + level) continue # do a file inspection names = [] def tokeneater(type, token, start, end, line, names=names): if type == tokenize.NAME and token not in keyword.kwlist: if token not in names: names.append(token) if type == tokenize.NEWLINE: raise IndexError def linereader(file=file, lnum=[lnum]): line = linecache.getline(file, lnum[0]) lnum[0] = lnum[0] + 1 return line try: tokenize.tokenize(linereader, tokeneater) except IndexError: pass lvals = [] for name in names: if name in frame.f_code.co_varnames: if name in locals: value = pydoc.html.repr(locals[name]) else: value = _('undefined') name = '%s' % name else: if name in frame.f_globals: value = pydoc.html.repr(frame.f_globals[name]) else: value = _('undefined') name = 'global %s' % name lvals.append('%s = %s'%(name, value)) if lvals: lvals = string.join(lvals, ', ') lvals = indent + '%s'\ '
'%lvals else: lvals = '' excerpt = [] i = lnum - index for line in lines: number = ' ' * (5-len(str(i))) + str(i) number = '%s' % number line = '%s %s' % (number, pydoc.html.preformat(line)) if i == lnum: line = '''
%s
''' % line excerpt.append('\n' + line) if i == lnum: excerpt.append(lvals) i = i + 1 traceback.append('

' + level + string.join(excerpt, '\n')) traceback.reverse() exception = '

%s: %s' % (str(etype), str(evalue)) attribs = [] if type(evalue) is types.InstanceType: for name in dir(evalue): value = pydoc.html.repr(getattr(evalue, name)) attribs.append('
%s%s = %s' % (indent, name, value)) return head + string.join(attribs) + string.join(traceback) + '

 

' def handler(): print breaker() print html() # vim: set filetype=python ts=4 sw=4 et si :