From e4474874fe008e4e7d6cb06b1ef9077ccec3a530 2021-12-02 20:19:09 From: Matthias Bussonnier Date: 2021-12-02 20:19:09 Subject: [PATCH] Merge pull request #13357 from Carreau/nuke-lib.inputhook Remove all the lib/inputhook logic and related files. --- diff --git a/IPython/lib/inputhook.py b/IPython/lib/inputhook.py deleted file mode 100644 index 86077d0..0000000 --- a/IPython/lib/inputhook.py +++ /dev/null @@ -1,663 +0,0 @@ -# coding: utf-8 -""" -Deprecated since IPython 5.0 - -Inputhook management for GUI event loop integration. -""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -try: - import ctypes -except ImportError: - ctypes = None -except SystemError: # IronPython issue, 2/8/2014 - ctypes = None -import os -import platform -import sys -from distutils.version import LooseVersion as V - -from warnings import warn - - -warn("`IPython.lib.inputhook` is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - - -#----------------------------------------------------------------------------- -# Constants -#----------------------------------------------------------------------------- - -# Constants for identifying the GUI toolkits. -GUI_WX = 'wx' -GUI_QT = 'qt' -GUI_QT4 = 'qt4' -GUI_GTK = 'gtk' -GUI_TK = 'tk' -GUI_OSX = 'osx' -GUI_GLUT = 'glut' -GUI_PYGLET = 'pyglet' -GUI_GTK3 = 'gtk3' -GUI_NONE = 'none' # i.e. disable - -#----------------------------------------------------------------------------- -# Utilities -#----------------------------------------------------------------------------- - -def _stdin_ready_posix(): - """Return True if there's something to read on stdin (posix version).""" - infds, outfds, erfds = select.select([sys.stdin],[],[],0) - return bool(infds) - -def _stdin_ready_nt(): - """Return True if there's something to read on stdin (nt version).""" - return msvcrt.kbhit() - -def _stdin_ready_other(): - """Return True, assuming there's something to read on stdin.""" - return True - -def _use_appnope(): - """Should we use appnope for dealing with OS X app nap? - - Checks if we are on OS X 10.9 or greater. - """ - return sys.platform == 'darwin' and V(platform.mac_ver()[0]) >= V('10.9') - -def _ignore_CTRL_C_posix(): - """Ignore CTRL+C (SIGINT).""" - signal.signal(signal.SIGINT, signal.SIG_IGN) - -def _allow_CTRL_C_posix(): - """Take CTRL+C into account (SIGINT).""" - signal.signal(signal.SIGINT, signal.default_int_handler) - -def _ignore_CTRL_C_other(): - """Ignore CTRL+C (not implemented).""" - pass - -def _allow_CTRL_C_other(): - """Take CTRL+C into account (not implemented).""" - pass - -if os.name == 'posix': - import select - import signal - stdin_ready = _stdin_ready_posix - ignore_CTRL_C = _ignore_CTRL_C_posix - allow_CTRL_C = _allow_CTRL_C_posix -elif os.name == 'nt': - import msvcrt - stdin_ready = _stdin_ready_nt - ignore_CTRL_C = _ignore_CTRL_C_other - allow_CTRL_C = _allow_CTRL_C_other -else: - stdin_ready = _stdin_ready_other - ignore_CTRL_C = _ignore_CTRL_C_other - allow_CTRL_C = _allow_CTRL_C_other - - -#----------------------------------------------------------------------------- -# Main InputHookManager class -#----------------------------------------------------------------------------- - - -class InputHookManager(object): - """DEPRECATED since IPython 5.0 - - Manage PyOS_InputHook for different GUI toolkits. - - This class installs various hooks under ``PyOSInputHook`` to handle - GUI event loop integration. - """ - - def __init__(self): - if ctypes is None: - warn("IPython GUI event loop requires ctypes, %gui will not be available") - else: - self.PYFUNC = ctypes.PYFUNCTYPE(ctypes.c_int) - self.guihooks = {} - self.aliases = {} - self.apps = {} - self._reset() - - def _reset(self): - self._callback_pyfunctype = None - self._callback = None - self._installed = False - self._current_gui = None - - def get_pyos_inputhook(self): - """DEPRECATED since IPython 5.0 - - Return the current PyOS_InputHook as a ctypes.c_void_p.""" - warn("`get_pyos_inputhook` is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - return ctypes.c_void_p.in_dll(ctypes.pythonapi,"PyOS_InputHook") - - def get_pyos_inputhook_as_func(self): - """DEPRECATED since IPython 5.0 - - Return the current PyOS_InputHook as a ctypes.PYFUNCYPE.""" - warn("`get_pyos_inputhook_as_func` is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - return self.PYFUNC.in_dll(ctypes.pythonapi,"PyOS_InputHook") - - def set_inputhook(self, callback): - """DEPRECATED since IPython 5.0 - - Set PyOS_InputHook to callback and return the previous one.""" - # On platforms with 'readline' support, it's all too likely to - # have a KeyboardInterrupt signal delivered *even before* an - # initial ``try:`` clause in the callback can be executed, so - # we need to disable CTRL+C in this situation. - ignore_CTRL_C() - self._callback = callback - self._callback_pyfunctype = self.PYFUNC(callback) - pyos_inputhook_ptr = self.get_pyos_inputhook() - original = self.get_pyos_inputhook_as_func() - pyos_inputhook_ptr.value = \ - ctypes.cast(self._callback_pyfunctype, ctypes.c_void_p).value - self._installed = True - return original - - def clear_inputhook(self, app=None): - """DEPRECATED since IPython 5.0 - - Set PyOS_InputHook to NULL and return the previous one. - - Parameters - ---------- - app : optional, ignored - This parameter is allowed only so that clear_inputhook() can be - called with a similar interface as all the ``enable_*`` methods. But - the actual value of the parameter is ignored. This uniform interface - makes it easier to have user-level entry points in the main IPython - app like :meth:`enable_gui`.""" - warn("`clear_inputhook` is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - pyos_inputhook_ptr = self.get_pyos_inputhook() - original = self.get_pyos_inputhook_as_func() - pyos_inputhook_ptr.value = ctypes.c_void_p(None).value - allow_CTRL_C() - self._reset() - return original - - def clear_app_refs(self, gui=None): - """DEPRECATED since IPython 5.0 - - Clear IPython's internal reference to an application instance. - - Whenever we create an app for a user on qt4 or wx, we hold a - reference to the app. This is needed because in some cases bad things - can happen if a user doesn't hold a reference themselves. This - method is provided to clear the references we are holding. - - Parameters - ---------- - gui : None or str - If None, clear all app references. If ('wx', 'qt4') clear - the app for that toolkit. References are not held for gtk or tk - as those toolkits don't have the notion of an app. - """ - warn("`clear_app_refs` is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - if gui is None: - self.apps = {} - elif gui in self.apps: - del self.apps[gui] - - def register(self, toolkitname, *aliases): - """DEPRECATED since IPython 5.0 - - Register a class to provide the event loop for a given GUI. - - This is intended to be used as a class decorator. It should be passed - the names with which to register this GUI integration. The classes - themselves should subclass :class:`InputHookBase`. - - :: - - @inputhook_manager.register('qt') - class QtInputHook(InputHookBase): - def enable(self, app=None): - ... - """ - warn("`register` is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - def decorator(cls): - if ctypes is not None: - inst = cls(self) - self.guihooks[toolkitname] = inst - for a in aliases: - self.aliases[a] = toolkitname - return cls - return decorator - - def current_gui(self): - """DEPRECATED since IPython 5.0 - - Return a string indicating the currently active GUI or None.""" - warn("`current_gui` is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - return self._current_gui - - def enable_gui(self, gui=None, app=None): - """DEPRECATED since IPython 5.0 - - Switch amongst GUI input hooks by name. - - This is a higher level method than :meth:`set_inputhook` - it uses the - GUI name to look up a registered object which enables the input hook - for that GUI. - - Parameters - ---------- - gui : optional, string or None - If None (or 'none'), clears input hook, otherwise it must be one - of the recognized GUI names (see ``GUI_*`` constants in module). - - app : optional, existing application object. - For toolkits that have the concept of a global app, you can supply an - existing one. If not given, the toolkit will be probed for one, and if - none is found, a new one will be created. Note that GTK does not have - this concept, and passing an app if ``gui=="GTK"`` will raise an error. - - Returns - ------- - The output of the underlying gui switch routine, typically the actual - PyOS_InputHook wrapper object or the GUI toolkit app created, if there was - one. - """ - warn("`enable_gui` is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - if gui in (None, GUI_NONE): - return self.disable_gui() - - if gui in self.aliases: - return self.enable_gui(self.aliases[gui], app) - - try: - gui_hook = self.guihooks[gui] - except KeyError as e: - e = "Invalid GUI request {!r}, valid ones are: {}" - raise ValueError(e.format(gui, ', '.join(self.guihooks))) from e - self._current_gui = gui - - app = gui_hook.enable(app) - if app is not None: - app._in_event_loop = True - self.apps[gui] = app - return app - - def disable_gui(self): - """DEPRECATED since IPython 5.0 - - Disable GUI event loop integration. - - If an application was registered, this sets its ``_in_event_loop`` - attribute to False. It then calls :meth:`clear_inputhook`. - """ - warn("`disable_gui` is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - gui = self._current_gui - if gui in self.apps: - self.apps[gui]._in_event_loop = False - return self.clear_inputhook() - -class InputHookBase(object): - """DEPRECATED since IPython 5.0 - - Base class for input hooks for specific toolkits. - - Subclasses should define an :meth:`enable` method with one argument, ``app``, - which will either be an instance of the toolkit's application class, or None. - They may also define a :meth:`disable` method with no arguments. - """ - def __init__(self, manager): - self.manager = manager - - def disable(self): - pass - -inputhook_manager = InputHookManager() - -@inputhook_manager.register('osx') -class NullInputHook(InputHookBase): - """DEPRECATED since IPython 5.0 - - A null inputhook that doesn't need to do anything""" - def enable(self, app=None): - warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - -@inputhook_manager.register('wx') -class WxInputHook(InputHookBase): - def enable(self, app=None): - """DEPRECATED since IPython 5.0 - - Enable event loop integration with wxPython. - - Parameters - ---------- - app : WX Application, optional. - Running application to use. If not given, we probe WX for an - existing application object, and create a new one if none is found. - - Notes - ----- - This methods sets the ``PyOS_InputHook`` for wxPython, which allows - the wxPython to integrate with terminal based applications like - IPython. - - If ``app`` is not given we probe for an existing one, and return it if - found. If no existing app is found, we create an :class:`wx.App` as - follows:: - - import wx - app = wx.App(redirect=False, clearSigInt=False) - """ - warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - import wx - - wx_version = V(wx.__version__).version - - if wx_version < [2, 8]: - raise ValueError("requires wxPython >= 2.8, but you have %s" % wx.__version__) - - from IPython.lib.inputhookwx import inputhook_wx - self.manager.set_inputhook(inputhook_wx) - if _use_appnope(): - from appnope import nope - nope() - - import wx - if app is None: - app = wx.GetApp() - if app is None: - app = wx.App(redirect=False, clearSigInt=False) - - return app - - def disable(self): - """DEPRECATED since IPython 5.0 - - Disable event loop integration with wxPython. - - This restores appnapp on OS X - """ - warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - if _use_appnope(): - from appnope import nap - nap() - -@inputhook_manager.register('qt', 'qt4') -class Qt4InputHook(InputHookBase): - def enable(self, app=None): - """DEPRECATED since IPython 5.0 - - Enable event loop integration with PyQt4. - - Parameters - ---------- - 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. - - Notes - ----- - This methods sets the PyOS_InputHook for PyQt4, which allows - the PyQt4 to integrate with terminal based applications like - IPython. - - If ``app`` is not given we probe for an existing one, and return it if - found. If no existing app is found, we create an :class:`QApplication` - as follows:: - - from PyQt4 import QtCore - app = QtGui.QApplication(sys.argv) - """ - warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - from IPython.lib.inputhookqt4 import create_inputhook_qt4 - app, inputhook_qt4 = create_inputhook_qt4(self.manager, app) - self.manager.set_inputhook(inputhook_qt4) - if _use_appnope(): - from appnope import nope - nope() - - return app - - def disable_qt4(self): - """DEPRECATED since IPython 5.0 - - Disable event loop integration with PyQt4. - - This restores appnapp on OS X - """ - warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - if _use_appnope(): - from appnope import nap - nap() - - -@inputhook_manager.register('qt5') -class Qt5InputHook(Qt4InputHook): - def enable(self, app=None): - warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - os.environ['QT_API'] = 'pyqt5' - return Qt4InputHook.enable(self, app) - - -@inputhook_manager.register('gtk') -class GtkInputHook(InputHookBase): - def enable(self, app=None): - """DEPRECATED since IPython 5.0 - - Enable event loop integration with PyGTK. - - Parameters - ---------- - app : ignored - Ignored, it's only a placeholder to keep the call signature of all - gui activation methods consistent, which simplifies the logic of - supporting magics. - - Notes - ----- - This methods sets the PyOS_InputHook for PyGTK, which allows - the PyGTK to integrate with terminal based applications like - IPython. - """ - warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - import gtk - try: - gtk.set_interactive(True) - except AttributeError: - # For older versions of gtk, use our own ctypes version - from IPython.lib.inputhookgtk import inputhook_gtk - self.manager.set_inputhook(inputhook_gtk) - - -@inputhook_manager.register('tk') -class TkInputHook(InputHookBase): - def enable(self, app=None): - """DEPRECATED since IPython 5.0 - - Enable event loop integration with Tk. - - Parameters - ---------- - app : toplevel :class:`Tkinter.Tk` widget, optional. - Running toplevel widget to use. If not given, we probe Tk for an - existing one, and create a new one if none is found. - - Notes - ----- - If you have already created a :class:`Tkinter.Tk` object, the only - thing done by this method is to register with the - :class:`InputHookManager`, since creating that object automatically - sets ``PyOS_InputHook``. - """ - warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - if app is None: - from tkinter import Tk - app = Tk() - app.withdraw() - self.manager.apps[GUI_TK] = app - return app - - -@inputhook_manager.register('glut') -class GlutInputHook(InputHookBase): - def enable(self, app=None): - """DEPRECATED since IPython 5.0 - - Enable event loop integration with GLUT. - - Parameters - ---------- - - app : ignored - Ignored, it's only a placeholder to keep the call signature of all - gui activation methods consistent, which simplifies the logic of - supporting magics. - - Notes - ----- - - This methods sets the PyOS_InputHook for GLUT, which allows the GLUT to - integrate with terminal based applications like IPython. Due to GLUT - limitations, it is currently not possible to start the event loop - without first creating a window. You should thus not create another - window but use instead the created one. See 'gui-glut.py' in the - docs/examples/lib directory. - - The default screen mode is set to: - glut.GLUT_DOUBLE | glut.GLUT_RGBA | glut.GLUT_DEPTH - """ - warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - - import OpenGL.GLUT as glut - from IPython.lib.inputhookglut import glut_display_mode, \ - glut_close, glut_display, \ - glut_idle, inputhook_glut - - if GUI_GLUT not in self.manager.apps: - glut.glutInit( sys.argv ) - glut.glutInitDisplayMode( glut_display_mode ) - # This is specific to freeglut - if bool(glut.glutSetOption): - glut.glutSetOption( glut.GLUT_ACTION_ON_WINDOW_CLOSE, - glut.GLUT_ACTION_GLUTMAINLOOP_RETURNS ) - glut.glutCreateWindow( sys.argv[0] ) - glut.glutReshapeWindow( 1, 1 ) - glut.glutHideWindow( ) - glut.glutWMCloseFunc( glut_close ) - glut.glutDisplayFunc( glut_display ) - glut.glutIdleFunc( glut_idle ) - else: - glut.glutWMCloseFunc( glut_close ) - glut.glutDisplayFunc( glut_display ) - glut.glutIdleFunc( glut_idle) - self.manager.set_inputhook( inputhook_glut ) - - - def disable(self): - """DEPRECATED since IPython 5.0 - - Disable event loop integration with glut. - - This sets PyOS_InputHook to NULL and set the display function to a - dummy one and set the timer to a dummy timer that will be triggered - very far in the future. - """ - warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - import OpenGL.GLUT as glut - from glut_support import glutMainLoopEvent - - glut.glutHideWindow() # This is an event to be processed below - glutMainLoopEvent() - super(GlutInputHook, self).disable() - -@inputhook_manager.register('pyglet') -class PygletInputHook(InputHookBase): - def enable(self, app=None): - """DEPRECATED since IPython 5.0 - - Enable event loop integration with pyglet. - - Parameters - ---------- - app : ignored - Ignored, it's only a placeholder to keep the call signature of all - gui activation methods consistent, which simplifies the logic of - supporting magics. - - Notes - ----- - This methods sets the ``PyOS_InputHook`` for pyglet, which allows - pyglet to integrate with terminal based applications like - IPython. - - """ - warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - from IPython.lib.inputhookpyglet import inputhook_pyglet - self.manager.set_inputhook(inputhook_pyglet) - return app - - -@inputhook_manager.register('gtk3') -class Gtk3InputHook(InputHookBase): - def enable(self, app=None): - """DEPRECATED since IPython 5.0 - - Enable event loop integration with Gtk3 (gir bindings). - - Parameters - ---------- - app : ignored - Ignored, it's only a placeholder to keep the call signature of all - gui activation methods consistent, which simplifies the logic of - supporting magics. - - Notes - ----- - This methods sets the PyOS_InputHook for Gtk3, which allows - the Gtk3 to integrate with terminal based applications like - IPython. - """ - warn("This function is deprecated since IPython 5.0 and will be removed in future versions.", - DeprecationWarning, stacklevel=2) - from IPython.lib.inputhookgtk3 import inputhook_gtk3 - self.manager.set_inputhook(inputhook_gtk3) - - -clear_inputhook = inputhook_manager.clear_inputhook -set_inputhook = inputhook_manager.set_inputhook -current_gui = inputhook_manager.current_gui -clear_app_refs = inputhook_manager.clear_app_refs -enable_gui = inputhook_manager.enable_gui -disable_gui = inputhook_manager.disable_gui -register = inputhook_manager.register -guis = inputhook_manager.guihooks - - -def _deprecated_disable(): - warn("This function is deprecated since IPython 4.0 use disable_gui() instead", - DeprecationWarning, stacklevel=2) - inputhook_manager.disable_gui() - -disable_wx = disable_qt4 = disable_gtk = disable_gtk3 = disable_glut = \ - disable_pyglet = disable_osx = _deprecated_disable diff --git a/IPython/lib/inputhookglut.py b/IPython/lib/inputhookglut.py deleted file mode 100644 index e866ebd..0000000 --- a/IPython/lib/inputhookglut.py +++ /dev/null @@ -1,172 +0,0 @@ -# coding: utf-8 -""" -GLUT Inputhook support functions -""" - -#----------------------------------------------------------------------------- -# 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. -#----------------------------------------------------------------------------- - -# GLUT is quite an old library and it is difficult to ensure proper -# integration within IPython since original GLUT does not allow to handle -# events one by one. Instead, it requires for the mainloop to be entered -# and never returned (there is not even a function to exit he -# mainloop). Fortunately, there are alternatives such as freeglut -# (available for linux and windows) and the OSX implementation gives -# access to a glutCheckLoop() function that blocks itself until a new -# event is received. This means we have to setup the idle callback to -# ensure we got at least one event that will unblock the function. -# -# Furthermore, it is not possible to install these handlers without a window -# being first created. We choose to make this window invisible. This means that -# display mode options are set at this level and user won't be able to change -# them later without modifying the code. This should probably be made available -# via IPython options system. - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- -import os -import sys -import time -import signal -import OpenGL.GLUT as glut -import OpenGL.platform as platform -from timeit import default_timer as clock - -#----------------------------------------------------------------------------- -# Constants -#----------------------------------------------------------------------------- - -# Frame per second : 60 -# Should probably be an IPython option -glut_fps = 60 - - -# Display mode : double buffeed + rgba + depth -# Should probably be an IPython option -glut_display_mode = (glut.GLUT_DOUBLE | - glut.GLUT_RGBA | - glut.GLUT_DEPTH) - -glutMainLoopEvent = None -if sys.platform == 'darwin': - try: - glutCheckLoop = platform.createBaseFunction( - 'glutCheckLoop', dll=platform.GLUT, resultType=None, - argTypes=[], - doc='glutCheckLoop( ) -> None', - argNames=(), - ) - except AttributeError as e: - raise RuntimeError( - '''Your glut implementation does not allow interactive sessions. ''' - '''Consider installing freeglut.''') from e - glutMainLoopEvent = glutCheckLoop -elif glut.HAVE_FREEGLUT: - glutMainLoopEvent = glut.glutMainLoopEvent -else: - raise RuntimeError( - '''Your glut implementation does not allow interactive sessions. ''' - '''Consider installing freeglut.''') - - -#----------------------------------------------------------------------------- -# Platform-dependent imports and functions -#----------------------------------------------------------------------------- - -if os.name == 'posix': - import select - - def stdin_ready(): - infds, outfds, erfds = select.select([sys.stdin],[],[],0) - if infds: - return True - else: - return False - -elif sys.platform == 'win32': - import msvcrt - - def stdin_ready(): - return msvcrt.kbhit() - -#----------------------------------------------------------------------------- -# Callback functions -#----------------------------------------------------------------------------- - -def glut_display(): - # Dummy display function - pass - -def glut_idle(): - # Dummy idle function - pass - -def glut_close(): - # Close function only hides the current window - glut.glutHideWindow() - glutMainLoopEvent() - -def glut_int_handler(signum, frame): - # Catch sigint and print the default message - signal.signal(signal.SIGINT, signal.default_int_handler) - print('\nKeyboardInterrupt') - # Need to reprint the prompt at this stage - - - -#----------------------------------------------------------------------------- -# Code -#----------------------------------------------------------------------------- -def inputhook_glut(): - """Run the pyglet event loop by processing pending events only. - - This keeps processing pending events until stdin is ready. After - processing all pending events, a call to time.sleep is inserted. This is - needed, otherwise, CPU usage is at 100%. This sleep time should be tuned - though for best performance. - """ - # We need to protect against a user pressing Control-C when IPython is - # idle and this is running. We trap KeyboardInterrupt and pass. - - signal.signal(signal.SIGINT, glut_int_handler) - - try: - t = clock() - - # Make sure the default window is set after a window has been closed - if glut.glutGetWindow() == 0: - glut.glutSetWindow( 1 ) - glutMainLoopEvent() - return 0 - - while not stdin_ready(): - glutMainLoopEvent() - # We need to sleep at this point to keep the idle CPU load - # low. However, if sleep to long, GUI response is poor. As - # a compromise, we watch how often GUI events are being processed - # and switch between a short and long sleep time. Here are some - # stats useful in helping to tune this. - # time CPU load - # 0.001 13% - # 0.005 3% - # 0.01 1.5% - # 0.05 0.5% - used_time = clock() - t - if used_time > 10.0: - # print 'Sleep for 1 s' # dbg - time.sleep(1.0) - elif used_time > 0.1: - # Few GUI events coming in, so we can sleep longer - # print 'Sleep for 0.05 s' # dbg - time.sleep(0.05) - else: - # Many GUI events coming in, so sleep only very little - time.sleep(0.001) - except KeyboardInterrupt: - pass - return 0 diff --git a/IPython/lib/inputhookgtk.py b/IPython/lib/inputhookgtk.py deleted file mode 100644 index 98569f5..0000000 --- a/IPython/lib/inputhookgtk.py +++ /dev/null @@ -1,35 +0,0 @@ -# encoding: utf-8 -""" -Enable pygtk to be used interactively by setting PyOS_InputHook. - -Authors: Brian Granger -""" - -#----------------------------------------------------------------------------- -# 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. -#----------------------------------------------------------------------------- - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -import sys -import gtk, gobject - -#----------------------------------------------------------------------------- -# Code -#----------------------------------------------------------------------------- - - -def _main_quit(*args, **kwargs): - gtk.main_quit() - return False - -def inputhook_gtk(): - gobject.io_add_watch(sys.stdin, gobject.IO_IN, _main_quit) - gtk.main() - return 0 - diff --git a/IPython/lib/inputhookgtk3.py b/IPython/lib/inputhookgtk3.py deleted file mode 100644 index b797e86..0000000 --- a/IPython/lib/inputhookgtk3.py +++ /dev/null @@ -1,34 +0,0 @@ -# encoding: utf-8 -""" -Enable Gtk3 to be used interactively by IPython. - -Authors: Thomi Richards -""" -#----------------------------------------------------------------------------- -# Copyright (c) 2012, the IPython Development Team. -# -# Distributed under the terms of the Modified BSD License. -# -# The full license is in the file COPYING.txt, distributed with this software. -#----------------------------------------------------------------------------- - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -import sys -from gi.repository import Gtk, GLib - -#----------------------------------------------------------------------------- -# Code -#----------------------------------------------------------------------------- - -def _main_quit(*args, **kwargs): - Gtk.main_quit() - return False - - -def inputhook_gtk3(): - GLib.io_add_watch(sys.stdin, GLib.PRIORITY_DEFAULT, GLib.IO_IN, _main_quit) - Gtk.main() - return 0 diff --git a/IPython/lib/inputhookgtk4.py b/IPython/lib/inputhookgtk4.py deleted file mode 100644 index a872cee..0000000 --- a/IPython/lib/inputhookgtk4.py +++ /dev/null @@ -1,43 +0,0 @@ -""" -Enable Gtk4 to be used interactively by IPython. -""" -# ----------------------------------------------------------------------------- -# Copyright (c) 2021, the IPython Development Team. -# -# Distributed under the terms of the Modified BSD License. -# -# The full license is in the file COPYING.txt, distributed with this software. -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# Imports -# ----------------------------------------------------------------------------- - -import sys - -from gi.repository import GLib - -# ----------------------------------------------------------------------------- -# Code -# ----------------------------------------------------------------------------- - - -class _InputHook: - def __init__(self, context): - self._quit = False - GLib.io_add_watch(sys.stdin, GLib.PRIORITY_DEFAULT, GLib.IO_IN, self.quit) - - def quit(self, *args, **kwargs): - self._quit = True - return False - - def run(self): - context = GLib.MainContext.default() - while not self._quit: - context.iteration(True) - - -def inputhook_gtk4(): - hook = _InputHook() - hook.run() - return 0 diff --git a/IPython/lib/inputhookpyglet.py b/IPython/lib/inputhookpyglet.py deleted file mode 100644 index fb91ffe..0000000 --- a/IPython/lib/inputhookpyglet.py +++ /dev/null @@ -1,111 +0,0 @@ -# encoding: utf-8 -""" -Enable pyglet to be used interactively by setting PyOS_InputHook. - -Authors -------- - -* Nicolas P. Rougier -* Fernando Perez -""" - -#----------------------------------------------------------------------------- -# 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. -#----------------------------------------------------------------------------- - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -import os -import sys -import time -from timeit import default_timer as clock -import pyglet - -#----------------------------------------------------------------------------- -# Platform-dependent imports and functions -#----------------------------------------------------------------------------- - -if os.name == 'posix': - import select - - def stdin_ready(): - infds, outfds, erfds = select.select([sys.stdin],[],[],0) - if infds: - return True - else: - return False - -elif sys.platform == 'win32': - import msvcrt - - def stdin_ready(): - return msvcrt.kbhit() - - -# On linux only, window.flip() has a bug that causes an AttributeError on -# window close. For details, see: -# http://groups.google.com/group/pyglet-users/browse_thread/thread/47c1aab9aa4a3d23/c22f9e819826799e?#c22f9e819826799e - -if sys.platform.startswith('linux'): - def flip(window): - try: - window.flip() - except AttributeError: - pass -else: - def flip(window): - window.flip() - -#----------------------------------------------------------------------------- -# Code -#----------------------------------------------------------------------------- - -def inputhook_pyglet(): - """Run the pyglet event loop by processing pending events only. - - This keeps processing pending events until stdin is ready. After - processing all pending events, a call to time.sleep is inserted. This is - needed, otherwise, CPU usage is at 100%. This sleep time should be tuned - though for best performance. - """ - # We need to protect against a user pressing Control-C when IPython is - # idle and this is running. We trap KeyboardInterrupt and pass. - try: - t = clock() - while not stdin_ready(): - pyglet.clock.tick() - for window in pyglet.app.windows: - window.switch_to() - window.dispatch_events() - window.dispatch_event('on_draw') - flip(window) - - # We need to sleep at this point to keep the idle CPU load - # low. However, if sleep to long, GUI response is poor. As - # a compromise, we watch how often GUI events are being processed - # and switch between a short and long sleep time. Here are some - # stats useful in helping to tune this. - # time CPU load - # 0.001 13% - # 0.005 3% - # 0.01 1.5% - # 0.05 0.5% - used_time = clock() - t - if used_time > 10.0: - # print 'Sleep for 1 s' # dbg - time.sleep(1.0) - elif used_time > 0.1: - # Few GUI events coming in, so we can sleep longer - # print 'Sleep for 0.05 s' # dbg - time.sleep(0.05) - else: - # Many GUI events coming in, so sleep only very little - time.sleep(0.001) - except KeyboardInterrupt: - pass - return 0 diff --git a/IPython/lib/inputhookqt4.py b/IPython/lib/inputhookqt4.py deleted file mode 100644 index 8a83902..0000000 --- a/IPython/lib/inputhookqt4.py +++ /dev/null @@ -1,180 +0,0 @@ -# -*- 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 -#----------------------------------------------------------------------------- - -import os -import signal -import threading - -from IPython.core.interactiveshell import InteractiveShell -from IPython.external.qt_for_kernel import QtCore, QtGui -from IPython.lib.inputhook import allow_CTRL_C, ignore_CTRL_C, stdin_ready - -#----------------------------------------------------------------------------- -# Module Globals -#----------------------------------------------------------------------------- - -got_kbdint = False -sigint_timer = None - -#----------------------------------------------------------------------------- -# 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 - ----- - We use a custom input hook instead of PyQt4's default one, as it - interacts better with the readline packages (issue #481). - - 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. - """ - - if app is None: - app = QtCore.QCoreApplication.instance() - if app is None: - app = QtGui.QApplication([" "]) - - # Re-use previously created inputhook if any - ip = InteractiveShell.instance() - if hasattr(ip, '_inputhook_qt4'): - return app, ip._inputhook_qt4 - - # Otherwise create the inputhook_qt4/preprompthook_qt4 pair of - # hooks (they both share the got_kbdint flag) - - def inputhook_qt4(): - """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. - """ - try: - allow_CTRL_C() - app = QtCore.QCoreApplication.instance() - if not app: # shouldn't happen, but safer if it happens anyway... - return 0 - app.processEvents(QtCore.QEventLoop.AllEvents, 300) - if not stdin_ready(): - # Generally a program would run QCoreApplication::exec() - # from main() to enter and process the Qt event loop until - # quit() or exit() is called and the program terminates. - # - # For our input hook integration, we need to repeatedly - # enter and process the Qt event loop for only a short - # amount of time (say 50ms) to ensure that Python stays - # responsive to other user inputs. - # - # A naive approach would be to repeatedly call - # QCoreApplication::exec(), using a timer to quit after a - # short amount of time. Unfortunately, QCoreApplication - # emits an aboutToQuit signal before stopping, which has - # the undesirable effect of closing all modal windows. - # - # To work around this problem, we instead create a - # QEventLoop and call QEventLoop::exec(). Other than - # setting some state variables which do not seem to be - # used anywhere, the only thing QCoreApplication adds is - # the aboutToQuit signal which is precisely what we are - # trying to avoid. - timer = QtCore.QTimer() - event_loop = QtCore.QEventLoop() - timer.timeout.connect(event_loop.quit) - while not stdin_ready(): - timer.start(50) - event_loop.exec_() - timer.stop() - except KeyboardInterrupt: - global got_kbdint, sigint_timer - - ignore_CTRL_C() - got_kbdint = True - mgr.clear_inputhook() - - # This generates a second SIGINT so the user doesn't have to - # press CTRL+C twice to get a clean prompt. - # - # Since we can't catch the resulting KeyboardInterrupt here - # (because this is a ctypes callback), we use a timer to - # generate the SIGINT after we leave this callback. - # - # Unfortunately this doesn't work on Windows (SIGINT kills - # Python and CTRL_C_EVENT doesn't work). - if(os.name == 'posix'): - pid = os.getpid() - if(not sigint_timer): - sigint_timer = threading.Timer(.01, os.kill, - args=[pid, signal.SIGINT] ) - sigint_timer.start() - else: - print("\nKeyboardInterrupt - Ctrl-C again for new prompt") - - - except: # NO exceptions are allowed to escape from a ctypes callback - ignore_CTRL_C() - from traceback import print_exc - print_exc() - print("Got exception from inputhook_qt4, unregistering.") - mgr.clear_inputhook() - finally: - allow_CTRL_C() - return 0 - - def preprompthook_qt4(ishell): - """'pre_prompt_hook' used to restore the Qt4 input hook - - (in case the latter was temporarily deactivated after a - CTRL+C) - """ - global got_kbdint, sigint_timer - - if(sigint_timer): - sigint_timer.cancel() - sigint_timer = None - - if got_kbdint: - mgr.set_inputhook(inputhook_qt4) - got_kbdint = False - - ip._inputhook_qt4 = inputhook_qt4 - ip.set_hook('pre_prompt_hook', preprompthook_qt4) - - return app, inputhook_qt4 diff --git a/IPython/lib/inputhookwx.py b/IPython/lib/inputhookwx.py deleted file mode 100644 index 60520a2..0000000 --- a/IPython/lib/inputhookwx.py +++ /dev/null @@ -1,167 +0,0 @@ -# encoding: utf-8 - -""" -Enable wxPython to be used interactively by setting PyOS_InputHook. - -Authors: Robin Dunn, Brian Granger, Ondrej Certik -""" - -#----------------------------------------------------------------------------- -# 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. -#----------------------------------------------------------------------------- - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -import sys -import signal -import time -from timeit import default_timer as clock -import wx - -from IPython.lib.inputhook import stdin_ready - - -#----------------------------------------------------------------------------- -# Code -#----------------------------------------------------------------------------- - -def inputhook_wx1(): - """Run the wx event loop by processing pending events only. - - This approach seems to work, but its performance is not great as it - relies on having PyOS_InputHook called regularly. - """ - try: - app = wx.GetApp() - if app is not None: - assert wx.Thread_IsMain() - - # Make a temporary event loop and process system events until - # there are no more waiting, then allow idle events (which - # will also deal with pending or posted wx events.) - evtloop = wx.EventLoop() - ea = wx.EventLoopActivator(evtloop) - while evtloop.Pending(): - evtloop.Dispatch() - app.ProcessIdle() - del ea - except KeyboardInterrupt: - pass - return 0 - -class EventLoopTimer(wx.Timer): - - def __init__(self, func): - self.func = func - wx.Timer.__init__(self) - - def Notify(self): - self.func() - -class EventLoopRunner(object): - - def Run(self, time): - self.evtloop = wx.EventLoop() - self.timer = EventLoopTimer(self.check_stdin) - self.timer.Start(time) - self.evtloop.Run() - - def check_stdin(self): - if stdin_ready(): - self.timer.Stop() - self.evtloop.Exit() - -def inputhook_wx2(): - """Run the wx event loop, polling for stdin. - - This version runs the wx eventloop for an undetermined amount of time, - during which it periodically checks to see if anything is ready on - stdin. If anything is ready on stdin, the event loop exits. - - The argument to elr.Run controls how often the event loop looks at stdin. - This determines the responsiveness at the keyboard. A setting of 1000 - enables a user to type at most 1 char per second. I have found that a - setting of 10 gives good keyboard response. We can shorten it further, - but eventually performance would suffer from calling select/kbhit too - often. - """ - try: - app = wx.GetApp() - if app is not None: - assert wx.Thread_IsMain() - elr = EventLoopRunner() - # As this time is made shorter, keyboard response improves, but idle - # CPU load goes up. 10 ms seems like a good compromise. - elr.Run(time=10) # CHANGE time here to control polling interval - except KeyboardInterrupt: - pass - return 0 - -def inputhook_wx3(): - """Run the wx event loop by processing pending events only. - - This is like inputhook_wx1, but it keeps processing pending events - until stdin is ready. After processing all pending events, a call to - time.sleep is inserted. This is needed, otherwise, CPU usage is at 100%. - This sleep time should be tuned though for best performance. - """ - # We need to protect against a user pressing Control-C when IPython is - # idle and this is running. We trap KeyboardInterrupt and pass. - try: - app = wx.GetApp() - if app is not None: - assert wx.Thread_IsMain() - - # The import of wx on Linux sets the handler for signal.SIGINT - # to 0. This is a bug in wx or gtk. We fix by just setting it - # back to the Python default. - if not callable(signal.getsignal(signal.SIGINT)): - signal.signal(signal.SIGINT, signal.default_int_handler) - - evtloop = wx.EventLoop() - ea = wx.EventLoopActivator(evtloop) - t = clock() - while not stdin_ready(): - while evtloop.Pending(): - t = clock() - evtloop.Dispatch() - app.ProcessIdle() - # We need to sleep at this point to keep the idle CPU load - # low. However, if sleep to long, GUI response is poor. As - # a compromise, we watch how often GUI events are being processed - # and switch between a short and long sleep time. Here are some - # stats useful in helping to tune this. - # time CPU load - # 0.001 13% - # 0.005 3% - # 0.01 1.5% - # 0.05 0.5% - used_time = clock() - t - if used_time > 10.0: - # print 'Sleep for 1 s' # dbg - time.sleep(1.0) - elif used_time > 0.1: - # Few GUI events coming in, so we can sleep longer - # print 'Sleep for 0.05 s' # dbg - time.sleep(0.05) - else: - # Many GUI events coming in, so sleep only very little - time.sleep(0.001) - del ea - except KeyboardInterrupt: - pass - return 0 - -if sys.platform == 'darwin': - # On OSX, evtloop.Pending() always returns True, regardless of there being - # any events pending. As such we can't use implementations 1 or 3 of the - # inputhook as those depend on a pending/dispatch loop. - inputhook_wx = inputhook_wx2 -else: - # This is our default implementation - inputhook_wx = inputhook_wx3 diff --git a/codecov.yml b/codecov.yml index 7054b5b..81ce677 100644 --- a/codecov.yml +++ b/codecov.yml @@ -18,7 +18,6 @@ ignore: - IPython/kernel/* - IPython/consoleapp.py - IPython/core/inputsplitter.py - - IPython/lib/inputhook*.py - IPython/lib/kernel.py - IPython/utils/jsonutil.py - IPython/utils/localinterfaces.py diff --git a/examples/IPython Kernel/gui/gui-gtk.py b/examples/IPython Kernel/gui/gui-gtk.py deleted file mode 100755 index 3df9922..0000000 --- a/examples/IPython Kernel/gui/gui-gtk.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python -"""Simple GTK example to manually test event loop integration. - -This is meant to run tests manually in ipython as: - -In [5]: %gui gtk - -In [6]: %run gui-gtk.py -""" - -import pygtk -pygtk.require('2.0') -import gtk - - -def hello_world(widget, data=None): - print("Hello World") - -def delete_event(widget, event, data=None): - return False - -def destroy(widget, data=None): - gtk.main_quit() - -window = gtk.Window(gtk.WINDOW_TOPLEVEL) -window.connect("delete_event", delete_event) -window.connect("destroy", destroy) -button = gtk.Button("Hello World") -button.connect("clicked", hello_world, None) - -window.add(button) -button.show() -window.show() - -try: - from IPython.lib.inputhook import enable_gui - enable_gui('gtk') -except ImportError: - gtk.main() diff --git a/examples/IPython Kernel/gui/gui-gtk3.py b/examples/IPython Kernel/gui/gui-gtk3.py deleted file mode 100644 index f35f498..0000000 --- a/examples/IPython Kernel/gui/gui-gtk3.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python -"""Simple Gtk example to manually test event loop integration. - -This is meant to run tests manually in ipython as: - -In [1]: %gui gtk3 - -In [2]: %run gui-gtk3.py -""" - -from gi.repository import Gtk - - -def hello_world(widget, data=None): - print("Hello World") - -def delete_event(widget, event, data=None): - return False - -def destroy(widget, data=None): - Gtk.main_quit() - -window = Gtk.Window(type=Gtk.WindowType.TOPLEVEL) -window.connect("delete_event", delete_event) -window.connect("destroy", destroy) -button = Gtk.Button(label="Hello World") -button.connect("clicked", hello_world, None) - -window.add(button) -button.show() -window.show() - -try: - from IPython.lib.inputhook import enable_gui - enable_gui('gtk3') -except ImportError: - Gtk.main() diff --git a/examples/IPython Kernel/gui/gui-pyglet.py b/examples/IPython Kernel/gui/gui-pyglet.py deleted file mode 100644 index f641622..0000000 --- a/examples/IPython Kernel/gui/gui-pyglet.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python -"""Simple pyglet example to manually test event loop integration. - -This is meant to run tests manually in ipython as: - -In [5]: %gui pyglet - -In [6]: %run gui-pyglet.py -""" - -import pyglet - - -window = pyglet.window.Window() -label = pyglet.text.Label('Hello, world', - font_name='Times New Roman', - font_size=36, - x=window.width//2, y=window.height//2, - anchor_x='center', anchor_y='center') -@window.event -def on_close(): - window.close() - -@window.event -def on_draw(): - window.clear() - label.draw() - -try: - from IPython.lib.inputhook import enable_gui - enable_gui('pyglet') -except ImportError: - pyglet.app.run() diff --git a/examples/IPython Kernel/gui/gui-tk.py b/examples/IPython Kernel/gui/gui-tk.py deleted file mode 100755 index 89caf3e..0000000 --- a/examples/IPython Kernel/gui/gui-tk.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python -"""Simple Tk example to manually test event loop integration. - -This is meant to run tests manually in ipython as: - -In [5]: %gui tk - -In [6]: %run gui-tk.py -""" - -from tkinter import * - - -class MyApp: - - def __init__(self, root): - frame = Frame(root) - frame.pack() - - self.button = Button(frame, text="Hello", command=self.hello_world) - self.button.pack(side=LEFT) - - def hello_world(self): - print("Hello World!") - -root = Tk() - -app = MyApp(root) - -try: - from IPython.lib.inputhook import enable_gui - enable_gui('tk', root) -except ImportError: - root.mainloop() diff --git a/examples/IPython Kernel/gui/gui-wx.py b/examples/IPython Kernel/gui/gui-wx.py deleted file mode 100755 index 86e37ac..0000000 --- a/examples/IPython Kernel/gui/gui-wx.py +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env python -""" -A Simple wx example to test IPython's event loop integration. - -To run this do: - -In [5]: %gui wx # or start IPython with '--gui wx' - -In [6]: %run gui-wx.py - -Ref: Modified from wxPython source code wxPython/samples/simple/simple.py -""" - -import wx - - -class MyFrame(wx.Frame): - """ - This is MyFrame. It just shows a few controls on a wxPanel, - and has a simple menu. - """ - def __init__(self, parent, title): - wx.Frame.__init__(self, parent, -1, title, - pos=(150, 150), size=(350, 200)) - - # Create the menubar - menuBar = wx.MenuBar() - - # and a menu - menu = wx.Menu() - - # add an item to the menu, using \tKeyName automatically - # creates an accelerator, the third param is some help text - # that will show up in the statusbar - menu.Append(wx.ID_EXIT, "E&xit\tAlt-X", "Exit this simple sample") - - # bind the menu event to an event handler - self.Bind(wx.EVT_MENU, self.OnTimeToClose, id=wx.ID_EXIT) - - # and put the menu on the menubar - menuBar.Append(menu, "&File") - self.SetMenuBar(menuBar) - - self.CreateStatusBar() - - # Now create the Panel to put the other controls on. - panel = wx.Panel(self) - - # and a few controls - text = wx.StaticText(panel, -1, "Hello World!") - text.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD)) - text.SetSize(text.GetBestSize()) - btn = wx.Button(panel, -1, "Close") - funbtn = wx.Button(panel, -1, "Just for fun...") - - # bind the button events to handlers - self.Bind(wx.EVT_BUTTON, self.OnTimeToClose, btn) - self.Bind(wx.EVT_BUTTON, self.OnFunButton, funbtn) - - # Use a sizer to layout the controls, stacked vertically and with - # a 10 pixel border around each - sizer = wx.BoxSizer(wx.VERTICAL) - sizer.Add(text, 0, wx.ALL, 10) - sizer.Add(btn, 0, wx.ALL, 10) - sizer.Add(funbtn, 0, wx.ALL, 10) - panel.SetSizer(sizer) - panel.Layout() - - - def OnTimeToClose(self, evt): - """Event handler for the button click.""" - print("See ya later!") - self.Close() - - def OnFunButton(self, evt): - """Event handler for the button click.""" - print("Having fun yet?") - - -class MyApp(wx.App): - def OnInit(self): - frame = MyFrame(None, "Simple wxPython App") - self.SetTopWindow(frame) - - print("Print statements go to this stdout window by default.") - - frame.Show(True) - return True - - -if __name__ == '__main__': - - app = wx.GetApp() - if app is None: - app = MyApp(redirect=False, clearSigInt=False) - else: - frame = MyFrame(None, "Simple wxPython App") - app.SetTopWindow(frame) - print("Print statements go to this stdout window by default.") - frame.Show(True) - - try: - from IPython.lib.inputhook import enable_gui - enable_gui('wx', app) - except ImportError: - app.MainLoop() diff --git a/pytest.ini b/pytest.ini index 9189cf6..e0cfec0 100644 --- a/pytest.ini +++ b/pytest.ini @@ -36,7 +36,6 @@ addopts = --durations=10 --ignore=IPython/kernel --ignore=IPython/consoleapp.py --ignore=IPython/core/inputsplitter.py - --ignore-glob=IPython/lib/inputhook*.py --ignore=IPython/lib/kernel.py --ignore=IPython/utils/jsonutil.py --ignore=IPython/utils/localinterfaces.py