Coverage for larch/shell.py: 0%

116 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2024-10-16 21:04 +0000

1#!/usr/bin/env python 

2""" 

3Larch command-line shell 

4""" 

5import cmd 

6import os 

7import sys 

8import signal 

9from .interpreter import Interpreter 

10 

11from .site_config import history_file 

12from .version import make_banner 

13from .larchlib import StdWriter 

14from .utils import uname 

15 

16HAS_READLINE = False 

17try: 

18 import readline 

19 HAS_READLINE = True 

20except ImportError: 

21 pass 

22 

23HAS_WXPYTHON = False 

24try: 

25 import wx 

26 HAS_WXPYTHON = True 

27except ImportError: 

28 wx = None 

29 

30 

31class Shell(cmd.Cmd): 

32 """command shell for Larch""" 

33 def __init__(self, completekey='tab', debug=False, quiet=False, 

34 stdin=None, stdout=None, banner_msg=None, 

35 maxhist=25000, with_wx=False): 

36 

37 self.debug = debug 

38 cmd.Cmd.__init__(self,completekey='tab') 

39 if stdin is not None: 

40 sys.stdin = stdin 

41 if stdout is not None: 

42 sys.stdout = stdout 

43 self.stdin = sys.stdin 

44 self.stdout = sys.stdout 

45 

46 if HAS_READLINE: 

47 try: 

48 readline.read_history_file(history_file) 

49 except IOError: 

50 print(f'could not read history from {history_file}') 

51 

52 

53 self.larch = Interpreter(historyfile=history_file, 

54 maxhistory=maxhist) 

55 self.larch.writer = StdWriter(_larch=self.larch) 

56 

57 if with_wx and HAS_WXPYTHON: 

58 symtable = self.larch.symtable 

59 try: 

60 from .wxlib import LarchWxApp 

61 app = LarchWxApp(redirect=False, clearSigInt=False) 

62 except SystemExit: 

63 with_wx = False 

64 

65 symtable.set_symbol('_sys.wx.wxapp', app) 

66 symtable.set_symbol('_sys.wx.force_wxupdate', False) 

67 symtable.set_symbol('_sys.wx.parent', None) 

68 

69 from .wxlib import inputhook 

70 symtable.set_symbol('_sys.wx.inputhook', inputhook) 

71 if uname == 'darwin': 

72 symtable.set_symbol('_sys.wx.ping', inputhook.ping_darwin) 

73 else: 

74 symtable.set_symbol('_sys.wx.ping', inputhook.ping) 

75 

76 inputhook.ON_INTERRUPT = self.onCtrlC 

77 inputhook.WXLARCH_SYM = symtable 

78 

79 signal.signal(signal.SIGINT, self.onCtrlC) 

80 self.prompt = self.larch.input.prompt 

81 writer = self.larch.writer 

82 self.color_writer = (uname != 'win' and hasattr(writer, 'set_textstyle')) 

83 if not quiet: 

84 if banner_msg is None: 

85 banner_msg = make_banner(show_libraries=['numpy', 'scipy', 'matplotlib', 'h5py', 

86 'lmfit', 'xraydb', 'wx','wxmplot']) 

87 if self.color_writer: 

88 writer.set_textstyle('error') 

89 writer.write(banner_msg) 

90 writer.write("\n") 

91 if self.color_writer: 

92 writer.set_textstyle('text') 

93 

94 self.larch_execute = self.default 

95 self.larch.run_init_scripts() 

96 

97 def onCtrlC(self, *args, **kws): 

98 self.larch.symtable.set_symbol('_sys.wx.keyboard_interrupt', True) 

99 return 0 

100 

101 def on_exit(self, text=None): 

102 "exit" 

103 trim_last = False 

104 if text is not None: 

105 trim_last = text.strip() in ('quit', 'exit') 

106 try: 

107 self.larch.input.history.save(trim_last=trim_last) 

108 except PermissionError: 

109 print("Warning: could not save session history -- permission denied") 

110 self.larch.symtable._plotter.close_all_displays() 

111 sys.exit() 

112 

113 def do_exit(self, text): 

114 "exit" 

115 self.on_exit(text=text) 

116 

117 def do_quit(self, text): 

118 "quit" 

119 self.on_exit(text=text) 

120 

121 def emptyline(self): 

122 pass 

123 

124 def onecmd(self, line): 

125 "single command" 

126 return self.default(line) 

127 

128 def do_help(self, arg): 

129 "help" 

130 if arg.startswith('(') and arg.endswith(')'): 

131 arg = arg[1:-1] 

132 elif arg.startswith("'") and arg.endswith("'"): 

133 arg = arg[1:-1] 

134 elif arg.startswith('"') and arg.endswith('"'): 

135 arg = arg[1:-1] 

136 self.default(f"help({arg})") 

137 

138 def do_shell(self, txt): 

139 "shell command" 

140 os.system(txt) 

141 

142 def default(self, line): 

143 "default handler" 

144 if line.strip() in ('quit', 'exit', 'quit()', 'exit()', 'EOF'): 

145 self.on_exit(line) 

146 ret = self.larch.eval(line, fname='<stdin>', lineno=0) 

147 if self.larch.error: 

148 self.larch.input.clear() 

149 if self.color_writer: 

150 self.larch.writer.set_textstyle('error') 

151 self.larch.show_errors() 

152 if self.color_writer: 

153 self.larch.writer.set_textstyle('line') 

154 if ret is not None: 

155 self.larch.writer.write("%s\n" % repr(ret)) 

156 

157 self.larch.writer.flush() 

158 self.prompt = self.larch.input.next_prompt