##// END OF EJS Templates
qtconsole: fix race-cond, handle multiple exec...
Matthias BUSSONNIER -
Show More
@@ -138,6 +138,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
138 self._input_splitter = self._input_splitter_class(input_mode='cell')
138 self._input_splitter = self._input_splitter_class(input_mode='cell')
139 self._kernel_manager = None
139 self._kernel_manager = None
140 self._request_info = {}
140 self._request_info = {}
141 self._request_info['execute'] = {};
141 self._callback_dict = {}
142 self._callback_dict = {}
142
143
143 # Configure the ConsoleWidget.
144 # Configure the ConsoleWidget.
@@ -199,7 +200,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
199 See parent class :meth:`execute` docstring for full details.
200 See parent class :meth:`execute` docstring for full details.
200 """
201 """
201 msg_id = self.kernel_manager.shell_channel.execute(source, hidden)
202 msg_id = self.kernel_manager.shell_channel.execute(source, hidden)
202 self._request_info['execute'] = self._ExecutionRequest(msg_id, 'user')
203 self._request_info['execute'][msg_id] = self._ExecutionRequest(msg_id, 'user')
203 self._hidden = hidden
204 self._hidden = hidden
204 if not hidden:
205 if not hidden:
205 self.executing.emit(source)
206 self.executing.emit(source)
@@ -343,7 +344,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
343 msg_id = self.kernel_manager.shell_channel.execute('',
344 msg_id = self.kernel_manager.shell_channel.execute('',
344 silent=True, user_expressions={ local_uuid:expr })
345 silent=True, user_expressions={ local_uuid:expr })
345 self._callback_dict[local_uuid] = callback
346 self._callback_dict[local_uuid] = callback
346 self._request_info['execute'] = self._ExecutionRequest(msg_id, 'silent_exec_callback')
347 self._request_info['execute'][msg_id] = self._ExecutionRequest(msg_id, 'silent_exec_callback')
347
348
348 def _handle_exec_callback(self, msg):
349 def _handle_exec_callback(self, msg):
349 """Execute `callback` corresonding to `msg` reply, after ``_silent_exec_callback``
350 """Execute `callback` corresonding to `msg` reply, after ``_silent_exec_callback``
@@ -373,12 +374,14 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
373 """ Handles replies for code execution.
374 """ Handles replies for code execution.
374 """
375 """
375 self.log.debug("execute: %s", msg.get('content', ''))
376 self.log.debug("execute: %s", msg.get('content', ''))
376 info = self._request_info.get('execute')
377 info_list = self._request_info.get('execute')
378 msg_id = msg['parent_header']['msg_id']
379 if msg_id in info_list:
380 info = info_list[msg_id]
377 # unset reading flag, because if execute finished, raw_input can't
381 # unset reading flag, because if execute finished, raw_input can't
378 # still be pending.
382 # still be pending.
379 self._reading = False
383 self._reading = False
380 if info and info.id == msg['parent_header']['msg_id'] and \
384 if info and info.kind == 'user' and not self._hidden:
381 info.kind == 'user' and not self._hidden:
382 # Make sure that all output from the SUB channel has been processed
385 # Make sure that all output from the SUB channel has been processed
383 # before writing a new prompt.
386 # before writing a new prompt.
384 self.kernel_manager.sub_channel.flush()
387 self.kernel_manager.sub_channel.flush()
@@ -400,8 +403,8 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
400
403
401 self._show_interpreter_prompt_for_reply(msg)
404 self._show_interpreter_prompt_for_reply(msg)
402 self.executed.emit(msg)
405 self.executed.emit(msg)
403 elif info and info.id == msg['parent_header']['msg_id'] and \
406 info_list.pop(msg_id)
404 info.kind == 'silent_exec_callback' and not self._hidden:
407 elif info and info.kind == 'silent_exec_callback' and not self._hidden:
405 self._handle_exec_callback(msg)
408 self._handle_exec_callback(msg)
406 else:
409 else:
407 super(FrontendWidget, self)._handle_execute_reply(msg)
410 super(FrontendWidget, self)._handle_execute_reply(msg)
@@ -559,7 +562,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
559 """
562 """
560 if self._executing:
563 if self._executing:
561 self._executing = False
564 self._executing = False
562 self._request_info['execute'] = None
565 self._request_info['execute'] = {}
563 self._reading = False
566 self._reading = False
564 self._highlighter.highlighting_on = False
567 self._highlighter.highlighting_on = False
565
568
@@ -211,14 +211,16 b' class HistoryConsoleWidget(ConsoleWidget):'
211 'hlen':'len(get_ipython().history_manager.input_hist_raw)',
211 'hlen':'len(get_ipython().history_manager.input_hist_raw)',
212 }
212 }
213 )
213 )
214 self._request_info['execute'] = self._ExecutionRequest(msg_id, 'save_magic')
214 self._request_info['execute'][msg_id] = self._ExecutionRequest(msg_id, 'save_magic')
215
215
216 def _handle_execute_reply(self, msg):
216 def _handle_execute_reply(self, msg):
217 """ Handles replies for code execution, here only session history length
217 """ Handles replies for code execution, here only session history length
218 """
218 """
219 info = self._request_info.get('execute')
219 info_list = self._request_info.get('execute')
220 if info and info.id == msg['parent_header']['msg_id'] and \
220 msg_id = msg['parent_header']['msg_id']
221 info.kind == 'save_magic' and not self._hidden:
221 if msg_id in info_list:
222 info = info_list.pop(msg_id)
223 if info.kind == 'save_magic' and not self._hidden:
222 content = msg['content']
224 content = msg['content']
223 status = content['status']
225 status = content['status']
224 if status == 'ok':
226 if status == 'ok':
@@ -165,11 +165,14 b' class IPythonWidget(FrontendWidget):'
165 def _handle_execute_reply(self, msg):
165 def _handle_execute_reply(self, msg):
166 """ Reimplemented to support prompt requests.
166 """ Reimplemented to support prompt requests.
167 """
167 """
168 info = self._request_info.get('execute')
168 info_list = self._request_info.get('execute')
169 if info and info.id == msg['parent_header']['msg_id']:
169 msg_id = msg['parent_header']['msg_id']
170 if msg_id in info_list:
171 info = info_list[msg_id]
170 if info.kind == 'prompt':
172 if info.kind == 'prompt':
171 number = msg['content']['execution_count'] + 1
173 number = msg['content']['execution_count'] + 1
172 self._show_interpreter_prompt(number)
174 self._show_interpreter_prompt(number)
175 info_list.pop(msg_id)
173 else:
176 else:
174 super(IPythonWidget, self)._handle_execute_reply(msg)
177 super(IPythonWidget, self)._handle_execute_reply(msg)
175
178
@@ -358,7 +361,7 b' class IPythonWidget(FrontendWidget):'
358 if number is None:
361 if number is None:
359 msg_id = self.kernel_manager.shell_channel.execute('', silent=True)
362 msg_id = self.kernel_manager.shell_channel.execute('', silent=True)
360 info = self._ExecutionRequest(msg_id, 'prompt')
363 info = self._ExecutionRequest(msg_id, 'prompt')
361 self._request_info['execute'] = info
364 self._request_info['execute'][msg_id] = info
362 return
365 return
363
366
364 # Show a new prompt and save information about it so that it can be
367 # Show a new prompt and save information about it so that it can be
@@ -629,6 +629,9 b' class MainWindow(QtGui.QMainWindow):'
629 self.pop = QtGui.QAction("&Update All Magic Menu ",
629 self.pop = QtGui.QAction("&Update All Magic Menu ",
630 self, triggered=self.update_all_magic_menu)
630 self, triggered=self.update_all_magic_menu)
631 self.add_menu_action(self.all_magic_menu, self.pop)
631 self.add_menu_action(self.all_magic_menu, self.pop)
632 # we need to populate the 'Magic Menu' once the kernel has answer at
633 # least once let's do it immedialy, but it's assured to works
634 self.pop.trigger()
632
635
633 self.reset_action = QtGui.QAction("&Reset",
636 self.reset_action = QtGui.QAction("&Reset",
634 self,
637 self,
@@ -452,9 +452,6 b' class IPythonQtConsoleApp(BaseIPythonApplication):'
452 self.window.add_tab_with_frontend(self.widget)
452 self.window.add_tab_with_frontend(self.widget)
453 self.window.init_menu_bar()
453 self.window.init_menu_bar()
454
454
455 # we need to populate the 'Magic Menu' once the kernel has answer at least once
456 self.kernel_manager.shell_channel.first_reply.connect(self.window.pop.trigger)
457
458 self.window.setWindowTitle('Python' if self.pure else 'IPython')
455 self.window.setWindowTitle('Python' if self.pure else 'IPython')
459
456
460 def init_colors(self):
457 def init_colors(self):
General Comments 0
You need to be logged in to leave comments. Login now