Show More
@@ -10,6 +10,7 b' be accessed directly from the outside' | |||
|
10 | 10 | """ |
|
11 | 11 | import importlib.abc |
|
12 | 12 | import sys |
|
13 | import os | |
|
13 | 14 | import types |
|
14 | 15 | from functools import partial, lru_cache |
|
15 | 16 | import operator |
@@ -368,6 +369,10 b' def load_qt(api_options):' | |||
|
368 | 369 | commit_api(api) |
|
369 | 370 | return result |
|
370 | 371 | else: |
|
372 | # Clear the environment variable since it doesn't work. | |
|
373 | if "QT_API" in os.environ: | |
|
374 | del os.environ["QT_API"] | |
|
375 | ||
|
371 | 376 | raise ImportError( |
|
372 | 377 | """ |
|
373 | 378 | Could not load requested Qt binding. Please ensure that |
@@ -913,10 +913,19 b' class TerminalInteractiveShell(InteractiveShell):' | |||
|
913 | 913 | |
|
914 | 914 | active_eventloop = None |
|
915 | 915 | def enable_gui(self, gui=None): |
|
916 | if self._inputhook is None and gui is None: | |
|
917 | print("No event loop hook running.") | |
|
918 | return | |
|
919 | ||
|
916 | 920 | if self._inputhook is not None and gui is not None: |
|
917 |
|
|
|
918 |
f"Shell |
|
|
921 | print( | |
|
922 | f"Shell is already running a gui event loop for {self.active_eventloop}. " | |
|
923 | "Call with no arguments to disable the current loop." | |
|
919 | 924 | ) |
|
925 | return | |
|
926 | if self._inputhook is not None and gui is None: | |
|
927 | self.active_eventloop = self._inputhook = None | |
|
928 | ||
|
920 | 929 | if gui and (gui not in {"inline", "webagg"}): |
|
921 | 930 | # This hook runs with each cycle of the `prompt_toolkit`'s event loop. |
|
922 | 931 | self.active_eventloop, self._inputhook = get_inputhook_name_and_func(gui) |
@@ -934,15 +943,18 b' class TerminalInteractiveShell(InteractiveShell):' | |||
|
934 | 943 | # same event loop as the rest of the code. don't use an actual |
|
935 | 944 | # input hook. (Asyncio is not made for nesting event loops.) |
|
936 | 945 | self.pt_loop = get_asyncio_loop() |
|
946 | print("Installed asyncio event loop hook.") | |
|
937 | 947 | |
|
938 | 948 | elif self._inputhook: |
|
939 | 949 | # If an inputhook was set, create a new asyncio event loop with |
|
940 | 950 | # this inputhook for the prompt. |
|
941 | 951 | self.pt_loop = new_eventloop_with_inputhook(self._inputhook) |
|
952 | print(f"Installed {self.active_eventloop} event loop hook.") | |
|
942 | 953 | else: |
|
943 | 954 | # When there's no inputhook, run the prompt in a separate |
|
944 | 955 | # asyncio event loop. |
|
945 | 956 | self.pt_loop = asyncio.new_event_loop() |
|
957 | print("GUI event loop hook disabled.") | |
|
946 | 958 | |
|
947 | 959 | # Run !system commands directly, not through pipes, so terminal programs |
|
948 | 960 | # work correctly. |
@@ -69,9 +69,9 b' def set_qt_api(gui):' | |||
|
69 | 69 | if loaded is not None and gui != "qt": |
|
70 | 70 | if qt_env2gui[loaded] != gui: |
|
71 | 71 | print( |
|
72 |
f"Cannot switch Qt versions for this session; |
|
|
72 | f"Cannot switch Qt versions for this session; will use {qt_env2gui[loaded]}." | |
|
73 | 73 | ) |
|
74 | return | |
|
74 | return qt_env2gui[loaded] | |
|
75 | 75 | |
|
76 | 76 | if qt_api is not None and gui != "qt": |
|
77 | 77 | if qt_env2gui[qt_api] != gui: |
@@ -79,6 +79,7 b' def set_qt_api(gui):' | |||
|
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 | return qt_env2gui[qt_api] | |
|
82 | 83 | else: |
|
83 | 84 | if gui == "qt5": |
|
84 | 85 | try: |
@@ -112,6 +113,11 b' def set_qt_api(gui):' | |||
|
112 | 113 | print(f'Unrecognized Qt version: {gui}. Should be "qt5", "qt6", or "qt".') |
|
113 | 114 | return |
|
114 | 115 | |
|
116 | # Import it now so we can figure out which version it is. | |
|
117 | from IPython.external.qt_for_kernel import QT_API | |
|
118 | ||
|
119 | return qt_env2gui[QT_API] | |
|
120 | ||
|
115 | 121 | |
|
116 | 122 | def get_inputhook_name_and_func(gui): |
|
117 | 123 | if gui in registered: |
@@ -125,7 +131,7 b' def get_inputhook_name_and_func(gui):' | |||
|
125 | 131 | |
|
126 | 132 | gui_mod = gui |
|
127 | 133 | if gui.startswith("qt"): |
|
128 | set_qt_api(gui) | |
|
134 | gui = set_qt_api(gui) | |
|
129 | 135 | gui_mod = "qt" |
|
130 | 136 | |
|
131 | 137 | mod = importlib.import_module("IPython.terminal.pt_inputhooks." + gui_mod) |
@@ -33,18 +33,18 b' _get_qt_vers()' | |||
|
33 | 33 | len(guis_avail) == 0, reason="No viable version of PyQt or PySide installed." |
|
34 | 34 | ) |
|
35 | 35 | def test_inputhook_qt(): |
|
36 | gui = guis_avail[0] | |
|
37 | ||
|
38 | # Choose a qt version and get the input hook function. This will import Qt... | |
|
39 | get_inputhook_name_and_func(gui) | |
|
40 | ||
|
41 | # ...and now we're stuck with this version of Qt for good; can't switch. | |
|
42 | for not_gui in ["qt6", "qt5"]: | |
|
43 | if not_gui not in guis_avail: | |
|
44 | break | |
|
45 | ||
|
46 | with pytest.raises(ImportError): | |
|
47 | get_inputhook_name_and_func(not_gui) | |
|
48 | ||
|
49 | # A gui of 'qt' means "best available", or in this case, the last one that was used. | |
|
50 | get_inputhook_name_and_func("qt") | |
|
36 | # Choose the "best" Qt version. | |
|
37 | gui_ret, _ = get_inputhook_name_and_func("qt") | |
|
38 | ||
|
39 | assert gui_ret != "qt" # you get back the specific version that was loaded. | |
|
40 | assert gui_ret in guis_avail | |
|
41 | ||
|
42 | if len(guis_avail) > 2: | |
|
43 | # ...and now we're stuck with this version of Qt for good; can't switch. | |
|
44 | for not_gui in ["qt6", "qt5"]: | |
|
45 | if not_gui != gui_ret: | |
|
46 | break | |
|
47 | # Try to import the other gui; it won't work. | |
|
48 | gui_ret2, _ = get_inputhook_name_and_func(not_gui) | |
|
49 | assert gui_ret2 == gui_ret | |
|
50 | assert gui_ret2 != not_gui |
General Comments 0
You need to be logged in to leave comments.
Login now