##// END OF EJS Templates
qt4agg matplotlib backend support for pylab...
vivainio -
Show More

The requested changes are too big and content was truncated. Show full diff

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