diff --git a/Doc/lib/libtraceback.tex b/Doc/lib/libtraceback.tex index 9778c838342..eee898e14fc 100644 --- a/Doc/lib/libtraceback.tex +++ b/Doc/lib/libtraceback.tex @@ -48,6 +48,11 @@ information in a thread-safe way instead of using the deprecated variables.) \end{funcdesc} +\begin{funcdesc}{format_exc}{\optional{limit\optional{, file}}} +This is like \code{print_exc(\var{limit})} but returns a string +instead of printing to a file. +\end{funcdesc} + \begin{funcdesc}{print_last}{\optional{limit\optional{, file}}} This is a shorthand for \code{print_exception(sys.last_type, sys.last_value, sys.last_traceback, \var{limit}, \var{file})}. diff --git a/Lib/threading.py b/Lib/threading.py index 81a26933494..c5d5af38268 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -8,9 +8,8 @@ except ImportError: del _sys.modules[__name__] raise -from StringIO import StringIO as _StringIO from time import time as _time, sleep as _sleep -from traceback import print_exc as _print_exc +from traceback import format_exc as _format_exc # Rename some stuff so "from threading import *" is safe __all__ = ['activeCount', 'Condition', 'currentThread', 'enumerate', 'Event', @@ -440,10 +439,8 @@ class Thread(_Verbose): except: if __debug__: self._note("%s.__bootstrap(): unhandled exception", self) - s = _StringIO() - _print_exc(file=s) _sys.stderr.write("Exception in thread %s:\n%s\n" % - (self.getName(), s.getvalue())) + (self.getName(), _format_exc())) else: if __debug__: self._note("%s.__bootstrap(): normal return", self) diff --git a/Lib/traceback.py b/Lib/traceback.py index 4910a37cb06..d99009bf28e 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -6,8 +6,8 @@ import types __all__ = ['extract_stack', 'extract_tb', 'format_exception', 'format_exception_only', 'format_list', 'format_stack', - 'format_tb', 'print_exc', 'print_exception', 'print_last', - 'print_stack', 'print_tb', 'tb_lineno'] + 'format_tb', 'print_exc', 'format_exc', 'print_exception', + 'print_last', 'print_stack', 'print_tb', 'tb_lineno'] def _print(file, str='', terminator='\n'): file.write(str+terminator) @@ -211,6 +211,16 @@ def print_exc(limit=None, file=None): finally: etype = value = tb = None + +def format_exc(limit=None): + """Like print_exc() but return a string.""" + try: + etype, value, tb = sys.exc_info() + return ''.join(format_exception(etype, value, tb, limit)) + finally: + etype = value = tb = None + + def print_last(limit=None, file=None): """This is a shorthand for 'print_exception(sys.last_type, sys.last_value, sys.last_traceback, limit, file)'.""" diff --git a/Misc/NEWS b/Misc/NEWS index 1371e6c8171..c47ed158afc 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -101,6 +101,9 @@ Extension modules Library ------- +- traceback.format_exc has been added (similar to print_exc but it returns + a string). + - xmlrpclib.MultiCall has been added. - poplib.POP3_SSL has been added.