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