Uploaded Test files
This commit is contained in:
parent
f584ad9d97
commit
2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions
|
@ -0,0 +1,50 @@
|
|||
import importlib
|
||||
import os
|
||||
|
||||
aliases = {
|
||||
'qt4': 'qt',
|
||||
'gtk2': 'gtk',
|
||||
}
|
||||
|
||||
backends = [
|
||||
'qt', 'qt4', 'qt5',
|
||||
'gtk', 'gtk2', 'gtk3',
|
||||
'tk',
|
||||
'wx',
|
||||
'pyglet', 'glut',
|
||||
'osx',
|
||||
'asyncio'
|
||||
]
|
||||
|
||||
registered = {}
|
||||
|
||||
def register(name, inputhook):
|
||||
"""Register the function *inputhook* as an event loop integration."""
|
||||
registered[name] = inputhook
|
||||
|
||||
class UnknownBackend(KeyError):
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
def __str__(self):
|
||||
return ("No event loop integration for {!r}. "
|
||||
"Supported event loops are: {}").format(self.name,
|
||||
', '.join(backends + sorted(registered)))
|
||||
|
||||
def get_inputhook_name_and_func(gui):
|
||||
if gui in registered:
|
||||
return gui, registered[gui]
|
||||
|
||||
if gui not in backends:
|
||||
raise UnknownBackend(gui)
|
||||
|
||||
if gui in aliases:
|
||||
return get_inputhook_name_and_func(aliases[gui])
|
||||
|
||||
gui_mod = gui
|
||||
if gui == 'qt5':
|
||||
os.environ['QT_API'] = 'pyqt5'
|
||||
gui_mod = 'qt'
|
||||
|
||||
mod = importlib.import_module('IPython.terminal.pt_inputhooks.'+gui_mod)
|
||||
return gui, mod.inputhook
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,64 @@
|
|||
"""
|
||||
Inputhook for running the original asyncio event loop while we're waiting for
|
||||
input.
|
||||
|
||||
By default, in IPython, we run the prompt with a different asyncio event loop,
|
||||
because otherwise we risk that people are freezing the prompt by scheduling bad
|
||||
coroutines. E.g., a coroutine that does a while/true and never yield back
|
||||
control to the loop. We can't cancel that.
|
||||
|
||||
However, sometimes we want the asyncio loop to keep running while waiting for
|
||||
a prompt.
|
||||
|
||||
The following example will print the numbers from 1 to 10 above the prompt,
|
||||
while we are waiting for input. (This works also because we use
|
||||
prompt_toolkit`s `patch_stdout`)::
|
||||
|
||||
In [1]: import asyncio
|
||||
|
||||
In [2]: %gui asyncio
|
||||
|
||||
In [3]: async def f():
|
||||
...: for i in range(10):
|
||||
...: await asyncio.sleep(1)
|
||||
...: print(i)
|
||||
|
||||
|
||||
In [4]: asyncio.ensure_future(f())
|
||||
|
||||
"""
|
||||
import asyncio
|
||||
from prompt_toolkit import __version__ as ptk_version
|
||||
|
||||
PTK3 = ptk_version.startswith('3.')
|
||||
|
||||
|
||||
# Keep reference to the original asyncio loop, because getting the event loop
|
||||
# within the input hook would return the other loop.
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
|
||||
def inputhook(context):
|
||||
"""
|
||||
Inputhook for asyncio event loop integration.
|
||||
"""
|
||||
# For prompt_toolkit 3.0, this input hook literally doesn't do anything.
|
||||
# The event loop integration here is implemented in `interactiveshell.py`
|
||||
# by running the prompt itself in the current asyncio loop. The main reason
|
||||
# for this is that nesting asyncio event loops is unreliable.
|
||||
if PTK3:
|
||||
return
|
||||
|
||||
# For prompt_toolkit 2.0, we can run the current asyncio event loop,
|
||||
# because prompt_toolkit 2.0 uses a different event loop internally.
|
||||
|
||||
def stop():
|
||||
loop.stop()
|
||||
|
||||
fileno = context.fileno()
|
||||
loop.add_reader(fileno, stop)
|
||||
try:
|
||||
loop.run_forever()
|
||||
finally:
|
||||
loop.remove_reader(fileno)
|
||||
|
140
venv/Lib/site-packages/IPython/terminal/pt_inputhooks/glut.py
Normal file
140
venv/Lib/site-packages/IPython/terminal/pt_inputhooks/glut.py
Normal file
|
@ -0,0 +1,140 @@
|
|||
"""GLUT Input hook for interactive use with prompt_toolkit
|
||||
"""
|
||||
|
||||
|
||||
# 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.
|
||||
|
||||
import sys
|
||||
import time
|
||||
import signal
|
||||
import OpenGL.GLUT as glut
|
||||
import OpenGL.platform as platform
|
||||
from timeit import default_timer as clock
|
||||
|
||||
# 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:
|
||||
raise RuntimeError(
|
||||
'''Your glut implementation does not allow interactive sessions'''
|
||||
'''Consider installing freeglut.''')
|
||||
glutMainLoopEvent = glutCheckLoop
|
||||
elif glut.HAVE_FREEGLUT:
|
||||
glutMainLoopEvent = glut.glutMainLoopEvent
|
||||
else:
|
||||
raise RuntimeError(
|
||||
'''Your glut implementation does not allow interactive sessions. '''
|
||||
'''Consider installing freeglut.''')
|
||||
|
||||
|
||||
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 defaultipyt message
|
||||
signal.signal(signal.SIGINT, signal.default_int_handler)
|
||||
print('\nKeyboardInterrupt')
|
||||
# Need to reprint the prompt at this stage
|
||||
|
||||
# Initialisation code
|
||||
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( b'ipython' )
|
||||
glut.glutReshapeWindow( 1, 1 )
|
||||
glut.glutHideWindow( )
|
||||
glut.glutWMCloseFunc( glut_close )
|
||||
glut.glutDisplayFunc( glut_display )
|
||||
glut.glutIdleFunc( glut_idle )
|
||||
|
||||
|
||||
def inputhook(context):
|
||||
"""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 context.input_is_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
|
58
venv/Lib/site-packages/IPython/terminal/pt_inputhooks/gtk.py
Normal file
58
venv/Lib/site-packages/IPython/terminal/pt_inputhooks/gtk.py
Normal file
|
@ -0,0 +1,58 @@
|
|||
# Code borrowed from python-prompt-toolkit examples
|
||||
# https://github.com/jonathanslenders/python-prompt-toolkit/blob/77cdcfbc7f4b4c34a9d2f9a34d422d7152f16209/examples/inputhook.py
|
||||
|
||||
# Copyright (c) 2014, Jonathan Slenders
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice, this
|
||||
# list of conditions and the following disclaimer in the documentation and/or
|
||||
# other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the {organization} nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""
|
||||
PyGTK input hook for prompt_toolkit.
|
||||
|
||||
Listens on the pipe prompt_toolkit sets up for a notification that it should
|
||||
return control to the terminal event loop.
|
||||
"""
|
||||
|
||||
import gtk, gobject
|
||||
|
||||
# Enable threading in GTK. (Otherwise, GTK will keep the GIL.)
|
||||
gtk.gdk.threads_init()
|
||||
|
||||
def inputhook(context):
|
||||
"""
|
||||
When the eventloop of prompt-toolkit is idle, call this inputhook.
|
||||
|
||||
This will run the GTK main loop until the file descriptor
|
||||
`context.fileno()` becomes ready.
|
||||
|
||||
:param context: An `InputHookContext` instance.
|
||||
"""
|
||||
def _main_quit(*a, **kw):
|
||||
gtk.main_quit()
|
||||
return False
|
||||
|
||||
gobject.io_add_watch(context.fileno(), gobject.IO_IN, _main_quit)
|
||||
gtk.main()
|
|
@ -0,0 +1,12 @@
|
|||
"""prompt_toolkit input hook for GTK 3
|
||||
"""
|
||||
|
||||
from gi.repository import Gtk, GLib
|
||||
|
||||
def _main_quit(*args, **kwargs):
|
||||
Gtk.main_quit()
|
||||
return False
|
||||
|
||||
def inputhook(context):
|
||||
GLib.io_add_watch(context.fileno(), GLib.PRIORITY_DEFAULT, GLib.IO_IN, _main_quit)
|
||||
Gtk.main()
|
137
venv/Lib/site-packages/IPython/terminal/pt_inputhooks/osx.py
Normal file
137
venv/Lib/site-packages/IPython/terminal/pt_inputhooks/osx.py
Normal file
|
@ -0,0 +1,137 @@
|
|||
"""Inputhook for OS X
|
||||
|
||||
Calls NSApp / CoreFoundation APIs via ctypes.
|
||||
"""
|
||||
|
||||
# obj-c boilerplate from appnope, used under BSD 2-clause
|
||||
|
||||
import ctypes
|
||||
import ctypes.util
|
||||
from threading import Event
|
||||
|
||||
objc = ctypes.cdll.LoadLibrary(ctypes.util.find_library('objc'))
|
||||
|
||||
void_p = ctypes.c_void_p
|
||||
|
||||
objc.objc_getClass.restype = void_p
|
||||
objc.sel_registerName.restype = void_p
|
||||
objc.objc_msgSend.restype = void_p
|
||||
objc.objc_msgSend.argtypes = [void_p, void_p]
|
||||
|
||||
msg = objc.objc_msgSend
|
||||
|
||||
def _utf8(s):
|
||||
"""ensure utf8 bytes"""
|
||||
if not isinstance(s, bytes):
|
||||
s = s.encode('utf8')
|
||||
return s
|
||||
|
||||
def n(name):
|
||||
"""create a selector name (for ObjC methods)"""
|
||||
return objc.sel_registerName(_utf8(name))
|
||||
|
||||
def C(classname):
|
||||
"""get an ObjC Class by name"""
|
||||
return objc.objc_getClass(_utf8(classname))
|
||||
|
||||
# end obj-c boilerplate from appnope
|
||||
|
||||
# CoreFoundation C-API calls we will use:
|
||||
CoreFoundation = ctypes.cdll.LoadLibrary(ctypes.util.find_library('CoreFoundation'))
|
||||
|
||||
CFFileDescriptorCreate = CoreFoundation.CFFileDescriptorCreate
|
||||
CFFileDescriptorCreate.restype = void_p
|
||||
CFFileDescriptorCreate.argtypes = [void_p, ctypes.c_int, ctypes.c_bool, void_p]
|
||||
|
||||
CFFileDescriptorGetNativeDescriptor = CoreFoundation.CFFileDescriptorGetNativeDescriptor
|
||||
CFFileDescriptorGetNativeDescriptor.restype = ctypes.c_int
|
||||
CFFileDescriptorGetNativeDescriptor.argtypes = [void_p]
|
||||
|
||||
CFFileDescriptorEnableCallBacks = CoreFoundation.CFFileDescriptorEnableCallBacks
|
||||
CFFileDescriptorEnableCallBacks.restype = None
|
||||
CFFileDescriptorEnableCallBacks.argtypes = [void_p, ctypes.c_ulong]
|
||||
|
||||
CFFileDescriptorCreateRunLoopSource = CoreFoundation.CFFileDescriptorCreateRunLoopSource
|
||||
CFFileDescriptorCreateRunLoopSource.restype = void_p
|
||||
CFFileDescriptorCreateRunLoopSource.argtypes = [void_p, void_p, void_p]
|
||||
|
||||
CFRunLoopGetCurrent = CoreFoundation.CFRunLoopGetCurrent
|
||||
CFRunLoopGetCurrent.restype = void_p
|
||||
|
||||
CFRunLoopAddSource = CoreFoundation.CFRunLoopAddSource
|
||||
CFRunLoopAddSource.restype = None
|
||||
CFRunLoopAddSource.argtypes = [void_p, void_p, void_p]
|
||||
|
||||
CFRelease = CoreFoundation.CFRelease
|
||||
CFRelease.restype = None
|
||||
CFRelease.argtypes = [void_p]
|
||||
|
||||
CFFileDescriptorInvalidate = CoreFoundation.CFFileDescriptorInvalidate
|
||||
CFFileDescriptorInvalidate.restype = None
|
||||
CFFileDescriptorInvalidate.argtypes = [void_p]
|
||||
|
||||
# From CFFileDescriptor.h
|
||||
kCFFileDescriptorReadCallBack = 1
|
||||
kCFRunLoopCommonModes = void_p.in_dll(CoreFoundation, 'kCFRunLoopCommonModes')
|
||||
|
||||
|
||||
def _NSApp():
|
||||
"""Return the global NSApplication instance (NSApp)"""
|
||||
return msg(C('NSApplication'), n('sharedApplication'))
|
||||
|
||||
|
||||
def _wake(NSApp):
|
||||
"""Wake the Application"""
|
||||
event = msg(C('NSEvent'),
|
||||
n('otherEventWithType:location:modifierFlags:'
|
||||
'timestamp:windowNumber:context:subtype:data1:data2:'),
|
||||
15, # Type
|
||||
0, # location
|
||||
0, # flags
|
||||
0, # timestamp
|
||||
0, # window
|
||||
None, # context
|
||||
0, # subtype
|
||||
0, # data1
|
||||
0, # data2
|
||||
)
|
||||
msg(NSApp, n('postEvent:atStart:'), void_p(event), True)
|
||||
|
||||
|
||||
_triggered = Event()
|
||||
|
||||
def _input_callback(fdref, flags, info):
|
||||
"""Callback to fire when there's input to be read"""
|
||||
_triggered.set()
|
||||
CFFileDescriptorInvalidate(fdref)
|
||||
CFRelease(fdref)
|
||||
NSApp = _NSApp()
|
||||
msg(NSApp, n('stop:'), NSApp)
|
||||
_wake(NSApp)
|
||||
|
||||
_c_callback_func_type = ctypes.CFUNCTYPE(None, void_p, void_p, void_p)
|
||||
_c_input_callback = _c_callback_func_type(_input_callback)
|
||||
|
||||
|
||||
def _stop_on_read(fd):
|
||||
"""Register callback to stop eventloop when there's data on fd"""
|
||||
_triggered.clear()
|
||||
fdref = CFFileDescriptorCreate(None, fd, False, _c_input_callback, None)
|
||||
CFFileDescriptorEnableCallBacks(fdref, kCFFileDescriptorReadCallBack)
|
||||
source = CFFileDescriptorCreateRunLoopSource(None, fdref, 0)
|
||||
loop = CFRunLoopGetCurrent()
|
||||
CFRunLoopAddSource(loop, source, kCFRunLoopCommonModes)
|
||||
CFRelease(source)
|
||||
|
||||
|
||||
def inputhook(context):
|
||||
"""Inputhook for Cocoa (NSApp)"""
|
||||
NSApp = _NSApp()
|
||||
_stop_on_read(context.fileno())
|
||||
msg(NSApp, n('run'))
|
||||
if not _triggered.is_set():
|
||||
# app closed without firing callback,
|
||||
# probably due to last window being closed.
|
||||
# Run the loop manually in this case,
|
||||
# since there may be events still to process (#9734)
|
||||
CoreFoundation.CFRunLoopRun()
|
|
@ -0,0 +1,66 @@
|
|||
"""Enable pyglet to be used interactively with prompt_toolkit
|
||||
"""
|
||||
|
||||
import sys
|
||||
import time
|
||||
from timeit import default_timer as clock
|
||||
import pyglet
|
||||
|
||||
# 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()
|
||||
|
||||
|
||||
def inputhook(context):
|
||||
"""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 context.input_is_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
|
54
venv/Lib/site-packages/IPython/terminal/pt_inputhooks/qt.py
Normal file
54
venv/Lib/site-packages/IPython/terminal/pt_inputhooks/qt.py
Normal file
|
@ -0,0 +1,54 @@
|
|||
import sys
|
||||
import os
|
||||
from IPython.external.qt_for_kernel import QtCore, QtGui
|
||||
|
||||
# If we create a QApplication, keep a reference to it so that it doesn't get
|
||||
# garbage collected.
|
||||
_appref = None
|
||||
_already_warned = False
|
||||
|
||||
|
||||
def inputhook(context):
|
||||
global _appref
|
||||
app = QtCore.QCoreApplication.instance()
|
||||
if not app:
|
||||
if sys.platform == 'linux':
|
||||
if not os.environ.get('DISPLAY') \
|
||||
and not os.environ.get('WAYLAND_DISPLAY'):
|
||||
import warnings
|
||||
global _already_warned
|
||||
if not _already_warned:
|
||||
_already_warned = True
|
||||
warnings.warn(
|
||||
'The DISPLAY or WAYLAND_DISPLAY environment variable is '
|
||||
'not set or empty and Qt5 requires this environment '
|
||||
'variable. Deactivate Qt5 code.'
|
||||
)
|
||||
return
|
||||
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
|
||||
_appref = app = QtGui.QApplication([" "])
|
||||
event_loop = QtCore.QEventLoop(app)
|
||||
|
||||
if sys.platform == 'win32':
|
||||
# The QSocketNotifier method doesn't appear to work on Windows.
|
||||
# Use polling instead.
|
||||
timer = QtCore.QTimer()
|
||||
timer.timeout.connect(event_loop.quit)
|
||||
while not context.input_is_ready():
|
||||
timer.start(50) # 50 ms
|
||||
event_loop.exec_()
|
||||
timer.stop()
|
||||
else:
|
||||
# On POSIX platforms, we can use a file descriptor to quit the event
|
||||
# loop when there is input ready to read.
|
||||
notifier = QtCore.QSocketNotifier(context.fileno(),
|
||||
QtCore.QSocketNotifier.Read)
|
||||
try:
|
||||
# connect the callback we care about before we turn it on
|
||||
notifier.activated.connect(lambda: event_loop.exit())
|
||||
notifier.setEnabled(True)
|
||||
# only start the event loop we are not already flipped
|
||||
if not context.input_is_ready():
|
||||
event_loop.exec_()
|
||||
finally:
|
||||
notifier.setEnabled(False)
|
90
venv/Lib/site-packages/IPython/terminal/pt_inputhooks/tk.py
Normal file
90
venv/Lib/site-packages/IPython/terminal/pt_inputhooks/tk.py
Normal file
|
@ -0,0 +1,90 @@
|
|||
# Code borrowed from ptpython
|
||||
# https://github.com/jonathanslenders/ptpython/blob/86b71a89626114b18898a0af463978bdb32eeb70/ptpython/eventloop.py
|
||||
|
||||
# Copyright (c) 2015, Jonathan Slenders
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice, this
|
||||
# list of conditions and the following disclaimer in the documentation and/or
|
||||
# other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the {organization} nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""
|
||||
Wrapper around the eventloop that gives some time to the Tkinter GUI to process
|
||||
events when it's loaded and while we are waiting for input at the REPL. This
|
||||
way we don't block the UI of for instance ``turtle`` and other Tk libraries.
|
||||
|
||||
(Normally Tkinter registers it's callbacks in ``PyOS_InputHook`` to integrate
|
||||
in readline. ``prompt-toolkit`` doesn't understand that input hook, but this
|
||||
will fix it for Tk.)
|
||||
"""
|
||||
import time
|
||||
|
||||
import _tkinter
|
||||
import tkinter
|
||||
|
||||
def inputhook(inputhook_context):
|
||||
"""
|
||||
Inputhook for Tk.
|
||||
Run the Tk eventloop until prompt-toolkit needs to process the next input.
|
||||
"""
|
||||
# Get the current TK application.
|
||||
root = tkinter._default_root
|
||||
|
||||
def wait_using_filehandler():
|
||||
"""
|
||||
Run the TK eventloop until the file handler that we got from the
|
||||
inputhook becomes readable.
|
||||
"""
|
||||
# Add a handler that sets the stop flag when `prompt-toolkit` has input
|
||||
# to process.
|
||||
stop = [False]
|
||||
def done(*a):
|
||||
stop[0] = True
|
||||
|
||||
root.createfilehandler(inputhook_context.fileno(), _tkinter.READABLE, done)
|
||||
|
||||
# Run the TK event loop as long as we don't receive input.
|
||||
while root.dooneevent(_tkinter.ALL_EVENTS):
|
||||
if stop[0]:
|
||||
break
|
||||
|
||||
root.deletefilehandler(inputhook_context.fileno())
|
||||
|
||||
def wait_using_polling():
|
||||
"""
|
||||
Windows TK doesn't support 'createfilehandler'.
|
||||
So, run the TK eventloop and poll until input is ready.
|
||||
"""
|
||||
while not inputhook_context.input_is_ready():
|
||||
while root.dooneevent(_tkinter.ALL_EVENTS | _tkinter.DONT_WAIT):
|
||||
pass
|
||||
# Sleep to make the CPU idle, but not too long, so that the UI
|
||||
# stays responsive.
|
||||
time.sleep(.01)
|
||||
|
||||
if root is not None:
|
||||
if hasattr(root, 'createfilehandler'):
|
||||
wait_using_filehandler()
|
||||
else:
|
||||
wait_using_polling()
|
219
venv/Lib/site-packages/IPython/terminal/pt_inputhooks/wx.py
Normal file
219
venv/Lib/site-packages/IPython/terminal/pt_inputhooks/wx.py
Normal file
|
@ -0,0 +1,219 @@
|
|||
"""Enable wxPython to be used interactively in prompt_toolkit
|
||||
"""
|
||||
|
||||
import sys
|
||||
import signal
|
||||
import time
|
||||
from timeit import default_timer as clock
|
||||
import wx
|
||||
|
||||
|
||||
def ignore_keyboardinterrupts(func):
|
||||
"""Decorator which causes KeyboardInterrupt exceptions to be ignored during
|
||||
execution of the decorated function.
|
||||
|
||||
This is used by the inputhook functions to handle the event where the user
|
||||
presses CTRL+C while IPython is idle, and the inputhook loop is running. In
|
||||
this case, we want to ignore interrupts.
|
||||
"""
|
||||
def wrapper(*args, **kwargs):
|
||||
try:
|
||||
func(*args, **kwargs)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
return wrapper
|
||||
|
||||
|
||||
@ignore_keyboardinterrupts
|
||||
def inputhook_wx1(context):
|
||||
"""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.
|
||||
"""
|
||||
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
|
||||
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, input_is_ready):
|
||||
self.input_is_ready = input_is_ready
|
||||
self.evtloop = wx.EventLoop()
|
||||
self.timer = EventLoopTimer(self.check_stdin)
|
||||
self.timer.Start(time)
|
||||
self.evtloop.Run()
|
||||
|
||||
def check_stdin(self):
|
||||
if self.input_is_ready():
|
||||
self.timer.Stop()
|
||||
self.evtloop.Exit()
|
||||
|
||||
|
||||
@ignore_keyboardinterrupts
|
||||
def inputhook_wx2(context):
|
||||
"""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.
|
||||
"""
|
||||
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
|
||||
input_is_ready=context.input_is_ready)
|
||||
return 0
|
||||
|
||||
|
||||
@ignore_keyboardinterrupts
|
||||
def inputhook_wx3(context):
|
||||
"""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.
|
||||
"""
|
||||
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 context.input_is_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
|
||||
return 0
|
||||
|
||||
|
||||
@ignore_keyboardinterrupts
|
||||
def inputhook_wxphoenix(context):
|
||||
"""Run the wx event loop until the user provides more input.
|
||||
|
||||
This input hook is suitable for use with wxPython >= 4 (a.k.a. Phoenix).
|
||||
|
||||
It uses the same approach to that used in
|
||||
ipykernel.eventloops.loop_wx. The wx.MainLoop is executed, and a wx.Timer
|
||||
is used to periodically poll the context for input. As soon as input is
|
||||
ready, the wx.MainLoop is stopped.
|
||||
"""
|
||||
|
||||
app = wx.GetApp()
|
||||
|
||||
if app is None:
|
||||
return
|
||||
|
||||
if context.input_is_ready():
|
||||
return
|
||||
|
||||
assert wx.IsMainThread()
|
||||
|
||||
# Wx uses milliseconds
|
||||
poll_interval = 100
|
||||
|
||||
# Use a wx.Timer to periodically check whether input is ready - as soon as
|
||||
# it is, we exit the main loop
|
||||
timer = wx.Timer()
|
||||
|
||||
def poll(ev):
|
||||
if context.input_is_ready():
|
||||
timer.Stop()
|
||||
app.ExitMainLoop()
|
||||
|
||||
timer.Start(poll_interval)
|
||||
timer.Bind(wx.EVT_TIMER, poll)
|
||||
|
||||
# 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)
|
||||
|
||||
# The SetExitOnFrameDelete call allows us to run the wx mainloop without
|
||||
# having a frame open.
|
||||
app.SetExitOnFrameDelete(False)
|
||||
app.MainLoop()
|
||||
|
||||
|
||||
# Get the major wx version number to figure out what input hook we should use.
|
||||
major_version = 3
|
||||
|
||||
try:
|
||||
major_version = int(wx.__version__[0])
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Use the phoenix hook on all platforms for wxpython >= 4
|
||||
if major_version >= 4:
|
||||
inputhook = inputhook_wxphoenix
|
||||
# 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.
|
||||
elif sys.platform == 'darwin':
|
||||
inputhook = inputhook_wx2
|
||||
else:
|
||||
inputhook = inputhook_wx3
|
Loading…
Add table
Add a link
Reference in a new issue