import importlib import os from typing import Tuple, Callable aliases = { 'qt4': 'qt', 'gtk2': 'gtk', } backends = [ "qt", "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 set_qt_api(gui): """Sets the `QT_API` environment variable if it isn't already set.""" qt_api = os.environ.get("QT_API", None) from IPython.external.qt_loaders import ( QT_API_PYQT, QT_API_PYQT5, QT_API_PYQT6, QT_API_PYSIDE, QT_API_PYSIDE2, QT_API_PYSIDE6, QT_API_PYQTv1, loaded_api, ) loaded = loaded_api() qt_env2gui = { QT_API_PYSIDE: "qt4", QT_API_PYQTv1: "qt4", QT_API_PYQT: "qt4", QT_API_PYSIDE2: "qt5", QT_API_PYQT5: "qt5", QT_API_PYSIDE6: "qt6", QT_API_PYQT6: "qt6", } if loaded is not None and gui != "qt": if qt_env2gui[loaded] != gui: print( f"Cannot switch Qt versions for this session; will use {qt_env2gui[loaded]}." ) return qt_env2gui[loaded] if qt_api is not None and gui != "qt": if qt_env2gui[qt_api] != gui: print( f'Request for "{gui}" will be ignored because `QT_API` ' f'environment variable is set to "{qt_api}"' ) return qt_env2gui[qt_api] else: if gui == "qt5": try: import PyQt5 # noqa os.environ["QT_API"] = "pyqt5" except ImportError: try: import PySide2 # noqa os.environ["QT_API"] = "pyside2" except ImportError: os.environ["QT_API"] = "pyqt5" elif gui == "qt6": try: import PyQt6 # noqa os.environ["QT_API"] = "pyqt6" except ImportError: try: import PySide6 # noqa os.environ["QT_API"] = "pyside6" except ImportError: os.environ["QT_API"] = "pyqt6" elif gui == "qt": # Don't set QT_API; let IPython logic choose the version. if "QT_API" in os.environ.keys(): del os.environ["QT_API"] else: print(f'Unrecognized Qt version: {gui}. Should be "qt5", "qt6", or "qt".') return # Import it now so we can figure out which version it is. from IPython.external.qt_for_kernel import QT_API return qt_env2gui[QT_API] def get_inputhook_name_and_func(gui: str) -> Tuple[str, Callable]: 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.startswith("qt"): gui = set_qt_api(gui) gui_mod = "qt" mod = importlib.import_module("IPython.terminal.pt_inputhooks." + gui_mod) return gui, mod.inputhook