"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "roundup/cgi/cgitb.py" between
roundup-1.6.1.tar.gz and roundup-2.0.0.tar.gz

About: Roundup is an highly customisable issue-tracking system with command-line, web and e-mail interfaces (written in Python).

cgitb.py  (roundup-1.6.1):cgitb.py  (roundup-2.0.0)
# #
# This module was written by Ka-Ping Yee, <ping@lfw.org>. # This module was written by Ka-Ping Yee, <ping@lfw.org>.
# #
"""Extended CGI traceback handler by Ka-Ping Yee, <ping@lfw.org>. """Extended CGI traceback handler by Ka-Ping Yee, <ping@lfw.org>.
""" """
from __future__ import print_function
__docformat__ = 'restructuredtext' __docformat__ = 'restructuredtext'
import sys, os, types, string, keyword, linecache, tokenize, inspect, cgi import sys, os, keyword, linecache, tokenize, inspect
import pydoc, traceback import pydoc, traceback
from roundup.cgi import templating, TranslationService from roundup.anypy.html import html_escape
from roundup.cgi import TranslationService
from roundup.anypy.strings import s2b
def get_translator(i18n=None): def get_translator(i18n=None):
"""Return message translation function (gettext) """Return message translation function (gettext)
Parameters: Parameters:
i18n - translation service, such as roundup.i18n module i18n - translation service, such as roundup.i18n module
or TranslationService object. or TranslationService object.
Return ``gettext`` attribute of the ``i18n`` object, if available Return ``gettext`` attribute of the ``i18n`` object, if available
(must be a message translation function with one argument). (must be a message translation function with one argument).
If ``gettext`` cannot be obtained from ``i18n``, take default If ``gettext`` cannot be obtained from ``i18n``, take default
TranslationService. TranslationService.
""" """
try: try:
return i18n.gettext return i18n.gettext
except: except AttributeError:
return TranslationService.get_translation().gettext return TranslationService.get_translation().gettext
def breaker(): def breaker():
return ('<body bgcolor="white">' + return ('<body bgcolor="white">' +
'<font color="white" size="-5"> > </font> ' + '<font color="white" size="-5"> > </font> ' +
'</table>' * 5) '</table>' * 5)
def niceDict(indent, dict): def niceDict(indent, dict):
l = [] l = []
for k in sorted(dict): for k in sorted(dict):
v = dict[k] v = dict[k]
l.append('<tr><td><strong>%s</strong></td><td>%s</td></tr>'%(k, l.append('<tr><td><strong>%s</strong></td><td>%s</td></tr>' % (k,
cgi.escape(repr(v)))) html_escape(repr(v))))
return '\n'.join(l) return '\n'.join(l)
def pt_html(context=5, i18n=None): def pt_html(context=5, i18n=None):
_ = get_translator(i18n) _ = get_translator(i18n)
esc = cgi.escape esc = html_escape
exc_info = [esc(str(value)) for value in sys.exc_info()[:2]] exc_info = [esc(str(value)) for value in sys.exc_info()[:2]]
l = [_('<h1>Templating Error</h1>\n' l = [_('<h1>Templating Error</h1>\n'
'<p><b>%(exc_type)s</b>: %(exc_value)s</p>\n' '<p><b>%(exc_type)s</b>: %(exc_value)s</p>\n'
'<p class="help">Debugging information follows</p>' '<p class="help">Debugging information follows</p>'
) % {'exc_type': exc_info[0], 'exc_value': exc_info[1]}, ) % {'exc_type': exc_info[0], 'exc_value': exc_info[1]},
'<ol>',] '<ol>', ]
from roundup.cgi.PageTemplates.Expressions import TraversalError from roundup.cgi.PageTemplates.Expressions import TraversalError
t = inspect.trace(context) t = inspect.trace(context)
t.reverse() t.reverse()
for frame, file, lnum, func, lines, index in t: for frame, file, lnum, func, lines, index in t:
args, varargs, varkw, locals = inspect.getargvalues(frame) args, varargs, varkw, locals = inspect.getargvalues(frame)
if '__traceback_info__' in locals: if '__traceback_info__' in locals:
ti = locals['__traceback_info__'] ti = locals['__traceback_info__']
if isinstance(ti, TraversalError): if isinstance(ti, TraversalError):
s = [] s = []
for name, info in ti.path: for name, info in ti.path:
s.append(_('<li>"%(name)s" (%(info)s)</li>') s.append(_('<li>"%(name)s" (%(info)s)</li>')
% {'name': name, 'info': esc(repr(info))}) % {'name': name, 'info': esc(repr(info))})
s = '\n'.join(s) s = '\n'.join(s)
l.append(_('<li>Looking for "%(name)s", ' l.append(_('<li>Looking for "%(name)s", '
'current path:<ol>%(path)s</ol></li>' 'current path:<ol>%(path)s</ol></li>'
) % {'name': ti.name, 'path': s}) ) % {'name': ti.name, 'path': s})
else: else:
l.append(_('<li>In %s</li>') % esc(str(ti))) l.append(_('<li>In %s</li>') % esc(str(ti)))
if '__traceback_supplement__' in locals: if '__traceback_supplement__' in locals:
ts = locals['__traceback_supplement__'] ts = locals['__traceback_supplement__']
if len(ts) == 2: if len(ts) == 2:
supp, context = ts supp, context = ts
s = _('A problem occurred in your template "%s".') \ s = _('A problem occurred in your template "%s".') \
% str(context.id) % str(context.id)
if context._v_errors: if context._v_errors:
s = s + '<br>' + '<br>'.join( s = s + '<br>' + '<br>'.join(
[esc(x) for x in context._v_errors]) [esc(x) for x in context._v_errors])
l.append('<li>%s</li>'%s) l.append('<li>%s</li>' % s)
elif len(ts) == 3: elif len(ts) == 3:
supp, context, info = ts supp, context, info = ts
l.append(_(''' l.append(_('''
<li>While evaluating the %(info)r expression on line %(line)d <li>While evaluating the %(info)r expression on line %(line)d
<table class="otherinfo" style="font-size: 90%%"> <table class="otherinfo" style="font-size: 90%%">
<tr><th colspan="2" class="header">Current variables:</th></tr> <tr><th colspan="2" class="header">Current variables:</th></tr>
%(globals)s %(globals)s
%(locals)s %(locals)s
</table></li> </table></li>
''') % { ''') % {
skipping to change at line 103 skipping to change at line 107
'line': context.position[0], 'line': context.position[0],
'globals': niceDict(' ', context.global_vars), 'globals': niceDict(' ', context.global_vars),
'locals': niceDict(' ', context.local_vars) 'locals': niceDict(' ', context.local_vars)
}) })
l.append(''' l.append('''
</ol> </ol>
<table style="font-size: 80%%; color: gray"> <table style="font-size: 80%%; color: gray">
<tr><th class="header" align="left">%s</th></tr> <tr><th class="header" align="left">%s</th></tr>
<tr><td><pre>%s</pre></td></tr> <tr><td><pre>%s</pre></td></tr>
</table>''' % (_('Full traceback:'), cgi.escape(''.join( </table>''' % (_('Full traceback:'), html_escape(''.join(
traceback.format_exception(*sys.exc_info()) traceback.format_exception(*sys.exc_info())
)))) ))))
l.append('<p>&nbsp;</p>') l.append('<p>&nbsp;</p>')
return '\n'.join(l) return '\n'.join(l)
def html(context=5, i18n=None): def html(context=5, i18n=None):
_ = get_translator(i18n) _ = get_translator(i18n)
etype, evalue = sys.exc_info()[0], sys.exc_info()[1] etype, evalue = sys.exc_info()[0], sys.exc_info()[1]
if type(etype) is type: if type(etype) is type:
etype = etype.__name__ etype = etype.__name__
pyver = 'Python ' + string.split(sys.version)[0] + '<br>' + sys.executable pyver = 'Python ' + sys.version.split()[0] + '<br>' + sys.executable
head = pydoc.html.heading( head = pydoc.html.heading(
_('<font size=+1><strong>%(exc_type)s</strong>: %(exc_value)s</font>') _('<font size=+1><strong>%(exc_type)s</strong>: %(exc_value)s</font>')
% {'exc_type': etype, 'exc_value': evalue}, % {'exc_type': etype, 'exc_value': evalue},
'#ffffff', '#777777', pyver) '#ffffff', '#777777', pyver)
head = head + (_('<p>A problem occurred while running a Python script. ' head = head + (_('<p>A problem occurred while running a Python script. '
'Here is the sequence of function calls leading up to ' 'Here is the sequence of function calls leading up to '
'the error, with the most recent (innermost) call first. ' 'the error, with the most recent (innermost) call first. '
'The exception attributes are:')) 'The exception attributes are:'))
indent = '<tt><small>%s</small>&nbsp;</tt>' % ('&nbsp;' * 5) indent = '<tt><small>%s</small>&nbsp;</tt>' % ('&nbsp;' * 5)
traceback = [] traceback = []
for frame, file, lnum, func, lines, index in inspect.trace(context): for frame, file, lnum, func, lines, index in inspect.trace(context):
if file is None: if file is None:
link = _("&lt;file is None - probably inside <tt>eval</tt> " link = _("&lt;file is None - probably inside <tt>eval</tt> "
"or <tt>exec</tt>&gt;") "or <tt>exec</tt>&gt;")
else: else:
file = os.path.abspath(file) file = os.path.abspath(file)
link = '<a href="file:%s">%s</a>' % (file, pydoc.html.escape(file)) link = '<a href="file:%s">%s</a>' % (file, pydoc.html.escape(file))
args, varargs, varkw, locals = inspect.getargvalues(frame) args, varargs, varkw, locals = inspect.getargvalues(frame)
if func == '?': if func == '?':
call = '' call = ''
else: else:
call = _('in <strong>%s</strong>') % func + inspect.formatargvalues( call = _('in <strong>%s</strong>') % \
args, varargs, varkw, locals, func + inspect.formatargvalues(
formatvalue=lambda value: '=' + pydoc.html.repr(value)) args, varargs, varkw, locals,
formatvalue=lambda value: '=' + pydoc.html.repr(value))
level = ''' level = '''
<table width="100%%" bgcolor="#dddddd" cellspacing=0 cellpadding=2 border=0> <table width="100%%" bgcolor="#dddddd" cellspacing=0 cellpadding=2 border=0>
<tr><td>%s %s</td></tr></table>''' % (link, call) <tr><td>%s %s</td></tr></table>''' % (link, call)
if index is None or file is None: if index is None or file is None:
traceback.append('<p>' + level) traceback.append('<p>' + level)
continue continue
# do a file inspection # do a file inspection
names = [] names = []
def tokeneater(type, token, start, end, line, names=names): def tokeneater(type, token, start, end, line, names=names):
if type == tokenize.NAME and token not in keyword.kwlist: if type == tokenize.NAME and token not in keyword.kwlist:
if token not in names: if token not in names:
names.append(token) names.append(token)
if type == tokenize.NEWLINE: raise IndexError if type == tokenize.NEWLINE: raise IndexError
def linereader(file=file, lnum=[lnum]): def linereader(file=file, lnum=[lnum]):
line = linecache.getline(file, lnum[0]) line = s2b(linecache.getline(file, lnum[0]))
lnum[0] = lnum[0] + 1 lnum[0] = lnum[0] + 1
return line return line
# The interface that is tokenize.tokenize in Python 3 is
# called tokenize.generate_tokens in Python 2. However,
# Python 2 has tokenize.tokenize with a different interface,
# and Python 3 has an undocumented generate_tokens function,
# also with a different interface, so a version check is
# needed instead of checking for which functions exist.
if sys.version_info[0] > 2:
tokenize_fn = tokenize.tokenize
else:
tokenize_fn = tokenize.generate_tokens
try: try:
tokenize.tokenize(linereader, tokeneater) for t in tokenize_fn(linereader):
tokeneater(*t)
except IndexError: except IndexError:
pass pass
lvals = [] lvals = []
for name in names: for name in names:
if name in frame.f_code.co_varnames: if name in frame.f_code.co_varnames:
if name in locals: if name in locals:
value = pydoc.html.repr(locals[name]) value = pydoc.html.repr(locals[name])
else: else:
value = _('<em>undefined</em>') value = _('<em>undefined</em>')
name = '<strong>%s</strong>' % name name = '<strong>%s</strong>' % name
else: else:
if name in frame.f_globals: if name in frame.f_globals:
value = pydoc.html.repr(frame.f_globals[name]) value = pydoc.html.repr(frame.f_globals[name])
else: else:
value = _('<em>undefined</em>') value = _('<em>undefined</em>')
name = '<em>global</em> <strong>%s</strong>' % name name = '<em>global</em> <strong>%s</strong>' % name
lvals.append('%s&nbsp;= %s'%(name, value)) lvals.append('%s&nbsp;= %s' % (name, value))
if lvals: if lvals:
lvals = string.join(lvals, ', ') lvals = ', '.join(lvals)
lvals = indent + '<small><font color="#909090">%s'\ lvals = indent + '<small><font color="#909090">%s'\
'</font></small><br>'%lvals '</font></small><br>' % lvals
else: else:
lvals = '' lvals = ''
excerpt = [] excerpt = []
i = lnum - index i = lnum - index
for line in lines: for line in lines:
number = '&nbsp;' * (5-len(str(i))) + str(i) number = '&nbsp;' * (5-len(str(i))) + str(i)
number = '<small><font color="#909090">%s</font></small>' % number number = '<small><font color="#909090">%s</font></small>' % number
line = '<tt>%s&nbsp;%s</tt>' % (number, pydoc.html.preformat(line)) line = '<tt>%s&nbsp;%s</tt>' % (number, pydoc.html.preformat(line))
if i == lnum: if i == lnum:
line = ''' line = '''
<table width="100%%" bgcolor="white" cellspacing=0 cellpadding=0 border=0> <table width="100%%" bgcolor="white" cellspacing=0 cellpadding=0 border=0>
<tr><td>%s</td></tr></table>''' % line <tr><td>%s</td></tr></table>''' % line
excerpt.append('\n' + line) excerpt.append('\n' + line)
if i == lnum: if i == lnum:
excerpt.append(lvals) excerpt.append(lvals)
i = i + 1 i = i + 1
traceback.append('<p>' + level + string.join(excerpt, '\n')) traceback.append('<p>' + level + '\n'.join(excerpt))
traceback.reverse() traceback.reverse()
exception = '<p><strong>%s</strong>: %s' % (str(etype), str(evalue)) exception = '<p><strong>%s</strong>: %s' % (str(etype), str(evalue))
attribs = [] attribs = []
if type(evalue) is types.InstanceType: for name in dir(evalue):
for name in dir(evalue): value = pydoc.html.repr(getattr(evalue, name))
value = pydoc.html.repr(getattr(evalue, name)) attribs.append('<br>%s%s&nbsp;= %s' % (indent, name, value))
attribs.append('<br>%s%s&nbsp;= %s' % (indent, name, value))
return head + string.join(attribs) + string.join(traceback) + '<p>&nbsp;</p> ' return head + ' '.join(attribs) + ' '.join(traceback) + '<p>&nbsp;</p>'
def handler(): def handler():
print breaker() print(breaker())
print html() print(html())
# vim: set filetype=python ts=4 sw=4 et si : # vim: set filetype=python ts=4 sw=4 et si :
 End of changes. 27 change blocks. 
36 lines changed or deleted 53 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)