##// END OF EJS Templates
Merge pull request #1065 from Carreau/qtconsole-racecondition...
Fernando Perez -
r5527:a5fd0a3d merge
parent child Browse files
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,12 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 msg_id = msg['parent_header']['msg_id']
378 info = self._request_info['execute'].get(msg_id)
377 # unset reading flag, because if execute finished, raw_input can't
379 # unset reading flag, because if execute finished, raw_input can't
378 # still be pending.
380 # still be pending.
379 self._reading = False
381 self._reading = False
380 if info and info.id == msg['parent_header']['msg_id'] and \
382 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
383 # Make sure that all output from the SUB channel has been processed
383 # before writing a new prompt.
384 # before writing a new prompt.
384 self.kernel_manager.sub_channel.flush()
385 self.kernel_manager.sub_channel.flush()
@@ -400,9 +401,10 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
400
401
401 self._show_interpreter_prompt_for_reply(msg)
402 self._show_interpreter_prompt_for_reply(msg)
402 self.executed.emit(msg)
403 self.executed.emit(msg)
403 elif info and info.id == msg['parent_header']['msg_id'] and \
404 self._request_info['execute'].pop(msg_id)
404 info.kind == 'silent_exec_callback' and not self._hidden:
405 elif info and info.kind == 'silent_exec_callback' and not self._hidden:
405 self._handle_exec_callback(msg)
406 self._handle_exec_callback(msg)
407 self._request_info['execute'].pop(msg_id)
406 else:
408 else:
407 super(FrontendWidget, self)._handle_execute_reply(msg)
409 super(FrontendWidget, self)._handle_execute_reply(msg)
408
410
@@ -559,7 +561,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
559 """
561 """
560 if self._executing:
562 if self._executing:
561 self._executing = False
563 self._executing = False
562 self._request_info['execute'] = None
564 self._request_info['execute'] = {}
563 self._reading = False
565 self._reading = False
564 self._highlighter.highlighting_on = False
566 self._highlighter.highlighting_on = False
565
567
@@ -211,14 +211,14 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 msg_id = msg['parent_header']['msg_id']
220 if info and info.id == msg['parent_header']['msg_id'] and \
220 info = self._request_info.get['execute'].pop(msg_id,None)
221 info.kind == 'save_magic' and not self._hidden:
221 if info and info.kind == 'save_magic' and not self._hidden:
222 content = msg['content']
222 content = msg['content']
223 status = content['status']
223 status = content['status']
224 if status == 'ok':
224 if status == 'ok':
@@ -165,13 +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 msg_id = msg['parent_header'].get('msg_id')
169 if info and info.id == msg['parent_header']['msg_id']:
169 info = self._request_info['execute'].get(msg_id)
170 if info.kind == 'prompt':
170 if info and info.kind == 'prompt':
171 number = msg['content']['execution_count'] + 1
171 number = msg['content']['execution_count'] + 1
172 self._show_interpreter_prompt(number)
172 self._show_interpreter_prompt(number)
173 else:
173 self._request_info['execute'].pop(msg_id)
174 super(IPythonWidget, self)._handle_execute_reply(msg)
174 else:
175 super(IPythonWidget, self)._handle_execute_reply(msg)
175
176
176 def _handle_history_reply(self, msg):
177 def _handle_history_reply(self, msg):
177 """ Implemented to handle history tail replies, which are only supported
178 """ Implemented to handle history tail replies, which are only supported
@@ -358,7 +359,7 b' class IPythonWidget(FrontendWidget):'
358 if number is None:
359 if number is None:
359 msg_id = self.kernel_manager.shell_channel.execute('', silent=True)
360 msg_id = self.kernel_manager.shell_channel.execute('', silent=True)
360 info = self._ExecutionRequest(msg_id, 'prompt')
361 info = self._ExecutionRequest(msg_id, 'prompt')
361 self._request_info['execute'] = info
362 self._request_info['execute'][msg_id] = info
362 return
363 return
363
364
364 # Show a new prompt and save information about it so that it can be
365 # Show a new prompt and save information about it so that it can be
@@ -626,17 +626,12 b' class MainWindow(QtGui.QMainWindow):'
626 # is updated at first kernel response. Though, it is necessary when
626 # is updated at first kernel response. Though, it is necessary when
627 # connecting through X-forwarding, as in this case, the menu is not
627 # connecting through X-forwarding, as in this case, the menu is not
628 # auto updated, SO DO NOT DELETE.
628 # auto updated, SO DO NOT DELETE.
629
629 self.pop = QtGui.QAction("&Update All Magic Menu ",
630 ########################################################################
630 self, triggered=self.update_all_magic_menu)
631 ## TEMPORARILY DISABLED - see #1057 for details. Uncomment this
631 self.add_menu_action(self.all_magic_menu, self.pop)
632 ## section when a proper fix is found
632 # we need to populate the 'Magic Menu' once the kernel has answer at
633
633 # least once let's do it immedialy, but it's assured to works
634 ## self.pop = QtGui.QAction("&Update All Magic Menu ",
634 self.pop.trigger()
635 ## self, triggered=self.update_all_magic_menu)
636 ## self.add_menu_action(self.all_magic_menu, self.pop)
637
638 ## END TEMPORARY FIX
639 ########################################################################
640
635
641 self.reset_action = QtGui.QAction("&Reset",
636 self.reset_action = QtGui.QAction("&Reset",
642 self,
637 self,
@@ -674,49 +669,6 b' class MainWindow(QtGui.QMainWindow):'
674 triggered=self.whos_magic_active_frontend)
669 triggered=self.whos_magic_active_frontend)
675 self.add_menu_action(self.magic_menu, self.whos_action)
670 self.add_menu_action(self.magic_menu, self.whos_action)
676
671
677
678 ########################################################################
679 ## TEMPORARILY ADDED BACK - see #1057 for details. The magic menu is
680 ## supposed to be dynamic, but the mechanism merged in #1057 has a race
681 ## condition that locks up the console very often. We're putting back
682 ## the static list temporarily/ Remove this code when a proper fix is
683 ## found.
684
685 # allmagics submenu.
686
687 # for now this is just a copy and paste, but we should get this
688 # dynamically
689 magiclist = ["%alias", "%autocall", "%automagic", "%bookmark", "%cd",
690 "%clear", "%colors", "%debug", "%dhist", "%dirs", "%doctest_mode",
691 "%ed", "%edit", "%env", "%gui", "%guiref", "%hist", "%history",
692 "%install_default_config", "%install_profiles", "%less", "%load_ext",
693 "%loadpy", "%logoff", "%logon", "%logstart", "%logstate", "%logstop",
694 "%lsmagic", "%macro", "%magic", "%man", "%more", "%notebook", "%page",
695 "%pastebin", "%pdb", "%pdef", "%pdoc", "%pfile", "%pinfo", "%pinfo2",
696 "%popd", "%pprint", "%precision", "%profile", "%prun", "%psearch",
697 "%psource", "%pushd", "%pwd", "%pycat", "%pylab", "%quickref",
698 "%recall", "%rehashx", "%reload_ext", "%rep", "%rerun", "%reset",
699 "%reset_selective", "%run", "%save", "%sc", "%sx", "%tb", "%time",
700 "%timeit", "%unalias", "%unload_ext", "%who", "%who_ls", "%whos",
701 "%xdel", "%xmode"]
702
703 def make_dynamic_magic(i):
704 def inner_dynamic_magic():
705 self.active_frontend.execute(i)
706 inner_dynamic_magic.__name__ = "dynamics_magic_%s" % i
707 return inner_dynamic_magic
708
709 for magic in magiclist:
710 xaction = QtGui.QAction(magic,
711 self,
712 triggered=make_dynamic_magic(magic)
713 )
714 self.all_magic_menu.addAction(xaction)
715
716 ## END TEMPORARY FIX
717 ########################################################################
718
719
720 def init_window_menu(self):
672 def init_window_menu(self):
721 self.window_menu = self.menuBar().addMenu("&Window")
673 self.window_menu = self.menuBar().addMenu("&Window")
722 if sys.platform == 'darwin':
674 if sys.platform == 'darwin':
@@ -452,16 +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
456 # least once
457
458 ########################################################################
459 ## TEMPORARILY DISABLED - see #1057 for details, uncomment the next
460 ## line when a proper fix is found:
461 ## self.kernel_manager.shell_channel.first_reply.connect(self.window.pop.trigger)
462 ## END TEMPORARY FIX
463 ########################################################################
464
465 self.window.setWindowTitle('Python' if self.pure else 'IPython')
455 self.window.setWindowTitle('Python' if self.pure else 'IPython')
466
456
467 def init_colors(self):
457 def init_colors(self):
General Comments 0
You need to be logged in to leave comments. Login now