diff --git a/IPython/external/qt_for_kernel.py b/IPython/external/qt_for_kernel.py index 8926cac..d2e7bd9 100644 --- a/IPython/external/qt_for_kernel.py +++ b/IPython/external/qt_for_kernel.py @@ -33,26 +33,36 @@ import sys from IPython.utils.version import check_version from IPython.external.qt_loaders import ( - load_qt, loaded_api, enum_factory, + load_qt, + loaded_api, + enum_factory, # QT6 - QT_API_PYQT6, QT_API_PYSIDE6, + QT_API_PYQT6, + QT_API_PYSIDE6, # QT5 - QT_API_PYQT5, QT_API_PYSIDE2, + QT_API_PYQT5, + QT_API_PYSIDE2, # QT4 - QT_API_PYQTv1, QT_API_PYQT, QT_API_PYSIDE, + QT_API_PYQTv1, + QT_API_PYQT, + QT_API_PYSIDE, # default - QT_API_PYQT_DEFAULT + QT_API_PYQT_DEFAULT, ) _qt_apis = ( # QT6 - QT_API_PYQT6, QT_API_PYSIDE6, + QT_API_PYQT6, + QT_API_PYSIDE6, # QT5 - QT_API_PYQT5, QT_API_PYSIDE2, + QT_API_PYQT5, + QT_API_PYSIDE2, # QT4 - QT_API_PYQTv1, QT_API_PYQT, QT_API_PYSIDE, + QT_API_PYQTv1, + QT_API_PYQT, + QT_API_PYSIDE, # default - QT_API_PYQT_DEFAULT + QT_API_PYQT_DEFAULT, ) @@ -105,7 +115,7 @@ def get_options(): QT_API_PYQT5, QT_API_PYSIDE2, QT_API_PYQT, - QT_API_PYSIDE + QT_API_PYSIDE, ] elif qt_api not in _qt_apis: raise RuntimeError("Invalid Qt API %r, valid values are: %r" % diff --git a/IPython/external/qt_loaders.py b/IPython/external/qt_loaders.py index 14ce409..7980535 100644 --- a/IPython/external/qt_loaders.py +++ b/IPython/external/qt_loaders.py @@ -25,25 +25,25 @@ QT_API_PYQT5 = 'pyqt5' QT_API_PYSIDE2 = 'pyside2' # Qt4 -QT_API_PYQT = 'pyqt' # Force version 2 -QT_API_PYQTv1 = 'pyqtv1' # Force version 2 -QT_API_PYSIDE = 'pyside' +QT_API_PYQT = "pyqt" # Force version 2 +QT_API_PYQTv1 = "pyqtv1" # Force version 2 +QT_API_PYSIDE = "pyside" -QT_API_PYQT_DEFAULT = 'pyqtdefault' # use system default for version 1 vs. 2 +QT_API_PYQT_DEFAULT = "pyqtdefault" # use system default for version 1 vs. 2 api_to_module = { # Qt6 QT_API_PYQT6: "PyQt6", QT_API_PYSIDE6: "PySide6", # Qt5 - QT_API_PYQT5: 'PyQt5', - QT_API_PYSIDE2: 'PySide2', + QT_API_PYQT5: "PyQt5", + QT_API_PYSIDE2: "PySide2", # Qt4 - QT_API_PYSIDE: 'PySide', - QT_API_PYQT: 'PyQt4', - QT_API_PYQTv1: 'PyQt4', + QT_API_PYSIDE: "PySide", + QT_API_PYQT: "PyQt4", + QT_API_PYQTv1: "PyQt4", # default - QT_API_PYQT_DEFAULT: 'PyQt6', + QT_API_PYQT_DEFAULT: "PyQt6", } @@ -104,12 +104,12 @@ def loaded_api(): return QT_API_PYQT5 elif sys.modules.get("PySide2.QtCore"): return QT_API_PYSIDE2 - elif sys.modules.get('PyQt4.QtCore'): + elif sys.modules.get("PyQt4.QtCore"): if qtapi_version() == 2: return QT_API_PYQT else: return QT_API_PYQTv1 - elif sys.modules.get('PySide.QtCore'): + elif sys.modules.get("PySide.QtCore"): return QT_API_PYSIDE return None @@ -246,6 +246,7 @@ def import_pyqt5(): api = QT_API_PYQT5 return QtCore, QtGuiCompat, QtSvg, api + def import_pyqt6(): """ Import PyQt6 @@ -260,7 +261,7 @@ def import_pyqt6(): QtCore.Slot = QtCore.pyqtSlot # Join QtGui and QtWidgets for Qt4 compatibility. - QtGuiCompat = types.ModuleType('QtGuiCompat') + QtGuiCompat = types.ModuleType("QtGuiCompat") QtGuiCompat.__dict__.update(QtGui.__dict__) QtGuiCompat.__dict__.update(QtWidgets.__dict__) @@ -293,6 +294,7 @@ def import_pyside2(): return QtCore, QtGuiCompat, QtSvg, QT_API_PYSIDE2 + def import_pyside6(): """ Import PySide6 @@ -302,7 +304,7 @@ def import_pyside6(): from PySide6 import QtGui, QtCore, QtSvg, QtWidgets, QtPrintSupport # Join QtGui and QtWidgets for Qt4 compatibility. - QtGuiCompat = types.ModuleType('QtGuiCompat') + QtGuiCompat = types.ModuleType("QtGuiCompat") QtGuiCompat.__dict__.update(QtGui.__dict__) QtGuiCompat.__dict__.update(QtWidgets.__dict__) QtGuiCompat.__dict__.update(QtPrintSupport.__dict__) @@ -388,6 +390,7 @@ def load_qt(api_options): def enum_factory(QT_API, QtCore): """Construct an enum helper to account for PyQt5 <-> PyQt6 changes.""" + @lru_cache(None) def _enum(name): # foo.bar.Enum.Entry (PyQt6) <=> foo.bar.Entry (non-PyQt6). diff --git a/IPython/terminal/pt_inputhooks/__init__.py b/IPython/terminal/pt_inputhooks/__init__.py index 095881c..8917baf 100644 --- a/IPython/terminal/pt_inputhooks/__init__.py +++ b/IPython/terminal/pt_inputhooks/__init__.py @@ -7,13 +7,19 @@ aliases = { } backends = [ - 'qt', 'qt4', 'qt5', 'qt6', - 'gtk', 'gtk2', 'gtk3', - 'tk', - 'wx', - 'pyglet', 'glut', - 'osx', - 'asyncio' + "qt", + "qt4", + "qt5", + "qt6", + "gtk", + "gtk2", + "gtk3", + "tk", + "wx", + "pyglet", + "glut", + "osx", + "asyncio", ] registered = {} @@ -44,12 +50,12 @@ def get_inputhook_name_and_func(gui): 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' + 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 diff --git a/IPython/terminal/pt_inputhooks/qt.py b/IPython/terminal/pt_inputhooks/qt.py index 6e9b120..bc34f70 100644 --- a/IPython/terminal/pt_inputhooks/qt.py +++ b/IPython/terminal/pt_inputhooks/qt.py @@ -38,13 +38,13 @@ def inputhook(context): ) return try: - QtCore.QApplication.setAttribute( - QtCore.Qt.AA_EnableHighDpiScaling) + QtCore.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling) except AttributeError: # Only for Qt>=5.6, <6. pass try: QtCore.QApplication.setHighDpiScaleFactorRoundingPolicy( - QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough) + QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough + ) except AttributeError: # Only for Qt>=5.14. pass _appref = app = QtGui.QApplication([" "]) @@ -70,8 +70,7 @@ def inputhook(context): # 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 + context.fileno(), enum_helper("QtCore.QSocketNotifier.Type").Read ) try: # connect the callback we care about before we turn it on