##// END OF EJS Templates
Make the prefilterfrontend take an optional ipython0 instance as the...
Gael Varoquaux -
r1504:1d3334e3 merge
parent child Browse files
Show More
@@ -1,1236 +1,1236 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 # Default timeout for waiting for multithreaded shells (in seconds)
63 63 GUI_TIMEOUT = 10
64 64
65 65 #-----------------------------------------------------------------------------
66 66 # This class is trivial now, but I want to have it in to publish a clean
67 67 # interface. Later when the internals are reorganized, code that uses this
68 68 # shouldn't have to change.
69 69
70 70 class IPShell:
71 71 """Create an IPython instance."""
72 72
73 73 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
74 74 debug=1,shell_class=InteractiveShell):
75 75 self.IP = make_IPython(argv,user_ns=user_ns,
76 76 user_global_ns=user_global_ns,
77 77 debug=debug,shell_class=shell_class)
78 78
79 79 def mainloop(self,sys_exit=0,banner=None):
80 80 self.IP.mainloop(banner)
81 81 if sys_exit:
82 82 sys.exit()
83 83
84 84 #-----------------------------------------------------------------------------
85 85 def kill_embedded(self,parameter_s=''):
86 86 """%kill_embedded : deactivate for good the current embedded IPython.
87 87
88 88 This function (after asking for confirmation) sets an internal flag so that
89 89 an embedded IPython will never activate again. This is useful to
90 90 permanently disable a shell that is being called inside a loop: once you've
91 91 figured out what you needed from it, you may then kill it and the program
92 92 will then continue to run without the interactive shell interfering again.
93 93 """
94 94
95 95 kill = ask_yes_no("Are you sure you want to kill this embedded instance "
96 96 "(y/n)? [y/N] ",'n')
97 97 if kill:
98 98 self.shell.embedded_active = False
99 99 print "This embedded IPython will not reactivate anymore once you exit."
100 100
101 101 class IPShellEmbed:
102 102 """Allow embedding an IPython shell into a running program.
103 103
104 104 Instances of this class are callable, with the __call__ method being an
105 105 alias to the embed() method of an InteractiveShell instance.
106 106
107 107 Usage (see also the example-embed.py file for a running example):
108 108
109 109 ipshell = IPShellEmbed([argv,banner,exit_msg,rc_override])
110 110
111 111 - argv: list containing valid command-line options for IPython, as they
112 112 would appear in sys.argv[1:].
113 113
114 114 For example, the following command-line options:
115 115
116 116 $ ipython -prompt_in1 'Input <\\#>' -colors LightBG
117 117
118 118 would be passed in the argv list as:
119 119
120 120 ['-prompt_in1','Input <\\#>','-colors','LightBG']
121 121
122 122 - banner: string which gets printed every time the interpreter starts.
123 123
124 124 - exit_msg: string which gets printed every time the interpreter exits.
125 125
126 126 - rc_override: a dict or Struct of configuration options such as those
127 127 used by IPython. These options are read from your ~/.ipython/ipythonrc
128 128 file when the Shell object is created. Passing an explicit rc_override
129 129 dict with any options you want allows you to override those values at
130 130 creation time without having to modify the file. This way you can create
131 131 embeddable instances configured in any way you want without editing any
132 132 global files (thus keeping your interactive IPython configuration
133 133 unchanged).
134 134
135 135 Then the ipshell instance can be called anywhere inside your code:
136 136
137 137 ipshell(header='') -> Opens up an IPython shell.
138 138
139 139 - header: string printed by the IPython shell upon startup. This can let
140 140 you know where in your code you are when dropping into the shell. Note
141 141 that 'banner' gets prepended to all calls, so header is used for
142 142 location-specific information.
143 143
144 144 For more details, see the __call__ method below.
145 145
146 146 When the IPython shell is exited with Ctrl-D, normal program execution
147 147 resumes.
148 148
149 149 This functionality was inspired by a posting on comp.lang.python by cmkl
150 150 <cmkleffner@gmx.de> on Dec. 06/01 concerning similar uses of pyrepl, and
151 151 by the IDL stop/continue commands."""
152 152
153 153 def __init__(self,argv=None,banner='',exit_msg=None,rc_override=None,
154 154 user_ns=None):
155 155 """Note that argv here is a string, NOT a list."""
156 156 self.set_banner(banner)
157 157 self.set_exit_msg(exit_msg)
158 158 self.set_dummy_mode(0)
159 159
160 160 # sys.displayhook is a global, we need to save the user's original
161 161 # Don't rely on __displayhook__, as the user may have changed that.
162 162 self.sys_displayhook_ori = sys.displayhook
163 163
164 164 # save readline completer status
165 165 try:
166 166 #print 'Save completer',sys.ipcompleter # dbg
167 167 self.sys_ipcompleter_ori = sys.ipcompleter
168 168 except:
169 169 pass # not nested with IPython
170 170
171 171 self.IP = make_IPython(argv,rc_override=rc_override,
172 172 embedded=True,
173 173 user_ns=user_ns)
174 174
175 175 ip = ipapi.IPApi(self.IP)
176 176 ip.expose_magic("kill_embedded",kill_embedded)
177 177
178 178 # copy our own displayhook also
179 179 self.sys_displayhook_embed = sys.displayhook
180 180 # and leave the system's display hook clean
181 181 sys.displayhook = self.sys_displayhook_ori
182 182 # don't use the ipython crash handler so that user exceptions aren't
183 183 # trapped
184 184 sys.excepthook = ultraTB.FormattedTB(color_scheme = self.IP.rc.colors,
185 185 mode = self.IP.rc.xmode,
186 186 call_pdb = self.IP.rc.pdb)
187 187 self.restore_system_completer()
188 188
189 189 def restore_system_completer(self):
190 190 """Restores the readline completer which was in place.
191 191
192 192 This allows embedded IPython within IPython not to disrupt the
193 193 parent's completion.
194 194 """
195 195
196 196 try:
197 197 self.IP.readline.set_completer(self.sys_ipcompleter_ori)
198 198 sys.ipcompleter = self.sys_ipcompleter_ori
199 199 except:
200 200 pass
201 201
202 202 def __call__(self,header='',local_ns=None,global_ns=None,dummy=None):
203 203 """Activate the interactive interpreter.
204 204
205 205 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
206 206 the interpreter shell with the given local and global namespaces, and
207 207 optionally print a header string at startup.
208 208
209 209 The shell can be globally activated/deactivated using the
210 210 set/get_dummy_mode methods. This allows you to turn off a shell used
211 211 for debugging globally.
212 212
213 213 However, *each* time you call the shell you can override the current
214 214 state of dummy_mode with the optional keyword parameter 'dummy'. For
215 215 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
216 216 can still have a specific call work by making it as IPShell(dummy=0).
217 217
218 218 The optional keyword parameter dummy controls whether the call
219 219 actually does anything. """
220 220
221 221 # If the user has turned it off, go away
222 222 if not self.IP.embedded_active:
223 223 return
224 224
225 225 # Normal exits from interactive mode set this flag, so the shell can't
226 226 # re-enter (it checks this variable at the start of interactive mode).
227 227 self.IP.exit_now = False
228 228
229 229 # Allow the dummy parameter to override the global __dummy_mode
230 230 if dummy or (dummy != 0 and self.__dummy_mode):
231 231 return
232 232
233 233 # Set global subsystems (display,completions) to our values
234 234 sys.displayhook = self.sys_displayhook_embed
235 235 if self.IP.has_readline:
236 236 self.IP.set_completer()
237 237
238 238 if self.banner and header:
239 239 format = '%s\n%s\n'
240 240 else:
241 241 format = '%s%s\n'
242 242 banner = format % (self.banner,header)
243 243
244 244 # Call the embedding code with a stack depth of 1 so it can skip over
245 245 # our call and get the original caller's namespaces.
246 246 self.IP.embed_mainloop(banner,local_ns,global_ns,stack_depth=1)
247 247
248 248 if self.exit_msg:
249 249 print self.exit_msg
250 250
251 251 # Restore global systems (display, completion)
252 252 sys.displayhook = self.sys_displayhook_ori
253 253 self.restore_system_completer()
254 254
255 255 def set_dummy_mode(self,dummy):
256 256 """Sets the embeddable shell's dummy mode parameter.
257 257
258 258 set_dummy_mode(dummy): dummy = 0 or 1.
259 259
260 260 This parameter is persistent and makes calls to the embeddable shell
261 261 silently return without performing any action. This allows you to
262 262 globally activate or deactivate a shell you're using with a single call.
263 263
264 264 If you need to manually"""
265 265
266 266 if dummy not in [0,1,False,True]:
267 267 raise ValueError,'dummy parameter must be boolean'
268 268 self.__dummy_mode = dummy
269 269
270 270 def get_dummy_mode(self):
271 271 """Return the current value of the dummy mode parameter.
272 272 """
273 273 return self.__dummy_mode
274 274
275 275 def set_banner(self,banner):
276 276 """Sets the global banner.
277 277
278 278 This banner gets prepended to every header printed when the shell
279 279 instance is called."""
280 280
281 281 self.banner = banner
282 282
283 283 def set_exit_msg(self,exit_msg):
284 284 """Sets the global exit_msg.
285 285
286 286 This exit message gets printed upon exiting every time the embedded
287 287 shell is called. It is None by default. """
288 288
289 289 self.exit_msg = exit_msg
290 290
291 291 #-----------------------------------------------------------------------------
292 292 if HAS_CTYPES:
293 293 # Add async exception support. Trick taken from:
294 294 # http://sebulba.wikispaces.com/recipe+thread2
295 295 def _async_raise(tid, exctype):
296 296 """raises the exception, performs cleanup if needed"""
297 297 if not inspect.isclass(exctype):
298 298 raise TypeError("Only types can be raised (not instances)")
299 299 res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,
300 300 ctypes.py_object(exctype))
301 301 if res == 0:
302 302 raise ValueError("invalid thread id")
303 303 elif res != 1:
304 304 # """if it returns a number greater than one, you're in trouble,
305 305 # and you should call it again with exc=NULL to revert the effect"""
306 306 ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
307 307 raise SystemError("PyThreadState_SetAsyncExc failed")
308 308
309 309 def sigint_handler (signum,stack_frame):
310 310 """Sigint handler for threaded apps.
311 311
312 312 This is a horrible hack to pass information about SIGINT _without_
313 313 using exceptions, since I haven't been able to properly manage
314 314 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
315 315 done (or at least that's my understanding from a c.l.py thread where
316 316 this was discussed)."""
317 317
318 318 global KBINT
319 319
320 320 if CODE_RUN:
321 321 _async_raise(MAIN_THREAD_ID,KeyboardInterrupt)
322 322 else:
323 323 KBINT = True
324 324 print '\nKeyboardInterrupt - Press <Enter> to continue.',
325 325 Term.cout.flush()
326 326
327 327 else:
328 328 def sigint_handler (signum,stack_frame):
329 329 """Sigint handler for threaded apps.
330 330
331 331 This is a horrible hack to pass information about SIGINT _without_
332 332 using exceptions, since I haven't been able to properly manage
333 333 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
334 334 done (or at least that's my understanding from a c.l.py thread where
335 335 this was discussed)."""
336 336
337 337 global KBINT
338 338
339 339 print '\nKeyboardInterrupt - Press <Enter> to continue.',
340 340 Term.cout.flush()
341 341 # Set global flag so that runsource can know that Ctrl-C was hit
342 342 KBINT = True
343 343
344 344
345 345 class MTInteractiveShell(InteractiveShell):
346 346 """Simple multi-threaded shell."""
347 347
348 348 # Threading strategy taken from:
349 349 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109, by Brian
350 350 # McErlean and John Finlay. Modified with corrections by Antoon Pardon,
351 351 # from the pygtk mailing list, to avoid lockups with system calls.
352 352
353 353 # class attribute to indicate whether the class supports threads or not.
354 354 # Subclasses with thread support should override this as needed.
355 355 isthreaded = True
356 356
357 357 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
358 358 user_ns=None,user_global_ns=None,banner2='',
359 359 gui_timeout=GUI_TIMEOUT,**kw):
360 360 """Similar to the normal InteractiveShell, but with threading control"""
361 361
362 362 InteractiveShell.__init__(self,name,usage,rc,user_ns,
363 363 user_global_ns,banner2)
364 364
365 365 # Timeout we wait for GUI thread
366 366 self.gui_timeout = gui_timeout
367 367
368 368 # A queue to hold the code to be executed.
369 369 self.code_queue = Queue.Queue()
370 370
371 371 # Stuff to do at closing time
372 372 self._kill = None
373 373 on_kill = kw.get('on_kill', [])
374 374 # Check that all things to kill are callable:
375 375 for t in on_kill:
376 376 if not callable(t):
377 377 raise TypeError,'on_kill must be a list of callables'
378 378 self.on_kill = on_kill
379 379 # thread identity of the "worker thread" (that may execute code directly)
380 380 self.worker_ident = None
381 381
382 382 def runsource(self, source, filename="<input>", symbol="single"):
383 383 """Compile and run some source in the interpreter.
384 384
385 385 Modified version of code.py's runsource(), to handle threading issues.
386 386 See the original for full docstring details."""
387 387
388 388 global KBINT
389 389
390 390 # If Ctrl-C was typed, we reset the flag and return right away
391 391 if KBINT:
392 392 KBINT = False
393 393 return False
394 394
395 395 if self._kill:
396 396 # can't queue new code if we are being killed
397 397 return True
398 398
399 399 try:
400 400 code = self.compile(source, filename, symbol)
401 401 except (OverflowError, SyntaxError, ValueError):
402 402 # Case 1
403 403 self.showsyntaxerror(filename)
404 404 return False
405 405
406 406 if code is None:
407 407 # Case 2
408 408 return True
409 409
410 410 # shortcut - if we are in worker thread, or the worker thread is not
411 411 # running, execute directly (to allow recursion and prevent deadlock if
412 412 # code is run early in IPython construction)
413 413
414 414 if (self.worker_ident is None
415 415 or self.worker_ident == thread.get_ident() ):
416 416 InteractiveShell.runcode(self,code)
417 417 return
418 418
419 419 # Case 3
420 420 # Store code in queue, so the execution thread can handle it.
421 421
422 422 completed_ev, received_ev = threading.Event(), threading.Event()
423 423
424 424 self.code_queue.put((code,completed_ev, received_ev))
425 425 # first make sure the message was received, with timeout
426 426 received_ev.wait(self.gui_timeout)
427 427 if not received_ev.isSet():
428 428 # the mainloop is dead, start executing code directly
429 429 print "Warning: Timeout for mainloop thread exceeded"
430 430 print "switching to nonthreaded mode (until mainloop wakes up again)"
431 431 self.worker_ident = None
432 432 else:
433 433 completed_ev.wait()
434 434 return False
435 435
436 436 def runcode(self):
437 437 """Execute a code object.
438 438
439 439 Multithreaded wrapper around IPython's runcode()."""
440 440
441 441 global CODE_RUN
442 442
443 443 # we are in worker thread, stash out the id for runsource()
444 444 self.worker_ident = thread.get_ident()
445 445
446 446 if self._kill:
447 447 print >>Term.cout, 'Closing threads...',
448 448 Term.cout.flush()
449 449 for tokill in self.on_kill:
450 450 tokill()
451 451 print >>Term.cout, 'Done.'
452 452 # allow kill() to return
453 453 self._kill.set()
454 454 return True
455 455
456 456 # Install sigint handler. We do it every time to ensure that if user
457 457 # code modifies it, we restore our own handling.
458 458 try:
459 459 signal(SIGINT,sigint_handler)
460 460 except SystemError:
461 461 # This happens under Windows, which seems to have all sorts
462 462 # of problems with signal handling. Oh well...
463 463 pass
464 464
465 465 # Flush queue of pending code by calling the run methood of the parent
466 466 # class with all items which may be in the queue.
467 467 code_to_run = None
468 468 while 1:
469 469 try:
470 470 code_to_run, completed_ev, received_ev = self.code_queue.get_nowait()
471 471 except Queue.Empty:
472 472 break
473 473 received_ev.set()
474 474
475 475 # Exceptions need to be raised differently depending on which
476 476 # thread is active. This convoluted try/except is only there to
477 477 # protect against asynchronous exceptions, to ensure that a KBINT
478 478 # at the wrong time doesn't deadlock everything. The global
479 479 # CODE_TO_RUN is set to true/false as close as possible to the
480 480 # runcode() call, so that the KBINT handler is correctly informed.
481 481 try:
482 482 try:
483 483 CODE_RUN = True
484 484 InteractiveShell.runcode(self,code_to_run)
485 485 except KeyboardInterrupt:
486 486 print "Keyboard interrupted in mainloop"
487 487 while not self.code_queue.empty():
488 488 code, ev1,ev2 = self.code_queue.get_nowait()
489 489 ev1.set()
490 490 ev2.set()
491 491 break
492 492 finally:
493 493 CODE_RUN = False
494 494 # allow runsource() return from wait
495 495 completed_ev.set()
496 496
497 497
498 498 # This MUST return true for gtk threading to work
499 499 return True
500 500
501 501 def kill(self):
502 502 """Kill the thread, returning when it has been shut down."""
503 503 self._kill = threading.Event()
504 504 self._kill.wait()
505 505
506 506 class MatplotlibShellBase:
507 507 """Mixin class to provide the necessary modifications to regular IPython
508 508 shell classes for matplotlib support.
509 509
510 510 Given Python's MRO, this should be used as the FIRST class in the
511 511 inheritance hierarchy, so that it overrides the relevant methods."""
512 512
513 513 def _matplotlib_config(self,name,user_ns,user_global_ns=None):
514 514 """Return items needed to setup the user's shell with matplotlib"""
515 515
516 516 # Initialize matplotlib to interactive mode always
517 517 import matplotlib
518 518 from matplotlib import backends
519 519 matplotlib.interactive(True)
520 520
521 521 def use(arg):
522 522 """IPython wrapper for matplotlib's backend switcher.
523 523
524 524 In interactive use, we can not allow switching to a different
525 525 interactive backend, since thread conflicts will most likely crash
526 526 the python interpreter. This routine does a safety check first,
527 527 and refuses to perform a dangerous switch. It still allows
528 528 switching to non-interactive backends."""
529 529
530 530 if arg in backends.interactive_bk and arg != self.mpl_backend:
531 531 m=('invalid matplotlib backend switch.\n'
532 532 'This script attempted to switch to the interactive '
533 533 'backend: `%s`\n'
534 534 'Your current choice of interactive backend is: `%s`\n\n'
535 535 'Switching interactive matplotlib backends at runtime\n'
536 536 'would crash the python interpreter, '
537 537 'and IPython has blocked it.\n\n'
538 538 'You need to either change your choice of matplotlib backend\n'
539 539 'by editing your .matplotlibrc file, or run this script as a \n'
540 540 'standalone file from the command line, not using IPython.\n' %
541 541 (arg,self.mpl_backend) )
542 542 raise RuntimeError, m
543 543 else:
544 544 self.mpl_use(arg)
545 545 self.mpl_use._called = True
546 546
547 547 self.matplotlib = matplotlib
548 548 self.mpl_backend = matplotlib.rcParams['backend']
549 549
550 550 # we also need to block switching of interactive backends by use()
551 551 self.mpl_use = matplotlib.use
552 552 self.mpl_use._called = False
553 553 # overwrite the original matplotlib.use with our wrapper
554 554 matplotlib.use = use
555 555
556 556 # This must be imported last in the matplotlib series, after
557 557 # backend/interactivity choices have been made
558 558 import matplotlib.pylab as pylab
559 559 self.pylab = pylab
560 560
561 561 self.pylab.show._needmain = False
562 562 # We need to detect at runtime whether show() is called by the user.
563 563 # For this, we wrap it into a decorator which adds a 'called' flag.
564 564 self.pylab.draw_if_interactive = flag_calls(self.pylab.draw_if_interactive)
565 565
566 566 # Build a user namespace initialized with matplotlib/matlab features.
567 567 user_ns, user_global_ns = IPython.ipapi.make_user_namespaces(user_ns,
568 568 user_global_ns)
569 569
570 570 # Import numpy as np/pyplot as plt are conventions we're trying to
571 571 # somewhat standardize on. Making them available to users by default
572 572 # will greatly help this.
573 573 exec ("import numpy\n"
574 574 "import numpy as np\n"
575 575 "import matplotlib\n"
576 576 "import matplotlib.pylab as pylab\n"
577 577 "try:\n"
578 578 " import matplotlib.pyplot as plt\n"
579 579 "except ImportError:\n"
580 580 " pass\n"
581 581 ) in user_ns
582 582
583 583 # Build matplotlib info banner
584 584 b="""
585 585 Welcome to pylab, a matplotlib-based Python environment.
586 586 For more information, type 'help(pylab)'.
587 587 """
588 588 return user_ns,user_global_ns,b
589 589
590 590 def mplot_exec(self,fname,*where,**kw):
591 591 """Execute a matplotlib script.
592 592
593 593 This is a call to execfile(), but wrapped in safeties to properly
594 594 handle interactive rendering and backend switching."""
595 595
596 596 #print '*** Matplotlib runner ***' # dbg
597 597 # turn off rendering until end of script
598 598 isInteractive = self.matplotlib.rcParams['interactive']
599 599 self.matplotlib.interactive(False)
600 600 self.safe_execfile(fname,*where,**kw)
601 601 self.matplotlib.interactive(isInteractive)
602 602 # make rendering call now, if the user tried to do it
603 603 if self.pylab.draw_if_interactive.called:
604 604 self.pylab.draw()
605 605 self.pylab.draw_if_interactive.called = False
606 606
607 607 # if a backend switch was performed, reverse it now
608 608 if self.mpl_use._called:
609 609 self.matplotlib.rcParams['backend'] = self.mpl_backend
610 610
611 611 def magic_run(self,parameter_s=''):
612 612 Magic.magic_run(self,parameter_s,runner=self.mplot_exec)
613 613
614 614 # Fix the docstring so users see the original as well
615 615 magic_run.__doc__ = "%s\n%s" % (Magic.magic_run.__doc__,
616 616 "\n *** Modified %run for Matplotlib,"
617 617 " with proper interactive handling ***")
618 618
619 619 # Now we provide 2 versions of a matplotlib-aware IPython base shells, single
620 620 # and multithreaded. Note that these are meant for internal use, the IPShell*
621 621 # classes below are the ones meant for public consumption.
622 622
623 623 class MatplotlibShell(MatplotlibShellBase,InteractiveShell):
624 624 """Single-threaded shell with matplotlib support."""
625 625
626 626 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
627 627 user_ns=None,user_global_ns=None,**kw):
628 628 user_ns,user_global_ns,b2 = self._matplotlib_config(name,user_ns,user_global_ns)
629 629 InteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
630 630 banner2=b2,**kw)
631 631
632 632 class MatplotlibMTShell(MatplotlibShellBase,MTInteractiveShell):
633 633 """Multi-threaded shell with matplotlib support."""
634 634
635 635 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
636 636 user_ns=None,user_global_ns=None, **kw):
637 user_ns,b2 = self._matplotlib_config(name,user_ns)
637 user_ns,user_global_ns,b2 = self._matplotlib_config(name,user_ns,user_global_ns)
638 638 MTInteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
639 639 banner2=b2,**kw)
640 640
641 641 #-----------------------------------------------------------------------------
642 642 # Utility functions for the different GUI enabled IPShell* classes.
643 643
644 644 def get_tk():
645 645 """Tries to import Tkinter and returns a withdrawn Tkinter root
646 646 window. If Tkinter is already imported or not available, this
647 647 returns None. This function calls `hijack_tk` underneath.
648 648 """
649 649 if not USE_TK or sys.modules.has_key('Tkinter'):
650 650 return None
651 651 else:
652 652 try:
653 653 import Tkinter
654 654 except ImportError:
655 655 return None
656 656 else:
657 657 hijack_tk()
658 658 r = Tkinter.Tk()
659 659 r.withdraw()
660 660 return r
661 661
662 662 def hijack_tk():
663 663 """Modifies Tkinter's mainloop with a dummy so when a module calls
664 664 mainloop, it does not block.
665 665
666 666 """
667 667 def misc_mainloop(self, n=0):
668 668 pass
669 669 def tkinter_mainloop(n=0):
670 670 pass
671 671
672 672 import Tkinter
673 673 Tkinter.Misc.mainloop = misc_mainloop
674 674 Tkinter.mainloop = tkinter_mainloop
675 675
676 676 def update_tk(tk):
677 677 """Updates the Tkinter event loop. This is typically called from
678 678 the respective WX or GTK mainloops.
679 679 """
680 680 if tk:
681 681 tk.update()
682 682
683 683 def hijack_wx():
684 684 """Modifies wxPython's MainLoop with a dummy so user code does not
685 685 block IPython. The hijacked mainloop function is returned.
686 686 """
687 687 def dummy_mainloop(*args, **kw):
688 688 pass
689 689
690 690 try:
691 691 import wx
692 692 except ImportError:
693 693 # For very old versions of WX
694 694 import wxPython as wx
695 695
696 696 ver = wx.__version__
697 697 orig_mainloop = None
698 698 if ver[:3] >= '2.5':
699 699 import wx
700 700 if hasattr(wx, '_core_'): core = getattr(wx, '_core_')
701 701 elif hasattr(wx, '_core'): core = getattr(wx, '_core')
702 702 else: raise AttributeError('Could not find wx core module')
703 703 orig_mainloop = core.PyApp_MainLoop
704 704 core.PyApp_MainLoop = dummy_mainloop
705 705 elif ver[:3] == '2.4':
706 706 orig_mainloop = wx.wxc.wxPyApp_MainLoop
707 707 wx.wxc.wxPyApp_MainLoop = dummy_mainloop
708 708 else:
709 709 warn("Unable to find either wxPython version 2.4 or >= 2.5.")
710 710 return orig_mainloop
711 711
712 712 def hijack_gtk():
713 713 """Modifies pyGTK's mainloop with a dummy so user code does not
714 714 block IPython. This function returns the original `gtk.mainloop`
715 715 function that has been hijacked.
716 716 """
717 717 def dummy_mainloop(*args, **kw):
718 718 pass
719 719 import gtk
720 720 if gtk.pygtk_version >= (2,4,0): orig_mainloop = gtk.main
721 721 else: orig_mainloop = gtk.mainloop
722 722 gtk.mainloop = dummy_mainloop
723 723 gtk.main = dummy_mainloop
724 724 return orig_mainloop
725 725
726 726 def hijack_qt():
727 727 """Modifies PyQt's mainloop with a dummy so user code does not
728 728 block IPython. This function returns the original
729 729 `qt.qApp.exec_loop` function that has been hijacked.
730 730 """
731 731 def dummy_mainloop(*args, **kw):
732 732 pass
733 733 import qt
734 734 orig_mainloop = qt.qApp.exec_loop
735 735 qt.qApp.exec_loop = dummy_mainloop
736 736 qt.QApplication.exec_loop = dummy_mainloop
737 737 return orig_mainloop
738 738
739 739 def hijack_qt4():
740 740 """Modifies PyQt4's mainloop with a dummy so user code does not
741 741 block IPython. This function returns the original
742 742 `QtGui.qApp.exec_` function that has been hijacked.
743 743 """
744 744 def dummy_mainloop(*args, **kw):
745 745 pass
746 746 from PyQt4 import QtGui, QtCore
747 747 orig_mainloop = QtGui.qApp.exec_
748 748 QtGui.qApp.exec_ = dummy_mainloop
749 749 QtGui.QApplication.exec_ = dummy_mainloop
750 750 QtCore.QCoreApplication.exec_ = dummy_mainloop
751 751 return orig_mainloop
752 752
753 753 #-----------------------------------------------------------------------------
754 754 # The IPShell* classes below are the ones meant to be run by external code as
755 755 # IPython instances. Note that unless a specific threading strategy is
756 756 # desired, the factory function start() below should be used instead (it
757 757 # selects the proper threaded class).
758 758
759 759 class IPThread(threading.Thread):
760 760 def run(self):
761 761 self.IP.mainloop(self._banner)
762 762 self.IP.kill()
763 763
764 764 class IPShellGTK(IPThread):
765 765 """Run a gtk mainloop() in a separate thread.
766 766
767 767 Python commands can be passed to the thread where they will be executed.
768 768 This is implemented by periodically checking for passed code using a
769 769 GTK timeout callback."""
770 770
771 771 TIMEOUT = 100 # Millisecond interval between timeouts.
772 772
773 773 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
774 774 debug=1,shell_class=MTInteractiveShell):
775 775
776 776 import gtk
777 777
778 778 self.gtk = gtk
779 779 self.gtk_mainloop = hijack_gtk()
780 780
781 781 # Allows us to use both Tk and GTK.
782 782 self.tk = get_tk()
783 783
784 784 if gtk.pygtk_version >= (2,4,0): mainquit = self.gtk.main_quit
785 785 else: mainquit = self.gtk.mainquit
786 786
787 787 self.IP = make_IPython(argv,user_ns=user_ns,
788 788 user_global_ns=user_global_ns,
789 789 debug=debug,
790 790 shell_class=shell_class,
791 791 on_kill=[mainquit])
792 792
793 793 # HACK: slot for banner in self; it will be passed to the mainloop
794 794 # method only and .run() needs it. The actual value will be set by
795 795 # .mainloop().
796 796 self._banner = None
797 797
798 798 threading.Thread.__init__(self)
799 799
800 800 def mainloop(self,sys_exit=0,banner=None):
801 801
802 802 self._banner = banner
803 803
804 804 if self.gtk.pygtk_version >= (2,4,0):
805 805 import gobject
806 806 gobject.idle_add(self.on_timer)
807 807 else:
808 808 self.gtk.idle_add(self.on_timer)
809 809
810 810 if sys.platform != 'win32':
811 811 try:
812 812 if self.gtk.gtk_version[0] >= 2:
813 813 self.gtk.gdk.threads_init()
814 814 except AttributeError:
815 815 pass
816 816 except RuntimeError:
817 817 error('Your pyGTK likely has not been compiled with '
818 818 'threading support.\n'
819 819 'The exception printout is below.\n'
820 820 'You can either rebuild pyGTK with threads, or '
821 821 'try using \n'
822 822 'matplotlib with a different backend (like Tk or WX).\n'
823 823 'Note that matplotlib will most likely not work in its '
824 824 'current state!')
825 825 self.IP.InteractiveTB()
826 826
827 827 self.start()
828 828 self.gtk.gdk.threads_enter()
829 829 self.gtk_mainloop()
830 830 self.gtk.gdk.threads_leave()
831 831 self.join()
832 832
833 833 def on_timer(self):
834 834 """Called when GTK is idle.
835 835
836 836 Must return True always, otherwise GTK stops calling it"""
837 837
838 838 update_tk(self.tk)
839 839 self.IP.runcode()
840 840 time.sleep(0.01)
841 841 return True
842 842
843 843
844 844 class IPShellWX(IPThread):
845 845 """Run a wx mainloop() in a separate thread.
846 846
847 847 Python commands can be passed to the thread where they will be executed.
848 848 This is implemented by periodically checking for passed code using a
849 849 GTK timeout callback."""
850 850
851 851 TIMEOUT = 100 # Millisecond interval between timeouts.
852 852
853 853 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
854 854 debug=1,shell_class=MTInteractiveShell):
855 855
856 856 self.IP = make_IPython(argv,user_ns=user_ns,
857 857 user_global_ns=user_global_ns,
858 858 debug=debug,
859 859 shell_class=shell_class,
860 860 on_kill=[self.wxexit])
861 861
862 862 wantedwxversion=self.IP.rc.wxversion
863 863 if wantedwxversion!="0":
864 864 try:
865 865 import wxversion
866 866 except ImportError:
867 867 error('The wxversion module is needed for WX version selection')
868 868 else:
869 869 try:
870 870 wxversion.select(wantedwxversion)
871 871 except:
872 872 self.IP.InteractiveTB()
873 873 error('Requested wxPython version %s could not be loaded' %
874 874 wantedwxversion)
875 875
876 876 import wx
877 877
878 878 threading.Thread.__init__(self)
879 879 self.wx = wx
880 880 self.wx_mainloop = hijack_wx()
881 881
882 882 # Allows us to use both Tk and GTK.
883 883 self.tk = get_tk()
884 884
885 885 # HACK: slot for banner in self; it will be passed to the mainloop
886 886 # method only and .run() needs it. The actual value will be set by
887 887 # .mainloop().
888 888 self._banner = None
889 889
890 890 self.app = None
891 891
892 892 def wxexit(self, *args):
893 893 if self.app is not None:
894 894 self.app.agent.timer.Stop()
895 895 self.app.ExitMainLoop()
896 896
897 897 def mainloop(self,sys_exit=0,banner=None):
898 898
899 899 self._banner = banner
900 900
901 901 self.start()
902 902
903 903 class TimerAgent(self.wx.MiniFrame):
904 904 wx = self.wx
905 905 IP = self.IP
906 906 tk = self.tk
907 907 def __init__(self, parent, interval):
908 908 style = self.wx.DEFAULT_FRAME_STYLE | self.wx.TINY_CAPTION_HORIZ
909 909 self.wx.MiniFrame.__init__(self, parent, -1, ' ', pos=(200, 200),
910 910 size=(100, 100),style=style)
911 911 self.Show(False)
912 912 self.interval = interval
913 913 self.timerId = self.wx.NewId()
914 914
915 915 def StartWork(self):
916 916 self.timer = self.wx.Timer(self, self.timerId)
917 917 self.wx.EVT_TIMER(self, self.timerId, self.OnTimer)
918 918 self.timer.Start(self.interval)
919 919
920 920 def OnTimer(self, event):
921 921 update_tk(self.tk)
922 922 self.IP.runcode()
923 923
924 924 class App(self.wx.App):
925 925 wx = self.wx
926 926 TIMEOUT = self.TIMEOUT
927 927 def OnInit(self):
928 928 'Create the main window and insert the custom frame'
929 929 self.agent = TimerAgent(None, self.TIMEOUT)
930 930 self.agent.Show(False)
931 931 self.agent.StartWork()
932 932 return True
933 933
934 934 self.app = App(redirect=False)
935 935 self.wx_mainloop(self.app)
936 936 self.join()
937 937
938 938
939 939 class IPShellQt(IPThread):
940 940 """Run a Qt event loop in a separate thread.
941 941
942 942 Python commands can be passed to the thread where they will be executed.
943 943 This is implemented by periodically checking for passed code using a
944 944 Qt timer / slot."""
945 945
946 946 TIMEOUT = 100 # Millisecond interval between timeouts.
947 947
948 948 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
949 949 debug=0, shell_class=MTInteractiveShell):
950 950
951 951 import qt
952 952
953 953 self.exec_loop = hijack_qt()
954 954
955 955 # Allows us to use both Tk and QT.
956 956 self.tk = get_tk()
957 957
958 958 self.IP = make_IPython(argv,
959 959 user_ns=user_ns,
960 960 user_global_ns=user_global_ns,
961 961 debug=debug,
962 962 shell_class=shell_class,
963 963 on_kill=[qt.qApp.exit])
964 964
965 965 # HACK: slot for banner in self; it will be passed to the mainloop
966 966 # method only and .run() needs it. The actual value will be set by
967 967 # .mainloop().
968 968 self._banner = None
969 969
970 970 threading.Thread.__init__(self)
971 971
972 972 def mainloop(self, sys_exit=0, banner=None):
973 973
974 974 import qt
975 975
976 976 self._banner = banner
977 977
978 978 if qt.QApplication.startingUp():
979 979 a = qt.QApplication(sys.argv)
980 980
981 981 self.timer = qt.QTimer()
982 982 qt.QObject.connect(self.timer,
983 983 qt.SIGNAL('timeout()'),
984 984 self.on_timer)
985 985
986 986 self.start()
987 987 self.timer.start(self.TIMEOUT, True)
988 988 while True:
989 989 if self.IP._kill: break
990 990 self.exec_loop()
991 991 self.join()
992 992
993 993 def on_timer(self):
994 994 update_tk(self.tk)
995 995 result = self.IP.runcode()
996 996 self.timer.start(self.TIMEOUT, True)
997 997 return result
998 998
999 999
1000 1000 class IPShellQt4(IPThread):
1001 1001 """Run a Qt event loop in a separate thread.
1002 1002
1003 1003 Python commands can be passed to the thread where they will be executed.
1004 1004 This is implemented by periodically checking for passed code using a
1005 1005 Qt timer / slot."""
1006 1006
1007 1007 TIMEOUT = 100 # Millisecond interval between timeouts.
1008 1008
1009 1009 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
1010 1010 debug=0, shell_class=MTInteractiveShell):
1011 1011
1012 1012 from PyQt4 import QtCore, QtGui
1013 1013
1014 1014 try:
1015 1015 # present in PyQt4-4.2.1 or later
1016 1016 QtCore.pyqtRemoveInputHook()
1017 1017 except AttributeError:
1018 1018 pass
1019 1019
1020 1020 if QtCore.PYQT_VERSION_STR == '4.3':
1021 1021 warn('''PyQt4 version 4.3 detected.
1022 1022 If you experience repeated threading warnings, please update PyQt4.
1023 1023 ''')
1024 1024
1025 1025 self.exec_ = hijack_qt4()
1026 1026
1027 1027 # Allows us to use both Tk and QT.
1028 1028 self.tk = get_tk()
1029 1029
1030 1030 self.IP = make_IPython(argv,
1031 1031 user_ns=user_ns,
1032 1032 user_global_ns=user_global_ns,
1033 1033 debug=debug,
1034 1034 shell_class=shell_class,
1035 1035 on_kill=[QtGui.qApp.exit])
1036 1036
1037 1037 # HACK: slot for banner in self; it will be passed to the mainloop
1038 1038 # method only and .run() needs it. The actual value will be set by
1039 1039 # .mainloop().
1040 1040 self._banner = None
1041 1041
1042 1042 threading.Thread.__init__(self)
1043 1043
1044 1044 def mainloop(self, sys_exit=0, banner=None):
1045 1045
1046 1046 from PyQt4 import QtCore, QtGui
1047 1047
1048 1048 self._banner = banner
1049 1049
1050 1050 if QtGui.QApplication.startingUp():
1051 1051 a = QtGui.QApplication(sys.argv)
1052 1052
1053 1053 self.timer = QtCore.QTimer()
1054 1054 QtCore.QObject.connect(self.timer,
1055 1055 QtCore.SIGNAL('timeout()'),
1056 1056 self.on_timer)
1057 1057
1058 1058 self.start()
1059 1059 self.timer.start(self.TIMEOUT)
1060 1060 while True:
1061 1061 if self.IP._kill: break
1062 1062 self.exec_()
1063 1063 self.join()
1064 1064
1065 1065 def on_timer(self):
1066 1066 update_tk(self.tk)
1067 1067 result = self.IP.runcode()
1068 1068 self.timer.start(self.TIMEOUT)
1069 1069 return result
1070 1070
1071 1071
1072 1072 # A set of matplotlib public IPython shell classes, for single-threaded (Tk*
1073 1073 # and FLTK*) and multithreaded (GTK*, WX* and Qt*) backends to use.
1074 1074 def _load_pylab(user_ns):
1075 1075 """Allow users to disable pulling all of pylab into the top-level
1076 1076 namespace.
1077 1077
1078 1078 This little utility must be called AFTER the actual ipython instance is
1079 1079 running, since only then will the options file have been fully parsed."""
1080 1080
1081 1081 ip = IPython.ipapi.get()
1082 1082 if ip.options.pylab_import_all:
1083 1083 ip.ex("from matplotlib.pylab import *")
1084 1084 ip.IP.user_config_ns.update(ip.user_ns)
1085 1085
1086 1086
1087 1087 class IPShellMatplotlib(IPShell):
1088 1088 """Subclass IPShell with MatplotlibShell as the internal shell.
1089 1089
1090 1090 Single-threaded class, meant for the Tk* and FLTK* backends.
1091 1091
1092 1092 Having this on a separate class simplifies the external driver code."""
1093 1093
1094 1094 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1095 1095 IPShell.__init__(self,argv,user_ns,user_global_ns,debug,
1096 1096 shell_class=MatplotlibShell)
1097 1097 _load_pylab(self.IP.user_ns)
1098 1098
1099 1099 class IPShellMatplotlibGTK(IPShellGTK):
1100 1100 """Subclass IPShellGTK with MatplotlibMTShell as the internal shell.
1101 1101
1102 1102 Multi-threaded class, meant for the GTK* backends."""
1103 1103
1104 1104 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1105 1105 IPShellGTK.__init__(self,argv,user_ns,user_global_ns,debug,
1106 1106 shell_class=MatplotlibMTShell)
1107 1107 _load_pylab(self.IP.user_ns)
1108 1108
1109 1109 class IPShellMatplotlibWX(IPShellWX):
1110 1110 """Subclass IPShellWX with MatplotlibMTShell as the internal shell.
1111 1111
1112 1112 Multi-threaded class, meant for the WX* backends."""
1113 1113
1114 1114 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1115 1115 IPShellWX.__init__(self,argv,user_ns,user_global_ns,debug,
1116 1116 shell_class=MatplotlibMTShell)
1117 1117 _load_pylab(self.IP.user_ns)
1118 1118
1119 1119 class IPShellMatplotlibQt(IPShellQt):
1120 1120 """Subclass IPShellQt with MatplotlibMTShell as the internal shell.
1121 1121
1122 1122 Multi-threaded class, meant for the Qt* backends."""
1123 1123
1124 1124 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1125 1125 IPShellQt.__init__(self,argv,user_ns,user_global_ns,debug,
1126 1126 shell_class=MatplotlibMTShell)
1127 1127 _load_pylab(self.IP.user_ns)
1128 1128
1129 1129 class IPShellMatplotlibQt4(IPShellQt4):
1130 1130 """Subclass IPShellQt4 with MatplotlibMTShell as the internal shell.
1131 1131
1132 1132 Multi-threaded class, meant for the Qt4* backends."""
1133 1133
1134 1134 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1135 1135 IPShellQt4.__init__(self,argv,user_ns,user_global_ns,debug,
1136 1136 shell_class=MatplotlibMTShell)
1137 1137 _load_pylab(self.IP.user_ns)
1138 1138
1139 1139 #-----------------------------------------------------------------------------
1140 1140 # Factory functions to actually start the proper thread-aware shell
1141 1141
1142 1142 def _select_shell(argv):
1143 1143 """Select a shell from the given argv vector.
1144 1144
1145 1145 This function implements the threading selection policy, allowing runtime
1146 1146 control of the threading mode, both for general users and for matplotlib.
1147 1147
1148 1148 Return:
1149 1149 Shell class to be instantiated for runtime operation.
1150 1150 """
1151 1151
1152 1152 global USE_TK
1153 1153
1154 1154 mpl_shell = {'gthread' : IPShellMatplotlibGTK,
1155 1155 'wthread' : IPShellMatplotlibWX,
1156 1156 'qthread' : IPShellMatplotlibQt,
1157 1157 'q4thread' : IPShellMatplotlibQt4,
1158 1158 'tkthread' : IPShellMatplotlib, # Tk is built-in
1159 1159 }
1160 1160
1161 1161 th_shell = {'gthread' : IPShellGTK,
1162 1162 'wthread' : IPShellWX,
1163 1163 'qthread' : IPShellQt,
1164 1164 'q4thread' : IPShellQt4,
1165 1165 'tkthread' : IPShell, # Tk is built-in
1166 1166 }
1167 1167
1168 1168 backends = {'gthread' : 'GTKAgg',
1169 1169 'wthread' : 'WXAgg',
1170 1170 'qthread' : 'QtAgg',
1171 1171 'q4thread' :'Qt4Agg',
1172 1172 'tkthread' :'TkAgg',
1173 1173 }
1174 1174
1175 1175 all_opts = set(['tk','pylab','gthread','qthread','q4thread','wthread',
1176 1176 'tkthread'])
1177 1177 user_opts = set([s.replace('-','') for s in argv[:3]])
1178 1178 special_opts = user_opts & all_opts
1179 1179
1180 1180 if 'tk' in special_opts:
1181 1181 USE_TK = True
1182 1182 special_opts.remove('tk')
1183 1183
1184 1184 if 'pylab' in special_opts:
1185 1185
1186 1186 try:
1187 1187 import matplotlib
1188 1188 except ImportError:
1189 1189 error('matplotlib could NOT be imported! Starting normal IPython.')
1190 1190 return IPShell
1191 1191
1192 1192 special_opts.remove('pylab')
1193 1193 # If there's any option left, it means the user wants to force the
1194 1194 # threading backend, else it's auto-selected from the rc file
1195 1195 if special_opts:
1196 1196 th_mode = special_opts.pop()
1197 1197 matplotlib.rcParams['backend'] = backends[th_mode]
1198 1198 else:
1199 1199 backend = matplotlib.rcParams['backend']
1200 1200 if backend.startswith('GTK'):
1201 1201 th_mode = 'gthread'
1202 1202 elif backend.startswith('WX'):
1203 1203 th_mode = 'wthread'
1204 1204 elif backend.startswith('Qt4'):
1205 1205 th_mode = 'q4thread'
1206 1206 elif backend.startswith('Qt'):
1207 1207 th_mode = 'qthread'
1208 1208 else:
1209 1209 # Any other backend, use plain Tk
1210 1210 th_mode = 'tkthread'
1211 1211
1212 1212 return mpl_shell[th_mode]
1213 1213 else:
1214 1214 # No pylab requested, just plain threads
1215 1215 try:
1216 1216 th_mode = special_opts.pop()
1217 1217 except KeyError:
1218 1218 th_mode = 'tkthread'
1219 1219 return th_shell[th_mode]
1220 1220
1221 1221
1222 1222 # This is the one which should be called by external code.
1223 1223 def start(user_ns = None):
1224 1224 """Return a running shell instance, dealing with threading options.
1225 1225
1226 1226 This is a factory function which will instantiate the proper IPython shell
1227 1227 based on the user's threading choice. Such a selector is needed because
1228 1228 different GUI toolkits require different thread handling details."""
1229 1229
1230 1230 shell = _select_shell(sys.argv)
1231 1231 return shell(user_ns = user_ns)
1232 1232
1233 1233 # Some aliases for backwards compatibility
1234 1234 IPythonShell = IPShell
1235 1235 IPythonShellEmbed = IPShellEmbed
1236 1236 #************************ End of file <Shell.py> ***************************
@@ -1,212 +1,220 b''
1 1 """
2 2 Frontend class that uses IPython0 to prefilter the inputs.
3 3
4 4 Using the IPython0 mechanism gives us access to the magics.
5 5
6 6 This is a transitory class, used here to do the transition between
7 7 ipython0 and ipython1. This class is meant to be short-lived as more
8 8 functionnality is abstracted out of ipython0 in reusable functions and
9 9 is added on the interpreter. This class can be a used to guide this
10 10 refactoring.
11 11 """
12 12 __docformat__ = "restructuredtext en"
13 13
14 14 #-------------------------------------------------------------------------------
15 15 # Copyright (C) 2008 The IPython Development Team
16 16 #
17 17 # Distributed under the terms of the BSD License. The full license is in
18 18 # the file COPYING, distributed as part of this software.
19 19 #-------------------------------------------------------------------------------
20 20
21 21 #-------------------------------------------------------------------------------
22 22 # Imports
23 23 #-------------------------------------------------------------------------------
24 24 import sys
25 25
26 26 from linefrontendbase import LineFrontEndBase, common_prefix
27 27
28 28 from IPython.ipmaker import make_IPython
29 29 from IPython.ipapi import IPApi
30 30 from IPython.kernel.core.redirector_output_trap import RedirectorOutputTrap
31 31
32 32 from IPython.kernel.core.sync_traceback_trap import SyncTracebackTrap
33 33
34 34 from IPython.genutils import Term
35 35 import pydoc
36 36 import os
37 37
38 38
39 39 def mk_system_call(system_call_function, command):
40 40 """ given a os.system replacement, and a leading string command,
41 41 returns a function that will execute the command with the given
42 42 argument string.
43 43 """
44 44 def my_system_call(args):
45 45 system_call_function("%s %s" % (command, args))
46 46 return my_system_call
47 47
48 48 #-------------------------------------------------------------------------------
49 49 # Frontend class using ipython0 to do the prefiltering.
50 50 #-------------------------------------------------------------------------------
51 51 class PrefilterFrontEnd(LineFrontEndBase):
52 52 """ Class that uses ipython0 to do prefilter the input, do the
53 53 completion and the magics.
54 54
55 55 The core trick is to use an ipython0 instance to prefilter the
56 56 input, and share the namespace between the interpreter instance used
57 57 to execute the statements and the ipython0 used for code
58 58 completion...
59 59 """
60 60
61 def __init__(self, *args, **kwargs):
61 def __init__(self, ipython0=None, *args, **kwargs):
62 """ Parameters:
63 -----------
64
65 ipython0: an optional ipython0 instance to use for command
66 prefiltering and completion.
67 """
62 68 self.save_output_hooks()
63 # Instanciate an IPython0 interpreter to be able to use the
64 # prefiltering.
65 self.ipython0 = make_IPython()
69 if ipython0 is None:
70 # Instanciate an IPython0 interpreter to be able to use the
71 # prefiltering.
72 ipython0 = make_IPython()
73 self.ipython0 = ipython0
66 74 # Set the pager:
67 75 self.ipython0.set_hook('show_in_pager',
68 lambda s, string: self.write("\n"+string))
76 lambda s, string: self.write("\n" + string))
69 77 self.ipython0.write = self.write
70 78 self._ip = _ip = IPApi(self.ipython0)
71 79 # Make sure the raw system call doesn't get called, as we don't
72 80 # have a stdin accessible.
73 81 self._ip.system = self.system_call
74 82 # XXX: Muck around with magics so that they work better
75 83 # in our environment
76 84 self.ipython0.magic_ls = mk_system_call(self.system_call,
77 85 'ls -CF')
78 86 # And now clean up the mess created by ipython0
79 87 self.release_output()
80 88 if not 'banner' in kwargs:
81 89 kwargs['banner'] = self.ipython0.BANNER + """
82 90 This is the wx frontend, by Gael Varoquaux. This is EXPERIMENTAL code."""
83 91
84 92 LineFrontEndBase.__init__(self, *args, **kwargs)
85 93 # XXX: Hack: mix the two namespaces
86 94 self.shell.user_ns = self.ipython0.user_ns
87 95 self.shell.user_global_ns = self.ipython0.user_global_ns
88 96
89 97 self.shell.output_trap = RedirectorOutputTrap(
90 98 out_callback=self.write,
91 99 err_callback=self.write,
92 100 )
93 101 self.shell.traceback_trap = SyncTracebackTrap(
94 102 formatters=self.shell.traceback_trap.formatters,
95 103 )
96 104
97 105 #--------------------------------------------------------------------------
98 106 # FrontEndBase interface
99 107 #--------------------------------------------------------------------------
100 108
101 109 def show_traceback(self):
102 110 """ Use ipython0 to capture the last traceback and display it.
103 111 """
104 112 self.capture_output()
105 113 self.ipython0.showtraceback()
106 114 self.release_output()
107 115
108 116
109 117 def execute(self, python_string, raw_string=None):
110 118 if self.debug:
111 119 print 'Executing Python code:', repr(python_string)
112 120 self.capture_output()
113 121 LineFrontEndBase.execute(self, python_string,
114 122 raw_string=raw_string)
115 123 self.release_output()
116 124
117 125
118 126 def save_output_hooks(self):
119 127 """ Store all the output hooks we can think of, to be able to
120 128 restore them.
121 129
122 130 We need to do this early, as starting the ipython0 instance will
123 131 screw ouput hooks.
124 132 """
125 133 self.__old_cout_write = Term.cout.write
126 134 self.__old_cerr_write = Term.cerr.write
127 135 self.__old_stdout = sys.stdout
128 136 self.__old_stderr= sys.stderr
129 137 self.__old_help_output = pydoc.help.output
130 138 self.__old_display_hook = sys.displayhook
131 139
132 140
133 141 def capture_output(self):
134 142 """ Capture all the output mechanisms we can think of.
135 143 """
136 144 self.save_output_hooks()
137 145 Term.cout.write = self.write
138 146 Term.cerr.write = self.write
139 147 sys.stdout = Term.cout
140 148 sys.stderr = Term.cerr
141 149 pydoc.help.output = self.shell.output_trap.out
142 150
143 151
144 152 def release_output(self):
145 153 """ Release all the different captures we have made.
146 154 """
147 155 Term.cout.write = self.__old_cout_write
148 156 Term.cerr.write = self.__old_cerr_write
149 157 sys.stdout = self.__old_stdout
150 158 sys.stderr = self.__old_stderr
151 159 pydoc.help.output = self.__old_help_output
152 160 sys.displayhook = self.__old_display_hook
153 161
154 162
155 163 def complete(self, line):
156 164 word = line.split('\n')[-1].split(' ')[-1]
157 165 completions = self.ipython0.complete(word)
158 166 # FIXME: The proper sort should be done in the complete method.
159 167 key = lambda x: x.replace('_', '')
160 168 completions.sort(key=key)
161 169 if completions:
162 170 prefix = common_prefix(completions)
163 171 line = line[:-len(word)] + prefix
164 172 return line, completions
165 173
166 174
167 175 #--------------------------------------------------------------------------
168 176 # LineFrontEndBase interface
169 177 #--------------------------------------------------------------------------
170 178
171 179 def prefilter_input(self, input_string):
172 180 """ Using IPython0 to prefilter the commands to turn them
173 181 in executable statements that are valid Python strings.
174 182 """
175 183 input_string = LineFrontEndBase.prefilter_input(self, input_string)
176 184 filtered_lines = []
177 185 # The IPython0 prefilters sometime produce output. We need to
178 186 # capture it.
179 187 self.capture_output()
180 188 self.last_result = dict(number=self.prompt_number)
181 189 try:
182 190 for line in input_string.split('\n'):
183 191 filtered_lines.append(
184 192 self.ipython0.prefilter(line, False).rstrip())
185 193 except:
186 194 # XXX: probably not the right thing to do.
187 195 self.ipython0.showsyntaxerror()
188 196 self.after_execute()
189 197 finally:
190 198 self.release_output()
191 199
192 200 # Clean up the trailing whitespace, to avoid indentation errors
193 201 filtered_string = '\n'.join(filtered_lines)
194 202 return filtered_string
195 203
196 204
197 205 #--------------------------------------------------------------------------
198 206 # PrefilterFrontEnd interface
199 207 #--------------------------------------------------------------------------
200 208
201 209 def system_call(self, command_string):
202 210 """ Allows for frontend to define their own system call, to be
203 211 able capture output and redirect input.
204 212 """
205 213 return os.system(command_string)
206 214
207 215
208 216 def do_exit(self):
209 217 """ Exit the shell, cleanup and save the history.
210 218 """
211 219 self.ipython0.atexit_operations()
212 220
@@ -1,130 +1,132 b''
1 1 # encoding: utf-8
2 2 """
3 3 Test process execution and IO redirection.
4 4 """
5 5
6 6 __docformat__ = "restructuredtext en"
7 7
8 8 #-------------------------------------------------------------------------------
9 9 # Copyright (C) 2008 The IPython Development Team
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is
12 12 # in the file COPYING, distributed as part of this software.
13 13 #-------------------------------------------------------------------------------
14 14
15 15 from IPython.frontend.prefilterfrontend import PrefilterFrontEnd
16 16 from cStringIO import StringIO
17 17 import string
18 18 import sys
19 from IPython.ipapi import get as get_ipython0
19 20
20 21 class TestPrefilterFrontEnd(PrefilterFrontEnd):
21 22
22 23 input_prompt_template = string.Template('')
23 24 output_prompt_template = string.Template('')
24 25
25 26 def __init__(self):
27 ipython0 = get_ipython0()
26 28 self.out = StringIO()
27 PrefilterFrontEnd.__init__(self)
29 PrefilterFrontEnd.__init__(self, ipython0=ipython0)
28 30
29 31 def write(self, string):
30 32 self.out.write(string)
31 33
32 34 def _on_enter(self):
33 35 self.input_buffer += '\n'
34 36 PrefilterFrontEnd._on_enter(self)
35 37
36 38
37 39 def test_execution():
38 40 """ Test execution of a command.
39 41 """
40 42 f = TestPrefilterFrontEnd()
41 43 f.input_buffer = 'print 1\n'
42 44 f._on_enter()
43 45 assert f.out.getvalue() == '1\n'
44 46
45 47
46 48 def test_multiline():
47 49 """ Test execution of a multiline command.
48 50 """
49 51 f = TestPrefilterFrontEnd()
50 52 f.input_buffer = 'if True:'
51 53 f._on_enter()
52 54 f.input_buffer += 'print 1'
53 55 f._on_enter()
54 56 assert f.out.getvalue() == ''
55 57 f._on_enter()
56 58 assert f.out.getvalue() == '1\n'
57 59 f = TestPrefilterFrontEnd()
58 60 f.input_buffer='(1 +'
59 61 f._on_enter()
60 62 f.input_buffer += '0)'
61 63 f._on_enter()
62 64 assert f.out.getvalue() == ''
63 65 f._on_enter()
64 66 assert f.out.getvalue() == '1\n'
65 67
66 68
67 69 def test_capture():
68 70 """ Test the capture of output in different channels.
69 71 """
70 72 # Test on the OS-level stdout, stderr.
71 73 f = TestPrefilterFrontEnd()
72 74 f.input_buffer = \
73 75 'import os; out=os.fdopen(1, "w"); out.write("1") ; out.flush()'
74 76 f._on_enter()
75 77 assert f.out.getvalue() == '1'
76 78 f = TestPrefilterFrontEnd()
77 79 f.input_buffer = \
78 80 'import os; out=os.fdopen(2, "w"); out.write("1") ; out.flush()'
79 81 f._on_enter()
80 82 assert f.out.getvalue() == '1'
81 83
82 84
83 85 def test_magic():
84 86 """ Test the magic expansion and history.
85 87
86 88 This test is fairly fragile and will break when magics change.
87 89 """
88 90 f = TestPrefilterFrontEnd()
89 91 f.input_buffer += '%who\n'
90 92 f._on_enter()
91 93 assert f.out.getvalue() == 'Interactive namespace is empty.\n'
92 94
93 95
94 96 def test_help():
95 97 """ Test object inspection.
96 98 """
97 99 f = TestPrefilterFrontEnd()
98 100 f.input_buffer += "def f():"
99 101 f._on_enter()
100 102 f.input_buffer += "'foobar'"
101 103 f._on_enter()
102 104 f.input_buffer += "pass"
103 105 f._on_enter()
104 106 f._on_enter()
105 107 f.input_buffer += "f?"
106 108 f._on_enter()
107 109 assert f.out.getvalue().split()[-1] == 'foobar'
108 110
109 111
110 112 def test_completion():
111 113 """ Test command-line completion.
112 114 """
113 115 f = TestPrefilterFrontEnd()
114 116 f.input_buffer = 'zzza = 1'
115 117 f._on_enter()
116 118 f.input_buffer = 'zzzb = 2'
117 119 f._on_enter()
118 120 f.input_buffer = 'zz'
119 121 f.complete_current_input()
120 122 assert f.out.getvalue() == '\nzzza zzzb '
121 123 assert f.input_buffer == 'zzz'
122 124
123 125
124 126 if __name__ == '__main__':
125 127 test_magic()
126 128 test_help()
127 129 test_execution()
128 130 test_multiline()
129 131 test_capture()
130 132 test_completion()
@@ -1,647 +1,687 b''
1 1 """IPython customization API
2 2
3 3 Your one-stop module for configuring & extending ipython
4 4
5 5 The API will probably break when ipython 1.0 is released, but so
6 6 will the other configuration method (rc files).
7 7
8 8 All names prefixed by underscores are for internal use, not part
9 9 of the public api.
10 10
11 11 Below is an example that you can just put to a module and import from ipython.
12 12
13 13 A good practice is to install the config script below as e.g.
14 14
15 15 ~/.ipython/my_private_conf.py
16 16
17 17 And do
18 18
19 19 import_mod my_private_conf
20 20
21 21 in ~/.ipython/ipythonrc
22 22
23 23 That way the module is imported at startup and you can have all your
24 24 personal configuration (as opposed to boilerplate ipythonrc-PROFILENAME
25 25 stuff) in there.
26 26
27 27 -----------------------------------------------
28 28 import IPython.ipapi
29 29 ip = IPython.ipapi.get()
30 30
31 31 def ankka_f(self, arg):
32 32 print 'Ankka',self,'says uppercase:',arg.upper()
33 33
34 34 ip.expose_magic('ankka',ankka_f)
35 35
36 36 ip.magic('alias sayhi echo "Testing, hi ok"')
37 37 ip.magic('alias helloworld echo "Hello world"')
38 38 ip.system('pwd')
39 39
40 40 ip.ex('import re')
41 41 ip.ex('''
42 42 def funcci(a,b):
43 43 print a+b
44 44 print funcci(3,4)
45 45 ''')
46 46 ip.ex('funcci(348,9)')
47 47
48 48 def jed_editor(self,filename, linenum=None):
49 49 print 'Calling my own editor, jed ... via hook!'
50 50 import os
51 51 if linenum is None: linenum = 0
52 52 os.system('jed +%d %s' % (linenum, filename))
53 53 print 'exiting jed'
54 54
55 55 ip.set_hook('editor',jed_editor)
56 56
57 57 o = ip.options
58 58 o.autocall = 2 # FULL autocall mode
59 59
60 60 print 'done!'
61 61 """
62 62
63 63 #-----------------------------------------------------------------------------
64 64 # Modules and globals
65 65
66 66 # stdlib imports
67 67 import __builtin__
68 68 import sys
69 69
70 70 # contains the most recently instantiated IPApi
71 71 _RECENT_IP = None
72 72
73 73 #-----------------------------------------------------------------------------
74 74 # Code begins
75 75
76 76 class TryNext(Exception):
77 77 """Try next hook exception.
78 78
79 79 Raise this in your hook function to indicate that the next hook handler
80 80 should be used to handle the operation. If you pass arguments to the
81 81 constructor those arguments will be used by the next hook instead of the
82 82 original ones.
83 83 """
84 84
85 85 def __init__(self, *args, **kwargs):
86 86 self.args = args
87 87 self.kwargs = kwargs
88 88
89 89
90 90 class UsageError(Exception):
91 91 """ Error in magic function arguments, etc.
92 92
93 93 Something that probably won't warrant a full traceback, but should
94 94 nevertheless interrupt a macro / batch file.
95 95 """
96 96
97 97
98 98 class IPyAutocall:
99 99 """ Instances of this class are always autocalled
100 100
101 101 This happens regardless of 'autocall' variable state. Use this to
102 102 develop macro-like mechanisms.
103 103 """
104 104
105 105 def set_ip(self,ip):
106 106 """ Will be used to set _ip point to current ipython instance b/f call
107 107
108 108 Override this method if you don't want this to happen.
109 109
110 110 """
111 111 self._ip = ip
112 112
113 113
114 114 class IPythonNotRunning:
115 115 """Dummy do-nothing class.
116 116
117 117 Instances of this class return a dummy attribute on all accesses, which
118 118 can be called and warns. This makes it easier to write scripts which use
119 119 the ipapi.get() object for informational purposes to operate both with and
120 120 without ipython. Obviously code which uses the ipython object for
121 121 computations will not work, but this allows a wider range of code to
122 122 transparently work whether ipython is being used or not."""
123 123
124 124 def __init__(self,warn=True):
125 125 if warn:
126 126 self.dummy = self._dummy_warn
127 127 else:
128 128 self.dummy = self._dummy_silent
129 129
130 130 def __str__(self):
131 131 return "<IPythonNotRunning>"
132 132
133 133 __repr__ = __str__
134 134
135 135 def __getattr__(self,name):
136 136 return self.dummy
137 137
138 138 def _dummy_warn(self,*args,**kw):
139 139 """Dummy function, which doesn't do anything but warn."""
140 140
141 141 print ("IPython is not running, this is a dummy no-op function")
142 142
143 143 def _dummy_silent(self,*args,**kw):
144 144 """Dummy function, which doesn't do anything and emits no warnings."""
145 145 pass
146 146
147 147
148 148 def get(allow_dummy=False,dummy_warn=True):
149 149 """Get an IPApi object.
150 150
151 151 If allow_dummy is true, returns an instance of IPythonNotRunning
152 152 instead of None if not running under IPython.
153 153
154 154 If dummy_warn is false, the dummy instance will be completely silent.
155 155
156 156 Running this should be the first thing you do when writing extensions that
157 157 can be imported as normal modules. You can then direct all the
158 158 configuration operations against the returned object.
159 159 """
160 160 global _RECENT_IP
161 161 if allow_dummy and not _RECENT_IP:
162 162 _RECENT_IP = IPythonNotRunning(dummy_warn)
163 163 return _RECENT_IP
164 164
165 165
166 166 class IPApi(object):
167 167 """ The actual API class for configuring IPython
168 168
169 169 You should do all of the IPython configuration by getting an IPApi object
170 170 with IPython.ipapi.get() and using the attributes and methods of the
171 171 returned object."""
172 172
173 173 def __init__(self,ip):
174 174
175 175 global _RECENT_IP
176 176
177 177 # All attributes exposed here are considered to be the public API of
178 178 # IPython. As needs dictate, some of these may be wrapped as
179 179 # properties.
180 180
181 181 self.magic = ip.ipmagic
182 182
183 183 self.system = ip.system
184 184
185 185 self.set_hook = ip.set_hook
186 186
187 187 self.set_custom_exc = ip.set_custom_exc
188 188
189 189 self.user_ns = ip.user_ns
190 190 self.user_ns['_ip'] = self
191 191
192 192 self.set_crash_handler = ip.set_crash_handler
193 193
194 194 # Session-specific data store, which can be used to store
195 195 # data that should persist through the ipython session.
196 196 self.meta = ip.meta
197 197
198 198 # The ipython instance provided
199 199 self.IP = ip
200 200
201 201 self.extensions = {}
202 202
203 203 self.dbg = DebugTools(self)
204 204
205 205 _RECENT_IP = self
206 206
207 207 # Use a property for some things which are added to the instance very
208 208 # late. I don't have time right now to disentangle the initialization
209 209 # order issues, so a property lets us delay item extraction while
210 210 # providing a normal attribute API.
211 211 def get_db(self):
212 212 """A handle to persistent dict-like database (a PickleShareDB object)"""
213 213 return self.IP.db
214 214
215 215 db = property(get_db,None,None,get_db.__doc__)
216 216
217 217 def get_options(self):
218 218 """All configurable variables."""
219 219
220 220 # catch typos by disabling new attribute creation. If new attr creation
221 221 # is in fact wanted (e.g. when exposing new options), do
222 222 # allow_new_attr(True) for the received rc struct.
223 223
224 224 self.IP.rc.allow_new_attr(False)
225 225 return self.IP.rc
226 226
227 227 options = property(get_options,None,None,get_options.__doc__)
228 228
229 229 def expose_magic(self,magicname, func):
230 230 """Expose own function as magic function for ipython
231 231
232 232 def foo_impl(self,parameter_s=''):
233 233 'My very own magic!. (Use docstrings, IPython reads them).'
234 234 print 'Magic function. Passed parameter is between < >:'
235 235 print '<%s>' % parameter_s
236 236 print 'The self object is:',self
237 237
238 238 ipapi.expose_magic('foo',foo_impl)
239 239 """
240 240
241 241 import new
242 242 im = new.instancemethod(func,self.IP, self.IP.__class__)
243 243 old = getattr(self.IP, "magic_" + magicname, None)
244 244 if old:
245 245 self.dbg.debug_stack("Magic redefinition '%s', old %s" %
246 246 (magicname,old) )
247 247
248 248 setattr(self.IP, "magic_" + magicname, im)
249 249
250 250 def ex(self,cmd):
251 251 """ Execute a normal python statement in user namespace """
252 252 exec cmd in self.user_ns
253 253
254 254 def ev(self,expr):
255 255 """ Evaluate python expression expr in user namespace
256 256
257 257 Returns the result of evaluation"""
258 258 return eval(expr,self.user_ns)
259 259
260 260 def runlines(self,lines):
261 261 """ Run the specified lines in interpreter, honoring ipython directives.
262 262
263 263 This allows %magic and !shell escape notations.
264 264
265 265 Takes either all lines in one string or list of lines.
266 266 """
267 267
268 268 def cleanup_ipy_script(script):
269 269 """ Make a script safe for _ip.runlines()
270 270
271 271 - Removes empty lines Suffixes all indented blocks that end with
272 272 - unindented lines with empty lines
273 273 """
274 274
275 275 res = []
276 276 lines = script.splitlines()
277 277
278 278 level = 0
279 279 for l in lines:
280 280 lstripped = l.lstrip()
281 281 stripped = l.strip()
282 282 if not stripped:
283 283 continue
284 284 newlevel = len(l) - len(lstripped)
285 285 def is_secondary_block_start(s):
286 286 if not s.endswith(':'):
287 287 return False
288 288 if (s.startswith('elif') or
289 289 s.startswith('else') or
290 290 s.startswith('except') or
291 291 s.startswith('finally')):
292 292 return True
293 293
294 294 if level > 0 and newlevel == 0 and \
295 295 not is_secondary_block_start(stripped):
296 296 # add empty line
297 297 res.append('')
298 298
299 299 res.append(l)
300 300 level = newlevel
301 301 return '\n'.join(res) + '\n'
302 302
303 303 if isinstance(lines,basestring):
304 304 script = lines
305 305 else:
306 306 script = '\n'.join(lines)
307 307 clean=cleanup_ipy_script(script)
308 308 # print "_ip.runlines() script:\n",clean # dbg
309 309 self.IP.runlines(clean)
310 310
311 311 def to_user_ns(self,vars, interactive = True):
312 312 """Inject a group of variables into the IPython user namespace.
313 313
314 314 Inputs:
315 315
316 316 - vars: string with variable names separated by whitespace, or a
317 317 dict with name/value pairs.
318 318
319 319 - interactive: if True (default), the var will be listed with
320 320 %whos et. al.
321 321
322 322 This utility routine is meant to ease interactive debugging work,
323 323 where you want to easily propagate some internal variable in your code
324 324 up to the interactive namespace for further exploration.
325 325
326 326 When you run code via %run, globals in your script become visible at
327 327 the interactive prompt, but this doesn't happen for locals inside your
328 328 own functions and methods. Yet when debugging, it is common to want
329 329 to explore some internal variables further at the interactive propmt.
330 330
331 331 Examples:
332 332
333 333 To use this, you first must obtain a handle on the ipython object as
334 334 indicated above, via:
335 335
336 336 import IPython.ipapi
337 337 ip = IPython.ipapi.get()
338 338
339 339 Once this is done, inside a routine foo() where you want to expose
340 340 variables x and y, you do the following:
341 341
342 342 def foo():
343 343 ...
344 344 x = your_computation()
345 345 y = something_else()
346 346
347 347 # This pushes x and y to the interactive prompt immediately, even
348 348 # if this routine crashes on the next line after:
349 349 ip.to_user_ns('x y')
350 350 ...
351 351
352 352 # To expose *ALL* the local variables from the function, use:
353 353 ip.to_user_ns(locals())
354 354
355 355 ...
356 356 # return
357 357
358 358
359 359 If you need to rename variables, the dict input makes it easy. For
360 360 example, this call exposes variables 'foo' as 'x' and 'bar' as 'y'
361 361 in IPython user namespace:
362 362
363 363 ip.to_user_ns(dict(x=foo,y=bar))
364 364 """
365 365
366 366 # print 'vars given:',vars # dbg
367 367
368 368 # We need a dict of name/value pairs to do namespace updates.
369 369 if isinstance(vars,dict):
370 370 # If a dict was given, no need to change anything.
371 371 vdict = vars
372 372 elif isinstance(vars,basestring):
373 373 # If a string with names was given, get the caller's frame to
374 374 # evaluate the given names in
375 375 cf = sys._getframe(1)
376 376 vdict = {}
377 377 for name in vars.split():
378 378 try:
379 379 vdict[name] = eval(name,cf.f_globals,cf.f_locals)
380 380 except:
381 381 print ('could not get var. %s from %s' %
382 382 (name,cf.f_code.co_name))
383 383 else:
384 384 raise ValueError('vars must be a string or a dict')
385 385
386 386 # Propagate variables to user namespace
387 387 self.user_ns.update(vdict)
388 388
389 389 # And configure interactive visibility
390 390 config_ns = self.IP.user_config_ns
391 391 if interactive:
392 392 for name,val in vdict.iteritems():
393 393 config_ns.pop(name,None)
394 394 else:
395 395 for name,val in vdict.iteritems():
396 396 config_ns[name] = val
397 397
398 398 def expand_alias(self,line):
399 399 """ Expand an alias in the command line
400 400
401 401 Returns the provided command line, possibly with the first word
402 402 (command) translated according to alias expansion rules.
403 403
404 404 [ipython]|16> _ip.expand_aliases("np myfile.txt")
405 405 <16> 'q:/opt/np/notepad++.exe myfile.txt'
406 406 """
407 407
408 408 pre,fn,rest = self.IP.split_user_input(line)
409 409 res = pre + self.IP.expand_aliases(fn,rest)
410 410 return res
411 411
412 412 def itpl(self, s, depth = 1):
413 413 """ Expand Itpl format string s.
414 414
415 415 Only callable from command line (i.e. prefilter results);
416 416 If you use in your scripts, you need to use a bigger depth!
417 417 """
418 418 return self.IP.var_expand(s, depth)
419 419
420 420 def defalias(self, name, cmd):
421 421 """ Define a new alias
422 422
423 423 _ip.defalias('bb','bldmake bldfiles')
424 424
425 425 Creates a new alias named 'bb' in ipython user namespace
426 426 """
427 427
428 428 self.dbg.check_hotname(name)
429 429
430 430 if name in self.IP.alias_table:
431 431 self.dbg.debug_stack("Alias redefinition: '%s' => '%s' (old '%s')"
432 432 % (name, cmd, self.IP.alias_table[name]))
433 433
434 434 if callable(cmd):
435 435 self.IP.alias_table[name] = cmd
436 436 import IPython.shadowns
437 437 setattr(IPython.shadowns, name,cmd)
438 438 return
439 439
440 440 if isinstance(cmd,basestring):
441 441 nargs = cmd.count('%s')
442 442 if nargs>0 and cmd.find('%l')>=0:
443 443 raise Exception('The %s and %l specifiers are mutually '
444 444 'exclusive in alias definitions.')
445 445
446 446 self.IP.alias_table[name] = (nargs,cmd)
447 447 return
448 448
449 449 # just put it in - it's probably (0,'foo')
450 450 self.IP.alias_table[name] = cmd
451 451
452 452 def defmacro(self, *args):
453 453 """ Define a new macro
454 454
455 455 2 forms of calling:
456 456
457 457 mac = _ip.defmacro('print "hello"\nprint "world"')
458 458
459 459 (doesn't put the created macro on user namespace)
460 460
461 461 _ip.defmacro('build', 'bldmake bldfiles\nabld build winscw udeb')
462 462
463 463 (creates a macro named 'build' in user namespace)
464 464 """
465 465
466 466 import IPython.macro
467 467
468 468 if len(args) == 1:
469 469 return IPython.macro.Macro(args[0])
470 470 elif len(args) == 2:
471 471 self.user_ns[args[0]] = IPython.macro.Macro(args[1])
472 472 else:
473 473 return Exception("_ip.defmacro must be called with 1 or 2 arguments")
474 474
475 475 def set_next_input(self, s):
476 476 """ Sets the 'default' input string for the next command line.
477 477
478 478 Requires readline.
479 479
480 480 Example:
481 481
482 482 [D:\ipython]|1> _ip.set_next_input("Hello Word")
483 483 [D:\ipython]|2> Hello Word_ # cursor is here
484 484 """
485 485
486 486 self.IP.rl_next_input = s
487 487
488 488 def load(self, mod):
489 489 """ Load an extension.
490 490
491 491 Some modules should (or must) be 'load()':ed, rather than just imported.
492 492
493 493 Loading will do:
494 494
495 495 - run init_ipython(ip)
496 496 - run ipython_firstrun(ip)
497 497 """
498 498
499 499 if mod in self.extensions:
500 500 # just to make sure we don't init it twice
501 501 # note that if you 'load' a module that has already been
502 502 # imported, init_ipython gets run anyway
503 503
504 504 return self.extensions[mod]
505 505 __import__(mod)
506 506 m = sys.modules[mod]
507 507 if hasattr(m,'init_ipython'):
508 508 m.init_ipython(self)
509 509
510 510 if hasattr(m,'ipython_firstrun'):
511 511 already_loaded = self.db.get('firstrun_done', set())
512 512 if mod not in already_loaded:
513 513 m.ipython_firstrun(self)
514 514 already_loaded.add(mod)
515 515 self.db['firstrun_done'] = already_loaded
516 516
517 517 self.extensions[mod] = m
518 518 return m
519 519
520 520
521 521 class DebugTools:
522 522 """ Used for debugging mishaps in api usage
523 523
524 524 So far, tracing redefinitions is supported.
525 525 """
526 526
527 527 def __init__(self, ip):
528 528 self.ip = ip
529 529 self.debugmode = False
530 530 self.hotnames = set()
531 531
532 532 def hotname(self, name_to_catch):
533 533 self.hotnames.add(name_to_catch)
534 534
535 535 def debug_stack(self, msg = None):
536 536 if not self.debugmode:
537 537 return
538 538
539 539 import traceback
540 540 if msg is not None:
541 541 print '====== %s ========' % msg
542 542 traceback.print_stack()
543 543
544 544 def check_hotname(self,name):
545 545 if name in self.hotnames:
546 546 self.debug_stack( "HotName '%s' caught" % name)
547 547
548 548
549 549 def launch_new_instance(user_ns = None,shellclass = None):
550 550 """ Make and start a new ipython instance.
551 551
552 552 This can be called even without having an already initialized
553 553 ipython session running.
554 554
555 555 This is also used as the egg entry point for the 'ipython' script.
556 556
557 557 """
558 558 ses = make_session(user_ns,shellclass)
559 559 ses.mainloop()
560 560
561 561
562 562 def make_user_ns(user_ns = None):
563 563 """Return a valid user interactive namespace.
564 564
565 565 This builds a dict with the minimal information needed to operate as a
566 566 valid IPython user namespace, which you can pass to the various embedding
567 567 classes in ipython.
568
569 This API is currently deprecated. Use ipapi.make_user_namespaces() instead
570 to make both the local and global namespace objects simultaneously.
571
572 :Parameters:
573 user_ns : dict-like, optional
574 The current user namespace. The items in this namespace should be
575 included in the output. If None, an appropriate blank namespace
576 should be created.
577
578 :Returns:
579 A dictionary-like object to be used as the local namespace of the
580 interpreter.
568 581 """
569 582
570 583 raise NotImplementedError
571 584
572 585
573 586 def make_user_global_ns(ns = None):
574 587 """Return a valid user global namespace.
575 588
576 589 Similar to make_user_ns(), but global namespaces are really only needed in
577 590 embedded applications, where there is a distinction between the user's
578 interactive namespace and the global one where ipython is running."""
591 interactive namespace and the global one where ipython is running.
592
593 This API is currently deprecated. Use ipapi.make_user_namespaces() instead
594 to make both the local and global namespace objects simultaneously.
595
596 :Parameters:
597 ns : dict, optional
598 The current user global namespace. The items in this namespace
599 should be included in the output. If None, an appropriate blank
600 namespace should be created.
601
602 :Returns:
603 A true dict to be used as the global namespace of the interpreter.
604 """
579 605
580 606 raise NotImplementedError
581 607
582 608 # Record the true objects in order to be able to test if the user has overridden
583 609 # these API functions.
584 610 _make_user_ns = make_user_ns
585 611 _make_user_global_ns = make_user_global_ns
586 612
587 613
588 614 def make_user_namespaces(user_ns = None,user_global_ns = None):
589 615 """Return a valid local and global user interactive namespaces.
590 616
591 617 This builds a dict with the minimal information needed to operate as a
592 618 valid IPython user namespace, which you can pass to the various embedding
593 619 classes in ipython. The default implementation returns the same dict for
594 620 both the locals and the globals to allow functions to refer to variables in
595 621 the namespace. Customized implementations can return different dicts. The
596 622 locals dictionary can actually be anything following the basic mapping
597 623 protocol of a dict, but the globals dict must be a true dict, not even
598 624 a subclass. It is recommended that any custom object for the locals
599 625 namespace synchronize with the globals dict somehow.
600 626
601 627 Raises TypeError if the provided globals namespace is not a true dict.
628
629 :Parameters:
630 user_ns : dict-like, optional
631 The current user namespace. The items in this namespace should be
632 included in the output. If None, an appropriate blank namespace
633 should be created.
634 user_global_ns : dict, optional
635 The current user global namespace. The items in this namespace
636 should be included in the output. If None, an appropriate blank
637 namespace should be created.
638
639 :Returns:
640 A tuple pair of dictionary-like object to be used as the local namespace
641 of the interpreter and a dict to be used as the global namespace.
602 642 """
603 643
604 644 if user_ns is None:
605 645 if make_user_ns is not _make_user_ns:
606 646 # Old API overridden.
607 647 # FIXME: Issue DeprecationWarning, or just let the old API live on?
608 648 user_ns = make_user_ns(user_ns)
609 649 else:
610 650 # Set __name__ to __main__ to better match the behavior of the
611 651 # normal interpreter.
612 652 user_ns = {'__name__' :'__main__',
613 653 '__builtins__' : __builtin__,
614 654 }
615 655 else:
616 656 user_ns.setdefault('__name__','__main__')
617 657 user_ns.setdefault('__builtins__',__builtin__)
618 658
619 659 if user_global_ns is None:
620 660 if make_user_global_ns is not _make_user_global_ns:
621 661 # Old API overridden.
622 662 user_global_ns = make_user_global_ns(user_global_ns)
623 663 else:
624 664 user_global_ns = user_ns
625 665 if type(user_global_ns) is not dict:
626 666 raise TypeError("user_global_ns must be a true dict; got %r"
627 667 % type(user_global_ns))
628 668
629 669 return user_ns, user_global_ns
630 670
631 671
632 672 def make_session(user_ns = None, shellclass = None):
633 673 """Makes, but does not launch an IPython session.
634 674
635 675 Later on you can call obj.mainloop() on the returned object.
636 676
637 677 Inputs:
638 678
639 679 - user_ns(None): a dict to be used as the user's namespace with initial
640 680 data.
641 681
642 682 WARNING: This should *not* be run when a session exists already."""
643 683
644 684 import IPython.Shell
645 685 if shellclass is None:
646 686 return IPython.Shell.start(user_ns)
647 687 return shellclass(user_ns = user_ns)
General Comments 0
You need to be logged in to leave comments. Login now