mirror of https://github.com/python/cpython
bpo-43008: Make IDLE respect sys.excepthook (GH-24302)
Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
This commit is contained in:
parent
01faf4542a
commit
7a34380ad7
|
@ -250,7 +250,7 @@ View Last Restart
|
|||
Scroll the shell window to the last Shell restart.
|
||||
|
||||
Restart Shell
|
||||
Restart the shell to clean the environment.
|
||||
Restart the shell to clean the environment and reset display and exception handling.
|
||||
|
||||
Previous History
|
||||
Cycle through earlier commands in history which match the current entry.
|
||||
|
|
|
@ -3,6 +3,9 @@ Released on 2021-10-04?
|
|||
======================================
|
||||
|
||||
|
||||
bpo-43008: Make IDLE invoke :func:`sys.excepthook` in normal,
|
||||
2-process mode.
|
||||
|
||||
bpo-33065: Fix problem debugging user classes with __repr__ method.
|
||||
|
||||
bpo-32631: Finish zzdummy example extension module: make menu entries
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
"Test run, coverage 49%."
|
||||
|
||||
from idlelib import run
|
||||
import unittest
|
||||
from unittest import mock
|
||||
from idlelib.idle_test.mock_idle import Func
|
||||
from test.support import captured_output, captured_stderr
|
||||
|
||||
import io
|
||||
import sys
|
||||
from test.support import captured_output, captured_stderr
|
||||
import unittest
|
||||
from unittest import mock
|
||||
import idlelib
|
||||
from idlelib.idle_test.mock_idle import Func
|
||||
|
||||
idlelib.testing = True # Use {} for executing test user code.
|
||||
|
||||
|
||||
class RunTest(unittest.TestCase):
|
||||
class PrintExceptionTest(unittest.TestCase):
|
||||
|
||||
def test_print_exception_unhashable(self):
|
||||
class UnhashableException(Exception):
|
||||
|
@ -351,5 +353,38 @@ class HandleErrorTest(unittest.TestCase):
|
|||
self.assertIn('IndexError', msg)
|
||||
eq(func.called, 2)
|
||||
|
||||
|
||||
class ExecRuncodeTest(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.addClassCleanup(setattr,run,'print_exception',run.print_exception)
|
||||
cls.prt = Func() # Need reference.
|
||||
run.print_exception = cls.prt
|
||||
mockrpc = mock.Mock()
|
||||
mockrpc.console.getvar = Func(result=False)
|
||||
cls.ex = run.Executive(mockrpc)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
assert sys.excepthook == sys.__excepthook__
|
||||
|
||||
def test_exceptions(self):
|
||||
ex = self.ex
|
||||
ex.runcode('1/0')
|
||||
self.assertIs(ex.user_exc_info[0], ZeroDivisionError)
|
||||
|
||||
self.addCleanup(setattr, sys, 'excepthook', sys.__excepthook__)
|
||||
sys.excepthook = lambda t, e, tb: run.print_exception(t)
|
||||
ex.runcode('1/0')
|
||||
self.assertIs(self.prt.args[0], ZeroDivisionError)
|
||||
|
||||
sys.excepthook = lambda: None
|
||||
ex.runcode('1/0')
|
||||
t, e, tb = ex.user_exc_info
|
||||
self.assertIs(t, TypeError)
|
||||
self.assertTrue(isinstance(e.__context__, ZeroDivisionError))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(verbosity=2)
|
||||
|
|
|
@ -16,6 +16,7 @@ import _thread as thread
|
|||
import threading
|
||||
import warnings
|
||||
|
||||
import idlelib # testing
|
||||
from idlelib import autocomplete # AutoComplete, fetch_encodings
|
||||
from idlelib import calltip # Calltip
|
||||
from idlelib import debugger_r # start_debugger
|
||||
|
@ -542,14 +543,17 @@ class Executive:
|
|||
|
||||
def __init__(self, rpchandler):
|
||||
self.rpchandler = rpchandler
|
||||
self.locals = __main__.__dict__
|
||||
self.calltip = calltip.Calltip()
|
||||
self.autocomplete = autocomplete.AutoComplete()
|
||||
if idlelib.testing is False:
|
||||
self.locals = __main__.__dict__
|
||||
self.calltip = calltip.Calltip()
|
||||
self.autocomplete = autocomplete.AutoComplete()
|
||||
else:
|
||||
self.locals = {}
|
||||
|
||||
def runcode(self, code):
|
||||
global interruptable
|
||||
try:
|
||||
self.usr_exc_info = None
|
||||
self.user_exc_info = None
|
||||
interruptable = True
|
||||
try:
|
||||
exec(code, self.locals)
|
||||
|
@ -562,10 +566,17 @@ class Executive:
|
|||
print('SystemExit: ' + str(ob), file=sys.stderr)
|
||||
# Return to the interactive prompt.
|
||||
except:
|
||||
self.usr_exc_info = sys.exc_info()
|
||||
self.user_exc_info = sys.exc_info() # For testing, hook, viewer.
|
||||
if quitting:
|
||||
exit()
|
||||
print_exception()
|
||||
if sys.excepthook is sys.__excepthook__:
|
||||
print_exception()
|
||||
else:
|
||||
try:
|
||||
sys.excepthook(*self.user_exc_info)
|
||||
except:
|
||||
self.user_exc_info = sys.exc_info() # For testing.
|
||||
print_exception()
|
||||
jit = self.rpchandler.console.getvar("<<toggle-jit-stack-viewer>>")
|
||||
if jit:
|
||||
self.rpchandler.interp.open_remote_stack_viewer()
|
||||
|
@ -590,8 +601,8 @@ class Executive:
|
|||
return self.autocomplete.fetch_completions(what, mode)
|
||||
|
||||
def stackviewer(self, flist_oid=None):
|
||||
if self.usr_exc_info:
|
||||
typ, val, tb = self.usr_exc_info
|
||||
if self.user_exc_info:
|
||||
typ, val, tb = self.user_exc_info
|
||||
else:
|
||||
return None
|
||||
flist = None
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Make IDLE invoke :func:`sys.excepthook` in normal, 2-process mode.
|
Loading…
Reference in New Issue