##// END OF EJS Templates
protect execution_count from longs returned by json
MinRK -
Show More
@@ -1,252 +1,252 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Frontend of ipython working with python-zmq
2 """Frontend of ipython working with python-zmq
3
3
4 Ipython's frontend, is a ipython interface that send request to kernel and proccess the kernel's outputs.
4 Ipython's frontend, is a ipython interface that send request to kernel and proccess the kernel's outputs.
5
5
6 For more details, see the ipython-zmq design
6 For more details, see the ipython-zmq design
7 """
7 """
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2011 The IPython Development Team
9 # Copyright (C) 2011 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 from __future__ import print_function
18 from __future__ import print_function
19
19
20 import bdb
20 import bdb
21 import sys
21 import sys
22
22
23 from Queue import Empty
23 from Queue import Empty
24
24
25 from IPython.core.alias import AliasManager, AliasError
25 from IPython.core.alias import AliasManager, AliasError
26 from IPython.utils.warn import warn, error, fatal
26 from IPython.utils.warn import warn, error, fatal
27 from IPython.utils import io
27 from IPython.utils import io
28
28
29 from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
29 from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
30 from IPython.frontend.zmqterminal.completer import ZMQCompleter
30 from IPython.frontend.zmqterminal.completer import ZMQCompleter
31
31
32
32
33 class ZMQTerminalInteractiveShell(TerminalInteractiveShell):
33 class ZMQTerminalInteractiveShell(TerminalInteractiveShell):
34 """A subclass of TerminalInteractiveShell that """
34 """A subclass of TerminalInteractiveShell that """
35
35
36 def __init__(self, *args, **kwargs):
36 def __init__(self, *args, **kwargs):
37 self.km = kwargs.pop('kernel_manager')
37 self.km = kwargs.pop('kernel_manager')
38 self.session_id = self.km.session.session
38 self.session_id = self.km.session.session
39 super(ZMQTerminalInteractiveShell, self).__init__(*args, **kwargs)
39 super(ZMQTerminalInteractiveShell, self).__init__(*args, **kwargs)
40
40
41 def init_completer(self):
41 def init_completer(self):
42 """Initialize the completion machinery.
42 """Initialize the completion machinery.
43
43
44 This creates completion machinery that can be used by client code,
44 This creates completion machinery that can be used by client code,
45 either interactively in-process (typically triggered by the readline
45 either interactively in-process (typically triggered by the readline
46 library), programatically (such as in test suites) or out-of-prcess
46 library), programatically (such as in test suites) or out-of-prcess
47 (typically over the network by remote frontends).
47 (typically over the network by remote frontends).
48 """
48 """
49 from IPython.core.completerlib import (module_completer,
49 from IPython.core.completerlib import (module_completer,
50 magic_run_completer, cd_completer)
50 magic_run_completer, cd_completer)
51
51
52 self.Completer = ZMQCompleter(self, self.km)
52 self.Completer = ZMQCompleter(self, self.km)
53
53
54
54
55 self.set_hook('complete_command', module_completer, str_key = 'import')
55 self.set_hook('complete_command', module_completer, str_key = 'import')
56 self.set_hook('complete_command', module_completer, str_key = 'from')
56 self.set_hook('complete_command', module_completer, str_key = 'from')
57 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
57 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
58 self.set_hook('complete_command', cd_completer, str_key = '%cd')
58 self.set_hook('complete_command', cd_completer, str_key = '%cd')
59
59
60 # Only configure readline if we truly are using readline. IPython can
60 # Only configure readline if we truly are using readline. IPython can
61 # do tab-completion over the network, in GUIs, etc, where readline
61 # do tab-completion over the network, in GUIs, etc, where readline
62 # itself may be absent
62 # itself may be absent
63 if self.has_readline:
63 if self.has_readline:
64 self.set_readline_completer()
64 self.set_readline_completer()
65
65
66 def run_cell(self, cell, store_history=True):
66 def run_cell(self, cell, store_history=True):
67 """Run a complete IPython cell.
67 """Run a complete IPython cell.
68
68
69 Parameters
69 Parameters
70 ----------
70 ----------
71 cell : str
71 cell : str
72 The code (including IPython code such as %magic functions) to run.
72 The code (including IPython code such as %magic functions) to run.
73 store_history : bool
73 store_history : bool
74 If True, the raw and translated cell will be stored in IPython's
74 If True, the raw and translated cell will be stored in IPython's
75 history. For user code calling back into IPython's machinery, this
75 history. For user code calling back into IPython's machinery, this
76 should be set to False.
76 should be set to False.
77 """
77 """
78 if (not cell) or cell.isspace():
78 if (not cell) or cell.isspace():
79 return
79 return
80
80
81 # shell_channel.execute takes 'hidden', which is the inverse of store_hist
81 # shell_channel.execute takes 'hidden', which is the inverse of store_hist
82 msg_id = self.km.shell_channel.execute(cell, not store_history)
82 msg_id = self.km.shell_channel.execute(cell, not store_history)
83 while not self.km.shell_channel.msg_ready():
83 while not self.km.shell_channel.msg_ready():
84 try:
84 try:
85 self.handle_stdin_request(timeout=0.05)
85 self.handle_stdin_request(timeout=0.05)
86 except Empty:
86 except Empty:
87 pass
87 pass
88 self.handle_execute_reply(msg_id)
88 self.handle_execute_reply(msg_id)
89
89
90 #-----------------
90 #-----------------
91 # message handlers
91 # message handlers
92 #-----------------
92 #-----------------
93
93
94 def handle_execute_reply(self, msg_id):
94 def handle_execute_reply(self, msg_id):
95 msg = self.km.shell_channel.get_msg()
95 msg = self.km.shell_channel.get_msg()
96 if msg["parent_header"]["msg_id"] == msg_id:
96 if msg["parent_header"]["msg_id"] == msg_id:
97 if msg["content"]["status"] == 'ok' :
97 if msg["content"]["status"] == 'ok' :
98 self.handle_iopub()
98 self.handle_iopub()
99
99
100 elif msg["content"]["status"] == 'error':
100 elif msg["content"]["status"] == 'error':
101 for frame in msg["content"]["traceback"]:
101 for frame in msg["content"]["traceback"]:
102 print(frame, file=io.stderr)
102 print(frame, file=io.stderr)
103
103
104 self.execution_count = msg["content"]["execution_count"] + 1
104 self.execution_count = int(msg["content"]["execution_count"] + 1)
105
105
106
106
107 def handle_iopub(self):
107 def handle_iopub(self):
108 """ Method to procces subscribe channel's messages
108 """ Method to procces subscribe channel's messages
109
109
110 This method reads a message and processes the content in different
110 This method reads a message and processes the content in different
111 outputs like stdout, stderr, pyout and status
111 outputs like stdout, stderr, pyout and status
112
112
113 Arguments:
113 Arguments:
114 sub_msg: message receive from kernel in the sub socket channel
114 sub_msg: message receive from kernel in the sub socket channel
115 capture by kernel manager.
115 capture by kernel manager.
116 """
116 """
117 while self.km.sub_channel.msg_ready():
117 while self.km.sub_channel.msg_ready():
118 sub_msg = self.km.sub_channel.get_msg()
118 sub_msg = self.km.sub_channel.get_msg()
119 msg_type = sub_msg['header']['msg_type']
119 msg_type = sub_msg['header']['msg_type']
120 if self.session_id == sub_msg['parent_header']['session']:
120 if self.session_id == sub_msg['parent_header']['session']:
121 if msg_type == 'status' :
121 if msg_type == 'status' :
122 if sub_msg["content"]["execution_state"] == "busy" :
122 if sub_msg["content"]["execution_state"] == "busy" :
123 pass
123 pass
124
124
125 elif msg_type == 'stream' :
125 elif msg_type == 'stream' :
126 if sub_msg["content"]["name"] == "stdout":
126 if sub_msg["content"]["name"] == "stdout":
127 print(sub_msg["content"]["data"], file=io.stdout, end="")
127 print(sub_msg["content"]["data"], file=io.stdout, end="")
128 io.stdout.flush()
128 io.stdout.flush()
129 elif sub_msg["content"]["name"] == "stderr" :
129 elif sub_msg["content"]["name"] == "stderr" :
130 print(sub_msg["content"]["data"], file=io.stderr, end="")
130 print(sub_msg["content"]["data"], file=io.stderr, end="")
131 io.stderr.flush()
131 io.stderr.flush()
132
132
133 elif msg_type == 'pyout':
133 elif msg_type == 'pyout':
134 format_dict = sub_msg["content"]["data"]
134 format_dict = sub_msg["content"]["data"]
135 # taken from DisplayHook.__call__:
135 # taken from DisplayHook.__call__:
136 hook = self.displayhook
136 hook = self.displayhook
137 hook.start_displayhook()
137 hook.start_displayhook()
138 hook.write_output_prompt()
138 hook.write_output_prompt()
139 hook.write_format_data(format_dict)
139 hook.write_format_data(format_dict)
140 hook.log_output(format_dict)
140 hook.log_output(format_dict)
141 hook.finish_displayhook()
141 hook.finish_displayhook()
142
142
143 def handle_stdin_request(self, timeout=0.1):
143 def handle_stdin_request(self, timeout=0.1):
144 """ Method to capture raw_input
144 """ Method to capture raw_input
145 """
145 """
146 msg_rep = self.km.stdin_channel.get_msg(timeout=timeout)
146 msg_rep = self.km.stdin_channel.get_msg(timeout=timeout)
147 if self.session_id == msg_rep["parent_header"]["session"] :
147 if self.session_id == msg_rep["parent_header"]["session"] :
148 raw_data = raw_input(msg_rep["content"]["prompt"])
148 raw_data = raw_input(msg_rep["content"]["prompt"])
149 self.km.stdin_channel.input(raw_data)
149 self.km.stdin_channel.input(raw_data)
150
150
151 def mainloop(self, display_banner=False):
151 def mainloop(self, display_banner=False):
152 while True:
152 while True:
153 try:
153 try:
154 self.interact(display_banner=display_banner)
154 self.interact(display_banner=display_banner)
155 #self.interact_with_readline()
155 #self.interact_with_readline()
156 # XXX for testing of a readline-decoupled repl loop, call
156 # XXX for testing of a readline-decoupled repl loop, call
157 # interact_with_readline above
157 # interact_with_readline above
158 break
158 break
159 except KeyboardInterrupt:
159 except KeyboardInterrupt:
160 # this should not be necessary, but KeyboardInterrupt
160 # this should not be necessary, but KeyboardInterrupt
161 # handling seems rather unpredictable...
161 # handling seems rather unpredictable...
162 self.write("\nKeyboardInterrupt in interact()\n")
162 self.write("\nKeyboardInterrupt in interact()\n")
163
163
164 def interact(self, display_banner=None):
164 def interact(self, display_banner=None):
165 """Closely emulate the interactive Python console."""
165 """Closely emulate the interactive Python console."""
166
166
167 # batch run -> do not interact
167 # batch run -> do not interact
168 if self.exit_now:
168 if self.exit_now:
169 return
169 return
170
170
171 if display_banner is None:
171 if display_banner is None:
172 display_banner = self.display_banner
172 display_banner = self.display_banner
173
173
174 if isinstance(display_banner, basestring):
174 if isinstance(display_banner, basestring):
175 self.show_banner(display_banner)
175 self.show_banner(display_banner)
176 elif display_banner:
176 elif display_banner:
177 self.show_banner()
177 self.show_banner()
178
178
179 more = False
179 more = False
180
180
181 if self.has_readline:
181 if self.has_readline:
182 self.readline_startup_hook(self.pre_readline)
182 self.readline_startup_hook(self.pre_readline)
183 # exit_now is set by a call to %Exit or %Quit, through the
183 # exit_now is set by a call to %Exit or %Quit, through the
184 # ask_exit callback.
184 # ask_exit callback.
185
185
186 while not self.exit_now:
186 while not self.exit_now:
187 if not self.km.is_alive:
187 if not self.km.is_alive:
188 ans = self.raw_input("kernel died, restart ([y]/n)?")
188 ans = self.raw_input("kernel died, restart ([y]/n)?")
189 if not ans.lower().startswith('n'):
189 if not ans.lower().startswith('n'):
190 self.km.restart_kernel(True)
190 self.km.restart_kernel(True)
191 else:
191 else:
192 self.exit_now=True
192 self.exit_now=True
193 continue
193 continue
194 self.hooks.pre_prompt_hook()
194 self.hooks.pre_prompt_hook()
195 if more:
195 if more:
196 try:
196 try:
197 prompt = self.hooks.generate_prompt(True)
197 prompt = self.hooks.generate_prompt(True)
198 except:
198 except:
199 self.showtraceback()
199 self.showtraceback()
200 if self.autoindent:
200 if self.autoindent:
201 self.rl_do_indent = True
201 self.rl_do_indent = True
202
202
203 else:
203 else:
204 try:
204 try:
205 prompt = self.hooks.generate_prompt(False)
205 prompt = self.hooks.generate_prompt(False)
206 except:
206 except:
207 self.showtraceback()
207 self.showtraceback()
208 try:
208 try:
209 line = self.raw_input(prompt)
209 line = self.raw_input(prompt)
210 if self.exit_now:
210 if self.exit_now:
211 # quick exit on sys.std[in|out] close
211 # quick exit on sys.std[in|out] close
212 break
212 break
213 if self.autoindent:
213 if self.autoindent:
214 self.rl_do_indent = False
214 self.rl_do_indent = False
215
215
216 except KeyboardInterrupt:
216 except KeyboardInterrupt:
217 #double-guard against keyboardinterrupts during kbdint handling
217 #double-guard against keyboardinterrupts during kbdint handling
218 try:
218 try:
219 self.write('\nKeyboardInterrupt\n')
219 self.write('\nKeyboardInterrupt\n')
220 self.input_splitter.reset()
220 self.input_splitter.reset()
221 more = False
221 more = False
222 except KeyboardInterrupt:
222 except KeyboardInterrupt:
223 pass
223 pass
224 except EOFError:
224 except EOFError:
225 if self.autoindent:
225 if self.autoindent:
226 self.rl_do_indent = False
226 self.rl_do_indent = False
227 if self.has_readline:
227 if self.has_readline:
228 self.readline_startup_hook(None)
228 self.readline_startup_hook(None)
229 self.write('\n')
229 self.write('\n')
230 self.exit()
230 self.exit()
231 except bdb.BdbQuit:
231 except bdb.BdbQuit:
232 warn('The Python debugger has exited with a BdbQuit exception.\n'
232 warn('The Python debugger has exited with a BdbQuit exception.\n'
233 'Because of how pdb handles the stack, it is impossible\n'
233 'Because of how pdb handles the stack, it is impossible\n'
234 'for IPython to properly format this particular exception.\n'
234 'for IPython to properly format this particular exception.\n'
235 'IPython will resume normal operation.')
235 'IPython will resume normal operation.')
236 except:
236 except:
237 # exceptions here are VERY RARE, but they can be triggered
237 # exceptions here are VERY RARE, but they can be triggered
238 # asynchronously by signal handlers, for example.
238 # asynchronously by signal handlers, for example.
239 self.showtraceback()
239 self.showtraceback()
240 else:
240 else:
241 self.input_splitter.push(line)
241 self.input_splitter.push(line)
242 more = self.input_splitter.push_accepts_more()
242 more = self.input_splitter.push_accepts_more()
243 if (self.SyntaxTB.last_syntax_error and
243 if (self.SyntaxTB.last_syntax_error and
244 self.autoedit_syntax):
244 self.autoedit_syntax):
245 self.edit_syntax_error()
245 self.edit_syntax_error()
246 if not more:
246 if not more:
247 source_raw = self.input_splitter.source_reset()
247 source_raw = self.input_splitter.source_reset()
248 self.run_cell(source_raw)
248 self.run_cell(source_raw)
249
249
250
250
251 # Turn off the exit flag, so the mainloop can be restarted if desired
251 # Turn off the exit flag, so the mainloop can be restarted if desired
252 self.exit_now = False
252 self.exit_now = False
General Comments 0
You need to be logged in to leave comments. Login now