##// 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 50 def __init__(self,wx_instance,
51 51 argv=[],user_ns={},user_global_ns=None,
52 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 56 NonBlockingIPShell.__init__(self,argv,user_ns,user_global_ns,
57 57 cin, cout, cerr,
58 exit_handler,time_loop)
58 ask_exit_handler)
59 59
60 60 # This creates a new Event class and a EVT binder function
61 61 (self.IPythonAskExitEvent, EVT_IP_ASK_EXIT) = wx.lib.newevent.NewEvent()
62 (self.IPythonAddButtonEvent, EVT_IP_ADD_BUTTON_EXIT) = wx.lib.newevent.NewEvent()
63 (self.IPythonExecuteDoneEvent, EVT_IP_EXECUTE_DONE) = wx.lib.newevent.NewEvent()
62 (self.IPythonAddButtonEvent, EVT_IP_ADD_BUTTON_EXIT) = \
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 68 wx_instance.Bind(EVT_IP_ADD_BUTTON_EXIT, wx_instance.add_button_handler)
67 69 wx_instance.Bind(EVT_IP_EXECUTE_DONE, wx_instance.evtStateExecuteDone)
68 70
69 71 self.wx_instance = wx_instance
70 self._IP.exit = self._AskExit
72 self._IP.ask_exit = self._askExit
71 73
72 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 78 wx.PostEvent(self.wx_instance, evt)
75 79
76 def _AskExit(self):
80 def _askExit(self):
77 81 evt = self.IPythonAskExitEvent()
78 82 wx.PostEvent(self.wx_instance, evt)
79 83
@@ -463,7 +467,8 b' class WxIPythonViewPanel(wx.Panel):'
463 467 I've choosed to derivate from a wx.Panel because it seems to be ore usefull
464 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 472 background_color="BLACK", add_button_handler=None,
468 473 wx_ip_shell=None,
469 474 ):
@@ -479,17 +484,14 b' class WxIPythonViewPanel(wx.Panel):'
479 484 self.cout = StringIO()
480 485
481 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 489 if wx_ip_shell is not None:
485 490 self.IP = wx_ip_shell
486 491 else:
487 492 self.IP = WxNonBlockingIPShell(self,
488 493 cout=self.cout,cerr=self.cout,
489 exit_handler = exit_handler,
490 time_loop = 0.1)
491 self.IP.start()
492
494 ask_exit_handler = ask_exit_handler)
493 495 ### IPython wx console view instanciation ###
494 496 #If user didn't defined an intro text, we create one for him
495 497 #If you really wnat an empty intrp just call wxIPythonViewPanel with intro=''
@@ -541,8 +543,6 b' class WxIPythonViewPanel(wx.Panel):'
541 543 #self.Bind(wx.EVT_IDLE, self.runStateMachine)
542 544
543 545 def __del__(self):
544 self.IP.shutdown()
545 self.IP.join()
546 546 WxConsoleView.__del__()
547 547
548 548 #---------------------------- IPython Thread Management ---------------------------------------
@@ -705,7 +705,7 b' class WxIPythonViewPanel(wx.Panel):'
705 705 if event.Modifiers == wx.MOD_CONTROL:
706 706 if self.cur_state == 'WAIT_END_OF_EXECUTION':
707 707 #we raise an exception inside the IPython thread container
708 self.IP.raise_exc(KeyboardInterrupt)
708 self.IP.ce.raise_exc(KeyboardInterrupt)
709 709 return
710 710
711 711 if event.KeyCode == wx.WXK_RETURN:
@@ -31,16 +31,19 b' try:'
31 31 except Exception,e:
32 32 raise "Error importing IPython (%s)" % str(e)
33 33
34 ##############################################################################
34 35 class _Helper(object):
35 36 """Redefine the built-in 'help'.
36 37 This is a wrapper around pydoc.help (with a twist).
37 38 """
39
38 40 def __init__(self,pager):
39 41 self._pager = pager
40 42
41 43 def __repr__(self):
42 44 return "Type help() for interactive help, " \
43 45 "or help(object) for help about object."
46
44 47 def __call__(self, *args, **kwds):
45 48 class DummyWriter(object):
46 49 def __init__(self,pager):
@@ -57,20 +60,41 b' class _Helper(object):'
57 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.
63 Does not start a blocking event loop, instead allow single iterations.
86 Create an IPython instance, running the commands in a separate,
87 non-blocking thread.
64 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.
66 Note ThreadEx class supports asynchroneous function call
89
90 Note: The ThreadEx class supports asynchroneous function call
67 91 via raise_exc()
68 92 '''
69 93
70 94 def __init__(self,argv
71 95 =[],user_ns={},user_global_ns=None,
72 96 cin=None, cout=None, cerr=None,
73 exit_handler=None,time_loop = 0.1):
97 ask_exit_handler=None):
74 98 '''
75 99 @param argv: Command line options for IPython
76 100 @type argv: list
@@ -89,8 +113,6 b' class NonBlockingIPShell(ThreadEx):'
89 113 @param time_loop: Define the sleep time between two thread's loop
90 114 @type int
91 115 '''
92 ThreadEx.__init__(self)
93
94 116 #first we redefine in/out/error functions of IPython
95 117 if cin:
96 118 IPython.Shell.Term.cin = cin
@@ -127,6 +149,10 b' class NonBlockingIPShell(ThreadEx):'
127 149 IPython.iplib.raw_input_original = self._raw_input
128 150 #we replace the ipython default exit command by our method
129 151 self._IP.exit = self._setAskExit
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)
130 156
131 157 sys.excepthook = excepthook
132 158
@@ -136,9 +162,6 b' class NonBlockingIPShell(ThreadEx):'
136 162 self._prompt = str(self._IP.outputcache.prompt1).strip()
137 163
138 164 #thread working vars
139 self._terminate = False
140 self._time_loop = time_loop
141 self._do_execute = False
142 165 self._line_to_execute = ''
143 166
144 167 #vars that will be checked by GUI loop to handle thread states...
@@ -152,45 +175,15 b' class NonBlockingIPShell(ThreadEx):'
152 175 self._IP.user_ns['help'] = _Helper(self._pager_help)
153 176
154 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 178 def doExecute(self,line):
183 179 """
184 180 Tell the thread to process the 'line' command
185 181 """
186 self._do_execute = True
182
187 183 self._line_to_execute = line
188 184
189 def isExecuteDone(self):
190 """
191 Returns the processing state
192 """
193 return not self._do_execute
185 self.ce = _CodeExecutor(self,self._afterExecute)
186 self.ce.start()
194 187
195 188 #----------------------- IPython management section ----------------------
196 189 def getAskExit(self):
@@ -351,7 +344,7 b' class NonBlockingIPShell(ThreadEx):'
351 344 '''
352 345 self._history_level = self._getHistoryMaxIndex()+1
353 346
354 #----------------------- IPython PRIVATE management section ----------------------
347 #----------------------- IPython PRIVATE management section --------------
355 348 def _afterExecute(self):
356 349 '''
357 350 Can be redefined to generate post event after excution is done
@@ -360,11 +353,18 b' class NonBlockingIPShell(ThreadEx):'
360 353
361 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 357 IPython request an exit handling
365 358 '''
366 359 self._ask_exit = True
367 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
368 368 def _getHistoryMaxIndex(self):
369 369 '''
370 370 returns the max length of the history buffer
@@ -378,7 +378,7 b' class NonBlockingIPShell(ThreadEx):'
378 378 '''
379 379 Get's the command string of the current history level.
380 380
381 @return: Historic command string.
381 @return: Historic command stri
382 382 @rtype: string
383 383 '''
384 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