diff options
author | Jason Madden <jamadden@gmail.com> | 2017-09-11 11:28:00 -0500 |
---|---|---|
committer | Jason Madden <jamadden@gmail.com> | 2017-09-11 11:28:00 -0500 |
commit | cc9f097936226845a89d879d49f38894dd032d03 (patch) | |
tree | 3643ca6bc8d5d22d2c8927e0cb3686c5698075cf /src/zope/exceptions/exceptionformatter.py | |
parent | d97f1b37d541554ad85e15dd824a84d3e3883f4c (diff) | |
download | zope-exceptions-issue1.tar.gz |
Fix non-ASCII supplement info under Python 2 and drop Py3.3.issue1
Fixes #1.
Fix the coverage environment using zope.testrunner (nose no longer
works, that same namespace path issue).
Also run the doctests on all supported versions. This requires
dropping Python 3.3 because sphinx needs 3.4+.
Diffstat (limited to 'src/zope/exceptions/exceptionformatter.py')
-rw-r--r-- | src/zope/exceptions/exceptionformatter.py | 42 |
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: |