##// END OF EJS Templates
ipapi: to_user_ns takes "x y", and doesn't support renaming anymore
vivainio -
Show More
@@ -1,325 +1,294 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 sys
65 65
66 66 # our own
67 67 from IPython.genutils import warn,error
68 68
69 69 class TryNext(Exception):
70 70 """Try next hook exception.
71 71
72 72 Raise this in your hook function to indicate that the next hook handler
73 73 should be used to handle the operation. If you pass arguments to the
74 74 constructor those arguments will be used by the next hook instead of the
75 75 original ones.
76 76 """
77 77
78 78 def __init__(self, *args, **kwargs):
79 79 self.args = args
80 80 self.kwargs = kwargs
81 81
82 82 # contains the most recently instantiated IPApi
83 83
84 84 class IPythonNotRunning:
85 85 """Dummy do-nothing class.
86 86
87 87 Instances of this class return a dummy attribute on all accesses, which
88 88 can be called and warns. This makes it easier to write scripts which use
89 89 the ipapi.get() object for informational purposes to operate both with and
90 90 without ipython. Obviously code which uses the ipython object for
91 91 computations will not work, but this allows a wider range of code to
92 92 transparently work whether ipython is being used or not."""
93 93
94 94 def __str__(self):
95 95 return "<IPythonNotRunning>"
96 96
97 97 __repr__ = __str__
98 98
99 99 def __getattr__(self,name):
100 100 return self.dummy
101 101
102 102 def dummy(self,*args,**kw):
103 103 """Dummy function, which doesn't do anything but warn."""
104 104 warn("IPython is not running, this is a dummy no-op function")
105 105
106 106 _recent = None
107 107
108 108
109 109 def get(allow_dummy=False):
110 110 """Get an IPApi object.
111 111
112 112 If allow_dummy is true, returns an instance of IPythonNotRunning
113 113 instead of None if not running under IPython.
114 114
115 115 Running this should be the first thing you do when writing extensions that
116 116 can be imported as normal modules. You can then direct all the
117 117 configuration operations against the returned object.
118 118 """
119 119 global _recent
120 120 if allow_dummy and not _recent:
121 121 _recent = IPythonNotRunning()
122 122 return _recent
123 123
124 124 class IPApi:
125 125 """ The actual API class for configuring IPython
126 126
127 127 You should do all of the IPython configuration by getting an IPApi object
128 128 with IPython.ipapi.get() and using the attributes and methods of the
129 129 returned object."""
130 130
131 131 def __init__(self,ip):
132 132
133 133 # All attributes exposed here are considered to be the public API of
134 134 # IPython. As needs dictate, some of these may be wrapped as
135 135 # properties.
136 136
137 137 self.magic = ip.ipmagic
138 138
139 139 self.system = ip.ipsystem
140 140
141 141 self.set_hook = ip.set_hook
142 142
143 143 self.set_custom_exc = ip.set_custom_exc
144 144
145 145 self.user_ns = ip.user_ns
146 146
147 147 # Session-specific data store, which can be used to store
148 148 # data that should persist through the ipython session.
149 149 self.meta = ip.meta
150 150
151 151 # The ipython instance provided
152 152 self.IP = ip
153 153
154 154 global _recent
155 155 _recent = self
156 156
157 157 # Use a property for some things which are added to the instance very
158 158 # late. I don't have time right now to disentangle the initialization
159 159 # order issues, so a property lets us delay item extraction while
160 160 # providing a normal attribute API.
161 161 def get_db(self):
162 162 """A handle to persistent dict-like database (a PickleShareDB object)"""
163 163 return self.IP.db
164 164
165 165 db = property(get_db,None,None,get_db.__doc__)
166 166
167 167 def get_options(self):
168 168 """All configurable variables."""
169 169 return self.IP.rc
170 170
171 171 options = property(get_options,None,None,get_options.__doc__)
172 172
173 173 def expose_magic(self,magicname, func):
174 174 ''' Expose own function as magic function for ipython
175 175
176 176 def foo_impl(self,parameter_s=''):
177 177 """My very own magic!. (Use docstrings, IPython reads them)."""
178 178 print 'Magic function. Passed parameter is between < >: <'+parameter_s+'>'
179 179 print 'The self object is:',self
180 180
181 181 ipapi.expose_magic("foo",foo_impl)
182 182 '''
183 183
184 184 import new
185 185 im = new.instancemethod(func,self.IP, self.IP.__class__)
186 186 setattr(self.IP, "magic_" + magicname, im)
187 187
188 188 def ex(self,cmd):
189 189 """ Execute a normal python statement in user namespace """
190 190 exec cmd in self.user_ns
191 191
192 192 def ev(self,expr):
193 193 """ Evaluate python expression expr in user namespace
194 194
195 195 Returns the result of evaluation"""
196 196 return eval(expr,self.user_ns)
197 197
198 198 def runlines(self,lines):
199 199 """ Run the specified lines in interpreter, honoring ipython directives.
200 200
201 201 This allows %magic and !shell escape notations.
202 202
203 203 Takes either all lines in one string or list of lines.
204 204 """
205 205 if isinstance(lines,basestring):
206 206 self.IP.runlines(lines)
207 207 else:
208 208 self.IP.runlines('\n'.join(lines))
209 209
210 def to_user_ns(self,*vars):
210 def to_user_ns(self,vars):
211 211 """Inject a group of variables into the IPython user namespace.
212 212
213 213 Inputs:
214 214
215 - *vars: one or more variables from the caller's namespace to be put
216 into the interactive IPython namespace. The arguments can be given
217 in one of two forms, but ALL arguments must follow the same
218 convention (the first is checked and the rest are assumed to follow
219 it):
220
221 a) All strings, naming variables in the caller. These names are
222 evaluated in the caller's frame and put in, with the same name, in
223 the IPython namespace.
224
225 b) Pairs of (name, value), where the name is a string (a valid
226 python identifier). In this case, the value is put into the
227 IPython namespace labeled by the given name. This allows you to
228 rename your local variables so they don't collide with other names
229 you may already be using globally, or elsewhere and which you also
230 want to propagate.
231
215 - vars: string with variable names separated by whitespace
232 216
233 217 This utility routine is meant to ease interactive debugging work,
234 218 where you want to easily propagate some internal variable in your code
235 219 up to the interactive namespace for further exploration.
236 220
237 221 When you run code via %run, globals in your script become visible at
238 222 the interactive prompt, but this doesn't happen for locals inside your
239 223 own functions and methods. Yet when debugging, it is common to want
240 224 to explore some internal variables further at the interactive propmt.
241 225
242 226 Examples:
243 227
244 228 To use this, you first must obtain a handle on the ipython object as
245 229 indicated above, via:
246 230
247 231 import IPython.ipapi
248 232 ip = IPython.ipapi.get()
249 233
250 234 Once this is done, inside a routine foo() where you want to expose
251 235 variables x and y, you do the following:
252 236
253 237 def foo():
254 238 ...
255 239 x = your_computation()
256 240 y = something_else()
257 241
258 242 # This pushes x and y to the interactive prompt immediately, even
259 243 # if this routine crashes on the next line after:
260 ip.to_user_ns('x','y')
244 ip.to_user_ns('x y')
261 245 ...
262 246 # return
263 247
264 The following example shows you how to rename variables to avoid
265 clashes:
266
267 def bar():
268 ...
269 x,y,z,w = foo()
248 If you need to rename variables, just use ip.user_ns with dict
249 and update:
270 250
271 # Push these variables with different names, so they don't
272 # overwrite x and y from before
273 ip.to_user_ns(('x1',x),('y1',y),('z1',z),('w1',w))
274 # which is more conveniently written as:
275 ip.to_user_ns(*zip(('x1','y1','z1','w1'),(x,y,z,w)))
251 # exposes variables 'foo' as 'x' and 'bar' as 'y' in IPython
252 # user namespace
253 ip.user_ns.update(dict(x=foo,y=bar))
276 254
277 ...
278 # return """
255 """
279 256
280 257 # print 'vars given:',vars # dbg
281 258 # Get the caller's frame to evaluate the given names in
282 259 cf = sys._getframe(1)
283 260
284 # XXX fix this after Ville replies...
285 261 user_ns = self.user_ns
286 262
287 if isinstance(vars[0],basestring):
288 # assume that all variables are given as strings
263 for name in vars.split():
289 264 try:
290 for name in vars:
291 265 user_ns[name] = eval(name,cf.f_globals,cf.f_locals)
292 266 except:
293 267 error('could not get var. %s from %s' %
294 268 (name,cf.f_code.co_name))
295 269
296 else:
297 # assume they are all given as pairs of name,object
298 user_ns.update(dict(vars))
299
300
301 270 def launch_new_instance(user_ns = None):
302 271 """ Create and start a new ipython instance.
303 272
304 273 This can be called even without having an already initialized
305 274 ipython session running.
306 275
307 276 This is also used as the egg entry point for the 'ipython' script.
308 277
309 278 """
310 279 ses = create_session(user_ns)
311 280 ses.mainloop()
312 281
313 282
314 283 def create_session(user_ns = None):
315 284 """ Creates, but does not launch an IPython session.
316 285
317 286 Later on you can call obj.mainloop() on the returned object.
318 287
319 288 This should *not* be run when a session exists already.
320 289
321 290 """
322 291 if user_ns is not None:
323 292 user_ns["__name__"] = user_ns.get("__name__",'ipy_session')
324 293 import IPython
325 294 return IPython.Shell.start(user_ns = user_ns)
General Comments 0
You need to be logged in to leave comments. Login now