summaryrefslogtreecommitdiff
path: root/src/zope/exceptions/exceptionformatter.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/zope/exceptions/exceptionformatter.py')
-rw-r--r--src/zope/exceptions/exceptionformatter.py42
1 files changed, 30 insertions, 12 deletions
diff --git a/src/zope/exceptions/exceptionformatter.py b/src/zope/exceptions/exceptionformatter.py
index fabea9f..47e0f41 100644
--- a/src/zope/exceptions/exceptionformatter.py
+++ b/src/zope/exceptions/exceptionformatter.py
@@ -46,7 +46,12 @@ class TextExceptionFormatter(object):
return limit
def formatSupplementLine(self, line):
- return ' - %s' % line
+ result = ' - %s' % line
+ if not isinstance(result, str):
+ # Must be an Python 2, and must be a unicode `line`
+ # and we upconverted the result to a unicode
+ result = result.encode('utf-8')
+ return result
def formatSourceURL(self, url):
return [self.formatSupplementLine(url)]
@@ -110,13 +115,13 @@ class TextExceptionFormatter(object):
co = f.f_code
filename = co.co_filename
name = co.co_name
- locals = f.f_locals # XXX shadowing normal builtins deliberately?
- globals = f.f_globals # XXX shadowing normal builtins deliberately?
+ f_locals = f.f_locals
+ f_globals = f.f_globals
if self.with_filenames:
s = ' File "%s", line %d' % (filename, lineno)
else:
- modname = globals.get('__name__', filename)
+ modname = f_globals.get('__name__', filename)
s = ' Module %s, line %d' % (modname, lineno)
s = s + ', in %s' % name
@@ -130,13 +135,13 @@ class TextExceptionFormatter(object):
result.append(" " + self.escape(line.strip()))
# Output a traceback supplement, if any.
- if '__traceback_supplement__' in locals:
+ if '__traceback_supplement__' in f_locals:
# Use the supplement defined in the function.
- tbs = locals['__traceback_supplement__']
- elif '__traceback_supplement__' in globals:
+ tbs = f_locals['__traceback_supplement__']
+ elif '__traceback_supplement__' in f_globals:
# Use the supplement defined in the module.
# This is used by Scripts (Python).
- tbs = globals['__traceback_supplement__']
+ tbs = f_globals['__traceback_supplement__']
else:
tbs = None
if tbs is not None:
@@ -151,7 +156,7 @@ class TextExceptionFormatter(object):
# else just swallow the exception.
try:
- tbi = locals.get('__traceback_info__', None)
+ tbi = f_locals.get('__traceback_info__', None)
if tbi is not None:
result.append(self.formatTracebackInfo(tbi))
except: #pragma: no cover
@@ -240,13 +245,23 @@ class HTMLExceptionFormatter(TextExceptionFormatter):
line_sep = '<br />\r\n'
def escape(self, s):
+ if not isinstance(s, str):
+ try:
+ s = str(s)
+ except UnicodeError:
+ if hasattr(s, 'encode'):
+ # We probably got a unicode string on
+ # Python 2.
+ s = s.encode('utf-8')
+ else: # pragma: no cover
+ raise
return escape(s, quote=False)
def getPrefix(self):
return '<p>Traceback (most recent call last):</p>\r\n<ul>'
def formatSupplementLine(self, line):
- return '<b>%s</b>' % self.escape(str(line))
+ return '<b>%s</b>' % self.escape(line)
def formatSupplementInfo(self, info):
info = self.escape(info)
@@ -255,7 +270,7 @@ class HTMLExceptionFormatter(TextExceptionFormatter):
return info
def formatTracebackInfo(self, tbi):
- s = self.escape(str(tbi))
+ s = self.escape(tbi)
s = s.replace('\n', self.line_sep)
return '__traceback_info__: %s' % (s, )
@@ -275,6 +290,9 @@ def format_exception(t, v, tb, limit=None, as_html=False,
Similar to 'traceback.format_exception', but adds supplemental
information to the traceback and accepts two options, 'as_html'
and 'with_filenames'.
+
+ The result is a list of native strings; on Python 2 they are UTF-8
+ encoded if need be.
"""
if as_html:
fmt = HTMLExceptionFormatter(limit, with_filenames)
@@ -291,7 +309,7 @@ def print_exception(t, v, tb, limit=None, file=None, as_html=False,
information to the traceback and accepts two options, 'as_html'
and 'with_filenames'.
"""
- if file is None: #pragma: no cover
+ if file is None: # pragma: no cover
file = sys.stderr
lines = format_exception(t, v, tb, limit, as_html, with_filenames)
for line in lines: