##// END OF EJS Templates
Merged the cosmetic changes with the thread refactoring.
Gael Varoquaux -
r1097:f117697b merge
parent child Browse files
Show More
@@ -50,30 +50,34 b' class WxNonBlockingIPShell(NonBlockingIPShell):'
50 def __init__(self,wx_instance,
50 def __init__(self,wx_instance,
51 argv=[],user_ns={},user_global_ns=None,
51 argv=[],user_ns={},user_global_ns=None,
52 cin=None, cout=None, cerr=None,
52 cin=None, cout=None, cerr=None,
53 exit_handler=None,time_loop = 0.1):
53 ask_exit_handler=None):
54
54
55 user_ns['addGUIShortcut'] = self.addGUIShortcut
55 #user_ns['addGUIShortcut'] = self.addGUIShortcut
56 NonBlockingIPShell.__init__(self,argv,user_ns,user_global_ns,
56 NonBlockingIPShell.__init__(self,argv,user_ns,user_global_ns,
57 cin, cout, cerr,
57 cin, cout, cerr,
58 exit_handler,time_loop)
58 ask_exit_handler)
59
59
60 # This creates a new Event class and a EVT binder function
60 # This creates a new Event class and a EVT binder function
61 (self.IPythonAskExitEvent, EVT_IP_ASK_EXIT) = wx.lib.newevent.NewEvent()
61 (self.IPythonAskExitEvent, EVT_IP_ASK_EXIT) = wx.lib.newevent.NewEvent()
62 (self.IPythonAddButtonEvent, EVT_IP_ADD_BUTTON_EXIT) = wx.lib.newevent.NewEvent()
62 (self.IPythonAddButtonEvent, EVT_IP_ADD_BUTTON_EXIT) = \
63 (self.IPythonExecuteDoneEvent, EVT_IP_EXECUTE_DONE) = wx.lib.newevent.NewEvent()
63 wx.lib.newevent.NewEvent()
64 (self.IPythonExecuteDoneEvent, EVT_IP_EXECUTE_DONE) = \
65 wx.lib.newevent.NewEvent()
64
66
65 wx_instance.Bind(EVT_IP_ASK_EXIT, wx_instance.exit_handler)
67 wx_instance.Bind(EVT_IP_ASK_EXIT, wx_instance.ask_exit_handler)
66 wx_instance.Bind(EVT_IP_ADD_BUTTON_EXIT, wx_instance.add_button_handler)
68 wx_instance.Bind(EVT_IP_ADD_BUTTON_EXIT, wx_instance.add_button_handler)
67 wx_instance.Bind(EVT_IP_EXECUTE_DONE, wx_instance.evtStateExecuteDone)
69 wx_instance.Bind(EVT_IP_EXECUTE_DONE, wx_instance.evtStateExecuteDone)
68
70
69 self.wx_instance = wx_instance
71 self.wx_instance = wx_instance
70 self._IP.exit = self._AskExit
72 self._IP.ask_exit = self._askExit
71
73
72 def addGUIShortcut(self,text,func):
74 def addGUIShortcut(self,text,func):
73 evt = self.IPythonAddButtonEvent(button_info={'text':text,'func':self.wx_instance.doExecuteLine(func)})
75 evt = self.IPythonAddButtonEvent(
76 button_info={ 'text':text,
77 'func':self.wx_instance.doExecuteLine(func)})
74 wx.PostEvent(self.wx_instance, evt)
78 wx.PostEvent(self.wx_instance, evt)
75
79
76 def _AskExit(self):
80 def _askExit(self):
77 evt = self.IPythonAskExitEvent()
81 evt = self.IPythonAskExitEvent()
78 wx.PostEvent(self.wx_instance, evt)
82 wx.PostEvent(self.wx_instance, evt)
79
83
@@ -463,7 +467,8 b' class WxIPythonViewPanel(wx.Panel):'
463 I've choosed to derivate from a wx.Panel because it seems to be ore usefull
467 I've choosed to derivate from a wx.Panel because it seems to be ore usefull
464 Any idea to make it more 'genric' welcomed.
468 Any idea to make it more 'genric' welcomed.
465 '''
469 '''
466 def __init__(self, parent, exit_handler=None, intro=None,
470
471 def __init__(self, parent, ask_exit_handler=None, intro=None,
467 background_color="BLACK", add_button_handler=None,
472 background_color="BLACK", add_button_handler=None,
468 wx_ip_shell=None,
473 wx_ip_shell=None,
469 ):
474 ):
@@ -479,17 +484,14 b' class WxIPythonViewPanel(wx.Panel):'
479 self.cout = StringIO()
484 self.cout = StringIO()
480
485
481 self.add_button_handler = add_button_handler
486 self.add_button_handler = add_button_handler
482 self.exit_handler = exit_handler
487 self.ask_exit_handler = ask_exit_handler
483
488
484 if wx_ip_shell is not None:
489 if wx_ip_shell is not None:
485 self.IP = wx_ip_shell
490 self.IP = wx_ip_shell
486 else:
491 else:
487 self.IP = WxNonBlockingIPShell(self,
492 self.IP = WxNonBlockingIPShell(self,
488 cout=self.cout,cerr=self.cout,
493 cout=self.cout,cerr=self.cout,
489 exit_handler = exit_handler,
494 ask_exit_handler = ask_exit_handler)
490 time_loop = 0.1)
491 self.IP.start()
492
493 ### IPython wx console view instanciation ###
495 ### IPython wx console view instanciation ###
494 #If user didn't defined an intro text, we create one for him
496 #If user didn't defined an intro text, we create one for him
495 #If you really wnat an empty intrp just call wxIPythonViewPanel with intro=''
497 #If you really wnat an empty intrp just call wxIPythonViewPanel with intro=''
@@ -541,8 +543,6 b' class WxIPythonViewPanel(wx.Panel):'
541 #self.Bind(wx.EVT_IDLE, self.runStateMachine)
543 #self.Bind(wx.EVT_IDLE, self.runStateMachine)
542
544
543 def __del__(self):
545 def __del__(self):
544 self.IP.shutdown()
545 self.IP.join()
546 WxConsoleView.__del__()
546 WxConsoleView.__del__()
547
547
548 #---------------------------- IPython Thread Management ---------------------------------------
548 #---------------------------- IPython Thread Management ---------------------------------------
@@ -705,7 +705,7 b' class WxIPythonViewPanel(wx.Panel):'
705 if event.Modifiers == wx.MOD_CONTROL:
705 if event.Modifiers == wx.MOD_CONTROL:
706 if self.cur_state == 'WAIT_END_OF_EXECUTION':
706 if self.cur_state == 'WAIT_END_OF_EXECUTION':
707 #we raise an exception inside the IPython thread container
707 #we raise an exception inside the IPython thread container
708 self.IP.raise_exc(KeyboardInterrupt)
708 self.IP.ce.raise_exc(KeyboardInterrupt)
709 return
709 return
710
710
711 if event.KeyCode == wx.WXK_RETURN:
711 if event.KeyCode == wx.WXK_RETURN:
@@ -31,16 +31,19 b' try:'
31 except Exception,e:
31 except Exception,e:
32 raise "Error importing IPython (%s)" % str(e)
32 raise "Error importing IPython (%s)" % str(e)
33
33
34 ##############################################################################
34 class _Helper(object):
35 class _Helper(object):
35 """Redefine the built-in 'help'.
36 """Redefine the built-in 'help'.
36 This is a wrapper around pydoc.help (with a twist).
37 This is a wrapper around pydoc.help (with a twist).
37 """
38 """
39
38 def __init__(self,pager):
40 def __init__(self,pager):
39 self._pager = pager
41 self._pager = pager
40
42
41 def __repr__(self):
43 def __repr__(self):
42 return "Type help() for interactive help, " \
44 return "Type help() for interactive help, " \
43 "or help(object) for help about object."
45 "or help(object) for help about object."
46
44 def __call__(self, *args, **kwds):
47 def __call__(self, *args, **kwds):
45 class DummyWriter(object):
48 class DummyWriter(object):
46 def __init__(self,pager):
49 def __init__(self,pager):
@@ -57,20 +60,41 b' class _Helper(object):'
57 return pydoc.help(*args, **kwds)
60 return pydoc.help(*args, **kwds)
58
61
59
62
60 class NonBlockingIPShell(ThreadEx):
63 ##############################################################################
64 class _CodeExecutor(ThreadEx):
65
66 def __init__(self, instance, after):
67 ThreadEx.__init__(self)
68 self.instance = instance
69 self._afterExecute=after
70
71 def run(self):
72 try:
73 self.instance._doc_text = None
74 self.instance._help_text = None
75 self.instance._execute()
76 # used for uper class to generate event after execution
77 self._afterExecute()
78
79 except KeyboardInterrupt:
80 pass
81
82
83 ##############################################################################
84 class NonBlockingIPShell(object):
61 '''
85 '''
62 Create an IPython instance inside a dedicated thread.
86 Create an IPython instance, running the commands in a separate,
63 Does not start a blocking event loop, instead allow single iterations.
87 non-blocking thread.
64 This allows embedding in any GUI without blockage.
88 This allows embedding in any GUI without blockage.
65 The thread is a slave one, in that it doesn't interact directly with the GUI.
89
66 Note ThreadEx class supports asynchroneous function call
90 Note: The ThreadEx class supports asynchroneous function call
67 via raise_exc()
91 via raise_exc()
68 '''
92 '''
69
93
70 def __init__(self,argv
94 def __init__(self,argv
71 =[],user_ns={},user_global_ns=None,
95 =[],user_ns={},user_global_ns=None,
72 cin=None, cout=None, cerr=None,
96 cin=None, cout=None, cerr=None,
73 exit_handler=None,time_loop = 0.1):
97 ask_exit_handler=None):
74 '''
98 '''
75 @param argv: Command line options for IPython
99 @param argv: Command line options for IPython
76 @type argv: list
100 @type argv: list
@@ -89,8 +113,6 b' class NonBlockingIPShell(ThreadEx):'
89 @param time_loop: Define the sleep time between two thread's loop
113 @param time_loop: Define the sleep time between two thread's loop
90 @type int
114 @type int
91 '''
115 '''
92 ThreadEx.__init__(self)
93
94 #first we redefine in/out/error functions of IPython
116 #first we redefine in/out/error functions of IPython
95 if cin:
117 if cin:
96 IPython.Shell.Term.cin = cin
118 IPython.Shell.Term.cin = cin
@@ -127,7 +149,11 b' class NonBlockingIPShell(ThreadEx):'
127 IPython.iplib.raw_input_original = self._raw_input
149 IPython.iplib.raw_input_original = self._raw_input
128 #we replace the ipython default exit command by our method
150 #we replace the ipython default exit command by our method
129 self._IP.exit = self._setAskExit
151 self._IP.exit = self._setAskExit
130
152 #we modify Exit and Quit Magic
153 ip = IPython.ipapi.get()
154 ip.expose_magic('Exit', self._setDoExit)
155 ip.expose_magic('Quit', self._setDoExit)
156
131 sys.excepthook = excepthook
157 sys.excepthook = excepthook
132
158
133 self._iter_more = 0
159 self._iter_more = 0
@@ -136,9 +162,6 b' class NonBlockingIPShell(ThreadEx):'
136 self._prompt = str(self._IP.outputcache.prompt1).strip()
162 self._prompt = str(self._IP.outputcache.prompt1).strip()
137
163
138 #thread working vars
164 #thread working vars
139 self._terminate = False
140 self._time_loop = time_loop
141 self._do_execute = False
142 self._line_to_execute = ''
165 self._line_to_execute = ''
143
166
144 #vars that will be checked by GUI loop to handle thread states...
167 #vars that will be checked by GUI loop to handle thread states...
@@ -152,46 +175,16 b' class NonBlockingIPShell(ThreadEx):'
152 self._IP.user_ns['help'] = _Helper(self._pager_help)
175 self._IP.user_ns['help'] = _Helper(self._pager_help)
153
176
154 #----------------------- Thread management section ----------------------
177 #----------------------- Thread management section ----------------------
155 def run (self):
156 """
157 Thread main loop
158 The thread will run until self._terminate will be set to True via shutdown() function
159 Command processing can be interrupted with Instance.raise_exc(KeyboardInterrupt) call in the
160 GUI thread.
161 """
162 while(not self._terminate):
163 try:
164 if self._do_execute:
165 self._doc_text = None
166 self._help_text = None
167 self._execute()
168 self._do_execute = False
169 self._afterExecute() #used for uper class to generate event after execution
170
171 except KeyboardInterrupt:
172 pass
173
174 time.sleep(self._time_loop)
175
176 def shutdown(self):
177 """
178 Shutdown the tread
179 """
180 self._terminate = True
181
182 def doExecute(self,line):
178 def doExecute(self,line):
183 """
179 """
184 Tell the thread to process the 'line' command
180 Tell the thread to process the 'line' command
185 """
181 """
186 self._do_execute = True
182
187 self._line_to_execute = line
183 self._line_to_execute = line
184
185 self.ce = _CodeExecutor(self,self._afterExecute)
186 self.ce.start()
188
187
189 def isExecuteDone(self):
190 """
191 Returns the processing state
192 """
193 return not self._do_execute
194
195 #----------------------- IPython management section ----------------------
188 #----------------------- IPython management section ----------------------
196 def getAskExit(self):
189 def getAskExit(self):
197 '''
190 '''
@@ -351,7 +344,7 b' class NonBlockingIPShell(ThreadEx):'
351 '''
344 '''
352 self._history_level = self._getHistoryMaxIndex()+1
345 self._history_level = self._getHistoryMaxIndex()+1
353
346
354 #----------------------- IPython PRIVATE management section ----------------------
347 #----------------------- IPython PRIVATE management section --------------
355 def _afterExecute(self):
348 def _afterExecute(self):
356 '''
349 '''
357 Can be redefined to generate post event after excution is done
350 Can be redefined to generate post event after excution is done
@@ -360,10 +353,17 b' class NonBlockingIPShell(ThreadEx):'
360
353
361 def _setAskExit(self):
354 def _setAskExit(self):
362 '''
355 '''
363 set the _ask_exit variable that can be cjhecked by GUI to see if
356 set the _ask_exit variable that can be checked by GUI to see if
364 IPython request an exit handling
357 IPython request an exit handling
365 '''
358 '''
366 self._ask_exit = True
359 self._ask_exit = True
360
361 def _setDoExit(self, toto, arg):
362 '''
363 set the _do_exit variable that can be checked by GUI to see if
364 IPython do a direct exit of the app
365 '''
366 self._do_exit = True
367
367
368 def _getHistoryMaxIndex(self):
368 def _getHistoryMaxIndex(self):
369 '''
369 '''
@@ -378,7 +378,7 b' class NonBlockingIPShell(ThreadEx):'
378 '''
378 '''
379 Get's the command string of the current history level.
379 Get's the command string of the current history level.
380
380
381 @return: Historic command string.
381 @return: Historic command stri
382 @rtype: string
382 @rtype: string
383 '''
383 '''
384 rv = self._IP.input_hist_raw[self._history_level].strip('\n')
384 rv = self._IP.input_hist_raw[self._history_level].strip('\n')
General Comments 0
You need to be logged in to leave comments. Login now