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