##// END OF EJS Templates
ipy_which.py added (%which magic)...
vivainio -
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -0,0 +1,70 b''
1 r""" %which magic command
2
3 %which <cmd> => search PATH for files matching PATH. Also scans aliases
4
5 """
6
7 import IPython.ipapi
8 ip = IPython.ipapi.get()
9
10 import os,sys
11 from fnmatch import fnmatch
12 def which(fname):
13 fullpath = filter(os.path.isdir,os.environ['PATH'].split(os.pathsep))
14
15 if '.' not in fullpath:
16 fullpath = ['.'] + fullpath
17 fn = fname
18 for p in fullpath:
19 for f in os.listdir(p):
20 head, ext = os.path.splitext(f)
21 if f == fn or fnmatch(head, fn):
22 yield os.path.join(p,f)
23 return
24
25 def which_alias(fname):
26 for al, tgt in ip.IP.alias_table.items():
27 if not (al == fname or fnmatch(al, fname)):
28 continue
29 trg = tgt[1]
30
31 trans = ip.expand_alias(trg)
32 cmd = trans.split(None,1)[0]
33 print al,"->",trans
34 for realcmd in which(cmd):
35 print " ==",realcmd
36
37 def which_f(self, arg):
38 r""" %which <cmd> => search PATH for files matching cmd. Also scans aliases.
39
40 Traverses PATH and prints all files (not just executables!) that match the
41 pattern on command line. Probably more useful in finding stuff
42 interactively than 'which', which only prints the first matching item.
43
44 Also discovers and expands aliases, so you'll see what will be executed
45 when you call an alias.
46
47 Example:
48
49 [~]|62> %which d
50 d -> ls -F --color=auto
51 == c:\cygwin\bin\ls.exe
52 c:\cygwin\bin\d.exe
53
54 [~]|64> %which diff*
55 diff3 -> diff3
56 == c:\cygwin\bin\diff3.exe
57 diff -> diff
58 == c:\cygwin\bin\diff.exe
59 c:\cygwin\bin\diff.exe
60 c:\cygwin\bin\diff3.exe
61
62 """
63
64 which_alias(arg)
65
66 for e in which(arg):
67 print e
68
69 ip.expose_magic("which",which_f)
70
@@ -1,187 +1,188 b''
1 1 """Shell mode for IPython.
2 2
3 3 Start ipython in shell mode by invoking "ipython -p sh"
4 4
5 5 (the old version, "ipython -p pysh" still works but this is the more "modern"
6 6 shell mode and is recommended for users who don't care about pysh-mode
7 7 compatibility)
8 8 """
9 9
10 10 from IPython import ipapi
11 11 import os,textwrap
12 12
13 13 # The import below effectively obsoletes your old-style ipythonrc[.ini],
14 14 # so consider yourself warned!
15 15
16 16 import ipy_defaults
17 17
18 18 def main():
19 19 ip = ipapi.get()
20 20 o = ip.options
21 21 # autocall to "full" mode (smart mode is default, I like full mode)
22 22
23 23 o.autocall = 2
24 24
25 25 # Jason Orendorff's path class is handy to have in user namespace
26 26 # if you are doing shell-like stuff
27 27 try:
28 28 ip.ex("from path import path" )
29 29 except ImportError:
30 30 pass
31 31
32 32 # beefed up %env is handy in shell mode
33 33 import envpersist
34 import ipy_which
34 35
35 36
36 37 ip.ex('import os')
37 38 ip.ex("def up(): os.chdir('..')")
38 39
39 40 # Get pysh-like prompt for all profiles.
40 41
41 42 o.prompt_in1= '\C_LightBlue[\C_LightCyan\Y1\C_LightBlue]\C_Green|\#> '
42 43 o.prompt_in2= '\C_Green|\C_LightGreen\D\C_Green> '
43 44 o.prompt_out= '<\#> '
44 45
45 46 from IPython import Release
46 47
47 48 import sys
48 49 # I like my banner minimal.
49 50 o.banner = "Py %s IPy %s\n" % (sys.version.split('\n')[0],Release.version)
50 51
51 52 # make 'd' an alias for ls -F
52 53
53 54 ip.magic('alias d ls -F --color=auto')
54 55
55 56 ip.IP.default_option('cd','-q')
56 57
57 58 # If you only rarely want to execute the things you %edit...
58 59
59 60 #ip.IP.default_option('edit','-x')
60 61
61 62
62 63 o.prompts_pad_left="1"
63 64 # Remove all blank lines in between prompts, like a normal shell.
64 65 o.separate_in="0"
65 66 o.separate_out="0"
66 67 o.separate_out2="0"
67 68
68 69 # now alias all syscommands
69 70
70 71 db = ip.db
71 72
72 73 syscmds = db.get("syscmdlist",[] )
73 74 if not syscmds:
74 75 print textwrap.dedent("""
75 76 System command list not initialized, probably the first run...
76 77 running %rehashx to refresh the command list. Run %rehashx
77 78 again to refresh command list (after installing new software etc.)
78 79 """)
79 80 ip.magic('rehashx')
80 81 syscmds = db.get("syscmdlist")
81 82 for cmd in syscmds:
82 83 #print "al",cmd
83 84 noext, ext = os.path.splitext(cmd)
84 85 ip.IP.alias_table[noext] = (0,cmd)
85 86 extend_shell_behavior(ip)
86 87
87 88 def extend_shell_behavior(ip):
88 89
89 90 # Instead of making signature a global variable tie it to IPSHELL.
90 91 # In future if it is required to distinguish between different
91 92 # shells we can assign a signature per shell basis
92 93 ip.IP.__sig__ = 0xa005
93 94 # mark the IPSHELL with this signature
94 95 ip.IP.user_ns['__builtins__'].__dict__['__sig__'] = ip.IP.__sig__
95 96
96 97 from IPython.Itpl import ItplNS
97 98 from IPython.genutils import shell
98 99 # utility to expand user variables via Itpl
99 100 # xxx do something sensible with depth?
100 101 ip.IP.var_expand = lambda cmd, lvars=None, depth=2: \
101 102 str(ItplNS(cmd.replace('#','\#'), ip.IP.user_ns, get_locals()))
102 103
103 104 def get_locals():
104 105 """ Substituting a variable through Itpl deep inside the IPSHELL stack
105 106 requires the knowledge of all the variables in scope upto the last
106 107 IPSHELL frame. This routine simply merges all the local variables
107 108 on the IPSHELL stack without worrying about their scope rules
108 109 """
109 110 import sys
110 111 # note lambda expression constitues a function call
111 112 # hence fno should be incremented by one
112 113 getsig = lambda fno: sys._getframe(fno+1).f_globals \
113 114 ['__builtins__'].__dict__['__sig__']
114 115 getlvars = lambda fno: sys._getframe(fno+1).f_locals
115 116 # trackback until we enter the IPSHELL
116 117 frame_no = 1
117 118 sig = ip.IP.__sig__
118 119 fsig = ~sig
119 120 while fsig != sig :
120 121 try:
121 122 fsig = getsig(frame_no)
122 123 except (AttributeError, KeyError):
123 124 frame_no += 1
124 125 except ValueError:
125 126 # stack is depleted
126 127 # call did not originate from IPSHELL
127 128 return {}
128 129 first_frame = frame_no
129 130 # walk further back until we exit from IPSHELL or deplete stack
130 131 try:
131 132 while(sig == getsig(frame_no+1)):
132 133 frame_no += 1
133 134 except (AttributeError, KeyError, ValueError):
134 135 pass
135 136 # merge the locals from top down hence overriding
136 137 # any re-definitions of variables, functions etc.
137 138 lvars = {}
138 139 for fno in range(frame_no, first_frame-1, -1):
139 140 lvars.update(getlvars(fno))
140 141 #print '\n'*5, first_frame, frame_no, '\n', lvars, '\n'*5 #dbg
141 142 return lvars
142 143
143 144 def _runlines(lines):
144 145 """Run a string of one or more lines of source.
145 146
146 147 This method is capable of running a string containing multiple source
147 148 lines, as if they had been entered at the IPython prompt. Since it
148 149 exposes IPython's processing machinery, the given strings can contain
149 150 magic calls (%magic), special shell access (!cmd), etc."""
150 151
151 152 # We must start with a clean buffer, in case this is run from an
152 153 # interactive IPython session (via a magic, for example).
153 154 ip.IP.resetbuffer()
154 155 lines = lines.split('\n')
155 156 more = 0
156 157 command = ''
157 158 for line in lines:
158 159 # skip blank lines so we don't mess up the prompt counter, but do
159 160 # NOT skip even a blank line if we are in a code block (more is
160 161 # true)
161 162 # if command is not empty trim the line
162 163 if command != '' :
163 164 line = line.strip()
164 165 # add the broken line to the command
165 166 if line and line[-1] == '\\' :
166 167 command += line[0:-1] + ' '
167 168 more = True
168 169 continue
169 170 else :
170 171 # add the last (current) line to the command
171 172 command += line
172 173 if command or more:
173 174 more = ip.IP.push(ip.IP.prefilter(command,more))
174 175 command = ''
175 176 # IPython's runsource returns None if there was an error
176 177 # compiling the code. This allows us to stop processing right
177 178 # away, so the user gets the error message at the right place.
178 179 if more is None:
179 180 break
180 181 # final newline in case the input didn't have it, so that the code
181 182 # actually does get executed
182 183 if more:
183 184 ip.IP.push('\n')
184 185
185 186 ip.IP.runlines = _runlines
186 187
187 188 main()
@@ -1,405 +1,406 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 # our own
68 68 from IPython.genutils import warn,error
69 69
70 70 class TryNext(Exception):
71 71 """Try next hook exception.
72 72
73 73 Raise this in your hook function to indicate that the next hook handler
74 74 should be used to handle the operation. If you pass arguments to the
75 75 constructor those arguments will be used by the next hook instead of the
76 76 original ones.
77 77 """
78 78
79 79 def __init__(self, *args, **kwargs):
80 80 self.args = args
81 81 self.kwargs = kwargs
82 82
83 83 # contains the most recently instantiated IPApi
84 84
85 85 class IPythonNotRunning:
86 86 """Dummy do-nothing class.
87 87
88 88 Instances of this class return a dummy attribute on all accesses, which
89 89 can be called and warns. This makes it easier to write scripts which use
90 90 the ipapi.get() object for informational purposes to operate both with and
91 91 without ipython. Obviously code which uses the ipython object for
92 92 computations will not work, but this allows a wider range of code to
93 93 transparently work whether ipython is being used or not."""
94 94
95 95 def __init__(self,warn=True):
96 96 if warn:
97 97 self.dummy = self._dummy_warn
98 98 else:
99 99 self.dummy = self._dummy_silent
100 100
101 101 def __str__(self):
102 102 return "<IPythonNotRunning>"
103 103
104 104 __repr__ = __str__
105 105
106 106 def __getattr__(self,name):
107 107 return self.dummy
108 108
109 109 def _dummy_warn(self,*args,**kw):
110 110 """Dummy function, which doesn't do anything but warn."""
111 111
112 112 warn("IPython is not running, this is a dummy no-op function")
113 113
114 114 def _dummy_silent(self,*args,**kw):
115 115 """Dummy function, which doesn't do anything and emits no warnings."""
116 116 pass
117 117
118 118 _recent = None
119 119
120 120
121 121 def get(allow_dummy=False,dummy_warn=True):
122 122 """Get an IPApi object.
123 123
124 124 If allow_dummy is true, returns an instance of IPythonNotRunning
125 125 instead of None if not running under IPython.
126 126
127 127 If dummy_warn is false, the dummy instance will be completely silent.
128 128
129 129 Running this should be the first thing you do when writing extensions that
130 130 can be imported as normal modules. You can then direct all the
131 131 configuration operations against the returned object.
132 132 """
133 133 global _recent
134 134 if allow_dummy and not _recent:
135 135 _recent = IPythonNotRunning(dummy_warn)
136 136 return _recent
137 137
138 138 class IPApi:
139 139 """ The actual API class for configuring IPython
140 140
141 141 You should do all of the IPython configuration by getting an IPApi object
142 142 with IPython.ipapi.get() and using the attributes and methods of the
143 143 returned object."""
144 144
145 145 def __init__(self,ip):
146 146
147 147 # All attributes exposed here are considered to be the public API of
148 148 # IPython. As needs dictate, some of these may be wrapped as
149 149 # properties.
150 150
151 151 self.magic = ip.ipmagic
152 152
153 153 self.system = ip.ipsystem
154 154
155 155 self.set_hook = ip.set_hook
156 156
157 157 self.set_custom_exc = ip.set_custom_exc
158 158
159 159 self.user_ns = ip.user_ns
160 160
161 161 self.set_crash_handler = ip.set_crash_handler
162 162
163 163 # Session-specific data store, which can be used to store
164 164 # data that should persist through the ipython session.
165 165 self.meta = ip.meta
166 166
167 167 # The ipython instance provided
168 168 self.IP = ip
169 169
170 170 global _recent
171 171 _recent = self
172 172
173 173 # Use a property for some things which are added to the instance very
174 174 # late. I don't have time right now to disentangle the initialization
175 175 # order issues, so a property lets us delay item extraction while
176 176 # providing a normal attribute API.
177 177 def get_db(self):
178 178 """A handle to persistent dict-like database (a PickleShareDB object)"""
179 179 return self.IP.db
180 180
181 181 db = property(get_db,None,None,get_db.__doc__)
182 182
183 183 def get_options(self):
184 184 """All configurable variables."""
185 185
186 186 # catch typos by disabling new attribute creation. If new attr creation
187 187 # is in fact wanted (e.g. when exposing new options), do allow_new_attr(True)
188 188 # for the received rc struct.
189 189
190 190 self.IP.rc.allow_new_attr(False)
191 191 return self.IP.rc
192 192
193 193 options = property(get_options,None,None,get_options.__doc__)
194 194
195 195 def expose_magic(self,magicname, func):
196 196 ''' Expose own function as magic function for ipython
197 197
198 198 def foo_impl(self,parameter_s=''):
199 199 """My very own magic!. (Use docstrings, IPython reads them)."""
200 200 print 'Magic function. Passed parameter is between < >: <'+parameter_s+'>'
201 201 print 'The self object is:',self
202 202
203 203 ipapi.expose_magic("foo",foo_impl)
204 204 '''
205 205
206 206 import new
207 207 im = new.instancemethod(func,self.IP, self.IP.__class__)
208 208 setattr(self.IP, "magic_" + magicname, im)
209 209
210 210 def ex(self,cmd):
211 211 """ Execute a normal python statement in user namespace """
212 212 exec cmd in self.user_ns
213 213
214 214 def ev(self,expr):
215 215 """ Evaluate python expression expr in user namespace
216 216
217 217 Returns the result of evaluation"""
218 218 return eval(expr,self.user_ns)
219 219
220 220 def runlines(self,lines):
221 221 """ Run the specified lines in interpreter, honoring ipython directives.
222 222
223 223 This allows %magic and !shell escape notations.
224 224
225 225 Takes either all lines in one string or list of lines.
226 226 """
227 227 if isinstance(lines,basestring):
228 228 self.IP.runlines(lines)
229 229 else:
230 230 self.IP.runlines('\n'.join(lines))
231 231
232 232 def to_user_ns(self,vars):
233 233 """Inject a group of variables into the IPython user namespace.
234 234
235 235 Inputs:
236 236
237 237 - vars: string with variable names separated by whitespace
238 238
239 239 This utility routine is meant to ease interactive debugging work,
240 240 where you want to easily propagate some internal variable in your code
241 241 up to the interactive namespace for further exploration.
242 242
243 243 When you run code via %run, globals in your script become visible at
244 244 the interactive prompt, but this doesn't happen for locals inside your
245 245 own functions and methods. Yet when debugging, it is common to want
246 246 to explore some internal variables further at the interactive propmt.
247 247
248 248 Examples:
249 249
250 250 To use this, you first must obtain a handle on the ipython object as
251 251 indicated above, via:
252 252
253 253 import IPython.ipapi
254 254 ip = IPython.ipapi.get()
255 255
256 256 Once this is done, inside a routine foo() where you want to expose
257 257 variables x and y, you do the following:
258 258
259 259 def foo():
260 260 ...
261 261 x = your_computation()
262 262 y = something_else()
263 263
264 264 # This pushes x and y to the interactive prompt immediately, even
265 265 # if this routine crashes on the next line after:
266 266 ip.to_user_ns('x y')
267 267 ...
268 268 # return
269 269
270 270 If you need to rename variables, just use ip.user_ns with dict
271 271 and update:
272 272
273 273 # exposes variables 'foo' as 'x' and 'bar' as 'y' in IPython
274 274 # user namespace
275 275 ip.user_ns.update(dict(x=foo,y=bar))
276 276 """
277 277
278 278 # print 'vars given:',vars # dbg
279 279 # Get the caller's frame to evaluate the given names in
280 280 cf = sys._getframe(1)
281 281
282 282 user_ns = self.user_ns
283 283
284 284 for name in vars.split():
285 285 try:
286 286 user_ns[name] = eval(name,cf.f_globals,cf.f_locals)
287 287 except:
288 288 error('could not get var. %s from %s' %
289 289 (name,cf.f_code.co_name))
290 290
291 291 def expand_alias(self,line):
292 292 """ Expand an alias in the command line
293 293
294 294 Returns the provided command line, possibly with the first word
295 295 (command) translated according to alias expansion rules.
296 296
297 297 [ipython]|16> _ip.expand_aliases("np myfile.txt")
298 298 <16> 'q:/opt/np/notepad++.exe myfile.txt'
299 299 """
300 300
301 301 pre,fn,rest = self.IP.split_user_input(line)
302 302 res = pre + self.IP.expand_aliases(fn,rest)
303 return res
303 304
304 305 def defalias(self, name, cmd):
305 306 """ Define a new alias
306 307
307 308 _ip.defalias('bb','bldmake bldfiles')
308 309
309 310 Creates a new alias named 'bb' in ipython user namespace
310 311 """
311 312
312 313
313 314 nargs = cmd.count('%s')
314 315 if nargs>0 and cmd.find('%l')>=0:
315 316 raise Exception('The %s and %l specifiers are mutually exclusive '
316 317 'in alias definitions.')
317 318
318 319 else: # all looks OK
319 320 self.IP.alias_table[name] = (nargs,cmd)
320 321
321 322 def defmacro(self, *args):
322 323 """ Define a new macro
323 324
324 325 2 forms of calling:
325 326
326 327 mac = _ip.defmacro('print "hello"\nprint "world"')
327 328
328 329 (doesn't put the created macro on user namespace)
329 330
330 331 _ip.defmacro('build', 'bldmake bldfiles\nabld build winscw udeb')
331 332
332 333 (creates a macro named 'build' in user namespace)
333 334 """
334 335
335 336 import IPython.macro
336 337
337 338 if len(args) == 1:
338 339 return IPython.macro.Macro(args[0])
339 340 elif len(args) == 2:
340 341 self.user_ns[args[0]] = IPython.macro.Macro(args[1])
341 342 else:
342 343 return Exception("_ip.defmacro must be called with 1 or 2 arguments")
343 344
344 345
345 346
346 347 def launch_new_instance(user_ns = None):
347 348 """ Make and start a new ipython instance.
348 349
349 350 This can be called even without having an already initialized
350 351 ipython session running.
351 352
352 353 This is also used as the egg entry point for the 'ipython' script.
353 354
354 355 """
355 356 ses = make_session(user_ns)
356 357 ses.mainloop()
357 358
358 359
359 360 def make_user_ns(user_ns = None):
360 361 """Return a valid user interactive namespace.
361 362
362 363 This builds a dict with the minimal information needed to operate as a
363 364 valid IPython user namespace, which you can pass to the various embedding
364 365 classes in ipython.
365 366 """
366 367
367 368 if user_ns is None:
368 369 # Set __name__ to __main__ to better match the behavior of the
369 370 # normal interpreter.
370 371 user_ns = {'__name__' :'__main__',
371 372 '__builtins__' : __builtin__,
372 373 }
373 374 else:
374 375 user_ns.setdefault('__name__','__main__')
375 376 user_ns.setdefault('__builtins__',__builtin__)
376 377
377 378 return user_ns
378 379
379 380
380 381 def make_user_global_ns(ns = None):
381 382 """Return a valid user global namespace.
382 383
383 384 Similar to make_user_ns(), but global namespaces are really only needed in
384 385 embedded applications, where there is a distinction between the user's
385 386 interactive namespace and the global one where ipython is running."""
386 387
387 388 if ns is None: ns = {}
388 389 return ns
389 390
390 391
391 392 def make_session(user_ns = None):
392 393 """Makes, but does not launch an IPython session.
393 394
394 395 Later on you can call obj.mainloop() on the returned object.
395 396
396 397 Inputs:
397 398
398 399 - user_ns(None): a dict to be used as the user's namespace with initial
399 400 data.
400 401
401 402 WARNING: This should *not* be run when a session exists already."""
402 403
403 404 import IPython
404 405 return IPython.Shell.start(user_ns)
405 406
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now