##// END OF EJS Templates
Clear inputhook after printing exception information....
Clear inputhook after printing exception information. Makes this codepath more robust against KeyboardInterrupt raised during exception printing in Qt4 inputhook. Credit goes to @cboos for spotting this.

File last commit:

r5761:699fdb40
r5761:699fdb40
Show More
inputhookqt4.py
122 lines | 4.2 KiB | text/x-python | PythonLexer
Christian Boos
inputhook: move inputhook_qt4 related code in own file
r4931 # -*- coding: utf-8 -*-
"""
Qt4's inputhook support function
Author: Christian Boos
"""
#-----------------------------------------------------------------------------
# Copyright (C) 2011 The IPython Development Team
#
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
Christian Boos
inputhookqt4: use InteractiveShell.instance instead of get_ipython...
r5132 from IPython.core.interactiveshell import InteractiveShell
Christian Boos
inputhook: move inputhook_qt4 related code in own file
r4931 from IPython.external.qt_for_kernel import QtCore, QtGui
Christian Boos
inputhook: disable CTRL+C when a hook is active....
r4944 from IPython.lib.inputhook import allow_CTRL_C, ignore_CTRL_C, stdin_ready
Christian Boos
inputhook: move inputhook_qt4 related code in own file
r4931
#-----------------------------------------------------------------------------
# Code
#-----------------------------------------------------------------------------
def create_inputhook_qt4(mgr, app=None):
"""Create an input hook for running the Qt4 application event loop.
Parameters
----------
mgr : an InputHookManager
app : Qt Application, optional.
Running application to use. If not given, we probe Qt for an
existing application object, and create a new one if none is found.
Returns
-------
A pair consisting of a Qt Application (either the one given or the
one found or created) and a inputhook.
Notes
-----
Christian Boos
inputhookqt4: polish the qt4 related hooks...
r4936 We use a custom input hook instead of PyQt4's default one, as it
interacts better with the readline packages (issue #481).
Christian Boos
inputhook: move inputhook_qt4 related code in own file
r4931 The inputhook function works in tandem with a 'pre_prompt_hook'
which automatically restores the hook as an inputhook in case the
latter has been temporarily disabled after having intercepted a
KeyboardInterrupt.
"""
Christian Boos
inputhookqt4: polish the qt4 related hooks...
r4936
Christian Boos
inputhook: move inputhook_qt4 related code in own file
r4931 if app is None:
app = QtCore.QCoreApplication.instance()
if app is None:
app = QtGui.QApplication([" "])
Christian Boos
inputhookqt4: polish the qt4 related hooks...
r4936 # Re-use previously created inputhook if any
Christian Boos
inputhookqt4: use InteractiveShell.instance instead of get_ipython...
r5132 ip = InteractiveShell.instance()
Christian Boos
inputhookqt4: polish the qt4 related hooks...
r4936 if hasattr(ip, '_inputhook_qt4'):
return app, ip._inputhook_qt4
Christian Boos
inputhook: move inputhook_qt4 related code in own file
r4931
Christian Boos
inputhookqt4: polish the qt4 related hooks...
r4936 # Otherwise create the inputhook_qt4/preprompthook_qt4 pair of
# hooks (they both share the got_kbdint flag)
Christian Boos
inputhook: move inputhook_qt4 related code in own file
r4931
got_kbdint = [False]
def inputhook_qt4():
Christian Boos
inputhookqt4: polish the qt4 related hooks...
r4936 """PyOS_InputHook python hook for Qt4.
Process pending Qt events and if there's no pending keyboard
input, spend a short slice of time (50ms) running the Qt event
loop.
As a Python ctypes callback can't raise an exception, we catch
the KeyboardInterrupt and temporarily deactivate the hook,
which will let a *second* CTRL+C be processed normally and go
back to a clean prompt line.
"""
Christian Boos
inputhook: move inputhook_qt4 related code in own file
r4931 try:
Christian Boos
inputhook: disable CTRL+C when a hook is active....
r4944 allow_CTRL_C()
Christian Boos
inputhookqt4: polish the qt4 related hooks...
r4936 app = QtCore.QCoreApplication.instance()
Christian Boos
inputhookqt4: make hook more robust in case of unexpected conditions...
r5180 if not app: # shouldn't happen, but safer if it happens anyway...
return 0
Christian Boos
inputhook: move inputhook_qt4 related code in own file
r4931 app.processEvents(QtCore.QEventLoop.AllEvents, 300)
if not stdin_ready():
timer = QtCore.QTimer()
timer.timeout.connect(app.quit)
while not stdin_ready():
timer.start(50)
app.exec_()
timer.stop()
except KeyboardInterrupt:
Christian Boos
inputhook: disable CTRL+C when a hook is active....
r4944 ignore_CTRL_C()
Christian Boos
inputhook: move inputhook_qt4 related code in own file
r4931 got_kbdint[0] = True
MinRK
shorten qt4 ctrl-C message to one line
r5743 print("\nKeyboardInterrupt - Ctrl-C again for new prompt")
Christian Boos
inputhook: disable CTRL+C when a hook is active....
r4944 mgr.clear_inputhook()
Christian Boos
inputhookqt4: make hook more robust in case of unexpected conditions...
r5180 except: # NO exceptions are allowed to escape from a ctypes callback
MinRK
Don't ignore ctrl-C during normal execution in inputhook_qt4
r5741 ignore_CTRL_C()
Christian Boos
inputhookqt4: make hook more robust in case of unexpected conditions...
r5180 from traceback import print_exc
print_exc()
print("Got exception from inputhook_qt4, unregistering.")
Fernando Perez
Clear inputhook after printing exception information....
r5761 mgr.clear_inputhook()
MinRK
Don't ignore ctrl-C during normal execution in inputhook_qt4
r5741 finally:
allow_CTRL_C()
Christian Boos
inputhook: move inputhook_qt4 related code in own file
r4931 return 0
def preprompthook_qt4(ishell):
Christian Boos
inputhookqt4: polish the qt4 related hooks...
r4936 """'pre_prompt_hook' used to restore the Qt4 input hook
(in case the latter was temporarily deactivated after a
CTRL+C)
"""
Christian Boos
inputhook: move inputhook_qt4 related code in own file
r4931 if got_kbdint[0]:
mgr.set_inputhook(inputhook_qt4)
Christian Boos
inputhookqt4: forgot to reset KeyboardInterrupt flag
r4932 got_kbdint[0] = False
Christian Boos
inputhookqt4: polish the qt4 related hooks...
r4936
ip._inputhook_qt4 = inputhook_qt4
ip.set_hook('pre_prompt_hook', preprompthook_qt4)
Christian Boos
inputhook: move inputhook_qt4 related code in own file
r4931
return app, inputhook_qt4