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