From da5a98f891dfc1ae03c5dda449d83f8f8999dc2a 2016-10-03 15:51:45 From: Thomas Kluyver Date: 2016-10-03 15:51:45 Subject: [PATCH] Let IPython.lib.guisupport detect terminal-integrated event loops Closes gh-9974 --- diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index 0c6d8b4..ab77854 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -2891,6 +2891,8 @@ class InteractiveShell(SingletonConfigurable): # Things related to GUI support and pylab #------------------------------------------------------------------------- + active_eventloop = None + def enable_gui(self, gui=None): raise NotImplementedError('Implement enable_gui in a subclass') diff --git a/IPython/lib/guisupport.py b/IPython/lib/guisupport.py index e2fc107..5e13d43 100644 --- a/IPython/lib/guisupport.py +++ b/IPython/lib/guisupport.py @@ -57,16 +57,10 @@ so you don't have to depend on IPython. """ -#----------------------------------------------------------------------------- -# Copyright (C) 2008-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. -#----------------------------------------------------------------------------- +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- +from IPython.core.getipython import get_ipython #----------------------------------------------------------------------------- # wx @@ -84,6 +78,15 @@ def get_app_wx(*args, **kwargs): def is_event_loop_running_wx(app=None): """Is the wx event loop running.""" + # New way: check attribute on shell instance + ip = get_ipython() + if ip is not None: + if ip.active_eventloop and ip.active_eventloop == 'wx': + return True + # Fall through to checking the application, because Wx has a native way + # to check if the event loop is running, unlike Qt. + + # Old way: check Wx application if app is None: app = get_app_wx() if hasattr(app, '_in_event_loop'): @@ -118,6 +121,12 @@ def get_app_qt4(*args, **kwargs): def is_event_loop_running_qt4(app=None): """Is the qt4 event loop running.""" + # New way: check attribute on shell instance + ip = get_ipython() + if ip is not None: + return ip.active_eventloop and ip.active_eventloop.startswith('qt') + + # Old way: check attribute on QApplication singleton if app is None: app = get_app_qt4(['']) if hasattr(app, '_in_event_loop'): diff --git a/IPython/terminal/interactiveshell.py b/IPython/terminal/interactiveshell.py index 9db6745..0de3aaa 100644 --- a/IPython/terminal/interactiveshell.py +++ b/IPython/terminal/interactiveshell.py @@ -28,7 +28,7 @@ from pygments.token import Token from .debugger import TerminalPdb, Pdb from .magics import TerminalMagics -from .pt_inputhooks import get_inputhook_func +from .pt_inputhooks import get_inputhook_name_and_func from .prompts import Prompts, ClassicPrompts, RichPromptDisplayHook from .ptutils import IPythonPTCompleter, IPythonPTLexer from .shortcuts import register_ipython_shortcuts @@ -458,11 +458,13 @@ class TerminalInteractiveShell(InteractiveShell): if self._inputhook is not None: self._inputhook(context) + active_eventloop = None def enable_gui(self, gui=None): if gui: - self._inputhook = get_inputhook_func(gui) + self.active_eventloop, self._inputhook =\ + get_inputhook_name_and_func(gui) else: - self._inputhook = None + self.active_eventloop = self._inputhook = None # Run !system commands directly, not through pipes, so terminal programs # work correctly. diff --git a/IPython/terminal/pt_inputhooks/__init__.py b/IPython/terminal/pt_inputhooks/__init__.py index 0f37b13..3766973 100644 --- a/IPython/terminal/pt_inputhooks/__init__.py +++ b/IPython/terminal/pt_inputhooks/__init__.py @@ -30,19 +30,20 @@ class UnknownBackend(KeyError): "Supported event loops are: {}").format(self.name, ', '.join(backends + sorted(registered))) -def get_inputhook_func(gui): +def get_inputhook_name_and_func(gui): if gui in registered: - return registered[gui] + return gui, registered[gui] if gui not in backends: raise UnknownBackend(gui) if gui in aliases: - return get_inputhook_func(aliases[gui]) + return get_inputhook_name_and_func(aliases[gui]) + gui_mod = gui if gui == 'qt5': os.environ['QT_API'] = 'pyqt5' - gui = 'qt' + gui_mod = 'qt' - mod = importlib.import_module('IPython.terminal.pt_inputhooks.'+gui) - return mod.inputhook + mod = importlib.import_module('IPython.terminal.pt_inputhooks.'+gui_mod) + return gui, mod.inputhook