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