diff -r 245d9679cd5b Doc/library/code.rst --- a/Doc/library/code.rst Mon Sep 29 23:02:56 2014 -0400 +++ b/Doc/library/code.rst Tue Sep 30 14:25:13 2014 +0300 @@ -117,6 +117,10 @@ .. versionchanged:: 3.5 The full chained traceback is displayed instead of just the primary traceback. + .. versionchanged:: 3.5 The last traceback is passed to + :meth:`sys.excepthook`, if a custom excepthook was used. + Previously, it received ``None``. + .. method:: InteractiveInterpreter.write(data) diff -r 245d9679cd5b Lib/code.py --- a/Lib/code.py Mon Sep 29 23:02:56 2014 -0400 +++ b/Lib/code.py Tue Sep 30 14:25:13 2014 +0300 @@ -165,7 +165,7 @@ else: # If someone has set sys.excepthook, we let that take precedence # over self.write - sys.excepthook(type, value, last_tb) + sys.excepthook(type, value, sys.last_traceback) def write(self, data): """Write a string. diff -r 245d9679cd5b Lib/test/test_code_module.py --- a/Lib/test/test_code_module.py Mon Sep 29 23:02:56 2014 -0400 +++ b/Lib/test/test_code_module.py Tue Sep 30 14:25:13 2014 +0300 @@ -4,6 +4,7 @@ from textwrap import dedent from contextlib import ExitStack from unittest import mock +from inspect import istraceback from test import support code = support.import_module('code') @@ -65,6 +66,18 @@ self.console.interact() self.assertTrue(hook.called) + def test_sysexcepthook_traceback(self): + self.infunc.side_effect = ["raise ValueError('')", + EOFError('Finished')] + hook = mock.Mock() + self.sysmod.excepthook = hook + self.console.interact() + self.assertTrue(hook.called) + self.assertEqual(len(hook.call_args[0]), 3) + tb = hook.call_args[0][2] + self.assertTrue(istraceback(tb)) + self.assertEqual(tb, self.sysmod.last_traceback) + def test_banner(self): # with banner self.infunc.side_effect = EOFError('Finished')