[pypy-svn] r75238 - in pypy/trunk/pypy/module/sys: . test
arigo at codespeak.net
arigo at codespeak.net
Wed Jun 9 18:24:27 CEST 2010
Author: arigo
Date: Wed Jun 9 18:24:25 2010
New Revision: 75238
Modified:
pypy/trunk/pypy/module/sys/app.py
pypy/trunk/pypy/module/sys/test/test_sysmodule.py
Log:
Try to be really careful in sys.excepthook().
Modified: pypy/trunk/pypy/module/sys/app.py
==============================================================================
--- pypy/trunk/pypy/module/sys/app.py (original)
+++ pypy/trunk/pypy/module/sys/app.py Wed Jun 9 18:24:25 2010
@@ -7,8 +7,35 @@
def excepthook(exctype, value, traceback):
"""Handle an exception by displaying it with a traceback on sys.stderr."""
- from traceback import print_exception
- print_exception(exctype, value, traceback)
+ try:
+ from traceback import print_exception
+ print_exception(exctype, value, traceback)
+ except:
+ if not excepthook_failsafe(exctype, value):
+ raise
+
+def excepthook_failsafe(exctype, value):
+ # This version carefully tries to handle all bad cases (e.g. an
+ # ImportError looking for traceback.py), but may still raise.
+ # If it does, we get "Error calling sys.excepthook" from app_main.py.
+ try:
+ # first try to print the exception's class name
+ stderr = sys.stderr
+ stderr.write(getattr(exctype, '__name__', exctype))
+ # then attempt to get the str() of the exception
+ try:
+ s = str(value)
+ except:
+ s = '<failure of str() on the exception instance>'
+ # then print it, and don't worry too much about the extra space
+ # between the exception class and the ':'
+ if s:
+ stderr.write(': %s\n' % (s,))
+ else:
+ stderr.write('\n')
+ return True # successfully printed at least the class and value
+ except:
+ return False # got an exception again... ignore, report the original
def exit(exitcode=0):
"""Exit the interpreter by raising SystemExit(exitcode).
Modified: pypy/trunk/pypy/module/sys/test/test_sysmodule.py
==============================================================================
--- pypy/trunk/pypy/module/sys/test/test_sysmodule.py (original)
+++ pypy/trunk/pypy/module/sys/test/test_sysmodule.py Wed Jun 9 18:24:25 2010
@@ -177,6 +177,26 @@
sys.stderr = savestderr
assert err.getvalue().endswith("ValueError: 42\n")
+ def test_excepthook_failsafe_path(self):
+ import traceback
+ original_print_exception = traceback.print_exception
+ import cStringIO
+ savestderr = sys.stderr
+ err = cStringIO.StringIO()
+ sys.stderr = err
+ try:
+ traceback.print_exception = "foo"
+ eh = sys.__excepthook__
+ try:
+ raise ValueError(42)
+ except ValueError, exc:
+ eh(*sys.exc_info())
+ finally:
+ traceback.print_exception = original_print_exception
+ sys.stderr = savestderr
+
+ assert err.getvalue() == "ValueError: 42\n"
+
# FIXME: testing the code for a lost or replaced excepthook in
# Python/pythonrun.c::PyErr_PrintEx() is tricky.
More information about the Pypy-commit
mailing list