mirror of
https://github.com/aykhans/AzSuicideDataVisualization.git
synced 2025-07-02 14:27:31 +00:00
first commit
This commit is contained in:
@ -0,0 +1,62 @@
|
||||
import importlib
|
||||
import os
|
||||
|
||||
aliases = {
|
||||
'qt4': 'qt',
|
||||
'gtk2': 'gtk',
|
||||
}
|
||||
|
||||
backends = [
|
||||
"qt",
|
||||
"qt4",
|
||||
"qt5",
|
||||
"qt6",
|
||||
"gtk",
|
||||
"gtk2",
|
||||
"gtk3",
|
||||
"gtk4",
|
||||
"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"
|
||||
elif gui == "qt6":
|
||||
os.environ["QT_API"] = "pyqt6"
|
||||
gui_mod = "qt"
|
||||
|
||||
mod = importlib.import_module('IPython.terminal.pt_inputhooks.'+gui_mod)
|
||||
return gui, mod.inputhook
|
@ -0,0 +1,63 @@
|
||||
"""
|
||||
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())
|
||||
|
||||
"""
|
||||
from prompt_toolkit import __version__ as ptk_version
|
||||
|
||||
from IPython.core.async_helpers import get_asyncio_loop
|
||||
|
||||
PTK3 = ptk_version.startswith('3.')
|
||||
|
||||
|
||||
|
||||
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.
|
||||
|
||||
# get the persistent asyncio event loop
|
||||
loop = get_asyncio_loop()
|
||||
|
||||
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 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.''')
|
||||
|
||||
|
||||
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
|
@ -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()
|
@ -0,0 +1,27 @@
|
||||
"""
|
||||
prompt_toolkit input hook for GTK 4.
|
||||
"""
|
||||
|
||||
from gi.repository import GLib
|
||||
|
||||
|
||||
class _InputHook:
|
||||
def __init__(self, context):
|
||||
self._quit = False
|
||||
GLib.io_add_watch(
|
||||
context.fileno(), 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(context):
|
||||
hook = _InputHook(context)
|
||||
hook.run()
|
157
.venv/Lib/site-packages/IPython/terminal/pt_inputhooks/osx.py
Normal file
157
.venv/Lib/site-packages/IPython/terminal/pt_inputhooks/osx.py
Normal file
@ -0,0 +1,157 @@
|
||||
"""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")) # type: ignore
|
||||
|
||||
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")) # type: ignore
|
||||
|
||||
CFFileDescriptorCreate = CoreFoundation.CFFileDescriptorCreate
|
||||
CFFileDescriptorCreate.restype = void_p
|
||||
CFFileDescriptorCreate.argtypes = [void_p, ctypes.c_int, ctypes.c_bool, void_p, 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)"""
|
||||
objc.objc_msgSend.argtypes = [void_p, void_p]
|
||||
return msg(C('NSApplication'), n('sharedApplication'))
|
||||
|
||||
|
||||
def _wake(NSApp):
|
||||
"""Wake the Application"""
|
||||
objc.objc_msgSend.argtypes = [
|
||||
void_p,
|
||||
void_p,
|
||||
void_p,
|
||||
void_p,
|
||||
void_p,
|
||||
void_p,
|
||||
void_p,
|
||||
void_p,
|
||||
void_p,
|
||||
void_p,
|
||||
void_p,
|
||||
]
|
||||
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
|
||||
)
|
||||
objc.objc_msgSend.argtypes = [void_p, void_p, void_p, void_p]
|
||||
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()
|
||||
objc.objc_msgSend.argtypes = [void_p, void_p, void_p]
|
||||
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())
|
||||
objc.objc_msgSend.argtypes = [void_p, void_p]
|
||||
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
|
85
.venv/Lib/site-packages/IPython/terminal/pt_inputhooks/qt.py
Normal file
85
.venv/Lib/site-packages/IPython/terminal/pt_inputhooks/qt.py
Normal file
@ -0,0 +1,85 @@
|
||||
import sys
|
||||
import os
|
||||
from IPython.external.qt_for_kernel import QtCore, QtGui, enum_helper
|
||||
from IPython import get_ipython
|
||||
|
||||
# If we create a QApplication, keep a reference to it so that it doesn't get
|
||||
# garbage collected.
|
||||
_appref = None
|
||||
_already_warned = False
|
||||
|
||||
|
||||
def _exec(obj):
|
||||
# exec on PyQt6, exec_ elsewhere.
|
||||
obj.exec() if hasattr(obj, "exec") else obj.exec_()
|
||||
|
||||
|
||||
def _reclaim_excepthook():
|
||||
shell = get_ipython()
|
||||
if shell is not None:
|
||||
sys.excepthook = shell.excepthook
|
||||
|
||||
|
||||
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
|
||||
try:
|
||||
QtCore.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
|
||||
except AttributeError: # Only for Qt>=5.6, <6.
|
||||
pass
|
||||
try:
|
||||
QtCore.QApplication.setHighDpiScaleFactorRoundingPolicy(
|
||||
QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough
|
||||
)
|
||||
except AttributeError: # Only for Qt>=5.14.
|
||||
pass
|
||||
_appref = app = QtGui.QApplication([" "])
|
||||
|
||||
# "reclaim" IPython sys.excepthook after event loop starts
|
||||
# without this, it defaults back to BaseIPythonApplication.excepthook
|
||||
# and exceptions in the Qt event loop are rendered without traceback
|
||||
# formatting and look like "bug in IPython".
|
||||
QtCore.QTimer.singleShot(0, _reclaim_excepthook)
|
||||
|
||||
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
|
||||
_exec(event_loop)
|
||||
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(), enum_helper("QtCore.QSocketNotifier.Type").Read
|
||||
)
|
||||
try:
|
||||
# connect the callback we care about before we turn it on
|
||||
# lambda is necessary as PyQT inspect the function signature to know
|
||||
# what arguments to pass to. See https://github.com/ipython/ipython/pull/12355
|
||||
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():
|
||||
_exec(event_loop)
|
||||
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
|
Reference in New Issue
Block a user