##// END OF EJS Templates
ENH: Docstrings for the user namespace API.
Robert Kern -
Show More
@@ -1,646 +1,686 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 # stdlib imports
64 64 import __builtin__
65 65 import sys
66 66
67 67 try: # Python 2.3 compatibility
68 68 set
69 69 except NameError:
70 70 import sets
71 71 set = sets.Set
72 72
73 73 # our own
74 74 #from IPython.genutils import warn,error
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 class UsageError(Exception):
90 90 """ Error in magic function arguments, etc.
91 91
92 92 Something that probably won't warrant a full traceback, but should
93 93 nevertheless interrupt a macro / batch file.
94 94 """
95 95
96 96 class IPyAutocall:
97 97 """ Instances of this class are always autocalled
98 98
99 99 This happens regardless of 'autocall' variable state. Use this to
100 100 develop macro-like mechanisms.
101 101 """
102 102
103 103 def set_ip(self,ip):
104 104 """ Will be used to set _ip point to current ipython instance b/f call
105 105
106 106 Override this method if you don't want this to happen.
107 107
108 108 """
109 109 self._ip = ip
110 110
111 111
112 112 # contains the most recently instantiated IPApi
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 _recent = None
148 148
149 149
150 150 def get(allow_dummy=False,dummy_warn=True):
151 151 """Get an IPApi object.
152 152
153 153 If allow_dummy is true, returns an instance of IPythonNotRunning
154 154 instead of None if not running under IPython.
155 155
156 156 If dummy_warn is false, the dummy instance will be completely silent.
157 157
158 158 Running this should be the first thing you do when writing extensions that
159 159 can be imported as normal modules. You can then direct all the
160 160 configuration operations against the returned object.
161 161 """
162 162 global _recent
163 163 if allow_dummy and not _recent:
164 164 _recent = IPythonNotRunning(dummy_warn)
165 165 return _recent
166 166
167 167 class IPApi:
168 168 """ The actual API class for configuring IPython
169 169
170 170 You should do all of the IPython configuration by getting an IPApi object
171 171 with IPython.ipapi.get() and using the attributes and methods of the
172 172 returned object."""
173 173
174 174 def __init__(self,ip):
175 175
176 176 # All attributes exposed here are considered to be the public API of
177 177 # IPython. As needs dictate, some of these may be wrapped as
178 178 # properties.
179 179
180 180 self.magic = ip.ipmagic
181 181
182 182 self.system = ip.system
183 183
184 184 self.set_hook = ip.set_hook
185 185
186 186 self.set_custom_exc = ip.set_custom_exc
187 187
188 188 self.user_ns = ip.user_ns
189 189 self.user_ns['_ip'] = self
190 190
191 191 self.set_crash_handler = ip.set_crash_handler
192 192
193 193 # Session-specific data store, which can be used to store
194 194 # data that should persist through the ipython session.
195 195 self.meta = ip.meta
196 196
197 197 # The ipython instance provided
198 198 self.IP = ip
199 199
200 200 self.extensions = {}
201 201
202 202 self.dbg = DebugTools(self)
203 203
204 204 global _recent
205 205 _recent = 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 allow_new_attr(True)
222 222 # 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 < >: <'+parameter_s+'>'
235 235 print 'The self object is:',self
236 236
237 237 ipapi.expose_magic("foo",foo_impl)
238 238 '''
239 239
240 240 import new
241 241 im = new.instancemethod(func,self.IP, self.IP.__class__)
242 242 old = getattr(self.IP, "magic_" + magicname, None)
243 243 if old:
244 244 self.dbg.debug_stack("Magic redefinition '%s', old %s" % (magicname,
245 245 old))
246 246
247 247 setattr(self.IP, "magic_" + magicname, im)
248 248
249 249 def ex(self,cmd):
250 250 """ Execute a normal python statement in user namespace """
251 251 exec cmd in self.user_ns
252 252
253 253 def ev(self,expr):
254 254 """ Evaluate python expression expr in user namespace
255 255
256 256 Returns the result of evaluation"""
257 257 return eval(expr,self.user_ns)
258 258
259 259 def runlines(self,lines):
260 260 """ Run the specified lines in interpreter, honoring ipython directives.
261 261
262 262 This allows %magic and !shell escape notations.
263 263
264 264 Takes either all lines in one string or list of lines.
265 265 """
266 266
267 267 def cleanup_ipy_script(script):
268 268 """ Make a script safe for _ip.runlines()
269 269
270 270 - Removes empty lines
271 271 - Suffixes all indented blocks that end with unindented lines with empty lines
272 272
273 273 """
274 274 res = []
275 275 lines = script.splitlines()
276 276
277 277 level = 0
278 278 for l in lines:
279 279 lstripped = l.lstrip()
280 280 stripped = l.strip()
281 281 if not stripped:
282 282 continue
283 283 newlevel = len(l) - len(lstripped)
284 284 def is_secondary_block_start(s):
285 285 if not s.endswith(':'):
286 286 return False
287 287 if (s.startswith('elif') or
288 288 s.startswith('else') or
289 289 s.startswith('except') or
290 290 s.startswith('finally')):
291 291 return True
292 292
293 293 if level > 0 and newlevel == 0 and not is_secondary_block_start(stripped):
294 294 # add empty line
295 295 res.append('')
296 296
297 297 res.append(l)
298 298 level = newlevel
299 299 return '\n'.join(res) + '\n'
300 300
301 301 if isinstance(lines,basestring):
302 302 script = lines
303 303 else:
304 304 script = '\n'.join(lines)
305 305 clean=cleanup_ipy_script(script)
306 306 # print "_ip.runlines() script:\n",clean #dbg
307 307 self.IP.runlines(clean)
308 308 def to_user_ns(self,vars, interactive = True):
309 309 """Inject a group of variables into the IPython user namespace.
310 310
311 311 Inputs:
312 312
313 313 - vars: string with variable names separated by whitespace, or a
314 314 dict with name/value pairs.
315 315
316 316 - interactive: if True (default), the var will be listed with
317 317 %whos et. al.
318 318
319 319 This utility routine is meant to ease interactive debugging work,
320 320 where you want to easily propagate some internal variable in your code
321 321 up to the interactive namespace for further exploration.
322 322
323 323 When you run code via %run, globals in your script become visible at
324 324 the interactive prompt, but this doesn't happen for locals inside your
325 325 own functions and methods. Yet when debugging, it is common to want
326 326 to explore some internal variables further at the interactive propmt.
327 327
328 328 Examples:
329 329
330 330 To use this, you first must obtain a handle on the ipython object as
331 331 indicated above, via:
332 332
333 333 import IPython.ipapi
334 334 ip = IPython.ipapi.get()
335 335
336 336 Once this is done, inside a routine foo() where you want to expose
337 337 variables x and y, you do the following:
338 338
339 339 def foo():
340 340 ...
341 341 x = your_computation()
342 342 y = something_else()
343 343
344 344 # This pushes x and y to the interactive prompt immediately, even
345 345 # if this routine crashes on the next line after:
346 346 ip.to_user_ns('x y')
347 347 ...
348 348
349 349 # To expose *ALL* the local variables from the function, use:
350 350 ip.to_user_ns(locals())
351 351
352 352 ...
353 353 # return
354 354
355 355
356 356 If you need to rename variables, the dict input makes it easy. For
357 357 example, this call exposes variables 'foo' as 'x' and 'bar' as 'y'
358 358 in IPython user namespace:
359 359
360 360 ip.to_user_ns(dict(x=foo,y=bar))
361 361 """
362 362
363 363 # print 'vars given:',vars # dbg
364 364
365 365 # We need a dict of name/value pairs to do namespace updates.
366 366 if isinstance(vars,dict):
367 367 # If a dict was given, no need to change anything.
368 368 vdict = vars
369 369 elif isinstance(vars,basestring):
370 370 # If a string with names was given, get the caller's frame to
371 371 # evaluate the given names in
372 372 cf = sys._getframe(1)
373 373 vdict = {}
374 374 for name in vars.split():
375 375 try:
376 376 vdict[name] = eval(name,cf.f_globals,cf.f_locals)
377 377 except:
378 378 print ('could not get var. %s from %s' %
379 379 (name,cf.f_code.co_name))
380 380 else:
381 381 raise ValueError('vars must be a string or a dict')
382 382
383 383 # Propagate variables to user namespace
384 384 self.user_ns.update(vdict)
385 385
386 386 # And configure interactive visibility
387 387 config_ns = self.IP.user_config_ns
388 388 if interactive:
389 389 for name,val in vdict.iteritems():
390 390 config_ns.pop(name,None)
391 391 else:
392 392 for name,val in vdict.iteritems():
393 393 config_ns[name] = val
394 394
395 395
396 396 def expand_alias(self,line):
397 397 """ Expand an alias in the command line
398 398
399 399 Returns the provided command line, possibly with the first word
400 400 (command) translated according to alias expansion rules.
401 401
402 402 [ipython]|16> _ip.expand_aliases("np myfile.txt")
403 403 <16> 'q:/opt/np/notepad++.exe myfile.txt'
404 404 """
405 405
406 406 pre,fn,rest = self.IP.split_user_input(line)
407 407 res = pre + self.IP.expand_aliases(fn,rest)
408 408 return res
409 409
410 410 def itpl(self, s, depth = 1):
411 411 """ Expand Itpl format string s.
412 412
413 413 Only callable from command line (i.e. prefilter results);
414 414 If you use in your scripts, you need to use a bigger depth!
415 415 """
416 416 return self.IP.var_expand(s, depth)
417 417
418 418 def defalias(self, name, cmd):
419 419 """ Define a new alias
420 420
421 421 _ip.defalias('bb','bldmake bldfiles')
422 422
423 423 Creates a new alias named 'bb' in ipython user namespace
424 424 """
425 425
426 426 self.dbg.check_hotname(name)
427 427
428 428
429 429 if name in self.IP.alias_table:
430 430 self.dbg.debug_stack("Alias redefinition: '%s' => '%s' (old '%s')" %
431 431 (name, cmd, self.IP.alias_table[name]))
432 432
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 exclusive '
444 444 '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 def launch_new_instance(user_ns = None,shellclass = None):
549 549 """ Make and start a new ipython instance.
550 550
551 551 This can be called even without having an already initialized
552 552 ipython session running.
553 553
554 554 This is also used as the egg entry point for the 'ipython' script.
555 555
556 556 """
557 557 ses = make_session(user_ns,shellclass)
558 558 ses.mainloop()
559 559
560 560
561 561 def make_user_ns(user_ns = None):
562 562 """Return a valid user interactive namespace.
563 563
564 564 This builds a dict with the minimal information needed to operate as a
565 565 valid IPython user namespace, which you can pass to the various embedding
566 566 classes in ipython.
567
568 This API is currently deprecated. Use ipapi.make_user_namespaces() instead
569 to make both the local and global namespace objects simultaneously.
570
571 :Parameters:
572 user_ns : dict-like, optional
573 The current user namespace. The items in this namespace should be
574 included in the output. If None, an appropriate blank namespace
575 should be created.
576
577 :Returns:
578 A dictionary-like object to be used as the local namespace of the
579 interpreter.
567 580 """
568 581
569 582 raise NotImplementedError
570 583
571 584
572 585 def make_user_global_ns(ns = None):
573 586 """Return a valid user global namespace.
574 587
575 588 Similar to make_user_ns(), but global namespaces are really only needed in
576 589 embedded applications, where there is a distinction between the user's
577 interactive namespace and the global one where ipython is running."""
590 interactive namespace and the global one where ipython is running.
591
592 This API is currently deprecated. Use ipapi.make_user_namespaces() instead
593 to make both the local and global namespace objects simultaneously.
594
595 :Parameters:
596 ns : dict, optional
597 The current user global namespace. The items in this namespace
598 should be included in the output. If None, an appropriate blank
599 namespace should be created.
600
601 :Returns:
602 A true dict to be used as the global namespace of the interpreter.
603 """
578 604
579 605 raise NotImplementedError
580 606
581 607 # Record the true objects in order to be able to test if the user has overridden
582 608 # these API functions.
583 609 _make_user_ns = make_user_ns
584 610 _make_user_global_ns = make_user_global_ns
585 611
586 612
587 613 def make_user_namespaces(user_ns = None,user_global_ns = None):
588 614 """Return a valid local and global user interactive namespaces.
589 615
590 616 This builds a dict with the minimal information needed to operate as a
591 617 valid IPython user namespace, which you can pass to the various embedding
592 618 classes in ipython. The default implementation returns the same dict for
593 619 both the locals and the globals to allow functions to refer to variables in
594 620 the namespace. Customized implementations can return different dicts. The
595 621 locals dictionary can actually be anything following the basic mapping
596 622 protocol of a dict, but the globals dict must be a true dict, not even
597 623 a subclass. It is recommended that any custom object for the locals
598 624 namespace synchronize with the globals dict somehow.
599 625
600 626 Raises TypeError if the provided globals namespace is not a true dict.
627
628 :Parameters:
629 user_ns : dict-like, optional
630 The current user namespace. The items in this namespace should be
631 included in the output. If None, an appropriate blank namespace
632 should be created.
633 user_global_ns : dict, optional
634 The current user global namespace. The items in this namespace
635 should be included in the output. If None, an appropriate blank
636 namespace should be created.
637
638 :Returns:
639 A tuple pair of dictionary-like object to be used as the local namespace
640 of the interpreter and a dict to be used as the global namespace.
601 641 """
602 642
603 643 if user_ns is None:
604 644 if make_user_ns is not _make_user_ns:
605 645 # Old API overridden.
606 646 # FIXME: Issue DeprecationWarning, or just let the old API live on?
607 647 user_ns = make_user_ns(user_ns)
608 648 else:
609 649 # Set __name__ to __main__ to better match the behavior of the
610 650 # normal interpreter.
611 651 user_ns = {'__name__' :'__main__',
612 652 '__builtins__' : __builtin__,
613 653 }
614 654 else:
615 655 user_ns.setdefault('__name__','__main__')
616 656 user_ns.setdefault('__builtins__',__builtin__)
617 657
618 658 if user_global_ns is None:
619 659 if make_user_global_ns is not _make_user_global_ns:
620 660 # Old API overridden.
621 661 user_global_ns = make_user_global_ns(user_global_ns)
622 662 else:
623 663 user_global_ns = user_ns
624 664 if type(user_global_ns) is not dict:
625 665 raise TypeError("user_global_ns must be a true dict; got %r"
626 666 % type(user_global_ns))
627 667
628 668 return user_ns, user_global_ns
629 669
630 670
631 671 def make_session(user_ns = None, shellclass = None):
632 672 """Makes, but does not launch an IPython session.
633 673
634 674 Later on you can call obj.mainloop() on the returned object.
635 675
636 676 Inputs:
637 677
638 678 - user_ns(None): a dict to be used as the user's namespace with initial
639 679 data.
640 680
641 681 WARNING: This should *not* be run when a session exists already."""
642 682
643 683 import IPython.Shell
644 684 if shellclass is None:
645 685 return IPython.Shell.start(user_ns)
646 686 return shellclass(user_ns = user_ns)
General Comments 0
You need to be logged in to leave comments. Login now