##// END OF EJS Templates
Formatting
Emilio Graff -
Show More
@@ -1,147 +1,147 b''
1 1 import importlib
2 2 import os
3 3
4 4 aliases = {
5 5 'qt4': 'qt',
6 6 'gtk2': 'gtk',
7 7 }
8 8
9 9 backends = [
10 10 "qt",
11 11 "qt4",
12 12 "qt5",
13 13 "qt6",
14 14 "gtk",
15 15 "gtk2",
16 16 "gtk3",
17 17 "gtk4",
18 18 "tk",
19 19 "wx",
20 20 "pyglet",
21 21 "glut",
22 22 "osx",
23 23 "asyncio",
24 24 ]
25 25
26 26 registered = {}
27 27
28 28 def register(name, inputhook):
29 29 """Register the function *inputhook* as an event loop integration."""
30 30 registered[name] = inputhook
31 31
32 32
33 33 class UnknownBackend(KeyError):
34 34 def __init__(self, name):
35 35 self.name = name
36 36
37 37 def __str__(self):
38 38 return ("No event loop integration for {!r}. "
39 39 "Supported event loops are: {}").format(self.name,
40 40 ', '.join(backends + sorted(registered)))
41 41
42 42
43 43 def set_qt_api(gui):
44 44 """Sets the `QT_API` environment variable if it isn't already set."""
45 45
46 46 qt_api = os.environ.get("QT_API", None)
47 47
48 48 from IPython.external.qt_loaders import (
49 49 QT_API_PYQT,
50 50 QT_API_PYQT5,
51 51 QT_API_PYQT6,
52 52 QT_API_PYSIDE,
53 53 QT_API_PYSIDE2,
54 54 QT_API_PYSIDE6,
55 55 QT_API_PYQTv1,
56 56 loaded_api,
57 57 )
58 58
59 59 loaded = loaded_api()
60 60
61 61 qt_env2gui = {
62 QT_API_PYSIDE: 'qt4',
63 QT_API_PYQTv1: 'qt4',
64 QT_API_PYQT: 'qt4',
65 QT_API_PYSIDE2: 'qt5',
66 QT_API_PYQT5: 'qt5',
67 QT_API_PYSIDE6: 'qt6',
68 QT_API_PYQT6: 'qt6',
62 QT_API_PYSIDE: "qt4",
63 QT_API_PYQTv1: "qt4",
64 QT_API_PYQT: "qt4",
65 QT_API_PYSIDE2: "qt5",
66 QT_API_PYQT5: "qt5",
67 QT_API_PYSIDE6: "qt6",
68 QT_API_PYQT6: "qt6",
69 69 }
70 if loaded is not None and gui != 'qt':
70 if loaded is not None and gui != "qt":
71 71 if qt_env2gui[loaded] != gui:
72 72 raise ImportError(
73 f'Cannot switch Qt versions for this session; must use {qt_env2gui[loaded]}.'
73 f"Cannot switch Qt versions for this session; must use {qt_env2gui[loaded]}."
74 74 )
75 75
76 if qt_api is not None and gui != 'qt':
76 if qt_api is not None and gui != "qt":
77 77 if qt_env2gui[qt_api] != gui:
78 78 print(
79 79 f'Request for "{gui}" will be ignored because `QT_API` '
80 80 f'environment variable is set to "{qt_api}"'
81 81 )
82 82 else:
83 83 # NOTE: 'qt4' is not selectable because it's set as an alias for 'qt'; see `aliases` above.
84 84 if gui == "qt4":
85 85 try:
86 86 import PyQt # noqa
87 87
88 88 os.environ["QT_API"] = "pyqt"
89 89 except ImportError:
90 90 try:
91 91 import PySide # noqa
92 92
93 93 os.environ["QT_API"] = "pyside"
94 94 except ImportError:
95 95 # Neither implementation installed; set it to something so IPython gives an error
96 96 os.environ["QT_API"] = "pyqt"
97 97 elif gui == "qt5":
98 98 try:
99 99 import PyQt5 # noqa
100 100
101 101 os.environ["QT_API"] = "pyqt5"
102 102 except ImportError:
103 103 try:
104 104 import PySide2 # noqa
105 105
106 106 os.environ["QT_API"] = "pyside2"
107 107 except ImportError:
108 108 os.environ["QT_API"] = "pyqt5"
109 109 elif gui == "qt6":
110 110 try:
111 111 import PyQt6 # noqa
112 112
113 113 os.environ["QT_API"] = "pyqt6"
114 114 except ImportError:
115 115 try:
116 116 import PySide6 # noqa
117 117
118 118 os.environ["QT_API"] = "pyside6"
119 119 except ImportError:
120 120 os.environ["QT_API"] = "pyqt6"
121 121 elif gui == "qt":
122 122 # Don't set QT_API; let IPython logic choose the version.
123 123 if "QT_API" in os.environ.keys():
124 124 del os.environ["QT_API"]
125 125 else:
126 126 raise ValueError(
127 127 f'Unrecognized Qt version: {gui}. Should be "qt4", "qt5", "qt6", or "qt".'
128 128 )
129 129
130 130
131 131 def get_inputhook_name_and_func(gui):
132 132 if gui in registered:
133 133 return gui, registered[gui]
134 134
135 135 if gui not in backends:
136 136 raise UnknownBackend(gui)
137 137
138 138 if gui in aliases:
139 139 return get_inputhook_name_and_func(aliases[gui])
140 140
141 141 gui_mod = gui
142 142 if gui.startswith("qt"):
143 143 set_qt_api(gui)
144 144 gui_mod = "qt"
145 145
146 146 mod = importlib.import_module("IPython.terminal.pt_inputhooks." + gui_mod)
147 147 return gui, mod.inputhook
@@ -1,48 +1,50 b''
1 1 import os
2 2 import importlib
3 3
4 4 import pytest
5 5
6 6 from IPython.terminal.pt_inputhooks import set_qt_api, get_inputhook_name_and_func
7 7
8 8
9 9 guis_avail = []
10 10
11 11
12 12 def _get_qt_vers():
13 13 """If any version of Qt is available, this will populate `guis_avail` with 'qt' and 'qtx'. Due
14 14 to the import mechanism, we can't import multiple versions of Qt in one session."""
15 for gui in ['qt', 'qt6', 'qt5', 'qt4']:
16 print(f'Trying {gui}')
15 for gui in ["qt", "qt6", "qt5", "qt4"]:
16 print(f"Trying {gui}")
17 17 try:
18 18 set_qt_api(gui)
19 19 importlib.import_module("IPython.terminal.pt_inputhooks.qt")
20 20 guis_avail.append(gui)
21 if 'QT_API' in os.environ.keys():
22 del os.environ['QT_API']
21 if "QT_API" in os.environ.keys():
22 del os.environ["QT_API"]
23 23 except ImportError:
24 24 pass # that version of Qt isn't available.
25 25 except RuntimeError:
26 26 pass # the version of IPython doesn't know what to do with this Qt version.
27 27
28 28
29 29 _get_qt_vers()
30 30
31 31
32 @pytest.mark.skipif(len(guis_avail) == 0, reason='No viable version of PyQt or PySide installed.')
32 @pytest.mark.skipif(
33 len(guis_avail) == 0, reason="No viable version of PyQt or PySide installed."
34 )
33 35 def test_inputhook_qt():
34 36 gui = guis_avail[0]
35 37
36 38 # Choose a qt version and get the input hook function. This will import Qt...
37 39 get_inputhook_name_and_func(gui)
38 40
39 41 # ...and now we're stuck with this version of Qt for good; can't switch.
40 for not_gui in ['qt6', 'qt5', 'qt4']:
42 for not_gui in ["qt6", "qt5", "qt4"]:
41 43 if not_gui not in guis_avail:
42 44 break
43 45
44 46 with pytest.raises(ImportError):
45 47 get_inputhook_name_and_func(not_gui)
46 48
47 49 # A gui of 'qt' means "best available", or in this case, the last one that was used.
48 get_inputhook_name_and_func('qt')
50 get_inputhook_name_and_func("qt")
General Comments 0
You need to be logged in to leave comments. Login now