##// END OF EJS Templates
-twisted command line opt launches twisted reactor and uses it to execute code given by ipython mainloop thread
Ville M. Vainio -
Show More
@@ -1,1218 +1,1221 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """IPython Shell classes.
2 """IPython Shell classes.
3
3
4 All the matplotlib support code was co-developed with John Hunter,
4 All the matplotlib support code was co-developed with John Hunter,
5 matplotlib's author.
5 matplotlib's author.
6
6
7 $Id: Shell.py 3024 2008-02-07 15:34:42Z darren.dale $"""
7 $Id: Shell.py 3024 2008-02-07 15:34:42Z darren.dale $"""
8
8
9 #*****************************************************************************
9 #*****************************************************************************
10 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
10 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
11 #
11 #
12 # Distributed under the terms of the BSD License. The full license is in
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
13 # the file COPYING, distributed as part of this software.
14 #*****************************************************************************
14 #*****************************************************************************
15
15
16 from IPython import Release
16 from IPython import Release
17 __author__ = '%s <%s>' % Release.authors['Fernando']
17 __author__ = '%s <%s>' % Release.authors['Fernando']
18 __license__ = Release.license
18 __license__ = Release.license
19
19
20 # Code begins
20 # Code begins
21 # Stdlib imports
21 # Stdlib imports
22 import __builtin__
22 import __builtin__
23 import __main__
23 import __main__
24 import Queue
24 import Queue
25 import inspect
25 import inspect
26 import os
26 import os
27 import sys
27 import sys
28 import thread
28 import thread
29 import threading
29 import threading
30 import time
30 import time
31
31
32 from signal import signal, SIGINT
32 from signal import signal, SIGINT
33
33
34 try:
34 try:
35 import ctypes
35 import ctypes
36 HAS_CTYPES = True
36 HAS_CTYPES = True
37 except ImportError:
37 except ImportError:
38 HAS_CTYPES = False
38 HAS_CTYPES = False
39
39
40 # IPython imports
40 # IPython imports
41 import IPython
41 import IPython
42 from IPython import ultraTB, ipapi
42 from IPython import ultraTB, ipapi
43 from IPython.genutils import Term,warn,error,flag_calls, ask_yes_no
43 from IPython.genutils import Term,warn,error,flag_calls, ask_yes_no
44 from IPython.iplib import InteractiveShell
44 from IPython.iplib import InteractiveShell
45 from IPython.ipmaker import make_IPython
45 from IPython.ipmaker import make_IPython
46 from IPython.Magic import Magic
46 from IPython.Magic import Magic
47 from IPython.ipstruct import Struct
47 from IPython.ipstruct import Struct
48
48
49 # Globals
49 # Globals
50 # global flag to pass around information about Ctrl-C without exceptions
50 # global flag to pass around information about Ctrl-C without exceptions
51 KBINT = False
51 KBINT = False
52
52
53 # global flag to turn on/off Tk support.
53 # global flag to turn on/off Tk support.
54 USE_TK = False
54 USE_TK = False
55
55
56 # ID for the main thread, used for cross-thread exceptions
56 # ID for the main thread, used for cross-thread exceptions
57 MAIN_THREAD_ID = thread.get_ident()
57 MAIN_THREAD_ID = thread.get_ident()
58
58
59 # Tag when runcode() is active, for exception handling
59 # Tag when runcode() is active, for exception handling
60 CODE_RUN = None
60 CODE_RUN = None
61
61
62 #-----------------------------------------------------------------------------
62 #-----------------------------------------------------------------------------
63 # This class is trivial now, but I want to have it in to publish a clean
63 # This class is trivial now, but I want to have it in to publish a clean
64 # interface. Later when the internals are reorganized, code that uses this
64 # interface. Later when the internals are reorganized, code that uses this
65 # shouldn't have to change.
65 # shouldn't have to change.
66
66
67 class IPShell:
67 class IPShell:
68 """Create an IPython instance."""
68 """Create an IPython instance."""
69
69
70 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
70 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
71 debug=1,shell_class=InteractiveShell):
71 debug=1,shell_class=InteractiveShell):
72 self.IP = make_IPython(argv,user_ns=user_ns,
72 self.IP = make_IPython(argv,user_ns=user_ns,
73 user_global_ns=user_global_ns,
73 user_global_ns=user_global_ns,
74 debug=debug,shell_class=shell_class)
74 debug=debug,shell_class=shell_class)
75
75
76 def mainloop(self,sys_exit=0,banner=None):
76 def mainloop(self,sys_exit=0,banner=None):
77 self.IP.mainloop(banner)
77 self.IP.mainloop(banner)
78 if sys_exit:
78 if sys_exit:
79 sys.exit()
79 sys.exit()
80
80
81 #-----------------------------------------------------------------------------
81 #-----------------------------------------------------------------------------
82 def kill_embedded(self,parameter_s=''):
82 def kill_embedded(self,parameter_s=''):
83 """%kill_embedded : deactivate for good the current embedded IPython.
83 """%kill_embedded : deactivate for good the current embedded IPython.
84
84
85 This function (after asking for confirmation) sets an internal flag so that
85 This function (after asking for confirmation) sets an internal flag so that
86 an embedded IPython will never activate again. This is useful to
86 an embedded IPython will never activate again. This is useful to
87 permanently disable a shell that is being called inside a loop: once you've
87 permanently disable a shell that is being called inside a loop: once you've
88 figured out what you needed from it, you may then kill it and the program
88 figured out what you needed from it, you may then kill it and the program
89 will then continue to run without the interactive shell interfering again.
89 will then continue to run without the interactive shell interfering again.
90 """
90 """
91
91
92 kill = ask_yes_no("Are you sure you want to kill this embedded instance "
92 kill = ask_yes_no("Are you sure you want to kill this embedded instance "
93 "(y/n)? [y/N] ",'n')
93 "(y/n)? [y/N] ",'n')
94 if kill:
94 if kill:
95 self.shell.embedded_active = False
95 self.shell.embedded_active = False
96 print "This embedded IPython will not reactivate anymore once you exit."
96 print "This embedded IPython will not reactivate anymore once you exit."
97
97
98 class IPShellEmbed:
98 class IPShellEmbed:
99 """Allow embedding an IPython shell into a running program.
99 """Allow embedding an IPython shell into a running program.
100
100
101 Instances of this class are callable, with the __call__ method being an
101 Instances of this class are callable, with the __call__ method being an
102 alias to the embed() method of an InteractiveShell instance.
102 alias to the embed() method of an InteractiveShell instance.
103
103
104 Usage (see also the example-embed.py file for a running example):
104 Usage (see also the example-embed.py file for a running example):
105
105
106 ipshell = IPShellEmbed([argv,banner,exit_msg,rc_override])
106 ipshell = IPShellEmbed([argv,banner,exit_msg,rc_override])
107
107
108 - argv: list containing valid command-line options for IPython, as they
108 - argv: list containing valid command-line options for IPython, as they
109 would appear in sys.argv[1:].
109 would appear in sys.argv[1:].
110
110
111 For example, the following command-line options:
111 For example, the following command-line options:
112
112
113 $ ipython -prompt_in1 'Input <\\#>' -colors LightBG
113 $ ipython -prompt_in1 'Input <\\#>' -colors LightBG
114
114
115 would be passed in the argv list as:
115 would be passed in the argv list as:
116
116
117 ['-prompt_in1','Input <\\#>','-colors','LightBG']
117 ['-prompt_in1','Input <\\#>','-colors','LightBG']
118
118
119 - banner: string which gets printed every time the interpreter starts.
119 - banner: string which gets printed every time the interpreter starts.
120
120
121 - exit_msg: string which gets printed every time the interpreter exits.
121 - exit_msg: string which gets printed every time the interpreter exits.
122
122
123 - rc_override: a dict or Struct of configuration options such as those
123 - rc_override: a dict or Struct of configuration options such as those
124 used by IPython. These options are read from your ~/.ipython/ipythonrc
124 used by IPython. These options are read from your ~/.ipython/ipythonrc
125 file when the Shell object is created. Passing an explicit rc_override
125 file when the Shell object is created. Passing an explicit rc_override
126 dict with any options you want allows you to override those values at
126 dict with any options you want allows you to override those values at
127 creation time without having to modify the file. This way you can create
127 creation time without having to modify the file. This way you can create
128 embeddable instances configured in any way you want without editing any
128 embeddable instances configured in any way you want without editing any
129 global files (thus keeping your interactive IPython configuration
129 global files (thus keeping your interactive IPython configuration
130 unchanged).
130 unchanged).
131
131
132 Then the ipshell instance can be called anywhere inside your code:
132 Then the ipshell instance can be called anywhere inside your code:
133
133
134 ipshell(header='') -> Opens up an IPython shell.
134 ipshell(header='') -> Opens up an IPython shell.
135
135
136 - header: string printed by the IPython shell upon startup. This can let
136 - header: string printed by the IPython shell upon startup. This can let
137 you know where in your code you are when dropping into the shell. Note
137 you know where in your code you are when dropping into the shell. Note
138 that 'banner' gets prepended to all calls, so header is used for
138 that 'banner' gets prepended to all calls, so header is used for
139 location-specific information.
139 location-specific information.
140
140
141 For more details, see the __call__ method below.
141 For more details, see the __call__ method below.
142
142
143 When the IPython shell is exited with Ctrl-D, normal program execution
143 When the IPython shell is exited with Ctrl-D, normal program execution
144 resumes.
144 resumes.
145
145
146 This functionality was inspired by a posting on comp.lang.python by cmkl
146 This functionality was inspired by a posting on comp.lang.python by cmkl
147 <cmkleffner@gmx.de> on Dec. 06/01 concerning similar uses of pyrepl, and
147 <cmkleffner@gmx.de> on Dec. 06/01 concerning similar uses of pyrepl, and
148 by the IDL stop/continue commands."""
148 by the IDL stop/continue commands."""
149
149
150 def __init__(self,argv=None,banner='',exit_msg=None,rc_override=None,
150 def __init__(self,argv=None,banner='',exit_msg=None,rc_override=None,
151 user_ns=None):
151 user_ns=None):
152 """Note that argv here is a string, NOT a list."""
152 """Note that argv here is a string, NOT a list."""
153 self.set_banner(banner)
153 self.set_banner(banner)
154 self.set_exit_msg(exit_msg)
154 self.set_exit_msg(exit_msg)
155 self.set_dummy_mode(0)
155 self.set_dummy_mode(0)
156
156
157 # sys.displayhook is a global, we need to save the user's original
157 # sys.displayhook is a global, we need to save the user's original
158 # Don't rely on __displayhook__, as the user may have changed that.
158 # Don't rely on __displayhook__, as the user may have changed that.
159 self.sys_displayhook_ori = sys.displayhook
159 self.sys_displayhook_ori = sys.displayhook
160
160
161 # save readline completer status
161 # save readline completer status
162 try:
162 try:
163 #print 'Save completer',sys.ipcompleter # dbg
163 #print 'Save completer',sys.ipcompleter # dbg
164 self.sys_ipcompleter_ori = sys.ipcompleter
164 self.sys_ipcompleter_ori = sys.ipcompleter
165 except:
165 except:
166 pass # not nested with IPython
166 pass # not nested with IPython
167
167
168 self.IP = make_IPython(argv,rc_override=rc_override,
168 self.IP = make_IPython(argv,rc_override=rc_override,
169 embedded=True,
169 embedded=True,
170 user_ns=user_ns)
170 user_ns=user_ns)
171
171
172 ip = ipapi.IPApi(self.IP)
172 ip = ipapi.IPApi(self.IP)
173 ip.expose_magic("kill_embedded",kill_embedded)
173 ip.expose_magic("kill_embedded",kill_embedded)
174
174
175 # copy our own displayhook also
175 # copy our own displayhook also
176 self.sys_displayhook_embed = sys.displayhook
176 self.sys_displayhook_embed = sys.displayhook
177 # and leave the system's display hook clean
177 # and leave the system's display hook clean
178 sys.displayhook = self.sys_displayhook_ori
178 sys.displayhook = self.sys_displayhook_ori
179 # don't use the ipython crash handler so that user exceptions aren't
179 # don't use the ipython crash handler so that user exceptions aren't
180 # trapped
180 # trapped
181 sys.excepthook = ultraTB.FormattedTB(color_scheme = self.IP.rc.colors,
181 sys.excepthook = ultraTB.FormattedTB(color_scheme = self.IP.rc.colors,
182 mode = self.IP.rc.xmode,
182 mode = self.IP.rc.xmode,
183 call_pdb = self.IP.rc.pdb)
183 call_pdb = self.IP.rc.pdb)
184 self.restore_system_completer()
184 self.restore_system_completer()
185
185
186 def restore_system_completer(self):
186 def restore_system_completer(self):
187 """Restores the readline completer which was in place.
187 """Restores the readline completer which was in place.
188
188
189 This allows embedded IPython within IPython not to disrupt the
189 This allows embedded IPython within IPython not to disrupt the
190 parent's completion.
190 parent's completion.
191 """
191 """
192
192
193 try:
193 try:
194 self.IP.readline.set_completer(self.sys_ipcompleter_ori)
194 self.IP.readline.set_completer(self.sys_ipcompleter_ori)
195 sys.ipcompleter = self.sys_ipcompleter_ori
195 sys.ipcompleter = self.sys_ipcompleter_ori
196 except:
196 except:
197 pass
197 pass
198
198
199 def __call__(self,header='',local_ns=None,global_ns=None,dummy=None):
199 def __call__(self,header='',local_ns=None,global_ns=None,dummy=None):
200 """Activate the interactive interpreter.
200 """Activate the interactive interpreter.
201
201
202 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
202 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
203 the interpreter shell with the given local and global namespaces, and
203 the interpreter shell with the given local and global namespaces, and
204 optionally print a header string at startup.
204 optionally print a header string at startup.
205
205
206 The shell can be globally activated/deactivated using the
206 The shell can be globally activated/deactivated using the
207 set/get_dummy_mode methods. This allows you to turn off a shell used
207 set/get_dummy_mode methods. This allows you to turn off a shell used
208 for debugging globally.
208 for debugging globally.
209
209
210 However, *each* time you call the shell you can override the current
210 However, *each* time you call the shell you can override the current
211 state of dummy_mode with the optional keyword parameter 'dummy'. For
211 state of dummy_mode with the optional keyword parameter 'dummy'. For
212 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
212 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
213 can still have a specific call work by making it as IPShell(dummy=0).
213 can still have a specific call work by making it as IPShell(dummy=0).
214
214
215 The optional keyword parameter dummy controls whether the call
215 The optional keyword parameter dummy controls whether the call
216 actually does anything. """
216 actually does anything. """
217
217
218 # If the user has turned it off, go away
218 # If the user has turned it off, go away
219 if not self.IP.embedded_active:
219 if not self.IP.embedded_active:
220 return
220 return
221
221
222 # Normal exits from interactive mode set this flag, so the shell can't
222 # Normal exits from interactive mode set this flag, so the shell can't
223 # re-enter (it checks this variable at the start of interactive mode).
223 # re-enter (it checks this variable at the start of interactive mode).
224 self.IP.exit_now = False
224 self.IP.exit_now = False
225
225
226 # Allow the dummy parameter to override the global __dummy_mode
226 # Allow the dummy parameter to override the global __dummy_mode
227 if dummy or (dummy != 0 and self.__dummy_mode):
227 if dummy or (dummy != 0 and self.__dummy_mode):
228 return
228 return
229
229
230 # Set global subsystems (display,completions) to our values
230 # Set global subsystems (display,completions) to our values
231 sys.displayhook = self.sys_displayhook_embed
231 sys.displayhook = self.sys_displayhook_embed
232 if self.IP.has_readline:
232 if self.IP.has_readline:
233 self.IP.set_completer()
233 self.IP.set_completer()
234
234
235 if self.banner and header:
235 if self.banner and header:
236 format = '%s\n%s\n'
236 format = '%s\n%s\n'
237 else:
237 else:
238 format = '%s%s\n'
238 format = '%s%s\n'
239 banner = format % (self.banner,header)
239 banner = format % (self.banner,header)
240
240
241 # Call the embedding code with a stack depth of 1 so it can skip over
241 # Call the embedding code with a stack depth of 1 so it can skip over
242 # our call and get the original caller's namespaces.
242 # our call and get the original caller's namespaces.
243 self.IP.embed_mainloop(banner,local_ns,global_ns,stack_depth=1)
243 self.IP.embed_mainloop(banner,local_ns,global_ns,stack_depth=1)
244
244
245 if self.exit_msg:
245 if self.exit_msg:
246 print self.exit_msg
246 print self.exit_msg
247
247
248 # Restore global systems (display, completion)
248 # Restore global systems (display, completion)
249 sys.displayhook = self.sys_displayhook_ori
249 sys.displayhook = self.sys_displayhook_ori
250 self.restore_system_completer()
250 self.restore_system_completer()
251
251
252 def set_dummy_mode(self,dummy):
252 def set_dummy_mode(self,dummy):
253 """Sets the embeddable shell's dummy mode parameter.
253 """Sets the embeddable shell's dummy mode parameter.
254
254
255 set_dummy_mode(dummy): dummy = 0 or 1.
255 set_dummy_mode(dummy): dummy = 0 or 1.
256
256
257 This parameter is persistent and makes calls to the embeddable shell
257 This parameter is persistent and makes calls to the embeddable shell
258 silently return without performing any action. This allows you to
258 silently return without performing any action. This allows you to
259 globally activate or deactivate a shell you're using with a single call.
259 globally activate or deactivate a shell you're using with a single call.
260
260
261 If you need to manually"""
261 If you need to manually"""
262
262
263 if dummy not in [0,1,False,True]:
263 if dummy not in [0,1,False,True]:
264 raise ValueError,'dummy parameter must be boolean'
264 raise ValueError,'dummy parameter must be boolean'
265 self.__dummy_mode = dummy
265 self.__dummy_mode = dummy
266
266
267 def get_dummy_mode(self):
267 def get_dummy_mode(self):
268 """Return the current value of the dummy mode parameter.
268 """Return the current value of the dummy mode parameter.
269 """
269 """
270 return self.__dummy_mode
270 return self.__dummy_mode
271
271
272 def set_banner(self,banner):
272 def set_banner(self,banner):
273 """Sets the global banner.
273 """Sets the global banner.
274
274
275 This banner gets prepended to every header printed when the shell
275 This banner gets prepended to every header printed when the shell
276 instance is called."""
276 instance is called."""
277
277
278 self.banner = banner
278 self.banner = banner
279
279
280 def set_exit_msg(self,exit_msg):
280 def set_exit_msg(self,exit_msg):
281 """Sets the global exit_msg.
281 """Sets the global exit_msg.
282
282
283 This exit message gets printed upon exiting every time the embedded
283 This exit message gets printed upon exiting every time the embedded
284 shell is called. It is None by default. """
284 shell is called. It is None by default. """
285
285
286 self.exit_msg = exit_msg
286 self.exit_msg = exit_msg
287
287
288 #-----------------------------------------------------------------------------
288 #-----------------------------------------------------------------------------
289 if HAS_CTYPES:
289 if HAS_CTYPES:
290 # Add async exception support. Trick taken from:
290 # Add async exception support. Trick taken from:
291 # http://sebulba.wikispaces.com/recipe+thread2
291 # http://sebulba.wikispaces.com/recipe+thread2
292 def _async_raise(tid, exctype):
292 def _async_raise(tid, exctype):
293 """raises the exception, performs cleanup if needed"""
293 """raises the exception, performs cleanup if needed"""
294 if not inspect.isclass(exctype):
294 if not inspect.isclass(exctype):
295 raise TypeError("Only types can be raised (not instances)")
295 raise TypeError("Only types can be raised (not instances)")
296 res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,
296 res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,
297 ctypes.py_object(exctype))
297 ctypes.py_object(exctype))
298 if res == 0:
298 if res == 0:
299 raise ValueError("invalid thread id")
299 raise ValueError("invalid thread id")
300 elif res != 1:
300 elif res != 1:
301 # """if it returns a number greater than one, you're in trouble,
301 # """if it returns a number greater than one, you're in trouble,
302 # and you should call it again with exc=NULL to revert the effect"""
302 # and you should call it again with exc=NULL to revert the effect"""
303 ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
303 ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
304 raise SystemError("PyThreadState_SetAsyncExc failed")
304 raise SystemError("PyThreadState_SetAsyncExc failed")
305
305
306 def sigint_handler (signum,stack_frame):
306 def sigint_handler (signum,stack_frame):
307 """Sigint handler for threaded apps.
307 """Sigint handler for threaded apps.
308
308
309 This is a horrible hack to pass information about SIGINT _without_
309 This is a horrible hack to pass information about SIGINT _without_
310 using exceptions, since I haven't been able to properly manage
310 using exceptions, since I haven't been able to properly manage
311 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
311 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
312 done (or at least that's my understanding from a c.l.py thread where
312 done (or at least that's my understanding from a c.l.py thread where
313 this was discussed)."""
313 this was discussed)."""
314
314
315 global KBINT
315 global KBINT
316
316
317 if CODE_RUN:
317 if CODE_RUN:
318 _async_raise(MAIN_THREAD_ID,KeyboardInterrupt)
318 _async_raise(MAIN_THREAD_ID,KeyboardInterrupt)
319 else:
319 else:
320 KBINT = True
320 KBINT = True
321 print '\nKeyboardInterrupt - Press <Enter> to continue.',
321 print '\nKeyboardInterrupt - Press <Enter> to continue.',
322 Term.cout.flush()
322 Term.cout.flush()
323
323
324 else:
324 else:
325 def sigint_handler (signum,stack_frame):
325 def sigint_handler (signum,stack_frame):
326 """Sigint handler for threaded apps.
326 """Sigint handler for threaded apps.
327
327
328 This is a horrible hack to pass information about SIGINT _without_
328 This is a horrible hack to pass information about SIGINT _without_
329 using exceptions, since I haven't been able to properly manage
329 using exceptions, since I haven't been able to properly manage
330 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
330 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
331 done (or at least that's my understanding from a c.l.py thread where
331 done (or at least that's my understanding from a c.l.py thread where
332 this was discussed)."""
332 this was discussed)."""
333
333
334 global KBINT
334 global KBINT
335
335
336 print '\nKeyboardInterrupt - Press <Enter> to continue.',
336 print '\nKeyboardInterrupt - Press <Enter> to continue.',
337 Term.cout.flush()
337 Term.cout.flush()
338 # Set global flag so that runsource can know that Ctrl-C was hit
338 # Set global flag so that runsource can know that Ctrl-C was hit
339 KBINT = True
339 KBINT = True
340
340
341
341
342 class MTInteractiveShell(InteractiveShell):
342 class MTInteractiveShell(InteractiveShell):
343 """Simple multi-threaded shell."""
343 """Simple multi-threaded shell."""
344
344
345 # Threading strategy taken from:
345 # Threading strategy taken from:
346 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109, by Brian
346 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109, by Brian
347 # McErlean and John Finlay. Modified with corrections by Antoon Pardon,
347 # McErlean and John Finlay. Modified with corrections by Antoon Pardon,
348 # from the pygtk mailing list, to avoid lockups with system calls.
348 # from the pygtk mailing list, to avoid lockups with system calls.
349
349
350 # class attribute to indicate whether the class supports threads or not.
350 # class attribute to indicate whether the class supports threads or not.
351 # Subclasses with thread support should override this as needed.
351 # Subclasses with thread support should override this as needed.
352 isthreaded = True
352 isthreaded = True
353
353
354 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
354 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
355 user_ns=None,user_global_ns=None,banner2='',**kw):
355 user_ns=None,user_global_ns=None,banner2='',**kw):
356 """Similar to the normal InteractiveShell, but with threading control"""
356 """Similar to the normal InteractiveShell, but with threading control"""
357
357
358 InteractiveShell.__init__(self,name,usage,rc,user_ns,
358 InteractiveShell.__init__(self,name,usage,rc,user_ns,
359 user_global_ns,banner2)
359 user_global_ns,banner2)
360
360
361
361
362 # A queue to hold the code to be executed.
362 # A queue to hold the code to be executed.
363 self.code_queue = Queue.Queue()
363 self.code_queue = Queue.Queue()
364
364
365 # Stuff to do at closing time
365 # Stuff to do at closing time
366 self._kill = None
366 self._kill = None
367 on_kill = kw.get('on_kill', [])
367 on_kill = kw.get('on_kill', [])
368 # Check that all things to kill are callable:
368 # Check that all things to kill are callable:
369 for t in on_kill:
369 for t in on_kill:
370 if not callable(t):
370 if not callable(t):
371 raise TypeError,'on_kill must be a list of callables'
371 raise TypeError,'on_kill must be a list of callables'
372 self.on_kill = on_kill
372 self.on_kill = on_kill
373 # thread identity of the "worker thread" (that may execute code directly)
373 # thread identity of the "worker thread" (that may execute code directly)
374 self.worker_ident = None
374 self.worker_ident = None
375
375
376 def runsource(self, source, filename="<input>", symbol="single"):
376 def runsource(self, source, filename="<input>", symbol="single"):
377 """Compile and run some source in the interpreter.
377 """Compile and run some source in the interpreter.
378
378
379 Modified version of code.py's runsource(), to handle threading issues.
379 Modified version of code.py's runsource(), to handle threading issues.
380 See the original for full docstring details."""
380 See the original for full docstring details."""
381
381
382 global KBINT
382 global KBINT
383
383
384 # If Ctrl-C was typed, we reset the flag and return right away
384 # If Ctrl-C was typed, we reset the flag and return right away
385 if KBINT:
385 if KBINT:
386 KBINT = False
386 KBINT = False
387 return False
387 return False
388
388
389 if self._kill:
389 if self._kill:
390 # can't queue new code if we are being killed
390 # can't queue new code if we are being killed
391 return True
391 return True
392
392
393 try:
393 try:
394 code = self.compile(source, filename, symbol)
394 code = self.compile(source, filename, symbol)
395 except (OverflowError, SyntaxError, ValueError):
395 except (OverflowError, SyntaxError, ValueError):
396 # Case 1
396 # Case 1
397 self.showsyntaxerror(filename)
397 self.showsyntaxerror(filename)
398 return False
398 return False
399
399
400 if code is None:
400 if code is None:
401 # Case 2
401 # Case 2
402 return True
402 return True
403
403
404 # shortcut - if we are in worker thread, or the worker thread is not running,
404 # shortcut - if we are in worker thread, or the worker thread is not running,
405 # execute directly (to allow recursion and prevent deadlock if code is run early
405 # execute directly (to allow recursion and prevent deadlock if code is run early
406 # in IPython construction)
406 # in IPython construction)
407
407
408 if self.worker_ident is None or self.worker_ident == thread.get_ident():
408 if (self.worker_ident is None or self.worker_ident == thread.get_ident()):
409 InteractiveShell.runcode(self,code)
409 InteractiveShell.runcode(self,code)
410 return
410 return
411
411
412 # Case 3
412 # Case 3
413 # Store code in queue, so the execution thread can handle it.
413 # Store code in queue, so the execution thread can handle it.
414
414
415 completed_ev, received_ev = threading.Event(), threading.Event()
415 completed_ev, received_ev = threading.Event(), threading.Event()
416
416
417 self.code_queue.put((code,completed_ev, received_ev))
417 self.code_queue.put((code,completed_ev, received_ev))
418 # first make sure the message was received, with timeout
418 # first make sure the message was received, with timeout
419 received_ev.wait(5)
419 received_ev.wait(5)
420 if not received_ev.isSet():
420 if not received_ev.isSet():
421 # the mainloop is dead, start executing code directly
421 # the mainloop is dead, start executing code directly
422 print "Warning: Timeout for mainloop thread exceeded"
422 print "Warning: Timeout for mainloop thread exceeded"
423 print "switching to nonthreaded mode (until mainloop wakes up again)"
423 print "switching to nonthreaded mode (until mainloop wakes up again)"
424 self.worker_ident = None
424 self.worker_ident = None
425 else:
425 else:
426 completed_ev.wait()
426 completed_ev.wait()
427 return False
427 return False
428
428
429 def runcode(self):
429 def runcode(self):
430 """Execute a code object.
430 """Execute a code object.
431
431
432 Multithreaded wrapper around IPython's runcode()."""
432 Multithreaded wrapper around IPython's runcode()."""
433
433
434 global CODE_RUN
434 global CODE_RUN
435
435
436 # we are in worker thread, stash out the id for runsource()
436 # we are in worker thread, stash out the id for runsource()
437 self.worker_ident = thread.get_ident()
437 self.worker_ident = thread.get_ident()
438
438
439 if self._kill:
439 if self._kill:
440 print >>Term.cout, 'Closing threads...',
440 print >>Term.cout, 'Closing threads...',
441 Term.cout.flush()
441 Term.cout.flush()
442 for tokill in self.on_kill:
442 for tokill in self.on_kill:
443 tokill()
443 tokill()
444 print >>Term.cout, 'Done.'
444 print >>Term.cout, 'Done.'
445 # allow kill() to return
445 # allow kill() to return
446 self._kill.set()
446 self._kill.set()
447 return True
447 return True
448
448
449 # Install sigint handler. We do it every time to ensure that if user
449 # Install sigint handler. We do it every time to ensure that if user
450 # code modifies it, we restore our own handling.
450 # code modifies it, we restore our own handling.
451 try:
451 try:
452 signal(SIGINT,sigint_handler)
452 signal(SIGINT,sigint_handler)
453 except SystemError:
453 except SystemError:
454 # This happens under Windows, which seems to have all sorts
454 # This happens under Windows, which seems to have all sorts
455 # of problems with signal handling. Oh well...
455 # of problems with signal handling. Oh well...
456 pass
456 pass
457
457
458 # Flush queue of pending code by calling the run methood of the parent
458 # Flush queue of pending code by calling the run methood of the parent
459 # class with all items which may be in the queue.
459 # class with all items which may be in the queue.
460 code_to_run = None
460 code_to_run = None
461 while 1:
461 while 1:
462 try:
462 try:
463 code_to_run, completed_ev, received_ev = self.code_queue.get_nowait()
463 code_to_run, completed_ev, received_ev = self.code_queue.get_nowait()
464 except Queue.Empty:
464 except Queue.Empty:
465 break
465 break
466 received_ev.set()
466 received_ev.set()
467
467
468 # Exceptions need to be raised differently depending on which
468 # Exceptions need to be raised differently depending on which
469 # thread is active. This convoluted try/except is only there to
469 # thread is active. This convoluted try/except is only there to
470 # protect against asynchronous exceptions, to ensure that a KBINT
470 # protect against asynchronous exceptions, to ensure that a KBINT
471 # at the wrong time doesn't deadlock everything. The global
471 # at the wrong time doesn't deadlock everything. The global
472 # CODE_TO_RUN is set to true/false as close as possible to the
472 # CODE_TO_RUN is set to true/false as close as possible to the
473 # runcode() call, so that the KBINT handler is correctly informed.
473 # runcode() call, so that the KBINT handler is correctly informed.
474 try:
474 try:
475 try:
475 try:
476 CODE_RUN = True
476 CODE_RUN = True
477 InteractiveShell.runcode(self,code_to_run)
477 InteractiveShell.runcode(self,code_to_run)
478 except KeyboardInterrupt:
478 except KeyboardInterrupt:
479 print "Keyboard interrupted in mainloop"
479 print "Keyboard interrupted in mainloop"
480 while not self.code_queue.empty():
480 while not self.code_queue.empty():
481 code, ev1,ev2 = self.code_queue.get_nowait()
481 code, ev1,ev2 = self.code_queue.get_nowait()
482 ev1.set()
482 ev1.set()
483 ev2.set()
483 ev2.set()
484 break
484 break
485 finally:
485 finally:
486 CODE_RUN = False
486 CODE_RUN = False
487 # allow runsource() return from wait
487 # allow runsource() return from wait
488 completed_ev.set()
488 completed_ev.set()
489
489
490
490
491 # This MUST return true for gtk threading to work
491 # This MUST return true for gtk threading to work
492 return True
492 return True
493
493
494 def kill(self):
494 def kill(self):
495 """Kill the thread, returning when it has been shut down."""
495 """Kill the thread, returning when it has been shut down."""
496 self._kill = threading.Event()
496 self._kill = threading.Event()
497 self._kill.wait()
497 self._kill.wait()
498
498
499 class MatplotlibShellBase:
499 class MatplotlibShellBase:
500 """Mixin class to provide the necessary modifications to regular IPython
500 """Mixin class to provide the necessary modifications to regular IPython
501 shell classes for matplotlib support.
501 shell classes for matplotlib support.
502
502
503 Given Python's MRO, this should be used as the FIRST class in the
503 Given Python's MRO, this should be used as the FIRST class in the
504 inheritance hierarchy, so that it overrides the relevant methods."""
504 inheritance hierarchy, so that it overrides the relevant methods."""
505
505
506 def _matplotlib_config(self,name,user_ns):
506 def _matplotlib_config(self,name,user_ns):
507 """Return items needed to setup the user's shell with matplotlib"""
507 """Return items needed to setup the user's shell with matplotlib"""
508
508
509 # Initialize matplotlib to interactive mode always
509 # Initialize matplotlib to interactive mode always
510 import matplotlib
510 import matplotlib
511 from matplotlib import backends
511 from matplotlib import backends
512 matplotlib.interactive(True)
512 matplotlib.interactive(True)
513
513
514 def use(arg):
514 def use(arg):
515 """IPython wrapper for matplotlib's backend switcher.
515 """IPython wrapper for matplotlib's backend switcher.
516
516
517 In interactive use, we can not allow switching to a different
517 In interactive use, we can not allow switching to a different
518 interactive backend, since thread conflicts will most likely crash
518 interactive backend, since thread conflicts will most likely crash
519 the python interpreter. This routine does a safety check first,
519 the python interpreter. This routine does a safety check first,
520 and refuses to perform a dangerous switch. It still allows
520 and refuses to perform a dangerous switch. It still allows
521 switching to non-interactive backends."""
521 switching to non-interactive backends."""
522
522
523 if arg in backends.interactive_bk and arg != self.mpl_backend:
523 if arg in backends.interactive_bk and arg != self.mpl_backend:
524 m=('invalid matplotlib backend switch.\n'
524 m=('invalid matplotlib backend switch.\n'
525 'This script attempted to switch to the interactive '
525 'This script attempted to switch to the interactive '
526 'backend: `%s`\n'
526 'backend: `%s`\n'
527 'Your current choice of interactive backend is: `%s`\n\n'
527 'Your current choice of interactive backend is: `%s`\n\n'
528 'Switching interactive matplotlib backends at runtime\n'
528 'Switching interactive matplotlib backends at runtime\n'
529 'would crash the python interpreter, '
529 'would crash the python interpreter, '
530 'and IPython has blocked it.\n\n'
530 'and IPython has blocked it.\n\n'
531 'You need to either change your choice of matplotlib backend\n'
531 'You need to either change your choice of matplotlib backend\n'
532 'by editing your .matplotlibrc file, or run this script as a \n'
532 'by editing your .matplotlibrc file, or run this script as a \n'
533 'standalone file from the command line, not using IPython.\n' %
533 'standalone file from the command line, not using IPython.\n' %
534 (arg,self.mpl_backend) )
534 (arg,self.mpl_backend) )
535 raise RuntimeError, m
535 raise RuntimeError, m
536 else:
536 else:
537 self.mpl_use(arg)
537 self.mpl_use(arg)
538 self.mpl_use._called = True
538 self.mpl_use._called = True
539
539
540 self.matplotlib = matplotlib
540 self.matplotlib = matplotlib
541 self.mpl_backend = matplotlib.rcParams['backend']
541 self.mpl_backend = matplotlib.rcParams['backend']
542
542
543 # we also need to block switching of interactive backends by use()
543 # we also need to block switching of interactive backends by use()
544 self.mpl_use = matplotlib.use
544 self.mpl_use = matplotlib.use
545 self.mpl_use._called = False
545 self.mpl_use._called = False
546 # overwrite the original matplotlib.use with our wrapper
546 # overwrite the original matplotlib.use with our wrapper
547 matplotlib.use = use
547 matplotlib.use = use
548
548
549 # This must be imported last in the matplotlib series, after
549 # This must be imported last in the matplotlib series, after
550 # backend/interactivity choices have been made
550 # backend/interactivity choices have been made
551 import matplotlib.pylab as pylab
551 import matplotlib.pylab as pylab
552 self.pylab = pylab
552 self.pylab = pylab
553
553
554 self.pylab.show._needmain = False
554 self.pylab.show._needmain = False
555 # We need to detect at runtime whether show() is called by the user.
555 # We need to detect at runtime whether show() is called by the user.
556 # For this, we wrap it into a decorator which adds a 'called' flag.
556 # For this, we wrap it into a decorator which adds a 'called' flag.
557 self.pylab.draw_if_interactive = flag_calls(self.pylab.draw_if_interactive)
557 self.pylab.draw_if_interactive = flag_calls(self.pylab.draw_if_interactive)
558
558
559 # Build a user namespace initialized with matplotlib/matlab features.
559 # Build a user namespace initialized with matplotlib/matlab features.
560 user_ns = IPython.ipapi.make_user_ns(user_ns)
560 user_ns = IPython.ipapi.make_user_ns(user_ns)
561
561
562 exec ("import matplotlib\n"
562 exec ("import matplotlib\n"
563 "import matplotlib.pylab as pylab\n") in user_ns
563 "import matplotlib.pylab as pylab\n") in user_ns
564
564
565 # Build matplotlib info banner
565 # Build matplotlib info banner
566 b="""
566 b="""
567 Welcome to pylab, a matplotlib-based Python environment.
567 Welcome to pylab, a matplotlib-based Python environment.
568 For more information, type 'help(pylab)'.
568 For more information, type 'help(pylab)'.
569 """
569 """
570 return user_ns,b
570 return user_ns,b
571
571
572 def mplot_exec(self,fname,*where,**kw):
572 def mplot_exec(self,fname,*where,**kw):
573 """Execute a matplotlib script.
573 """Execute a matplotlib script.
574
574
575 This is a call to execfile(), but wrapped in safeties to properly
575 This is a call to execfile(), but wrapped in safeties to properly
576 handle interactive rendering and backend switching."""
576 handle interactive rendering and backend switching."""
577
577
578 #print '*** Matplotlib runner ***' # dbg
578 #print '*** Matplotlib runner ***' # dbg
579 # turn off rendering until end of script
579 # turn off rendering until end of script
580 isInteractive = self.matplotlib.rcParams['interactive']
580 isInteractive = self.matplotlib.rcParams['interactive']
581 self.matplotlib.interactive(False)
581 self.matplotlib.interactive(False)
582 self.safe_execfile(fname,*where,**kw)
582 self.safe_execfile(fname,*where,**kw)
583 self.matplotlib.interactive(isInteractive)
583 self.matplotlib.interactive(isInteractive)
584 # make rendering call now, if the user tried to do it
584 # make rendering call now, if the user tried to do it
585 if self.pylab.draw_if_interactive.called:
585 if self.pylab.draw_if_interactive.called:
586 self.pylab.draw()
586 self.pylab.draw()
587 self.pylab.draw_if_interactive.called = False
587 self.pylab.draw_if_interactive.called = False
588
588
589 # if a backend switch was performed, reverse it now
589 # if a backend switch was performed, reverse it now
590 if self.mpl_use._called:
590 if self.mpl_use._called:
591 self.matplotlib.rcParams['backend'] = self.mpl_backend
591 self.matplotlib.rcParams['backend'] = self.mpl_backend
592
592
593 def magic_run(self,parameter_s=''):
593 def magic_run(self,parameter_s=''):
594 Magic.magic_run(self,parameter_s,runner=self.mplot_exec)
594 Magic.magic_run(self,parameter_s,runner=self.mplot_exec)
595
595
596 # Fix the docstring so users see the original as well
596 # Fix the docstring so users see the original as well
597 magic_run.__doc__ = "%s\n%s" % (Magic.magic_run.__doc__,
597 magic_run.__doc__ = "%s\n%s" % (Magic.magic_run.__doc__,
598 "\n *** Modified %run for Matplotlib,"
598 "\n *** Modified %run for Matplotlib,"
599 " with proper interactive handling ***")
599 " with proper interactive handling ***")
600
600
601 # Now we provide 2 versions of a matplotlib-aware IPython base shells, single
601 # Now we provide 2 versions of a matplotlib-aware IPython base shells, single
602 # and multithreaded. Note that these are meant for internal use, the IPShell*
602 # and multithreaded. Note that these are meant for internal use, the IPShell*
603 # classes below are the ones meant for public consumption.
603 # classes below are the ones meant for public consumption.
604
604
605 class MatplotlibShell(MatplotlibShellBase,InteractiveShell):
605 class MatplotlibShell(MatplotlibShellBase,InteractiveShell):
606 """Single-threaded shell with matplotlib support."""
606 """Single-threaded shell with matplotlib support."""
607
607
608 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
608 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
609 user_ns=None,user_global_ns=None,**kw):
609 user_ns=None,user_global_ns=None,**kw):
610 user_ns,b2 = self._matplotlib_config(name,user_ns)
610 user_ns,b2 = self._matplotlib_config(name,user_ns)
611 InteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
611 InteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
612 banner2=b2,**kw)
612 banner2=b2,**kw)
613
613
614 class MatplotlibMTShell(MatplotlibShellBase,MTInteractiveShell):
614 class MatplotlibMTShell(MatplotlibShellBase,MTInteractiveShell):
615 """Multi-threaded shell with matplotlib support."""
615 """Multi-threaded shell with matplotlib support."""
616
616
617 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
617 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
618 user_ns=None,user_global_ns=None, **kw):
618 user_ns=None,user_global_ns=None, **kw):
619 user_ns,b2 = self._matplotlib_config(name,user_ns)
619 user_ns,b2 = self._matplotlib_config(name,user_ns)
620 MTInteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
620 MTInteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
621 banner2=b2,**kw)
621 banner2=b2,**kw)
622
622
623 #-----------------------------------------------------------------------------
623 #-----------------------------------------------------------------------------
624 # Utility functions for the different GUI enabled IPShell* classes.
624 # Utility functions for the different GUI enabled IPShell* classes.
625
625
626 def get_tk():
626 def get_tk():
627 """Tries to import Tkinter and returns a withdrawn Tkinter root
627 """Tries to import Tkinter and returns a withdrawn Tkinter root
628 window. If Tkinter is already imported or not available, this
628 window. If Tkinter is already imported or not available, this
629 returns None. This function calls `hijack_tk` underneath.
629 returns None. This function calls `hijack_tk` underneath.
630 """
630 """
631 if not USE_TK or sys.modules.has_key('Tkinter'):
631 if not USE_TK or sys.modules.has_key('Tkinter'):
632 return None
632 return None
633 else:
633 else:
634 try:
634 try:
635 import Tkinter
635 import Tkinter
636 except ImportError:
636 except ImportError:
637 return None
637 return None
638 else:
638 else:
639 hijack_tk()
639 hijack_tk()
640 r = Tkinter.Tk()
640 r = Tkinter.Tk()
641 r.withdraw()
641 r.withdraw()
642 return r
642 return r
643
643
644 def hijack_tk():
644 def hijack_tk():
645 """Modifies Tkinter's mainloop with a dummy so when a module calls
645 """Modifies Tkinter's mainloop with a dummy so when a module calls
646 mainloop, it does not block.
646 mainloop, it does not block.
647
647
648 """
648 """
649 def misc_mainloop(self, n=0):
649 def misc_mainloop(self, n=0):
650 pass
650 pass
651 def tkinter_mainloop(n=0):
651 def tkinter_mainloop(n=0):
652 pass
652 pass
653
653
654 import Tkinter
654 import Tkinter
655 Tkinter.Misc.mainloop = misc_mainloop
655 Tkinter.Misc.mainloop = misc_mainloop
656 Tkinter.mainloop = tkinter_mainloop
656 Tkinter.mainloop = tkinter_mainloop
657
657
658 def update_tk(tk):
658 def update_tk(tk):
659 """Updates the Tkinter event loop. This is typically called from
659 """Updates the Tkinter event loop. This is typically called from
660 the respective WX or GTK mainloops.
660 the respective WX or GTK mainloops.
661 """
661 """
662 if tk:
662 if tk:
663 tk.update()
663 tk.update()
664
664
665 def hijack_wx():
665 def hijack_wx():
666 """Modifies wxPython's MainLoop with a dummy so user code does not
666 """Modifies wxPython's MainLoop with a dummy so user code does not
667 block IPython. The hijacked mainloop function is returned.
667 block IPython. The hijacked mainloop function is returned.
668 """
668 """
669 def dummy_mainloop(*args, **kw):
669 def dummy_mainloop(*args, **kw):
670 pass
670 pass
671
671
672 try:
672 try:
673 import wx
673 import wx
674 except ImportError:
674 except ImportError:
675 # For very old versions of WX
675 # For very old versions of WX
676 import wxPython as wx
676 import wxPython as wx
677
677
678 ver = wx.__version__
678 ver = wx.__version__
679 orig_mainloop = None
679 orig_mainloop = None
680 if ver[:3] >= '2.5':
680 if ver[:3] >= '2.5':
681 import wx
681 import wx
682 if hasattr(wx, '_core_'): core = getattr(wx, '_core_')
682 if hasattr(wx, '_core_'): core = getattr(wx, '_core_')
683 elif hasattr(wx, '_core'): core = getattr(wx, '_core')
683 elif hasattr(wx, '_core'): core = getattr(wx, '_core')
684 else: raise AttributeError('Could not find wx core module')
684 else: raise AttributeError('Could not find wx core module')
685 orig_mainloop = core.PyApp_MainLoop
685 orig_mainloop = core.PyApp_MainLoop
686 core.PyApp_MainLoop = dummy_mainloop
686 core.PyApp_MainLoop = dummy_mainloop
687 elif ver[:3] == '2.4':
687 elif ver[:3] == '2.4':
688 orig_mainloop = wx.wxc.wxPyApp_MainLoop
688 orig_mainloop = wx.wxc.wxPyApp_MainLoop
689 wx.wxc.wxPyApp_MainLoop = dummy_mainloop
689 wx.wxc.wxPyApp_MainLoop = dummy_mainloop
690 else:
690 else:
691 warn("Unable to find either wxPython version 2.4 or >= 2.5.")
691 warn("Unable to find either wxPython version 2.4 or >= 2.5.")
692 return orig_mainloop
692 return orig_mainloop
693
693
694 def hijack_gtk():
694 def hijack_gtk():
695 """Modifies pyGTK's mainloop with a dummy so user code does not
695 """Modifies pyGTK's mainloop with a dummy so user code does not
696 block IPython. This function returns the original `gtk.mainloop`
696 block IPython. This function returns the original `gtk.mainloop`
697 function that has been hijacked.
697 function that has been hijacked.
698 """
698 """
699 def dummy_mainloop(*args, **kw):
699 def dummy_mainloop(*args, **kw):
700 pass
700 pass
701 import gtk
701 import gtk
702 if gtk.pygtk_version >= (2,4,0): orig_mainloop = gtk.main
702 if gtk.pygtk_version >= (2,4,0): orig_mainloop = gtk.main
703 else: orig_mainloop = gtk.mainloop
703 else: orig_mainloop = gtk.mainloop
704 gtk.mainloop = dummy_mainloop
704 gtk.mainloop = dummy_mainloop
705 gtk.main = dummy_mainloop
705 gtk.main = dummy_mainloop
706 return orig_mainloop
706 return orig_mainloop
707
707
708 def hijack_qt():
708 def hijack_qt():
709 """Modifies PyQt's mainloop with a dummy so user code does not
709 """Modifies PyQt's mainloop with a dummy so user code does not
710 block IPython. This function returns the original
710 block IPython. This function returns the original
711 `qt.qApp.exec_loop` function that has been hijacked.
711 `qt.qApp.exec_loop` function that has been hijacked.
712 """
712 """
713 def dummy_mainloop(*args, **kw):
713 def dummy_mainloop(*args, **kw):
714 pass
714 pass
715 import qt
715 import qt
716 orig_mainloop = qt.qApp.exec_loop
716 orig_mainloop = qt.qApp.exec_loop
717 qt.qApp.exec_loop = dummy_mainloop
717 qt.qApp.exec_loop = dummy_mainloop
718 qt.QApplication.exec_loop = dummy_mainloop
718 qt.QApplication.exec_loop = dummy_mainloop
719 return orig_mainloop
719 return orig_mainloop
720
720
721 def hijack_qt4():
721 def hijack_qt4():
722 """Modifies PyQt4's mainloop with a dummy so user code does not
722 """Modifies PyQt4's mainloop with a dummy so user code does not
723 block IPython. This function returns the original
723 block IPython. This function returns the original
724 `QtGui.qApp.exec_` function that has been hijacked.
724 `QtGui.qApp.exec_` function that has been hijacked.
725 """
725 """
726 def dummy_mainloop(*args, **kw):
726 def dummy_mainloop(*args, **kw):
727 pass
727 pass
728 from PyQt4 import QtGui, QtCore
728 from PyQt4 import QtGui, QtCore
729 orig_mainloop = QtGui.qApp.exec_
729 orig_mainloop = QtGui.qApp.exec_
730 QtGui.qApp.exec_ = dummy_mainloop
730 QtGui.qApp.exec_ = dummy_mainloop
731 QtGui.QApplication.exec_ = dummy_mainloop
731 QtGui.QApplication.exec_ = dummy_mainloop
732 QtCore.QCoreApplication.exec_ = dummy_mainloop
732 QtCore.QCoreApplication.exec_ = dummy_mainloop
733 return orig_mainloop
733 return orig_mainloop
734
734
735 #-----------------------------------------------------------------------------
735 #-----------------------------------------------------------------------------
736 # The IPShell* classes below are the ones meant to be run by external code as
736 # The IPShell* classes below are the ones meant to be run by external code as
737 # IPython instances. Note that unless a specific threading strategy is
737 # IPython instances. Note that unless a specific threading strategy is
738 # desired, the factory function start() below should be used instead (it
738 # desired, the factory function start() below should be used instead (it
739 # selects the proper threaded class).
739 # selects the proper threaded class).
740
740
741 class IPThread(threading.Thread):
741 class IPThread(threading.Thread):
742 def run(self):
742 def run(self):
743 self.IP.mainloop(self._banner)
743 self.IP.mainloop(self._banner)
744 self.IP.kill()
744 self.IP.kill()
745
745
746 class IPShellGTK(IPThread):
746 class IPShellGTK(IPThread):
747 """Run a gtk mainloop() in a separate thread.
747 """Run a gtk mainloop() in a separate thread.
748
748
749 Python commands can be passed to the thread where they will be executed.
749 Python commands can be passed to the thread where they will be executed.
750 This is implemented by periodically checking for passed code using a
750 This is implemented by periodically checking for passed code using a
751 GTK timeout callback."""
751 GTK timeout callback."""
752
752
753 TIMEOUT = 100 # Millisecond interval between timeouts.
753 TIMEOUT = 100 # Millisecond interval between timeouts.
754
754
755 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
755 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
756 debug=1,shell_class=MTInteractiveShell):
756 debug=1,shell_class=MTInteractiveShell):
757
757
758 import gtk
758 import gtk
759
759
760 self.gtk = gtk
760 self.gtk = gtk
761 self.gtk_mainloop = hijack_gtk()
761 self.gtk_mainloop = hijack_gtk()
762
762
763 # Allows us to use both Tk and GTK.
763 # Allows us to use both Tk and GTK.
764 self.tk = get_tk()
764 self.tk = get_tk()
765
765
766 if gtk.pygtk_version >= (2,4,0): mainquit = self.gtk.main_quit
766 if gtk.pygtk_version >= (2,4,0): mainquit = self.gtk.main_quit
767 else: mainquit = self.gtk.mainquit
767 else: mainquit = self.gtk.mainquit
768
768
769 self.IP = make_IPython(argv,user_ns=user_ns,
769 self.IP = make_IPython(argv,user_ns=user_ns,
770 user_global_ns=user_global_ns,
770 user_global_ns=user_global_ns,
771 debug=debug,
771 debug=debug,
772 shell_class=shell_class,
772 shell_class=shell_class,
773 on_kill=[mainquit])
773 on_kill=[mainquit])
774
774
775 # HACK: slot for banner in self; it will be passed to the mainloop
775 # HACK: slot for banner in self; it will be passed to the mainloop
776 # method only and .run() needs it. The actual value will be set by
776 # method only and .run() needs it. The actual value will be set by
777 # .mainloop().
777 # .mainloop().
778 self._banner = None
778 self._banner = None
779
779
780 threading.Thread.__init__(self)
780 threading.Thread.__init__(self)
781
781
782 def mainloop(self,sys_exit=0,banner=None):
782 def mainloop(self,sys_exit=0,banner=None):
783
783
784 self._banner = banner
784 self._banner = banner
785
785
786 if self.gtk.pygtk_version >= (2,4,0):
786 if self.gtk.pygtk_version >= (2,4,0):
787 import gobject
787 import gobject
788 gobject.idle_add(self.on_timer)
788 gobject.idle_add(self.on_timer)
789 else:
789 else:
790 self.gtk.idle_add(self.on_timer)
790 self.gtk.idle_add(self.on_timer)
791
791
792 if sys.platform != 'win32':
792 if sys.platform != 'win32':
793 try:
793 try:
794 if self.gtk.gtk_version[0] >= 2:
794 if self.gtk.gtk_version[0] >= 2:
795 self.gtk.gdk.threads_init()
795 self.gtk.gdk.threads_init()
796 except AttributeError:
796 except AttributeError:
797 pass
797 pass
798 except RuntimeError:
798 except RuntimeError:
799 error('Your pyGTK likely has not been compiled with '
799 error('Your pyGTK likely has not been compiled with '
800 'threading support.\n'
800 'threading support.\n'
801 'The exception printout is below.\n'
801 'The exception printout is below.\n'
802 'You can either rebuild pyGTK with threads, or '
802 'You can either rebuild pyGTK with threads, or '
803 'try using \n'
803 'try using \n'
804 'matplotlib with a different backend (like Tk or WX).\n'
804 'matplotlib with a different backend (like Tk or WX).\n'
805 'Note that matplotlib will most likely not work in its '
805 'Note that matplotlib will most likely not work in its '
806 'current state!')
806 'current state!')
807 self.IP.InteractiveTB()
807 self.IP.InteractiveTB()
808
808
809 self.start()
809 self.start()
810 self.gtk.gdk.threads_enter()
810 self.gtk.gdk.threads_enter()
811 self.gtk_mainloop()
811 self.gtk_mainloop()
812 self.gtk.gdk.threads_leave()
812 self.gtk.gdk.threads_leave()
813 self.join()
813 self.join()
814
814
815 def on_timer(self):
815 def on_timer(self):
816 """Called when GTK is idle.
816 """Called when GTK is idle.
817
817
818 Must return True always, otherwise GTK stops calling it"""
818 Must return True always, otherwise GTK stops calling it"""
819
819
820 update_tk(self.tk)
820 update_tk(self.tk)
821 self.IP.runcode()
821 self.IP.runcode()
822 time.sleep(0.01)
822 time.sleep(0.01)
823 return True
823 return True
824
824
825
825
826 class IPShellWX(IPThread):
826 class IPShellWX(IPThread):
827 """Run a wx mainloop() in a separate thread.
827 """Run a wx mainloop() in a separate thread.
828
828
829 Python commands can be passed to the thread where they will be executed.
829 Python commands can be passed to the thread where they will be executed.
830 This is implemented by periodically checking for passed code using a
830 This is implemented by periodically checking for passed code using a
831 GTK timeout callback."""
831 GTK timeout callback."""
832
832
833 TIMEOUT = 100 # Millisecond interval between timeouts.
833 TIMEOUT = 100 # Millisecond interval between timeouts.
834
834
835 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
835 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
836 debug=1,shell_class=MTInteractiveShell):
836 debug=1,shell_class=MTInteractiveShell):
837
837
838 self.IP = make_IPython(argv,user_ns=user_ns,
838 self.IP = make_IPython(argv,user_ns=user_ns,
839 user_global_ns=user_global_ns,
839 user_global_ns=user_global_ns,
840 debug=debug,
840 debug=debug,
841 shell_class=shell_class,
841 shell_class=shell_class,
842 on_kill=[self.wxexit])
842 on_kill=[self.wxexit])
843
843
844 wantedwxversion=self.IP.rc.wxversion
844 wantedwxversion=self.IP.rc.wxversion
845 if wantedwxversion!="0":
845 if wantedwxversion!="0":
846 try:
846 try:
847 import wxversion
847 import wxversion
848 except ImportError:
848 except ImportError:
849 error('The wxversion module is needed for WX version selection')
849 error('The wxversion module is needed for WX version selection')
850 else:
850 else:
851 try:
851 try:
852 wxversion.select(wantedwxversion)
852 wxversion.select(wantedwxversion)
853 except:
853 except:
854 self.IP.InteractiveTB()
854 self.IP.InteractiveTB()
855 error('Requested wxPython version %s could not be loaded' %
855 error('Requested wxPython version %s could not be loaded' %
856 wantedwxversion)
856 wantedwxversion)
857
857
858 import wx
858 import wx
859
859
860 threading.Thread.__init__(self)
860 threading.Thread.__init__(self)
861 self.wx = wx
861 self.wx = wx
862 self.wx_mainloop = hijack_wx()
862 self.wx_mainloop = hijack_wx()
863
863
864 # Allows us to use both Tk and GTK.
864 # Allows us to use both Tk and GTK.
865 self.tk = get_tk()
865 self.tk = get_tk()
866
866
867 # HACK: slot for banner in self; it will be passed to the mainloop
867 # HACK: slot for banner in self; it will be passed to the mainloop
868 # method only and .run() needs it. The actual value will be set by
868 # method only and .run() needs it. The actual value will be set by
869 # .mainloop().
869 # .mainloop().
870 self._banner = None
870 self._banner = None
871
871
872 self.app = None
872 self.app = None
873
873
874 def wxexit(self, *args):
874 def wxexit(self, *args):
875 if self.app is not None:
875 if self.app is not None:
876 self.app.agent.timer.Stop()
876 self.app.agent.timer.Stop()
877 self.app.ExitMainLoop()
877 self.app.ExitMainLoop()
878
878
879 def mainloop(self,sys_exit=0,banner=None):
879 def mainloop(self,sys_exit=0,banner=None):
880
880
881 self._banner = banner
881 self._banner = banner
882
882
883 self.start()
883 self.start()
884
884
885 class TimerAgent(self.wx.MiniFrame):
885 class TimerAgent(self.wx.MiniFrame):
886 wx = self.wx
886 wx = self.wx
887 IP = self.IP
887 IP = self.IP
888 tk = self.tk
888 tk = self.tk
889 def __init__(self, parent, interval):
889 def __init__(self, parent, interval):
890 style = self.wx.DEFAULT_FRAME_STYLE | self.wx.TINY_CAPTION_HORIZ
890 style = self.wx.DEFAULT_FRAME_STYLE | self.wx.TINY_CAPTION_HORIZ
891 self.wx.MiniFrame.__init__(self, parent, -1, ' ', pos=(200, 200),
891 self.wx.MiniFrame.__init__(self, parent, -1, ' ', pos=(200, 200),
892 size=(100, 100),style=style)
892 size=(100, 100),style=style)
893 self.Show(False)
893 self.Show(False)
894 self.interval = interval
894 self.interval = interval
895 self.timerId = self.wx.NewId()
895 self.timerId = self.wx.NewId()
896
896
897 def StartWork(self):
897 def StartWork(self):
898 self.timer = self.wx.Timer(self, self.timerId)
898 self.timer = self.wx.Timer(self, self.timerId)
899 self.wx.EVT_TIMER(self, self.timerId, self.OnTimer)
899 self.wx.EVT_TIMER(self, self.timerId, self.OnTimer)
900 self.timer.Start(self.interval)
900 self.timer.Start(self.interval)
901
901
902 def OnTimer(self, event):
902 def OnTimer(self, event):
903 update_tk(self.tk)
903 update_tk(self.tk)
904 self.IP.runcode()
904 self.IP.runcode()
905
905
906 class App(self.wx.App):
906 class App(self.wx.App):
907 wx = self.wx
907 wx = self.wx
908 TIMEOUT = self.TIMEOUT
908 TIMEOUT = self.TIMEOUT
909 def OnInit(self):
909 def OnInit(self):
910 'Create the main window and insert the custom frame'
910 'Create the main window and insert the custom frame'
911 self.agent = TimerAgent(None, self.TIMEOUT)
911 self.agent = TimerAgent(None, self.TIMEOUT)
912 self.agent.Show(False)
912 self.agent.Show(False)
913 self.agent.StartWork()
913 self.agent.StartWork()
914 return True
914 return True
915
915
916 self.app = App(redirect=False)
916 self.app = App(redirect=False)
917 self.wx_mainloop(self.app)
917 self.wx_mainloop(self.app)
918 self.join()
918 self.join()
919
919
920
920
921 class IPShellQt(IPThread):
921 class IPShellQt(IPThread):
922 """Run a Qt event loop in a separate thread.
922 """Run a Qt event loop in a separate thread.
923
923
924 Python commands can be passed to the thread where they will be executed.
924 Python commands can be passed to the thread where they will be executed.
925 This is implemented by periodically checking for passed code using a
925 This is implemented by periodically checking for passed code using a
926 Qt timer / slot."""
926 Qt timer / slot."""
927
927
928 TIMEOUT = 100 # Millisecond interval between timeouts.
928 TIMEOUT = 100 # Millisecond interval between timeouts.
929
929
930 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
930 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
931 debug=0, shell_class=MTInteractiveShell):
931 debug=0, shell_class=MTInteractiveShell):
932
932
933 import qt
933 import qt
934
934
935 self.exec_loop = hijack_qt()
935 self.exec_loop = hijack_qt()
936
936
937 # Allows us to use both Tk and QT.
937 # Allows us to use both Tk and QT.
938 self.tk = get_tk()
938 self.tk = get_tk()
939
939
940 self.IP = make_IPython(argv,
940 self.IP = make_IPython(argv,
941 user_ns=user_ns,
941 user_ns=user_ns,
942 user_global_ns=user_global_ns,
942 user_global_ns=user_global_ns,
943 debug=debug,
943 debug=debug,
944 shell_class=shell_class,
944 shell_class=shell_class,
945 on_kill=[qt.qApp.exit])
945 on_kill=[qt.qApp.exit])
946
946
947 # HACK: slot for banner in self; it will be passed to the mainloop
947 # HACK: slot for banner in self; it will be passed to the mainloop
948 # method only and .run() needs it. The actual value will be set by
948 # method only and .run() needs it. The actual value will be set by
949 # .mainloop().
949 # .mainloop().
950 self._banner = None
950 self._banner = None
951
951
952 threading.Thread.__init__(self)
952 threading.Thread.__init__(self)
953
953
954 def mainloop(self, sys_exit=0, banner=None):
954 def mainloop(self, sys_exit=0, banner=None):
955
955
956 import qt
956 import qt
957
957
958 self._banner = banner
958 self._banner = banner
959
959
960 if qt.QApplication.startingUp():
960 if qt.QApplication.startingUp():
961 a = qt.QApplication(sys.argv)
961 a = qt.QApplication(sys.argv)
962
962
963 self.timer = qt.QTimer()
963 self.timer = qt.QTimer()
964 qt.QObject.connect(self.timer,
964 qt.QObject.connect(self.timer,
965 qt.SIGNAL('timeout()'),
965 qt.SIGNAL('timeout()'),
966 self.on_timer)
966 self.on_timer)
967
967
968 self.start()
968 self.start()
969 self.timer.start(self.TIMEOUT, True)
969 self.timer.start(self.TIMEOUT, True)
970 while True:
970 while True:
971 if self.IP._kill: break
971 if self.IP._kill: break
972 self.exec_loop()
972 self.exec_loop()
973 self.join()
973 self.join()
974
974
975 def on_timer(self):
975 def on_timer(self):
976 update_tk(self.tk)
976 update_tk(self.tk)
977 result = self.IP.runcode()
977 result = self.IP.runcode()
978 self.timer.start(self.TIMEOUT, True)
978 self.timer.start(self.TIMEOUT, True)
979 return result
979 return result
980
980
981
981
982 class IPShellQt4(IPThread):
982 class IPShellQt4(IPThread):
983 """Run a Qt event loop in a separate thread.
983 """Run a Qt event loop in a separate thread.
984
984
985 Python commands can be passed to the thread where they will be executed.
985 Python commands can be passed to the thread where they will be executed.
986 This is implemented by periodically checking for passed code using a
986 This is implemented by periodically checking for passed code using a
987 Qt timer / slot."""
987 Qt timer / slot."""
988
988
989 TIMEOUT = 100 # Millisecond interval between timeouts.
989 TIMEOUT = 100 # Millisecond interval between timeouts.
990
990
991 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
991 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
992 debug=0, shell_class=MTInteractiveShell):
992 debug=0, shell_class=MTInteractiveShell):
993
993
994 from PyQt4 import QtCore, QtGui
994 from PyQt4 import QtCore, QtGui
995
995
996 try:
996 try:
997 # present in PyQt4-4.2.1 or later
997 # present in PyQt4-4.2.1 or later
998 QtCore.pyqtRemoveInputHook()
998 QtCore.pyqtRemoveInputHook()
999 except AttributeError:
999 except AttributeError:
1000 pass
1000 pass
1001
1001
1002 if QtCore.PYQT_VERSION_STR == '4.3':
1002 if QtCore.PYQT_VERSION_STR == '4.3':
1003 warn('''PyQt4 version 4.3 detected.
1003 warn('''PyQt4 version 4.3 detected.
1004 If you experience repeated threading warnings, please update PyQt4.
1004 If you experience repeated threading warnings, please update PyQt4.
1005 ''')
1005 ''')
1006
1006
1007 self.exec_ = hijack_qt4()
1007 self.exec_ = hijack_qt4()
1008
1008
1009 # Allows us to use both Tk and QT.
1009 # Allows us to use both Tk and QT.
1010 self.tk = get_tk()
1010 self.tk = get_tk()
1011
1011
1012 self.IP = make_IPython(argv,
1012 self.IP = make_IPython(argv,
1013 user_ns=user_ns,
1013 user_ns=user_ns,
1014 user_global_ns=user_global_ns,
1014 user_global_ns=user_global_ns,
1015 debug=debug,
1015 debug=debug,
1016 shell_class=shell_class,
1016 shell_class=shell_class,
1017 on_kill=[QtGui.qApp.exit])
1017 on_kill=[QtGui.qApp.exit])
1018
1018
1019 # HACK: slot for banner in self; it will be passed to the mainloop
1019 # HACK: slot for banner in self; it will be passed to the mainloop
1020 # method only and .run() needs it. The actual value will be set by
1020 # method only and .run() needs it. The actual value will be set by
1021 # .mainloop().
1021 # .mainloop().
1022 self._banner = None
1022 self._banner = None
1023
1023
1024 threading.Thread.__init__(self)
1024 threading.Thread.__init__(self)
1025
1025
1026 def mainloop(self, sys_exit=0, banner=None):
1026 def mainloop(self, sys_exit=0, banner=None):
1027
1027
1028 from PyQt4 import QtCore, QtGui
1028 from PyQt4 import QtCore, QtGui
1029
1029
1030 self._banner = banner
1030 self._banner = banner
1031
1031
1032 if QtGui.QApplication.startingUp():
1032 if QtGui.QApplication.startingUp():
1033 a = QtGui.QApplication(sys.argv)
1033 a = QtGui.QApplication(sys.argv)
1034
1034
1035 self.timer = QtCore.QTimer()
1035 self.timer = QtCore.QTimer()
1036 QtCore.QObject.connect(self.timer,
1036 QtCore.QObject.connect(self.timer,
1037 QtCore.SIGNAL('timeout()'),
1037 QtCore.SIGNAL('timeout()'),
1038 self.on_timer)
1038 self.on_timer)
1039
1039
1040 self.start()
1040 self.start()
1041 self.timer.start(self.TIMEOUT)
1041 self.timer.start(self.TIMEOUT)
1042 while True:
1042 while True:
1043 if self.IP._kill: break
1043 if self.IP._kill: break
1044 self.exec_()
1044 self.exec_()
1045 self.join()
1045 self.join()
1046
1046
1047 def on_timer(self):
1047 def on_timer(self):
1048 update_tk(self.tk)
1048 update_tk(self.tk)
1049 result = self.IP.runcode()
1049 result = self.IP.runcode()
1050 self.timer.start(self.TIMEOUT)
1050 self.timer.start(self.TIMEOUT)
1051 return result
1051 return result
1052
1052
1053
1053
1054 # A set of matplotlib public IPython shell classes, for single-threaded (Tk*
1054 # A set of matplotlib public IPython shell classes, for single-threaded (Tk*
1055 # and FLTK*) and multithreaded (GTK*, WX* and Qt*) backends to use.
1055 # and FLTK*) and multithreaded (GTK*, WX* and Qt*) backends to use.
1056 def _load_pylab(user_ns):
1056 def _load_pylab(user_ns):
1057 """Allow users to disable pulling all of pylab into the top-level
1057 """Allow users to disable pulling all of pylab into the top-level
1058 namespace.
1058 namespace.
1059
1059
1060 This little utility must be called AFTER the actual ipython instance is
1060 This little utility must be called AFTER the actual ipython instance is
1061 running, since only then will the options file have been fully parsed."""
1061 running, since only then will the options file have been fully parsed."""
1062
1062
1063 ip = IPython.ipapi.get()
1063 ip = IPython.ipapi.get()
1064 if ip.options.pylab_import_all:
1064 if ip.options.pylab_import_all:
1065 ip.ex("from matplotlib.pylab import *")
1065 ip.ex("from matplotlib.pylab import *")
1066 ip.IP.user_config_ns.update(ip.user_ns)
1066 ip.IP.user_config_ns.update(ip.user_ns)
1067
1067
1068
1068
1069 class IPShellMatplotlib(IPShell):
1069 class IPShellMatplotlib(IPShell):
1070 """Subclass IPShell with MatplotlibShell as the internal shell.
1070 """Subclass IPShell with MatplotlibShell as the internal shell.
1071
1071
1072 Single-threaded class, meant for the Tk* and FLTK* backends.
1072 Single-threaded class, meant for the Tk* and FLTK* backends.
1073
1073
1074 Having this on a separate class simplifies the external driver code."""
1074 Having this on a separate class simplifies the external driver code."""
1075
1075
1076 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1076 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1077 IPShell.__init__(self,argv,user_ns,user_global_ns,debug,
1077 IPShell.__init__(self,argv,user_ns,user_global_ns,debug,
1078 shell_class=MatplotlibShell)
1078 shell_class=MatplotlibShell)
1079 _load_pylab(self.IP.user_ns)
1079 _load_pylab(self.IP.user_ns)
1080
1080
1081 class IPShellMatplotlibGTK(IPShellGTK):
1081 class IPShellMatplotlibGTK(IPShellGTK):
1082 """Subclass IPShellGTK with MatplotlibMTShell as the internal shell.
1082 """Subclass IPShellGTK with MatplotlibMTShell as the internal shell.
1083
1083
1084 Multi-threaded class, meant for the GTK* backends."""
1084 Multi-threaded class, meant for the GTK* backends."""
1085
1085
1086 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1086 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1087 IPShellGTK.__init__(self,argv,user_ns,user_global_ns,debug,
1087 IPShellGTK.__init__(self,argv,user_ns,user_global_ns,debug,
1088 shell_class=MatplotlibMTShell)
1088 shell_class=MatplotlibMTShell)
1089 _load_pylab(self.IP.user_ns)
1089 _load_pylab(self.IP.user_ns)
1090
1090
1091 class IPShellMatplotlibWX(IPShellWX):
1091 class IPShellMatplotlibWX(IPShellWX):
1092 """Subclass IPShellWX with MatplotlibMTShell as the internal shell.
1092 """Subclass IPShellWX with MatplotlibMTShell as the internal shell.
1093
1093
1094 Multi-threaded class, meant for the WX* backends."""
1094 Multi-threaded class, meant for the WX* backends."""
1095
1095
1096 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1096 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1097 IPShellWX.__init__(self,argv,user_ns,user_global_ns,debug,
1097 IPShellWX.__init__(self,argv,user_ns,user_global_ns,debug,
1098 shell_class=MatplotlibMTShell)
1098 shell_class=MatplotlibMTShell)
1099 _load_pylab(self.IP.user_ns)
1099 _load_pylab(self.IP.user_ns)
1100
1100
1101 class IPShellMatplotlibQt(IPShellQt):
1101 class IPShellMatplotlibQt(IPShellQt):
1102 """Subclass IPShellQt with MatplotlibMTShell as the internal shell.
1102 """Subclass IPShellQt with MatplotlibMTShell as the internal shell.
1103
1103
1104 Multi-threaded class, meant for the Qt* backends."""
1104 Multi-threaded class, meant for the Qt* backends."""
1105
1105
1106 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1106 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1107 IPShellQt.__init__(self,argv,user_ns,user_global_ns,debug,
1107 IPShellQt.__init__(self,argv,user_ns,user_global_ns,debug,
1108 shell_class=MatplotlibMTShell)
1108 shell_class=MatplotlibMTShell)
1109 _load_pylab(self.IP.user_ns)
1109 _load_pylab(self.IP.user_ns)
1110
1110
1111 class IPShellMatplotlibQt4(IPShellQt4):
1111 class IPShellMatplotlibQt4(IPShellQt4):
1112 """Subclass IPShellQt4 with MatplotlibMTShell as the internal shell.
1112 """Subclass IPShellQt4 with MatplotlibMTShell as the internal shell.
1113
1113
1114 Multi-threaded class, meant for the Qt4* backends."""
1114 Multi-threaded class, meant for the Qt4* backends."""
1115
1115
1116 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1116 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1117 IPShellQt4.__init__(self,argv,user_ns,user_global_ns,debug,
1117 IPShellQt4.__init__(self,argv,user_ns,user_global_ns,debug,
1118 shell_class=MatplotlibMTShell)
1118 shell_class=MatplotlibMTShell)
1119 _load_pylab(self.IP.user_ns)
1119 _load_pylab(self.IP.user_ns)
1120
1120
1121 #-----------------------------------------------------------------------------
1121 #-----------------------------------------------------------------------------
1122 # Factory functions to actually start the proper thread-aware shell
1122 # Factory functions to actually start the proper thread-aware shell
1123
1123
1124 def _select_shell(argv):
1124 def _select_shell(argv):
1125 """Select a shell from the given argv vector.
1125 """Select a shell from the given argv vector.
1126
1126
1127 This function implements the threading selection policy, allowing runtime
1127 This function implements the threading selection policy, allowing runtime
1128 control of the threading mode, both for general users and for matplotlib.
1128 control of the threading mode, both for general users and for matplotlib.
1129
1129
1130 Return:
1130 Return:
1131 Shell class to be instantiated for runtime operation.
1131 Shell class to be instantiated for runtime operation.
1132 """
1132 """
1133
1133
1134 global USE_TK
1134 global USE_TK
1135
1135
1136 mpl_shell = {'gthread' : IPShellMatplotlibGTK,
1136 mpl_shell = {'gthread' : IPShellMatplotlibGTK,
1137 'wthread' : IPShellMatplotlibWX,
1137 'wthread' : IPShellMatplotlibWX,
1138 'qthread' : IPShellMatplotlibQt,
1138 'qthread' : IPShellMatplotlibQt,
1139 'q4thread' : IPShellMatplotlibQt4,
1139 'q4thread' : IPShellMatplotlibQt4,
1140 'tkthread' : IPShellMatplotlib, # Tk is built-in
1140 'tkthread' : IPShellMatplotlib, # Tk is built-in
1141 }
1141 }
1142
1142
1143 th_shell = {'gthread' : IPShellGTK,
1143 th_shell = {'gthread' : IPShellGTK,
1144 'wthread' : IPShellWX,
1144 'wthread' : IPShellWX,
1145 'qthread' : IPShellQt,
1145 'qthread' : IPShellQt,
1146 'q4thread' : IPShellQt4,
1146 'q4thread' : IPShellQt4,
1147 'tkthread' : IPShell, # Tk is built-in
1147 'tkthread' : IPShell, # Tk is built-in
1148 }
1148 }
1149
1149
1150 backends = {'gthread' : 'GTKAgg',
1150 backends = {'gthread' : 'GTKAgg',
1151 'wthread' : 'WXAgg',
1151 'wthread' : 'WXAgg',
1152 'qthread' : 'QtAgg',
1152 'qthread' : 'QtAgg',
1153 'q4thread' :'Qt4Agg',
1153 'q4thread' :'Qt4Agg',
1154 'tkthread' :'TkAgg',
1154 'tkthread' :'TkAgg',
1155 }
1155 }
1156
1156
1157 all_opts = set(['tk','pylab','gthread','qthread','q4thread','wthread',
1157 all_opts = set(['tk','pylab','gthread','qthread','q4thread','wthread',
1158 'tkthread'])
1158 'tkthread', 'twisted'])
1159 user_opts = set([s.replace('-','') for s in argv[:3]])
1159 user_opts = set([s.replace('-','') for s in argv[:3]])
1160 special_opts = user_opts & all_opts
1160 special_opts = user_opts & all_opts
1161
1161
1162 if 'twisted' in special_opts:
1163 import twshell
1164 return twshell.IPShellTwisted
1162 if 'tk' in special_opts:
1165 if 'tk' in special_opts:
1163 USE_TK = True
1166 USE_TK = True
1164 special_opts.remove('tk')
1167 special_opts.remove('tk')
1165
1168
1166 if 'pylab' in special_opts:
1169 if 'pylab' in special_opts:
1167
1170
1168 try:
1171 try:
1169 import matplotlib
1172 import matplotlib
1170 except ImportError:
1173 except ImportError:
1171 error('matplotlib could NOT be imported! Starting normal IPython.')
1174 error('matplotlib could NOT be imported! Starting normal IPython.')
1172 return IPShell
1175 return IPShell
1173
1176
1174 special_opts.remove('pylab')
1177 special_opts.remove('pylab')
1175 # If there's any option left, it means the user wants to force the
1178 # If there's any option left, it means the user wants to force the
1176 # threading backend, else it's auto-selected from the rc file
1179 # threading backend, else it's auto-selected from the rc file
1177 if special_opts:
1180 if special_opts:
1178 th_mode = special_opts.pop()
1181 th_mode = special_opts.pop()
1179 matplotlib.rcParams['backend'] = backends[th_mode]
1182 matplotlib.rcParams['backend'] = backends[th_mode]
1180 else:
1183 else:
1181 backend = matplotlib.rcParams['backend']
1184 backend = matplotlib.rcParams['backend']
1182 if backend.startswith('GTK'):
1185 if backend.startswith('GTK'):
1183 th_mode = 'gthread'
1186 th_mode = 'gthread'
1184 elif backend.startswith('WX'):
1187 elif backend.startswith('WX'):
1185 th_mode = 'wthread'
1188 th_mode = 'wthread'
1186 elif backend.startswith('Qt4'):
1189 elif backend.startswith('Qt4'):
1187 th_mode = 'q4thread'
1190 th_mode = 'q4thread'
1188 elif backend.startswith('Qt'):
1191 elif backend.startswith('Qt'):
1189 th_mode = 'qthread'
1192 th_mode = 'qthread'
1190 else:
1193 else:
1191 # Any other backend, use plain Tk
1194 # Any other backend, use plain Tk
1192 th_mode = 'tkthread'
1195 th_mode = 'tkthread'
1193
1196
1194 return mpl_shell[th_mode]
1197 return mpl_shell[th_mode]
1195 else:
1198 else:
1196 # No pylab requested, just plain threads
1199 # No pylab requested, just plain threads
1197 try:
1200 try:
1198 th_mode = special_opts.pop()
1201 th_mode = special_opts.pop()
1199 except KeyError:
1202 except KeyError:
1200 th_mode = 'tkthread'
1203 th_mode = 'tkthread'
1201 return th_shell[th_mode]
1204 return th_shell[th_mode]
1202
1205
1203
1206
1204 # This is the one which should be called by external code.
1207 # This is the one which should be called by external code.
1205 def start(user_ns = None):
1208 def start(user_ns = None):
1206 """Return a running shell instance, dealing with threading options.
1209 """Return a running shell instance, dealing with threading options.
1207
1210
1208 This is a factory function which will instantiate the proper IPython shell
1211 This is a factory function which will instantiate the proper IPython shell
1209 based on the user's threading choice. Such a selector is needed because
1212 based on the user's threading choice. Such a selector is needed because
1210 different GUI toolkits require different thread handling details."""
1213 different GUI toolkits require different thread handling details."""
1211
1214
1212 shell = _select_shell(sys.argv)
1215 shell = _select_shell(sys.argv)
1213 return shell(user_ns = user_ns)
1216 return shell(user_ns = user_ns)
1214
1217
1215 # Some aliases for backwards compatibility
1218 # Some aliases for backwards compatibility
1216 IPythonShell = IPShell
1219 IPythonShell = IPShell
1217 IPythonShellEmbed = IPShellEmbed
1220 IPythonShellEmbed = IPShellEmbed
1218 #************************ End of file <Shell.py> ***************************
1221 #************************ End of file <Shell.py> ***************************
@@ -1,775 +1,775 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 IPython -- An enhanced Interactive Python
3 IPython -- An enhanced Interactive Python
4
4
5 Requires Python 2.1 or better.
5 Requires Python 2.1 or better.
6
6
7 This file contains the main make_IPython() starter function.
7 This file contains the main make_IPython() starter function.
8
8
9 $Id: ipmaker.py 2930 2008-01-11 07:03:11Z vivainio $"""
9 $Id: ipmaker.py 2930 2008-01-11 07:03:11Z vivainio $"""
10
10
11 #*****************************************************************************
11 #*****************************************************************************
12 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
12 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
13 #
13 #
14 # Distributed under the terms of the BSD License. The full license is in
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
15 # the file COPYING, distributed as part of this software.
16 #*****************************************************************************
16 #*****************************************************************************
17
17
18 from IPython import Release
18 from IPython import Release
19 __author__ = '%s <%s>' % Release.authors['Fernando']
19 __author__ = '%s <%s>' % Release.authors['Fernando']
20 __license__ = Release.license
20 __license__ = Release.license
21 __version__ = Release.version
21 __version__ = Release.version
22
22
23 try:
23 try:
24 credits._Printer__data = """
24 credits._Printer__data = """
25 Python: %s
25 Python: %s
26
26
27 IPython: Fernando Perez, Janko Hauser, Nathan Gray, and many users.
27 IPython: Fernando Perez, Janko Hauser, Nathan Gray, and many users.
28 See http://ipython.scipy.org for more information.""" \
28 See http://ipython.scipy.org for more information.""" \
29 % credits._Printer__data
29 % credits._Printer__data
30
30
31 copyright._Printer__data += """
31 copyright._Printer__data += """
32
32
33 Copyright (c) 2001-2004 Fernando Perez, Janko Hauser, Nathan Gray.
33 Copyright (c) 2001-2004 Fernando Perez, Janko Hauser, Nathan Gray.
34 All Rights Reserved."""
34 All Rights Reserved."""
35 except NameError:
35 except NameError:
36 # Can happen if ipython was started with 'python -S', so that site.py is
36 # Can happen if ipython was started with 'python -S', so that site.py is
37 # not loaded
37 # not loaded
38 pass
38 pass
39
39
40 #****************************************************************************
40 #****************************************************************************
41 # Required modules
41 # Required modules
42
42
43 # From the standard library
43 # From the standard library
44 import __main__
44 import __main__
45 import __builtin__
45 import __builtin__
46 import os
46 import os
47 import re
47 import re
48 import sys
48 import sys
49 import types
49 import types
50 from pprint import pprint,pformat
50 from pprint import pprint,pformat
51
51
52 # Our own
52 # Our own
53 from IPython import DPyGetOpt
53 from IPython import DPyGetOpt
54 from IPython.ipstruct import Struct
54 from IPython.ipstruct import Struct
55 from IPython.OutputTrap import OutputTrap
55 from IPython.OutputTrap import OutputTrap
56 from IPython.ConfigLoader import ConfigLoader
56 from IPython.ConfigLoader import ConfigLoader
57 from IPython.iplib import InteractiveShell
57 from IPython.iplib import InteractiveShell
58 from IPython.usage import cmd_line_usage,interactive_usage
58 from IPython.usage import cmd_line_usage,interactive_usage
59 from IPython.genutils import *
59 from IPython.genutils import *
60
60
61 def force_import(modname):
61 def force_import(modname):
62 if modname in sys.modules:
62 if modname in sys.modules:
63 print "reload",modname
63 print "reload",modname
64 reload(sys.modules[modname])
64 reload(sys.modules[modname])
65 else:
65 else:
66 __import__(modname)
66 __import__(modname)
67
67
68
68
69 #-----------------------------------------------------------------------------
69 #-----------------------------------------------------------------------------
70 def make_IPython(argv=None,user_ns=None,user_global_ns=None,debug=1,
70 def make_IPython(argv=None,user_ns=None,user_global_ns=None,debug=1,
71 rc_override=None,shell_class=InteractiveShell,
71 rc_override=None,shell_class=InteractiveShell,
72 embedded=False,**kw):
72 embedded=False,**kw):
73 """This is a dump of IPython into a single function.
73 """This is a dump of IPython into a single function.
74
74
75 Later it will have to be broken up in a sensible manner.
75 Later it will have to be broken up in a sensible manner.
76
76
77 Arguments:
77 Arguments:
78
78
79 - argv: a list similar to sys.argv[1:]. It should NOT contain the desired
79 - argv: a list similar to sys.argv[1:]. It should NOT contain the desired
80 script name, b/c DPyGetOpt strips the first argument only for the real
80 script name, b/c DPyGetOpt strips the first argument only for the real
81 sys.argv.
81 sys.argv.
82
82
83 - user_ns: a dict to be used as the user's namespace."""
83 - user_ns: a dict to be used as the user's namespace."""
84
84
85 #----------------------------------------------------------------------
85 #----------------------------------------------------------------------
86 # Defaults and initialization
86 # Defaults and initialization
87
87
88 # For developer debugging, deactivates crash handler and uses pdb.
88 # For developer debugging, deactivates crash handler and uses pdb.
89 DEVDEBUG = False
89 DEVDEBUG = False
90
90
91 if argv is None:
91 if argv is None:
92 argv = sys.argv
92 argv = sys.argv
93
93
94 # __IP is the main global that lives throughout and represents the whole
94 # __IP is the main global that lives throughout and represents the whole
95 # application. If the user redefines it, all bets are off as to what
95 # application. If the user redefines it, all bets are off as to what
96 # happens.
96 # happens.
97
97
98 # __IP is the name of he global which the caller will have accessible as
98 # __IP is the name of he global which the caller will have accessible as
99 # __IP.name. We set its name via the first parameter passed to
99 # __IP.name. We set its name via the first parameter passed to
100 # InteractiveShell:
100 # InteractiveShell:
101
101
102 IP = shell_class('__IP',user_ns=user_ns,user_global_ns=user_global_ns,
102 IP = shell_class('__IP',user_ns=user_ns,user_global_ns=user_global_ns,
103 embedded=embedded,**kw)
103 embedded=embedded,**kw)
104
104
105 # Put 'help' in the user namespace
105 # Put 'help' in the user namespace
106 from site import _Helper
106 from site import _Helper
107 IP.user_config_ns = {}
107 IP.user_config_ns = {}
108 IP.user_ns['help'] = _Helper()
108 IP.user_ns['help'] = _Helper()
109
109
110
110
111 if DEVDEBUG:
111 if DEVDEBUG:
112 # For developer debugging only (global flag)
112 # For developer debugging only (global flag)
113 from IPython import ultraTB
113 from IPython import ultraTB
114 sys.excepthook = ultraTB.VerboseTB(call_pdb=1)
114 sys.excepthook = ultraTB.VerboseTB(call_pdb=1)
115
115
116 IP.BANNER_PARTS = ['Python %s\n'
116 IP.BANNER_PARTS = ['Python %s\n'
117 'Type "copyright", "credits" or "license" '
117 'Type "copyright", "credits" or "license" '
118 'for more information.\n'
118 'for more information.\n'
119 % (sys.version.split('\n')[0],),
119 % (sys.version.split('\n')[0],),
120 "IPython %s -- An enhanced Interactive Python."
120 "IPython %s -- An enhanced Interactive Python."
121 % (__version__,),
121 % (__version__,),
122 """\
122 """\
123 ? -> Introduction and overview of IPython's features.
123 ? -> Introduction and overview of IPython's features.
124 %quickref -> Quick reference.
124 %quickref -> Quick reference.
125 help -> Python's own help system.
125 help -> Python's own help system.
126 object? -> Details about 'object'. ?object also works, ?? prints more.
126 object? -> Details about 'object'. ?object also works, ?? prints more.
127 """ ]
127 """ ]
128
128
129 IP.usage = interactive_usage
129 IP.usage = interactive_usage
130
130
131 # Platform-dependent suffix and directory names. We use _ipython instead
131 # Platform-dependent suffix and directory names. We use _ipython instead
132 # of .ipython under win32 b/c there's software that breaks with .named
132 # of .ipython under win32 b/c there's software that breaks with .named
133 # directories on that platform.
133 # directories on that platform.
134 if os.name == 'posix':
134 if os.name == 'posix':
135 rc_suffix = ''
135 rc_suffix = ''
136 ipdir_def = '.ipython'
136 ipdir_def = '.ipython'
137 else:
137 else:
138 rc_suffix = '.ini'
138 rc_suffix = '.ini'
139 ipdir_def = '_ipython'
139 ipdir_def = '_ipython'
140
140
141 # default directory for configuration
141 # default directory for configuration
142 ipythondir_def = os.path.abspath(os.environ.get('IPYTHONDIR',
142 ipythondir_def = os.path.abspath(os.environ.get('IPYTHONDIR',
143 os.path.join(IP.home_dir,ipdir_def)))
143 os.path.join(IP.home_dir,ipdir_def)))
144
144
145 sys.path.insert(0, '') # add . to sys.path. Fix from Prabhu Ramachandran
145 sys.path.insert(0, '') # add . to sys.path. Fix from Prabhu Ramachandran
146
146
147 # we need the directory where IPython itself is installed
147 # we need the directory where IPython itself is installed
148 import IPython
148 import IPython
149 IPython_dir = os.path.dirname(IPython.__file__)
149 IPython_dir = os.path.dirname(IPython.__file__)
150 del IPython
150 del IPython
151
151
152 #-------------------------------------------------------------------------
152 #-------------------------------------------------------------------------
153 # Command line handling
153 # Command line handling
154
154
155 # Valid command line options (uses DPyGetOpt syntax, like Perl's
155 # Valid command line options (uses DPyGetOpt syntax, like Perl's
156 # GetOpt::Long)
156 # GetOpt::Long)
157
157
158 # Any key not listed here gets deleted even if in the file (like session
158 # Any key not listed here gets deleted even if in the file (like session
159 # or profile). That's deliberate, to maintain the rc namespace clean.
159 # or profile). That's deliberate, to maintain the rc namespace clean.
160
160
161 # Each set of options appears twice: under _conv only the names are
161 # Each set of options appears twice: under _conv only the names are
162 # listed, indicating which type they must be converted to when reading the
162 # listed, indicating which type they must be converted to when reading the
163 # ipythonrc file. And under DPyGetOpt they are listed with the regular
163 # ipythonrc file. And under DPyGetOpt they are listed with the regular
164 # DPyGetOpt syntax (=s,=i,:f,etc).
164 # DPyGetOpt syntax (=s,=i,:f,etc).
165
165
166 # Make sure there's a space before each end of line (they get auto-joined!)
166 # Make sure there's a space before each end of line (they get auto-joined!)
167 cmdline_opts = ('autocall=i autoindent! automagic! banner! cache_size|cs=i '
167 cmdline_opts = ('autocall=i autoindent! automagic! banner! cache_size|cs=i '
168 'c=s classic|cl color_info! colors=s confirm_exit! '
168 'c=s classic|cl color_info! colors=s confirm_exit! '
169 'debug! deep_reload! editor=s log|l messages! nosep '
169 'debug! deep_reload! editor=s log|l messages! nosep '
170 'object_info_string_level=i pdb! '
170 'object_info_string_level=i pdb! '
171 'pprint! prompt_in1|pi1=s prompt_in2|pi2=s prompt_out|po=s '
171 'pprint! prompt_in1|pi1=s prompt_in2|pi2=s prompt_out|po=s '
172 'pydb! '
172 'pydb! '
173 'pylab_import_all! '
173 'pylab_import_all! '
174 'quick screen_length|sl=i prompts_pad_left=i '
174 'quick screen_length|sl=i prompts_pad_left=i '
175 'logfile|lf=s logplay|lp=s profile|p=s '
175 'logfile|lf=s logplay|lp=s profile|p=s '
176 'readline! readline_merge_completions! '
176 'readline! readline_merge_completions! '
177 'readline_omit__names! '
177 'readline_omit__names! '
178 'rcfile=s separate_in|si=s separate_out|so=s '
178 'rcfile=s separate_in|si=s separate_out|so=s '
179 'separate_out2|so2=s xmode=s wildcards_case_sensitive! '
179 'separate_out2|so2=s xmode=s wildcards_case_sensitive! '
180 'magic_docstrings system_verbose! '
180 'magic_docstrings system_verbose! '
181 'multi_line_specials! '
181 'multi_line_specials! '
182 'term_title! wxversion=s '
182 'term_title! wxversion=s '
183 'autoedit_syntax!')
183 'autoedit_syntax!')
184
184
185 # Options that can *only* appear at the cmd line (not in rcfiles).
185 # Options that can *only* appear at the cmd line (not in rcfiles).
186
186
187 # The "ignore" option is a kludge so that Emacs buffers don't crash, since
188 # the 'C-c !' command in emacs automatically appends a -i option at the end.
189 cmdline_only = ('help interact|i ipythondir=s Version upgrade '
187 cmdline_only = ('help interact|i ipythondir=s Version upgrade '
190 'gthread! qthread! q4thread! wthread! tkthread! pylab! tk!')
188 'gthread! qthread! q4thread! wthread! tkthread! pylab! tk! '
189 'twisted!')
191
190
192 # Build the actual name list to be used by DPyGetOpt
191 # Build the actual name list to be used by DPyGetOpt
193 opts_names = qw(cmdline_opts) + qw(cmdline_only)
192 opts_names = qw(cmdline_opts) + qw(cmdline_only)
194
193
195 # Set sensible command line defaults.
194 # Set sensible command line defaults.
196 # This should have everything from cmdline_opts and cmdline_only
195 # This should have everything from cmdline_opts and cmdline_only
197 opts_def = Struct(autocall = 1,
196 opts_def = Struct(autocall = 1,
198 autoedit_syntax = 0,
197 autoedit_syntax = 0,
199 autoindent = 0,
198 autoindent = 0,
200 automagic = 1,
199 automagic = 1,
201 autoexec = [],
200 autoexec = [],
202 banner = 1,
201 banner = 1,
203 c = '',
202 c = '',
204 cache_size = 1000,
203 cache_size = 1000,
205 classic = 0,
204 classic = 0,
206 color_info = 0,
205 color_info = 0,
207 colors = 'NoColor',
206 colors = 'NoColor',
208 confirm_exit = 1,
207 confirm_exit = 1,
209 debug = 0,
208 debug = 0,
210 deep_reload = 0,
209 deep_reload = 0,
211 editor = '0',
210 editor = '0',
212 gthread = 0,
211 gthread = 0,
213 help = 0,
212 help = 0,
214 interact = 1,
213 interact = 1,
215 ipythondir = ipythondir_def,
214 ipythondir = ipythondir_def,
216 log = 0,
215 log = 0,
217 logfile = '',
216 logfile = '',
218 logplay = '',
217 logplay = '',
219 messages = 1,
218 messages = 1,
220 multi_line_specials = 1,
219 multi_line_specials = 1,
221 nosep = 0,
220 nosep = 0,
222 object_info_string_level = 0,
221 object_info_string_level = 0,
223 pdb = 0,
222 pdb = 0,
224 pprint = 0,
223 pprint = 0,
225 profile = '',
224 profile = '',
226 prompt_in1 = 'In [\\#]: ',
225 prompt_in1 = 'In [\\#]: ',
227 prompt_in2 = ' .\\D.: ',
226 prompt_in2 = ' .\\D.: ',
228 prompt_out = 'Out[\\#]: ',
227 prompt_out = 'Out[\\#]: ',
229 prompts_pad_left = 1,
228 prompts_pad_left = 1,
230 pylab = 0,
229 pylab = 0,
231 pylab_import_all = 1,
230 pylab_import_all = 1,
232 q4thread = 0,
231 q4thread = 0,
233 qthread = 0,
232 qthread = 0,
234 quick = 0,
233 quick = 0,
235 quiet = 0,
234 quiet = 0,
236 rcfile = 'ipythonrc' + rc_suffix,
235 rcfile = 'ipythonrc' + rc_suffix,
237 readline = 1,
236 readline = 1,
238 readline_merge_completions = 1,
237 readline_merge_completions = 1,
239 readline_omit__names = 0,
238 readline_omit__names = 0,
240 screen_length = 0,
239 screen_length = 0,
241 separate_in = '\n',
240 separate_in = '\n',
242 separate_out = '\n',
241 separate_out = '\n',
243 separate_out2 = '',
242 separate_out2 = '',
244 system_header = 'IPython system call: ',
243 system_header = 'IPython system call: ',
245 system_verbose = 0,
244 system_verbose = 0,
246 term_title = 1,
245 term_title = 1,
247 tk = 0,
246 tk = 0,
247 twisted= 0,
248 upgrade = 0,
248 upgrade = 0,
249 Version = 0,
249 Version = 0,
250 wildcards_case_sensitive = 1,
250 wildcards_case_sensitive = 1,
251 wthread = 0,
251 wthread = 0,
252 wxversion = '0',
252 wxversion = '0',
253 xmode = 'Context',
253 xmode = 'Context',
254 magic_docstrings = 0, # undocumented, for doc generation
254 magic_docstrings = 0, # undocumented, for doc generation
255 )
255 )
256
256
257 # Things that will *only* appear in rcfiles (not at the command line).
257 # Things that will *only* appear in rcfiles (not at the command line).
258 # Make sure there's a space before each end of line (they get auto-joined!)
258 # Make sure there's a space before each end of line (they get auto-joined!)
259 rcfile_opts = { qwflat: 'include import_mod import_all execfile ',
259 rcfile_opts = { qwflat: 'include import_mod import_all execfile ',
260 qw_lol: 'import_some ',
260 qw_lol: 'import_some ',
261 # for things with embedded whitespace:
261 # for things with embedded whitespace:
262 list_strings:'execute alias readline_parse_and_bind ',
262 list_strings:'execute alias readline_parse_and_bind ',
263 # Regular strings need no conversion:
263 # Regular strings need no conversion:
264 None:'readline_remove_delims ',
264 None:'readline_remove_delims ',
265 }
265 }
266 # Default values for these
266 # Default values for these
267 rc_def = Struct(include = [],
267 rc_def = Struct(include = [],
268 import_mod = [],
268 import_mod = [],
269 import_all = [],
269 import_all = [],
270 import_some = [[]],
270 import_some = [[]],
271 execute = [],
271 execute = [],
272 execfile = [],
272 execfile = [],
273 alias = [],
273 alias = [],
274 readline_parse_and_bind = [],
274 readline_parse_and_bind = [],
275 readline_remove_delims = '',
275 readline_remove_delims = '',
276 )
276 )
277
277
278 # Build the type conversion dictionary from the above tables:
278 # Build the type conversion dictionary from the above tables:
279 typeconv = rcfile_opts.copy()
279 typeconv = rcfile_opts.copy()
280 typeconv.update(optstr2types(cmdline_opts))
280 typeconv.update(optstr2types(cmdline_opts))
281
281
282 # FIXME: the None key appears in both, put that back together by hand. Ugly!
282 # FIXME: the None key appears in both, put that back together by hand. Ugly!
283 typeconv[None] += ' ' + rcfile_opts[None]
283 typeconv[None] += ' ' + rcfile_opts[None]
284
284
285 # Remove quotes at ends of all strings (used to protect spaces)
285 # Remove quotes at ends of all strings (used to protect spaces)
286 typeconv[unquote_ends] = typeconv[None]
286 typeconv[unquote_ends] = typeconv[None]
287 del typeconv[None]
287 del typeconv[None]
288
288
289 # Build the list we'll use to make all config decisions with defaults:
289 # Build the list we'll use to make all config decisions with defaults:
290 opts_all = opts_def.copy()
290 opts_all = opts_def.copy()
291 opts_all.update(rc_def)
291 opts_all.update(rc_def)
292
292
293 # Build conflict resolver for recursive loading of config files:
293 # Build conflict resolver for recursive loading of config files:
294 # - preserve means the outermost file maintains the value, it is not
294 # - preserve means the outermost file maintains the value, it is not
295 # overwritten if an included file has the same key.
295 # overwritten if an included file has the same key.
296 # - add_flip applies + to the two values, so it better make sense to add
296 # - add_flip applies + to the two values, so it better make sense to add
297 # those types of keys. But it flips them first so that things loaded
297 # those types of keys. But it flips them first so that things loaded
298 # deeper in the inclusion chain have lower precedence.
298 # deeper in the inclusion chain have lower precedence.
299 conflict = {'preserve': ' '.join([ typeconv[int],
299 conflict = {'preserve': ' '.join([ typeconv[int],
300 typeconv[unquote_ends] ]),
300 typeconv[unquote_ends] ]),
301 'add_flip': ' '.join([ typeconv[qwflat],
301 'add_flip': ' '.join([ typeconv[qwflat],
302 typeconv[qw_lol],
302 typeconv[qw_lol],
303 typeconv[list_strings] ])
303 typeconv[list_strings] ])
304 }
304 }
305
305
306 # Now actually process the command line
306 # Now actually process the command line
307 getopt = DPyGetOpt.DPyGetOpt()
307 getopt = DPyGetOpt.DPyGetOpt()
308 getopt.setIgnoreCase(0)
308 getopt.setIgnoreCase(0)
309
309
310 getopt.parseConfiguration(opts_names)
310 getopt.parseConfiguration(opts_names)
311
311
312 try:
312 try:
313 getopt.processArguments(argv)
313 getopt.processArguments(argv)
314 except DPyGetOpt.ArgumentError, exc:
314 except DPyGetOpt.ArgumentError, exc:
315 print cmd_line_usage
315 print cmd_line_usage
316 warn('\nError in Arguments: "%s"' % exc)
316 warn('\nError in Arguments: "%s"' % exc)
317 sys.exit(1)
317 sys.exit(1)
318
318
319 # convert the options dict to a struct for much lighter syntax later
319 # convert the options dict to a struct for much lighter syntax later
320 opts = Struct(getopt.optionValues)
320 opts = Struct(getopt.optionValues)
321 args = getopt.freeValues
321 args = getopt.freeValues
322
322
323 # this is the struct (which has default values at this point) with which
323 # this is the struct (which has default values at this point) with which
324 # we make all decisions:
324 # we make all decisions:
325 opts_all.update(opts)
325 opts_all.update(opts)
326
326
327 # Options that force an immediate exit
327 # Options that force an immediate exit
328 if opts_all.help:
328 if opts_all.help:
329 page(cmd_line_usage)
329 page(cmd_line_usage)
330 sys.exit()
330 sys.exit()
331
331
332 if opts_all.Version:
332 if opts_all.Version:
333 print __version__
333 print __version__
334 sys.exit()
334 sys.exit()
335
335
336 if opts_all.magic_docstrings:
336 if opts_all.magic_docstrings:
337 IP.magic_magic('-latex')
337 IP.magic_magic('-latex')
338 sys.exit()
338 sys.exit()
339
339
340 # add personal ipythondir to sys.path so that users can put things in
340 # add personal ipythondir to sys.path so that users can put things in
341 # there for customization
341 # there for customization
342 sys.path.append(os.path.abspath(opts_all.ipythondir))
342 sys.path.append(os.path.abspath(opts_all.ipythondir))
343
343
344 # Create user config directory if it doesn't exist. This must be done
344 # Create user config directory if it doesn't exist. This must be done
345 # *after* getting the cmd line options.
345 # *after* getting the cmd line options.
346 if not os.path.isdir(opts_all.ipythondir):
346 if not os.path.isdir(opts_all.ipythondir):
347 IP.user_setup(opts_all.ipythondir,rc_suffix,'install')
347 IP.user_setup(opts_all.ipythondir,rc_suffix,'install')
348
348
349 # upgrade user config files while preserving a copy of the originals
349 # upgrade user config files while preserving a copy of the originals
350 if opts_all.upgrade:
350 if opts_all.upgrade:
351 IP.user_setup(opts_all.ipythondir,rc_suffix,'upgrade')
351 IP.user_setup(opts_all.ipythondir,rc_suffix,'upgrade')
352
352
353 # check mutually exclusive options in the *original* command line
353 # check mutually exclusive options in the *original* command line
354 mutex_opts(opts,[qw('log logfile'),qw('rcfile profile'),
354 mutex_opts(opts,[qw('log logfile'),qw('rcfile profile'),
355 qw('classic profile'),qw('classic rcfile')])
355 qw('classic profile'),qw('classic rcfile')])
356
356
357 #---------------------------------------------------------------------------
357 #---------------------------------------------------------------------------
358 # Log replay
358 # Log replay
359
359
360 # if -logplay, we need to 'become' the other session. That basically means
360 # if -logplay, we need to 'become' the other session. That basically means
361 # replacing the current command line environment with that of the old
361 # replacing the current command line environment with that of the old
362 # session and moving on.
362 # session and moving on.
363
363
364 # this is needed so that later we know we're in session reload mode, as
364 # this is needed so that later we know we're in session reload mode, as
365 # opts_all will get overwritten:
365 # opts_all will get overwritten:
366 load_logplay = 0
366 load_logplay = 0
367
367
368 if opts_all.logplay:
368 if opts_all.logplay:
369 load_logplay = opts_all.logplay
369 load_logplay = opts_all.logplay
370 opts_debug_save = opts_all.debug
370 opts_debug_save = opts_all.debug
371 try:
371 try:
372 logplay = open(opts_all.logplay)
372 logplay = open(opts_all.logplay)
373 except IOError:
373 except IOError:
374 if opts_all.debug: IP.InteractiveTB()
374 if opts_all.debug: IP.InteractiveTB()
375 warn('Could not open logplay file '+`opts_all.logplay`)
375 warn('Could not open logplay file '+`opts_all.logplay`)
376 # restore state as if nothing had happened and move on, but make
376 # restore state as if nothing had happened and move on, but make
377 # sure that later we don't try to actually load the session file
377 # sure that later we don't try to actually load the session file
378 logplay = None
378 logplay = None
379 load_logplay = 0
379 load_logplay = 0
380 del opts_all.logplay
380 del opts_all.logplay
381 else:
381 else:
382 try:
382 try:
383 logplay.readline()
383 logplay.readline()
384 logplay.readline();
384 logplay.readline();
385 # this reloads that session's command line
385 # this reloads that session's command line
386 cmd = logplay.readline()[6:]
386 cmd = logplay.readline()[6:]
387 exec cmd
387 exec cmd
388 # restore the true debug flag given so that the process of
388 # restore the true debug flag given so that the process of
389 # session loading itself can be monitored.
389 # session loading itself can be monitored.
390 opts.debug = opts_debug_save
390 opts.debug = opts_debug_save
391 # save the logplay flag so later we don't overwrite the log
391 # save the logplay flag so later we don't overwrite the log
392 opts.logplay = load_logplay
392 opts.logplay = load_logplay
393 # now we must update our own structure with defaults
393 # now we must update our own structure with defaults
394 opts_all.update(opts)
394 opts_all.update(opts)
395 # now load args
395 # now load args
396 cmd = logplay.readline()[6:]
396 cmd = logplay.readline()[6:]
397 exec cmd
397 exec cmd
398 logplay.close()
398 logplay.close()
399 except:
399 except:
400 logplay.close()
400 logplay.close()
401 if opts_all.debug: IP.InteractiveTB()
401 if opts_all.debug: IP.InteractiveTB()
402 warn("Logplay file lacking full configuration information.\n"
402 warn("Logplay file lacking full configuration information.\n"
403 "I'll try to read it, but some things may not work.")
403 "I'll try to read it, but some things may not work.")
404
404
405 #-------------------------------------------------------------------------
405 #-------------------------------------------------------------------------
406 # set up output traps: catch all output from files, being run, modules
406 # set up output traps: catch all output from files, being run, modules
407 # loaded, etc. Then give it to the user in a clean form at the end.
407 # loaded, etc. Then give it to the user in a clean form at the end.
408
408
409 msg_out = 'Output messages. '
409 msg_out = 'Output messages. '
410 msg_err = 'Error messages. '
410 msg_err = 'Error messages. '
411 msg_sep = '\n'
411 msg_sep = '\n'
412 msg = Struct(config = OutputTrap('Configuration Loader',msg_out,
412 msg = Struct(config = OutputTrap('Configuration Loader',msg_out,
413 msg_err,msg_sep,debug,
413 msg_err,msg_sep,debug,
414 quiet_out=1),
414 quiet_out=1),
415 user_exec = OutputTrap('User File Execution',msg_out,
415 user_exec = OutputTrap('User File Execution',msg_out,
416 msg_err,msg_sep,debug),
416 msg_err,msg_sep,debug),
417 logplay = OutputTrap('Log Loader',msg_out,
417 logplay = OutputTrap('Log Loader',msg_out,
418 msg_err,msg_sep,debug),
418 msg_err,msg_sep,debug),
419 summary = ''
419 summary = ''
420 )
420 )
421
421
422 #-------------------------------------------------------------------------
422 #-------------------------------------------------------------------------
423 # Process user ipythonrc-type configuration files
423 # Process user ipythonrc-type configuration files
424
424
425 # turn on output trapping and log to msg.config
425 # turn on output trapping and log to msg.config
426 # remember that with debug on, trapping is actually disabled
426 # remember that with debug on, trapping is actually disabled
427 msg.config.trap_all()
427 msg.config.trap_all()
428
428
429 # look for rcfile in current or default directory
429 # look for rcfile in current or default directory
430 try:
430 try:
431 opts_all.rcfile = filefind(opts_all.rcfile,opts_all.ipythondir)
431 opts_all.rcfile = filefind(opts_all.rcfile,opts_all.ipythondir)
432 except IOError:
432 except IOError:
433 if opts_all.debug: IP.InteractiveTB()
433 if opts_all.debug: IP.InteractiveTB()
434 warn('Configuration file %s not found. Ignoring request.'
434 warn('Configuration file %s not found. Ignoring request.'
435 % (opts_all.rcfile) )
435 % (opts_all.rcfile) )
436
436
437 # 'profiles' are a shorthand notation for config filenames
437 # 'profiles' are a shorthand notation for config filenames
438 profile_handled_by_legacy = False
438 profile_handled_by_legacy = False
439 if opts_all.profile:
439 if opts_all.profile:
440
440
441 try:
441 try:
442 opts_all.rcfile = filefind('ipythonrc-' + opts_all.profile
442 opts_all.rcfile = filefind('ipythonrc-' + opts_all.profile
443 + rc_suffix,
443 + rc_suffix,
444 opts_all.ipythondir)
444 opts_all.ipythondir)
445 profile_handled_by_legacy = True
445 profile_handled_by_legacy = True
446 except IOError:
446 except IOError:
447 if opts_all.debug: IP.InteractiveTB()
447 if opts_all.debug: IP.InteractiveTB()
448 opts.profile = '' # remove profile from options if invalid
448 opts.profile = '' # remove profile from options if invalid
449 # We won't warn anymore, primary method is ipy_profile_PROFNAME
449 # We won't warn anymore, primary method is ipy_profile_PROFNAME
450 # which does trigger a warning.
450 # which does trigger a warning.
451
451
452 # load the config file
452 # load the config file
453 rcfiledata = None
453 rcfiledata = None
454 if opts_all.quick:
454 if opts_all.quick:
455 print 'Launching IPython in quick mode. No config file read.'
455 print 'Launching IPython in quick mode. No config file read.'
456 elif opts_all.rcfile:
456 elif opts_all.rcfile:
457 try:
457 try:
458 cfg_loader = ConfigLoader(conflict)
458 cfg_loader = ConfigLoader(conflict)
459 rcfiledata = cfg_loader.load(opts_all.rcfile,typeconv,
459 rcfiledata = cfg_loader.load(opts_all.rcfile,typeconv,
460 'include',opts_all.ipythondir,
460 'include',opts_all.ipythondir,
461 purge = 1,
461 purge = 1,
462 unique = conflict['preserve'])
462 unique = conflict['preserve'])
463 except:
463 except:
464 IP.InteractiveTB()
464 IP.InteractiveTB()
465 warn('Problems loading configuration file '+
465 warn('Problems loading configuration file '+
466 `opts_all.rcfile`+
466 `opts_all.rcfile`+
467 '\nStarting with default -bare bones- configuration.')
467 '\nStarting with default -bare bones- configuration.')
468 else:
468 else:
469 warn('No valid configuration file found in either currrent directory\n'+
469 warn('No valid configuration file found in either currrent directory\n'+
470 'or in the IPython config. directory: '+`opts_all.ipythondir`+
470 'or in the IPython config. directory: '+`opts_all.ipythondir`+
471 '\nProceeding with internal defaults.')
471 '\nProceeding with internal defaults.')
472
472
473 #------------------------------------------------------------------------
473 #------------------------------------------------------------------------
474 # Set exception handlers in mode requested by user.
474 # Set exception handlers in mode requested by user.
475 otrap = OutputTrap(trap_out=1) # trap messages from magic_xmode
475 otrap = OutputTrap(trap_out=1) # trap messages from magic_xmode
476 IP.magic_xmode(opts_all.xmode)
476 IP.magic_xmode(opts_all.xmode)
477 otrap.release_out()
477 otrap.release_out()
478
478
479 #------------------------------------------------------------------------
479 #------------------------------------------------------------------------
480 # Execute user config
480 # Execute user config
481
481
482 # Create a valid config structure with the right precedence order:
482 # Create a valid config structure with the right precedence order:
483 # defaults < rcfile < command line. This needs to be in the instance, so
483 # defaults < rcfile < command line. This needs to be in the instance, so
484 # that method calls below that rely on it find it.
484 # that method calls below that rely on it find it.
485 IP.rc = rc_def.copy()
485 IP.rc = rc_def.copy()
486
486
487 # Work with a local alias inside this routine to avoid unnecessary
487 # Work with a local alias inside this routine to avoid unnecessary
488 # attribute lookups.
488 # attribute lookups.
489 IP_rc = IP.rc
489 IP_rc = IP.rc
490
490
491 IP_rc.update(opts_def)
491 IP_rc.update(opts_def)
492 if rcfiledata:
492 if rcfiledata:
493 # now we can update
493 # now we can update
494 IP_rc.update(rcfiledata)
494 IP_rc.update(rcfiledata)
495 IP_rc.update(opts)
495 IP_rc.update(opts)
496 IP_rc.update(rc_override)
496 IP_rc.update(rc_override)
497
497
498 # Store the original cmd line for reference:
498 # Store the original cmd line for reference:
499 IP_rc.opts = opts
499 IP_rc.opts = opts
500 IP_rc.args = args
500 IP_rc.args = args
501
501
502 # create a *runtime* Struct like rc for holding parameters which may be
502 # create a *runtime* Struct like rc for holding parameters which may be
503 # created and/or modified by runtime user extensions.
503 # created and/or modified by runtime user extensions.
504 IP.runtime_rc = Struct()
504 IP.runtime_rc = Struct()
505
505
506 # from this point on, all config should be handled through IP_rc,
506 # from this point on, all config should be handled through IP_rc,
507 # opts* shouldn't be used anymore.
507 # opts* shouldn't be used anymore.
508
508
509
509
510 # update IP_rc with some special things that need manual
510 # update IP_rc with some special things that need manual
511 # tweaks. Basically options which affect other options. I guess this
511 # tweaks. Basically options which affect other options. I guess this
512 # should just be written so that options are fully orthogonal and we
512 # should just be written so that options are fully orthogonal and we
513 # wouldn't worry about this stuff!
513 # wouldn't worry about this stuff!
514
514
515 if IP_rc.classic:
515 if IP_rc.classic:
516 IP_rc.quick = 1
516 IP_rc.quick = 1
517 IP_rc.cache_size = 0
517 IP_rc.cache_size = 0
518 IP_rc.pprint = 0
518 IP_rc.pprint = 0
519 IP_rc.prompt_in1 = '>>> '
519 IP_rc.prompt_in1 = '>>> '
520 IP_rc.prompt_in2 = '... '
520 IP_rc.prompt_in2 = '... '
521 IP_rc.prompt_out = ''
521 IP_rc.prompt_out = ''
522 IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0'
522 IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0'
523 IP_rc.colors = 'NoColor'
523 IP_rc.colors = 'NoColor'
524 IP_rc.xmode = 'Plain'
524 IP_rc.xmode = 'Plain'
525
525
526 IP.pre_config_initialization()
526 IP.pre_config_initialization()
527 # configure readline
527 # configure readline
528 # Define the history file for saving commands in between sessions
528 # Define the history file for saving commands in between sessions
529 if IP_rc.profile:
529 if IP_rc.profile:
530 histfname = 'history-%s' % IP_rc.profile
530 histfname = 'history-%s' % IP_rc.profile
531 else:
531 else:
532 histfname = 'history'
532 histfname = 'history'
533 IP.histfile = os.path.join(opts_all.ipythondir,histfname)
533 IP.histfile = os.path.join(opts_all.ipythondir,histfname)
534
534
535 # update exception handlers with rc file status
535 # update exception handlers with rc file status
536 otrap.trap_out() # I don't want these messages ever.
536 otrap.trap_out() # I don't want these messages ever.
537 IP.magic_xmode(IP_rc.xmode)
537 IP.magic_xmode(IP_rc.xmode)
538 otrap.release_out()
538 otrap.release_out()
539
539
540 # activate logging if requested and not reloading a log
540 # activate logging if requested and not reloading a log
541 if IP_rc.logplay:
541 if IP_rc.logplay:
542 IP.magic_logstart(IP_rc.logplay + ' append')
542 IP.magic_logstart(IP_rc.logplay + ' append')
543 elif IP_rc.logfile:
543 elif IP_rc.logfile:
544 IP.magic_logstart(IP_rc.logfile)
544 IP.magic_logstart(IP_rc.logfile)
545 elif IP_rc.log:
545 elif IP_rc.log:
546 IP.magic_logstart()
546 IP.magic_logstart()
547
547
548 # find user editor so that it we don't have to look it up constantly
548 # find user editor so that it we don't have to look it up constantly
549 if IP_rc.editor.strip()=='0':
549 if IP_rc.editor.strip()=='0':
550 try:
550 try:
551 ed = os.environ['EDITOR']
551 ed = os.environ['EDITOR']
552 except KeyError:
552 except KeyError:
553 if os.name == 'posix':
553 if os.name == 'posix':
554 ed = 'vi' # the only one guaranteed to be there!
554 ed = 'vi' # the only one guaranteed to be there!
555 else:
555 else:
556 ed = 'notepad' # same in Windows!
556 ed = 'notepad' # same in Windows!
557 IP_rc.editor = ed
557 IP_rc.editor = ed
558
558
559 # Keep track of whether this is an embedded instance or not (useful for
559 # Keep track of whether this is an embedded instance or not (useful for
560 # post-mortems).
560 # post-mortems).
561 IP_rc.embedded = IP.embedded
561 IP_rc.embedded = IP.embedded
562
562
563 # Recursive reload
563 # Recursive reload
564 try:
564 try:
565 from IPython import deep_reload
565 from IPython import deep_reload
566 if IP_rc.deep_reload:
566 if IP_rc.deep_reload:
567 __builtin__.reload = deep_reload.reload
567 __builtin__.reload = deep_reload.reload
568 else:
568 else:
569 __builtin__.dreload = deep_reload.reload
569 __builtin__.dreload = deep_reload.reload
570 del deep_reload
570 del deep_reload
571 except ImportError:
571 except ImportError:
572 pass
572 pass
573
573
574 # Save the current state of our namespace so that the interactive shell
574 # Save the current state of our namespace so that the interactive shell
575 # can later know which variables have been created by us from config files
575 # can later know which variables have been created by us from config files
576 # and loading. This way, loading a file (in any way) is treated just like
576 # and loading. This way, loading a file (in any way) is treated just like
577 # defining things on the command line, and %who works as expected.
577 # defining things on the command line, and %who works as expected.
578
578
579 # DON'T do anything that affects the namespace beyond this point!
579 # DON'T do anything that affects the namespace beyond this point!
580 IP.internal_ns.update(__main__.__dict__)
580 IP.internal_ns.update(__main__.__dict__)
581
581
582 #IP.internal_ns.update(locals()) # so our stuff doesn't show up in %who
582 #IP.internal_ns.update(locals()) # so our stuff doesn't show up in %who
583
583
584 # Now run through the different sections of the users's config
584 # Now run through the different sections of the users's config
585 if IP_rc.debug:
585 if IP_rc.debug:
586 print 'Trying to execute the following configuration structure:'
586 print 'Trying to execute the following configuration structure:'
587 print '(Things listed first are deeper in the inclusion tree and get'
587 print '(Things listed first are deeper in the inclusion tree and get'
588 print 'loaded first).\n'
588 print 'loaded first).\n'
589 pprint(IP_rc.__dict__)
589 pprint(IP_rc.__dict__)
590
590
591 for mod in IP_rc.import_mod:
591 for mod in IP_rc.import_mod:
592 try:
592 try:
593 exec 'import '+mod in IP.user_ns
593 exec 'import '+mod in IP.user_ns
594 except :
594 except :
595 IP.InteractiveTB()
595 IP.InteractiveTB()
596 import_fail_info(mod)
596 import_fail_info(mod)
597
597
598 for mod_fn in IP_rc.import_some:
598 for mod_fn in IP_rc.import_some:
599 if not mod_fn == []:
599 if not mod_fn == []:
600 mod,fn = mod_fn[0],','.join(mod_fn[1:])
600 mod,fn = mod_fn[0],','.join(mod_fn[1:])
601 try:
601 try:
602 exec 'from '+mod+' import '+fn in IP.user_ns
602 exec 'from '+mod+' import '+fn in IP.user_ns
603 except :
603 except :
604 IP.InteractiveTB()
604 IP.InteractiveTB()
605 import_fail_info(mod,fn)
605 import_fail_info(mod,fn)
606
606
607 for mod in IP_rc.import_all:
607 for mod in IP_rc.import_all:
608 try:
608 try:
609 exec 'from '+mod+' import *' in IP.user_ns
609 exec 'from '+mod+' import *' in IP.user_ns
610 except :
610 except :
611 IP.InteractiveTB()
611 IP.InteractiveTB()
612 import_fail_info(mod)
612 import_fail_info(mod)
613
613
614 for code in IP_rc.execute:
614 for code in IP_rc.execute:
615 try:
615 try:
616 exec code in IP.user_ns
616 exec code in IP.user_ns
617 except:
617 except:
618 IP.InteractiveTB()
618 IP.InteractiveTB()
619 warn('Failure executing code: ' + `code`)
619 warn('Failure executing code: ' + `code`)
620
620
621 # Execute the files the user wants in ipythonrc
621 # Execute the files the user wants in ipythonrc
622 for file in IP_rc.execfile:
622 for file in IP_rc.execfile:
623 try:
623 try:
624 file = filefind(file,sys.path+[IPython_dir])
624 file = filefind(file,sys.path+[IPython_dir])
625 except IOError:
625 except IOError:
626 warn(itpl('File $file not found. Skipping it.'))
626 warn(itpl('File $file not found. Skipping it.'))
627 else:
627 else:
628 IP.safe_execfile(os.path.expanduser(file),IP.user_ns)
628 IP.safe_execfile(os.path.expanduser(file),IP.user_ns)
629
629
630 # finally, try importing ipy_*_conf for final configuration
630 # finally, try importing ipy_*_conf for final configuration
631 try:
631 try:
632 import ipy_system_conf
632 import ipy_system_conf
633 except ImportError:
633 except ImportError:
634 if opts_all.debug: IP.InteractiveTB()
634 if opts_all.debug: IP.InteractiveTB()
635 warn("Could not import 'ipy_system_conf'")
635 warn("Could not import 'ipy_system_conf'")
636 except:
636 except:
637 IP.InteractiveTB()
637 IP.InteractiveTB()
638 import_fail_info('ipy_system_conf')
638 import_fail_info('ipy_system_conf')
639
639
640 # only import prof module if ipythonrc-PROF was not found
640 # only import prof module if ipythonrc-PROF was not found
641 if opts_all.profile and not profile_handled_by_legacy:
641 if opts_all.profile and not profile_handled_by_legacy:
642 profmodname = 'ipy_profile_' + opts_all.profile
642 profmodname = 'ipy_profile_' + opts_all.profile
643 try:
643 try:
644
644
645 force_import(profmodname)
645 force_import(profmodname)
646 except:
646 except:
647 IP.InteractiveTB()
647 IP.InteractiveTB()
648 print "Error importing",profmodname,"- perhaps you should run %upgrade?"
648 print "Error importing",profmodname,"- perhaps you should run %upgrade?"
649 import_fail_info(profmodname)
649 import_fail_info(profmodname)
650 else:
650 else:
651 force_import('ipy_profile_none')
651 force_import('ipy_profile_none')
652 try:
652 try:
653
653
654 force_import('ipy_user_conf')
654 force_import('ipy_user_conf')
655
655
656 except:
656 except:
657 conf = opts_all.ipythondir + "/ipy_user_conf.py"
657 conf = opts_all.ipythondir + "/ipy_user_conf.py"
658 IP.InteractiveTB()
658 IP.InteractiveTB()
659 if not os.path.isfile(conf):
659 if not os.path.isfile(conf):
660 warn(conf + ' does not exist, please run %upgrade!')
660 warn(conf + ' does not exist, please run %upgrade!')
661
661
662 import_fail_info("ipy_user_conf")
662 import_fail_info("ipy_user_conf")
663
663
664 # finally, push the argv to options again to ensure highest priority
664 # finally, push the argv to options again to ensure highest priority
665 IP_rc.update(opts)
665 IP_rc.update(opts)
666
666
667 # release stdout and stderr and save config log into a global summary
667 # release stdout and stderr and save config log into a global summary
668 msg.config.release_all()
668 msg.config.release_all()
669 if IP_rc.messages:
669 if IP_rc.messages:
670 msg.summary += msg.config.summary_all()
670 msg.summary += msg.config.summary_all()
671
671
672 #------------------------------------------------------------------------
672 #------------------------------------------------------------------------
673 # Setup interactive session
673 # Setup interactive session
674
674
675 # Now we should be fully configured. We can then execute files or load
675 # Now we should be fully configured. We can then execute files or load
676 # things only needed for interactive use. Then we'll open the shell.
676 # things only needed for interactive use. Then we'll open the shell.
677
677
678 # Take a snapshot of the user namespace before opening the shell. That way
678 # Take a snapshot of the user namespace before opening the shell. That way
679 # we'll be able to identify which things were interactively defined and
679 # we'll be able to identify which things were interactively defined and
680 # which were defined through config files.
680 # which were defined through config files.
681 IP.user_config_ns.update(IP.user_ns)
681 IP.user_config_ns.update(IP.user_ns)
682
682
683 # Force reading a file as if it were a session log. Slower but safer.
683 # Force reading a file as if it were a session log. Slower but safer.
684 if load_logplay:
684 if load_logplay:
685 print 'Replaying log...'
685 print 'Replaying log...'
686 try:
686 try:
687 if IP_rc.debug:
687 if IP_rc.debug:
688 logplay_quiet = 0
688 logplay_quiet = 0
689 else:
689 else:
690 logplay_quiet = 1
690 logplay_quiet = 1
691
691
692 msg.logplay.trap_all()
692 msg.logplay.trap_all()
693 IP.safe_execfile(load_logplay,IP.user_ns,
693 IP.safe_execfile(load_logplay,IP.user_ns,
694 islog = 1, quiet = logplay_quiet)
694 islog = 1, quiet = logplay_quiet)
695 msg.logplay.release_all()
695 msg.logplay.release_all()
696 if IP_rc.messages:
696 if IP_rc.messages:
697 msg.summary += msg.logplay.summary_all()
697 msg.summary += msg.logplay.summary_all()
698 except:
698 except:
699 warn('Problems replaying logfile %s.' % load_logplay)
699 warn('Problems replaying logfile %s.' % load_logplay)
700 IP.InteractiveTB()
700 IP.InteractiveTB()
701
701
702 # Load remaining files in command line
702 # Load remaining files in command line
703 msg.user_exec.trap_all()
703 msg.user_exec.trap_all()
704
704
705 # Do NOT execute files named in the command line as scripts to be loaded
705 # Do NOT execute files named in the command line as scripts to be loaded
706 # by embedded instances. Doing so has the potential for an infinite
706 # by embedded instances. Doing so has the potential for an infinite
707 # recursion if there are exceptions thrown in the process.
707 # recursion if there are exceptions thrown in the process.
708
708
709 # XXX FIXME: the execution of user files should be moved out to after
709 # XXX FIXME: the execution of user files should be moved out to after
710 # ipython is fully initialized, just as if they were run via %run at the
710 # ipython is fully initialized, just as if they were run via %run at the
711 # ipython prompt. This would also give them the benefit of ipython's
711 # ipython prompt. This would also give them the benefit of ipython's
712 # nice tracebacks.
712 # nice tracebacks.
713
713
714 if (not embedded and IP_rc.args and
714 if (not embedded and IP_rc.args and
715 not IP_rc.args[0].lower().endswith('.ipy')):
715 not IP_rc.args[0].lower().endswith('.ipy')):
716 name_save = IP.user_ns['__name__']
716 name_save = IP.user_ns['__name__']
717 IP.user_ns['__name__'] = '__main__'
717 IP.user_ns['__name__'] = '__main__'
718 # Set our own excepthook in case the user code tries to call it
718 # Set our own excepthook in case the user code tries to call it
719 # directly. This prevents triggering the IPython crash handler.
719 # directly. This prevents triggering the IPython crash handler.
720 old_excepthook,sys.excepthook = sys.excepthook, IP.excepthook
720 old_excepthook,sys.excepthook = sys.excepthook, IP.excepthook
721
721
722 save_argv = sys.argv[1:] # save it for later restoring
722 save_argv = sys.argv[1:] # save it for later restoring
723
723
724 sys.argv = args
724 sys.argv = args
725
725
726 try:
726 try:
727 IP.safe_execfile(args[0], IP.user_ns)
727 IP.safe_execfile(args[0], IP.user_ns)
728 finally:
728 finally:
729 # Reset our crash handler in place
729 # Reset our crash handler in place
730 sys.excepthook = old_excepthook
730 sys.excepthook = old_excepthook
731 sys.argv[:] = save_argv
731 sys.argv[:] = save_argv
732 IP.user_ns['__name__'] = name_save
732 IP.user_ns['__name__'] = name_save
733
733
734 msg.user_exec.release_all()
734 msg.user_exec.release_all()
735
735
736 if IP_rc.messages:
736 if IP_rc.messages:
737 msg.summary += msg.user_exec.summary_all()
737 msg.summary += msg.user_exec.summary_all()
738
738
739 # since we can't specify a null string on the cmd line, 0 is the equivalent:
739 # since we can't specify a null string on the cmd line, 0 is the equivalent:
740 if IP_rc.nosep:
740 if IP_rc.nosep:
741 IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0'
741 IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0'
742 if IP_rc.separate_in == '0': IP_rc.separate_in = ''
742 if IP_rc.separate_in == '0': IP_rc.separate_in = ''
743 if IP_rc.separate_out == '0': IP_rc.separate_out = ''
743 if IP_rc.separate_out == '0': IP_rc.separate_out = ''
744 if IP_rc.separate_out2 == '0': IP_rc.separate_out2 = ''
744 if IP_rc.separate_out2 == '0': IP_rc.separate_out2 = ''
745 IP_rc.separate_in = IP_rc.separate_in.replace('\\n','\n')
745 IP_rc.separate_in = IP_rc.separate_in.replace('\\n','\n')
746 IP_rc.separate_out = IP_rc.separate_out.replace('\\n','\n')
746 IP_rc.separate_out = IP_rc.separate_out.replace('\\n','\n')
747 IP_rc.separate_out2 = IP_rc.separate_out2.replace('\\n','\n')
747 IP_rc.separate_out2 = IP_rc.separate_out2.replace('\\n','\n')
748
748
749 # Determine how many lines at the bottom of the screen are needed for
749 # Determine how many lines at the bottom of the screen are needed for
750 # showing prompts, so we can know wheter long strings are to be printed or
750 # showing prompts, so we can know wheter long strings are to be printed or
751 # paged:
751 # paged:
752 num_lines_bot = IP_rc.separate_in.count('\n')+1
752 num_lines_bot = IP_rc.separate_in.count('\n')+1
753 IP_rc.screen_length = IP_rc.screen_length - num_lines_bot
753 IP_rc.screen_length = IP_rc.screen_length - num_lines_bot
754
754
755 # configure startup banner
755 # configure startup banner
756 if IP_rc.c: # regular python doesn't print the banner with -c
756 if IP_rc.c: # regular python doesn't print the banner with -c
757 IP_rc.banner = 0
757 IP_rc.banner = 0
758 if IP_rc.banner:
758 if IP_rc.banner:
759 BANN_P = IP.BANNER_PARTS
759 BANN_P = IP.BANNER_PARTS
760 else:
760 else:
761 BANN_P = []
761 BANN_P = []
762
762
763 if IP_rc.profile: BANN_P.append('IPython profile: %s\n' % IP_rc.profile)
763 if IP_rc.profile: BANN_P.append('IPython profile: %s\n' % IP_rc.profile)
764
764
765 # add message log (possibly empty)
765 # add message log (possibly empty)
766 if msg.summary: BANN_P.append(msg.summary)
766 if msg.summary: BANN_P.append(msg.summary)
767 # Final banner is a string
767 # Final banner is a string
768 IP.BANNER = '\n'.join(BANN_P)
768 IP.BANNER = '\n'.join(BANN_P)
769
769
770 # Finalize the IPython instance. This assumes the rc structure is fully
770 # Finalize the IPython instance. This assumes the rc structure is fully
771 # in place.
771 # in place.
772 IP.post_config_initialization()
772 IP.post_config_initialization()
773
773
774 return IP
774 return IP
775 #************************ end of file <ipmaker.py> **************************
775 #************************ end of file <ipmaker.py> **************************
General Comments 0
You need to be logged in to leave comments. Login now