Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/IPython/terminal/pt_inputhooks/__init__.py: 19%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

67 statements  

1import importlib 

2import os 

3from typing import Tuple 

4from collections.abc import Callable 

5 

6aliases = { 

7 'qt4': 'qt', 

8 'gtk2': 'gtk', 

9} 

10 

11backends = [ 

12 "qt", 

13 "qt5", 

14 "qt6", 

15 "gtk", 

16 "gtk2", 

17 "gtk3", 

18 "gtk4", 

19 "tk", 

20 "wx", 

21 "pyglet", 

22 "glut", 

23 "osx", 

24 "asyncio", 

25] 

26 

27registered = {} 

28 

29def register(name, inputhook): 

30 """Register the function *inputhook* as an event loop integration.""" 

31 registered[name] = inputhook 

32 

33 

34class UnknownBackend(KeyError): 

35 def __init__(self, name): 

36 self.name = name 

37 

38 def __str__(self): 

39 return ("No event loop integration for {!r}. " 

40 "Supported event loops are: {}").format(self.name, 

41 ', '.join(backends + sorted(registered))) 

42 

43 

44def set_qt_api(gui): 

45 """Sets the `QT_API` environment variable if it isn't already set.""" 

46 

47 qt_api = os.environ.get("QT_API", None) 

48 

49 from IPython.external.qt_loaders import ( 

50 QT_API_PYQT, 

51 QT_API_PYQT5, 

52 QT_API_PYQT6, 

53 QT_API_PYSIDE, 

54 QT_API_PYSIDE2, 

55 QT_API_PYSIDE6, 

56 QT_API_PYQTv1, 

57 loaded_api, 

58 ) 

59 

60 loaded = loaded_api() 

61 

62 qt_env2gui = { 

63 QT_API_PYSIDE: "qt4", 

64 QT_API_PYQTv1: "qt4", 

65 QT_API_PYQT: "qt4", 

66 QT_API_PYSIDE2: "qt5", 

67 QT_API_PYQT5: "qt5", 

68 QT_API_PYSIDE6: "qt6", 

69 QT_API_PYQT6: "qt6", 

70 } 

71 if loaded is not None and gui != "qt": 

72 if qt_env2gui[loaded] != gui: 

73 print( 

74 f"Cannot switch Qt versions for this session; will use {qt_env2gui[loaded]}." 

75 ) 

76 return qt_env2gui[loaded] 

77 

78 if qt_api is not None and gui != "qt": 

79 if qt_env2gui[qt_api] != gui: 

80 print( 

81 f'Request for "{gui}" will be ignored because `QT_API` ' 

82 f'environment variable is set to "{qt_api}"' 

83 ) 

84 return qt_env2gui[qt_api] 

85 else: 

86 if gui == "qt5": 

87 try: 

88 import PyQt5 # noqa 

89 

90 os.environ["QT_API"] = "pyqt5" 

91 except ImportError: 

92 try: 

93 import PySide2 # noqa 

94 

95 os.environ["QT_API"] = "pyside2" 

96 except ImportError: 

97 os.environ["QT_API"] = "pyqt5" 

98 elif gui == "qt6": 

99 try: 

100 import PyQt6 # noqa 

101 

102 os.environ["QT_API"] = "pyqt6" 

103 except ImportError: 

104 try: 

105 import PySide6 # noqa 

106 

107 os.environ["QT_API"] = "pyside6" 

108 except ImportError: 

109 os.environ["QT_API"] = "pyqt6" 

110 elif gui == "qt": 

111 # Don't set QT_API; let IPython logic choose the version. 

112 if "QT_API" in os.environ.keys(): 

113 del os.environ["QT_API"] 

114 else: 

115 print(f'Unrecognized Qt version: {gui}. Should be "qt5", "qt6", or "qt".') 

116 return 

117 

118 # Import it now so we can figure out which version it is. 

119 from IPython.external.qt_for_kernel import QT_API 

120 

121 return qt_env2gui[QT_API] 

122 

123 

124def get_inputhook_name_and_func(gui: str) -> Tuple[str, Callable]: 

125 if gui in registered: 

126 return gui, registered[gui] 

127 

128 if gui not in backends: 

129 raise UnknownBackend(gui) 

130 

131 if gui in aliases: 

132 return get_inputhook_name_and_func(aliases[gui]) 

133 

134 gui_mod = gui 

135 if gui.startswith("qt"): 

136 gui = set_qt_api(gui) 

137 gui_mod = "qt" 

138 

139 mod = importlib.import_module("IPython.terminal.pt_inputhooks." + gui_mod) 

140 return gui, mod.inputhook