##// END OF EJS Templates
Merged with upstream.
gvaroquaux -
r1466:27953ac1 merge
parent child Browse files
Show More

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

1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,398 +1,400 b''
1 1 """
2 2 ``astyle`` provides classes for adding style (foreground and background color;
3 3 bold; blink; etc.) to terminal and curses output.
4 4 """
5 5
6 6
7 7 import sys, os
8 8
9 9 try:
10 10 import curses
11 11 except ImportError:
12 12 curses = None
13 13
14 14
15 15 COLOR_BLACK = 0
16 16 COLOR_RED = 1
17 17 COLOR_GREEN = 2
18 18 COLOR_YELLOW = 3
19 19 COLOR_BLUE = 4
20 20 COLOR_MAGENTA = 5
21 21 COLOR_CYAN = 6
22 22 COLOR_WHITE = 7
23 23
24 24 A_BLINK = 1<<0 # Blinking text
25 25 A_BOLD = 1<<1 # Extra bright or bold text
26 26 A_DIM = 1<<2 # Half bright text
27 27 A_REVERSE = 1<<3 # Reverse-video text
28 28 A_STANDOUT = 1<<4 # The best highlighting mode available
29 29 A_UNDERLINE = 1<<5 # Underlined text
30 30
31 31
32 32 class Style(object):
33 33 """
34 34 Store foreground color, background color and attribute (bold, underlined
35 35 etc.).
36 36 """
37 37 __slots__ = ("fg", "bg", "attrs")
38 38
39 39 COLORNAMES = {
40 40 "black": COLOR_BLACK,
41 41 "red": COLOR_RED,
42 42 "green": COLOR_GREEN,
43 43 "yellow": COLOR_YELLOW,
44 44 "blue": COLOR_BLUE,
45 45 "magenta": COLOR_MAGENTA,
46 46 "cyan": COLOR_CYAN,
47 47 "white": COLOR_WHITE,
48 48 }
49 49 ATTRNAMES = {
50 50 "blink": A_BLINK,
51 51 "bold": A_BOLD,
52 52 "dim": A_DIM,
53 53 "reverse": A_REVERSE,
54 54 "standout": A_STANDOUT,
55 55 "underline": A_UNDERLINE,
56 56 }
57 57
58 58 def __init__(self, fg, bg, attrs=0):
59 59 """
60 60 Create a ``Style`` object with ``fg`` as the foreground color,
61 61 ``bg`` as the background color and ``attrs`` as the attributes.
62 62
63 63 Examples:
64
65 64 >>> Style(COLOR_RED, COLOR_BLACK)
65 <Style fg=red bg=black attrs=0>
66
66 67 >>> Style(COLOR_YELLOW, COLOR_BLUE, A_BOLD|A_UNDERLINE)
68 <Style fg=yellow bg=blue attrs=bold|underline>
67 69 """
68 70 self.fg = fg
69 71 self.bg = bg
70 72 self.attrs = attrs
71 73
72 74 def __call__(self, *args):
73 75 text = Text()
74 76 for arg in args:
75 77 if isinstance(arg, Text):
76 78 text.extend(arg)
77 79 else:
78 80 text.append((self, arg))
79 81 return text
80 82
81 83 def __eq__(self, other):
82 84 return self.fg == other.fg and self.bg == other.bg and self.attrs == other.attrs
83 85
84 86 def __neq__(self, other):
85 87 return self.fg != other.fg or self.bg != other.bg or self.attrs != other.attrs
86 88
87 89 def __repr__(self):
88 90 color2name = ("black", "red", "green", "yellow", "blue", "magenta", "cyan", "white")
89 91 attrs2name = ("blink", "bold", "dim", "reverse", "standout", "underline")
90 92
91 93 return "<%s fg=%s bg=%s attrs=%s>" % (
92 94 self.__class__.__name__, color2name[self.fg], color2name[self.bg],
93 95 "|".join([attrs2name[b] for b in xrange(6) if self.attrs&(1<<b)]) or 0)
94 96
95 97 def fromstr(cls, value):
96 98 """
97 99 Create a ``Style`` object from a string. The format looks like this:
98 100 ``"red:black:bold|blink"``.
99 101 """
100 102 # defaults
101 103 fg = COLOR_WHITE
102 104 bg = COLOR_BLACK
103 105 attrs = 0
104 106
105 107 parts = value.split(":")
106 108 if len(parts) > 0:
107 109 fg = cls.COLORNAMES[parts[0].lower()]
108 110 if len(parts) > 1:
109 111 bg = cls.COLORNAMES[parts[1].lower()]
110 112 if len(parts) > 2:
111 113 for strattr in parts[2].split("|"):
112 114 attrs |= cls.ATTRNAMES[strattr.lower()]
113 115 return cls(fg, bg, attrs)
114 116 fromstr = classmethod(fromstr)
115 117
116 118 def fromenv(cls, name, default):
117 119 """
118 120 Create a ``Style`` from an environment variable named ``name``
119 121 (using ``default`` if the environment variable doesn't exist).
120 122 """
121 123 return cls.fromstr(os.environ.get(name, default))
122 124 fromenv = classmethod(fromenv)
123 125
124 126
125 127 def switchstyle(s1, s2):
126 128 """
127 129 Return the ANSI escape sequence needed to switch from style ``s1`` to
128 130 style ``s2``.
129 131 """
130 132 attrmask = (A_BLINK|A_BOLD|A_UNDERLINE|A_REVERSE)
131 133 a1 = s1.attrs & attrmask
132 134 a2 = s2.attrs & attrmask
133 135
134 136 args = []
135 137 if s1 != s2:
136 138 # do we have to get rid of the bold/underline/blink bit?
137 139 # (can only be done by a reset)
138 140 # use reset when our target color is the default color
139 141 # (this is shorter than 37;40)
140 142 if (a1 & ~a2 or s2==style_default):
141 143 args.append("0")
142 144 s1 = style_default
143 145 a1 = 0
144 146
145 147 # now we know that old and new color have the same boldness,
146 148 # or the new color is bold and the old isn't,
147 149 # i.e. we only might have to switch bold on, not off
148 150 if not (a1 & A_BOLD) and (a2 & A_BOLD):
149 151 args.append("1")
150 152
151 153 # Fix underline
152 154 if not (a1 & A_UNDERLINE) and (a2 & A_UNDERLINE):
153 155 args.append("4")
154 156
155 157 # Fix blink
156 158 if not (a1 & A_BLINK) and (a2 & A_BLINK):
157 159 args.append("5")
158 160
159 161 # Fix reverse
160 162 if not (a1 & A_REVERSE) and (a2 & A_REVERSE):
161 163 args.append("7")
162 164
163 165 # Fix foreground color
164 166 if s1.fg != s2.fg:
165 167 args.append("3%d" % s2.fg)
166 168
167 169 # Finally fix the background color
168 170 if s1.bg != s2.bg:
169 171 args.append("4%d" % s2.bg)
170 172
171 173 if args:
172 174 return "\033[%sm" % ";".join(args)
173 175 return ""
174 176
175 177
176 178 class Text(list):
177 179 """
178 180 A colored string. A ``Text`` object is a sequence, the sequence
179 181 items will be ``(style, string)`` tuples.
180 182 """
181 183
182 184 def __init__(self, *args):
183 185 list.__init__(self)
184 186 self.append(*args)
185 187
186 188 def __repr__(self):
187 189 return "%s.%s(%s)" % (
188 190 self.__class__.__module__, self.__class__.__name__,
189 191 list.__repr__(self)[1:-1])
190 192
191 193 def append(self, *args):
192 194 for arg in args:
193 195 if isinstance(arg, Text):
194 196 self.extend(arg)
195 197 elif isinstance(arg, tuple): # must be (style, string)
196 198 list.append(self, arg)
197 199 elif isinstance(arg, unicode):
198 200 list.append(self, (style_default, arg))
199 201 else:
200 202 list.append(self, (style_default, str(arg)))
201 203
202 204 def insert(self, index, *args):
203 205 self[index:index] = Text(*args)
204 206
205 207 def __add__(self, other):
206 208 new = Text()
207 209 new.append(self)
208 210 new.append(other)
209 211 return new
210 212
211 213 def __iadd__(self, other):
212 214 self.append(other)
213 215 return self
214 216
215 217 def format(self, styled=True):
216 218 """
217 219 This generator yields the strings that will make up the final
218 220 colorized string.
219 221 """
220 222 if styled:
221 223 oldstyle = style_default
222 224 for (style, string) in self:
223 225 if not isinstance(style, (int, long)):
224 226 switch = switchstyle(oldstyle, style)
225 227 if switch:
226 228 yield switch
227 229 if string:
228 230 yield string
229 231 oldstyle = style
230 232 switch = switchstyle(oldstyle, style_default)
231 233 if switch:
232 234 yield switch
233 235 else:
234 236 for (style, string) in self:
235 237 if not isinstance(style, (int, long)):
236 238 yield string
237 239
238 240 def string(self, styled=True):
239 241 """
240 242 Return the resulting string (with escape sequences, if ``styled``
241 243 is true).
242 244 """
243 245 return "".join(self.format(styled))
244 246
245 247 def __str__(self):
246 248 """
247 249 Return ``self`` as a string (without ANSI escape sequences).
248 250 """
249 251 return self.string(False)
250 252
251 253 def write(self, stream, styled=True):
252 254 """
253 255 Write ``self`` to the output stream ``stream`` (with escape sequences,
254 256 if ``styled`` is true).
255 257 """
256 258 for part in self.format(styled):
257 259 stream.write(part)
258 260
259 261
260 262 try:
261 263 import ipipe
262 264 except ImportError:
263 265 pass
264 266 else:
265 267 def xrepr_astyle_text(self, mode="default"):
266 268 yield (-1, True)
267 269 for info in self:
268 270 yield info
269 271 ipipe.xrepr.when_type(Text)(xrepr_astyle_text)
270 272
271 273
272 274 def streamstyle(stream, styled=None):
273 275 """
274 276 If ``styled`` is ``None``, return whether ``stream`` refers to a terminal.
275 277 If this can't be determined (either because ``stream`` doesn't refer to a
276 278 real OS file, or because you're on Windows) return ``False``. If ``styled``
277 279 is not ``None`` ``styled`` will be returned unchanged.
278 280 """
279 281 if styled is None:
280 282 try:
281 283 styled = os.isatty(stream.fileno())
282 284 except (KeyboardInterrupt, SystemExit):
283 285 raise
284 286 except Exception:
285 287 styled = False
286 288 return styled
287 289
288 290
289 291 def write(stream, styled, *texts):
290 292 """
291 293 Write ``texts`` to ``stream``.
292 294 """
293 295 text = Text(*texts)
294 296 text.write(stream, streamstyle(stream, styled))
295 297
296 298
297 299 def writeln(stream, styled, *texts):
298 300 """
299 301 Write ``texts`` to ``stream`` and finish with a line feed.
300 302 """
301 303 write(stream, styled, *texts)
302 304 stream.write("\n")
303 305
304 306
305 307 class Stream(object):
306 308 """
307 309 Stream wrapper that adds color output.
308 310 """
309 311 def __init__(self, stream, styled=None):
310 312 self.stream = stream
311 313 self.styled = streamstyle(stream, styled)
312 314
313 315 def write(self, *texts):
314 316 write(self.stream, self.styled, *texts)
315 317
316 318 def writeln(self, *texts):
317 319 writeln(self.stream, self.styled, *texts)
318 320
319 321 def __getattr__(self, name):
320 322 return getattr(self.stream, name)
321 323
322 324
323 325 class stdout(object):
324 326 """
325 327 Stream wrapper for ``sys.stdout`` that adds color output.
326 328 """
327 329 def write(self, *texts):
328 330 write(sys.stdout, None, *texts)
329 331
330 332 def writeln(self, *texts):
331 333 writeln(sys.stdout, None, *texts)
332 334
333 335 def __getattr__(self, name):
334 336 return getattr(sys.stdout, name)
335 337 stdout = stdout()
336 338
337 339
338 340 class stderr(object):
339 341 """
340 342 Stream wrapper for ``sys.stderr`` that adds color output.
341 343 """
342 344 def write(self, *texts):
343 345 write(sys.stderr, None, *texts)
344 346
345 347 def writeln(self, *texts):
346 348 writeln(sys.stderr, None, *texts)
347 349
348 350 def __getattr__(self, name):
349 351 return getattr(sys.stdout, name)
350 352 stderr = stderr()
351 353
352 354
353 355 if curses is not None:
354 356 # This is probably just range(8)
355 357 COLOR2CURSES = [
356 358 COLOR_BLACK,
357 359 COLOR_RED,
358 360 COLOR_GREEN,
359 361 COLOR_YELLOW,
360 362 COLOR_BLUE,
361 363 COLOR_MAGENTA,
362 364 COLOR_CYAN,
363 365 COLOR_WHITE,
364 366 ]
365 367
366 368 A2CURSES = {
367 369 A_BLINK: curses.A_BLINK,
368 370 A_BOLD: curses.A_BOLD,
369 371 A_DIM: curses.A_DIM,
370 372 A_REVERSE: curses.A_REVERSE,
371 373 A_STANDOUT: curses.A_STANDOUT,
372 374 A_UNDERLINE: curses.A_UNDERLINE,
373 375 }
374 376
375 377
376 378 # default style
377 379 style_default = Style.fromstr("white:black")
378 380
379 381 # Styles for datatypes
380 382 style_type_none = Style.fromstr("magenta:black")
381 383 style_type_bool = Style.fromstr("magenta:black")
382 384 style_type_number = Style.fromstr("yellow:black")
383 385 style_type_datetime = Style.fromstr("magenta:black")
384 386 style_type_type = Style.fromstr("cyan:black")
385 387
386 388 # Style for URLs and file/directory names
387 389 style_url = Style.fromstr("green:black")
388 390 style_dir = Style.fromstr("cyan:black")
389 391 style_file = Style.fromstr("green:black")
390 392
391 393 # Style for ellipsis (when an output has been shortened
392 394 style_ellisis = Style.fromstr("red:black")
393 395
394 396 # Style for displaying exceptions
395 397 style_error = Style.fromstr("red:black")
396 398
397 399 # Style for displaying non-existing attributes
398 400 style_nodata = Style.fromstr("red:black")
@@ -1,2292 +1,2322 b''
1 1 # -*- coding: iso-8859-1 -*-
2 2
3 3 """
4 4 ``ipipe`` provides classes to be used in an interactive Python session. Doing a
5 5 ``from ipipe import *`` is the preferred way to do this. The name of all
6 6 objects imported this way starts with ``i`` to minimize collisions.
7 7
8 8 ``ipipe`` supports "pipeline expressions", which is something resembling Unix
9 9 pipes. An example is::
10 10
11 11 >>> ienv | isort("key.lower()")
12 12
13 13 This gives a listing of all environment variables sorted by name.
14 14
15 15
16 16 There are three types of objects in a pipeline expression:
17 17
18 18 * ``Table``s: These objects produce items. Examples are ``ils`` (listing the
19 19 current directory, ``ienv`` (listing environment variables), ``ipwd`` (listing
20 20 user accounts) and ``igrp`` (listing user groups). A ``Table`` must be the
21 21 first object in a pipe expression.
22 22
23 23 * ``Pipe``s: These objects sit in the middle of a pipe expression. They
24 24 transform the input in some way (e.g. filtering or sorting it). Examples are:
25 25 ``ifilter`` (which filters the input pipe), ``isort`` (which sorts the input
26 26 pipe) and ``ieval`` (which evaluates a function or expression for each object
27 27 in the input pipe).
28 28
29 29 * ``Display``s: These objects can be put as the last object in a pipeline
30 30 expression. There are responsible for displaying the result of the pipeline
31 31 expression. If a pipeline expression doesn't end in a display object a default
32 32 display objects will be used. One example is ``ibrowse`` which is a ``curses``
33 33 based browser.
34 34
35 35
36 36 Adding support for pipeline expressions to your own objects can be done through
37 37 three extensions points (all of them optional):
38 38
39 39 * An object that will be displayed as a row by a ``Display`` object should
40 40 implement the method ``__xattrs__(self, mode)`` method or register an
41 41 implementation of the generic function ``xattrs``. For more info see ``xattrs``.
42 42
43 43 * When an object ``foo`` is displayed by a ``Display`` object, the generic
44 44 function ``xrepr`` is used.
45 45
46 46 * Objects that can be iterated by ``Pipe``s must iterable. For special cases,
47 47 where iteration for display is different than the normal iteration a special
48 48 implementation can be registered with the generic function ``xiter``. This
49 49 makes it possible to use dictionaries and modules in pipeline expressions,
50 50 for example::
51 51
52 52 >>> import sys
53 53 >>> sys | ifilter("isinstance(value, int)") | idump
54 54 key |value
55 55 api_version| 1012
56 56 dllhandle | 503316480
57 57 hexversion | 33817328
58 58 maxint |2147483647
59 59 maxunicode | 65535
60 60 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
61 61 ...
62 62
63 63 Note: The expression strings passed to ``ifilter()`` and ``isort()`` can
64 64 refer to the object to be filtered or sorted via the variable ``_`` and to any
65 65 of the attributes of the object, i.e.::
66 66
67 67 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
68 68
69 69 does the same as::
70 70
71 71 >>> sys.modules | ifilter("value is not None") | isort("key.lower()")
72 72
73 73 In addition to expression strings, it's possible to pass callables (taking
74 74 the object as an argument) to ``ifilter()``, ``isort()`` and ``ieval()``::
75 75
76 76 >>> sys | ifilter(lambda _:isinstance(_.value, int)) \
77 77 ... | ieval(lambda _: (_.key, hex(_.value))) | idump
78 78 0 |1
79 79 api_version|0x3f4
80 80 dllhandle |0x1e000000
81 81 hexversion |0x20402f0
82 82 maxint |0x7fffffff
83 83 maxunicode |0xffff
84 84 """
85 85
86 skip_doctest = True # ignore top-level docstring as a doctest.
87
86 88 import sys, os, os.path, stat, glob, new, csv, datetime, types
87 89 import itertools, mimetypes, StringIO
88 90
89 91 try: # Python 2.3 compatibility
90 92 import collections
91 93 except ImportError:
92 94 deque = list
93 95 else:
94 96 deque = collections.deque
95 97
96 98 try: # Python 2.3 compatibility
97 99 set
98 100 except NameError:
99 101 import sets
100 102 set = sets.Set
101 103
102 104 try: # Python 2.3 compatibility
103 105 sorted
104 106 except NameError:
105 107 def sorted(iterator, key=None, reverse=False):
106 108 items = list(iterator)
107 109 if key is not None:
108 110 items.sort(lambda i1, i2: cmp(key(i1), key(i2)))
109 111 else:
110 112 items.sort()
111 113 if reverse:
112 114 items.reverse()
113 115 return items
114 116
115 117 try:
116 118 import pwd
117 119 except ImportError:
118 120 pwd = None
119 121
120 122 try:
121 123 import grp
122 124 except ImportError:
123 125 grp = None
124 126
125 127 from IPython.external import simplegeneric
126
127 import path
128 from IPython.external import path
128 129
129 130 try:
130 131 from IPython import genutils, generics
131 132 except ImportError:
132 133 genutils = None
133 134 generics = None
134 135
135 136 from IPython import ipapi
136 137
137 138
138 139 __all__ = [
139 140 "ifile", "ils", "iglob", "iwalk", "ipwdentry", "ipwd", "igrpentry", "igrp",
140 141 "icsv", "ix", "ichain", "isort", "ifilter", "ieval", "ienum",
141 142 "ienv", "ihist", "ialias", "icap", "idump", "iless"
142 143 ]
143 144
144 145
145 146 os.stat_float_times(True) # enable microseconds
146 147
147 148
148 149 class AttrNamespace(object):
149 150 """
150 151 Helper class that is used for providing a namespace for evaluating
151 152 expressions containing attribute names of an object.
152 153 """
153 154 def __init__(self, wrapped):
154 155 self.wrapped = wrapped
155 156
156 157 def __getitem__(self, name):
157 158 if name == "_":
158 159 return self.wrapped
159 160 try:
160 161 return getattr(self.wrapped, name)
161 162 except AttributeError:
162 163 raise KeyError(name)
163 164
164 165 # Python 2.3 compatibility
165 166 # use eval workaround to find out which names are used in the
166 167 # eval string and put them into the locals. This works for most
167 168 # normal uses case, bizarre ones like accessing the locals()
168 169 # will fail
169 170 try:
170 171 eval("_", None, AttrNamespace(None))
171 172 except TypeError:
172 173 real_eval = eval
173 174 def eval(codestring, _globals, _locals):
174 175 """
175 176 eval(source[, globals[, locals]]) -> value
176 177
177 178 Evaluate the source in the context of globals and locals.
178 179 The source may be a string representing a Python expression
179 180 or a code object as returned by compile().
180 181 The globals must be a dictionary and locals can be any mappping.
181 182
182 183 This function is a workaround for the shortcomings of
183 184 Python 2.3's eval.
184 185 """
185 186
186 187 if isinstance(codestring, basestring):
187 188 code = compile(codestring, "_eval", "eval")
188 189 else:
189 190 code = codestring
190 191 newlocals = {}
191 192 for name in code.co_names:
192 193 try:
193 194 newlocals[name] = _locals[name]
194 195 except KeyError:
195 196 pass
196 197 return real_eval(code, _globals, newlocals)
197 198
198 199
199 200 noitem = object()
200 201
201 202
202 203 def item(iterator, index, default=noitem):
203 204 """
204 205 Return the ``index``th item from the iterator ``iterator``.
205 206 ``index`` must be an integer (negative integers are relative to the
206 207 end (i.e. the last items produced by the iterator)).
207 208
208 209 If ``default`` is given, this will be the default value when
209 210 the iterator doesn't contain an item at this position. Otherwise an
210 211 ``IndexError`` will be raised.
211 212
212 213 Note that using this function will partially or totally exhaust the
213 214 iterator.
214 215 """
215 216 i = index
216 217 if i>=0:
217 218 for item in iterator:
218 219 if not i:
219 220 return item
220 221 i -= 1
221 222 else:
222 223 i = -index
223 224 cache = deque()
224 225 for item in iterator:
225 226 cache.append(item)
226 227 if len(cache)>i:
227 228 cache.popleft()
228 229 if len(cache)==i:
229 230 return cache.popleft()
230 231 if default is noitem:
231 232 raise IndexError(index)
232 233 else:
233 234 return default
234 235
235 236
236 237 def getglobals(g):
237 238 """
238 239 Return the global namespace that is used for expression strings in
239 240 ``ifilter`` and others. This is ``g`` or (if ``g`` is ``None``) IPython's
240 241 user namespace.
241 242 """
242 243 if g is None:
243 244 if ipapi is not None:
244 245 api = ipapi.get()
245 246 if api is not None:
246 247 return api.user_ns
247 248 return globals()
248 249 return g
249 250
250 251
251 252 class Descriptor(object):
252 253 """
253 254 A ``Descriptor`` object is used for describing the attributes of objects.
254 255 """
255 256 def __hash__(self):
256 257 return hash(self.__class__) ^ hash(self.key())
257 258
258 259 def __eq__(self, other):
259 260 return self.__class__ is other.__class__ and self.key() == other.key()
260 261
261 262 def __ne__(self, other):
262 263 return self.__class__ is not other.__class__ or self.key() != other.key()
263 264
264 265 def key(self):
265 266 pass
266 267
267 268 def name(self):
268 269 """
269 270 Return the name of this attribute for display by a ``Display`` object
270 271 (e.g. as a column title).
271 272 """
272 273 key = self.key()
273 274 if key is None:
274 275 return "_"
275 276 return str(key)
276 277
277 278 def attrtype(self, obj):
278 279 """
279 280 Return the type of this attribute (i.e. something like "attribute" or
280 281 "method").
281 282 """
282 283
283 284 def valuetype(self, obj):
284 285 """
285 286 Return the type of this attribute value of the object ``obj``.
286 287 """
287 288
288 289 def value(self, obj):
289 290 """
290 291 Return the value of this attribute of the object ``obj``.
291 292 """
292 293
293 294 def doc(self, obj):
294 295 """
295 296 Return the documentation for this attribute.
296 297 """
297 298
298 299 def shortdoc(self, obj):
299 300 """
300 301 Return a short documentation for this attribute (defaulting to the
301 302 first line).
302 303 """
303 304 doc = self.doc(obj)
304 305 if doc is not None:
305 306 doc = doc.strip().splitlines()[0].strip()
306 307 return doc
307 308
308 309 def iter(self, obj):
309 310 """
310 311 Return an iterator for this attribute of the object ``obj``.
311 312 """
312 313 return xiter(self.value(obj))
313 314
314 315
315 316 class SelfDescriptor(Descriptor):
316 317 """
317 318 A ``SelfDescriptor`` describes the object itself.
318 319 """
319 320 def key(self):
320 321 return None
321 322
322 323 def attrtype(self, obj):
323 324 return "self"
324 325
325 326 def valuetype(self, obj):
326 327 return type(obj)
327 328
328 329 def value(self, obj):
329 330 return obj
330 331
331 332 def __repr__(self):
332 333 return "Self"
333 334
334 335 selfdescriptor = SelfDescriptor() # there's no need for more than one
335 336
336 337
337 338 class AttributeDescriptor(Descriptor):
338 339 """
339 340 An ``AttributeDescriptor`` describes a simple attribute of an object.
340 341 """
341 342 __slots__ = ("_name", "_doc")
342 343
343 344 def __init__(self, name, doc=None):
344 345 self._name = name
345 346 self._doc = doc
346 347
347 348 def key(self):
348 349 return self._name
349 350
350 351 def doc(self, obj):
351 352 return self._doc
352 353
353 354 def attrtype(self, obj):
354 355 return "attr"
355 356
356 357 def valuetype(self, obj):
357 358 return type(getattr(obj, self._name))
358 359
359 360 def value(self, obj):
360 361 return getattr(obj, self._name)
361 362
362 363 def __repr__(self):
363 364 if self._doc is None:
364 365 return "Attribute(%r)" % self._name
365 366 else:
366 367 return "Attribute(%r, %r)" % (self._name, self._doc)
367 368
368 369
369 370 class IndexDescriptor(Descriptor):
370 371 """
371 372 An ``IndexDescriptor`` describes an "attribute" of an object that is fetched
372 373 via ``__getitem__``.
373 374 """
374 375 __slots__ = ("_index",)
375 376
376 377 def __init__(self, index):
377 378 self._index = index
378 379
379 380 def key(self):
380 381 return self._index
381 382
382 383 def attrtype(self, obj):
383 384 return "item"
384 385
385 386 def valuetype(self, obj):
386 387 return type(obj[self._index])
387 388
388 389 def value(self, obj):
389 390 return obj[self._index]
390 391
391 392 def __repr__(self):
392 393 return "Index(%r)" % self._index
393 394
394 395
395 396 class MethodDescriptor(Descriptor):
396 397 """
397 398 A ``MethodDescriptor`` describes a method of an object that can be called
398 399 without argument. Note that this method shouldn't change the object.
399 400 """
400 401 __slots__ = ("_name", "_doc")
401 402
402 403 def __init__(self, name, doc=None):
403 404 self._name = name
404 405 self._doc = doc
405 406
406 407 def key(self):
407 408 return self._name
408 409
409 410 def doc(self, obj):
410 411 if self._doc is None:
411 412 return getattr(obj, self._name).__doc__
412 413 return self._doc
413 414
414 415 def attrtype(self, obj):
415 416 return "method"
416 417
417 418 def valuetype(self, obj):
418 419 return type(self.value(obj))
419 420
420 421 def value(self, obj):
421 422 return getattr(obj, self._name)()
422 423
423 424 def __repr__(self):
424 425 if self._doc is None:
425 426 return "Method(%r)" % self._name
426 427 else:
427 428 return "Method(%r, %r)" % (self._name, self._doc)
428 429
429 430
430 431 class IterAttributeDescriptor(Descriptor):
431 432 """
432 433 An ``IterAttributeDescriptor`` works like an ``AttributeDescriptor`` but
433 434 doesn't return an attribute values (because this value might be e.g. a large
434 435 list).
435 436 """
436 437 __slots__ = ("_name", "_doc")
437 438
438 439 def __init__(self, name, doc=None):
439 440 self._name = name
440 441 self._doc = doc
441 442
442 443 def key(self):
443 444 return self._name
444 445
445 446 def doc(self, obj):
446 447 return self._doc
447 448
448 449 def attrtype(self, obj):
449 450 return "iter"
450 451
451 452 def valuetype(self, obj):
452 453 return noitem
453 454
454 455 def value(self, obj):
455 456 return noitem
456 457
457 458 def iter(self, obj):
458 459 return xiter(getattr(obj, self._name))
459 460
460 461 def __repr__(self):
461 462 if self._doc is None:
462 463 return "IterAttribute(%r)" % self._name
463 464 else:
464 465 return "IterAttribute(%r, %r)" % (self._name, self._doc)
465 466
466 467
467 468 class IterMethodDescriptor(Descriptor):
468 469 """
469 470 An ``IterMethodDescriptor`` works like an ``MethodDescriptor`` but doesn't
470 471 return an attribute values (because this value might be e.g. a large list).
471 472 """
472 473 __slots__ = ("_name", "_doc")
473 474
474 475 def __init__(self, name, doc=None):
475 476 self._name = name
476 477 self._doc = doc
477 478
478 479 def key(self):
479 480 return self._name
480 481
481 482 def doc(self, obj):
482 483 if self._doc is None:
483 484 return getattr(obj, self._name).__doc__
484 485 return self._doc
485 486
486 487 def attrtype(self, obj):
487 488 return "itermethod"
488 489
489 490 def valuetype(self, obj):
490 491 return noitem
491 492
492 493 def value(self, obj):
493 494 return noitem
494 495
495 496 def iter(self, obj):
496 497 return xiter(getattr(obj, self._name)())
497 498
498 499 def __repr__(self):
499 500 if self._doc is None:
500 501 return "IterMethod(%r)" % self._name
501 502 else:
502 503 return "IterMethod(%r, %r)" % (self._name, self._doc)
503 504
504 505
505 506 class FunctionDescriptor(Descriptor):
506 507 """
507 508 A ``FunctionDescriptor`` turns a function into a descriptor. The function
508 509 will be called with the object to get the type and value of the attribute.
509 510 """
510 511 __slots__ = ("_function", "_name", "_doc")
511 512
512 513 def __init__(self, function, name=None, doc=None):
513 514 self._function = function
514 515 self._name = name
515 516 self._doc = doc
516 517
517 518 def key(self):
518 519 return self._function
519 520
520 521 def name(self):
521 522 if self._name is not None:
522 523 return self._name
523 524 return getattr(self._function, "__xname__", self._function.__name__)
524 525
525 526 def doc(self, obj):
526 527 if self._doc is None:
527 528 return self._function.__doc__
528 529 return self._doc
529 530
530 531 def attrtype(self, obj):
531 532 return "function"
532 533
533 534 def valuetype(self, obj):
534 535 return type(self._function(obj))
535 536
536 537 def value(self, obj):
537 538 return self._function(obj)
538 539
539 540 def __repr__(self):
540 541 if self._doc is None:
541 542 return "Function(%r)" % self._name
542 543 else:
543 544 return "Function(%r, %r)" % (self._name, self._doc)
544 545
545 546
546 547 class Table(object):
547 548 """
548 549 A ``Table`` is an object that produces items (just like a normal Python
549 550 iterator/generator does) and can be used as the first object in a pipeline
550 551 expression. The displayhook will open the default browser for such an object
551 552 (instead of simply printing the ``repr()`` result).
552 553 """
553 554
554 555 # We want to support ``foo`` and ``foo()`` in pipeline expression:
555 556 # So we implement the required operators (``|`` and ``+``) in the metaclass,
556 557 # instantiate the class and forward the operator to the instance
557 558 class __metaclass__(type):
558 559 def __iter__(self):
559 560 return iter(self())
560 561
561 562 def __or__(self, other):
562 563 return self() | other
563 564
564 565 def __add__(self, other):
565 566 return self() + other
566 567
567 568 def __radd__(self, other):
568 569 return other + self()
569 570
570 571 def __getitem__(self, index):
571 572 return self()[index]
572 573
573 574 def __getitem__(self, index):
574 575 return item(self, index)
575 576
576 577 def __contains__(self, item):
577 578 for haveitem in self:
578 579 if item == haveitem:
579 580 return True
580 581 return False
581 582
582 583 def __or__(self, other):
583 584 # autoinstantiate right hand side
584 585 if isinstance(other, type) and issubclass(other, (Table, Display)):
585 586 other = other()
586 587 # treat simple strings and functions as ``ieval`` instances
587 588 elif not isinstance(other, Display) and not isinstance(other, Table):
588 589 other = ieval(other)
589 590 # forward operations to the right hand side
590 591 return other.__ror__(self)
591 592
592 593 def __add__(self, other):
593 594 # autoinstantiate right hand side
594 595 if isinstance(other, type) and issubclass(other, Table):
595 596 other = other()
596 597 return ichain(self, other)
597 598
598 599 def __radd__(self, other):
599 600 # autoinstantiate left hand side
600 601 if isinstance(other, type) and issubclass(other, Table):
601 602 other = other()
602 603 return ichain(other, self)
603 604
604 605
605 606 class Pipe(Table):
606 607 """
607 608 A ``Pipe`` is an object that can be used in a pipeline expression. It
608 609 processes the objects it gets from its input ``Table``/``Pipe``. Note that
609 610 a ``Pipe`` object can't be used as the first object in a pipeline
610 611 expression, as it doesn't produces items itself.
611 612 """
612 613 class __metaclass__(Table.__metaclass__):
613 614 def __ror__(self, input):
614 615 return input | self()
615 616
616 617 def __ror__(self, input):
617 618 # autoinstantiate left hand side
618 619 if isinstance(input, type) and issubclass(input, Table):
619 620 input = input()
620 621 self.input = input
621 622 return self
622 623
623 624
624 625 def xrepr(item, mode="default"):
625 626 """
626 627 Generic function that adds color output and different display modes to ``repr``.
627 628
628 629 The result of an ``xrepr`` call is iterable and consists of ``(style, string)``
629 630 tuples. The ``style`` in this tuple must be a ``Style`` object from the
630 631 ``astring`` module. To reconfigure the output the first yielded tuple can be
631 632 a ``(aligment, full)`` tuple instead of a ``(style, string)`` tuple.
632 633 ``alignment`` can be -1 for left aligned, 0 for centered and 1 for right
633 634 aligned (the default is left alignment). ``full`` is a boolean that specifies
634 635 whether the complete output must be displayed or the ``Display`` object is
635 636 allowed to stop output after enough text has been produced (e.g. a syntax
636 637 highlighted text line would use ``True``, but for a large data structure
637 638 (i.e. a nested list, tuple or dictionary) ``False`` would be used).
638 639 The default is full output.
639 640
640 641 There are four different possible values for ``mode`` depending on where
641 642 the ``Display`` object will display ``item``:
642 643
643 644 ``"header"``
644 645 ``item`` will be displayed in a header line (this is used by ``ibrowse``).
645 646
646 647 ``"footer"``
647 648 ``item`` will be displayed in a footer line (this is used by ``ibrowse``).
648 649
649 650 ``"cell"``
650 651 ``item`` will be displayed in a table cell/list.
651 652
652 653 ``"default"``
653 654 default mode. If an ``xrepr`` implementation recursively outputs objects,
654 655 ``"default"`` must be passed in the recursive calls to ``xrepr``.
655 656
656 657 If no implementation is registered for ``item``, ``xrepr`` will try the
657 658 ``__xrepr__`` method on ``item``. If ``item`` doesn't have an ``__xrepr__``
658 659 method it falls back to ``repr``/``__repr__`` for all modes.
659 660 """
660 661 try:
661 662 func = item.__xrepr__
662 663 except AttributeError:
663 664 yield (astyle.style_default, repr(item))
664 665 else:
665 666 try:
666 667 for x in func(mode):
667 668 yield x
668 669 except (KeyboardInterrupt, SystemExit):
669 670 raise
670 671 except Exception:
671 672 yield (astyle.style_default, repr(item))
672 673 xrepr = simplegeneric.generic(xrepr)
673 674
674 675
675 676 def xrepr_none(self, mode="default"):
676 677 yield (astyle.style_type_none, repr(self))
677 678 xrepr.when_object(None)(xrepr_none)
678 679
679 680
680 681 def xrepr_noitem(self, mode="default"):
681 682 yield (2, True)
682 683 yield (astyle.style_nodata, "<?>")
683 684 xrepr.when_object(noitem)(xrepr_noitem)
684 685
685 686
686 687 def xrepr_bool(self, mode="default"):
687 688 yield (astyle.style_type_bool, repr(self))
688 689 xrepr.when_type(bool)(xrepr_bool)
689 690
690 691
691 692 def xrepr_str(self, mode="default"):
692 693 if mode == "cell":
693 694 yield (astyle.style_default, repr(self.expandtabs(tab))[1:-1])
694 695 else:
695 696 yield (astyle.style_default, repr(self))
696 697 xrepr.when_type(str)(xrepr_str)
697 698
698 699
699 700 def xrepr_unicode(self, mode="default"):
700 701 if mode == "cell":
701 702 yield (astyle.style_default, repr(self.expandtabs(tab))[2:-1])
702 703 else:
703 704 yield (astyle.style_default, repr(self))
704 705 xrepr.when_type(unicode)(xrepr_unicode)
705 706
706 707
707 708 def xrepr_number(self, mode="default"):
708 709 yield (1, True)
709 710 yield (astyle.style_type_number, repr(self))
710 711 xrepr.when_type(int)(xrepr_number)
711 712 xrepr.when_type(long)(xrepr_number)
712 713 xrepr.when_type(float)(xrepr_number)
713 714
714 715
715 716 def xrepr_complex(self, mode="default"):
716 717 yield (astyle.style_type_number, repr(self))
717 718 xrepr.when_type(complex)(xrepr_number)
718 719
719 720
720 721 def xrepr_datetime(self, mode="default"):
721 722 if mode == "cell":
722 723 # Don't use strftime() here, as this requires year >= 1900
723 724 yield (astyle.style_type_datetime,
724 725 "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
725 726 (self.year, self.month, self.day,
726 727 self.hour, self.minute, self.second,
727 728 self.microsecond),
728 729 )
729 730 else:
730 731 yield (astyle.style_type_datetime, repr(self))
731 732 xrepr.when_type(datetime.datetime)(xrepr_datetime)
732 733
733 734
734 735 def xrepr_date(self, mode="default"):
735 736 if mode == "cell":
736 737 yield (astyle.style_type_datetime,
737 738 "%04d-%02d-%02d" % (self.year, self.month, self.day))
738 739 else:
739 740 yield (astyle.style_type_datetime, repr(self))
740 741 xrepr.when_type(datetime.date)(xrepr_date)
741 742
742 743
743 744 def xrepr_time(self, mode="default"):
744 745 if mode == "cell":
745 746 yield (astyle.style_type_datetime,
746 747 "%02d:%02d:%02d.%06d" % \
747 748 (self.hour, self.minute, self.second, self.microsecond))
748 749 else:
749 750 yield (astyle.style_type_datetime, repr(self))
750 751 xrepr.when_type(datetime.time)(xrepr_time)
751 752
752 753
753 754 def xrepr_timedelta(self, mode="default"):
754 755 yield (astyle.style_type_datetime, repr(self))
755 756 xrepr.when_type(datetime.timedelta)(xrepr_timedelta)
756 757
757 758
758 759 def xrepr_type(self, mode="default"):
759 760 if self.__module__ == "__builtin__":
760 761 yield (astyle.style_type_type, self.__name__)
761 762 else:
762 763 yield (astyle.style_type_type, "%s.%s" % (self.__module__, self.__name__))
763 764 xrepr.when_type(type)(xrepr_type)
764 765
765 766
766 767 def xrepr_exception(self, mode="default"):
767 768 if self.__class__.__module__ == "exceptions":
768 769 classname = self.__class__.__name__
769 770 else:
770 771 classname = "%s.%s" % \
771 772 (self.__class__.__module__, self.__class__.__name__)
772 773 if mode == "header" or mode == "footer":
773 774 yield (astyle.style_error, "%s: %s" % (classname, self))
774 775 else:
775 776 yield (astyle.style_error, classname)
776 777 xrepr.when_type(Exception)(xrepr_exception)
777 778
778 779
779 780 def xrepr_listtuple(self, mode="default"):
780 781 if mode == "header" or mode == "footer":
781 782 if self.__class__.__module__ == "__builtin__":
782 783 classname = self.__class__.__name__
783 784 else:
784 785 classname = "%s.%s" % \
785 786 (self.__class__.__module__,self.__class__.__name__)
786 787 yield (astyle.style_default,
787 788 "<%s object with %d items at 0x%x>" % \
788 789 (classname, len(self), id(self)))
789 790 else:
790 791 yield (-1, False)
791 792 if isinstance(self, list):
792 793 yield (astyle.style_default, "[")
793 794 end = "]"
794 795 else:
795 796 yield (astyle.style_default, "(")
796 797 end = ")"
797 798 for (i, subself) in enumerate(self):
798 799 if i:
799 800 yield (astyle.style_default, ", ")
800 801 for part in xrepr(subself, "default"):
801 802 yield part
802 803 yield (astyle.style_default, end)
803 804 xrepr.when_type(list)(xrepr_listtuple)
804 805 xrepr.when_type(tuple)(xrepr_listtuple)
805 806
806 807
807 808 def xrepr_dict(self, mode="default"):
808 809 if mode == "header" or mode == "footer":
809 810 if self.__class__.__module__ == "__builtin__":
810 811 classname = self.__class__.__name__
811 812 else:
812 813 classname = "%s.%s" % \
813 814 (self.__class__.__module__,self.__class__.__name__)
814 815 yield (astyle.style_default,
815 816 "<%s object with %d items at 0x%x>" % \
816 817 (classname, len(self), id(self)))
817 818 else:
818 819 yield (-1, False)
819 820 if isinstance(self, dict):
820 821 yield (astyle.style_default, "{")
821 822 end = "}"
822 823 else:
823 824 yield (astyle.style_default, "dictproxy((")
824 825 end = "})"
825 826 for (i, (key, value)) in enumerate(self.iteritems()):
826 827 if i:
827 828 yield (astyle.style_default, ", ")
828 829 for part in xrepr(key, "default"):
829 830 yield part
830 831 yield (astyle.style_default, ": ")
831 832 for part in xrepr(value, "default"):
832 833 yield part
833 834 yield (astyle.style_default, end)
834 835 xrepr.when_type(dict)(xrepr_dict)
835 836 xrepr.when_type(types.DictProxyType)(xrepr_dict)
836 837
837 838
838 839 def upgradexattr(attr):
839 840 """
840 841 Convert an attribute descriptor string to a real descriptor object.
841 842
842 843 If attr already is a descriptor object return if unmodified. A
843 844 ``SelfDescriptor`` will be returned if ``attr`` is ``None``. ``"foo"``
844 845 returns an ``AttributeDescriptor`` for the attribute named ``"foo"``.
845 846 ``"foo()"`` returns a ``MethodDescriptor`` for the method named ``"foo"``.
846 847 ``"-foo"`` will return an ``IterAttributeDescriptor`` for the attribute
847 848 named ``"foo"`` and ``"-foo()"`` will return an ``IterMethodDescriptor``
848 849 for the method named ``"foo"``. Furthermore integer will return the appropriate
849 850 ``IndexDescriptor`` and callables will return a ``FunctionDescriptor``.
850 851 """
851 852 if attr is None:
852 853 return selfdescriptor
853 854 elif isinstance(attr, Descriptor):
854 855 return attr
855 856 elif isinstance(attr, str):
856 857 if attr.endswith("()"):
857 858 if attr.startswith("-"):
858 859 return IterMethodDescriptor(attr[1:-2])
859 860 else:
860 861 return MethodDescriptor(attr[:-2])
861 862 else:
862 863 if attr.startswith("-"):
863 864 return IterAttributeDescriptor(attr[1:])
864 865 else:
865 866 return AttributeDescriptor(attr)
866 867 elif isinstance(attr, (int, long)):
867 868 return IndexDescriptor(attr)
868 869 elif callable(attr):
869 870 return FunctionDescriptor(attr)
870 871 else:
871 872 raise TypeError("can't handle descriptor %r" % attr)
872 873
873 874
874 875 def xattrs(item, mode="default"):
875 876 """
876 877 Generic function that returns an iterable of attribute descriptors
877 878 to be used for displaying the attributes ob the object ``item`` in display
878 879 mode ``mode``.
879 880
880 881 There are two possible modes:
881 882
882 883 ``"detail"``
883 884 The ``Display`` object wants to display a detailed list of the object
884 885 attributes.
885 886
886 887 ``"default"``
887 888 The ``Display`` object wants to display the object in a list view.
888 889
889 890 If no implementation is registered for the object ``item`` ``xattrs`` falls
890 891 back to trying the ``__xattrs__`` method of the object. If this doesn't
891 892 exist either, ``dir(item)`` is used for ``"detail"`` mode and ``(None,)``
892 893 for ``"default"`` mode.
893 894
894 895 The implementation must yield attribute descriptors (see the class
895 896 ``Descriptor`` for more info). The ``__xattrs__`` method may also return
896 897 attribute descriptor strings (and ``None``) which will be converted to real
897 898 descriptors by ``upgradexattr()``.
898 899 """
899 900 try:
900 901 func = item.__xattrs__
901 902 except AttributeError:
902 903 if mode == "detail":
903 904 for attrname in dir(item):
904 905 yield AttributeDescriptor(attrname)
905 906 else:
906 907 yield selfdescriptor
907 908 else:
908 909 for attr in func(mode):
909 910 yield upgradexattr(attr)
910 911 xattrs = simplegeneric.generic(xattrs)
911 912
912 913
913 914 def xattrs_complex(self, mode="default"):
914 915 if mode == "detail":
915 916 return (AttributeDescriptor("real"), AttributeDescriptor("imag"))
916 917 return (selfdescriptor,)
917 918 xattrs.when_type(complex)(xattrs_complex)
918 919
919 920
920 921 def _isdict(item):
921 922 try:
922 923 itermeth = item.__class__.__iter__
923 924 except (AttributeError, TypeError):
924 925 return False
925 926 return itermeth is dict.__iter__ or itermeth is types.DictProxyType.__iter__
926 927
927 928
928 929 def _isstr(item):
929 930 if not isinstance(item, basestring):
930 931 return False
931 932 try:
932 933 itermeth = item.__class__.__iter__
933 934 except AttributeError:
934 935 return True
935 936 return False # ``__iter__`` has been redefined
936 937
937 938
938 939 def xiter(item):
939 940 """
940 941 Generic function that implements iteration for pipeline expression. If no
941 942 implementation is registered for ``item`` ``xiter`` falls back to ``iter``.
942 943 """
943 944 try:
944 945 func = item.__xiter__
945 946 except AttributeError:
946 947 if _isdict(item):
947 948 def items(item):
948 949 fields = ("key", "value")
949 950 for (key, value) in item.iteritems():
950 951 yield Fields(fields, key=key, value=value)
951 952 return items(item)
952 953 elif isinstance(item, new.module):
953 954 def items(item):
954 955 fields = ("key", "value")
955 956 for key in sorted(item.__dict__):
956 957 yield Fields(fields, key=key, value=getattr(item, key))
957 958 return items(item)
958 959 elif _isstr(item):
959 960 if not item:
960 961 raise ValueError("can't enter empty string")
961 962 lines = item.splitlines()
962 963 if len(lines) == 1:
963 964 def iterone(item):
964 965 yield item
965 966 return iterone(item)
966 967 else:
967 968 return iter(lines)
968 969 return iter(item)
969 970 else:
970 971 return iter(func()) # iter() just to be safe
971 972 xiter = simplegeneric.generic(xiter)
972 973
973 974
974 975 class ichain(Pipe):
975 976 """
976 977 Chains multiple ``Table``s into one.
977 978 """
978 979
979 980 def __init__(self, *iters):
980 981 self.iters = iters
981 982
982 983 def __iter__(self):
983 984 return itertools.chain(*self.iters)
984 985
985 986 def __xrepr__(self, mode="default"):
986 987 if mode == "header" or mode == "footer":
987 988 for (i, item) in enumerate(self.iters):
988 989 if i:
989 990 yield (astyle.style_default, "+")
990 991 if isinstance(item, Pipe):
991 992 yield (astyle.style_default, "(")
992 993 for part in xrepr(item, mode):
993 994 yield part
994 995 if isinstance(item, Pipe):
995 996 yield (astyle.style_default, ")")
996 997 else:
997 998 yield (astyle.style_default, repr(self))
998 999
999 1000 def __repr__(self):
1000 1001 args = ", ".join([repr(it) for it in self.iters])
1001 1002 return "%s.%s(%s)" % \
1002 1003 (self.__class__.__module__, self.__class__.__name__, args)
1003 1004
1004 1005
1005 1006 class ifile(path.path):
1006 1007 """
1007 1008 file (or directory) object.
1008 1009 """
1009 1010
1010 1011 def getmode(self):
1011 1012 return self.stat().st_mode
1012 1013 mode = property(getmode, None, None, "Access mode")
1013 1014
1014 1015 def gettype(self):
1015 1016 data = [
1016 1017 (stat.S_ISREG, "file"),
1017 1018 (stat.S_ISDIR, "dir"),
1018 1019 (stat.S_ISCHR, "chardev"),
1019 1020 (stat.S_ISBLK, "blockdev"),
1020 1021 (stat.S_ISFIFO, "fifo"),
1021 1022 (stat.S_ISLNK, "symlink"),
1022 1023 (stat.S_ISSOCK,"socket"),
1023 1024 ]
1024 1025 lstat = self.lstat()
1025 1026 if lstat is not None:
1026 1027 types = set([text for (func, text) in data if func(lstat.st_mode)])
1027 1028 else:
1028 1029 types = set()
1029 1030 m = self.mode
1030 1031 types.update([text for (func, text) in data if func(m)])
1031 1032 return ", ".join(types)
1032 1033 type = property(gettype, None, None, "file type (file, directory, link, etc.)")
1033 1034
1034 1035 def getmodestr(self):
1035 1036 m = self.mode
1036 1037 data = [
1037 1038 (stat.S_IRUSR, "-r"),
1038 1039 (stat.S_IWUSR, "-w"),
1039 1040 (stat.S_IXUSR, "-x"),
1040 1041 (stat.S_IRGRP, "-r"),
1041 1042 (stat.S_IWGRP, "-w"),
1042 1043 (stat.S_IXGRP, "-x"),
1043 1044 (stat.S_IROTH, "-r"),
1044 1045 (stat.S_IWOTH, "-w"),
1045 1046 (stat.S_IXOTH, "-x"),
1046 1047 ]
1047 1048 return "".join([text[bool(m&bit)] for (bit, text) in data])
1048 1049
1049 1050 modestr = property(getmodestr, None, None, "Access mode as string")
1050 1051
1051 1052 def getblocks(self):
1052 1053 return self.stat().st_blocks
1053 1054 blocks = property(getblocks, None, None, "File size in blocks")
1054 1055
1055 1056 def getblksize(self):
1056 1057 return self.stat().st_blksize
1057 1058 blksize = property(getblksize, None, None, "Filesystem block size")
1058 1059
1059 1060 def getdev(self):
1060 1061 return self.stat().st_dev
1061 1062 dev = property(getdev)
1062 1063
1063 1064 def getnlink(self):
1064 1065 return self.stat().st_nlink
1065 1066 nlink = property(getnlink, None, None, "Number of links")
1066 1067
1067 1068 def getuid(self):
1068 1069 return self.stat().st_uid
1069 1070 uid = property(getuid, None, None, "User id of file owner")
1070 1071
1071 1072 def getgid(self):
1072 1073 return self.stat().st_gid
1073 1074 gid = property(getgid, None, None, "Group id of file owner")
1074 1075
1075 1076 def getowner(self):
1076 1077 stat = self.stat()
1077 1078 try:
1078 1079 return pwd.getpwuid(stat.st_uid).pw_name
1079 1080 except KeyError:
1080 1081 return stat.st_uid
1081 1082 owner = property(getowner, None, None, "Owner name (or id)")
1082 1083
1083 1084 def getgroup(self):
1084 1085 stat = self.stat()
1085 1086 try:
1086 1087 return grp.getgrgid(stat.st_gid).gr_name
1087 1088 except KeyError:
1088 1089 return stat.st_gid
1089 1090 group = property(getgroup, None, None, "Group name (or id)")
1090 1091
1091 1092 def getadate(self):
1092 1093 return datetime.datetime.utcfromtimestamp(self.atime)
1093 1094 adate = property(getadate, None, None, "Access date")
1094 1095
1095 1096 def getcdate(self):
1096 1097 return datetime.datetime.utcfromtimestamp(self.ctime)
1097 1098 cdate = property(getcdate, None, None, "Creation date")
1098 1099
1099 1100 def getmdate(self):
1100 1101 return datetime.datetime.utcfromtimestamp(self.mtime)
1101 1102 mdate = property(getmdate, None, None, "Modification date")
1102 1103
1103 1104 def mimetype(self):
1104 1105 """
1105 1106 Return MIME type guessed from the extension.
1106 1107 """
1107 1108 return mimetypes.guess_type(self.basename())[0]
1108 1109
1109 1110 def encoding(self):
1110 1111 """
1111 1112 Return guessed compression (like "compress" or "gzip").
1112 1113 """
1113 1114 return mimetypes.guess_type(self.basename())[1]
1114 1115
1115 1116 def __repr__(self):
1116 1117 return "ifile(%s)" % path._base.__repr__(self)
1117 1118
1118 1119 if sys.platform == "win32":
1119 1120 defaultattrs = (None, "type", "size", "modestr", "mdate")
1120 1121 else:
1121 1122 defaultattrs = (None, "type", "size", "modestr", "owner", "group", "mdate")
1122 1123
1123 1124 def __xattrs__(self, mode="default"):
1124 1125 if mode == "detail":
1125 1126 return (
1126 1127 "name",
1127 1128 "basename()",
1128 1129 "abspath()",
1129 1130 "realpath()",
1130 1131 "type",
1131 1132 "mode",
1132 1133 "modestr",
1133 1134 "stat()",
1134 1135 "lstat()",
1135 1136 "uid",
1136 1137 "gid",
1137 1138 "owner",
1138 1139 "group",
1139 1140 "dev",
1140 1141 "nlink",
1141 1142 "ctime",
1142 1143 "mtime",
1143 1144 "atime",
1144 1145 "cdate",
1145 1146 "mdate",
1146 1147 "adate",
1147 1148 "size",
1148 1149 "blocks",
1149 1150 "blksize",
1150 1151 "isdir()",
1151 1152 "islink()",
1152 1153 "mimetype()",
1153 1154 "encoding()",
1154 1155 "-listdir()",
1155 1156 "-dirs()",
1156 1157 "-files()",
1157 1158 "-walk()",
1158 1159 "-walkdirs()",
1159 1160 "-walkfiles()",
1160 1161 )
1161 1162 else:
1162 1163 return self.defaultattrs
1163 1164
1164 1165
1165 1166 def xiter_ifile(self):
1166 1167 if self.isdir():
1167 1168 yield (self / os.pardir).abspath()
1168 1169 for child in sorted(self.listdir()):
1169 1170 yield child
1170 1171 else:
1171 1172 f = self.open("rb")
1172 1173 for line in f:
1173 1174 yield line
1174 1175 f.close()
1175 1176 xiter.when_type(ifile)(xiter_ifile)
1176 1177
1177 1178
1178 1179 # We need to implement ``xrepr`` for ``ifile`` as a generic function, because
1179 1180 # otherwise ``xrepr_str`` would kick in.
1180 1181 def xrepr_ifile(self, mode="default"):
1181 1182 try:
1182 1183 if self.isdir():
1183 1184 name = "idir"
1184 1185 style = astyle.style_dir
1185 1186 else:
1186 1187 name = "ifile"
1187 1188 style = astyle.style_file
1188 1189 except IOError:
1189 1190 name = "ifile"
1190 1191 style = astyle.style_default
1191 1192 if mode in ("cell", "header", "footer"):
1192 1193 abspath = repr(path._base(self.normpath()))
1193 1194 if abspath.startswith("u"):
1194 1195 abspath = abspath[2:-1]
1195 1196 else:
1196 1197 abspath = abspath[1:-1]
1197 1198 if mode == "cell":
1198 1199 yield (style, abspath)
1199 1200 else:
1200 1201 yield (style, "%s(%s)" % (name, abspath))
1201 1202 else:
1202 1203 yield (style, repr(self))
1203 1204 xrepr.when_type(ifile)(xrepr_ifile)
1204 1205
1205 1206
1206 1207 class ils(Table):
1207 1208 """
1208 1209 List the current (or a specified) directory.
1209 1210
1210 1211 Examples::
1211 1212
1212 1213 >>> ils
1214 <class 'IPython.Extensions.ipipe.ils'>
1213 1215 >>> ils("/usr/local/lib/python2.4")
1216 IPython.Extensions.ipipe.ils('/usr/local/lib/python2.4')
1214 1217 >>> ils("~")
1218 IPython.Extensions.ipipe.ils('/home/fperez')
1219 # all-random
1215 1220 """
1216 1221 def __init__(self, base=os.curdir, dirs=True, files=True):
1217 1222 self.base = os.path.expanduser(base)
1218 1223 self.dirs = dirs
1219 1224 self.files = files
1220 1225
1221 1226 def __iter__(self):
1222 1227 base = ifile(self.base)
1223 1228 yield (base / os.pardir).abspath()
1224 1229 for child in sorted(base.listdir()):
1225 1230 if self.dirs:
1226 1231 if self.files:
1227 1232 yield child
1228 1233 else:
1229 1234 if child.isdir():
1230 1235 yield child
1231 1236 elif self.files:
1232 1237 if not child.isdir():
1233 1238 yield child
1234 1239
1235 1240 def __xrepr__(self, mode="default"):
1236 1241 return xrepr(ifile(self.base), mode)
1237 1242
1238 1243 def __repr__(self):
1239 1244 return "%s.%s(%r)" % \
1240 1245 (self.__class__.__module__, self.__class__.__name__, self.base)
1241 1246
1242 1247
1243 1248 class iglob(Table):
1244 1249 """
1245 1250 List all files and directories matching a specified pattern.
1246 1251 (See ``glob.glob()`` for more info.).
1247 1252
1248 1253 Examples::
1249 1254
1250 1255 >>> iglob("*.py")
1256 IPython.Extensions.ipipe.iglob('*.py')
1251 1257 """
1252 1258 def __init__(self, glob):
1253 1259 self.glob = glob
1254 1260
1255 1261 def __iter__(self):
1256 1262 for name in glob.glob(self.glob):
1257 1263 yield ifile(name)
1258 1264
1259 1265 def __xrepr__(self, mode="default"):
1260 1266 if mode == "header" or mode == "footer" or mode == "cell":
1261 1267 yield (astyle.style_default,
1262 1268 "%s(%r)" % (self.__class__.__name__, self.glob))
1263 1269 else:
1264 1270 yield (astyle.style_default, repr(self))
1265 1271
1266 1272 def __repr__(self):
1267 1273 return "%s.%s(%r)" % \
1268 1274 (self.__class__.__module__, self.__class__.__name__, self.glob)
1269 1275
1270 1276
1271 1277 class iwalk(Table):
1272 1278 """
1273 1279 List all files and directories in a directory and it's subdirectory::
1274 1280
1275 1281 >>> iwalk
1276 >>> iwalk("/usr/local/lib/python2.4")
1282 <class 'IPython.Extensions.ipipe.iwalk'>
1283 >>> iwalk("/usr/lib")
1284 IPython.Extensions.ipipe.iwalk('/usr/lib')
1277 1285 >>> iwalk("~")
1286 IPython.Extensions.ipipe.iwalk('/home/fperez') # random
1287
1278 1288 """
1279 1289 def __init__(self, base=os.curdir, dirs=True, files=True):
1280 1290 self.base = os.path.expanduser(base)
1281 1291 self.dirs = dirs
1282 1292 self.files = files
1283 1293
1284 1294 def __iter__(self):
1285 1295 for (dirpath, dirnames, filenames) in os.walk(self.base):
1286 1296 if self.dirs:
1287 1297 for name in sorted(dirnames):
1288 1298 yield ifile(os.path.join(dirpath, name))
1289 1299 if self.files:
1290 1300 for name in sorted(filenames):
1291 1301 yield ifile(os.path.join(dirpath, name))
1292 1302
1293 1303 def __xrepr__(self, mode="default"):
1294 1304 if mode == "header" or mode == "footer" or mode == "cell":
1295 1305 yield (astyle.style_default,
1296 1306 "%s(%r)" % (self.__class__.__name__, self.base))
1297 1307 else:
1298 1308 yield (astyle.style_default, repr(self))
1299 1309
1300 1310 def __repr__(self):
1301 1311 return "%s.%s(%r)" % \
1302 1312 (self.__class__.__module__, self.__class__.__name__, self.base)
1303 1313
1304 1314
1305 1315 class ipwdentry(object):
1306 1316 """
1307 1317 ``ipwdentry`` objects encapsulate entries in the Unix user account and
1308 1318 password database.
1309 1319 """
1310 1320 def __init__(self, id):
1311 1321 self._id = id
1312 1322 self._entry = None
1313 1323
1314 1324 def __eq__(self, other):
1315 1325 return self.__class__ is other.__class__ and self._id == other._id
1316 1326
1317 1327 def __ne__(self, other):
1318 1328 return self.__class__ is not other.__class__ or self._id != other._id
1319 1329
1320 1330 def _getentry(self):
1321 1331 if self._entry is None:
1322 1332 if isinstance(self._id, basestring):
1323 1333 self._entry = pwd.getpwnam(self._id)
1324 1334 else:
1325 1335 self._entry = pwd.getpwuid(self._id)
1326 1336 return self._entry
1327 1337
1328 1338 def getname(self):
1329 1339 if isinstance(self._id, basestring):
1330 1340 return self._id
1331 1341 else:
1332 1342 return self._getentry().pw_name
1333 1343 name = property(getname, None, None, "User name")
1334 1344
1335 1345 def getpasswd(self):
1336 1346 return self._getentry().pw_passwd
1337 1347 passwd = property(getpasswd, None, None, "Password")
1338 1348
1339 1349 def getuid(self):
1340 1350 if isinstance(self._id, basestring):
1341 1351 return self._getentry().pw_uid
1342 1352 else:
1343 1353 return self._id
1344 1354 uid = property(getuid, None, None, "User id")
1345 1355
1346 1356 def getgid(self):
1347 1357 return self._getentry().pw_gid
1348 1358 gid = property(getgid, None, None, "Primary group id")
1349 1359
1350 1360 def getgroup(self):
1351 1361 return igrpentry(self.gid)
1352 1362 group = property(getgroup, None, None, "Group")
1353 1363
1354 1364 def getgecos(self):
1355 1365 return self._getentry().pw_gecos
1356 1366 gecos = property(getgecos, None, None, "Information (e.g. full user name)")
1357 1367
1358 1368 def getdir(self):
1359 1369 return self._getentry().pw_dir
1360 1370 dir = property(getdir, None, None, "$HOME directory")
1361 1371
1362 1372 def getshell(self):
1363 1373 return self._getentry().pw_shell
1364 1374 shell = property(getshell, None, None, "Login shell")
1365 1375
1366 1376 def __xattrs__(self, mode="default"):
1367 1377 return ("name", "passwd", "uid", "gid", "gecos", "dir", "shell")
1368 1378
1369 1379 def __repr__(self):
1370 1380 return "%s.%s(%r)" % \
1371 1381 (self.__class__.__module__, self.__class__.__name__, self._id)
1372 1382
1373 1383
1374 1384 class ipwd(Table):
1375 1385 """
1376 1386 List all entries in the Unix user account and password database.
1377 1387
1378 1388 Example::
1379 1389
1380 1390 >>> ipwd | isort("uid")
1391 <IPython.Extensions.ipipe.isort key='uid' reverse=False at 0x849efec>
1392 # random
1381 1393 """
1382 1394 def __iter__(self):
1383 1395 for entry in pwd.getpwall():
1384 1396 yield ipwdentry(entry.pw_name)
1385 1397
1386 1398 def __xrepr__(self, mode="default"):
1387 1399 if mode == "header" or mode == "footer" or mode == "cell":
1388 1400 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1389 1401 else:
1390 1402 yield (astyle.style_default, repr(self))
1391 1403
1392 1404
1393 1405 class igrpentry(object):
1394 1406 """
1395 1407 ``igrpentry`` objects encapsulate entries in the Unix group database.
1396 1408 """
1397 1409 def __init__(self, id):
1398 1410 self._id = id
1399 1411 self._entry = None
1400 1412
1401 1413 def __eq__(self, other):
1402 1414 return self.__class__ is other.__class__ and self._id == other._id
1403 1415
1404 1416 def __ne__(self, other):
1405 1417 return self.__class__ is not other.__class__ or self._id != other._id
1406 1418
1407 1419 def _getentry(self):
1408 1420 if self._entry is None:
1409 1421 if isinstance(self._id, basestring):
1410 1422 self._entry = grp.getgrnam(self._id)
1411 1423 else:
1412 1424 self._entry = grp.getgrgid(self._id)
1413 1425 return self._entry
1414 1426
1415 1427 def getname(self):
1416 1428 if isinstance(self._id, basestring):
1417 1429 return self._id
1418 1430 else:
1419 1431 return self._getentry().gr_name
1420 1432 name = property(getname, None, None, "Group name")
1421 1433
1422 1434 def getpasswd(self):
1423 1435 return self._getentry().gr_passwd
1424 1436 passwd = property(getpasswd, None, None, "Password")
1425 1437
1426 1438 def getgid(self):
1427 1439 if isinstance(self._id, basestring):
1428 1440 return self._getentry().gr_gid
1429 1441 else:
1430 1442 return self._id
1431 1443 gid = property(getgid, None, None, "Group id")
1432 1444
1433 1445 def getmem(self):
1434 1446 return self._getentry().gr_mem
1435 1447 mem = property(getmem, None, None, "Members")
1436 1448
1437 1449 def __xattrs__(self, mode="default"):
1438 1450 return ("name", "passwd", "gid", "mem")
1439 1451
1440 1452 def __xrepr__(self, mode="default"):
1441 1453 if mode == "header" or mode == "footer" or mode == "cell":
1442 1454 yield (astyle.style_default, "group ")
1443 1455 try:
1444 1456 yield (astyle.style_default, self.name)
1445 1457 except KeyError:
1446 1458 if isinstance(self._id, basestring):
1447 1459 yield (astyle.style_default, self.name_id)
1448 1460 else:
1449 1461 yield (astyle.style_type_number, str(self._id))
1450 1462 else:
1451 1463 yield (astyle.style_default, repr(self))
1452 1464
1453 1465 def __iter__(self):
1454 1466 for member in self.mem:
1455 1467 yield ipwdentry(member)
1456 1468
1457 1469 def __repr__(self):
1458 1470 return "%s.%s(%r)" % \
1459 1471 (self.__class__.__module__, self.__class__.__name__, self._id)
1460 1472
1461 1473
1462 1474 class igrp(Table):
1463 1475 """
1464 1476 This ``Table`` lists all entries in the Unix group database.
1465 1477 """
1466 1478 def __iter__(self):
1467 1479 for entry in grp.getgrall():
1468 1480 yield igrpentry(entry.gr_name)
1469 1481
1470 1482 def __xrepr__(self, mode="default"):
1471 1483 if mode == "header" or mode == "footer":
1472 1484 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1473 1485 else:
1474 1486 yield (astyle.style_default, repr(self))
1475 1487
1476 1488
1477 1489 class Fields(object):
1478 1490 def __init__(self, fieldnames, **fields):
1479 1491 self.__fieldnames = [upgradexattr(fieldname) for fieldname in fieldnames]
1480 1492 for (key, value) in fields.iteritems():
1481 1493 setattr(self, key, value)
1482 1494
1483 1495 def __xattrs__(self, mode="default"):
1484 1496 return self.__fieldnames
1485 1497
1486 1498 def __xrepr__(self, mode="default"):
1487 1499 yield (-1, False)
1488 1500 if mode == "header" or mode == "cell":
1489 1501 yield (astyle.style_default, self.__class__.__name__)
1490 1502 yield (astyle.style_default, "(")
1491 1503 for (i, f) in enumerate(self.__fieldnames):
1492 1504 if i:
1493 1505 yield (astyle.style_default, ", ")
1494 1506 yield (astyle.style_default, f.name())
1495 1507 yield (astyle.style_default, "=")
1496 1508 for part in xrepr(getattr(self, f), "default"):
1497 1509 yield part
1498 1510 yield (astyle.style_default, ")")
1499 1511 elif mode == "footer":
1500 1512 yield (astyle.style_default, self.__class__.__name__)
1501 1513 yield (astyle.style_default, "(")
1502 1514 for (i, f) in enumerate(self.__fieldnames):
1503 1515 if i:
1504 1516 yield (astyle.style_default, ", ")
1505 1517 yield (astyle.style_default, f.name())
1506 1518 yield (astyle.style_default, ")")
1507 1519 else:
1508 1520 yield (astyle.style_default, repr(self))
1509 1521
1510 1522
1511 1523 class FieldTable(Table, list):
1512 1524 def __init__(self, *fields):
1513 1525 Table.__init__(self)
1514 1526 list.__init__(self)
1515 1527 self.fields = fields
1516 1528
1517 1529 def add(self, **fields):
1518 1530 self.append(Fields(self.fields, **fields))
1519 1531
1520 1532 def __xrepr__(self, mode="default"):
1521 1533 yield (-1, False)
1522 1534 if mode == "header" or mode == "footer":
1523 1535 yield (astyle.style_default, self.__class__.__name__)
1524 1536 yield (astyle.style_default, "(")
1525 1537 for (i, f) in enumerate(self.__fieldnames):
1526 1538 if i:
1527 1539 yield (astyle.style_default, ", ")
1528 1540 yield (astyle.style_default, f)
1529 1541 yield (astyle.style_default, ")")
1530 1542 else:
1531 1543 yield (astyle.style_default, repr(self))
1532 1544
1533 1545 def __repr__(self):
1534 1546 return "<%s.%s object with fields=%r at 0x%x>" % \
1535 1547 (self.__class__.__module__, self.__class__.__name__,
1536 1548 ", ".join(map(repr, self.fields)), id(self))
1537 1549
1538 1550
1539 1551 class List(list):
1540 1552 def __xattrs__(self, mode="default"):
1541 1553 return xrange(len(self))
1542 1554
1543 1555 def __xrepr__(self, mode="default"):
1544 1556 yield (-1, False)
1545 1557 if mode == "header" or mode == "cell" or mode == "footer" or mode == "default":
1546 1558 yield (astyle.style_default, self.__class__.__name__)
1547 1559 yield (astyle.style_default, "(")
1548 1560 for (i, item) in enumerate(self):
1549 1561 if i:
1550 1562 yield (astyle.style_default, ", ")
1551 1563 for part in xrepr(item, "default"):
1552 1564 yield part
1553 1565 yield (astyle.style_default, ")")
1554 1566 else:
1555 1567 yield (astyle.style_default, repr(self))
1556 1568
1557 1569
1558 1570 class ienv(Table):
1559 1571 """
1560 1572 List environment variables.
1561 1573
1562 1574 Example::
1563 1575
1564 1576 >>> ienv
1577 <class 'IPython.Extensions.ipipe.ienv'>
1565 1578 """
1566 1579
1567 1580 def __iter__(self):
1568 1581 fields = ("key", "value")
1569 1582 for (key, value) in os.environ.iteritems():
1570 1583 yield Fields(fields, key=key, value=value)
1571 1584
1572 1585 def __xrepr__(self, mode="default"):
1573 1586 if mode == "header" or mode == "cell":
1574 1587 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1575 1588 else:
1576 1589 yield (astyle.style_default, repr(self))
1577 1590
1578 1591
1579 1592 class ihist(Table):
1580 1593 """
1581 1594 IPython input history
1582 1595
1583 1596 Example::
1584 1597
1585 1598 >>> ihist
1586 >>> ihist(True) (raw mode)
1599 <class 'IPython.Extensions.ipipe.ihist'>
1600 >>> ihist(True) # raw mode
1601 <IPython.Extensions.ipipe.ihist object at 0x849602c> # random
1587 1602 """
1588 1603 def __init__(self, raw=True):
1589 1604 self.raw = raw
1590 1605
1591 1606 def __iter__(self):
1592 1607 api = ipapi.get()
1593 1608 if self.raw:
1594 1609 for line in api.IP.input_hist_raw:
1595 1610 yield line.rstrip("\n")
1596 1611 else:
1597 1612 for line in api.IP.input_hist:
1598 1613 yield line.rstrip("\n")
1599 1614
1600 1615
1601 1616 class Alias(object):
1602 1617 """
1603 1618 Entry in the alias table
1604 1619 """
1605 1620 def __init__(self, name, args, command):
1606 1621 self.name = name
1607 1622 self.args = args
1608 1623 self.command = command
1609 1624
1610 1625 def __xattrs__(self, mode="default"):
1611 1626 return ("name", "args", "command")
1612 1627
1613 1628
1614 1629 class ialias(Table):
1615 1630 """
1616 1631 IPython alias list
1617 1632
1618 1633 Example::
1619 1634
1620 1635 >>> ialias
1636 <class 'IPython.Extensions.ipipe.ialias'>
1621 1637 """
1622 1638 def __iter__(self):
1623 1639 api = ipapi.get()
1624 1640
1625 1641 for (name, (args, command)) in api.IP.alias_table.iteritems():
1626 1642 yield Alias(name, args, command)
1627 1643
1628 1644
1629 1645 class icsv(Pipe):
1630 1646 """
1631 1647 This ``Pipe`` turns the input (with must be a pipe outputting lines
1632 1648 or an ``ifile``) into lines of CVS columns.
1633 1649 """
1634 1650 def __init__(self, **csvargs):
1635 1651 """
1636 1652 Create an ``icsv`` object. ``cvsargs`` will be passed through as
1637 1653 keyword arguments to ``cvs.reader()``.
1638 1654 """
1639 1655 self.csvargs = csvargs
1640 1656
1641 1657 def __iter__(self):
1642 1658 input = self.input
1643 1659 if isinstance(input, ifile):
1644 1660 input = input.open("rb")
1645 1661 reader = csv.reader(input, **self.csvargs)
1646 1662 for line in reader:
1647 1663 yield List(line)
1648 1664
1649 1665 def __xrepr__(self, mode="default"):
1650 1666 yield (-1, False)
1651 1667 if mode == "header" or mode == "footer":
1652 1668 input = getattr(self, "input", None)
1653 1669 if input is not None:
1654 1670 for part in xrepr(input, mode):
1655 1671 yield part
1656 1672 yield (astyle.style_default, " | ")
1657 1673 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1658 1674 for (i, (name, value)) in enumerate(self.csvargs.iteritems()):
1659 1675 if i:
1660 1676 yield (astyle.style_default, ", ")
1661 1677 yield (astyle.style_default, name)
1662 1678 yield (astyle.style_default, "=")
1663 1679 for part in xrepr(value, "default"):
1664 1680 yield part
1665 1681 yield (astyle.style_default, ")")
1666 1682 else:
1667 1683 yield (astyle.style_default, repr(self))
1668 1684
1669 1685 def __repr__(self):
1670 1686 args = ", ".join(["%s=%r" % item for item in self.csvargs.iteritems()])
1671 1687 return "<%s.%s %s at 0x%x>" % \
1672 1688 (self.__class__.__module__, self.__class__.__name__, args, id(self))
1673 1689
1674 1690
1675 1691 class ix(Table):
1676 1692 """
1677 1693 Execute a system command and list its output as lines
1678 1694 (similar to ``os.popen()``).
1679 1695
1680 1696 Examples::
1681 1697
1682 1698 >>> ix("ps x")
1699 IPython.Extensions.ipipe.ix('ps x')
1700
1683 1701 >>> ix("find .") | ifile
1702 <IPython.Extensions.ipipe.ieval expr=<class 'IPython.Extensions.ipipe.ifile'> at 0x8509d2c>
1703 # random
1684 1704 """
1685 1705 def __init__(self, cmd):
1686 1706 self.cmd = cmd
1687 1707 self._pipeout = None
1688 1708
1689 1709 def __iter__(self):
1690 1710 (_pipein, self._pipeout) = os.popen4(self.cmd)
1691 1711 _pipein.close()
1692 1712 for l in self._pipeout:
1693 1713 yield l.rstrip("\r\n")
1694 1714 self._pipeout.close()
1695 1715 self._pipeout = None
1696 1716
1697 1717 def __del__(self):
1698 1718 if self._pipeout is not None and not self._pipeout.closed:
1699 1719 self._pipeout.close()
1700 1720 self._pipeout = None
1701 1721
1702 1722 def __xrepr__(self, mode="default"):
1703 1723 if mode == "header" or mode == "footer":
1704 1724 yield (astyle.style_default,
1705 1725 "%s(%r)" % (self.__class__.__name__, self.cmd))
1706 1726 else:
1707 1727 yield (astyle.style_default, repr(self))
1708 1728
1709 1729 def __repr__(self):
1710 1730 return "%s.%s(%r)" % \
1711 1731 (self.__class__.__module__, self.__class__.__name__, self.cmd)
1712 1732
1713 1733
1714 1734 class ifilter(Pipe):
1715 1735 """
1716 1736 Filter an input pipe. Only objects where an expression evaluates to true
1717 1737 (and doesn't raise an exception) are listed.
1718 1738
1719 1739 Examples::
1720 1740
1721 1741 >>> ils | ifilter("_.isfile() and size>1000")
1722 1742 >>> igrp | ifilter("len(mem)")
1723 1743 >>> sys.modules | ifilter(lambda _:_.value is not None)
1744 # all-random
1724 1745 """
1725 1746
1726 1747 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1727 1748 """
1728 1749 Create an ``ifilter`` object. ``expr`` can be a callable or a string
1729 1750 containing an expression. ``globals`` will be used as the global
1730 1751 namespace for calling string expressions (defaulting to IPython's
1731 1752 user namespace). ``errors`` specifies how exception during evaluation
1732 1753 of ``expr`` are handled:
1733 1754
1734 1755 ``"drop"``
1735 1756 drop all items that have errors;
1736 1757
1737 1758 ``"keep"``
1738 1759 keep all items that have errors;
1739 1760
1740 1761 ``"keeperror"``
1741 1762 keep the exception of all items that have errors;
1742 1763
1743 1764 ``"raise"``
1744 1765 raise the exception;
1745 1766
1746 1767 ``"raiseifallfail"``
1747 1768 raise the first exception if all items have errors; otherwise drop
1748 1769 those with errors (this is the default).
1749 1770 """
1750 1771 self.expr = expr
1751 1772 self.globals = globals
1752 1773 self.errors = errors
1753 1774
1754 1775 def __iter__(self):
1755 1776 if callable(self.expr):
1756 1777 test = self.expr
1757 1778 else:
1758 1779 g = getglobals(self.globals)
1759 1780 expr = compile(self.expr, "ipipe-expression", "eval")
1760 1781 def test(item):
1761 1782 return eval(expr, g, AttrNamespace(item))
1762 1783
1763 1784 ok = 0
1764 1785 exc_info = None
1765 1786 for item in xiter(self.input):
1766 1787 try:
1767 1788 if test(item):
1768 1789 yield item
1769 1790 ok += 1
1770 1791 except (KeyboardInterrupt, SystemExit):
1771 1792 raise
1772 1793 except Exception, exc:
1773 1794 if self.errors == "drop":
1774 1795 pass # Ignore errors
1775 1796 elif self.errors == "keep":
1776 1797 yield item
1777 1798 elif self.errors == "keeperror":
1778 1799 yield exc
1779 1800 elif self.errors == "raise":
1780 1801 raise
1781 1802 elif self.errors == "raiseifallfail":
1782 1803 if exc_info is None:
1783 1804 exc_info = sys.exc_info()
1784 1805 if not ok and exc_info is not None:
1785 1806 raise exc_info[0], exc_info[1], exc_info[2]
1786 1807
1787 1808 def __xrepr__(self, mode="default"):
1788 1809 if mode == "header" or mode == "footer":
1789 1810 input = getattr(self, "input", None)
1790 1811 if input is not None:
1791 1812 for part in xrepr(input, mode):
1792 1813 yield part
1793 1814 yield (astyle.style_default, " | ")
1794 1815 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1795 1816 for part in xrepr(self.expr, "default"):
1796 1817 yield part
1797 1818 yield (astyle.style_default, ")")
1798 1819 else:
1799 1820 yield (astyle.style_default, repr(self))
1800 1821
1801 1822 def __repr__(self):
1802 1823 return "<%s.%s expr=%r at 0x%x>" % \
1803 1824 (self.__class__.__module__, self.__class__.__name__,
1804 1825 self.expr, id(self))
1805 1826
1806 1827
1807 1828 class ieval(Pipe):
1808 1829 """
1809 1830 Evaluate an expression for each object in the input pipe.
1810 1831
1811 1832 Examples::
1812 1833
1813 1834 >>> ils | ieval("_.abspath()")
1835 # random
1814 1836 >>> sys.path | ieval(ifile)
1837 # random
1815 1838 """
1816 1839
1817 1840 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1818 1841 """
1819 1842 Create an ``ieval`` object. ``expr`` can be a callable or a string
1820 1843 containing an expression. For the meaning of ``globals`` and
1821 1844 ``errors`` see ``ifilter``.
1822 1845 """
1823 1846 self.expr = expr
1824 1847 self.globals = globals
1825 1848 self.errors = errors
1826 1849
1827 1850 def __iter__(self):
1828 1851 if callable(self.expr):
1829 1852 do = self.expr
1830 1853 else:
1831 1854 g = getglobals(self.globals)
1832 1855 expr = compile(self.expr, "ipipe-expression", "eval")
1833 1856 def do(item):
1834 1857 return eval(expr, g, AttrNamespace(item))
1835 1858
1836 1859 ok = 0
1837 1860 exc_info = None
1838 1861 for item in xiter(self.input):
1839 1862 try:
1840 1863 yield do(item)
1841 1864 except (KeyboardInterrupt, SystemExit):
1842 1865 raise
1843 1866 except Exception, exc:
1844 1867 if self.errors == "drop":
1845 1868 pass # Ignore errors
1846 1869 elif self.errors == "keep":
1847 1870 yield item
1848 1871 elif self.errors == "keeperror":
1849 1872 yield exc
1850 1873 elif self.errors == "raise":
1851 1874 raise
1852 1875 elif self.errors == "raiseifallfail":
1853 1876 if exc_info is None:
1854 1877 exc_info = sys.exc_info()
1855 1878 if not ok and exc_info is not None:
1856 1879 raise exc_info[0], exc_info[1], exc_info[2]
1857 1880
1858 1881 def __xrepr__(self, mode="default"):
1859 1882 if mode == "header" or mode == "footer":
1860 1883 input = getattr(self, "input", None)
1861 1884 if input is not None:
1862 1885 for part in xrepr(input, mode):
1863 1886 yield part
1864 1887 yield (astyle.style_default, " | ")
1865 1888 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1866 1889 for part in xrepr(self.expr, "default"):
1867 1890 yield part
1868 1891 yield (astyle.style_default, ")")
1869 1892 else:
1870 1893 yield (astyle.style_default, repr(self))
1871 1894
1872 1895 def __repr__(self):
1873 1896 return "<%s.%s expr=%r at 0x%x>" % \
1874 1897 (self.__class__.__module__, self.__class__.__name__,
1875 1898 self.expr, id(self))
1876 1899
1877 1900
1878 1901 class ienum(Pipe):
1879 1902 """
1880 1903 Enumerate the input pipe (i.e. wrap each input object in an object
1881 1904 with ``index`` and ``object`` attributes).
1882 1905
1883 1906 Examples::
1884 1907
1885 1908 >>> xrange(20) | ieval("_,_*_") | ienum | ifilter("index % 2 == 0") | ieval("object")
1886 1909 """
1910 skip_doctest = True
1911
1887 1912 def __iter__(self):
1888 1913 fields = ("index", "object")
1889 1914 for (index, object) in enumerate(xiter(self.input)):
1890 1915 yield Fields(fields, index=index, object=object)
1891 1916
1892 1917
1893 1918 class isort(Pipe):
1894 1919 """
1895 1920 Sorts the input pipe.
1896 1921
1897 1922 Examples::
1898 1923
1899 1924 >>> ils | isort("size")
1925 <IPython.Extensions.ipipe.isort key='size' reverse=False at 0x849ec2c>
1900 1926 >>> ils | isort("_.isdir(), _.lower()", reverse=True)
1927 <IPython.Extensions.ipipe.isort key='_.isdir(), _.lower()' reverse=True at 0x849eacc>
1928 # all-random
1901 1929 """
1902 1930
1903 1931 def __init__(self, key=None, globals=None, reverse=False):
1904 1932 """
1905 1933 Create an ``isort`` object. ``key`` can be a callable or a string
1906 1934 containing an expression (or ``None`` in which case the items
1907 1935 themselves will be sorted). If ``reverse`` is true the sort order
1908 1936 will be reversed. For the meaning of ``globals`` see ``ifilter``.
1909 1937 """
1910 1938 self.key = key
1911 1939 self.globals = globals
1912 1940 self.reverse = reverse
1913 1941
1914 1942 def __iter__(self):
1915 1943 if self.key is None:
1916 1944 items = sorted(xiter(self.input), reverse=self.reverse)
1917 1945 elif callable(self.key):
1918 1946 items = sorted(xiter(self.input), key=self.key, reverse=self.reverse)
1919 1947 else:
1920 1948 g = getglobals(self.globals)
1921 1949 key = compile(self.key, "ipipe-expression", "eval")
1922 1950 def realkey(item):
1923 1951 return eval(key, g, AttrNamespace(item))
1924 1952 items = sorted(xiter(self.input), key=realkey, reverse=self.reverse)
1925 1953 for item in items:
1926 1954 yield item
1927 1955
1928 1956 def __xrepr__(self, mode="default"):
1929 1957 if mode == "header" or mode == "footer":
1930 1958 input = getattr(self, "input", None)
1931 1959 if input is not None:
1932 1960 for part in xrepr(input, mode):
1933 1961 yield part
1934 1962 yield (astyle.style_default, " | ")
1935 1963 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1936 1964 for part in xrepr(self.key, "default"):
1937 1965 yield part
1938 1966 if self.reverse:
1939 1967 yield (astyle.style_default, ", ")
1940 1968 for part in xrepr(True, "default"):
1941 1969 yield part
1942 1970 yield (astyle.style_default, ")")
1943 1971 else:
1944 1972 yield (astyle.style_default, repr(self))
1945 1973
1946 1974 def __repr__(self):
1947 1975 return "<%s.%s key=%r reverse=%r at 0x%x>" % \
1948 1976 (self.__class__.__module__, self.__class__.__name__,
1949 1977 self.key, self.reverse, id(self))
1950 1978
1951 1979
1952 1980 tab = 3 # for expandtabs()
1953 1981
1954 1982 def _format(field):
1955 1983 if isinstance(field, str):
1956 1984 text = repr(field.expandtabs(tab))[1:-1]
1957 1985 elif isinstance(field, unicode):
1958 1986 text = repr(field.expandtabs(tab))[2:-1]
1959 1987 elif isinstance(field, datetime.datetime):
1960 1988 # Don't use strftime() here, as this requires year >= 1900
1961 1989 text = "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
1962 1990 (field.year, field.month, field.day,
1963 1991 field.hour, field.minute, field.second, field.microsecond)
1964 1992 elif isinstance(field, datetime.date):
1965 1993 text = "%04d-%02d-%02d" % (field.year, field.month, field.day)
1966 1994 else:
1967 1995 text = repr(field)
1968 1996 return text
1969 1997
1970 1998
1971 1999 class Display(object):
1972 2000 class __metaclass__(type):
1973 2001 def __ror__(self, input):
1974 2002 return input | self()
1975 2003
1976 2004 def __init__(self, input=None):
1977 2005 self.input = input
1978 2006
1979 2007 def __ror__(self, input):
1980 2008 self.input = input
1981 2009 return self
1982 2010
1983 2011 def display(self):
1984 2012 pass
1985 2013
1986 2014
1987 2015 class iless(Display):
1988 2016 cmd = "less --quit-if-one-screen --LONG-PROMPT --LINE-NUMBERS --chop-long-lines --shift=8 --RAW-CONTROL-CHARS"
1989 2017
1990 2018 def display(self):
1991 2019 try:
1992 2020 pager = os.popen(self.cmd, "w")
1993 2021 try:
1994 2022 for item in xiter(self.input):
1995 2023 first = False
1996 2024 for attr in xattrs(item, "default"):
1997 2025 if first:
1998 2026 first = False
1999 2027 else:
2000 2028 pager.write(" ")
2001 2029 attr = upgradexattr(attr)
2002 2030 if not isinstance(attr, SelfDescriptor):
2003 2031 pager.write(attr.name())
2004 2032 pager.write("=")
2005 2033 pager.write(str(attr.value(item)))
2006 2034 pager.write("\n")
2007 2035 finally:
2008 2036 pager.close()
2009 2037 except Exception, exc:
2010 2038 print "%s: %s" % (exc.__class__.__name__, str(exc))
2011 2039
2012 2040
2013 2041 class _RedirectIO(object):
2014 2042 def __init__(self,*args,**kwargs):
2015 2043 """
2016 2044 Map the system output streams to self.
2017 2045 """
2018 2046 self.stream = StringIO.StringIO()
2019 2047 self.stdout = sys.stdout
2020 2048 sys.stdout = self
2021 2049 self.stderr = sys.stderr
2022 2050 sys.stderr = self
2023 2051
2024 2052 def write(self, text):
2025 2053 """
2026 2054 Write both to screen and to self.
2027 2055 """
2028 2056 self.stream.write(text)
2029 2057 self.stdout.write(text)
2030 2058 if "\n" in text:
2031 2059 self.stdout.flush()
2032 2060
2033 2061 def writelines(self, lines):
2034 2062 """
2035 2063 Write lines both to screen and to self.
2036 2064 """
2037 2065 self.stream.writelines(lines)
2038 2066 self.stdout.writelines(lines)
2039 2067 self.stdout.flush()
2040 2068
2041 2069 def restore(self):
2042 2070 """
2043 2071 Restore the default system streams.
2044 2072 """
2045 2073 self.stdout.flush()
2046 2074 self.stderr.flush()
2047 2075 sys.stdout = self.stdout
2048 2076 sys.stderr = self.stderr
2049 2077
2050 2078
2051 2079 class icap(Table):
2052 2080 """
2053 2081 Execute a python string and capture any output to stderr/stdout.
2054 2082
2055 2083 Examples::
2056 2084
2057 2085 >>> import time
2058 2086 >>> icap("for i in range(10): print i, time.sleep(0.1)")
2059 2087
2060 2088 """
2089 skip_doctest = True
2090
2061 2091 def __init__(self, expr, globals=None):
2062 2092 self.expr = expr
2063 2093 self.globals = globals
2064 2094 log = _RedirectIO()
2065 2095 try:
2066 2096 exec(expr, getglobals(globals))
2067 2097 finally:
2068 2098 log.restore()
2069 2099 self.stream = log.stream
2070 2100
2071 2101 def __iter__(self):
2072 2102 self.stream.seek(0)
2073 2103 for line in self.stream:
2074 2104 yield line.rstrip("\r\n")
2075 2105
2076 2106 def __xrepr__(self, mode="default"):
2077 2107 if mode == "header" or mode == "footer":
2078 2108 yield (astyle.style_default,
2079 2109 "%s(%r)" % (self.__class__.__name__, self.expr))
2080 2110 else:
2081 2111 yield (astyle.style_default, repr(self))
2082 2112
2083 2113 def __repr__(self):
2084 2114 return "%s.%s(%r)" % \
2085 2115 (self.__class__.__module__, self.__class__.__name__, self.expr)
2086 2116
2087 2117
2088 2118 def xformat(value, mode, maxlength):
2089 2119 align = None
2090 2120 full = True
2091 2121 width = 0
2092 2122 text = astyle.Text()
2093 2123 for (style, part) in xrepr(value, mode):
2094 2124 # only consider the first result
2095 2125 if align is None:
2096 2126 if isinstance(style, int):
2097 2127 # (style, text) really is (alignment, stop)
2098 2128 align = style
2099 2129 full = part
2100 2130 continue
2101 2131 else:
2102 2132 align = -1
2103 2133 full = True
2104 2134 if not isinstance(style, int):
2105 2135 text.append((style, part))
2106 2136 width += len(part)
2107 2137 if width >= maxlength and not full:
2108 2138 text.append((astyle.style_ellisis, "..."))
2109 2139 width += 3
2110 2140 break
2111 2141 if align is None: # default to left alignment
2112 2142 align = -1
2113 2143 return (align, width, text)
2114 2144
2115 2145
2116 2146
2117 2147 import astyle
2118 2148
2119 2149 class idump(Display):
2120 2150 # The approximate maximum length of a column entry
2121 2151 maxattrlength = 200
2122 2152
2123 2153 # Style for column names
2124 2154 style_header = astyle.Style.fromstr("white:black:bold")
2125 2155
2126 2156 def __init__(self, input=None, *attrs):
2127 2157 Display.__init__(self, input)
2128 2158 self.attrs = [upgradexattr(attr) for attr in attrs]
2129 2159 self.headerpadchar = " "
2130 2160 self.headersepchar = "|"
2131 2161 self.datapadchar = " "
2132 2162 self.datasepchar = "|"
2133 2163
2134 2164 def display(self):
2135 2165 stream = genutils.Term.cout
2136 2166 allattrs = []
2137 2167 attrset = set()
2138 2168 colwidths = {}
2139 2169 rows = []
2140 2170 for item in xiter(self.input):
2141 2171 row = {}
2142 2172 attrs = self.attrs
2143 2173 if not attrs:
2144 2174 attrs = xattrs(item, "default")
2145 2175 for attr in attrs:
2146 2176 if attr not in attrset:
2147 2177 allattrs.append(attr)
2148 2178 attrset.add(attr)
2149 2179 colwidths[attr] = len(attr.name())
2150 2180 try:
2151 2181 value = attr.value(item)
2152 2182 except (KeyboardInterrupt, SystemExit):
2153 2183 raise
2154 2184 except Exception, exc:
2155 2185 value = exc
2156 2186 (align, width, text) = xformat(value, "cell", self.maxattrlength)
2157 2187 colwidths[attr] = max(colwidths[attr], width)
2158 2188 # remember alignment, length and colored parts
2159 2189 row[attr] = (align, width, text)
2160 2190 rows.append(row)
2161 2191
2162 2192 stream.write("\n")
2163 2193 for (i, attr) in enumerate(allattrs):
2164 2194 attrname = attr.name()
2165 2195 self.style_header(attrname).write(stream)
2166 2196 spc = colwidths[attr] - len(attrname)
2167 2197 if i < len(colwidths)-1:
2168 2198 stream.write(self.headerpadchar*spc)
2169 2199 stream.write(self.headersepchar)
2170 2200 stream.write("\n")
2171 2201
2172 2202 for row in rows:
2173 2203 for (i, attr) in enumerate(allattrs):
2174 2204 (align, width, text) = row[attr]
2175 2205 spc = colwidths[attr] - width
2176 2206 if align == -1:
2177 2207 text.write(stream)
2178 2208 if i < len(colwidths)-1:
2179 2209 stream.write(self.datapadchar*spc)
2180 2210 elif align == 0:
2181 2211 spc = colwidths[attr] - width
2182 2212 spc1 = spc//2
2183 2213 spc2 = spc-spc1
2184 2214 stream.write(self.datapadchar*spc1)
2185 2215 text.write(stream)
2186 2216 if i < len(colwidths)-1:
2187 2217 stream.write(self.datapadchar*spc2)
2188 2218 else:
2189 2219 stream.write(self.datapadchar*spc)
2190 2220 text.write(stream)
2191 2221 if i < len(colwidths)-1:
2192 2222 stream.write(self.datasepchar)
2193 2223 stream.write("\n")
2194 2224
2195 2225
2196 2226 class AttributeDetail(Table):
2197 2227 """
2198 2228 ``AttributeDetail`` objects are use for displaying a detailed list of object
2199 2229 attributes.
2200 2230 """
2201 2231 def __init__(self, object, descriptor):
2202 2232 self.object = object
2203 2233 self.descriptor = descriptor
2204 2234
2205 2235 def __iter__(self):
2206 2236 return self.descriptor.iter(self.object)
2207 2237
2208 2238 def name(self):
2209 2239 return self.descriptor.name()
2210 2240
2211 2241 def attrtype(self):
2212 2242 return self.descriptor.attrtype(self.object)
2213 2243
2214 2244 def valuetype(self):
2215 2245 return self.descriptor.valuetype(self.object)
2216 2246
2217 2247 def doc(self):
2218 2248 return self.descriptor.doc(self.object)
2219 2249
2220 2250 def shortdoc(self):
2221 2251 return self.descriptor.shortdoc(self.object)
2222 2252
2223 2253 def value(self):
2224 2254 return self.descriptor.value(self.object)
2225 2255
2226 2256 def __xattrs__(self, mode="default"):
2227 2257 attrs = ("name()", "attrtype()", "valuetype()", "value()", "shortdoc()")
2228 2258 if mode == "detail":
2229 2259 attrs += ("doc()",)
2230 2260 return attrs
2231 2261
2232 2262 def __xrepr__(self, mode="default"):
2233 2263 yield (-1, True)
2234 2264 valuetype = self.valuetype()
2235 2265 if valuetype is not noitem:
2236 2266 for part in xrepr(valuetype):
2237 2267 yield part
2238 2268 yield (astyle.style_default, " ")
2239 2269 yield (astyle.style_default, self.attrtype())
2240 2270 yield (astyle.style_default, " ")
2241 2271 yield (astyle.style_default, self.name())
2242 2272 yield (astyle.style_default, " of ")
2243 2273 for part in xrepr(self.object):
2244 2274 yield part
2245 2275
2246 2276
2247 2277 try:
2248 2278 from ibrowse import ibrowse
2249 2279 except ImportError:
2250 2280 # No curses (probably Windows) => try igrid
2251 2281 try:
2252 2282 from igrid import igrid
2253 2283 except ImportError:
2254 2284 # no wx either => use ``idump`` as the default display.
2255 2285 defaultdisplay = idump
2256 2286 else:
2257 2287 defaultdisplay = igrid
2258 2288 __all__.append("igrid")
2259 2289 else:
2260 2290 defaultdisplay = ibrowse
2261 2291 __all__.append("ibrowse")
2262 2292
2263 2293
2264 2294 # If we're running under IPython, register our objects with IPython's
2265 2295 # generic function ``result_display``, else install a displayhook
2266 2296 # directly as sys.displayhook
2267 2297 if generics is not None:
2268 2298 def display_display(obj):
2269 2299 return obj.display()
2270 2300 generics.result_display.when_type(Display)(display_display)
2271 2301
2272 2302 def display_tableobject(obj):
2273 2303 return display_display(defaultdisplay(obj))
2274 2304 generics.result_display.when_type(Table)(display_tableobject)
2275 2305
2276 2306 def display_tableclass(obj):
2277 2307 return display_tableobject(obj())
2278 2308 generics.result_display.when_type(Table.__metaclass__)(display_tableclass)
2279 2309 else:
2280 2310 def installdisplayhook():
2281 2311 _originalhook = sys.displayhook
2282 2312 def displayhook(obj):
2283 2313 if isinstance(obj, type) and issubclass(obj, Table):
2284 2314 obj = obj()
2285 2315 if isinstance(obj, Table):
2286 2316 obj = defaultdisplay(obj)
2287 2317 if isinstance(obj, Display):
2288 2318 return obj.display()
2289 2319 else:
2290 2320 _originalhook(obj)
2291 2321 sys.displayhook = displayhook
2292 2322 installdisplayhook()
@@ -1,592 +1,578 b''
1 1 """ ILeo - Leo plugin for IPython
2 2
3 3
4 4 """
5 5 import IPython.ipapi
6 6 import IPython.genutils
7 7 import IPython.generics
8 8 from IPython.hooks import CommandChainDispatcher
9 9 import re
10 10 import UserDict
11 11 from IPython.ipapi import TryNext
12 12 import IPython.macro
13 13 import IPython.Shell
14 14
15 15 def init_ipython(ipy):
16 16 """ This will be run by _ip.load('ipy_leo')
17 17
18 18 Leo still needs to run update_commander() after this.
19 19
20 20 """
21 21 global ip
22 22 ip = ipy
23 23 IPython.Shell.hijack_tk()
24 24 ip.set_hook('complete_command', mb_completer, str_key = '%mb')
25 25 ip.expose_magic('mb',mb_f)
26 26 ip.expose_magic('lee',lee_f)
27 27 ip.expose_magic('leoref',leoref_f)
28 28 expose_ileo_push(push_cl_node,100)
29 29 # this should be the LAST one that will be executed, and it will never raise TryNext
30 30 expose_ileo_push(push_ipython_script, 1000)
31 31 expose_ileo_push(push_plain_python, 100)
32 32 expose_ileo_push(push_ev_node, 100)
33 33 global wb
34 34 wb = LeoWorkbook()
35 35 ip.user_ns['wb'] = wb
36 36
37 37 show_welcome()
38 38
39 39
40 40 def update_commander(new_leox):
41 41 """ Set the Leo commander to use
42 42
43 43 This will be run every time Leo does ipython-launch; basically,
44 44 when the user switches the document he is focusing on, he should do
45 45 ipython-launch to tell ILeo what document the commands apply to.
46 46
47 47 """
48 48
49 49 global c,g
50 50 c,g = new_leox.c, new_leox.g
51 51 print "Set Leo Commander:",c.frame.getTitle()
52 52
53 53 # will probably be overwritten by user, but handy for experimentation early on
54 54 ip.user_ns['c'] = c
55 55 ip.user_ns['g'] = g
56 56 ip.user_ns['_leo'] = new_leox
57 57
58 58 new_leox.push = push_position_from_leo
59 59 run_leo_startup_node()
60 60
61 61 from IPython.external.simplegeneric import generic
62 62 import pprint
63 63
64 64 def es(s):
65 65 g.es(s, tabName = 'IPython')
66 66 pass
67 67
68 68 @generic
69 69 def format_for_leo(obj):
70 70 """ Convert obj to string representiation (for editing in Leo)"""
71 71 return pprint.pformat(obj)
72 72
73 73 @format_for_leo.when_type(list)
74 74 def format_list(obj):
75 75 return "\n".join(str(s) for s in obj)
76 76
77 77
78 78 attribute_re = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$')
79 79 def valid_attribute(s):
80 80 return attribute_re.match(s)
81 81
82 82 _rootnode = None
83 83 def rootnode():
84 84 """ Get ileo root node (@ipy-root)
85 85
86 86 if node has become invalid or has not been set, return None
87 87
88 88 Note that the root is the *first* @ipy-root item found
89 89 """
90 90 global _rootnode
91 91 if _rootnode is None:
92 92 return None
93 93 if c.positionExists(_rootnode.p):
94 94 return _rootnode
95 95 _rootnode = None
96 96 return None
97 97
98 98 def all_cells():
99 99 global _rootnode
100 100 d = {}
101 101 r = rootnode()
102 102 if r is not None:
103 103 nodes = r.p.children_iter()
104 104 else:
105 105 nodes = c.allNodes_iter()
106 106
107 107 for p in nodes:
108 108 h = p.headString()
109 109 if h.strip() == '@ipy-root':
110 110 # update root node (found it for the first time)
111 111 _rootnode = LeoNode(p)
112 112 # the next recursive call will use the children of new root
113 113 return all_cells()
114 114
115 115 if h.startswith('@a '):
116 116 d[h.lstrip('@a ').strip()] = p.parent().copy()
117 117 elif not valid_attribute(h):
118 118 continue
119 119 d[h] = p.copy()
120 120 return d
121 121
122 122 def eval_node(n):
123 123 body = n.b
124 124 if not body.startswith('@cl'):
125 125 # plain python repr node, just eval it
126 126 return ip.ev(n.b)
127 127 # @cl nodes deserve special treatment - first eval the first line (minus cl), then use it to call the rest of body
128 128 first, rest = body.split('\n',1)
129 129 tup = first.split(None, 1)
130 130 # @cl alone SPECIAL USE-> dump var to user_ns
131 131 if len(tup) == 1:
132 132 val = ip.ev(rest)
133 133 ip.user_ns[n.h] = val
134 134 es("%s = %s" % (n.h, repr(val)[:20] ))
135 135 return val
136 136
137 137 cl, hd = tup
138 138
139 139 xformer = ip.ev(hd.strip())
140 140 es('Transform w/ %s' % repr(xformer))
141 141 return xformer(rest, n)
142 142
143 143 class LeoNode(object, UserDict.DictMixin):
144 144 """ Node in Leo outline
145 145
146 146 Most important attributes (getters/setters available:
147 147 .v - evaluate node, can also be alligned
148 148 .b, .h - body string, headline string
149 149 .l - value as string list
150 150
151 151 Also supports iteration,
152 152
153 153 setitem / getitem (indexing):
154 154 wb.foo['key'] = 12
155 155 assert wb.foo['key'].v == 12
156 156
157 157 Note the asymmetry on setitem and getitem! Also other
158 158 dict methods are available.
159 159
160 160 .ipush() - run push-to-ipython
161 161
162 162 Minibuffer command access (tab completion works):
163 163
164 164 mb save-to-file
165 165
166 166 """
167 167 def __init__(self,p):
168 168 self.p = p.copy()
169 169
170 170 def __str__(self):
171 171 return "<LeoNode %s>" % str(self.p)
172 172
173 173 __repr__ = __str__
174 174
175 175 def __get_h(self): return self.p.headString()
176 176 def __set_h(self,val):
177 print "set head",val
178 c.beginUpdate()
179 try:
180 177 c.setHeadString(self.p,val)
181 finally:
182 c.endUpdate()
178 c.redraw()
183 179
184 180 h = property( __get_h, __set_h, doc = "Node headline string")
185 181
186 182 def __get_b(self): return self.p.bodyString()
187 183 def __set_b(self,val):
188 print "set body",val
189 c.beginUpdate()
190 try:
191 184 c.setBodyString(self.p, val)
192 finally:
193 c.endUpdate()
185 c.redraw()
194 186
195 187 b = property(__get_b, __set_b, doc = "Nody body string")
196 188
197 189 def __set_val(self, val):
198 190 self.b = format_for_leo(val)
199 191
200 192 v = property(lambda self: eval_node(self), __set_val, doc = "Node evaluated value")
201 193
202 194 def __set_l(self,val):
203 195 self.b = '\n'.join(val )
204 196 l = property(lambda self : IPython.genutils.SList(self.b.splitlines()),
205 197 __set_l, doc = "Node value as string list")
206 198
207 199 def __iter__(self):
208 200 """ Iterate through nodes direct children """
209 201
210 202 return (LeoNode(p) for p in self.p.children_iter())
211 203
212 204 def __children(self):
213 205 d = {}
214 206 for child in self:
215 207 head = child.h
216 208 tup = head.split(None,1)
217 209 if len(tup) > 1 and tup[0] == '@k':
218 210 d[tup[1]] = child
219 211 continue
220 212
221 213 if not valid_attribute(head):
222 214 d[head] = child
223 215 continue
224 216 return d
225 217 def keys(self):
226 218 d = self.__children()
227 219 return d.keys()
228 220 def __getitem__(self, key):
229 221 """ wb.foo['Some stuff'] Return a child node with headline 'Some stuff'
230 222
231 223 If key is a valid python name (e.g. 'foo'), look for headline '@k foo' as well
232 224 """
233 225 key = str(key)
234 226 d = self.__children()
235 227 return d[key]
236 228 def __setitem__(self, key, val):
237 229 """ You can do wb.foo['My Stuff'] = 12 to create children
238 230
239 231 This will create 'My Stuff' as a child of foo (if it does not exist), and
240 232 do .v = 12 assignment.
241 233
242 234 Exception:
243 235
244 236 wb.foo['bar'] = 12
245 237
246 238 will create a child with headline '@k bar', because bar is a valid python name
247 239 and we don't want to crowd the WorkBook namespace with (possibly numerous) entries
248 240 """
249 241 key = str(key)
250 242 d = self.__children()
251 243 if key in d:
252 244 d[key].v = val
253 245 return
254 246
255 247 if not valid_attribute(key):
256 248 head = key
257 249 else:
258 250 head = '@k ' + key
259 251 p = c.createLastChildNode(self.p, head, '')
260 252 LeoNode(p).v = val
261 253
262 254 def ipush(self):
263 255 """ Does push-to-ipython on the node """
264 256 push_from_leo(self)
265 257
266 258 def go(self):
267 259 """ Set node as current node (to quickly see it in Outline) """
268 c.beginUpdate()
269 try:
270 260 c.setCurrentPosition(self.p)
271 finally:
272 c.endUpdate()
261 c.redraw()
273 262
274 263 def script(self):
275 264 """ Method to get the 'tangled' contents of the node
276 265
277 266 (parse @others, << section >> references etc.)
278 267 """
279 268 return g.getScript(c,self.p,useSelectedText=False,useSentinels=False)
280 269
281 270 def __get_uA(self):
282 271 p = self.p
283 272 # Create the uA if necessary.
284 273 if not hasattr(p.v.t,'unknownAttributes'):
285 274 p.v.t.unknownAttributes = {}
286 275
287 276 d = p.v.t.unknownAttributes.setdefault('ipython', {})
288 277 return d
289 278
290 279 uA = property(__get_uA, doc = "Access persistent unknownAttributes of node")
291 280
292 281
293 282 class LeoWorkbook:
294 283 """ class for 'advanced' node access
295 284
296 285 Has attributes for all "discoverable" nodes. Node is discoverable if it
297 286 either
298 287
299 288 - has a valid python name (Foo, bar_12)
300 289 - is a parent of an anchor node (if it has a child '@a foo', it is visible as foo)
301 290
302 291 """
303 292 def __getattr__(self, key):
304 293 if key.startswith('_') or key == 'trait_names' or not valid_attribute(key):
305 294 raise AttributeError
306 295 cells = all_cells()
307 296 p = cells.get(key, None)
308 297 if p is None:
309 298 return add_var(key)
310 299
311 300 return LeoNode(p)
312 301
313 302 def __str__(self):
314 303 return "<LeoWorkbook>"
315 304 def __setattr__(self,key, val):
316 305 raise AttributeError("Direct assignment to workbook denied, try wb.%s.v = %s" % (key,val))
317 306
318 307 __repr__ = __str__
319 308
320 309 def __iter__(self):
321 310 """ Iterate all (even non-exposed) nodes """
322 311 cells = all_cells()
323 312 return (LeoNode(p) for p in c.allNodes_iter())
324 313
325 314 current = property(lambda self: LeoNode(c.currentPosition()), doc = "Currently selected node")
326 315
327 316 def match_h(self, regex):
328 317 cmp = re.compile(regex)
329 318 for node in self:
330 319 if re.match(cmp, node.h, re.IGNORECASE):
331 320 yield node
332 321 return
333 322
334 323 @IPython.generics.complete_object.when_type(LeoWorkbook)
335 324 def workbook_complete(obj, prev):
336 325 return all_cells().keys() + [s for s in prev if not s.startswith('_')]
337 326
338 327
339 328 def add_var(varname):
340 c.beginUpdate()
341 329 r = rootnode()
342 330 try:
343 331 if r is None:
344 332 p2 = g.findNodeAnywhere(c,varname)
345 333 else:
346 334 p2 = g.findNodeInChildren(c, r.p, varname)
347 335 if p2:
348 336 return LeoNode(p2)
349 337
350 338 if r is not None:
351 339 p2 = r.p.insertAsLastChild()
352 340
353 341 else:
354 342 p2 = c.currentPosition().insertAfter()
355 343
356 344 c.setHeadString(p2,varname)
357 345 return LeoNode(p2)
358 346 finally:
359 c.endUpdate()
347 c.redraw()
360 348
361 349 def add_file(self,fname):
362 350 p2 = c.currentPosition().insertAfter()
363 351
364 352 push_from_leo = CommandChainDispatcher()
365 353
366 354 def expose_ileo_push(f, prio = 0):
367 355 push_from_leo.add(f, prio)
368 356
369 357 def push_ipython_script(node):
370 358 """ Execute the node body in IPython, as if it was entered in interactive prompt """
371 c.beginUpdate()
372 359 try:
373 360 ohist = ip.IP.output_hist
374 361 hstart = len(ip.IP.input_hist)
375 362 script = node.script()
376 363
377 364 ip.user_ns['_p'] = node
378 365 ip.runlines(script)
379 366 ip.user_ns.pop('_p',None)
380 367
381 368 has_output = False
382 369 for idx in range(hstart,len(ip.IP.input_hist)):
383 370 val = ohist.get(idx,None)
384 371 if val is None:
385 372 continue
386 373 has_output = True
387 374 inp = ip.IP.input_hist[idx]
388 375 if inp.strip():
389 376 es('In: %s' % (inp[:40], ))
390 377
391 378 es('<%d> %s' % (idx, pprint.pformat(ohist[idx],width = 40)))
392 379
393 380 if not has_output:
394 381 es('ipy run: %s (%d LL)' %( node.h,len(script)))
395 382 finally:
396 c.endUpdate()
383 c.redraw()
397 384
398 385
399 386 def eval_body(body):
400 387 try:
401 388 val = ip.ev(body)
402 389 except:
403 390 # just use stringlist if it's not completely legal python expression
404 391 val = IPython.genutils.SList(body.splitlines())
405 392 return val
406 393
407 394 def push_plain_python(node):
408 395 if not node.h.endswith('P'):
409 396 raise TryNext
410 397 script = node.script()
411 398 lines = script.count('\n')
412 399 try:
413 400 exec script in ip.user_ns
414 401 except:
415 402 print " -- Exception in script:\n"+script + "\n --"
416 403 raise
417 404 es('ipy plain: %s (%d LL)' % (node.h,lines))
418 405
419 406
420 407 def push_cl_node(node):
421 408 """ If node starts with @cl, eval it
422 409
423 410 The result is put as last child of @ipy-results node, if it exists
424 411 """
425 412 if not node.b.startswith('@cl'):
426 413 raise TryNext
427 414
428 415 p2 = g.findNodeAnywhere(c,'@ipy-results')
429 416 val = node.v
430 417 if p2:
431 418 es("=> @ipy-results")
432 419 LeoNode(p2).v = val
433 420 es(val)
434 421
435 422 def push_ev_node(node):
436 423 """ If headline starts with @ev, eval it and put result in body """
437 424 if not node.h.startswith('@ev '):
438 425 raise TryNext
439 426 expr = node.h.lstrip('@ev ')
440 427 es('ipy eval ' + expr)
441 428 res = ip.ev(expr)
442 429 node.v = res
443 430
444 431
445 432 def push_position_from_leo(p):
446 433 try:
447 434 push_from_leo(LeoNode(p))
448 435 except AttributeError,e:
449 436 if e.args == ("Commands instance has no attribute 'frame'",):
450 437 es("Error: ILeo not associated with .leo document")
451 438 es("Press alt+shift+I to fix!")
452 439 else:
453 440 raise
454 441
455 442 @generic
456 443 def edit_object_in_leo(obj, varname):
457 444 """ Make it @cl node so it can be pushed back directly by alt+I """
458 445 node = add_var(varname)
459 446 formatted = format_for_leo(obj)
460 447 if not formatted.startswith('@cl'):
461 448 formatted = '@cl\n' + formatted
462 449 node.b = formatted
463 450 node.go()
464 451
465 452 @edit_object_in_leo.when_type(IPython.macro.Macro)
466 453 def edit_macro(obj,varname):
467 454 bod = '_ip.defmacro("""\\\n' + obj.value + '""")'
468 455 node = add_var('Macro_' + varname)
469 456 node.b = bod
470 457 node.go()
471 458
472 459 def get_history(hstart = 0):
473 460 res = []
474 461 ohist = ip.IP.output_hist
475 462
476 463 for idx in range(hstart, len(ip.IP.input_hist)):
477 464 val = ohist.get(idx,None)
478 465 has_output = True
479 466 inp = ip.IP.input_hist_raw[idx]
480 467 if inp.strip():
481 468 res.append('In [%d]: %s' % (idx, inp))
482 469 if val:
483 470 res.append(pprint.pformat(val))
484 471 res.append('\n')
485 472 return ''.join(res)
486 473
487 474
488 475 def lee_f(self,s):
489 476 """ Open file(s)/objects in Leo
490 477
491 478 - %lee hist -> open full session history in leo
492 479 - Takes an object. l = [1,2,"hello"]; %lee l. Alt+I in leo pushes the object back
493 480 - Takes an mglob pattern, e.g. '%lee *.cpp' or %lee 'rec:*.cpp'
494 481 - Takes input history indices: %lee 4 6-8 10 12-47
495 482 """
496 483 import os
497 484
498 c.beginUpdate()
499 485 try:
500 486 if s == 'hist':
501 487 wb.ipython_history.b = get_history()
502 488 wb.ipython_history.go()
503 489 return
504 490
505 491
506 492 if s and s[0].isdigit():
507 493 # numbers; push input slices to leo
508 494 lines = self.extract_input_slices(s.strip().split(), True)
509 495 v = add_var('stored_ipython_input')
510 496 v.b = '\n'.join(lines)
511 497 return
512 498
513 499
514 500 # try editing the object directly
515 501 obj = ip.user_ns.get(s, None)
516 502 if obj is not None:
517 503 edit_object_in_leo(obj,s)
518 504 return
519 505
520 506
521 507 # if it's not object, it's a file name / mglob pattern
522 508 from IPython.external import mglob
523 509
524 510 files = (os.path.abspath(f) for f in mglob.expand(s))
525 511 for fname in files:
526 512 p = g.findNodeAnywhere(c,'@auto ' + fname)
527 513 if not p:
528 514 p = c.currentPosition().insertAfter()
529 515
530 516 p.setHeadString('@auto ' + fname)
531 517 if os.path.isfile(fname):
532 518 c.setBodyString(p,open(fname).read())
533 519 c.selectPosition(p)
534 520 print "Editing file(s), press ctrl+shift+w in Leo to write @auto nodes"
535 521 finally:
536 c.endUpdate()
522 c.redraw()
537 523
538 524
539 525
540 526 def leoref_f(self,s):
541 527 """ Quick reference for ILeo """
542 528 import textwrap
543 529 print textwrap.dedent("""\
544 530 %leoe file/object - open file / object in leo
545 531 wb.foo.v - eval node foo (i.e. headstring is 'foo' or '@ipy foo')
546 532 wb.foo.v = 12 - assign to body of node foo
547 533 wb.foo.b - read or write the body of node foo
548 534 wb.foo.l - body of node foo as string list
549 535
550 536 for el in wb.foo:
551 537 print el.v
552 538
553 539 """
554 540 )
555 541
556 542
557 543
558 544 def mb_f(self, arg):
559 545 """ Execute leo minibuffer commands
560 546
561 547 Example:
562 548 mb save-to-file
563 549 """
564 550 c.executeMinibufferCommand(arg)
565 551
566 552 def mb_completer(self,event):
567 553 """ Custom completer for minibuffer """
568 554 cmd_param = event.line.split()
569 555 if event.line.endswith(' '):
570 556 cmd_param.append('')
571 557 if len(cmd_param) > 2:
572 558 return ip.IP.Completer.file_matches(event.symbol)
573 559 cmds = c.commandsDict.keys()
574 560 cmds.sort()
575 561 return cmds
576 562
577 563 def show_welcome():
578 564 print "------------------"
579 565 print "Welcome to Leo-enabled IPython session!"
580 566 print "Try %leoref for quick reference."
581 567 import IPython.platutils
582 568 IPython.platutils.set_term_title('ILeo')
583 569 IPython.platutils.freeze_term_title()
584 570
585 571 def run_leo_startup_node():
586 572 p = g.findNodeAnywhere(c,'@ipy-startup')
587 573 if p:
588 574 print "Running @ipy-startup nodes"
589 575 for n in LeoNode(p):
590 576 push_from_leo(n)
591 577
592 578
@@ -1,3318 +1,3350 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Magic functions for InteractiveShell.
3 3
4 4 $Id: Magic.py 2996 2008-01-30 06:31:39Z fperez $"""
5 5
6 6 #*****************************************************************************
7 7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
8 8 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
9 9 #
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 12 #*****************************************************************************
13 13
14 14 #****************************************************************************
15 15 # Modules and globals
16 16
17 17 from IPython import Release
18 18 __author__ = '%s <%s>\n%s <%s>' % \
19 19 ( Release.authors['Janko'] + Release.authors['Fernando'] )
20 20 __license__ = Release.license
21 21
22 22 # Python standard modules
23 23 import __builtin__
24 24 import bdb
25 25 import inspect
26 26 import os
27 27 import pdb
28 28 import pydoc
29 29 import sys
30 30 import re
31 31 import tempfile
32 32 import time
33 33 import cPickle as pickle
34 34 import textwrap
35 35 from cStringIO import StringIO
36 36 from getopt import getopt,GetoptError
37 37 from pprint import pprint, pformat
38 38 from sets import Set
39 39
40 40 # cProfile was added in Python2.5
41 41 try:
42 42 import cProfile as profile
43 43 import pstats
44 44 except ImportError:
45 45 # profile isn't bundled by default in Debian for license reasons
46 46 try:
47 47 import profile,pstats
48 48 except ImportError:
49 49 profile = pstats = None
50 50
51 51 # Homebrewed
52 52 import IPython
53 53 from IPython import Debugger, OInspect, wildcard
54 54 from IPython.FakeModule import FakeModule
55 55 from IPython.Itpl import Itpl, itpl, printpl,itplns
56 56 from IPython.PyColorize import Parser
57 57 from IPython.ipstruct import Struct
58 58 from IPython.macro import Macro
59 59 from IPython.genutils import *
60 60 from IPython import platutils
61 61 import IPython.generics
62 62 import IPython.ipapi
63 63 from IPython.ipapi import UsageError
64 from IPython.testing import decorators as testdec
65
64 66 #***************************************************************************
65 67 # Utility functions
66 68 def on_off(tag):
67 69 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
68 70 return ['OFF','ON'][tag]
69 71
70 72 class Bunch: pass
71 73
72 74 def compress_dhist(dh):
73 75 head, tail = dh[:-10], dh[-10:]
74 76
75 77 newhead = []
76 78 done = Set()
77 79 for h in head:
78 80 if h in done:
79 81 continue
80 82 newhead.append(h)
81 83 done.add(h)
82 84
83 85 return newhead + tail
84 86
85 87
86 88 #***************************************************************************
87 89 # Main class implementing Magic functionality
88 90 class Magic:
89 91 """Magic functions for InteractiveShell.
90 92
91 93 Shell functions which can be reached as %function_name. All magic
92 94 functions should accept a string, which they can parse for their own
93 95 needs. This can make some functions easier to type, eg `%cd ../`
94 96 vs. `%cd("../")`
95 97
96 98 ALL definitions MUST begin with the prefix magic_. The user won't need it
97 99 at the command line, but it is is needed in the definition. """
98 100
99 101 # class globals
100 102 auto_status = ['Automagic is OFF, % prefix IS needed for magic functions.',
101 103 'Automagic is ON, % prefix NOT needed for magic functions.']
102 104
103 105 #......................................................................
104 106 # some utility functions
105 107
106 108 def __init__(self,shell):
107 109
108 110 self.options_table = {}
109 111 if profile is None:
110 112 self.magic_prun = self.profile_missing_notice
111 113 self.shell = shell
112 114
113 115 # namespace for holding state we may need
114 116 self._magic_state = Bunch()
115 117
116 118 def profile_missing_notice(self, *args, **kwargs):
117 119 error("""\
118 120 The profile module could not be found. It has been removed from the standard
119 121 python packages because of its non-free license. To use profiling, install the
120 122 python-profiler package from non-free.""")
121 123
122 124 def default_option(self,fn,optstr):
123 125 """Make an entry in the options_table for fn, with value optstr"""
124 126
125 127 if fn not in self.lsmagic():
126 128 error("%s is not a magic function" % fn)
127 129 self.options_table[fn] = optstr
128 130
129 131 def lsmagic(self):
130 132 """Return a list of currently available magic functions.
131 133
132 134 Gives a list of the bare names after mangling (['ls','cd', ...], not
133 135 ['magic_ls','magic_cd',...]"""
134 136
135 137 # FIXME. This needs a cleanup, in the way the magics list is built.
136 138
137 139 # magics in class definition
138 140 class_magic = lambda fn: fn.startswith('magic_') and \
139 141 callable(Magic.__dict__[fn])
140 142 # in instance namespace (run-time user additions)
141 143 inst_magic = lambda fn: fn.startswith('magic_') and \
142 144 callable(self.__dict__[fn])
143 145 # and bound magics by user (so they can access self):
144 146 inst_bound_magic = lambda fn: fn.startswith('magic_') and \
145 147 callable(self.__class__.__dict__[fn])
146 148 magics = filter(class_magic,Magic.__dict__.keys()) + \
147 149 filter(inst_magic,self.__dict__.keys()) + \
148 150 filter(inst_bound_magic,self.__class__.__dict__.keys())
149 151 out = []
150 152 for fn in Set(magics):
151 153 out.append(fn.replace('magic_','',1))
152 154 out.sort()
153 155 return out
154 156
155 157 def extract_input_slices(self,slices,raw=False):
156 158 """Return as a string a set of input history slices.
157 159
158 160 Inputs:
159 161
160 162 - slices: the set of slices is given as a list of strings (like
161 163 ['1','4:8','9'], since this function is for use by magic functions
162 164 which get their arguments as strings.
163 165
164 166 Optional inputs:
165 167
166 168 - raw(False): by default, the processed input is used. If this is
167 169 true, the raw input history is used instead.
168 170
169 171 Note that slices can be called with two notations:
170 172
171 173 N:M -> standard python form, means including items N...(M-1).
172 174
173 175 N-M -> include items N..M (closed endpoint)."""
174 176
175 177 if raw:
176 178 hist = self.shell.input_hist_raw
177 179 else:
178 180 hist = self.shell.input_hist
179 181
180 182 cmds = []
181 183 for chunk in slices:
182 184 if ':' in chunk:
183 185 ini,fin = map(int,chunk.split(':'))
184 186 elif '-' in chunk:
185 187 ini,fin = map(int,chunk.split('-'))
186 188 fin += 1
187 189 else:
188 190 ini = int(chunk)
189 191 fin = ini+1
190 192 cmds.append(hist[ini:fin])
191 193 return cmds
192 194
193 195 def _ofind(self, oname, namespaces=None):
194 196 """Find an object in the available namespaces.
195 197
196 198 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
197 199
198 200 Has special code to detect magic functions.
199 201 """
200 202
201 203 oname = oname.strip()
202 204
203 205 alias_ns = None
204 206 if namespaces is None:
205 207 # Namespaces to search in:
206 208 # Put them in a list. The order is important so that we
207 209 # find things in the same order that Python finds them.
208 210 namespaces = [ ('Interactive', self.shell.user_ns),
209 211 ('IPython internal', self.shell.internal_ns),
210 212 ('Python builtin', __builtin__.__dict__),
211 213 ('Alias', self.shell.alias_table),
212 214 ]
213 215 alias_ns = self.shell.alias_table
214 216
215 217 # initialize results to 'null'
216 218 found = 0; obj = None; ospace = None; ds = None;
217 219 ismagic = 0; isalias = 0; parent = None
218 220
219 221 # Look for the given name by splitting it in parts. If the head is
220 222 # found, then we look for all the remaining parts as members, and only
221 223 # declare success if we can find them all.
222 224 oname_parts = oname.split('.')
223 225 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
224 226 for nsname,ns in namespaces:
225 227 try:
226 228 obj = ns[oname_head]
227 229 except KeyError:
228 230 continue
229 231 else:
230 232 #print 'oname_rest:', oname_rest # dbg
231 233 for part in oname_rest:
232 234 try:
233 235 parent = obj
234 236 obj = getattr(obj,part)
235 237 except:
236 238 # Blanket except b/c some badly implemented objects
237 239 # allow __getattr__ to raise exceptions other than
238 240 # AttributeError, which then crashes IPython.
239 241 break
240 242 else:
241 243 # If we finish the for loop (no break), we got all members
242 244 found = 1
243 245 ospace = nsname
244 246 if ns == alias_ns:
245 247 isalias = 1
246 248 break # namespace loop
247 249
248 250 # Try to see if it's magic
249 251 if not found:
250 252 if oname.startswith(self.shell.ESC_MAGIC):
251 253 oname = oname[1:]
252 254 obj = getattr(self,'magic_'+oname,None)
253 255 if obj is not None:
254 256 found = 1
255 257 ospace = 'IPython internal'
256 258 ismagic = 1
257 259
258 260 # Last try: special-case some literals like '', [], {}, etc:
259 261 if not found and oname_head in ["''",'""','[]','{}','()']:
260 262 obj = eval(oname_head)
261 263 found = 1
262 264 ospace = 'Interactive'
263 265
264 266 return {'found':found, 'obj':obj, 'namespace':ospace,
265 267 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
266 268
267 269 def arg_err(self,func):
268 270 """Print docstring if incorrect arguments were passed"""
269 271 print 'Error in arguments:'
270 272 print OInspect.getdoc(func)
271 273
272 274 def format_latex(self,strng):
273 275 """Format a string for latex inclusion."""
274 276
275 277 # Characters that need to be escaped for latex:
276 278 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
277 279 # Magic command names as headers:
278 280 cmd_name_re = re.compile(r'^(%s.*?):' % self.shell.ESC_MAGIC,
279 281 re.MULTILINE)
280 282 # Magic commands
281 283 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % self.shell.ESC_MAGIC,
282 284 re.MULTILINE)
283 285 # Paragraph continue
284 286 par_re = re.compile(r'\\$',re.MULTILINE)
285 287
286 288 # The "\n" symbol
287 289 newline_re = re.compile(r'\\n')
288 290
289 291 # Now build the string for output:
290 292 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
291 293 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
292 294 strng)
293 295 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
294 296 strng = par_re.sub(r'\\\\',strng)
295 297 strng = escape_re.sub(r'\\\1',strng)
296 298 strng = newline_re.sub(r'\\textbackslash{}n',strng)
297 299 return strng
298 300
299 301 def format_screen(self,strng):
300 302 """Format a string for screen printing.
301 303
302 304 This removes some latex-type format codes."""
303 305 # Paragraph continue
304 306 par_re = re.compile(r'\\$',re.MULTILINE)
305 307 strng = par_re.sub('',strng)
306 308 return strng
307 309
308 310 def parse_options(self,arg_str,opt_str,*long_opts,**kw):
309 311 """Parse options passed to an argument string.
310 312
311 313 The interface is similar to that of getopt(), but it returns back a
312 314 Struct with the options as keys and the stripped argument string still
313 315 as a string.
314 316
315 317 arg_str is quoted as a true sys.argv vector by using shlex.split.
316 318 This allows us to easily expand variables, glob files, quote
317 319 arguments, etc.
318 320
319 321 Options:
320 322 -mode: default 'string'. If given as 'list', the argument string is
321 323 returned as a list (split on whitespace) instead of a string.
322 324
323 325 -list_all: put all option values in lists. Normally only options
324 326 appearing more than once are put in a list.
325 327
326 328 -posix (True): whether to split the input line in POSIX mode or not,
327 329 as per the conventions outlined in the shlex module from the
328 330 standard library."""
329 331
330 332 # inject default options at the beginning of the input line
331 333 caller = sys._getframe(1).f_code.co_name.replace('magic_','')
332 334 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
333 335
334 336 mode = kw.get('mode','string')
335 337 if mode not in ['string','list']:
336 338 raise ValueError,'incorrect mode given: %s' % mode
337 339 # Get options
338 340 list_all = kw.get('list_all',0)
339 341 posix = kw.get('posix',True)
340 342
341 343 # Check if we have more than one argument to warrant extra processing:
342 344 odict = {} # Dictionary with options
343 345 args = arg_str.split()
344 346 if len(args) >= 1:
345 347 # If the list of inputs only has 0 or 1 thing in it, there's no
346 348 # need to look for options
347 349 argv = arg_split(arg_str,posix)
348 350 # Do regular option processing
349 351 try:
350 352 opts,args = getopt(argv,opt_str,*long_opts)
351 353 except GetoptError,e:
352 354 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
353 355 " ".join(long_opts)))
354 356 for o,a in opts:
355 357 if o.startswith('--'):
356 358 o = o[2:]
357 359 else:
358 360 o = o[1:]
359 361 try:
360 362 odict[o].append(a)
361 363 except AttributeError:
362 364 odict[o] = [odict[o],a]
363 365 except KeyError:
364 366 if list_all:
365 367 odict[o] = [a]
366 368 else:
367 369 odict[o] = a
368 370
369 371 # Prepare opts,args for return
370 372 opts = Struct(odict)
371 373 if mode == 'string':
372 374 args = ' '.join(args)
373 375
374 376 return opts,args
375 377
376 378 #......................................................................
377 379 # And now the actual magic functions
378 380
379 381 # Functions for IPython shell work (vars,funcs, config, etc)
380 382 def magic_lsmagic(self, parameter_s = ''):
381 383 """List currently available magic functions."""
382 384 mesc = self.shell.ESC_MAGIC
383 385 print 'Available magic functions:\n'+mesc+\
384 386 (' '+mesc).join(self.lsmagic())
385 387 print '\n' + Magic.auto_status[self.shell.rc.automagic]
386 388 return None
387 389
388 390 def magic_magic(self, parameter_s = ''):
389 391 """Print information about the magic function system.
390 392
391 393 Supported formats: -latex, -brief, -rest
392 394 """
393 395
394 396 mode = ''
395 397 try:
396 398 if parameter_s.split()[0] == '-latex':
397 399 mode = 'latex'
398 400 if parameter_s.split()[0] == '-brief':
399 401 mode = 'brief'
400 402 if parameter_s.split()[0] == '-rest':
401 403 mode = 'rest'
402 404 rest_docs = []
403 405 except:
404 406 pass
405 407
406 408 magic_docs = []
407 409 for fname in self.lsmagic():
408 410 mname = 'magic_' + fname
409 411 for space in (Magic,self,self.__class__):
410 412 try:
411 413 fn = space.__dict__[mname]
412 414 except KeyError:
413 415 pass
414 416 else:
415 417 break
416 418 if mode == 'brief':
417 419 # only first line
418 420 if fn.__doc__:
419 421 fndoc = fn.__doc__.split('\n',1)[0]
420 422 else:
421 423 fndoc = 'No documentation'
422 424 else:
423 425 fndoc = fn.__doc__.rstrip()
424 426
425 427 if mode == 'rest':
426 428 rest_docs.append('**%s%s**::\n\n\t%s\n\n' %(self.shell.ESC_MAGIC,
427 429 fname,fndoc))
428 430
429 431 else:
430 432 magic_docs.append('%s%s:\n\t%s\n' %(self.shell.ESC_MAGIC,
431 433 fname,fndoc))
432 434
433 435 magic_docs = ''.join(magic_docs)
434 436
435 437 if mode == 'rest':
436 438 return "".join(rest_docs)
437 439
438 440 if mode == 'latex':
439 441 print self.format_latex(magic_docs)
440 442 return
441 443 else:
442 444 magic_docs = self.format_screen(magic_docs)
443 445 if mode == 'brief':
444 446 return magic_docs
445 447
446 448 outmsg = """
447 449 IPython's 'magic' functions
448 450 ===========================
449 451
450 452 The magic function system provides a series of functions which allow you to
451 453 control the behavior of IPython itself, plus a lot of system-type
452 454 features. All these functions are prefixed with a % character, but parameters
453 455 are given without parentheses or quotes.
454 456
455 457 NOTE: If you have 'automagic' enabled (via the command line option or with the
456 458 %automagic function), you don't need to type in the % explicitly. By default,
457 459 IPython ships with automagic on, so you should only rarely need the % escape.
458 460
459 461 Example: typing '%cd mydir' (without the quotes) changes you working directory
460 462 to 'mydir', if it exists.
461 463
462 464 You can define your own magic functions to extend the system. See the supplied
463 465 ipythonrc and example-magic.py files for details (in your ipython
464 466 configuration directory, typically $HOME/.ipython/).
465 467
466 468 You can also define your own aliased names for magic functions. In your
467 469 ipythonrc file, placing a line like:
468 470
469 471 execute __IPYTHON__.magic_pf = __IPYTHON__.magic_profile
470 472
471 473 will define %pf as a new name for %profile.
472 474
473 475 You can also call magics in code using the ipmagic() function, which IPython
474 476 automatically adds to the builtin namespace. Type 'ipmagic?' for details.
475 477
476 478 For a list of the available magic functions, use %lsmagic. For a description
477 479 of any of them, type %magic_name?, e.g. '%cd?'.
478 480
479 481 Currently the magic system has the following functions:\n"""
480 482
481 483 mesc = self.shell.ESC_MAGIC
482 484 outmsg = ("%s\n%s\n\nSummary of magic functions (from %slsmagic):"
483 485 "\n\n%s%s\n\n%s" % (outmsg,
484 486 magic_docs,mesc,mesc,
485 487 (' '+mesc).join(self.lsmagic()),
486 488 Magic.auto_status[self.shell.rc.automagic] ) )
487 489
488 490 page(outmsg,screen_lines=self.shell.rc.screen_length)
489 491
490 492
491 493 def magic_autoindent(self, parameter_s = ''):
492 494 """Toggle autoindent on/off (if available)."""
493 495
494 496 self.shell.set_autoindent()
495 497 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
496 498
497 499
498 500 def magic_automagic(self, parameter_s = ''):
499 501 """Make magic functions callable without having to type the initial %.
500 502
501 503 Without argumentsl toggles on/off (when off, you must call it as
502 504 %automagic, of course). With arguments it sets the value, and you can
503 505 use any of (case insensitive):
504 506
505 507 - on,1,True: to activate
506 508
507 509 - off,0,False: to deactivate.
508 510
509 511 Note that magic functions have lowest priority, so if there's a
510 512 variable whose name collides with that of a magic fn, automagic won't
511 513 work for that function (you get the variable instead). However, if you
512 514 delete the variable (del var), the previously shadowed magic function
513 515 becomes visible to automagic again."""
514 516
515 517 rc = self.shell.rc
516 518 arg = parameter_s.lower()
517 519 if parameter_s in ('on','1','true'):
518 520 rc.automagic = True
519 521 elif parameter_s in ('off','0','false'):
520 522 rc.automagic = False
521 523 else:
522 524 rc.automagic = not rc.automagic
523 525 print '\n' + Magic.auto_status[rc.automagic]
524 526
525
527 @testdec.skip_doctest
526 528 def magic_autocall(self, parameter_s = ''):
527 529 """Make functions callable without having to type parentheses.
528 530
529 531 Usage:
530 532
531 533 %autocall [mode]
532 534
533 535 The mode can be one of: 0->Off, 1->Smart, 2->Full. If not given, the
534 536 value is toggled on and off (remembering the previous state).
535 537
536 538 In more detail, these values mean:
537 539
538 540 0 -> fully disabled
539 541
540 542 1 -> active, but do not apply if there are no arguments on the line.
541 543
542 544 In this mode, you get:
543 545
544 546 In [1]: callable
545 547 Out[1]: <built-in function callable>
546 548
547 549 In [2]: callable 'hello'
548 550 ------> callable('hello')
549 551 Out[2]: False
550 552
551 553 2 -> Active always. Even if no arguments are present, the callable
552 554 object is called:
553 555
554 In [4]: callable
555 ------> callable()
556 In [2]: float
557 ------> float()
558 Out[2]: 0.0
556 559
557 560 Note that even with autocall off, you can still use '/' at the start of
558 561 a line to treat the first argument on the command line as a function
559 562 and add parentheses to it:
560 563
561 564 In [8]: /str 43
562 565 ------> str(43)
563 566 Out[8]: '43'
567
568 # all-random (note for auto-testing)
564 569 """
565 570
566 571 rc = self.shell.rc
567 572
568 573 if parameter_s:
569 574 arg = int(parameter_s)
570 575 else:
571 576 arg = 'toggle'
572 577
573 578 if not arg in (0,1,2,'toggle'):
574 579 error('Valid modes: (0->Off, 1->Smart, 2->Full')
575 580 return
576 581
577 582 if arg in (0,1,2):
578 583 rc.autocall = arg
579 584 else: # toggle
580 585 if rc.autocall:
581 586 self._magic_state.autocall_save = rc.autocall
582 587 rc.autocall = 0
583 588 else:
584 589 try:
585 590 rc.autocall = self._magic_state.autocall_save
586 591 except AttributeError:
587 592 rc.autocall = self._magic_state.autocall_save = 1
588 593
589 594 print "Automatic calling is:",['OFF','Smart','Full'][rc.autocall]
590 595
591 596 def magic_system_verbose(self, parameter_s = ''):
592 597 """Set verbose printing of system calls.
593 598
594 599 If called without an argument, act as a toggle"""
595 600
596 601 if parameter_s:
597 602 val = bool(eval(parameter_s))
598 603 else:
599 604 val = None
600 605
601 606 self.shell.rc_set_toggle('system_verbose',val)
602 607 print "System verbose printing is:",\
603 608 ['OFF','ON'][self.shell.rc.system_verbose]
604 609
605 610
606 611 def magic_page(self, parameter_s=''):
607 612 """Pretty print the object and display it through a pager.
608 613
609 614 %page [options] OBJECT
610 615
611 616 If no object is given, use _ (last output).
612 617
613 618 Options:
614 619
615 620 -r: page str(object), don't pretty-print it."""
616 621
617 622 # After a function contributed by Olivier Aubert, slightly modified.
618 623
619 624 # Process options/args
620 625 opts,args = self.parse_options(parameter_s,'r')
621 626 raw = 'r' in opts
622 627
623 628 oname = args and args or '_'
624 629 info = self._ofind(oname)
625 630 if info['found']:
626 631 txt = (raw and str or pformat)( info['obj'] )
627 632 page(txt)
628 633 else:
629 634 print 'Object `%s` not found' % oname
630 635
631 636 def magic_profile(self, parameter_s=''):
632 637 """Print your currently active IPyhton profile."""
633 638 if self.shell.rc.profile:
634 639 printpl('Current IPython profile: $self.shell.rc.profile.')
635 640 else:
636 641 print 'No profile active.'
637 642
638 643 def magic_pinfo(self, parameter_s='', namespaces=None):
639 644 """Provide detailed information about an object.
640 645
641 646 '%pinfo object' is just a synonym for object? or ?object."""
642 647
643 648 #print 'pinfo par: <%s>' % parameter_s # dbg
644 649
645 650
646 651 # detail_level: 0 -> obj? , 1 -> obj??
647 652 detail_level = 0
648 653 # We need to detect if we got called as 'pinfo pinfo foo', which can
649 654 # happen if the user types 'pinfo foo?' at the cmd line.
650 655 pinfo,qmark1,oname,qmark2 = \
651 656 re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
652 657 if pinfo or qmark1 or qmark2:
653 658 detail_level = 1
654 659 if "*" in oname:
655 660 self.magic_psearch(oname)
656 661 else:
657 662 self._inspect('pinfo', oname, detail_level=detail_level,
658 663 namespaces=namespaces)
659 664
660 665 def magic_pdef(self, parameter_s='', namespaces=None):
661 666 """Print the definition header for any callable object.
662 667
663 668 If the object is a class, print the constructor information."""
664 669 self._inspect('pdef',parameter_s, namespaces)
665 670
666 671 def magic_pdoc(self, parameter_s='', namespaces=None):
667 672 """Print the docstring for an object.
668 673
669 674 If the given object is a class, it will print both the class and the
670 675 constructor docstrings."""
671 676 self._inspect('pdoc',parameter_s, namespaces)
672 677
673 678 def magic_psource(self, parameter_s='', namespaces=None):
674 679 """Print (or run through pager) the source code for an object."""
675 680 self._inspect('psource',parameter_s, namespaces)
676 681
677 682 def magic_pfile(self, parameter_s=''):
678 683 """Print (or run through pager) the file where an object is defined.
679 684
680 685 The file opens at the line where the object definition begins. IPython
681 686 will honor the environment variable PAGER if set, and otherwise will
682 687 do its best to print the file in a convenient form.
683 688
684 689 If the given argument is not an object currently defined, IPython will
685 690 try to interpret it as a filename (automatically adding a .py extension
686 691 if needed). You can thus use %pfile as a syntax highlighting code
687 692 viewer."""
688 693
689 694 # first interpret argument as an object name
690 695 out = self._inspect('pfile',parameter_s)
691 696 # if not, try the input as a filename
692 697 if out == 'not found':
693 698 try:
694 699 filename = get_py_filename(parameter_s)
695 700 except IOError,msg:
696 701 print msg
697 702 return
698 703 page(self.shell.inspector.format(file(filename).read()))
699 704
700 705 def _inspect(self,meth,oname,namespaces=None,**kw):
701 706 """Generic interface to the inspector system.
702 707
703 708 This function is meant to be called by pdef, pdoc & friends."""
704 709
705 710 #oname = oname.strip()
706 711 #print '1- oname: <%r>' % oname # dbg
707 712 try:
708 713 oname = oname.strip().encode('ascii')
709 714 #print '2- oname: <%r>' % oname # dbg
710 715 except UnicodeEncodeError:
711 716 print 'Python identifiers can only contain ascii characters.'
712 717 return 'not found'
713 718
714 719 info = Struct(self._ofind(oname, namespaces))
715 720
716 721 if info.found:
717 722 try:
718 723 IPython.generics.inspect_object(info.obj)
719 724 return
720 725 except IPython.ipapi.TryNext:
721 726 pass
722 727 # Get the docstring of the class property if it exists.
723 728 path = oname.split('.')
724 729 root = '.'.join(path[:-1])
725 730 if info.parent is not None:
726 731 try:
727 732 target = getattr(info.parent, '__class__')
728 733 # The object belongs to a class instance.
729 734 try:
730 735 target = getattr(target, path[-1])
731 736 # The class defines the object.
732 737 if isinstance(target, property):
733 738 oname = root + '.__class__.' + path[-1]
734 739 info = Struct(self._ofind(oname))
735 740 except AttributeError: pass
736 741 except AttributeError: pass
737 742
738 743 pmethod = getattr(self.shell.inspector,meth)
739 744 formatter = info.ismagic and self.format_screen or None
740 745 if meth == 'pdoc':
741 746 pmethod(info.obj,oname,formatter)
742 747 elif meth == 'pinfo':
743 748 pmethod(info.obj,oname,formatter,info,**kw)
744 749 else:
745 750 pmethod(info.obj,oname)
746 751 else:
747 752 print 'Object `%s` not found.' % oname
748 753 return 'not found' # so callers can take other action
749 754
750 755 def magic_psearch(self, parameter_s=''):
751 756 """Search for object in namespaces by wildcard.
752 757
753 758 %psearch [options] PATTERN [OBJECT TYPE]
754 759
755 760 Note: ? can be used as a synonym for %psearch, at the beginning or at
756 761 the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
757 762 rest of the command line must be unchanged (options come first), so
758 763 for example the following forms are equivalent
759 764
760 765 %psearch -i a* function
761 766 -i a* function?
762 767 ?-i a* function
763 768
764 769 Arguments:
765 770
766 771 PATTERN
767 772
768 773 where PATTERN is a string containing * as a wildcard similar to its
769 774 use in a shell. The pattern is matched in all namespaces on the
770 775 search path. By default objects starting with a single _ are not
771 776 matched, many IPython generated objects have a single
772 777 underscore. The default is case insensitive matching. Matching is
773 778 also done on the attributes of objects and not only on the objects
774 779 in a module.
775 780
776 781 [OBJECT TYPE]
777 782
778 783 Is the name of a python type from the types module. The name is
779 784 given in lowercase without the ending type, ex. StringType is
780 785 written string. By adding a type here only objects matching the
781 786 given type are matched. Using all here makes the pattern match all
782 787 types (this is the default).
783 788
784 789 Options:
785 790
786 791 -a: makes the pattern match even objects whose names start with a
787 792 single underscore. These names are normally ommitted from the
788 793 search.
789 794
790 795 -i/-c: make the pattern case insensitive/sensitive. If neither of
791 796 these options is given, the default is read from your ipythonrc
792 797 file. The option name which sets this value is
793 798 'wildcards_case_sensitive'. If this option is not specified in your
794 799 ipythonrc file, IPython's internal default is to do a case sensitive
795 800 search.
796 801
797 802 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
798 803 specifiy can be searched in any of the following namespaces:
799 804 'builtin', 'user', 'user_global','internal', 'alias', where
800 805 'builtin' and 'user' are the search defaults. Note that you should
801 806 not use quotes when specifying namespaces.
802 807
803 808 'Builtin' contains the python module builtin, 'user' contains all
804 809 user data, 'alias' only contain the shell aliases and no python
805 810 objects, 'internal' contains objects used by IPython. The
806 811 'user_global' namespace is only used by embedded IPython instances,
807 812 and it contains module-level globals. You can add namespaces to the
808 813 search with -s or exclude them with -e (these options can be given
809 814 more than once).
810 815
811 816 Examples:
812 817
813 818 %psearch a* -> objects beginning with an a
814 819 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
815 820 %psearch a* function -> all functions beginning with an a
816 821 %psearch re.e* -> objects beginning with an e in module re
817 822 %psearch r*.e* -> objects that start with e in modules starting in r
818 823 %psearch r*.* string -> all strings in modules beginning with r
819 824
820 825 Case sensitve search:
821 826
822 827 %psearch -c a* list all object beginning with lower case a
823 828
824 829 Show objects beginning with a single _:
825 830
826 831 %psearch -a _* list objects beginning with a single underscore"""
827 832 try:
828 833 parameter_s = parameter_s.encode('ascii')
829 834 except UnicodeEncodeError:
830 835 print 'Python identifiers can only contain ascii characters.'
831 836 return
832 837
833 838 # default namespaces to be searched
834 839 def_search = ['user','builtin']
835 840
836 841 # Process options/args
837 842 opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True)
838 843 opt = opts.get
839 844 shell = self.shell
840 845 psearch = shell.inspector.psearch
841 846
842 847 # select case options
843 848 if opts.has_key('i'):
844 849 ignore_case = True
845 850 elif opts.has_key('c'):
846 851 ignore_case = False
847 852 else:
848 853 ignore_case = not shell.rc.wildcards_case_sensitive
849 854
850 855 # Build list of namespaces to search from user options
851 856 def_search.extend(opt('s',[]))
852 857 ns_exclude = ns_exclude=opt('e',[])
853 858 ns_search = [nm for nm in def_search if nm not in ns_exclude]
854 859
855 860 # Call the actual search
856 861 try:
857 862 psearch(args,shell.ns_table,ns_search,
858 863 show_all=opt('a'),ignore_case=ignore_case)
859 864 except:
860 865 shell.showtraceback()
861 866
862 867 def magic_who_ls(self, parameter_s=''):
863 868 """Return a sorted list of all interactive variables.
864 869
865 870 If arguments are given, only variables of types matching these
866 871 arguments are returned."""
867 872
868 873 user_ns = self.shell.user_ns
869 874 internal_ns = self.shell.internal_ns
870 875 user_config_ns = self.shell.user_config_ns
871 876 out = []
872 877 typelist = parameter_s.split()
873 878
874 879 for i in user_ns:
875 880 if not (i.startswith('_') or i.startswith('_i')) \
876 881 and not (i in internal_ns or i in user_config_ns):
877 882 if typelist:
878 883 if type(user_ns[i]).__name__ in typelist:
879 884 out.append(i)
880 885 else:
881 886 out.append(i)
882 887 out.sort()
883 888 return out
884 889
885 890 def magic_who(self, parameter_s=''):
886 891 """Print all interactive variables, with some minimal formatting.
887 892
888 893 If any arguments are given, only variables whose type matches one of
889 894 these are printed. For example:
890 895
891 896 %who function str
892 897
893 898 will only list functions and strings, excluding all other types of
894 899 variables. To find the proper type names, simply use type(var) at a
895 900 command line to see how python prints type names. For example:
896 901
897 902 In [1]: type('hello')\\
898 903 Out[1]: <type 'str'>
899 904
900 905 indicates that the type name for strings is 'str'.
901 906
902 907 %who always excludes executed names loaded through your configuration
903 908 file and things which are internal to IPython.
904 909
905 910 This is deliberate, as typically you may load many modules and the
906 911 purpose of %who is to show you only what you've manually defined."""
907 912
908 913 varlist = self.magic_who_ls(parameter_s)
909 914 if not varlist:
910 915 if parameter_s:
911 916 print 'No variables match your requested type.'
912 917 else:
913 918 print 'Interactive namespace is empty.'
914 919 return
915 920
916 921 # if we have variables, move on...
917 922 count = 0
918 923 for i in varlist:
919 924 print i+'\t',
920 925 count += 1
921 926 if count > 8:
922 927 count = 0
923 928 print
924 929 print
925 930
926 931 def magic_whos(self, parameter_s=''):
927 932 """Like %who, but gives some extra information about each variable.
928 933
929 934 The same type filtering of %who can be applied here.
930 935
931 936 For all variables, the type is printed. Additionally it prints:
932 937
933 938 - For {},[],(): their length.
934 939
935 940 - For numpy and Numeric arrays, a summary with shape, number of
936 941 elements, typecode and size in memory.
937 942
938 943 - Everything else: a string representation, snipping their middle if
939 944 too long."""
940 945
941 946 varnames = self.magic_who_ls(parameter_s)
942 947 if not varnames:
943 948 if parameter_s:
944 949 print 'No variables match your requested type.'
945 950 else:
946 951 print 'Interactive namespace is empty.'
947 952 return
948 953
949 954 # if we have variables, move on...
950 955
951 956 # for these types, show len() instead of data:
952 957 seq_types = [types.DictType,types.ListType,types.TupleType]
953 958
954 959 # for numpy/Numeric arrays, display summary info
955 960 try:
956 961 import numpy
957 962 except ImportError:
958 963 ndarray_type = None
959 964 else:
960 965 ndarray_type = numpy.ndarray.__name__
961 966 try:
962 967 import Numeric
963 968 except ImportError:
964 969 array_type = None
965 970 else:
966 971 array_type = Numeric.ArrayType.__name__
967 972
968 973 # Find all variable names and types so we can figure out column sizes
969 974 def get_vars(i):
970 975 return self.shell.user_ns[i]
971 976
972 977 # some types are well known and can be shorter
973 978 abbrevs = {'IPython.macro.Macro' : 'Macro'}
974 979 def type_name(v):
975 980 tn = type(v).__name__
976 981 return abbrevs.get(tn,tn)
977 982
978 983 varlist = map(get_vars,varnames)
979 984
980 985 typelist = []
981 986 for vv in varlist:
982 987 tt = type_name(vv)
983 988
984 989 if tt=='instance':
985 990 typelist.append( abbrevs.get(str(vv.__class__),
986 991 str(vv.__class__)))
987 992 else:
988 993 typelist.append(tt)
989 994
990 995 # column labels and # of spaces as separator
991 996 varlabel = 'Variable'
992 997 typelabel = 'Type'
993 998 datalabel = 'Data/Info'
994 999 colsep = 3
995 1000 # variable format strings
996 1001 vformat = "$vname.ljust(varwidth)$vtype.ljust(typewidth)"
997 1002 vfmt_short = '$vstr[:25]<...>$vstr[-25:]'
998 1003 aformat = "%s: %s elems, type `%s`, %s bytes"
999 1004 # find the size of the columns to format the output nicely
1000 1005 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
1001 1006 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
1002 1007 # table header
1003 1008 print varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
1004 1009 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1)
1005 1010 # and the table itself
1006 1011 kb = 1024
1007 1012 Mb = 1048576 # kb**2
1008 1013 for vname,var,vtype in zip(varnames,varlist,typelist):
1009 1014 print itpl(vformat),
1010 1015 if vtype in seq_types:
1011 1016 print len(var)
1012 1017 elif vtype in [array_type,ndarray_type]:
1013 1018 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
1014 1019 if vtype==ndarray_type:
1015 1020 # numpy
1016 1021 vsize = var.size
1017 1022 vbytes = vsize*var.itemsize
1018 1023 vdtype = var.dtype
1019 1024 else:
1020 1025 # Numeric
1021 1026 vsize = Numeric.size(var)
1022 1027 vbytes = vsize*var.itemsize()
1023 1028 vdtype = var.typecode()
1024 1029
1025 1030 if vbytes < 100000:
1026 1031 print aformat % (vshape,vsize,vdtype,vbytes)
1027 1032 else:
1028 1033 print aformat % (vshape,vsize,vdtype,vbytes),
1029 1034 if vbytes < Mb:
1030 1035 print '(%s kb)' % (vbytes/kb,)
1031 1036 else:
1032 1037 print '(%s Mb)' % (vbytes/Mb,)
1033 1038 else:
1034 1039 try:
1035 1040 vstr = str(var)
1036 1041 except UnicodeEncodeError:
1037 1042 vstr = unicode(var).encode(sys.getdefaultencoding(),
1038 1043 'backslashreplace')
1039 1044 vstr = vstr.replace('\n','\\n')
1040 1045 if len(vstr) < 50:
1041 1046 print vstr
1042 1047 else:
1043 1048 printpl(vfmt_short)
1044 1049
1045 1050 def magic_reset(self, parameter_s=''):
1046 1051 """Resets the namespace by removing all names defined by the user.
1047 1052
1048 1053 Input/Output history are left around in case you need them."""
1049 1054
1050 1055 ans = self.shell.ask_yes_no(
1051 1056 "Once deleted, variables cannot be recovered. Proceed (y/[n])? ")
1052 1057 if not ans:
1053 1058 print 'Nothing done.'
1054 1059 return
1055 1060 user_ns = self.shell.user_ns
1056 1061 for i in self.magic_who_ls():
1057 1062 del(user_ns[i])
1058 1063
1059 1064 # Also flush the private list of module references kept for script
1060 1065 # execution protection
1061 1066 self.shell._user_main_modules[:] = []
1062 1067
1063 1068 def magic_logstart(self,parameter_s=''):
1064 1069 """Start logging anywhere in a session.
1065 1070
1066 1071 %logstart [-o|-r|-t] [log_name [log_mode]]
1067 1072
1068 1073 If no name is given, it defaults to a file named 'ipython_log.py' in your
1069 1074 current directory, in 'rotate' mode (see below).
1070 1075
1071 1076 '%logstart name' saves to file 'name' in 'backup' mode. It saves your
1072 1077 history up to that point and then continues logging.
1073 1078
1074 1079 %logstart takes a second optional parameter: logging mode. This can be one
1075 1080 of (note that the modes are given unquoted):\\
1076 1081 append: well, that says it.\\
1077 1082 backup: rename (if exists) to name~ and start name.\\
1078 1083 global: single logfile in your home dir, appended to.\\
1079 1084 over : overwrite existing log.\\
1080 1085 rotate: create rotating logs name.1~, name.2~, etc.
1081 1086
1082 1087 Options:
1083 1088
1084 1089 -o: log also IPython's output. In this mode, all commands which
1085 1090 generate an Out[NN] prompt are recorded to the logfile, right after
1086 1091 their corresponding input line. The output lines are always
1087 1092 prepended with a '#[Out]# ' marker, so that the log remains valid
1088 1093 Python code.
1089 1094
1090 1095 Since this marker is always the same, filtering only the output from
1091 1096 a log is very easy, using for example a simple awk call:
1092 1097
1093 1098 awk -F'#\\[Out\\]# ' '{if($2) {print $2}}' ipython_log.py
1094 1099
1095 1100 -r: log 'raw' input. Normally, IPython's logs contain the processed
1096 1101 input, so that user lines are logged in their final form, converted
1097 1102 into valid Python. For example, %Exit is logged as
1098 1103 '_ip.magic("Exit"). If the -r flag is given, all input is logged
1099 1104 exactly as typed, with no transformations applied.
1100 1105
1101 1106 -t: put timestamps before each input line logged (these are put in
1102 1107 comments)."""
1103 1108
1104 1109 opts,par = self.parse_options(parameter_s,'ort')
1105 1110 log_output = 'o' in opts
1106 1111 log_raw_input = 'r' in opts
1107 1112 timestamp = 't' in opts
1108 1113
1109 1114 rc = self.shell.rc
1110 1115 logger = self.shell.logger
1111 1116
1112 1117 # if no args are given, the defaults set in the logger constructor by
1113 1118 # ipytohn remain valid
1114 1119 if par:
1115 1120 try:
1116 1121 logfname,logmode = par.split()
1117 1122 except:
1118 1123 logfname = par
1119 1124 logmode = 'backup'
1120 1125 else:
1121 1126 logfname = logger.logfname
1122 1127 logmode = logger.logmode
1123 1128 # put logfname into rc struct as if it had been called on the command
1124 1129 # line, so it ends up saved in the log header Save it in case we need
1125 1130 # to restore it...
1126 1131 old_logfile = rc.opts.get('logfile','')
1127 1132 if logfname:
1128 1133 logfname = os.path.expanduser(logfname)
1129 1134 rc.opts.logfile = logfname
1130 1135 loghead = self.shell.loghead_tpl % (rc.opts,rc.args)
1131 1136 try:
1132 1137 started = logger.logstart(logfname,loghead,logmode,
1133 1138 log_output,timestamp,log_raw_input)
1134 1139 except:
1135 1140 rc.opts.logfile = old_logfile
1136 1141 warn("Couldn't start log: %s" % sys.exc_info()[1])
1137 1142 else:
1138 1143 # log input history up to this point, optionally interleaving
1139 1144 # output if requested
1140 1145
1141 1146 if timestamp:
1142 1147 # disable timestamping for the previous history, since we've
1143 1148 # lost those already (no time machine here).
1144 1149 logger.timestamp = False
1145 1150
1146 1151 if log_raw_input:
1147 1152 input_hist = self.shell.input_hist_raw
1148 1153 else:
1149 1154 input_hist = self.shell.input_hist
1150 1155
1151 1156 if log_output:
1152 1157 log_write = logger.log_write
1153 1158 output_hist = self.shell.output_hist
1154 1159 for n in range(1,len(input_hist)-1):
1155 1160 log_write(input_hist[n].rstrip())
1156 1161 if n in output_hist:
1157 1162 log_write(repr(output_hist[n]),'output')
1158 1163 else:
1159 1164 logger.log_write(input_hist[1:])
1160 1165 if timestamp:
1161 1166 # re-enable timestamping
1162 1167 logger.timestamp = True
1163 1168
1164 1169 print ('Activating auto-logging. '
1165 1170 'Current session state plus future input saved.')
1166 1171 logger.logstate()
1167 1172
1168 1173 def magic_logstop(self,parameter_s=''):
1169 1174 """Fully stop logging and close log file.
1170 1175
1171 1176 In order to start logging again, a new %logstart call needs to be made,
1172 1177 possibly (though not necessarily) with a new filename, mode and other
1173 1178 options."""
1174 1179 self.logger.logstop()
1175 1180
1176 1181 def magic_logoff(self,parameter_s=''):
1177 1182 """Temporarily stop logging.
1178 1183
1179 1184 You must have previously started logging."""
1180 1185 self.shell.logger.switch_log(0)
1181 1186
1182 1187 def magic_logon(self,parameter_s=''):
1183 1188 """Restart logging.
1184 1189
1185 1190 This function is for restarting logging which you've temporarily
1186 1191 stopped with %logoff. For starting logging for the first time, you
1187 1192 must use the %logstart function, which allows you to specify an
1188 1193 optional log filename."""
1189 1194
1190 1195 self.shell.logger.switch_log(1)
1191 1196
1192 1197 def magic_logstate(self,parameter_s=''):
1193 1198 """Print the status of the logging system."""
1194 1199
1195 1200 self.shell.logger.logstate()
1196 1201
1197 1202 def magic_pdb(self, parameter_s=''):
1198 1203 """Control the automatic calling of the pdb interactive debugger.
1199 1204
1200 1205 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
1201 1206 argument it works as a toggle.
1202 1207
1203 1208 When an exception is triggered, IPython can optionally call the
1204 1209 interactive pdb debugger after the traceback printout. %pdb toggles
1205 1210 this feature on and off.
1206 1211
1207 1212 The initial state of this feature is set in your ipythonrc
1208 1213 configuration file (the variable is called 'pdb').
1209 1214
1210 1215 If you want to just activate the debugger AFTER an exception has fired,
1211 1216 without having to type '%pdb on' and rerunning your code, you can use
1212 1217 the %debug magic."""
1213 1218
1214 1219 par = parameter_s.strip().lower()
1215 1220
1216 1221 if par:
1217 1222 try:
1218 1223 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
1219 1224 except KeyError:
1220 1225 print ('Incorrect argument. Use on/1, off/0, '
1221 1226 'or nothing for a toggle.')
1222 1227 return
1223 1228 else:
1224 1229 # toggle
1225 1230 new_pdb = not self.shell.call_pdb
1226 1231
1227 1232 # set on the shell
1228 1233 self.shell.call_pdb = new_pdb
1229 1234 print 'Automatic pdb calling has been turned',on_off(new_pdb)
1230 1235
1231 1236 def magic_debug(self, parameter_s=''):
1232 1237 """Activate the interactive debugger in post-mortem mode.
1233 1238
1234 1239 If an exception has just occurred, this lets you inspect its stack
1235 1240 frames interactively. Note that this will always work only on the last
1236 1241 traceback that occurred, so you must call this quickly after an
1237 1242 exception that you wish to inspect has fired, because if another one
1238 1243 occurs, it clobbers the previous one.
1239 1244
1240 1245 If you want IPython to automatically do this on every exception, see
1241 1246 the %pdb magic for more details.
1242 1247 """
1243 1248
1244 1249 self.shell.debugger(force=True)
1245 1250
1251 @testdec.skip_doctest
1246 1252 def magic_prun(self, parameter_s ='',user_mode=1,
1247 1253 opts=None,arg_lst=None,prog_ns=None):
1248 1254
1249 1255 """Run a statement through the python code profiler.
1250 1256
1251 Usage:\\
1257 Usage:
1252 1258 %prun [options] statement
1253 1259
1254 1260 The given statement (which doesn't require quote marks) is run via the
1255 1261 python profiler in a manner similar to the profile.run() function.
1256 1262 Namespaces are internally managed to work correctly; profile.run
1257 1263 cannot be used in IPython because it makes certain assumptions about
1258 1264 namespaces which do not hold under IPython.
1259 1265
1260 1266 Options:
1261 1267
1262 1268 -l <limit>: you can place restrictions on what or how much of the
1263 1269 profile gets printed. The limit value can be:
1264 1270
1265 1271 * A string: only information for function names containing this string
1266 1272 is printed.
1267 1273
1268 1274 * An integer: only these many lines are printed.
1269 1275
1270 1276 * A float (between 0 and 1): this fraction of the report is printed
1271 1277 (for example, use a limit of 0.4 to see the topmost 40% only).
1272 1278
1273 1279 You can combine several limits with repeated use of the option. For
1274 1280 example, '-l __init__ -l 5' will print only the topmost 5 lines of
1275 1281 information about class constructors.
1276 1282
1277 1283 -r: return the pstats.Stats object generated by the profiling. This
1278 1284 object has all the information about the profile in it, and you can
1279 1285 later use it for further analysis or in other functions.
1280 1286
1281 1287 -s <key>: sort profile by given key. You can provide more than one key
1282 1288 by using the option several times: '-s key1 -s key2 -s key3...'. The
1283 1289 default sorting key is 'time'.
1284 1290
1285 1291 The following is copied verbatim from the profile documentation
1286 1292 referenced below:
1287 1293
1288 1294 When more than one key is provided, additional keys are used as
1289 1295 secondary criteria when the there is equality in all keys selected
1290 1296 before them.
1291 1297
1292 1298 Abbreviations can be used for any key names, as long as the
1293 1299 abbreviation is unambiguous. The following are the keys currently
1294 1300 defined:
1295 1301
1296 Valid Arg Meaning\\
1297 "calls" call count\\
1298 "cumulative" cumulative time\\
1299 "file" file name\\
1300 "module" file name\\
1301 "pcalls" primitive call count\\
1302 "line" line number\\
1303 "name" function name\\
1304 "nfl" name/file/line\\
1305 "stdname" standard name\\
1302 Valid Arg Meaning
1303 "calls" call count
1304 "cumulative" cumulative time
1305 "file" file name
1306 "module" file name
1307 "pcalls" primitive call count
1308 "line" line number
1309 "name" function name
1310 "nfl" name/file/line
1311 "stdname" standard name
1306 1312 "time" internal time
1307 1313
1308 1314 Note that all sorts on statistics are in descending order (placing
1309 1315 most time consuming items first), where as name, file, and line number
1310 1316 searches are in ascending order (i.e., alphabetical). The subtle
1311 1317 distinction between "nfl" and "stdname" is that the standard name is a
1312 1318 sort of the name as printed, which means that the embedded line
1313 1319 numbers get compared in an odd way. For example, lines 3, 20, and 40
1314 1320 would (if the file names were the same) appear in the string order
1315 1321 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
1316 1322 line numbers. In fact, sort_stats("nfl") is the same as
1317 1323 sort_stats("name", "file", "line").
1318 1324
1319 1325 -T <filename>: save profile results as shown on screen to a text
1320 1326 file. The profile is still shown on screen.
1321 1327
1322 1328 -D <filename>: save (via dump_stats) profile statistics to given
1323 1329 filename. This data is in a format understod by the pstats module, and
1324 1330 is generated by a call to the dump_stats() method of profile
1325 1331 objects. The profile is still shown on screen.
1326 1332
1327 1333 If you want to run complete programs under the profiler's control, use
1328 1334 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
1329 1335 contains profiler specific options as described here.
1330 1336
1331 You can read the complete documentation for the profile module with:\\
1332 In [1]: import profile; profile.help() """
1337 You can read the complete documentation for the profile module with::
1338
1339 In [1]: import profile; profile.help()
1340 """
1333 1341
1334 1342 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
1335 1343 # protect user quote marks
1336 1344 parameter_s = parameter_s.replace('"',r'\"').replace("'",r"\'")
1337 1345
1338 1346 if user_mode: # regular user call
1339 1347 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:',
1340 1348 list_all=1)
1341 1349 namespace = self.shell.user_ns
1342 1350 else: # called to run a program by %run -p
1343 1351 try:
1344 1352 filename = get_py_filename(arg_lst[0])
1345 1353 except IOError,msg:
1346 1354 error(msg)
1347 1355 return
1348 1356
1349 1357 arg_str = 'execfile(filename,prog_ns)'
1350 1358 namespace = locals()
1351 1359
1352 1360 opts.merge(opts_def)
1353 1361
1354 1362 prof = profile.Profile()
1355 1363 try:
1356 1364 prof = prof.runctx(arg_str,namespace,namespace)
1357 1365 sys_exit = ''
1358 1366 except SystemExit:
1359 1367 sys_exit = """*** SystemExit exception caught in code being profiled."""
1360 1368
1361 1369 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
1362 1370
1363 1371 lims = opts.l
1364 1372 if lims:
1365 1373 lims = [] # rebuild lims with ints/floats/strings
1366 1374 for lim in opts.l:
1367 1375 try:
1368 1376 lims.append(int(lim))
1369 1377 except ValueError:
1370 1378 try:
1371 1379 lims.append(float(lim))
1372 1380 except ValueError:
1373 1381 lims.append(lim)
1374 1382
1375 1383 # Trap output.
1376 1384 stdout_trap = StringIO()
1377 1385
1378 1386 if hasattr(stats,'stream'):
1379 1387 # In newer versions of python, the stats object has a 'stream'
1380 1388 # attribute to write into.
1381 1389 stats.stream = stdout_trap
1382 1390 stats.print_stats(*lims)
1383 1391 else:
1384 1392 # For older versions, we manually redirect stdout during printing
1385 1393 sys_stdout = sys.stdout
1386 1394 try:
1387 1395 sys.stdout = stdout_trap
1388 1396 stats.print_stats(*lims)
1389 1397 finally:
1390 1398 sys.stdout = sys_stdout
1391 1399
1392 1400 output = stdout_trap.getvalue()
1393 1401 output = output.rstrip()
1394 1402
1395 1403 page(output,screen_lines=self.shell.rc.screen_length)
1396 1404 print sys_exit,
1397 1405
1398 1406 dump_file = opts.D[0]
1399 1407 text_file = opts.T[0]
1400 1408 if dump_file:
1401 1409 prof.dump_stats(dump_file)
1402 1410 print '\n*** Profile stats marshalled to file',\
1403 1411 `dump_file`+'.',sys_exit
1404 1412 if text_file:
1405 1413 pfile = file(text_file,'w')
1406 1414 pfile.write(output)
1407 1415 pfile.close()
1408 1416 print '\n*** Profile printout saved to text file',\
1409 1417 `text_file`+'.',sys_exit
1410 1418
1411 1419 if opts.has_key('r'):
1412 1420 return stats
1413 1421 else:
1414 1422 return None
1415 1423
1424 @testdec.skip_doctest
1416 1425 def magic_run(self, parameter_s ='',runner=None):
1417 1426 """Run the named file inside IPython as a program.
1418 1427
1419 1428 Usage:\\
1420 1429 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options]] file [args]
1421 1430
1422 1431 Parameters after the filename are passed as command-line arguments to
1423 1432 the program (put in sys.argv). Then, control returns to IPython's
1424 1433 prompt.
1425 1434
1426 1435 This is similar to running at a system prompt:\\
1427 1436 $ python file args\\
1428 1437 but with the advantage of giving you IPython's tracebacks, and of
1429 1438 loading all variables into your interactive namespace for further use
1430 1439 (unless -p is used, see below).
1431 1440
1432 1441 The file is executed in a namespace initially consisting only of
1433 1442 __name__=='__main__' and sys.argv constructed as indicated. It thus
1434 1443 sees its environment as if it were being run as a stand-alone program
1435 1444 (except for sharing global objects such as previously imported
1436 1445 modules). But after execution, the IPython interactive namespace gets
1437 1446 updated with all variables defined in the program (except for __name__
1438 1447 and sys.argv). This allows for very convenient loading of code for
1439 1448 interactive work, while giving each program a 'clean sheet' to run in.
1440 1449
1441 1450 Options:
1442 1451
1443 1452 -n: __name__ is NOT set to '__main__', but to the running file's name
1444 1453 without extension (as python does under import). This allows running
1445 1454 scripts and reloading the definitions in them without calling code
1446 1455 protected by an ' if __name__ == "__main__" ' clause.
1447 1456
1448 1457 -i: run the file in IPython's namespace instead of an empty one. This
1449 1458 is useful if you are experimenting with code written in a text editor
1450 1459 which depends on variables defined interactively.
1451 1460
1452 1461 -e: ignore sys.exit() calls or SystemExit exceptions in the script
1453 1462 being run. This is particularly useful if IPython is being used to
1454 1463 run unittests, which always exit with a sys.exit() call. In such
1455 1464 cases you are interested in the output of the test results, not in
1456 1465 seeing a traceback of the unittest module.
1457 1466
1458 1467 -t: print timing information at the end of the run. IPython will give
1459 1468 you an estimated CPU time consumption for your script, which under
1460 1469 Unix uses the resource module to avoid the wraparound problems of
1461 1470 time.clock(). Under Unix, an estimate of time spent on system tasks
1462 1471 is also given (for Windows platforms this is reported as 0.0).
1463 1472
1464 1473 If -t is given, an additional -N<N> option can be given, where <N>
1465 1474 must be an integer indicating how many times you want the script to
1466 1475 run. The final timing report will include total and per run results.
1467 1476
1468 1477 For example (testing the script uniq_stable.py):
1469 1478
1470 1479 In [1]: run -t uniq_stable
1471 1480
1472 1481 IPython CPU timings (estimated):\\
1473 1482 User : 0.19597 s.\\
1474 1483 System: 0.0 s.\\
1475 1484
1476 1485 In [2]: run -t -N5 uniq_stable
1477 1486
1478 1487 IPython CPU timings (estimated):\\
1479 1488 Total runs performed: 5\\
1480 1489 Times : Total Per run\\
1481 1490 User : 0.910862 s, 0.1821724 s.\\
1482 1491 System: 0.0 s, 0.0 s.
1483 1492
1484 1493 -d: run your program under the control of pdb, the Python debugger.
1485 1494 This allows you to execute your program step by step, watch variables,
1486 1495 etc. Internally, what IPython does is similar to calling:
1487 1496
1488 1497 pdb.run('execfile("YOURFILENAME")')
1489 1498
1490 1499 with a breakpoint set on line 1 of your file. You can change the line
1491 1500 number for this automatic breakpoint to be <N> by using the -bN option
1492 1501 (where N must be an integer). For example:
1493 1502
1494 1503 %run -d -b40 myscript
1495 1504
1496 1505 will set the first breakpoint at line 40 in myscript.py. Note that
1497 1506 the first breakpoint must be set on a line which actually does
1498 1507 something (not a comment or docstring) for it to stop execution.
1499 1508
1500 1509 When the pdb debugger starts, you will see a (Pdb) prompt. You must
1501 1510 first enter 'c' (without qoutes) to start execution up to the first
1502 1511 breakpoint.
1503 1512
1504 1513 Entering 'help' gives information about the use of the debugger. You
1505 1514 can easily see pdb's full documentation with "import pdb;pdb.help()"
1506 1515 at a prompt.
1507 1516
1508 1517 -p: run program under the control of the Python profiler module (which
1509 1518 prints a detailed report of execution times, function calls, etc).
1510 1519
1511 1520 You can pass other options after -p which affect the behavior of the
1512 1521 profiler itself. See the docs for %prun for details.
1513 1522
1514 1523 In this mode, the program's variables do NOT propagate back to the
1515 1524 IPython interactive namespace (because they remain in the namespace
1516 1525 where the profiler executes them).
1517 1526
1518 1527 Internally this triggers a call to %prun, see its documentation for
1519 1528 details on the options available specifically for profiling.
1520 1529
1521 1530 There is one special usage for which the text above doesn't apply:
1522 1531 if the filename ends with .ipy, the file is run as ipython script,
1523 1532 just as if the commands were written on IPython prompt.
1524 1533 """
1525 1534
1526 1535 # get arguments and set sys.argv for program to be run.
1527 1536 opts,arg_lst = self.parse_options(parameter_s,'nidtN:b:pD:l:rs:T:e',
1528 1537 mode='list',list_all=1)
1529 1538
1530 1539 try:
1531 1540 filename = get_py_filename(arg_lst[0])
1532 1541 except IndexError:
1533 1542 warn('you must provide at least a filename.')
1534 1543 print '\n%run:\n',OInspect.getdoc(self.magic_run)
1535 1544 return
1536 1545 except IOError,msg:
1537 1546 error(msg)
1538 1547 return
1539 1548
1540 1549 if filename.lower().endswith('.ipy'):
1541 1550 self.api.runlines(open(filename).read())
1542 1551 return
1543 1552
1544 1553 # Control the response to exit() calls made by the script being run
1545 1554 exit_ignore = opts.has_key('e')
1546 1555
1547 1556 # Make sure that the running script gets a proper sys.argv as if it
1548 1557 # were run from a system shell.
1549 1558 save_argv = sys.argv # save it for later restoring
1550 1559 sys.argv = [filename]+ arg_lst[1:] # put in the proper filename
1551 1560
1552 1561 if opts.has_key('i'):
1553 1562 # Run in user's interactive namespace
1554 1563 prog_ns = self.shell.user_ns
1555 1564 __name__save = self.shell.user_ns['__name__']
1556 1565 prog_ns['__name__'] = '__main__'
1557 1566 main_mod = FakeModule(prog_ns)
1558 1567 else:
1559 1568 # Run in a fresh, empty namespace
1560 1569 if opts.has_key('n'):
1561 1570 name = os.path.splitext(os.path.basename(filename))[0]
1562 1571 else:
1563 1572 name = '__main__'
1564 1573 main_mod = FakeModule()
1565 1574 prog_ns = main_mod.__dict__
1566 1575 prog_ns['__name__'] = name
1567 1576 # The shell MUST hold a reference to main_mod so after %run exits,
1568 1577 # the python deletion mechanism doesn't zero it out (leaving
1569 1578 # dangling references)
1570 1579 self.shell._user_main_modules.append(main_mod)
1571 1580
1572 1581 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
1573 1582 # set the __file__ global in the script's namespace
1574 1583 prog_ns['__file__'] = filename
1575 1584
1576 1585 # pickle fix. See iplib for an explanation. But we need to make sure
1577 1586 # that, if we overwrite __main__, we replace it at the end
1578 if prog_ns['__name__'] == '__main__':
1587 main_mod_name = prog_ns['__name__']
1588
1589 if main_mod_name == '__main__':
1579 1590 restore_main = sys.modules['__main__']
1580 1591 else:
1581 1592 restore_main = False
1582 1593
1583 sys.modules[prog_ns['__name__']] = main_mod
1594 # This needs to be undone at the end to prevent holding references to
1595 # every single object ever created.
1596 sys.modules[main_mod_name] = main_mod
1584 1597
1585 1598 stats = None
1586 1599 try:
1587 1600 self.shell.savehist()
1588 1601
1589 1602 if opts.has_key('p'):
1590 1603 stats = self.magic_prun('',0,opts,arg_lst,prog_ns)
1591 1604 else:
1592 1605 if opts.has_key('d'):
1593 1606 deb = Debugger.Pdb(self.shell.rc.colors)
1594 1607 # reset Breakpoint state, which is moronically kept
1595 1608 # in a class
1596 1609 bdb.Breakpoint.next = 1
1597 1610 bdb.Breakpoint.bplist = {}
1598 1611 bdb.Breakpoint.bpbynumber = [None]
1599 1612 # Set an initial breakpoint to stop execution
1600 1613 maxtries = 10
1601 1614 bp = int(opts.get('b',[1])[0])
1602 1615 checkline = deb.checkline(filename,bp)
1603 1616 if not checkline:
1604 1617 for bp in range(bp+1,bp+maxtries+1):
1605 1618 if deb.checkline(filename,bp):
1606 1619 break
1607 1620 else:
1608 1621 msg = ("\nI failed to find a valid line to set "
1609 1622 "a breakpoint\n"
1610 1623 "after trying up to line: %s.\n"
1611 1624 "Please set a valid breakpoint manually "
1612 1625 "with the -b option." % bp)
1613 1626 error(msg)
1614 1627 return
1615 1628 # if we find a good linenumber, set the breakpoint
1616 1629 deb.do_break('%s:%s' % (filename,bp))
1617 1630 # Start file run
1618 1631 print "NOTE: Enter 'c' at the",
1619 1632 print "%s prompt to start your script." % deb.prompt
1620 1633 try:
1621 1634 deb.run('execfile("%s")' % filename,prog_ns)
1622 1635
1623 1636 except:
1624 1637 etype, value, tb = sys.exc_info()
1625 1638 # Skip three frames in the traceback: the %run one,
1626 1639 # one inside bdb.py, and the command-line typed by the
1627 1640 # user (run by exec in pdb itself).
1628 1641 self.shell.InteractiveTB(etype,value,tb,tb_offset=3)
1629 1642 else:
1630 1643 if runner is None:
1631 1644 runner = self.shell.safe_execfile
1632 1645 if opts.has_key('t'):
1633 1646 # timed execution
1634 1647 try:
1635 1648 nruns = int(opts['N'][0])
1636 1649 if nruns < 1:
1637 1650 error('Number of runs must be >=1')
1638 1651 return
1639 1652 except (KeyError):
1640 1653 nruns = 1
1641 1654 if nruns == 1:
1642 1655 t0 = clock2()
1643 1656 runner(filename,prog_ns,prog_ns,
1644 1657 exit_ignore=exit_ignore)
1645 1658 t1 = clock2()
1646 1659 t_usr = t1[0]-t0[0]
1647 1660 t_sys = t1[1]-t1[1]
1648 1661 print "\nIPython CPU timings (estimated):"
1649 1662 print " User : %10s s." % t_usr
1650 1663 print " System: %10s s." % t_sys
1651 1664 else:
1652 1665 runs = range(nruns)
1653 1666 t0 = clock2()
1654 1667 for nr in runs:
1655 1668 runner(filename,prog_ns,prog_ns,
1656 1669 exit_ignore=exit_ignore)
1657 1670 t1 = clock2()
1658 1671 t_usr = t1[0]-t0[0]
1659 1672 t_sys = t1[1]-t1[1]
1660 1673 print "\nIPython CPU timings (estimated):"
1661 1674 print "Total runs performed:",nruns
1662 1675 print " Times : %10s %10s" % ('Total','Per run')
1663 1676 print " User : %10s s, %10s s." % (t_usr,t_usr/nruns)
1664 1677 print " System: %10s s, %10s s." % (t_sys,t_sys/nruns)
1665 1678
1666 1679 else:
1667 1680 # regular execution
1668 1681 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1669 1682 if opts.has_key('i'):
1670 1683 self.shell.user_ns['__name__'] = __name__save
1671 1684 else:
1672 1685 # update IPython interactive namespace
1673 1686 del prog_ns['__name__']
1674 1687 self.shell.user_ns.update(prog_ns)
1675 1688 finally:
1689 # Ensure key global structures are restored
1676 1690 sys.argv = save_argv
1677 1691 if restore_main:
1678 1692 sys.modules['__main__'] = restore_main
1693 else:
1694 # Remove from sys.modules the reference to main_mod we'd
1695 # added. Otherwise it will trap references to objects
1696 # contained therein.
1697 del sys.modules[main_mod_name]
1679 1698 self.shell.reloadhist()
1680 1699
1681 1700 return stats
1682 1701
1683 1702 def magic_runlog(self, parameter_s =''):
1684 1703 """Run files as logs.
1685 1704
1686 1705 Usage:\\
1687 1706 %runlog file1 file2 ...
1688 1707
1689 1708 Run the named files (treating them as log files) in sequence inside
1690 1709 the interpreter, and return to the prompt. This is much slower than
1691 1710 %run because each line is executed in a try/except block, but it
1692 1711 allows running files with syntax errors in them.
1693 1712
1694 1713 Normally IPython will guess when a file is one of its own logfiles, so
1695 1714 you can typically use %run even for logs. This shorthand allows you to
1696 1715 force any file to be treated as a log file."""
1697 1716
1698 1717 for f in parameter_s.split():
1699 1718 self.shell.safe_execfile(f,self.shell.user_ns,
1700 1719 self.shell.user_ns,islog=1)
1701 1720
1721 @testdec.skip_doctest
1702 1722 def magic_timeit(self, parameter_s =''):
1703 1723 """Time execution of a Python statement or expression
1704 1724
1705 1725 Usage:\\
1706 1726 %timeit [-n<N> -r<R> [-t|-c]] statement
1707 1727
1708 1728 Time execution of a Python statement or expression using the timeit
1709 1729 module.
1710 1730
1711 1731 Options:
1712 1732 -n<N>: execute the given statement <N> times in a loop. If this value
1713 1733 is not given, a fitting value is chosen.
1714 1734
1715 1735 -r<R>: repeat the loop iteration <R> times and take the best result.
1716 1736 Default: 3
1717 1737
1718 1738 -t: use time.time to measure the time, which is the default on Unix.
1719 1739 This function measures wall time.
1720 1740
1721 1741 -c: use time.clock to measure the time, which is the default on
1722 1742 Windows and measures wall time. On Unix, resource.getrusage is used
1723 1743 instead and returns the CPU user time.
1724 1744
1725 1745 -p<P>: use a precision of <P> digits to display the timing result.
1726 1746 Default: 3
1727 1747
1728 1748
1729 Examples:\\
1749 Examples:
1750
1730 1751 In [1]: %timeit pass
1731 1752 10000000 loops, best of 3: 53.3 ns per loop
1732 1753
1733 1754 In [2]: u = None
1734 1755
1735 1756 In [3]: %timeit u is None
1736 1757 10000000 loops, best of 3: 184 ns per loop
1737 1758
1738 1759 In [4]: %timeit -r 4 u == None
1739 1760 1000000 loops, best of 4: 242 ns per loop
1740 1761
1741 1762 In [5]: import time
1742 1763
1743 1764 In [6]: %timeit -n1 time.sleep(2)
1744 1765 1 loops, best of 3: 2 s per loop
1745 1766
1746 1767
1747 1768 The times reported by %timeit will be slightly higher than those
1748 1769 reported by the timeit.py script when variables are accessed. This is
1749 1770 due to the fact that %timeit executes the statement in the namespace
1750 1771 of the shell, compared with timeit.py, which uses a single setup
1751 1772 statement to import function or create variables. Generally, the bias
1752 1773 does not matter as long as results from timeit.py are not mixed with
1753 1774 those from %timeit."""
1754 1775
1755 1776 import timeit
1756 1777 import math
1757 1778
1758 units = ["s", "ms", "\xc2\xb5s", "ns"]
1779 units = [u"s", u"ms", u"\xb5s", u"ns"]
1759 1780 scaling = [1, 1e3, 1e6, 1e9]
1760 1781
1761 1782 opts, stmt = self.parse_options(parameter_s,'n:r:tcp:',
1762 1783 posix=False)
1763 1784 if stmt == "":
1764 1785 return
1765 1786 timefunc = timeit.default_timer
1766 1787 number = int(getattr(opts, "n", 0))
1767 1788 repeat = int(getattr(opts, "r", timeit.default_repeat))
1768 1789 precision = int(getattr(opts, "p", 3))
1769 1790 if hasattr(opts, "t"):
1770 1791 timefunc = time.time
1771 1792 if hasattr(opts, "c"):
1772 1793 timefunc = clock
1773 1794
1774 1795 timer = timeit.Timer(timer=timefunc)
1775 1796 # this code has tight coupling to the inner workings of timeit.Timer,
1776 1797 # but is there a better way to achieve that the code stmt has access
1777 1798 # to the shell namespace?
1778 1799
1779 1800 src = timeit.template % {'stmt': timeit.reindent(stmt, 8),
1780 1801 'setup': "pass"}
1781 1802 # Track compilation time so it can be reported if too long
1782 1803 # Minimum time above which compilation time will be reported
1783 1804 tc_min = 0.1
1784 1805
1785 1806 t0 = clock()
1786 1807 code = compile(src, "<magic-timeit>", "exec")
1787 1808 tc = clock()-t0
1788 1809
1789 1810 ns = {}
1790 1811 exec code in self.shell.user_ns, ns
1791 1812 timer.inner = ns["inner"]
1792 1813
1793 1814 if number == 0:
1794 1815 # determine number so that 0.2 <= total time < 2.0
1795 1816 number = 1
1796 1817 for i in range(1, 10):
1797 1818 number *= 10
1798 1819 if timer.timeit(number) >= 0.2:
1799 1820 break
1800 1821
1801 1822 best = min(timer.repeat(repeat, number)) / number
1802 1823
1803 1824 if best > 0.0:
1804 1825 order = min(-int(math.floor(math.log10(best)) // 3), 3)
1805 1826 else:
1806 1827 order = 3
1807 print "%d loops, best of %d: %.*g %s per loop" % (number, repeat,
1828 print u"%d loops, best of %d: %.*g %s per loop" % (number, repeat,
1808 1829 precision,
1809 1830 best * scaling[order],
1810 1831 units[order])
1811 1832 if tc > tc_min:
1812 1833 print "Compiler time: %.2f s" % tc
1813 1834
1835 @testdec.skip_doctest
1814 1836 def magic_time(self,parameter_s = ''):
1815 1837 """Time execution of a Python statement or expression.
1816 1838
1817 1839 The CPU and wall clock times are printed, and the value of the
1818 1840 expression (if any) is returned. Note that under Win32, system time
1819 1841 is always reported as 0, since it can not be measured.
1820 1842
1821 1843 This function provides very basic timing functionality. In Python
1822 1844 2.3, the timeit module offers more control and sophistication, so this
1823 1845 could be rewritten to use it (patches welcome).
1824 1846
1825 1847 Some examples:
1826 1848
1827 1849 In [1]: time 2**128
1828 1850 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1829 1851 Wall time: 0.00
1830 1852 Out[1]: 340282366920938463463374607431768211456L
1831 1853
1832 1854 In [2]: n = 1000000
1833 1855
1834 1856 In [3]: time sum(range(n))
1835 1857 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1836 1858 Wall time: 1.37
1837 1859 Out[3]: 499999500000L
1838 1860
1839 1861 In [4]: time print 'hello world'
1840 1862 hello world
1841 1863 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1842 1864 Wall time: 0.00
1843 1865
1844 1866 Note that the time needed by Python to compile the given expression
1845 1867 will be reported if it is more than 0.1s. In this example, the
1846 1868 actual exponentiation is done by Python at compilation time, so while
1847 1869 the expression can take a noticeable amount of time to compute, that
1848 1870 time is purely due to the compilation:
1849 1871
1850 1872 In [5]: time 3**9999;
1851 1873 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1852 1874 Wall time: 0.00 s
1853 1875
1854 1876 In [6]: time 3**999999;
1855 1877 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1856 1878 Wall time: 0.00 s
1857 1879 Compiler : 0.78 s
1858 1880 """
1859 1881
1860 1882 # fail immediately if the given expression can't be compiled
1861 1883
1862 1884 expr = self.shell.prefilter(parameter_s,False)
1863 1885
1864 1886 # Minimum time above which compilation time will be reported
1865 1887 tc_min = 0.1
1866 1888
1867 1889 try:
1868 1890 mode = 'eval'
1869 1891 t0 = clock()
1870 1892 code = compile(expr,'<timed eval>',mode)
1871 1893 tc = clock()-t0
1872 1894 except SyntaxError:
1873 1895 mode = 'exec'
1874 1896 t0 = clock()
1875 1897 code = compile(expr,'<timed exec>',mode)
1876 1898 tc = clock()-t0
1877 1899 # skew measurement as little as possible
1878 1900 glob = self.shell.user_ns
1879 1901 clk = clock2
1880 1902 wtime = time.time
1881 1903 # time execution
1882 1904 wall_st = wtime()
1883 1905 if mode=='eval':
1884 1906 st = clk()
1885 1907 out = eval(code,glob)
1886 1908 end = clk()
1887 1909 else:
1888 1910 st = clk()
1889 1911 exec code in glob
1890 1912 end = clk()
1891 1913 out = None
1892 1914 wall_end = wtime()
1893 1915 # Compute actual times and report
1894 1916 wall_time = wall_end-wall_st
1895 1917 cpu_user = end[0]-st[0]
1896 1918 cpu_sys = end[1]-st[1]
1897 1919 cpu_tot = cpu_user+cpu_sys
1898 1920 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
1899 1921 (cpu_user,cpu_sys,cpu_tot)
1900 1922 print "Wall time: %.2f s" % wall_time
1901 1923 if tc > tc_min:
1902 1924 print "Compiler : %.2f s" % tc
1903 1925 return out
1904 1926
1927 @testdec.skip_doctest
1905 1928 def magic_macro(self,parameter_s = ''):
1906 1929 """Define a set of input lines as a macro for future re-execution.
1907 1930
1908 1931 Usage:\\
1909 1932 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1910 1933
1911 1934 Options:
1912 1935
1913 1936 -r: use 'raw' input. By default, the 'processed' history is used,
1914 1937 so that magics are loaded in their transformed version to valid
1915 1938 Python. If this option is given, the raw input as typed as the
1916 1939 command line is used instead.
1917 1940
1918 1941 This will define a global variable called `name` which is a string
1919 1942 made of joining the slices and lines you specify (n1,n2,... numbers
1920 1943 above) from your input history into a single string. This variable
1921 1944 acts like an automatic function which re-executes those lines as if
1922 1945 you had typed them. You just type 'name' at the prompt and the code
1923 1946 executes.
1924 1947
1925 1948 The notation for indicating number ranges is: n1-n2 means 'use line
1926 1949 numbers n1,...n2' (the endpoint is included). That is, '5-7' means
1927 1950 using the lines numbered 5,6 and 7.
1928 1951
1929 1952 Note: as a 'hidden' feature, you can also use traditional python slice
1930 1953 notation, where N:M means numbers N through M-1.
1931 1954
1932 1955 For example, if your history contains (%hist prints it):
1933 1956
1934 44: x=1\\
1935 45: y=3\\
1936 46: z=x+y\\
1937 47: print x\\
1938 48: a=5\\
1939 49: print 'x',x,'y',y\\
1957 44: x=1
1958 45: y=3
1959 46: z=x+y
1960 47: print x
1961 48: a=5
1962 49: print 'x',x,'y',y
1940 1963
1941 1964 you can create a macro with lines 44 through 47 (included) and line 49
1942 1965 called my_macro with:
1943 1966
1944 In [51]: %macro my_macro 44-47 49
1967 In [55]: %macro my_macro 44-47 49
1945 1968
1946 1969 Now, typing `my_macro` (without quotes) will re-execute all this code
1947 1970 in one pass.
1948 1971
1949 1972 You don't need to give the line-numbers in order, and any given line
1950 1973 number can appear multiple times. You can assemble macros with any
1951 1974 lines from your input history in any order.
1952 1975
1953 1976 The macro is a simple object which holds its value in an attribute,
1954 1977 but IPython's display system checks for macros and executes them as
1955 1978 code instead of printing them when you type their name.
1956 1979
1957 1980 You can view a macro's contents by explicitly printing it with:
1958 1981
1959 1982 'print macro_name'.
1960 1983
1961 1984 For one-off cases which DON'T contain magic function calls in them you
1962 1985 can obtain similar results by explicitly executing slices from your
1963 1986 input history with:
1964 1987
1965 1988 In [60]: exec In[44:48]+In[49]"""
1966 1989
1967 1990 opts,args = self.parse_options(parameter_s,'r',mode='list')
1968 1991 if not args:
1969 1992 macs = [k for k,v in self.shell.user_ns.items() if isinstance(v, Macro)]
1970 1993 macs.sort()
1971 1994 return macs
1972 1995 if len(args) == 1:
1973 1996 raise UsageError(
1974 1997 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1975 1998 name,ranges = args[0], args[1:]
1976 1999
1977 2000 #print 'rng',ranges # dbg
1978 2001 lines = self.extract_input_slices(ranges,opts.has_key('r'))
1979 2002 macro = Macro(lines)
1980 2003 self.shell.user_ns.update({name:macro})
1981 2004 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
1982 2005 print 'Macro contents:'
1983 2006 print macro,
1984 2007
1985 2008 def magic_save(self,parameter_s = ''):
1986 2009 """Save a set of lines to a given filename.
1987 2010
1988 2011 Usage:\\
1989 2012 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
1990 2013
1991 2014 Options:
1992 2015
1993 2016 -r: use 'raw' input. By default, the 'processed' history is used,
1994 2017 so that magics are loaded in their transformed version to valid
1995 2018 Python. If this option is given, the raw input as typed as the
1996 2019 command line is used instead.
1997 2020
1998 2021 This function uses the same syntax as %macro for line extraction, but
1999 2022 instead of creating a macro it saves the resulting string to the
2000 2023 filename you specify.
2001 2024
2002 2025 It adds a '.py' extension to the file if you don't do so yourself, and
2003 2026 it asks for confirmation before overwriting existing files."""
2004 2027
2005 2028 opts,args = self.parse_options(parameter_s,'r',mode='list')
2006 2029 fname,ranges = args[0], args[1:]
2007 2030 if not fname.endswith('.py'):
2008 2031 fname += '.py'
2009 2032 if os.path.isfile(fname):
2010 2033 ans = raw_input('File `%s` exists. Overwrite (y/[N])? ' % fname)
2011 2034 if ans.lower() not in ['y','yes']:
2012 2035 print 'Operation cancelled.'
2013 2036 return
2014 2037 cmds = ''.join(self.extract_input_slices(ranges,opts.has_key('r')))
2015 2038 f = file(fname,'w')
2016 2039 f.write(cmds)
2017 2040 f.close()
2018 2041 print 'The following commands were written to file `%s`:' % fname
2019 2042 print cmds
2020 2043
2021 2044 def _edit_macro(self,mname,macro):
2022 2045 """open an editor with the macro data in a file"""
2023 2046 filename = self.shell.mktempfile(macro.value)
2024 2047 self.shell.hooks.editor(filename)
2025 2048
2026 2049 # and make a new macro object, to replace the old one
2027 2050 mfile = open(filename)
2028 2051 mvalue = mfile.read()
2029 2052 mfile.close()
2030 2053 self.shell.user_ns[mname] = Macro(mvalue)
2031 2054
2032 2055 def magic_ed(self,parameter_s=''):
2033 2056 """Alias to %edit."""
2034 2057 return self.magic_edit(parameter_s)
2035 2058
2059 @testdec.skip_doctest
2036 2060 def magic_edit(self,parameter_s='',last_call=['','']):
2037 2061 """Bring up an editor and execute the resulting code.
2038 2062
2039 2063 Usage:
2040 2064 %edit [options] [args]
2041 2065
2042 2066 %edit runs IPython's editor hook. The default version of this hook is
2043 2067 set to call the __IPYTHON__.rc.editor command. This is read from your
2044 2068 environment variable $EDITOR. If this isn't found, it will default to
2045 2069 vi under Linux/Unix and to notepad under Windows. See the end of this
2046 2070 docstring for how to change the editor hook.
2047 2071
2048 2072 You can also set the value of this editor via the command line option
2049 2073 '-editor' or in your ipythonrc file. This is useful if you wish to use
2050 2074 specifically for IPython an editor different from your typical default
2051 2075 (and for Windows users who typically don't set environment variables).
2052 2076
2053 2077 This command allows you to conveniently edit multi-line code right in
2054 2078 your IPython session.
2055 2079
2056 2080 If called without arguments, %edit opens up an empty editor with a
2057 2081 temporary file and will execute the contents of this file when you
2058 2082 close it (don't forget to save it!).
2059 2083
2060 2084
2061 2085 Options:
2062 2086
2063 2087 -n <number>: open the editor at a specified line number. By default,
2064 2088 the IPython editor hook uses the unix syntax 'editor +N filename', but
2065 2089 you can configure this by providing your own modified hook if your
2066 2090 favorite editor supports line-number specifications with a different
2067 2091 syntax.
2068 2092
2069 2093 -p: this will call the editor with the same data as the previous time
2070 2094 it was used, regardless of how long ago (in your current session) it
2071 2095 was.
2072 2096
2073 2097 -r: use 'raw' input. This option only applies to input taken from the
2074 2098 user's history. By default, the 'processed' history is used, so that
2075 2099 magics are loaded in their transformed version to valid Python. If
2076 2100 this option is given, the raw input as typed as the command line is
2077 2101 used instead. When you exit the editor, it will be executed by
2078 2102 IPython's own processor.
2079 2103
2080 2104 -x: do not execute the edited code immediately upon exit. This is
2081 2105 mainly useful if you are editing programs which need to be called with
2082 2106 command line arguments, which you can then do using %run.
2083 2107
2084 2108
2085 2109 Arguments:
2086 2110
2087 2111 If arguments are given, the following possibilites exist:
2088 2112
2089 2113 - The arguments are numbers or pairs of colon-separated numbers (like
2090 2114 1 4:8 9). These are interpreted as lines of previous input to be
2091 2115 loaded into the editor. The syntax is the same of the %macro command.
2092 2116
2093 2117 - If the argument doesn't start with a number, it is evaluated as a
2094 2118 variable and its contents loaded into the editor. You can thus edit
2095 2119 any string which contains python code (including the result of
2096 2120 previous edits).
2097 2121
2098 2122 - If the argument is the name of an object (other than a string),
2099 2123 IPython will try to locate the file where it was defined and open the
2100 2124 editor at the point where it is defined. You can use `%edit function`
2101 2125 to load an editor exactly at the point where 'function' is defined,
2102 2126 edit it and have the file be executed automatically.
2103 2127
2104 2128 If the object is a macro (see %macro for details), this opens up your
2105 2129 specified editor with a temporary file containing the macro's data.
2106 2130 Upon exit, the macro is reloaded with the contents of the file.
2107 2131
2108 2132 Note: opening at an exact line is only supported under Unix, and some
2109 2133 editors (like kedit and gedit up to Gnome 2.8) do not understand the
2110 2134 '+NUMBER' parameter necessary for this feature. Good editors like
2111 2135 (X)Emacs, vi, jed, pico and joe all do.
2112 2136
2113 2137 - If the argument is not found as a variable, IPython will look for a
2114 2138 file with that name (adding .py if necessary) and load it into the
2115 2139 editor. It will execute its contents with execfile() when you exit,
2116 2140 loading any code in the file into your interactive namespace.
2117 2141
2118 2142 After executing your code, %edit will return as output the code you
2119 2143 typed in the editor (except when it was an existing file). This way
2120 2144 you can reload the code in further invocations of %edit as a variable,
2121 2145 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
2122 2146 the output.
2123 2147
2124 2148 Note that %edit is also available through the alias %ed.
2125 2149
2126 2150 This is an example of creating a simple function inside the editor and
2127 2151 then modifying it. First, start up the editor:
2128 2152
2129 In [1]: ed\\
2130 Editing... done. Executing edited code...\\
2131 Out[1]: 'def foo():\\n print "foo() was defined in an editing session"\\n'
2153 In [1]: ed
2154 Editing... done. Executing edited code...
2155 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
2132 2156
2133 2157 We can then call the function foo():
2134 2158
2135 In [2]: foo()\\
2159 In [2]: foo()
2136 2160 foo() was defined in an editing session
2137 2161
2138 2162 Now we edit foo. IPython automatically loads the editor with the
2139 2163 (temporary) file where foo() was previously defined:
2140 2164
2141 In [3]: ed foo\\
2165 In [3]: ed foo
2142 2166 Editing... done. Executing edited code...
2143 2167
2144 2168 And if we call foo() again we get the modified version:
2145 2169
2146 In [4]: foo()\\
2170 In [4]: foo()
2147 2171 foo() has now been changed!
2148 2172
2149 2173 Here is an example of how to edit a code snippet successive
2150 2174 times. First we call the editor:
2151 2175
2152 In [8]: ed\\
2153 Editing... done. Executing edited code...\\
2154 hello\\
2155 Out[8]: "print 'hello'\\n"
2176 In [5]: ed
2177 Editing... done. Executing edited code...
2178 hello
2179 Out[5]: "print 'hello'n"
2156 2180
2157 2181 Now we call it again with the previous output (stored in _):
2158 2182
2159 In [9]: ed _\\
2160 Editing... done. Executing edited code...\\
2161 hello world\\
2162 Out[9]: "print 'hello world'\\n"
2183 In [6]: ed _
2184 Editing... done. Executing edited code...
2185 hello world
2186 Out[6]: "print 'hello world'n"
2163 2187
2164 2188 Now we call it with the output #8 (stored in _8, also as Out[8]):
2165 2189
2166 In [10]: ed _8\\
2167 Editing... done. Executing edited code...\\
2168 hello again\\
2169 Out[10]: "print 'hello again'\\n"
2190 In [7]: ed _8
2191 Editing... done. Executing edited code...
2192 hello again
2193 Out[7]: "print 'hello again'n"
2170 2194
2171 2195
2172 2196 Changing the default editor hook:
2173 2197
2174 2198 If you wish to write your own editor hook, you can put it in a
2175 2199 configuration file which you load at startup time. The default hook
2176 2200 is defined in the IPython.hooks module, and you can use that as a
2177 2201 starting example for further modifications. That file also has
2178 2202 general instructions on how to set a new hook for use once you've
2179 2203 defined it."""
2180 2204
2181 2205 # FIXME: This function has become a convoluted mess. It needs a
2182 2206 # ground-up rewrite with clean, simple logic.
2183 2207
2184 2208 def make_filename(arg):
2185 2209 "Make a filename from the given args"
2186 2210 try:
2187 2211 filename = get_py_filename(arg)
2188 2212 except IOError:
2189 2213 if args.endswith('.py'):
2190 2214 filename = arg
2191 2215 else:
2192 2216 filename = None
2193 2217 return filename
2194 2218
2195 2219 # custom exceptions
2196 2220 class DataIsObject(Exception): pass
2197 2221
2198 2222 opts,args = self.parse_options(parameter_s,'prxn:')
2199 2223 # Set a few locals from the options for convenience:
2200 2224 opts_p = opts.has_key('p')
2201 2225 opts_r = opts.has_key('r')
2202 2226
2203 2227 # Default line number value
2204 2228 lineno = opts.get('n',None)
2205 2229
2206 2230 if opts_p:
2207 2231 args = '_%s' % last_call[0]
2208 2232 if not self.shell.user_ns.has_key(args):
2209 2233 args = last_call[1]
2210 2234
2211 2235 # use last_call to remember the state of the previous call, but don't
2212 2236 # let it be clobbered by successive '-p' calls.
2213 2237 try:
2214 2238 last_call[0] = self.shell.outputcache.prompt_count
2215 2239 if not opts_p:
2216 2240 last_call[1] = parameter_s
2217 2241 except:
2218 2242 pass
2219 2243
2220 2244 # by default this is done with temp files, except when the given
2221 2245 # arg is a filename
2222 2246 use_temp = 1
2223 2247
2224 2248 if re.match(r'\d',args):
2225 2249 # Mode where user specifies ranges of lines, like in %macro.
2226 2250 # This means that you can't edit files whose names begin with
2227 2251 # numbers this way. Tough.
2228 2252 ranges = args.split()
2229 2253 data = ''.join(self.extract_input_slices(ranges,opts_r))
2230 2254 elif args.endswith('.py'):
2231 2255 filename = make_filename(args)
2232 2256 data = ''
2233 2257 use_temp = 0
2234 2258 elif args:
2235 2259 try:
2236 2260 # Load the parameter given as a variable. If not a string,
2237 2261 # process it as an object instead (below)
2238 2262
2239 2263 #print '*** args',args,'type',type(args) # dbg
2240 2264 data = eval(args,self.shell.user_ns)
2241 2265 if not type(data) in StringTypes:
2242 2266 raise DataIsObject
2243 2267
2244 2268 except (NameError,SyntaxError):
2245 2269 # given argument is not a variable, try as a filename
2246 2270 filename = make_filename(args)
2247 2271 if filename is None:
2248 2272 warn("Argument given (%s) can't be found as a variable "
2249 2273 "or as a filename." % args)
2250 2274 return
2251 2275
2252 2276 data = ''
2253 2277 use_temp = 0
2254 2278 except DataIsObject:
2255 2279
2256 2280 # macros have a special edit function
2257 2281 if isinstance(data,Macro):
2258 2282 self._edit_macro(args,data)
2259 2283 return
2260 2284
2261 2285 # For objects, try to edit the file where they are defined
2262 2286 try:
2263 2287 filename = inspect.getabsfile(data)
2264 2288 if 'fakemodule' in filename.lower() and inspect.isclass(data):
2265 2289 # class created by %edit? Try to find source
2266 2290 # by looking for method definitions instead, the
2267 2291 # __module__ in those classes is FakeModule.
2268 2292 attrs = [getattr(data, aname) for aname in dir(data)]
2269 2293 for attr in attrs:
2270 2294 if not inspect.ismethod(attr):
2271 2295 continue
2272 2296 filename = inspect.getabsfile(attr)
2273 2297 if filename and 'fakemodule' not in filename.lower():
2274 2298 # change the attribute to be the edit target instead
2275 2299 data = attr
2276 2300 break
2277 2301
2278 2302 datafile = 1
2279 2303 except TypeError:
2280 2304 filename = make_filename(args)
2281 2305 datafile = 1
2282 2306 warn('Could not find file where `%s` is defined.\n'
2283 2307 'Opening a file named `%s`' % (args,filename))
2284 2308 # Now, make sure we can actually read the source (if it was in
2285 2309 # a temp file it's gone by now).
2286 2310 if datafile:
2287 2311 try:
2288 2312 if lineno is None:
2289 2313 lineno = inspect.getsourcelines(data)[1]
2290 2314 except IOError:
2291 2315 filename = make_filename(args)
2292 2316 if filename is None:
2293 2317 warn('The file `%s` where `%s` was defined cannot '
2294 2318 'be read.' % (filename,data))
2295 2319 return
2296 2320 use_temp = 0
2297 2321 else:
2298 2322 data = ''
2299 2323
2300 2324 if use_temp:
2301 2325 filename = self.shell.mktempfile(data)
2302 2326 print 'IPython will make a temporary file named:',filename
2303 2327
2304 2328 # do actual editing here
2305 2329 print 'Editing...',
2306 2330 sys.stdout.flush()
2307 2331 self.shell.hooks.editor(filename,lineno)
2308 2332 if opts.has_key('x'): # -x prevents actual execution
2309 2333 print
2310 2334 else:
2311 2335 print 'done. Executing edited code...'
2312 2336 if opts_r:
2313 2337 self.shell.runlines(file_read(filename))
2314 2338 else:
2315 2339 self.shell.safe_execfile(filename,self.shell.user_ns,
2316 2340 self.shell.user_ns)
2317 2341 if use_temp:
2318 2342 try:
2319 2343 return open(filename).read()
2320 2344 except IOError,msg:
2321 2345 if msg.filename == filename:
2322 2346 warn('File not found. Did you forget to save?')
2323 2347 return
2324 2348 else:
2325 2349 self.shell.showtraceback()
2326 2350
2327 2351 def magic_xmode(self,parameter_s = ''):
2328 2352 """Switch modes for the exception handlers.
2329 2353
2330 2354 Valid modes: Plain, Context and Verbose.
2331 2355
2332 2356 If called without arguments, acts as a toggle."""
2333 2357
2334 2358 def xmode_switch_err(name):
2335 2359 warn('Error changing %s exception modes.\n%s' %
2336 2360 (name,sys.exc_info()[1]))
2337 2361
2338 2362 shell = self.shell
2339 2363 new_mode = parameter_s.strip().capitalize()
2340 2364 try:
2341 2365 shell.InteractiveTB.set_mode(mode=new_mode)
2342 2366 print 'Exception reporting mode:',shell.InteractiveTB.mode
2343 2367 except:
2344 2368 xmode_switch_err('user')
2345 2369
2346 2370 # threaded shells use a special handler in sys.excepthook
2347 2371 if shell.isthreaded:
2348 2372 try:
2349 2373 shell.sys_excepthook.set_mode(mode=new_mode)
2350 2374 except:
2351 2375 xmode_switch_err('threaded')
2352 2376
2353 2377 def magic_colors(self,parameter_s = ''):
2354 2378 """Switch color scheme for prompts, info system and exception handlers.
2355 2379
2356 2380 Currently implemented schemes: NoColor, Linux, LightBG.
2357 2381
2358 2382 Color scheme names are not case-sensitive."""
2359 2383
2360 2384 def color_switch_err(name):
2361 2385 warn('Error changing %s color schemes.\n%s' %
2362 2386 (name,sys.exc_info()[1]))
2363 2387
2364 2388
2365 2389 new_scheme = parameter_s.strip()
2366 2390 if not new_scheme:
2367 2391 raise UsageError(
2368 2392 "%colors: you must specify a color scheme. See '%colors?'")
2369 2393 return
2370 2394 # local shortcut
2371 2395 shell = self.shell
2372 2396
2373 2397 import IPython.rlineimpl as readline
2374 2398
2375 2399 if not readline.have_readline and sys.platform == "win32":
2376 2400 msg = """\
2377 2401 Proper color support under MS Windows requires the pyreadline library.
2378 2402 You can find it at:
2379 2403 http://ipython.scipy.org/moin/PyReadline/Intro
2380 2404 Gary's readline needs the ctypes module, from:
2381 2405 http://starship.python.net/crew/theller/ctypes
2382 2406 (Note that ctypes is already part of Python versions 2.5 and newer).
2383 2407
2384 2408 Defaulting color scheme to 'NoColor'"""
2385 2409 new_scheme = 'NoColor'
2386 2410 warn(msg)
2387 2411
2388 2412 # readline option is 0
2389 2413 if not shell.has_readline:
2390 2414 new_scheme = 'NoColor'
2391 2415
2392 2416 # Set prompt colors
2393 2417 try:
2394 2418 shell.outputcache.set_colors(new_scheme)
2395 2419 except:
2396 2420 color_switch_err('prompt')
2397 2421 else:
2398 2422 shell.rc.colors = \
2399 2423 shell.outputcache.color_table.active_scheme_name
2400 2424 # Set exception colors
2401 2425 try:
2402 2426 shell.InteractiveTB.set_colors(scheme = new_scheme)
2403 2427 shell.SyntaxTB.set_colors(scheme = new_scheme)
2404 2428 except:
2405 2429 color_switch_err('exception')
2406 2430
2407 2431 # threaded shells use a verbose traceback in sys.excepthook
2408 2432 if shell.isthreaded:
2409 2433 try:
2410 2434 shell.sys_excepthook.set_colors(scheme=new_scheme)
2411 2435 except:
2412 2436 color_switch_err('system exception handler')
2413 2437
2414 2438 # Set info (for 'object?') colors
2415 2439 if shell.rc.color_info:
2416 2440 try:
2417 2441 shell.inspector.set_active_scheme(new_scheme)
2418 2442 except:
2419 2443 color_switch_err('object inspector')
2420 2444 else:
2421 2445 shell.inspector.set_active_scheme('NoColor')
2422 2446
2423 2447 def magic_color_info(self,parameter_s = ''):
2424 2448 """Toggle color_info.
2425 2449
2426 2450 The color_info configuration parameter controls whether colors are
2427 2451 used for displaying object details (by things like %psource, %pfile or
2428 2452 the '?' system). This function toggles this value with each call.
2429 2453
2430 2454 Note that unless you have a fairly recent pager (less works better
2431 2455 than more) in your system, using colored object information displays
2432 2456 will not work properly. Test it and see."""
2433 2457
2434 2458 self.shell.rc.color_info = 1 - self.shell.rc.color_info
2435 2459 self.magic_colors(self.shell.rc.colors)
2436 2460 print 'Object introspection functions have now coloring:',
2437 2461 print ['OFF','ON'][self.shell.rc.color_info]
2438 2462
2439 2463 def magic_Pprint(self, parameter_s=''):
2440 2464 """Toggle pretty printing on/off."""
2441 2465
2442 2466 self.shell.rc.pprint = 1 - self.shell.rc.pprint
2443 2467 print 'Pretty printing has been turned', \
2444 2468 ['OFF','ON'][self.shell.rc.pprint]
2445 2469
2446 2470 def magic_exit(self, parameter_s=''):
2447 2471 """Exit IPython, confirming if configured to do so.
2448 2472
2449 2473 You can configure whether IPython asks for confirmation upon exit by
2450 2474 setting the confirm_exit flag in the ipythonrc file."""
2451 2475
2452 2476 self.shell.exit()
2453 2477
2454 2478 def magic_quit(self, parameter_s=''):
2455 2479 """Exit IPython, confirming if configured to do so (like %exit)"""
2456 2480
2457 2481 self.shell.exit()
2458 2482
2459 2483 def magic_Exit(self, parameter_s=''):
2460 2484 """Exit IPython without confirmation."""
2461 2485
2462 2486 self.shell.ask_exit()
2463 2487
2464 2488 #......................................................................
2465 2489 # Functions to implement unix shell-type things
2466 2490
2491 @testdec.skip_doctest
2467 2492 def magic_alias(self, parameter_s = ''):
2468 2493 """Define an alias for a system command.
2469 2494
2470 2495 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
2471 2496
2472 2497 Then, typing 'alias_name params' will execute the system command 'cmd
2473 2498 params' (from your underlying operating system).
2474 2499
2475 2500 Aliases have lower precedence than magic functions and Python normal
2476 2501 variables, so if 'foo' is both a Python variable and an alias, the
2477 2502 alias can not be executed until 'del foo' removes the Python variable.
2478 2503
2479 2504 You can use the %l specifier in an alias definition to represent the
2480 2505 whole line when the alias is called. For example:
2481 2506
2482 In [2]: alias all echo "Input in brackets: <%l>"\\
2483 In [3]: all hello world\\
2507 In [2]: alias all echo "Input in brackets: <%l>"
2508 In [3]: all hello world
2484 2509 Input in brackets: <hello world>
2485 2510
2486 2511 You can also define aliases with parameters using %s specifiers (one
2487 2512 per parameter):
2488 2513
2489 In [1]: alias parts echo first %s second %s\\
2490 In [2]: %parts A B\\
2491 first A second B\\
2492 In [3]: %parts A\\
2493 Incorrect number of arguments: 2 expected.\\
2514 In [1]: alias parts echo first %s second %s
2515 In [2]: %parts A B
2516 first A second B
2517 In [3]: %parts A
2518 Incorrect number of arguments: 2 expected.
2494 2519 parts is an alias to: 'echo first %s second %s'
2495 2520
2496 2521 Note that %l and %s are mutually exclusive. You can only use one or
2497 2522 the other in your aliases.
2498 2523
2499 2524 Aliases expand Python variables just like system calls using ! or !!
2500 2525 do: all expressions prefixed with '$' get expanded. For details of
2501 2526 the semantic rules, see PEP-215:
2502 2527 http://www.python.org/peps/pep-0215.html. This is the library used by
2503 2528 IPython for variable expansion. If you want to access a true shell
2504 2529 variable, an extra $ is necessary to prevent its expansion by IPython:
2505 2530
2506 In [6]: alias show echo\\
2507 In [7]: PATH='A Python string'\\
2508 In [8]: show $PATH\\
2509 A Python string\\
2510 In [9]: show $$PATH\\
2531 In [6]: alias show echo
2532 In [7]: PATH='A Python string'
2533 In [8]: show $PATH
2534 A Python string
2535 In [9]: show $$PATH
2511 2536 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
2512 2537
2513 2538 You can use the alias facility to acess all of $PATH. See the %rehash
2514 2539 and %rehashx functions, which automatically create aliases for the
2515 2540 contents of your $PATH.
2516 2541
2517 2542 If called with no parameters, %alias prints the current alias table."""
2518 2543
2519 2544 par = parameter_s.strip()
2520 2545 if not par:
2521 2546 stored = self.db.get('stored_aliases', {} )
2522 2547 atab = self.shell.alias_table
2523 2548 aliases = atab.keys()
2524 2549 aliases.sort()
2525 2550 res = []
2526 2551 showlast = []
2527 2552 for alias in aliases:
2528 2553 special = False
2529 2554 try:
2530 2555 tgt = atab[alias][1]
2531 2556 except (TypeError, AttributeError):
2532 2557 # unsubscriptable? probably a callable
2533 2558 tgt = atab[alias]
2534 2559 special = True
2535 2560 # 'interesting' aliases
2536 2561 if (alias in stored or
2537 2562 special or
2538 2563 alias.lower() != os.path.splitext(tgt)[0].lower() or
2539 2564 ' ' in tgt):
2540 2565 showlast.append((alias, tgt))
2541 2566 else:
2542 2567 res.append((alias, tgt ))
2543 2568
2544 2569 # show most interesting aliases last
2545 2570 res.extend(showlast)
2546 2571 print "Total number of aliases:",len(aliases)
2547 2572 return res
2548 2573 try:
2549 2574 alias,cmd = par.split(None,1)
2550 2575 except:
2551 2576 print OInspect.getdoc(self.magic_alias)
2552 2577 else:
2553 2578 nargs = cmd.count('%s')
2554 2579 if nargs>0 and cmd.find('%l')>=0:
2555 2580 error('The %s and %l specifiers are mutually exclusive '
2556 2581 'in alias definitions.')
2557 2582 else: # all looks OK
2558 2583 self.shell.alias_table[alias] = (nargs,cmd)
2559 2584 self.shell.alias_table_validate(verbose=0)
2560 2585 # end magic_alias
2561 2586
2562 2587 def magic_unalias(self, parameter_s = ''):
2563 2588 """Remove an alias"""
2564 2589
2565 2590 aname = parameter_s.strip()
2566 2591 if aname in self.shell.alias_table:
2567 2592 del self.shell.alias_table[aname]
2568 2593 stored = self.db.get('stored_aliases', {} )
2569 2594 if aname in stored:
2570 2595 print "Removing %stored alias",aname
2571 2596 del stored[aname]
2572 2597 self.db['stored_aliases'] = stored
2573 2598
2574 2599
2575 2600 def magic_rehashx(self, parameter_s = ''):
2576 2601 """Update the alias table with all executable files in $PATH.
2577 2602
2578 2603 This version explicitly checks that every entry in $PATH is a file
2579 2604 with execute access (os.X_OK), so it is much slower than %rehash.
2580 2605
2581 2606 Under Windows, it checks executability as a match agains a
2582 2607 '|'-separated string of extensions, stored in the IPython config
2583 2608 variable win_exec_ext. This defaults to 'exe|com|bat'.
2584 2609
2585 2610 This function also resets the root module cache of module completer,
2586 2611 used on slow filesystems.
2587 2612 """
2588 2613
2589 2614
2590 2615 ip = self.api
2591 2616
2592 2617 # for the benefit of module completer in ipy_completers.py
2593 2618 del ip.db['rootmodules']
2594 2619
2595 2620 path = [os.path.abspath(os.path.expanduser(p)) for p in
2596 2621 os.environ.get('PATH','').split(os.pathsep)]
2597 2622 path = filter(os.path.isdir,path)
2598 2623
2599 2624 alias_table = self.shell.alias_table
2600 2625 syscmdlist = []
2601 2626 if os.name == 'posix':
2602 2627 isexec = lambda fname:os.path.isfile(fname) and \
2603 2628 os.access(fname,os.X_OK)
2604 2629 else:
2605 2630
2606 2631 try:
2607 2632 winext = os.environ['pathext'].replace(';','|').replace('.','')
2608 2633 except KeyError:
2609 2634 winext = 'exe|com|bat|py'
2610 2635 if 'py' not in winext:
2611 2636 winext += '|py'
2612 2637 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
2613 2638 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
2614 2639 savedir = os.getcwd()
2615 2640 try:
2616 2641 # write the whole loop for posix/Windows so we don't have an if in
2617 2642 # the innermost part
2618 2643 if os.name == 'posix':
2619 2644 for pdir in path:
2620 2645 os.chdir(pdir)
2621 2646 for ff in os.listdir(pdir):
2622 2647 if isexec(ff) and ff not in self.shell.no_alias:
2623 2648 # each entry in the alias table must be (N,name),
2624 2649 # where N is the number of positional arguments of the
2625 2650 # alias.
2626 2651 alias_table[ff] = (0,ff)
2627 2652 syscmdlist.append(ff)
2628 2653 else:
2629 2654 for pdir in path:
2630 2655 os.chdir(pdir)
2631 2656 for ff in os.listdir(pdir):
2632 2657 base, ext = os.path.splitext(ff)
2633 2658 if isexec(ff) and base.lower() not in self.shell.no_alias:
2634 2659 if ext.lower() == '.exe':
2635 2660 ff = base
2636 2661 alias_table[base.lower()] = (0,ff)
2637 2662 syscmdlist.append(ff)
2638 2663 # Make sure the alias table doesn't contain keywords or builtins
2639 2664 self.shell.alias_table_validate()
2640 2665 # Call again init_auto_alias() so we get 'rm -i' and other
2641 2666 # modified aliases since %rehashx will probably clobber them
2642 2667
2643 2668 # no, we don't want them. if %rehashx clobbers them, good,
2644 2669 # we'll probably get better versions
2645 2670 # self.shell.init_auto_alias()
2646 2671 db = ip.db
2647 2672 db['syscmdlist'] = syscmdlist
2648 2673 finally:
2649 2674 os.chdir(savedir)
2650 2675
2651 2676 def magic_pwd(self, parameter_s = ''):
2652 2677 """Return the current working directory path."""
2653 2678 return os.getcwd()
2654 2679
2655 2680 def magic_cd(self, parameter_s=''):
2656 2681 """Change the current working directory.
2657 2682
2658 2683 This command automatically maintains an internal list of directories
2659 2684 you visit during your IPython session, in the variable _dh. The
2660 2685 command %dhist shows this history nicely formatted. You can also
2661 2686 do 'cd -<tab>' to see directory history conveniently.
2662 2687
2663 2688 Usage:
2664 2689
2665 2690 cd 'dir': changes to directory 'dir'.
2666 2691
2667 2692 cd -: changes to the last visited directory.
2668 2693
2669 2694 cd -<n>: changes to the n-th directory in the directory history.
2670 2695
2671 2696 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
2672 2697 (note: cd <bookmark_name> is enough if there is no
2673 2698 directory <bookmark_name>, but a bookmark with the name exists.)
2674 2699 'cd -b <tab>' allows you to tab-complete bookmark names.
2675 2700
2676 2701 Options:
2677 2702
2678 2703 -q: quiet. Do not print the working directory after the cd command is
2679 2704 executed. By default IPython's cd command does print this directory,
2680 2705 since the default prompts do not display path information.
2681 2706
2682 2707 Note that !cd doesn't work for this purpose because the shell where
2683 2708 !command runs is immediately discarded after executing 'command'."""
2684 2709
2685 2710 parameter_s = parameter_s.strip()
2686 2711 #bkms = self.shell.persist.get("bookmarks",{})
2687 2712
2688 2713 oldcwd = os.getcwd()
2689 2714 numcd = re.match(r'(-)(\d+)$',parameter_s)
2690 2715 # jump in directory history by number
2691 2716 if numcd:
2692 2717 nn = int(numcd.group(2))
2693 2718 try:
2694 2719 ps = self.shell.user_ns['_dh'][nn]
2695 2720 except IndexError:
2696 2721 print 'The requested directory does not exist in history.'
2697 2722 return
2698 2723 else:
2699 2724 opts = {}
2700 2725 else:
2701 2726 #turn all non-space-escaping backslashes to slashes,
2702 2727 # for c:\windows\directory\names\
2703 2728 parameter_s = re.sub(r'\\(?! )','/', parameter_s)
2704 2729 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
2705 2730 # jump to previous
2706 2731 if ps == '-':
2707 2732 try:
2708 2733 ps = self.shell.user_ns['_dh'][-2]
2709 2734 except IndexError:
2710 2735 raise UsageError('%cd -: No previous directory to change to.')
2711 2736 # jump to bookmark if needed
2712 2737 else:
2713 2738 if not os.path.isdir(ps) or opts.has_key('b'):
2714 2739 bkms = self.db.get('bookmarks', {})
2715 2740
2716 2741 if bkms.has_key(ps):
2717 2742 target = bkms[ps]
2718 2743 print '(bookmark:%s) -> %s' % (ps,target)
2719 2744 ps = target
2720 2745 else:
2721 2746 if opts.has_key('b'):
2722 2747 raise UsageError("Bookmark '%s' not found. "
2723 2748 "Use '%%bookmark -l' to see your bookmarks." % ps)
2724 2749
2725 2750 # at this point ps should point to the target dir
2726 2751 if ps:
2727 2752 try:
2728 2753 os.chdir(os.path.expanduser(ps))
2729 2754 if self.shell.rc.term_title:
2730 2755 #print 'set term title:',self.shell.rc.term_title # dbg
2731 2756 platutils.set_term_title('IPy ' + abbrev_cwd())
2732 2757 except OSError:
2733 2758 print sys.exc_info()[1]
2734 2759 else:
2735 2760 cwd = os.getcwd()
2736 2761 dhist = self.shell.user_ns['_dh']
2737 2762 if oldcwd != cwd:
2738 2763 dhist.append(cwd)
2739 2764 self.db['dhist'] = compress_dhist(dhist)[-100:]
2740 2765
2741 2766 else:
2742 2767 os.chdir(self.shell.home_dir)
2743 2768 if self.shell.rc.term_title:
2744 2769 platutils.set_term_title("IPy ~")
2745 2770 cwd = os.getcwd()
2746 2771 dhist = self.shell.user_ns['_dh']
2747 2772
2748 2773 if oldcwd != cwd:
2749 2774 dhist.append(cwd)
2750 2775 self.db['dhist'] = compress_dhist(dhist)[-100:]
2751 2776 if not 'q' in opts and self.shell.user_ns['_dh']:
2752 2777 print self.shell.user_ns['_dh'][-1]
2753 2778
2754 2779
2755 2780 def magic_env(self, parameter_s=''):
2756 2781 """List environment variables."""
2757 2782
2758 2783 return os.environ.data
2759 2784
2760 2785 def magic_pushd(self, parameter_s=''):
2761 2786 """Place the current dir on stack and change directory.
2762 2787
2763 2788 Usage:\\
2764 2789 %pushd ['dirname']
2765 2790 """
2766 2791
2767 2792 dir_s = self.shell.dir_stack
2768 2793 tgt = os.path.expanduser(parameter_s)
2769 2794 cwd = os.getcwd().replace(self.home_dir,'~')
2770 2795 if tgt:
2771 2796 self.magic_cd(parameter_s)
2772 2797 dir_s.insert(0,cwd)
2773 2798 return self.magic_dirs()
2774 2799
2775 2800 def magic_popd(self, parameter_s=''):
2776 2801 """Change to directory popped off the top of the stack.
2777 2802 """
2778 2803 if not self.shell.dir_stack:
2779 2804 raise UsageError("%popd on empty stack")
2780 2805 top = self.shell.dir_stack.pop(0)
2781 2806 self.magic_cd(top)
2782 2807 print "popd ->",top
2783 2808
2784 2809 def magic_dirs(self, parameter_s=''):
2785 2810 """Return the current directory stack."""
2786 2811
2787 2812 return self.shell.dir_stack
2788 2813
2789 2814 def magic_dhist(self, parameter_s=''):
2790 2815 """Print your history of visited directories.
2791 2816
2792 2817 %dhist -> print full history\\
2793 2818 %dhist n -> print last n entries only\\
2794 2819 %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\\
2795 2820
2796 2821 This history is automatically maintained by the %cd command, and
2797 2822 always available as the global list variable _dh. You can use %cd -<n>
2798 2823 to go to directory number <n>.
2799 2824
2800 2825 Note that most of time, you should view directory history by entering
2801 2826 cd -<TAB>.
2802 2827
2803 2828 """
2804 2829
2805 2830 dh = self.shell.user_ns['_dh']
2806 2831 if parameter_s:
2807 2832 try:
2808 2833 args = map(int,parameter_s.split())
2809 2834 except:
2810 2835 self.arg_err(Magic.magic_dhist)
2811 2836 return
2812 2837 if len(args) == 1:
2813 2838 ini,fin = max(len(dh)-(args[0]),0),len(dh)
2814 2839 elif len(args) == 2:
2815 2840 ini,fin = args
2816 2841 else:
2817 2842 self.arg_err(Magic.magic_dhist)
2818 2843 return
2819 2844 else:
2820 2845 ini,fin = 0,len(dh)
2821 2846 nlprint(dh,
2822 2847 header = 'Directory history (kept in _dh)',
2823 2848 start=ini,stop=fin)
2824 2849
2825
2850 @testdec.skip_doctest
2826 2851 def magic_sc(self, parameter_s=''):
2827 2852 """Shell capture - execute a shell command and capture its output.
2828 2853
2829 2854 DEPRECATED. Suboptimal, retained for backwards compatibility.
2830 2855
2831 2856 You should use the form 'var = !command' instead. Example:
2832 2857
2833 2858 "%sc -l myfiles = ls ~" should now be written as
2834 2859
2835 2860 "myfiles = !ls ~"
2836 2861
2837 2862 myfiles.s, myfiles.l and myfiles.n still apply as documented
2838 2863 below.
2839 2864
2840 2865 --
2841 2866 %sc [options] varname=command
2842 2867
2843 2868 IPython will run the given command using commands.getoutput(), and
2844 2869 will then update the user's interactive namespace with a variable
2845 2870 called varname, containing the value of the call. Your command can
2846 2871 contain shell wildcards, pipes, etc.
2847 2872
2848 2873 The '=' sign in the syntax is mandatory, and the variable name you
2849 2874 supply must follow Python's standard conventions for valid names.
2850 2875
2851 2876 (A special format without variable name exists for internal use)
2852 2877
2853 2878 Options:
2854 2879
2855 2880 -l: list output. Split the output on newlines into a list before
2856 2881 assigning it to the given variable. By default the output is stored
2857 2882 as a single string.
2858 2883
2859 2884 -v: verbose. Print the contents of the variable.
2860 2885
2861 2886 In most cases you should not need to split as a list, because the
2862 2887 returned value is a special type of string which can automatically
2863 2888 provide its contents either as a list (split on newlines) or as a
2864 2889 space-separated string. These are convenient, respectively, either
2865 2890 for sequential processing or to be passed to a shell command.
2866 2891
2867 2892 For example:
2868 2893
2894 # all-random
2895
2869 2896 # Capture into variable a
2870 In [9]: sc a=ls *py
2897 In [1]: sc a=ls *py
2871 2898
2872 2899 # a is a string with embedded newlines
2873 In [10]: a
2874 Out[10]: 'setup.py\nwin32_manual_post_install.py'
2900 In [2]: a
2901 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
2875 2902
2876 2903 # which can be seen as a list:
2877 In [11]: a.l
2878 Out[11]: ['setup.py', 'win32_manual_post_install.py']
2904 In [3]: a.l
2905 Out[3]: ['setup.py', 'win32_manual_post_install.py']
2879 2906
2880 2907 # or as a whitespace-separated string:
2881 In [12]: a.s
2882 Out[12]: 'setup.py win32_manual_post_install.py'
2908 In [4]: a.s
2909 Out[4]: 'setup.py win32_manual_post_install.py'
2883 2910
2884 2911 # a.s is useful to pass as a single command line:
2885 In [13]: !wc -l $a.s
2912 In [5]: !wc -l $a.s
2886 2913 146 setup.py
2887 2914 130 win32_manual_post_install.py
2888 2915 276 total
2889 2916
2890 2917 # while the list form is useful to loop over:
2891 In [14]: for f in a.l:
2892 ....: !wc -l $f
2893 ....:
2918 In [6]: for f in a.l:
2919 ...: !wc -l $f
2920 ...:
2894 2921 146 setup.py
2895 2922 130 win32_manual_post_install.py
2896 2923
2897 2924 Similiarly, the lists returned by the -l option are also special, in
2898 2925 the sense that you can equally invoke the .s attribute on them to
2899 2926 automatically get a whitespace-separated string from their contents:
2900 2927
2901 In [1]: sc -l b=ls *py
2928 In [7]: sc -l b=ls *py
2902 2929
2903 In [2]: b
2904 Out[2]: ['setup.py', 'win32_manual_post_install.py']
2930 In [8]: b
2931 Out[8]: ['setup.py', 'win32_manual_post_install.py']
2905 2932
2906 In [3]: b.s
2907 Out[3]: 'setup.py win32_manual_post_install.py'
2933 In [9]: b.s
2934 Out[9]: 'setup.py win32_manual_post_install.py'
2908 2935
2909 2936 In summary, both the lists and strings used for ouptut capture have
2910 2937 the following special attributes:
2911 2938
2912 2939 .l (or .list) : value as list.
2913 2940 .n (or .nlstr): value as newline-separated string.
2914 2941 .s (or .spstr): value as space-separated string.
2915 2942 """
2916 2943
2917 2944 opts,args = self.parse_options(parameter_s,'lv')
2918 2945 # Try to get a variable name and command to run
2919 2946 try:
2920 2947 # the variable name must be obtained from the parse_options
2921 2948 # output, which uses shlex.split to strip options out.
2922 2949 var,_ = args.split('=',1)
2923 2950 var = var.strip()
2924 2951 # But the the command has to be extracted from the original input
2925 2952 # parameter_s, not on what parse_options returns, to avoid the
2926 2953 # quote stripping which shlex.split performs on it.
2927 2954 _,cmd = parameter_s.split('=',1)
2928 2955 except ValueError:
2929 2956 var,cmd = '',''
2930 2957 # If all looks ok, proceed
2931 2958 out,err = self.shell.getoutputerror(cmd)
2932 2959 if err:
2933 2960 print >> Term.cerr,err
2934 2961 if opts.has_key('l'):
2935 2962 out = SList(out.split('\n'))
2936 2963 else:
2937 2964 out = LSString(out)
2938 2965 if opts.has_key('v'):
2939 2966 print '%s ==\n%s' % (var,pformat(out))
2940 2967 if var:
2941 2968 self.shell.user_ns.update({var:out})
2942 2969 else:
2943 2970 return out
2944 2971
2945 2972 def magic_sx(self, parameter_s=''):
2946 2973 """Shell execute - run a shell command and capture its output.
2947 2974
2948 2975 %sx command
2949 2976
2950 2977 IPython will run the given command using commands.getoutput(), and
2951 2978 return the result formatted as a list (split on '\\n'). Since the
2952 2979 output is _returned_, it will be stored in ipython's regular output
2953 2980 cache Out[N] and in the '_N' automatic variables.
2954 2981
2955 2982 Notes:
2956 2983
2957 2984 1) If an input line begins with '!!', then %sx is automatically
2958 2985 invoked. That is, while:
2959 2986 !ls
2960 2987 causes ipython to simply issue system('ls'), typing
2961 2988 !!ls
2962 2989 is a shorthand equivalent to:
2963 2990 %sx ls
2964 2991
2965 2992 2) %sx differs from %sc in that %sx automatically splits into a list,
2966 2993 like '%sc -l'. The reason for this is to make it as easy as possible
2967 2994 to process line-oriented shell output via further python commands.
2968 2995 %sc is meant to provide much finer control, but requires more
2969 2996 typing.
2970 2997
2971 2998 3) Just like %sc -l, this is a list with special attributes:
2972 2999
2973 3000 .l (or .list) : value as list.
2974 3001 .n (or .nlstr): value as newline-separated string.
2975 3002 .s (or .spstr): value as whitespace-separated string.
2976 3003
2977 3004 This is very useful when trying to use such lists as arguments to
2978 3005 system commands."""
2979 3006
2980 3007 if parameter_s:
2981 3008 out,err = self.shell.getoutputerror(parameter_s)
2982 3009 if err:
2983 3010 print >> Term.cerr,err
2984 3011 return SList(out.split('\n'))
2985 3012
2986 3013 def magic_bg(self, parameter_s=''):
2987 3014 """Run a job in the background, in a separate thread.
2988 3015
2989 3016 For example,
2990 3017
2991 3018 %bg myfunc(x,y,z=1)
2992 3019
2993 3020 will execute 'myfunc(x,y,z=1)' in a background thread. As soon as the
2994 3021 execution starts, a message will be printed indicating the job
2995 3022 number. If your job number is 5, you can use
2996 3023
2997 3024 myvar = jobs.result(5) or myvar = jobs[5].result
2998 3025
2999 3026 to assign this result to variable 'myvar'.
3000 3027
3001 3028 IPython has a job manager, accessible via the 'jobs' object. You can
3002 3029 type jobs? to get more information about it, and use jobs.<TAB> to see
3003 3030 its attributes. All attributes not starting with an underscore are
3004 3031 meant for public use.
3005 3032
3006 3033 In particular, look at the jobs.new() method, which is used to create
3007 3034 new jobs. This magic %bg function is just a convenience wrapper
3008 3035 around jobs.new(), for expression-based jobs. If you want to create a
3009 3036 new job with an explicit function object and arguments, you must call
3010 3037 jobs.new() directly.
3011 3038
3012 3039 The jobs.new docstring also describes in detail several important
3013 3040 caveats associated with a thread-based model for background job
3014 3041 execution. Type jobs.new? for details.
3015 3042
3016 3043 You can check the status of all jobs with jobs.status().
3017 3044
3018 3045 The jobs variable is set by IPython into the Python builtin namespace.
3019 3046 If you ever declare a variable named 'jobs', you will shadow this
3020 3047 name. You can either delete your global jobs variable to regain
3021 3048 access to the job manager, or make a new name and assign it manually
3022 3049 to the manager (stored in IPython's namespace). For example, to
3023 3050 assign the job manager to the Jobs name, use:
3024 3051
3025 3052 Jobs = __builtins__.jobs"""
3026 3053
3027 3054 self.shell.jobs.new(parameter_s,self.shell.user_ns)
3028 3055
3029 3056 def magic_r(self, parameter_s=''):
3030 3057 """Repeat previous input.
3031 3058
3032 3059 Note: Consider using the more powerfull %rep instead!
3033 3060
3034 3061 If given an argument, repeats the previous command which starts with
3035 3062 the same string, otherwise it just repeats the previous input.
3036 3063
3037 3064 Shell escaped commands (with ! as first character) are not recognized
3038 3065 by this system, only pure python code and magic commands.
3039 3066 """
3040 3067
3041 3068 start = parameter_s.strip()
3042 3069 esc_magic = self.shell.ESC_MAGIC
3043 3070 # Identify magic commands even if automagic is on (which means
3044 3071 # the in-memory version is different from that typed by the user).
3045 3072 if self.shell.rc.automagic:
3046 3073 start_magic = esc_magic+start
3047 3074 else:
3048 3075 start_magic = start
3049 3076 # Look through the input history in reverse
3050 3077 for n in range(len(self.shell.input_hist)-2,0,-1):
3051 3078 input = self.shell.input_hist[n]
3052 3079 # skip plain 'r' lines so we don't recurse to infinity
3053 3080 if input != '_ip.magic("r")\n' and \
3054 3081 (input.startswith(start) or input.startswith(start_magic)):
3055 3082 #print 'match',`input` # dbg
3056 3083 print 'Executing:',input,
3057 3084 self.shell.runlines(input)
3058 3085 return
3059 3086 print 'No previous input matching `%s` found.' % start
3060 3087
3061 3088
3062 3089 def magic_bookmark(self, parameter_s=''):
3063 3090 """Manage IPython's bookmark system.
3064 3091
3065 3092 %bookmark <name> - set bookmark to current dir
3066 3093 %bookmark <name> <dir> - set bookmark to <dir>
3067 3094 %bookmark -l - list all bookmarks
3068 3095 %bookmark -d <name> - remove bookmark
3069 3096 %bookmark -r - remove all bookmarks
3070 3097
3071 3098 You can later on access a bookmarked folder with:
3072 3099 %cd -b <name>
3073 3100 or simply '%cd <name>' if there is no directory called <name> AND
3074 3101 there is such a bookmark defined.
3075 3102
3076 3103 Your bookmarks persist through IPython sessions, but they are
3077 3104 associated with each profile."""
3078 3105
3079 3106 opts,args = self.parse_options(parameter_s,'drl',mode='list')
3080 3107 if len(args) > 2:
3081 3108 raise UsageError("%bookmark: too many arguments")
3082 3109
3083 3110 bkms = self.db.get('bookmarks',{})
3084 3111
3085 3112 if opts.has_key('d'):
3086 3113 try:
3087 3114 todel = args[0]
3088 3115 except IndexError:
3089 3116 raise UsageError(
3090 3117 "%bookmark -d: must provide a bookmark to delete")
3091 3118 else:
3092 3119 try:
3093 3120 del bkms[todel]
3094 3121 except KeyError:
3095 3122 raise UsageError(
3096 3123 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
3097 3124
3098 3125 elif opts.has_key('r'):
3099 3126 bkms = {}
3100 3127 elif opts.has_key('l'):
3101 3128 bks = bkms.keys()
3102 3129 bks.sort()
3103 3130 if bks:
3104 3131 size = max(map(len,bks))
3105 3132 else:
3106 3133 size = 0
3107 3134 fmt = '%-'+str(size)+'s -> %s'
3108 3135 print 'Current bookmarks:'
3109 3136 for bk in bks:
3110 3137 print fmt % (bk,bkms[bk])
3111 3138 else:
3112 3139 if not args:
3113 3140 raise UsageError("%bookmark: You must specify the bookmark name")
3114 3141 elif len(args)==1:
3115 3142 bkms[args[0]] = os.getcwd()
3116 3143 elif len(args)==2:
3117 3144 bkms[args[0]] = args[1]
3118 3145 self.db['bookmarks'] = bkms
3119 3146
3120 3147 def magic_pycat(self, parameter_s=''):
3121 3148 """Show a syntax-highlighted file through a pager.
3122 3149
3123 3150 This magic is similar to the cat utility, but it will assume the file
3124 3151 to be Python source and will show it with syntax highlighting. """
3125 3152
3126 3153 try:
3127 3154 filename = get_py_filename(parameter_s)
3128 3155 cont = file_read(filename)
3129 3156 except IOError:
3130 3157 try:
3131 3158 cont = eval(parameter_s,self.user_ns)
3132 3159 except NameError:
3133 3160 cont = None
3134 3161 if cont is None:
3135 3162 print "Error: no such file or variable"
3136 3163 return
3137 3164
3138 3165 page(self.shell.pycolorize(cont),
3139 3166 screen_lines=self.shell.rc.screen_length)
3140 3167
3141 3168 def magic_cpaste(self, parameter_s=''):
3142 3169 """Allows you to paste & execute a pre-formatted code block from clipboard.
3143 3170
3144 3171 You must terminate the block with '--' (two minus-signs) alone on the
3145 3172 line. You can also provide your own sentinel with '%paste -s %%' ('%%'
3146 3173 is the new sentinel for this operation)
3147 3174
3148 3175 The block is dedented prior to execution to enable execution of method
3149 3176 definitions. '>' and '+' characters at the beginning of a line are
3150 3177 ignored, to allow pasting directly from e-mails, diff files and
3151 3178 doctests (the '...' continuation prompt is also stripped). The
3152 3179 executed block is also assigned to variable named 'pasted_block' for
3153 3180 later editing with '%edit pasted_block'.
3154 3181
3155 3182 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
3156 3183 This assigns the pasted block to variable 'foo' as string, without
3157 3184 dedenting or executing it (preceding >>> and + is still stripped)
3158 3185
3159 3186 Do not be alarmed by garbled output on Windows (it's a readline bug).
3160 3187 Just press enter and type -- (and press enter again) and the block
3161 3188 will be what was just pasted.
3162 3189
3163 3190 IPython statements (magics, shell escapes) are not supported (yet).
3164 3191 """
3165 3192 opts,args = self.parse_options(parameter_s,'s:',mode='string')
3166 3193 par = args.strip()
3167 3194 sentinel = opts.get('s','--')
3168 3195
3169 3196 # Regular expressions that declare text we strip from the input:
3170 3197 strip_re = [r'^\s*In \[\d+\]:', # IPython input prompt
3171 3198 r'^\s*(\s?>)+', # Python input prompt
3172 3199 r'^\s*\.{3,}', # Continuation prompts
3173 3200 r'^\++',
3174 3201 ]
3175 3202
3176 3203 strip_from_start = map(re.compile,strip_re)
3177 3204
3178 3205 from IPython import iplib
3179 3206 lines = []
3180 3207 print "Pasting code; enter '%s' alone on the line to stop." % sentinel
3181 3208 while 1:
3182 3209 l = iplib.raw_input_original(':')
3183 3210 if l ==sentinel:
3184 3211 break
3185 3212
3186 3213 for pat in strip_from_start:
3187 3214 l = pat.sub('',l)
3188 3215 lines.append(l)
3189 3216
3190 3217 block = "\n".join(lines) + '\n'
3191 3218 #print "block:\n",block
3192 3219 if not par:
3193 3220 b = textwrap.dedent(block)
3194 3221 exec b in self.user_ns
3195 3222 self.user_ns['pasted_block'] = b
3196 3223 else:
3197 3224 self.user_ns[par] = SList(block.splitlines())
3198 3225 print "Block assigned to '%s'" % par
3199 3226
3200 3227 def magic_quickref(self,arg):
3201 3228 """ Show a quick reference sheet """
3202 3229 import IPython.usage
3203 3230 qr = IPython.usage.quick_reference + self.magic_magic('-brief')
3204 3231
3205 3232 page(qr)
3206 3233
3207 3234 def magic_upgrade(self,arg):
3208 3235 """ Upgrade your IPython installation
3209 3236
3210 3237 This will copy the config files that don't yet exist in your
3211 3238 ipython dir from the system config dir. Use this after upgrading
3212 3239 IPython if you don't wish to delete your .ipython dir.
3213 3240
3214 3241 Call with -nolegacy to get rid of ipythonrc* files (recommended for
3215 3242 new users)
3216 3243
3217 3244 """
3218 3245 ip = self.getapi()
3219 3246 ipinstallation = path(IPython.__file__).dirname()
3220 3247 upgrade_script = '%s "%s"' % (sys.executable,ipinstallation / 'upgrade_dir.py')
3221 3248 src_config = ipinstallation / 'UserConfig'
3222 3249 userdir = path(ip.options.ipythondir)
3223 3250 cmd = '%s "%s" "%s"' % (upgrade_script, src_config, userdir)
3224 3251 print ">",cmd
3225 3252 shell(cmd)
3226 3253 if arg == '-nolegacy':
3227 3254 legacy = userdir.files('ipythonrc*')
3228 3255 print "Nuking legacy files:",legacy
3229 3256
3230 3257 [p.remove() for p in legacy]
3231 3258 suffix = (sys.platform == 'win32' and '.ini' or '')
3232 3259 (userdir / ('ipythonrc' + suffix)).write_text('# Empty, see ipy_user_conf.py\n')
3233 3260
3234 3261
3235 3262 def magic_doctest_mode(self,parameter_s=''):
3236 3263 """Toggle doctest mode on and off.
3237 3264
3238 3265 This mode allows you to toggle the prompt behavior between normal
3239 3266 IPython prompts and ones that are as similar to the default IPython
3240 3267 interpreter as possible.
3241 3268
3242 3269 It also supports the pasting of code snippets that have leading '>>>'
3243 3270 and '...' prompts in them. This means that you can paste doctests from
3244 3271 files or docstrings (even if they have leading whitespace), and the
3245 3272 code will execute correctly. You can then use '%history -tn' to see
3246 3273 the translated history without line numbers; this will give you the
3247 3274 input after removal of all the leading prompts and whitespace, which
3248 3275 can be pasted back into an editor.
3249 3276
3250 3277 With these features, you can switch into this mode easily whenever you
3251 3278 need to do testing and changes to doctests, without having to leave
3252 3279 your existing IPython session.
3253 3280 """
3254 3281
3255 3282 # XXX - Fix this to have cleaner activate/deactivate calls.
3256 3283 from IPython.Extensions import InterpreterPasteInput as ipaste
3257 3284 from IPython.ipstruct import Struct
3258 3285
3259 3286 # Shorthands
3260 3287 shell = self.shell
3261 3288 oc = shell.outputcache
3262 3289 rc = shell.rc
3263 3290 meta = shell.meta
3264 3291 # dstore is a data store kept in the instance metadata bag to track any
3265 3292 # changes we make, so we can undo them later.
3266 3293 dstore = meta.setdefault('doctest_mode',Struct())
3267 3294 save_dstore = dstore.setdefault
3268 3295
3269 3296 # save a few values we'll need to recover later
3270 3297 mode = save_dstore('mode',False)
3271 3298 save_dstore('rc_pprint',rc.pprint)
3272 3299 save_dstore('xmode',shell.InteractiveTB.mode)
3273 3300 save_dstore('rc_separate_out',rc.separate_out)
3274 3301 save_dstore('rc_separate_out2',rc.separate_out2)
3275 3302 save_dstore('rc_prompts_pad_left',rc.prompts_pad_left)
3303 save_dstore('rc_separate_in',rc.separate_in)
3276 3304
3277 3305 if mode == False:
3278 3306 # turn on
3279 3307 ipaste.activate_prefilter()
3280 3308
3281 3309 oc.prompt1.p_template = '>>> '
3282 3310 oc.prompt2.p_template = '... '
3283 3311 oc.prompt_out.p_template = ''
3284 3312
3313 # Prompt separators like plain python
3314 oc.input_sep = oc.prompt1.sep = ''
3285 3315 oc.output_sep = ''
3286 3316 oc.output_sep2 = ''
3287 3317
3288 3318 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3289 3319 oc.prompt_out.pad_left = False
3290 3320
3291 3321 rc.pprint = False
3292 3322
3293 3323 shell.magic_xmode('Plain')
3294 3324
3295 3325 else:
3296 3326 # turn off
3297 3327 ipaste.deactivate_prefilter()
3298 3328
3299 3329 oc.prompt1.p_template = rc.prompt_in1
3300 3330 oc.prompt2.p_template = rc.prompt_in2
3301 3331 oc.prompt_out.p_template = rc.prompt_out
3302 3332
3333 oc.input_sep = oc.prompt1.sep = dstore.rc_separate_in
3334
3303 3335 oc.output_sep = dstore.rc_separate_out
3304 3336 oc.output_sep2 = dstore.rc_separate_out2
3305 3337
3306 3338 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3307 3339 oc.prompt_out.pad_left = dstore.rc_prompts_pad_left
3308 3340
3309 3341 rc.pprint = dstore.rc_pprint
3310 3342
3311 3343 shell.magic_xmode(dstore.xmode)
3312 3344
3313 3345 # Store new mode and inform
3314 3346 dstore.mode = bool(1-int(mode))
3315 3347 print 'Doctest mode is:',
3316 3348 print ['OFF','ON'][dstore.mode]
3317 3349
3318 3350 # end Magic
@@ -1,610 +1,613 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tools for inspecting Python objects.
3 3
4 4 Uses syntax highlighting for presenting the various information elements.
5 5
6 6 Similar in spirit to the inspect module, but all calls take a name argument to
7 7 reference the name under which an object is being read.
8 8
9 9 $Id: OInspect.py 2843 2007-10-15 21:22:32Z fperez $
10 10 """
11 11
12 12 #*****************************************************************************
13 13 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #*****************************************************************************
18 18
19 19 from IPython import Release
20 20 __author__ = '%s <%s>' % Release.authors['Fernando']
21 21 __license__ = Release.license
22 22
23 23 __all__ = ['Inspector','InspectColors']
24 24
25 25 # stdlib modules
26 26 import __builtin__
27 import StringIO
27 28 import inspect
28 29 import linecache
29 import string
30 import StringIO
31 import types
32 30 import os
31 import string
33 32 import sys
33 import types
34
34 35 # IPython's own
35 36 from IPython import PyColorize
36 from IPython.genutils import page,indent,Term,mkdict
37 from IPython.genutils import page,indent,Term
37 38 from IPython.Itpl import itpl
38 39 from IPython.wildcard import list_namespace
39 40 from IPython.ColorANSI import *
40 41
41 42 #****************************************************************************
42 43 # HACK!!! This is a crude fix for bugs in python 2.3's inspect module. We
43 44 # simply monkeypatch inspect with code copied from python 2.4.
44 45 if sys.version_info[:2] == (2,3):
45 46 from inspect import ismodule, getabsfile, modulesbyfile
46 47 def getmodule(object):
47 48 """Return the module an object was defined in, or None if not found."""
48 49 if ismodule(object):
49 50 return object
50 51 if hasattr(object, '__module__'):
51 52 return sys.modules.get(object.__module__)
52 53 try:
53 54 file = getabsfile(object)
54 55 except TypeError:
55 56 return None
56 57 if file in modulesbyfile:
57 58 return sys.modules.get(modulesbyfile[file])
58 59 for module in sys.modules.values():
59 60 if hasattr(module, '__file__'):
60 61 modulesbyfile[
61 62 os.path.realpath(
62 63 getabsfile(module))] = module.__name__
63 64 if file in modulesbyfile:
64 65 return sys.modules.get(modulesbyfile[file])
65 66 main = sys.modules['__main__']
66 67 if not hasattr(object, '__name__'):
67 68 return None
68 69 if hasattr(main, object.__name__):
69 70 mainobject = getattr(main, object.__name__)
70 71 if mainobject is object:
71 72 return main
72 73 builtin = sys.modules['__builtin__']
73 74 if hasattr(builtin, object.__name__):
74 75 builtinobject = getattr(builtin, object.__name__)
75 76 if builtinobject is object:
76 77 return builtin
77 78
78 79 inspect.getmodule = getmodule
79 80
80 81 #****************************************************************************
81 82 # Builtin color schemes
82 83
83 84 Colors = TermColors # just a shorthand
84 85
85 86 # Build a few color schemes
86 87 NoColor = ColorScheme(
87 88 'NoColor',{
88 89 'header' : Colors.NoColor,
89 90 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
90 91 } )
91 92
92 93 LinuxColors = ColorScheme(
93 94 'Linux',{
94 95 'header' : Colors.LightRed,
95 96 'normal' : Colors.Normal # color off (usu. Colors.Normal)
96 97 } )
97 98
98 99 LightBGColors = ColorScheme(
99 100 'LightBG',{
100 101 'header' : Colors.Red,
101 102 'normal' : Colors.Normal # color off (usu. Colors.Normal)
102 103 } )
103 104
104 105 # Build table of color schemes (needed by the parser)
105 106 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
106 107 'Linux')
107 108
108 109 #****************************************************************************
109 110 # Auxiliary functions
110 111 def getdoc(obj):
111 112 """Stable wrapper around inspect.getdoc.
112 113
113 114 This can't crash because of attribute problems.
114 115
115 116 It also attempts to call a getdoc() method on the given object. This
116 117 allows objects which provide their docstrings via non-standard mechanisms
117 118 (like Pyro proxies) to still be inspected by ipython's ? system."""
118 119
119 120 ds = None # default return value
120 121 try:
121 122 ds = inspect.getdoc(obj)
122 123 except:
123 124 # Harden against an inspect failure, which can occur with
124 125 # SWIG-wrapped extensions.
125 126 pass
126 127 # Allow objects to offer customized documentation via a getdoc method:
127 128 try:
128 129 ds2 = obj.getdoc()
129 130 except:
130 131 pass
131 132 else:
132 133 # if we get extra info, we add it to the normal docstring.
133 134 if ds is None:
134 135 ds = ds2
135 136 else:
136 137 ds = '%s\n%s' % (ds,ds2)
137 138 return ds
138 139
140
139 141 def getsource(obj,is_binary=False):
140 142 """Wrapper around inspect.getsource.
141 143
142 144 This can be modified by other projects to provide customized source
143 145 extraction.
144 146
145 147 Inputs:
146 148
147 149 - obj: an object whose source code we will attempt to extract.
148 150
149 151 Optional inputs:
150 152
151 153 - is_binary: whether the object is known to come from a binary source.
152 154 This implementation will skip returning any output for binary objects, but
153 155 custom extractors may know how to meaningfully process them."""
154 156
155 157 if is_binary:
156 158 return None
157 159 else:
158 160 try:
159 161 src = inspect.getsource(obj)
160 162 except TypeError:
161 163 if hasattr(obj,'__class__'):
162 164 src = inspect.getsource(obj.__class__)
163 165 return src
164 166
165 #****************************************************************************
166 # Class definitions
167
168 class myStringIO(StringIO.StringIO):
169 """Adds a writeln method to normal StringIO."""
170 def writeln(self,*arg,**kw):
171 """Does a write() and then a write('\n')"""
172 self.write(*arg,**kw)
173 self.write('\n')
174
175 class Inspector:
176 def __init__(self,color_table,code_color_table,scheme,
177 str_detail_level=0):
178 self.color_table = color_table
179 self.parser = PyColorize.Parser(code_color_table,out='str')
180 self.format = self.parser.format
181 self.str_detail_level = str_detail_level
182 self.set_active_scheme(scheme)
183
184 def __getargspec(self,obj):
167 def getargspec(obj):
185 168 """Get the names and default values of a function's arguments.
186 169
187 170 A tuple of four things is returned: (args, varargs, varkw, defaults).
188 171 'args' is a list of the argument names (it may contain nested lists).
189 172 'varargs' and 'varkw' are the names of the * and ** arguments or None.
190 173 'defaults' is an n-tuple of the default values of the last n arguments.
191 174
192 175 Modified version of inspect.getargspec from the Python Standard
193 176 Library."""
194 177
195 178 if inspect.isfunction(obj):
196 179 func_obj = obj
197 180 elif inspect.ismethod(obj):
198 181 func_obj = obj.im_func
199 182 else:
200 183 raise TypeError, 'arg is not a Python function'
201 184 args, varargs, varkw = inspect.getargs(func_obj.func_code)
202 185 return args, varargs, varkw, func_obj.func_defaults
203 186
187 #****************************************************************************
188 # Class definitions
189
190 class myStringIO(StringIO.StringIO):
191 """Adds a writeln method to normal StringIO."""
192 def writeln(self,*arg,**kw):
193 """Does a write() and then a write('\n')"""
194 self.write(*arg,**kw)
195 self.write('\n')
196
197
198 class Inspector:
199 def __init__(self,color_table,code_color_table,scheme,
200 str_detail_level=0):
201 self.color_table = color_table
202 self.parser = PyColorize.Parser(code_color_table,out='str')
203 self.format = self.parser.format
204 self.str_detail_level = str_detail_level
205 self.set_active_scheme(scheme)
206
204 207 def __getdef(self,obj,oname=''):
205 208 """Return the definition header for any callable object.
206 209
207 210 If any exception is generated, None is returned instead and the
208 211 exception is suppressed."""
209 212
210 213 try:
211 return oname + inspect.formatargspec(*self.__getargspec(obj))
214 return oname + inspect.formatargspec(*getargspec(obj))
212 215 except:
213 216 return None
214 217
215 218 def __head(self,h):
216 219 """Return a header string with proper colors."""
217 220 return '%s%s%s' % (self.color_table.active_colors.header,h,
218 221 self.color_table.active_colors.normal)
219 222
220 223 def set_active_scheme(self,scheme):
221 224 self.color_table.set_active_scheme(scheme)
222 225 self.parser.color_table.set_active_scheme(scheme)
223 226
224 227 def noinfo(self,msg,oname):
225 228 """Generic message when no information is found."""
226 229 print 'No %s found' % msg,
227 230 if oname:
228 231 print 'for %s' % oname
229 232 else:
230 233 print
231 234
232 235 def pdef(self,obj,oname=''):
233 236 """Print the definition header for any callable object.
234 237
235 238 If the object is a class, print the constructor information."""
236 239
237 240 if not callable(obj):
238 241 print 'Object is not callable.'
239 242 return
240 243
241 244 header = ''
242 245
243 246 if inspect.isclass(obj):
244 247 header = self.__head('Class constructor information:\n')
245 248 obj = obj.__init__
246 249 elif type(obj) is types.InstanceType:
247 250 obj = obj.__call__
248 251
249 252 output = self.__getdef(obj,oname)
250 253 if output is None:
251 254 self.noinfo('definition header',oname)
252 255 else:
253 256 print >>Term.cout, header,self.format(output),
254 257
255 258 def pdoc(self,obj,oname='',formatter = None):
256 259 """Print the docstring for any object.
257 260
258 261 Optional:
259 262 -formatter: a function to run the docstring through for specially
260 263 formatted docstrings."""
261 264
262 265 head = self.__head # so that itpl can find it even if private
263 266 ds = getdoc(obj)
264 267 if formatter:
265 268 ds = formatter(ds)
266 269 if inspect.isclass(obj):
267 270 init_ds = getdoc(obj.__init__)
268 271 output = itpl('$head("Class Docstring:")\n'
269 272 '$indent(ds)\n'
270 273 '$head("Constructor Docstring"):\n'
271 274 '$indent(init_ds)')
272 275 elif (type(obj) is types.InstanceType or isinstance(obj,object)) \
273 276 and hasattr(obj,'__call__'):
274 277 call_ds = getdoc(obj.__call__)
275 278 if call_ds:
276 279 output = itpl('$head("Class Docstring:")\n$indent(ds)\n'
277 280 '$head("Calling Docstring:")\n$indent(call_ds)')
278 281 else:
279 282 output = ds
280 283 else:
281 284 output = ds
282 285 if output is None:
283 286 self.noinfo('documentation',oname)
284 287 return
285 288 page(output)
286 289
287 290 def psource(self,obj,oname=''):
288 291 """Print the source code for an object."""
289 292
290 293 # Flush the source cache because inspect can return out-of-date source
291 294 linecache.checkcache()
292 295 try:
293 296 src = getsource(obj)
294 297 except:
295 298 self.noinfo('source',oname)
296 299 else:
297 300 page(self.format(src))
298 301
299 302 def pfile(self,obj,oname=''):
300 303 """Show the whole file where an object was defined."""
301 304
302 305 try:
303 306 try:
304 307 lineno = inspect.getsourcelines(obj)[1]
305 308 except TypeError:
306 309 # For instances, try the class object like getsource() does
307 310 if hasattr(obj,'__class__'):
308 311 lineno = inspect.getsourcelines(obj.__class__)[1]
309 312 # Adjust the inspected object so getabsfile() below works
310 313 obj = obj.__class__
311 314 except:
312 315 self.noinfo('file',oname)
313 316 return
314 317
315 318 # We only reach this point if object was successfully queried
316 319
317 320 # run contents of file through pager starting at line
318 321 # where the object is defined
319 322 ofile = inspect.getabsfile(obj)
320 323
321 324 if (ofile.endswith('.so') or ofile.endswith('.dll')):
322 325 print 'File %r is binary, not printing.' % ofile
323 326 elif not os.path.isfile(ofile):
324 327 print 'File %r does not exist, not printing.' % ofile
325 328 else:
326 329 # Print only text files, not extension binaries. Note that
327 330 # getsourcelines returns lineno with 1-offset and page() uses
328 331 # 0-offset, so we must adjust.
329 332 page(self.format(open(ofile).read()),lineno-1)
330 333
331 334 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
332 335 """Show detailed information about an object.
333 336
334 337 Optional arguments:
335 338
336 339 - oname: name of the variable pointing to the object.
337 340
338 341 - formatter: special formatter for docstrings (see pdoc)
339 342
340 343 - info: a structure with some information fields which may have been
341 344 precomputed already.
342 345
343 346 - detail_level: if set to 1, more information is given.
344 347 """
345 348
346 349 obj_type = type(obj)
347 350
348 351 header = self.__head
349 352 if info is None:
350 353 ismagic = 0
351 354 isalias = 0
352 355 ospace = ''
353 356 else:
354 357 ismagic = info.ismagic
355 358 isalias = info.isalias
356 359 ospace = info.namespace
357 360 # Get docstring, special-casing aliases:
358 361 if isalias:
359 362 if not callable(obj):
360 363 try:
361 364 ds = "Alias to the system command:\n %s" % obj[1]
362 365 except:
363 366 ds = "Alias: " + str(obj)
364 367 else:
365 368 ds = "Alias to " + str(obj)
366 369 if obj.__doc__:
367 370 ds += "\nDocstring:\n" + obj.__doc__
368 371 else:
369 372 ds = getdoc(obj)
370 373 if ds is None:
371 374 ds = '<no docstring>'
372 375 if formatter is not None:
373 376 ds = formatter(ds)
374 377
375 378 # store output in a list which gets joined with \n at the end.
376 379 out = myStringIO()
377 380
378 381 string_max = 200 # max size of strings to show (snipped if longer)
379 382 shalf = int((string_max -5)/2)
380 383
381 384 if ismagic:
382 385 obj_type_name = 'Magic function'
383 386 elif isalias:
384 387 obj_type_name = 'System alias'
385 388 else:
386 389 obj_type_name = obj_type.__name__
387 390 out.writeln(header('Type:\t\t')+obj_type_name)
388 391
389 392 try:
390 393 bclass = obj.__class__
391 394 out.writeln(header('Base Class:\t')+str(bclass))
392 395 except: pass
393 396
394 397 # String form, but snip if too long in ? form (full in ??)
395 398 if detail_level >= self.str_detail_level:
396 399 try:
397 400 ostr = str(obj)
398 401 str_head = 'String Form:'
399 402 if not detail_level and len(ostr)>string_max:
400 403 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
401 404 ostr = ("\n" + " " * len(str_head.expandtabs())).\
402 405 join(map(string.strip,ostr.split("\n")))
403 406 if ostr.find('\n') > -1:
404 407 # Print multi-line strings starting at the next line.
405 408 str_sep = '\n'
406 409 else:
407 410 str_sep = '\t'
408 411 out.writeln("%s%s%s" % (header(str_head),str_sep,ostr))
409 412 except:
410 413 pass
411 414
412 415 if ospace:
413 416 out.writeln(header('Namespace:\t')+ospace)
414 417
415 418 # Length (for strings and lists)
416 419 try:
417 420 length = str(len(obj))
418 421 out.writeln(header('Length:\t\t')+length)
419 422 except: pass
420 423
421 424 # Filename where object was defined
422 425 binary_file = False
423 426 try:
424 427 try:
425 428 fname = inspect.getabsfile(obj)
426 429 except TypeError:
427 430 # For an instance, the file that matters is where its class was
428 431 # declared.
429 432 if hasattr(obj,'__class__'):
430 433 fname = inspect.getabsfile(obj.__class__)
431 434 if fname.endswith('<string>'):
432 435 fname = 'Dynamically generated function. No source code available.'
433 436 if (fname.endswith('.so') or fname.endswith('.dll')):
434 437 binary_file = True
435 438 out.writeln(header('File:\t\t')+fname)
436 439 except:
437 440 # if anything goes wrong, we don't want to show source, so it's as
438 441 # if the file was binary
439 442 binary_file = True
440 443
441 444 # reconstruct the function definition and print it:
442 445 defln = self.__getdef(obj,oname)
443 446 if defln:
444 447 out.write(header('Definition:\t')+self.format(defln))
445 448
446 449 # Docstrings only in detail 0 mode, since source contains them (we
447 450 # avoid repetitions). If source fails, we add them back, see below.
448 451 if ds and detail_level == 0:
449 452 out.writeln(header('Docstring:\n') + indent(ds))
450 453
451 454 # Original source code for any callable
452 455 if detail_level:
453 456 # Flush the source cache because inspect can return out-of-date
454 457 # source
455 458 linecache.checkcache()
456 459 source_success = False
457 460 try:
458 461 try:
459 462 src = getsource(obj,binary_file)
460 463 except TypeError:
461 464 if hasattr(obj,'__class__'):
462 465 src = getsource(obj.__class__,binary_file)
463 466 if src is not None:
464 467 source = self.format(src)
465 468 out.write(header('Source:\n')+source.rstrip())
466 469 source_success = True
467 470 except Exception, msg:
468 471 pass
469 472
470 473 if ds and not source_success:
471 474 out.writeln(header('Docstring [source file open failed]:\n')
472 475 + indent(ds))
473 476
474 477 # Constructor docstring for classes
475 478 if inspect.isclass(obj):
476 479 # reconstruct the function definition and print it:
477 480 try:
478 481 obj_init = obj.__init__
479 482 except AttributeError:
480 483 init_def = init_ds = None
481 484 else:
482 485 init_def = self.__getdef(obj_init,oname)
483 486 init_ds = getdoc(obj_init)
484 487 # Skip Python's auto-generated docstrings
485 488 if init_ds and \
486 489 init_ds.startswith('x.__init__(...) initializes'):
487 490 init_ds = None
488 491
489 492 if init_def or init_ds:
490 493 out.writeln(header('\nConstructor information:'))
491 494 if init_def:
492 495 out.write(header('Definition:\t')+ self.format(init_def))
493 496 if init_ds:
494 497 out.writeln(header('Docstring:\n') + indent(init_ds))
495 498 # and class docstring for instances:
496 499 elif obj_type is types.InstanceType or \
497 500 isinstance(obj,object):
498 501
499 502 # First, check whether the instance docstring is identical to the
500 503 # class one, and print it separately if they don't coincide. In
501 504 # most cases they will, but it's nice to print all the info for
502 505 # objects which use instance-customized docstrings.
503 506 if ds:
504 507 try:
505 508 cls = getattr(obj,'__class__')
506 509 except:
507 510 class_ds = None
508 511 else:
509 512 class_ds = getdoc(cls)
510 513 # Skip Python's auto-generated docstrings
511 514 if class_ds and \
512 515 (class_ds.startswith('function(code, globals[,') or \
513 516 class_ds.startswith('instancemethod(function, instance,') or \
514 517 class_ds.startswith('module(name[,') ):
515 518 class_ds = None
516 519 if class_ds and ds != class_ds:
517 520 out.writeln(header('Class Docstring:\n') +
518 521 indent(class_ds))
519 522
520 523 # Next, try to show constructor docstrings
521 524 try:
522 525 init_ds = getdoc(obj.__init__)
523 526 # Skip Python's auto-generated docstrings
524 527 if init_ds and \
525 528 init_ds.startswith('x.__init__(...) initializes'):
526 529 init_ds = None
527 530 except AttributeError:
528 531 init_ds = None
529 532 if init_ds:
530 533 out.writeln(header('Constructor Docstring:\n') +
531 534 indent(init_ds))
532 535
533 536 # Call form docstring for callable instances
534 537 if hasattr(obj,'__call__'):
535 538 #out.writeln(header('Callable:\t')+'Yes')
536 539 call_def = self.__getdef(obj.__call__,oname)
537 540 #if call_def is None:
538 541 # out.writeln(header('Call def:\t')+
539 542 # 'Calling definition not available.')
540 543 if call_def is not None:
541 544 out.writeln(header('Call def:\t')+self.format(call_def))
542 545 call_ds = getdoc(obj.__call__)
543 546 # Skip Python's auto-generated docstrings
544 547 if call_ds and call_ds.startswith('x.__call__(...) <==> x(...)'):
545 548 call_ds = None
546 549 if call_ds:
547 550 out.writeln(header('Call docstring:\n') + indent(call_ds))
548 551
549 552 # Finally send to printer/pager
550 553 output = out.getvalue()
551 554 if output:
552 555 page(output)
553 556 # end pinfo
554 557
555 558 def psearch(self,pattern,ns_table,ns_search=[],
556 559 ignore_case=False,show_all=False):
557 560 """Search namespaces with wildcards for objects.
558 561
559 562 Arguments:
560 563
561 564 - pattern: string containing shell-like wildcards to use in namespace
562 565 searches and optionally a type specification to narrow the search to
563 566 objects of that type.
564 567
565 568 - ns_table: dict of name->namespaces for search.
566 569
567 570 Optional arguments:
568 571
569 572 - ns_search: list of namespace names to include in search.
570 573
571 574 - ignore_case(False): make the search case-insensitive.
572 575
573 576 - show_all(False): show all names, including those starting with
574 577 underscores.
575 578 """
576 579 #print 'ps pattern:<%r>' % pattern # dbg
577 580
578 581 # defaults
579 582 type_pattern = 'all'
580 583 filter = ''
581 584
582 585 cmds = pattern.split()
583 586 len_cmds = len(cmds)
584 587 if len_cmds == 1:
585 588 # Only filter pattern given
586 589 filter = cmds[0]
587 590 elif len_cmds == 2:
588 591 # Both filter and type specified
589 592 filter,type_pattern = cmds
590 593 else:
591 594 raise ValueError('invalid argument string for psearch: <%s>' %
592 595 pattern)
593 596
594 597 # filter search namespaces
595 598 for name in ns_search:
596 599 if name not in ns_table:
597 600 raise ValueError('invalid namespace <%s>. Valid names: %s' %
598 601 (name,ns_table.keys()))
599 602
600 603 #print 'type_pattern:',type_pattern # dbg
601 604 search_result = []
602 605 for ns_name in ns_search:
603 606 ns = ns_table[ns_name]
604 607 tmp_res = list(list_namespace(ns,type_pattern,filter,
605 608 ignore_case=ignore_case,
606 609 show_all=show_all))
607 610 search_result.extend(tmp_res)
608 611 search_result.sort()
609 612
610 613 page('\n'.join(search_result))
@@ -1,1235 +1,1235 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 try: # Python 2.3 compatibility
50 set
51 except NameError:
52 import sets
53 set = sets.Set
54
55
56 49 # Globals
57 50 # global flag to pass around information about Ctrl-C without exceptions
58 51 KBINT = False
59 52
60 53 # global flag to turn on/off Tk support.
61 54 USE_TK = False
62 55
63 56 # ID for the main thread, used for cross-thread exceptions
64 57 MAIN_THREAD_ID = thread.get_ident()
65 58
66 59 # Tag when runcode() is active, for exception handling
67 60 CODE_RUN = None
68 61
62 # Default timeout for waiting for multithreaded shells (in seconds)
63 GUI_TIMEOUT = 10
64
69 65 #-----------------------------------------------------------------------------
70 66 # This class is trivial now, but I want to have it in to publish a clean
71 67 # interface. Later when the internals are reorganized, code that uses this
72 68 # shouldn't have to change.
73 69
74 70 class IPShell:
75 71 """Create an IPython instance."""
76 72
77 73 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
78 74 debug=1,shell_class=InteractiveShell):
79 75 self.IP = make_IPython(argv,user_ns=user_ns,
80 76 user_global_ns=user_global_ns,
81 77 debug=debug,shell_class=shell_class)
82 78
83 79 def mainloop(self,sys_exit=0,banner=None):
84 80 self.IP.mainloop(banner)
85 81 if sys_exit:
86 82 sys.exit()
87 83
88 84 #-----------------------------------------------------------------------------
89 85 def kill_embedded(self,parameter_s=''):
90 86 """%kill_embedded : deactivate for good the current embedded IPython.
91 87
92 88 This function (after asking for confirmation) sets an internal flag so that
93 89 an embedded IPython will never activate again. This is useful to
94 90 permanently disable a shell that is being called inside a loop: once you've
95 91 figured out what you needed from it, you may then kill it and the program
96 92 will then continue to run without the interactive shell interfering again.
97 93 """
98 94
99 95 kill = ask_yes_no("Are you sure you want to kill this embedded instance "
100 96 "(y/n)? [y/N] ",'n')
101 97 if kill:
102 98 self.shell.embedded_active = False
103 99 print "This embedded IPython will not reactivate anymore once you exit."
104 100
105 101 class IPShellEmbed:
106 102 """Allow embedding an IPython shell into a running program.
107 103
108 104 Instances of this class are callable, with the __call__ method being an
109 105 alias to the embed() method of an InteractiveShell instance.
110 106
111 107 Usage (see also the example-embed.py file for a running example):
112 108
113 109 ipshell = IPShellEmbed([argv,banner,exit_msg,rc_override])
114 110
115 111 - argv: list containing valid command-line options for IPython, as they
116 112 would appear in sys.argv[1:].
117 113
118 114 For example, the following command-line options:
119 115
120 116 $ ipython -prompt_in1 'Input <\\#>' -colors LightBG
121 117
122 118 would be passed in the argv list as:
123 119
124 120 ['-prompt_in1','Input <\\#>','-colors','LightBG']
125 121
126 122 - banner: string which gets printed every time the interpreter starts.
127 123
128 124 - exit_msg: string which gets printed every time the interpreter exits.
129 125
130 126 - rc_override: a dict or Struct of configuration options such as those
131 127 used by IPython. These options are read from your ~/.ipython/ipythonrc
132 128 file when the Shell object is created. Passing an explicit rc_override
133 129 dict with any options you want allows you to override those values at
134 130 creation time without having to modify the file. This way you can create
135 131 embeddable instances configured in any way you want without editing any
136 132 global files (thus keeping your interactive IPython configuration
137 133 unchanged).
138 134
139 135 Then the ipshell instance can be called anywhere inside your code:
140 136
141 137 ipshell(header='') -> Opens up an IPython shell.
142 138
143 139 - header: string printed by the IPython shell upon startup. This can let
144 140 you know where in your code you are when dropping into the shell. Note
145 141 that 'banner' gets prepended to all calls, so header is used for
146 142 location-specific information.
147 143
148 144 For more details, see the __call__ method below.
149 145
150 146 When the IPython shell is exited with Ctrl-D, normal program execution
151 147 resumes.
152 148
153 149 This functionality was inspired by a posting on comp.lang.python by cmkl
154 150 <cmkleffner@gmx.de> on Dec. 06/01 concerning similar uses of pyrepl, and
155 151 by the IDL stop/continue commands."""
156 152
157 153 def __init__(self,argv=None,banner='',exit_msg=None,rc_override=None,
158 154 user_ns=None):
159 155 """Note that argv here is a string, NOT a list."""
160 156 self.set_banner(banner)
161 157 self.set_exit_msg(exit_msg)
162 158 self.set_dummy_mode(0)
163 159
164 160 # sys.displayhook is a global, we need to save the user's original
165 161 # Don't rely on __displayhook__, as the user may have changed that.
166 162 self.sys_displayhook_ori = sys.displayhook
167 163
168 164 # save readline completer status
169 165 try:
170 166 #print 'Save completer',sys.ipcompleter # dbg
171 167 self.sys_ipcompleter_ori = sys.ipcompleter
172 168 except:
173 169 pass # not nested with IPython
174 170
175 171 self.IP = make_IPython(argv,rc_override=rc_override,
176 172 embedded=True,
177 173 user_ns=user_ns)
178 174
179 175 ip = ipapi.IPApi(self.IP)
180 176 ip.expose_magic("kill_embedded",kill_embedded)
181 177
182 178 # copy our own displayhook also
183 179 self.sys_displayhook_embed = sys.displayhook
184 180 # and leave the system's display hook clean
185 181 sys.displayhook = self.sys_displayhook_ori
186 182 # don't use the ipython crash handler so that user exceptions aren't
187 183 # trapped
188 184 sys.excepthook = ultraTB.FormattedTB(color_scheme = self.IP.rc.colors,
189 185 mode = self.IP.rc.xmode,
190 186 call_pdb = self.IP.rc.pdb)
191 187 self.restore_system_completer()
192 188
193 189 def restore_system_completer(self):
194 190 """Restores the readline completer which was in place.
195 191
196 192 This allows embedded IPython within IPython not to disrupt the
197 193 parent's completion.
198 194 """
199 195
200 196 try:
201 197 self.IP.readline.set_completer(self.sys_ipcompleter_ori)
202 198 sys.ipcompleter = self.sys_ipcompleter_ori
203 199 except:
204 200 pass
205 201
206 202 def __call__(self,header='',local_ns=None,global_ns=None,dummy=None):
207 203 """Activate the interactive interpreter.
208 204
209 205 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
210 206 the interpreter shell with the given local and global namespaces, and
211 207 optionally print a header string at startup.
212 208
213 209 The shell can be globally activated/deactivated using the
214 210 set/get_dummy_mode methods. This allows you to turn off a shell used
215 211 for debugging globally.
216 212
217 213 However, *each* time you call the shell you can override the current
218 214 state of dummy_mode with the optional keyword parameter 'dummy'. For
219 215 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
220 216 can still have a specific call work by making it as IPShell(dummy=0).
221 217
222 218 The optional keyword parameter dummy controls whether the call
223 219 actually does anything. """
224 220
225 221 # If the user has turned it off, go away
226 222 if not self.IP.embedded_active:
227 223 return
228 224
229 225 # Normal exits from interactive mode set this flag, so the shell can't
230 226 # re-enter (it checks this variable at the start of interactive mode).
231 227 self.IP.exit_now = False
232 228
233 229 # Allow the dummy parameter to override the global __dummy_mode
234 230 if dummy or (dummy != 0 and self.__dummy_mode):
235 231 return
236 232
237 233 # Set global subsystems (display,completions) to our values
238 234 sys.displayhook = self.sys_displayhook_embed
239 235 if self.IP.has_readline:
240 236 self.IP.set_completer()
241 237
242 238 if self.banner and header:
243 239 format = '%s\n%s\n'
244 240 else:
245 241 format = '%s%s\n'
246 242 banner = format % (self.banner,header)
247 243
248 244 # Call the embedding code with a stack depth of 1 so it can skip over
249 245 # our call and get the original caller's namespaces.
250 246 self.IP.embed_mainloop(banner,local_ns,global_ns,stack_depth=1)
251 247
252 248 if self.exit_msg:
253 249 print self.exit_msg
254 250
255 251 # Restore global systems (display, completion)
256 252 sys.displayhook = self.sys_displayhook_ori
257 253 self.restore_system_completer()
258 254
259 255 def set_dummy_mode(self,dummy):
260 256 """Sets the embeddable shell's dummy mode parameter.
261 257
262 258 set_dummy_mode(dummy): dummy = 0 or 1.
263 259
264 260 This parameter is persistent and makes calls to the embeddable shell
265 261 silently return without performing any action. This allows you to
266 262 globally activate or deactivate a shell you're using with a single call.
267 263
268 264 If you need to manually"""
269 265
270 266 if dummy not in [0,1,False,True]:
271 267 raise ValueError,'dummy parameter must be boolean'
272 268 self.__dummy_mode = dummy
273 269
274 270 def get_dummy_mode(self):
275 271 """Return the current value of the dummy mode parameter.
276 272 """
277 273 return self.__dummy_mode
278 274
279 275 def set_banner(self,banner):
280 276 """Sets the global banner.
281 277
282 278 This banner gets prepended to every header printed when the shell
283 279 instance is called."""
284 280
285 281 self.banner = banner
286 282
287 283 def set_exit_msg(self,exit_msg):
288 284 """Sets the global exit_msg.
289 285
290 286 This exit message gets printed upon exiting every time the embedded
291 287 shell is called. It is None by default. """
292 288
293 289 self.exit_msg = exit_msg
294 290
295 291 #-----------------------------------------------------------------------------
296 292 if HAS_CTYPES:
297 293 # Add async exception support. Trick taken from:
298 294 # http://sebulba.wikispaces.com/recipe+thread2
299 295 def _async_raise(tid, exctype):
300 296 """raises the exception, performs cleanup if needed"""
301 297 if not inspect.isclass(exctype):
302 298 raise TypeError("Only types can be raised (not instances)")
303 299 res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,
304 300 ctypes.py_object(exctype))
305 301 if res == 0:
306 302 raise ValueError("invalid thread id")
307 303 elif res != 1:
308 304 # """if it returns a number greater than one, you're in trouble,
309 305 # and you should call it again with exc=NULL to revert the effect"""
310 306 ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
311 307 raise SystemError("PyThreadState_SetAsyncExc failed")
312 308
313 309 def sigint_handler (signum,stack_frame):
314 310 """Sigint handler for threaded apps.
315 311
316 312 This is a horrible hack to pass information about SIGINT _without_
317 313 using exceptions, since I haven't been able to properly manage
318 314 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
319 315 done (or at least that's my understanding from a c.l.py thread where
320 316 this was discussed)."""
321 317
322 318 global KBINT
323 319
324 320 if CODE_RUN:
325 321 _async_raise(MAIN_THREAD_ID,KeyboardInterrupt)
326 322 else:
327 323 KBINT = True
328 324 print '\nKeyboardInterrupt - Press <Enter> to continue.',
329 325 Term.cout.flush()
330 326
331 327 else:
332 328 def sigint_handler (signum,stack_frame):
333 329 """Sigint handler for threaded apps.
334 330
335 331 This is a horrible hack to pass information about SIGINT _without_
336 332 using exceptions, since I haven't been able to properly manage
337 333 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
338 334 done (or at least that's my understanding from a c.l.py thread where
339 335 this was discussed)."""
340 336
341 337 global KBINT
342 338
343 339 print '\nKeyboardInterrupt - Press <Enter> to continue.',
344 340 Term.cout.flush()
345 341 # Set global flag so that runsource can know that Ctrl-C was hit
346 342 KBINT = True
347 343
348 344
349 345 class MTInteractiveShell(InteractiveShell):
350 346 """Simple multi-threaded shell."""
351 347
352 348 # Threading strategy taken from:
353 349 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109, by Brian
354 350 # McErlean and John Finlay. Modified with corrections by Antoon Pardon,
355 351 # from the pygtk mailing list, to avoid lockups with system calls.
356 352
357 353 # class attribute to indicate whether the class supports threads or not.
358 354 # Subclasses with thread support should override this as needed.
359 355 isthreaded = True
360 356
361 357 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
362 user_ns=None,user_global_ns=None,banner2='',**kw):
358 user_ns=None,user_global_ns=None,banner2='',
359 gui_timeout=GUI_TIMEOUT,**kw):
363 360 """Similar to the normal InteractiveShell, but with threading control"""
364 361
365 362 InteractiveShell.__init__(self,name,usage,rc,user_ns,
366 363 user_global_ns,banner2)
367 364
365 # Timeout we wait for GUI thread
366 self.gui_timeout = gui_timeout
368 367
369 368 # A queue to hold the code to be executed.
370 369 self.code_queue = Queue.Queue()
371 370
372 371 # Stuff to do at closing time
373 372 self._kill = None
374 373 on_kill = kw.get('on_kill', [])
375 374 # Check that all things to kill are callable:
376 375 for t in on_kill:
377 376 if not callable(t):
378 377 raise TypeError,'on_kill must be a list of callables'
379 378 self.on_kill = on_kill
380 379 # thread identity of the "worker thread" (that may execute code directly)
381 380 self.worker_ident = None
382 381
383 382 def runsource(self, source, filename="<input>", symbol="single"):
384 383 """Compile and run some source in the interpreter.
385 384
386 385 Modified version of code.py's runsource(), to handle threading issues.
387 386 See the original for full docstring details."""
388 387
389 388 global KBINT
390 389
391 390 # If Ctrl-C was typed, we reset the flag and return right away
392 391 if KBINT:
393 392 KBINT = False
394 393 return False
395 394
396 395 if self._kill:
397 396 # can't queue new code if we are being killed
398 397 return True
399 398
400 399 try:
401 400 code = self.compile(source, filename, symbol)
402 401 except (OverflowError, SyntaxError, ValueError):
403 402 # Case 1
404 403 self.showsyntaxerror(filename)
405 404 return False
406 405
407 406 if code is None:
408 407 # Case 2
409 408 return True
410 409
411 # shortcut - if we are in worker thread, or the worker thread is not running,
412 # execute directly (to allow recursion and prevent deadlock if code is run early
413 # in IPython construction)
410 # shortcut - if we are in worker thread, or the worker thread is not
411 # running, execute directly (to allow recursion and prevent deadlock if
412 # code is run early in IPython construction)
414 413
415 if (self.worker_ident is None or self.worker_ident == thread.get_ident()):
414 if (self.worker_ident is None
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 received_ev.wait(5)
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):
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 = IPython.ipapi.make_user_ns(user_ns)
568 568
569 569 # Import numpy as np/pyplot as plt are conventions we're trying to
570 570 # somewhat standardize on. Making them available to users by default
571 571 # will greatly help this.
572 572 exec ("import numpy\n"
573 573 "import numpy as np\n"
574 574 "import matplotlib\n"
575 575 "import matplotlib.pylab as pylab\n"
576 576 "try:\n"
577 577 " import matplotlib.pyplot as plt\n"
578 578 "except ImportError:\n"
579 579 " pass\n"
580 580 ) in user_ns
581 581
582 582 # Build matplotlib info banner
583 583 b="""
584 584 Welcome to pylab, a matplotlib-based Python environment.
585 585 For more information, type 'help(pylab)'.
586 586 """
587 587 return user_ns,b
588 588
589 589 def mplot_exec(self,fname,*where,**kw):
590 590 """Execute a matplotlib script.
591 591
592 592 This is a call to execfile(), but wrapped in safeties to properly
593 593 handle interactive rendering and backend switching."""
594 594
595 595 #print '*** Matplotlib runner ***' # dbg
596 596 # turn off rendering until end of script
597 597 isInteractive = self.matplotlib.rcParams['interactive']
598 598 self.matplotlib.interactive(False)
599 599 self.safe_execfile(fname,*where,**kw)
600 600 self.matplotlib.interactive(isInteractive)
601 601 # make rendering call now, if the user tried to do it
602 602 if self.pylab.draw_if_interactive.called:
603 603 self.pylab.draw()
604 604 self.pylab.draw_if_interactive.called = False
605 605
606 606 # if a backend switch was performed, reverse it now
607 607 if self.mpl_use._called:
608 608 self.matplotlib.rcParams['backend'] = self.mpl_backend
609 609
610 610 def magic_run(self,parameter_s=''):
611 611 Magic.magic_run(self,parameter_s,runner=self.mplot_exec)
612 612
613 613 # Fix the docstring so users see the original as well
614 614 magic_run.__doc__ = "%s\n%s" % (Magic.magic_run.__doc__,
615 615 "\n *** Modified %run for Matplotlib,"
616 616 " with proper interactive handling ***")
617 617
618 618 # Now we provide 2 versions of a matplotlib-aware IPython base shells, single
619 619 # and multithreaded. Note that these are meant for internal use, the IPShell*
620 620 # classes below are the ones meant for public consumption.
621 621
622 622 class MatplotlibShell(MatplotlibShellBase,InteractiveShell):
623 623 """Single-threaded shell with matplotlib support."""
624 624
625 625 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
626 626 user_ns=None,user_global_ns=None,**kw):
627 627 user_ns,b2 = self._matplotlib_config(name,user_ns)
628 628 InteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
629 629 banner2=b2,**kw)
630 630
631 631 class MatplotlibMTShell(MatplotlibShellBase,MTInteractiveShell):
632 632 """Multi-threaded shell with matplotlib support."""
633 633
634 634 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
635 635 user_ns=None,user_global_ns=None, **kw):
636 636 user_ns,b2 = self._matplotlib_config(name,user_ns)
637 637 MTInteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
638 638 banner2=b2,**kw)
639 639
640 640 #-----------------------------------------------------------------------------
641 641 # Utility functions for the different GUI enabled IPShell* classes.
642 642
643 643 def get_tk():
644 644 """Tries to import Tkinter and returns a withdrawn Tkinter root
645 645 window. If Tkinter is already imported or not available, this
646 646 returns None. This function calls `hijack_tk` underneath.
647 647 """
648 648 if not USE_TK or sys.modules.has_key('Tkinter'):
649 649 return None
650 650 else:
651 651 try:
652 652 import Tkinter
653 653 except ImportError:
654 654 return None
655 655 else:
656 656 hijack_tk()
657 657 r = Tkinter.Tk()
658 658 r.withdraw()
659 659 return r
660 660
661 661 def hijack_tk():
662 662 """Modifies Tkinter's mainloop with a dummy so when a module calls
663 663 mainloop, it does not block.
664 664
665 665 """
666 666 def misc_mainloop(self, n=0):
667 667 pass
668 668 def tkinter_mainloop(n=0):
669 669 pass
670 670
671 671 import Tkinter
672 672 Tkinter.Misc.mainloop = misc_mainloop
673 673 Tkinter.mainloop = tkinter_mainloop
674 674
675 675 def update_tk(tk):
676 676 """Updates the Tkinter event loop. This is typically called from
677 677 the respective WX or GTK mainloops.
678 678 """
679 679 if tk:
680 680 tk.update()
681 681
682 682 def hijack_wx():
683 683 """Modifies wxPython's MainLoop with a dummy so user code does not
684 684 block IPython. The hijacked mainloop function is returned.
685 685 """
686 686 def dummy_mainloop(*args, **kw):
687 687 pass
688 688
689 689 try:
690 690 import wx
691 691 except ImportError:
692 692 # For very old versions of WX
693 693 import wxPython as wx
694 694
695 695 ver = wx.__version__
696 696 orig_mainloop = None
697 697 if ver[:3] >= '2.5':
698 698 import wx
699 699 if hasattr(wx, '_core_'): core = getattr(wx, '_core_')
700 700 elif hasattr(wx, '_core'): core = getattr(wx, '_core')
701 701 else: raise AttributeError('Could not find wx core module')
702 702 orig_mainloop = core.PyApp_MainLoop
703 703 core.PyApp_MainLoop = dummy_mainloop
704 704 elif ver[:3] == '2.4':
705 705 orig_mainloop = wx.wxc.wxPyApp_MainLoop
706 706 wx.wxc.wxPyApp_MainLoop = dummy_mainloop
707 707 else:
708 708 warn("Unable to find either wxPython version 2.4 or >= 2.5.")
709 709 return orig_mainloop
710 710
711 711 def hijack_gtk():
712 712 """Modifies pyGTK's mainloop with a dummy so user code does not
713 713 block IPython. This function returns the original `gtk.mainloop`
714 714 function that has been hijacked.
715 715 """
716 716 def dummy_mainloop(*args, **kw):
717 717 pass
718 718 import gtk
719 719 if gtk.pygtk_version >= (2,4,0): orig_mainloop = gtk.main
720 720 else: orig_mainloop = gtk.mainloop
721 721 gtk.mainloop = dummy_mainloop
722 722 gtk.main = dummy_mainloop
723 723 return orig_mainloop
724 724
725 725 def hijack_qt():
726 726 """Modifies PyQt's mainloop with a dummy so user code does not
727 727 block IPython. This function returns the original
728 728 `qt.qApp.exec_loop` function that has been hijacked.
729 729 """
730 730 def dummy_mainloop(*args, **kw):
731 731 pass
732 732 import qt
733 733 orig_mainloop = qt.qApp.exec_loop
734 734 qt.qApp.exec_loop = dummy_mainloop
735 735 qt.QApplication.exec_loop = dummy_mainloop
736 736 return orig_mainloop
737 737
738 738 def hijack_qt4():
739 739 """Modifies PyQt4's mainloop with a dummy so user code does not
740 740 block IPython. This function returns the original
741 741 `QtGui.qApp.exec_` function that has been hijacked.
742 742 """
743 743 def dummy_mainloop(*args, **kw):
744 744 pass
745 745 from PyQt4 import QtGui, QtCore
746 746 orig_mainloop = QtGui.qApp.exec_
747 747 QtGui.qApp.exec_ = dummy_mainloop
748 748 QtGui.QApplication.exec_ = dummy_mainloop
749 749 QtCore.QCoreApplication.exec_ = dummy_mainloop
750 750 return orig_mainloop
751 751
752 752 #-----------------------------------------------------------------------------
753 753 # The IPShell* classes below are the ones meant to be run by external code as
754 754 # IPython instances. Note that unless a specific threading strategy is
755 755 # desired, the factory function start() below should be used instead (it
756 756 # selects the proper threaded class).
757 757
758 758 class IPThread(threading.Thread):
759 759 def run(self):
760 760 self.IP.mainloop(self._banner)
761 761 self.IP.kill()
762 762
763 763 class IPShellGTK(IPThread):
764 764 """Run a gtk mainloop() in a separate thread.
765 765
766 766 Python commands can be passed to the thread where they will be executed.
767 767 This is implemented by periodically checking for passed code using a
768 768 GTK timeout callback."""
769 769
770 770 TIMEOUT = 100 # Millisecond interval between timeouts.
771 771
772 772 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
773 773 debug=1,shell_class=MTInteractiveShell):
774 774
775 775 import gtk
776 776
777 777 self.gtk = gtk
778 778 self.gtk_mainloop = hijack_gtk()
779 779
780 780 # Allows us to use both Tk and GTK.
781 781 self.tk = get_tk()
782 782
783 783 if gtk.pygtk_version >= (2,4,0): mainquit = self.gtk.main_quit
784 784 else: mainquit = self.gtk.mainquit
785 785
786 786 self.IP = make_IPython(argv,user_ns=user_ns,
787 787 user_global_ns=user_global_ns,
788 788 debug=debug,
789 789 shell_class=shell_class,
790 790 on_kill=[mainquit])
791 791
792 792 # HACK: slot for banner in self; it will be passed to the mainloop
793 793 # method only and .run() needs it. The actual value will be set by
794 794 # .mainloop().
795 795 self._banner = None
796 796
797 797 threading.Thread.__init__(self)
798 798
799 799 def mainloop(self,sys_exit=0,banner=None):
800 800
801 801 self._banner = banner
802 802
803 803 if self.gtk.pygtk_version >= (2,4,0):
804 804 import gobject
805 805 gobject.idle_add(self.on_timer)
806 806 else:
807 807 self.gtk.idle_add(self.on_timer)
808 808
809 809 if sys.platform != 'win32':
810 810 try:
811 811 if self.gtk.gtk_version[0] >= 2:
812 812 self.gtk.gdk.threads_init()
813 813 except AttributeError:
814 814 pass
815 815 except RuntimeError:
816 816 error('Your pyGTK likely has not been compiled with '
817 817 'threading support.\n'
818 818 'The exception printout is below.\n'
819 819 'You can either rebuild pyGTK with threads, or '
820 820 'try using \n'
821 821 'matplotlib with a different backend (like Tk or WX).\n'
822 822 'Note that matplotlib will most likely not work in its '
823 823 'current state!')
824 824 self.IP.InteractiveTB()
825 825
826 826 self.start()
827 827 self.gtk.gdk.threads_enter()
828 828 self.gtk_mainloop()
829 829 self.gtk.gdk.threads_leave()
830 830 self.join()
831 831
832 832 def on_timer(self):
833 833 """Called when GTK is idle.
834 834
835 835 Must return True always, otherwise GTK stops calling it"""
836 836
837 837 update_tk(self.tk)
838 838 self.IP.runcode()
839 839 time.sleep(0.01)
840 840 return True
841 841
842 842
843 843 class IPShellWX(IPThread):
844 844 """Run a wx mainloop() in a separate thread.
845 845
846 846 Python commands can be passed to the thread where they will be executed.
847 847 This is implemented by periodically checking for passed code using a
848 848 GTK timeout callback."""
849 849
850 850 TIMEOUT = 100 # Millisecond interval between timeouts.
851 851
852 852 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
853 853 debug=1,shell_class=MTInteractiveShell):
854 854
855 855 self.IP = make_IPython(argv,user_ns=user_ns,
856 856 user_global_ns=user_global_ns,
857 857 debug=debug,
858 858 shell_class=shell_class,
859 859 on_kill=[self.wxexit])
860 860
861 861 wantedwxversion=self.IP.rc.wxversion
862 862 if wantedwxversion!="0":
863 863 try:
864 864 import wxversion
865 865 except ImportError:
866 866 error('The wxversion module is needed for WX version selection')
867 867 else:
868 868 try:
869 869 wxversion.select(wantedwxversion)
870 870 except:
871 871 self.IP.InteractiveTB()
872 872 error('Requested wxPython version %s could not be loaded' %
873 873 wantedwxversion)
874 874
875 875 import wx
876 876
877 877 threading.Thread.__init__(self)
878 878 self.wx = wx
879 879 self.wx_mainloop = hijack_wx()
880 880
881 881 # Allows us to use both Tk and GTK.
882 882 self.tk = get_tk()
883 883
884 884 # HACK: slot for banner in self; it will be passed to the mainloop
885 885 # method only and .run() needs it. The actual value will be set by
886 886 # .mainloop().
887 887 self._banner = None
888 888
889 889 self.app = None
890 890
891 891 def wxexit(self, *args):
892 892 if self.app is not None:
893 893 self.app.agent.timer.Stop()
894 894 self.app.ExitMainLoop()
895 895
896 896 def mainloop(self,sys_exit=0,banner=None):
897 897
898 898 self._banner = banner
899 899
900 900 self.start()
901 901
902 902 class TimerAgent(self.wx.MiniFrame):
903 903 wx = self.wx
904 904 IP = self.IP
905 905 tk = self.tk
906 906 def __init__(self, parent, interval):
907 907 style = self.wx.DEFAULT_FRAME_STYLE | self.wx.TINY_CAPTION_HORIZ
908 908 self.wx.MiniFrame.__init__(self, parent, -1, ' ', pos=(200, 200),
909 909 size=(100, 100),style=style)
910 910 self.Show(False)
911 911 self.interval = interval
912 912 self.timerId = self.wx.NewId()
913 913
914 914 def StartWork(self):
915 915 self.timer = self.wx.Timer(self, self.timerId)
916 916 self.wx.EVT_TIMER(self, self.timerId, self.OnTimer)
917 917 self.timer.Start(self.interval)
918 918
919 919 def OnTimer(self, event):
920 920 update_tk(self.tk)
921 921 self.IP.runcode()
922 922
923 923 class App(self.wx.App):
924 924 wx = self.wx
925 925 TIMEOUT = self.TIMEOUT
926 926 def OnInit(self):
927 927 'Create the main window and insert the custom frame'
928 928 self.agent = TimerAgent(None, self.TIMEOUT)
929 929 self.agent.Show(False)
930 930 self.agent.StartWork()
931 931 return True
932 932
933 933 self.app = App(redirect=False)
934 934 self.wx_mainloop(self.app)
935 935 self.join()
936 936
937 937
938 938 class IPShellQt(IPThread):
939 939 """Run a Qt event loop in a separate thread.
940 940
941 941 Python commands can be passed to the thread where they will be executed.
942 942 This is implemented by periodically checking for passed code using a
943 943 Qt timer / slot."""
944 944
945 945 TIMEOUT = 100 # Millisecond interval between timeouts.
946 946
947 947 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
948 948 debug=0, shell_class=MTInteractiveShell):
949 949
950 950 import qt
951 951
952 952 self.exec_loop = hijack_qt()
953 953
954 954 # Allows us to use both Tk and QT.
955 955 self.tk = get_tk()
956 956
957 957 self.IP = make_IPython(argv,
958 958 user_ns=user_ns,
959 959 user_global_ns=user_global_ns,
960 960 debug=debug,
961 961 shell_class=shell_class,
962 962 on_kill=[qt.qApp.exit])
963 963
964 964 # HACK: slot for banner in self; it will be passed to the mainloop
965 965 # method only and .run() needs it. The actual value will be set by
966 966 # .mainloop().
967 967 self._banner = None
968 968
969 969 threading.Thread.__init__(self)
970 970
971 971 def mainloop(self, sys_exit=0, banner=None):
972 972
973 973 import qt
974 974
975 975 self._banner = banner
976 976
977 977 if qt.QApplication.startingUp():
978 978 a = qt.QApplication(sys.argv)
979 979
980 980 self.timer = qt.QTimer()
981 981 qt.QObject.connect(self.timer,
982 982 qt.SIGNAL('timeout()'),
983 983 self.on_timer)
984 984
985 985 self.start()
986 986 self.timer.start(self.TIMEOUT, True)
987 987 while True:
988 988 if self.IP._kill: break
989 989 self.exec_loop()
990 990 self.join()
991 991
992 992 def on_timer(self):
993 993 update_tk(self.tk)
994 994 result = self.IP.runcode()
995 995 self.timer.start(self.TIMEOUT, True)
996 996 return result
997 997
998 998
999 999 class IPShellQt4(IPThread):
1000 1000 """Run a Qt event loop in a separate thread.
1001 1001
1002 1002 Python commands can be passed to the thread where they will be executed.
1003 1003 This is implemented by periodically checking for passed code using a
1004 1004 Qt timer / slot."""
1005 1005
1006 1006 TIMEOUT = 100 # Millisecond interval between timeouts.
1007 1007
1008 1008 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
1009 1009 debug=0, shell_class=MTInteractiveShell):
1010 1010
1011 1011 from PyQt4 import QtCore, QtGui
1012 1012
1013 1013 try:
1014 1014 # present in PyQt4-4.2.1 or later
1015 1015 QtCore.pyqtRemoveInputHook()
1016 1016 except AttributeError:
1017 1017 pass
1018 1018
1019 1019 if QtCore.PYQT_VERSION_STR == '4.3':
1020 1020 warn('''PyQt4 version 4.3 detected.
1021 1021 If you experience repeated threading warnings, please update PyQt4.
1022 1022 ''')
1023 1023
1024 1024 self.exec_ = hijack_qt4()
1025 1025
1026 1026 # Allows us to use both Tk and QT.
1027 1027 self.tk = get_tk()
1028 1028
1029 1029 self.IP = make_IPython(argv,
1030 1030 user_ns=user_ns,
1031 1031 user_global_ns=user_global_ns,
1032 1032 debug=debug,
1033 1033 shell_class=shell_class,
1034 1034 on_kill=[QtGui.qApp.exit])
1035 1035
1036 1036 # HACK: slot for banner in self; it will be passed to the mainloop
1037 1037 # method only and .run() needs it. The actual value will be set by
1038 1038 # .mainloop().
1039 1039 self._banner = None
1040 1040
1041 1041 threading.Thread.__init__(self)
1042 1042
1043 1043 def mainloop(self, sys_exit=0, banner=None):
1044 1044
1045 1045 from PyQt4 import QtCore, QtGui
1046 1046
1047 1047 self._banner = banner
1048 1048
1049 1049 if QtGui.QApplication.startingUp():
1050 1050 a = QtGui.QApplication(sys.argv)
1051 1051
1052 1052 self.timer = QtCore.QTimer()
1053 1053 QtCore.QObject.connect(self.timer,
1054 1054 QtCore.SIGNAL('timeout()'),
1055 1055 self.on_timer)
1056 1056
1057 1057 self.start()
1058 1058 self.timer.start(self.TIMEOUT)
1059 1059 while True:
1060 1060 if self.IP._kill: break
1061 1061 self.exec_()
1062 1062 self.join()
1063 1063
1064 1064 def on_timer(self):
1065 1065 update_tk(self.tk)
1066 1066 result = self.IP.runcode()
1067 1067 self.timer.start(self.TIMEOUT)
1068 1068 return result
1069 1069
1070 1070
1071 1071 # A set of matplotlib public IPython shell classes, for single-threaded (Tk*
1072 1072 # and FLTK*) and multithreaded (GTK*, WX* and Qt*) backends to use.
1073 1073 def _load_pylab(user_ns):
1074 1074 """Allow users to disable pulling all of pylab into the top-level
1075 1075 namespace.
1076 1076
1077 1077 This little utility must be called AFTER the actual ipython instance is
1078 1078 running, since only then will the options file have been fully parsed."""
1079 1079
1080 1080 ip = IPython.ipapi.get()
1081 1081 if ip.options.pylab_import_all:
1082 1082 ip.ex("from matplotlib.pylab import *")
1083 1083 ip.IP.user_config_ns.update(ip.user_ns)
1084 1084
1085 1085
1086 1086 class IPShellMatplotlib(IPShell):
1087 1087 """Subclass IPShell with MatplotlibShell as the internal shell.
1088 1088
1089 1089 Single-threaded class, meant for the Tk* and FLTK* backends.
1090 1090
1091 1091 Having this on a separate class simplifies the external driver code."""
1092 1092
1093 1093 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1094 1094 IPShell.__init__(self,argv,user_ns,user_global_ns,debug,
1095 1095 shell_class=MatplotlibShell)
1096 1096 _load_pylab(self.IP.user_ns)
1097 1097
1098 1098 class IPShellMatplotlibGTK(IPShellGTK):
1099 1099 """Subclass IPShellGTK with MatplotlibMTShell as the internal shell.
1100 1100
1101 1101 Multi-threaded class, meant for the GTK* backends."""
1102 1102
1103 1103 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1104 1104 IPShellGTK.__init__(self,argv,user_ns,user_global_ns,debug,
1105 1105 shell_class=MatplotlibMTShell)
1106 1106 _load_pylab(self.IP.user_ns)
1107 1107
1108 1108 class IPShellMatplotlibWX(IPShellWX):
1109 1109 """Subclass IPShellWX with MatplotlibMTShell as the internal shell.
1110 1110
1111 1111 Multi-threaded class, meant for the WX* backends."""
1112 1112
1113 1113 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1114 1114 IPShellWX.__init__(self,argv,user_ns,user_global_ns,debug,
1115 1115 shell_class=MatplotlibMTShell)
1116 1116 _load_pylab(self.IP.user_ns)
1117 1117
1118 1118 class IPShellMatplotlibQt(IPShellQt):
1119 1119 """Subclass IPShellQt with MatplotlibMTShell as the internal shell.
1120 1120
1121 1121 Multi-threaded class, meant for the Qt* backends."""
1122 1122
1123 1123 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1124 1124 IPShellQt.__init__(self,argv,user_ns,user_global_ns,debug,
1125 1125 shell_class=MatplotlibMTShell)
1126 1126 _load_pylab(self.IP.user_ns)
1127 1127
1128 1128 class IPShellMatplotlibQt4(IPShellQt4):
1129 1129 """Subclass IPShellQt4 with MatplotlibMTShell as the internal shell.
1130 1130
1131 1131 Multi-threaded class, meant for the Qt4* backends."""
1132 1132
1133 1133 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1134 1134 IPShellQt4.__init__(self,argv,user_ns,user_global_ns,debug,
1135 1135 shell_class=MatplotlibMTShell)
1136 1136 _load_pylab(self.IP.user_ns)
1137 1137
1138 1138 #-----------------------------------------------------------------------------
1139 1139 # Factory functions to actually start the proper thread-aware shell
1140 1140
1141 1141 def _select_shell(argv):
1142 1142 """Select a shell from the given argv vector.
1143 1143
1144 1144 This function implements the threading selection policy, allowing runtime
1145 1145 control of the threading mode, both for general users and for matplotlib.
1146 1146
1147 1147 Return:
1148 1148 Shell class to be instantiated for runtime operation.
1149 1149 """
1150 1150
1151 1151 global USE_TK
1152 1152
1153 1153 mpl_shell = {'gthread' : IPShellMatplotlibGTK,
1154 1154 'wthread' : IPShellMatplotlibWX,
1155 1155 'qthread' : IPShellMatplotlibQt,
1156 1156 'q4thread' : IPShellMatplotlibQt4,
1157 1157 'tkthread' : IPShellMatplotlib, # Tk is built-in
1158 1158 }
1159 1159
1160 1160 th_shell = {'gthread' : IPShellGTK,
1161 1161 'wthread' : IPShellWX,
1162 1162 'qthread' : IPShellQt,
1163 1163 'q4thread' : IPShellQt4,
1164 1164 'tkthread' : IPShell, # Tk is built-in
1165 1165 }
1166 1166
1167 1167 backends = {'gthread' : 'GTKAgg',
1168 1168 'wthread' : 'WXAgg',
1169 1169 'qthread' : 'QtAgg',
1170 1170 'q4thread' :'Qt4Agg',
1171 1171 'tkthread' :'TkAgg',
1172 1172 }
1173 1173
1174 1174 all_opts = set(['tk','pylab','gthread','qthread','q4thread','wthread',
1175 1175 'tkthread'])
1176 1176 user_opts = set([s.replace('-','') for s in argv[:3]])
1177 1177 special_opts = user_opts & all_opts
1178 1178
1179 1179 if 'tk' in special_opts:
1180 1180 USE_TK = True
1181 1181 special_opts.remove('tk')
1182 1182
1183 1183 if 'pylab' in special_opts:
1184 1184
1185 1185 try:
1186 1186 import matplotlib
1187 1187 except ImportError:
1188 1188 error('matplotlib could NOT be imported! Starting normal IPython.')
1189 1189 return IPShell
1190 1190
1191 1191 special_opts.remove('pylab')
1192 1192 # If there's any option left, it means the user wants to force the
1193 1193 # threading backend, else it's auto-selected from the rc file
1194 1194 if special_opts:
1195 1195 th_mode = special_opts.pop()
1196 1196 matplotlib.rcParams['backend'] = backends[th_mode]
1197 1197 else:
1198 1198 backend = matplotlib.rcParams['backend']
1199 1199 if backend.startswith('GTK'):
1200 1200 th_mode = 'gthread'
1201 1201 elif backend.startswith('WX'):
1202 1202 th_mode = 'wthread'
1203 1203 elif backend.startswith('Qt4'):
1204 1204 th_mode = 'q4thread'
1205 1205 elif backend.startswith('Qt'):
1206 1206 th_mode = 'qthread'
1207 1207 else:
1208 1208 # Any other backend, use plain Tk
1209 1209 th_mode = 'tkthread'
1210 1210
1211 1211 return mpl_shell[th_mode]
1212 1212 else:
1213 1213 # No pylab requested, just plain threads
1214 1214 try:
1215 1215 th_mode = special_opts.pop()
1216 1216 except KeyError:
1217 1217 th_mode = 'tkthread'
1218 1218 return th_shell[th_mode]
1219 1219
1220 1220
1221 1221 # This is the one which should be called by external code.
1222 1222 def start(user_ns = None):
1223 1223 """Return a running shell instance, dealing with threading options.
1224 1224
1225 1225 This is a factory function which will instantiate the proper IPython shell
1226 1226 based on the user's threading choice. Such a selector is needed because
1227 1227 different GUI toolkits require different thread handling details."""
1228 1228
1229 1229 shell = _select_shell(sys.argv)
1230 1230 return shell(user_ns = user_ns)
1231 1231
1232 1232 # Some aliases for backwards compatibility
1233 1233 IPythonShell = IPShell
1234 1234 IPythonShellEmbed = IPShellEmbed
1235 1235 #************************ End of file <Shell.py> ***************************
@@ -1,71 +1,72 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 IPython -- An enhanced Interactive Python
4 4
5 5 One of Python's nicest features is its interactive interpreter. This allows
6 6 very fast testing of ideas without the overhead of creating test files as is
7 7 typical in most programming languages. However, the interpreter supplied with
8 8 the standard Python distribution is fairly primitive (and IDLE isn't really
9 9 much better).
10 10
11 11 IPython tries to:
12 12
13 13 i - provide an efficient environment for interactive work in Python
14 14 programming. It tries to address what we see as shortcomings of the standard
15 15 Python prompt, and adds many features to make interactive work much more
16 16 efficient.
17 17
18 18 ii - offer a flexible framework so that it can be used as the base
19 19 environment for other projects and problems where Python can be the
20 20 underlying language. Specifically scientific environments like Mathematica,
21 21 IDL and Mathcad inspired its design, but similar ideas can be useful in many
22 22 fields. Python is a fabulous language for implementing this kind of system
23 23 (due to its dynamic and introspective features), and with suitable libraries
24 24 entire systems could be built leveraging Python's power.
25 25
26 26 iii - serve as an embeddable, ready to go interpreter for your own programs.
27 27
28 28 IPython requires Python 2.3 or newer.
29 29
30 30 $Id: __init__.py 2399 2007-05-26 10:23:10Z vivainio $"""
31 31
32 32 #*****************************************************************************
33 33 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
34 34 #
35 35 # Distributed under the terms of the BSD License. The full license is in
36 36 # the file COPYING, distributed as part of this software.
37 37 #*****************************************************************************
38 38
39 39 # Enforce proper version requirements
40 40 import sys
41 41
42 if sys.version[0:3] < '2.3':
43 raise ImportError('Python Version 2.3 or above is required for IPython.')
42 if sys.version[0:3] < '2.4':
43 raise ImportError('Python Version 2.4 or above is required for IPython.')
44 44
45 45 # Make it easy to import extensions - they are always directly on pythonpath.
46 46 # Therefore, non-IPython modules can be added to Extensions directory
47 47 import os
48 48 sys.path.append(os.path.dirname(__file__) + "/Extensions")
49 49
50 50 # Define what gets imported with a 'from IPython import *'
51 51 __all__ = ['ipapi','generics','ipstruct','Release','Shell']
52 52
53 53 # Load __all__ in IPython namespace so that a simple 'import IPython' gives
54 54 # access to them via IPython.<name>
55 55 glob,loc = globals(),locals()
56 56 for name in __all__:
57 #print 'Importing: ',name # dbg
57 58 __import__(name,glob,loc,[])
58 59
59 60 import Shell
60 61
61 62 # Release data
62 63 from IPython import Release # do it explicitly so pydoc can see it - pydoc bug
63 64 __author__ = '%s <%s>\n%s <%s>\n%s <%s>' % \
64 65 ( Release.authors['Fernando'] + Release.authors['Janko'] + \
65 66 Release.authors['Nathan'] )
66 67 __license__ = Release.license
67 68 __version__ = Release.version
68 69 __revision__ = Release.revision
69 70
70 71 # Namespace cleanup
71 72 del name,glob,loc
@@ -1,644 +1,637 b''
1 1 """Word completion for IPython.
2 2
3 3 This module is a fork of the rlcompleter module in the Python standard
4 4 library. The original enhancements made to rlcompleter have been sent
5 5 upstream and were accepted as of Python 2.3, but we need a lot more
6 6 functionality specific to IPython, so this module will continue to live as an
7 7 IPython-specific utility.
8 8
9 9 ---------------------------------------------------------------------------
10 10 Original rlcompleter documentation:
11 11
12 12 This requires the latest extension to the readline module (the
13 13 completes keywords, built-ins and globals in __main__; when completing
14 14 NAME.NAME..., it evaluates (!) the expression up to the last dot and
15 15 completes its attributes.
16 16
17 17 It's very cool to do "import string" type "string.", hit the
18 18 completion key (twice), and see the list of names defined by the
19 19 string module!
20 20
21 21 Tip: to use the tab key as the completion key, call
22 22
23 23 readline.parse_and_bind("tab: complete")
24 24
25 25 Notes:
26 26
27 27 - Exceptions raised by the completer function are *ignored* (and
28 28 generally cause the completion to fail). This is a feature -- since
29 29 readline sets the tty device in raw (or cbreak) mode, printing a
30 30 traceback wouldn't work well without some complicated hoopla to save,
31 31 reset and restore the tty state.
32 32
33 33 - The evaluation of the NAME.NAME... form may cause arbitrary
34 34 application defined code to be executed if an object with a
35 35 __getattr__ hook is found. Since it is the responsibility of the
36 36 application (or the user) to enable this feature, I consider this an
37 37 acceptable risk. More complicated expressions (e.g. function calls or
38 38 indexing operations) are *not* evaluated.
39 39
40 40 - GNU readline is also used by the built-in functions input() and
41 41 raw_input(), and thus these also benefit/suffer from the completer
42 42 features. Clearly an interactive application can benefit by
43 43 specifying its own completer function and using raw_input() for all
44 44 its input.
45 45
46 46 - When the original stdin is not a tty device, GNU readline is never
47 47 used, and this module (and the readline module) are silently inactive.
48 48
49 49 """
50 50
51 51 #*****************************************************************************
52 52 #
53 53 # Since this file is essentially a minimally modified copy of the rlcompleter
54 54 # module which is part of the standard Python distribution, I assume that the
55 55 # proper procedure is to maintain its copyright as belonging to the Python
56 56 # Software Foundation (in addition to my own, for all new code).
57 57 #
58 58 # Copyright (C) 2001 Python Software Foundation, www.python.org
59 59 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
60 60 #
61 61 # Distributed under the terms of the BSD License. The full license is in
62 62 # the file COPYING, distributed as part of this software.
63 63 #
64 64 #*****************************************************************************
65 65
66 66 import __builtin__
67 67 import __main__
68 68 import glob
69 69 import keyword
70 70 import os
71 71 import re
72 72 import shlex
73 73 import sys
74 74 import IPython.rlineimpl as readline
75 75 import itertools
76 76 from IPython.ipstruct import Struct
77 77 from IPython import ipapi
78 78 from IPython import generics
79 79 import types
80 80
81 81 # Python 2.4 offers sets as a builtin
82 82 try:
83 83 set()
84 84 except NameError:
85 85 from sets import Set as set
86 86
87 87 from IPython.genutils import debugx, dir2
88 88
89 89 __all__ = ['Completer','IPCompleter']
90 90
91 91 class Completer:
92 92 def __init__(self,namespace=None,global_namespace=None):
93 93 """Create a new completer for the command line.
94 94
95 95 Completer([namespace,global_namespace]) -> completer instance.
96 96
97 97 If unspecified, the default namespace where completions are performed
98 98 is __main__ (technically, __main__.__dict__). Namespaces should be
99 99 given as dictionaries.
100 100
101 101 An optional second namespace can be given. This allows the completer
102 102 to handle cases where both the local and global scopes need to be
103 103 distinguished.
104 104
105 105 Completer instances should be used as the completion mechanism of
106 106 readline via the set_completer() call:
107 107
108 108 readline.set_completer(Completer(my_namespace).complete)
109 109 """
110 110
111 # some minimal strict typechecks. For some core data structures, I
112 # want actual basic python types, not just anything that looks like
113 # one. This is especially true for namespaces.
114 for ns in (namespace,global_namespace):
115 if ns is not None and type(ns) != types.DictType:
116 raise TypeError,'namespace must be a dictionary'
117
118 111 # Don't bind to namespace quite yet, but flag whether the user wants a
119 112 # specific namespace or to use __main__.__dict__. This will allow us
120 113 # to bind to __main__.__dict__ at completion time, not now.
121 114 if namespace is None:
122 115 self.use_main_ns = 1
123 116 else:
124 117 self.use_main_ns = 0
125 118 self.namespace = namespace
126 119
127 120 # The global namespace, if given, can be bound directly
128 121 if global_namespace is None:
129 122 self.global_namespace = {}
130 123 else:
131 124 self.global_namespace = global_namespace
132 125
133 126 def complete(self, text, state):
134 127 """Return the next possible completion for 'text'.
135 128
136 129 This is called successively with state == 0, 1, 2, ... until it
137 130 returns None. The completion should begin with 'text'.
138 131
139 132 """
140 133 if self.use_main_ns:
141 134 self.namespace = __main__.__dict__
142 135
143 136 if state == 0:
144 137 if "." in text:
145 138 self.matches = self.attr_matches(text)
146 139 else:
147 140 self.matches = self.global_matches(text)
148 141 try:
149 142 return self.matches[state]
150 143 except IndexError:
151 144 return None
152 145
153 146 def global_matches(self, text):
154 147 """Compute matches when text is a simple name.
155 148
156 149 Return a list of all keywords, built-in functions and names currently
157 150 defined in self.namespace or self.global_namespace that match.
158 151
159 152 """
160 153 matches = []
161 154 match_append = matches.append
162 155 n = len(text)
163 156 for lst in [keyword.kwlist,
164 157 __builtin__.__dict__.keys(),
165 158 self.namespace.keys(),
166 159 self.global_namespace.keys()]:
167 160 for word in lst:
168 161 if word[:n] == text and word != "__builtins__":
169 162 match_append(word)
170 163 return matches
171 164
172 165 def attr_matches(self, text):
173 166 """Compute matches when text contains a dot.
174 167
175 168 Assuming the text is of the form NAME.NAME....[NAME], and is
176 169 evaluatable in self.namespace or self.global_namespace, it will be
177 170 evaluated and its attributes (as revealed by dir()) are used as
178 171 possible completions. (For class instances, class members are are
179 172 also considered.)
180 173
181 174 WARNING: this can still invoke arbitrary C code, if an object
182 175 with a __getattr__ hook is evaluated.
183 176
184 177 """
185 178 import re
186 179
187 180 # Another option, seems to work great. Catches things like ''.<tab>
188 181 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
189 182
190 183 if not m:
191 184 return []
192 185
193 186 expr, attr = m.group(1, 3)
194 187 try:
195 188 obj = eval(expr, self.namespace)
196 189 except:
197 190 try:
198 191 obj = eval(expr, self.global_namespace)
199 192 except:
200 193 return []
201 194
202 195 words = dir2(obj)
203 196
204 197 try:
205 198 words = generics.complete_object(obj, words)
206 199 except ipapi.TryNext:
207 200 pass
208 201 # Build match list to return
209 202 n = len(attr)
210 203 res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
211 204 return res
212 205
213 206 class IPCompleter(Completer):
214 207 """Extension of the completer class with IPython-specific features"""
215 208
216 209 def __init__(self,shell,namespace=None,global_namespace=None,
217 210 omit__names=0,alias_table=None):
218 211 """IPCompleter() -> completer
219 212
220 213 Return a completer object suitable for use by the readline library
221 214 via readline.set_completer().
222 215
223 216 Inputs:
224 217
225 218 - shell: a pointer to the ipython shell itself. This is needed
226 219 because this completer knows about magic functions, and those can
227 220 only be accessed via the ipython instance.
228 221
229 222 - namespace: an optional dict where completions are performed.
230 223
231 224 - global_namespace: secondary optional dict for completions, to
232 225 handle cases (such as IPython embedded inside functions) where
233 226 both Python scopes are visible.
234 227
235 228 - The optional omit__names parameter sets the completer to omit the
236 229 'magic' names (__magicname__) for python objects unless the text
237 230 to be completed explicitly starts with one or more underscores.
238 231
239 232 - If alias_table is supplied, it should be a dictionary of aliases
240 233 to complete. """
241 234
242 235 Completer.__init__(self,namespace,global_namespace)
243 236 self.magic_prefix = shell.name+'.magic_'
244 237 self.magic_escape = shell.ESC_MAGIC
245 238 self.readline = readline
246 239 delims = self.readline.get_completer_delims()
247 240 delims = delims.replace(self.magic_escape,'')
248 241 self.readline.set_completer_delims(delims)
249 242 self.get_line_buffer = self.readline.get_line_buffer
250 243 self.get_endidx = self.readline.get_endidx
251 244 self.omit__names = omit__names
252 245 self.merge_completions = shell.rc.readline_merge_completions
253 246 if alias_table is None:
254 247 alias_table = {}
255 248 self.alias_table = alias_table
256 249 # Regexp to split filenames with spaces in them
257 250 self.space_name_re = re.compile(r'([^\\] )')
258 251 # Hold a local ref. to glob.glob for speed
259 252 self.glob = glob.glob
260 253
261 254 # Determine if we are running on 'dumb' terminals, like (X)Emacs
262 255 # buffers, to avoid completion problems.
263 256 term = os.environ.get('TERM','xterm')
264 257 self.dumb_terminal = term in ['dumb','emacs']
265 258
266 259 # Special handling of backslashes needed in win32 platforms
267 260 if sys.platform == "win32":
268 261 self.clean_glob = self._clean_glob_win32
269 262 else:
270 263 self.clean_glob = self._clean_glob
271 264 self.matchers = [self.python_matches,
272 265 self.file_matches,
273 266 self.alias_matches,
274 267 self.python_func_kw_matches]
275 268
276 269
277 270 # Code contributed by Alex Schmolck, for ipython/emacs integration
278 271 def all_completions(self, text):
279 272 """Return all possible completions for the benefit of emacs."""
280 273
281 274 completions = []
282 275 comp_append = completions.append
283 276 try:
284 277 for i in xrange(sys.maxint):
285 278 res = self.complete(text, i)
286 279
287 280 if not res: break
288 281
289 282 comp_append(res)
290 283 #XXX workaround for ``notDefined.<tab>``
291 284 except NameError:
292 285 pass
293 286 return completions
294 287 # /end Alex Schmolck code.
295 288
296 289 def _clean_glob(self,text):
297 290 return self.glob("%s*" % text)
298 291
299 292 def _clean_glob_win32(self,text):
300 293 return [f.replace("\\","/")
301 294 for f in self.glob("%s*" % text)]
302 295
303 296 def file_matches(self, text):
304 297 """Match filenames, expanding ~USER type strings.
305 298
306 299 Most of the seemingly convoluted logic in this completer is an
307 300 attempt to handle filenames with spaces in them. And yet it's not
308 301 quite perfect, because Python's readline doesn't expose all of the
309 302 GNU readline details needed for this to be done correctly.
310 303
311 304 For a filename with a space in it, the printed completions will be
312 305 only the parts after what's already been typed (instead of the
313 306 full completions, as is normally done). I don't think with the
314 307 current (as of Python 2.3) Python readline it's possible to do
315 308 better."""
316 309
317 310 #print 'Completer->file_matches: <%s>' % text # dbg
318 311
319 312 # chars that require escaping with backslash - i.e. chars
320 313 # that readline treats incorrectly as delimiters, but we
321 314 # don't want to treat as delimiters in filename matching
322 315 # when escaped with backslash
323 316
324 317 protectables = ' '
325 318
326 319 if text.startswith('!'):
327 320 text = text[1:]
328 321 text_prefix = '!'
329 322 else:
330 323 text_prefix = ''
331 324
332 325 def protect_filename(s):
333 326 return "".join([(ch in protectables and '\\' + ch or ch)
334 327 for ch in s])
335 328
336 329 def single_dir_expand(matches):
337 330 "Recursively expand match lists containing a single dir."
338 331
339 332 if len(matches) == 1 and os.path.isdir(matches[0]):
340 333 # Takes care of links to directories also. Use '/'
341 334 # explicitly, even under Windows, so that name completions
342 335 # don't end up escaped.
343 336 d = matches[0]
344 337 if d[-1] in ['/','\\']:
345 338 d = d[:-1]
346 339
347 340 subdirs = os.listdir(d)
348 341 if subdirs:
349 342 matches = [ (d + '/' + p) for p in subdirs]
350 343 return single_dir_expand(matches)
351 344 else:
352 345 return matches
353 346 else:
354 347 return matches
355 348
356 349 lbuf = self.lbuf
357 350 open_quotes = 0 # track strings with open quotes
358 351 try:
359 352 lsplit = shlex.split(lbuf)[-1]
360 353 except ValueError:
361 354 # typically an unmatched ", or backslash without escaped char.
362 355 if lbuf.count('"')==1:
363 356 open_quotes = 1
364 357 lsplit = lbuf.split('"')[-1]
365 358 elif lbuf.count("'")==1:
366 359 open_quotes = 1
367 360 lsplit = lbuf.split("'")[-1]
368 361 else:
369 362 return []
370 363 except IndexError:
371 364 # tab pressed on empty line
372 365 lsplit = ""
373 366
374 367 if lsplit != protect_filename(lsplit):
375 368 # if protectables are found, do matching on the whole escaped
376 369 # name
377 370 has_protectables = 1
378 371 text0,text = text,lsplit
379 372 else:
380 373 has_protectables = 0
381 374 text = os.path.expanduser(text)
382 375
383 376 if text == "":
384 377 return [text_prefix + protect_filename(f) for f in self.glob("*")]
385 378
386 379 m0 = self.clean_glob(text.replace('\\',''))
387 380 if has_protectables:
388 381 # If we had protectables, we need to revert our changes to the
389 382 # beginning of filename so that we don't double-write the part
390 383 # of the filename we have so far
391 384 len_lsplit = len(lsplit)
392 385 matches = [text_prefix + text0 +
393 386 protect_filename(f[len_lsplit:]) for f in m0]
394 387 else:
395 388 if open_quotes:
396 389 # if we have a string with an open quote, we don't need to
397 390 # protect the names at all (and we _shouldn't_, as it
398 391 # would cause bugs when the filesystem call is made).
399 392 matches = m0
400 393 else:
401 394 matches = [text_prefix +
402 395 protect_filename(f) for f in m0]
403 396
404 397 #print 'mm',matches # dbg
405 398 return single_dir_expand(matches)
406 399
407 400 def alias_matches(self, text):
408 401 """Match internal system aliases"""
409 402 #print 'Completer->alias_matches:',text,'lb',self.lbuf # dbg
410 403
411 404 # if we are not in the first 'item', alias matching
412 405 # doesn't make sense - unless we are starting with 'sudo' command.
413 406 if ' ' in self.lbuf.lstrip() and not self.lbuf.lstrip().startswith('sudo'):
414 407 return []
415 408 text = os.path.expanduser(text)
416 409 aliases = self.alias_table.keys()
417 410 if text == "":
418 411 return aliases
419 412 else:
420 413 return [alias for alias in aliases if alias.startswith(text)]
421 414
422 415 def python_matches(self,text):
423 416 """Match attributes or global python names"""
424 417
425 418 #print 'Completer->python_matches, txt=<%s>' % text # dbg
426 419 if "." in text:
427 420 try:
428 421 matches = self.attr_matches(text)
429 422 if text.endswith('.') and self.omit__names:
430 423 if self.omit__names == 1:
431 424 # true if txt is _not_ a __ name, false otherwise:
432 425 no__name = (lambda txt:
433 426 re.match(r'.*\.__.*?__',txt) is None)
434 427 else:
435 428 # true if txt is _not_ a _ name, false otherwise:
436 429 no__name = (lambda txt:
437 430 re.match(r'.*\._.*?',txt) is None)
438 431 matches = filter(no__name, matches)
439 432 except NameError:
440 433 # catches <undefined attributes>.<tab>
441 434 matches = []
442 435 else:
443 436 matches = self.global_matches(text)
444 437 # this is so completion finds magics when automagic is on:
445 438 if (matches == [] and
446 439 not text.startswith(os.sep) and
447 440 not ' ' in self.lbuf):
448 441 matches = self.attr_matches(self.magic_prefix+text)
449 442 return matches
450 443
451 444 def _default_arguments(self, obj):
452 445 """Return the list of default arguments of obj if it is callable,
453 446 or empty list otherwise."""
454 447
455 448 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
456 449 # for classes, check for __init__,__new__
457 450 if inspect.isclass(obj):
458 451 obj = (getattr(obj,'__init__',None) or
459 452 getattr(obj,'__new__',None))
460 453 # for all others, check if they are __call__able
461 454 elif hasattr(obj, '__call__'):
462 455 obj = obj.__call__
463 456 # XXX: is there a way to handle the builtins ?
464 457 try:
465 458 args,_,_1,defaults = inspect.getargspec(obj)
466 459 if defaults:
467 460 return args[-len(defaults):]
468 461 except TypeError: pass
469 462 return []
470 463
471 464 def python_func_kw_matches(self,text):
472 465 """Match named parameters (kwargs) of the last open function"""
473 466
474 467 if "." in text: # a parameter cannot be dotted
475 468 return []
476 469 try: regexp = self.__funcParamsRegex
477 470 except AttributeError:
478 471 regexp = self.__funcParamsRegex = re.compile(r'''
479 472 '.*?' | # single quoted strings or
480 473 ".*?" | # double quoted strings or
481 474 \w+ | # identifier
482 475 \S # other characters
483 476 ''', re.VERBOSE | re.DOTALL)
484 477 # 1. find the nearest identifier that comes before an unclosed
485 478 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
486 479 tokens = regexp.findall(self.get_line_buffer())
487 480 tokens.reverse()
488 481 iterTokens = iter(tokens); openPar = 0
489 482 for token in iterTokens:
490 483 if token == ')':
491 484 openPar -= 1
492 485 elif token == '(':
493 486 openPar += 1
494 487 if openPar > 0:
495 488 # found the last unclosed parenthesis
496 489 break
497 490 else:
498 491 return []
499 492 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
500 493 ids = []
501 494 isId = re.compile(r'\w+$').match
502 495 while True:
503 496 try:
504 497 ids.append(iterTokens.next())
505 498 if not isId(ids[-1]):
506 499 ids.pop(); break
507 500 if not iterTokens.next() == '.':
508 501 break
509 502 except StopIteration:
510 503 break
511 504 # lookup the candidate callable matches either using global_matches
512 505 # or attr_matches for dotted names
513 506 if len(ids) == 1:
514 507 callableMatches = self.global_matches(ids[0])
515 508 else:
516 509 callableMatches = self.attr_matches('.'.join(ids[::-1]))
517 510 argMatches = []
518 511 for callableMatch in callableMatches:
519 512 try: namedArgs = self._default_arguments(eval(callableMatch,
520 513 self.namespace))
521 514 except: continue
522 515 for namedArg in namedArgs:
523 516 if namedArg.startswith(text):
524 517 argMatches.append("%s=" %namedArg)
525 518 return argMatches
526 519
527 520 def dispatch_custom_completer(self,text):
528 521 #print "Custom! '%s' %s" % (text, self.custom_completers) # dbg
529 522 line = self.full_lbuf
530 523 if not line.strip():
531 524 return None
532 525
533 526 event = Struct()
534 527 event.line = line
535 528 event.symbol = text
536 529 cmd = line.split(None,1)[0]
537 530 event.command = cmd
538 531 #print "\ncustom:{%s]\n" % event # dbg
539 532
540 533 # for foo etc, try also to find completer for %foo
541 534 if not cmd.startswith(self.magic_escape):
542 535 try_magic = self.custom_completers.s_matches(
543 536 self.magic_escape + cmd)
544 537 else:
545 538 try_magic = []
546 539
547 540
548 541 for c in itertools.chain(
549 542 self.custom_completers.s_matches(cmd),
550 543 try_magic,
551 544 self.custom_completers.flat_matches(self.lbuf)):
552 545 #print "try",c # dbg
553 546 try:
554 547 res = c(event)
555 548 # first, try case sensitive match
556 549 withcase = [r for r in res if r.startswith(text)]
557 550 if withcase:
558 551 return withcase
559 552 # if none, then case insensitive ones are ok too
560 553 return [r for r in res if r.lower().startswith(text.lower())]
561 554 except ipapi.TryNext:
562 555 pass
563 556
564 557 return None
565 558
566 559 def complete(self, text, state,line_buffer=None):
567 560 """Return the next possible completion for 'text'.
568 561
569 562 This is called successively with state == 0, 1, 2, ... until it
570 563 returns None. The completion should begin with 'text'.
571 564
572 565 :Keywords:
573 566 - line_buffer: string
574 567 If not given, the completer attempts to obtain the current line buffer
575 568 via readline. This keyword allows clients which are requesting for
576 569 text completions in non-readline contexts to inform the completer of
577 570 the entire text.
578 571 """
579 572
580 573 #print '\n*** COMPLETE: <%s> (%s)' % (text,state) # dbg
581 574
582 575 # if there is only a tab on a line with only whitespace, instead
583 576 # of the mostly useless 'do you want to see all million
584 577 # completions' message, just do the right thing and give the user
585 578 # his tab! Incidentally, this enables pasting of tabbed text from
586 579 # an editor (as long as autoindent is off).
587 580
588 581 # It should be noted that at least pyreadline still shows
589 582 # file completions - is there a way around it?
590 583
591 584 # don't apply this on 'dumb' terminals, such as emacs buffers, so we
592 585 # don't interfere with their own tab-completion mechanism.
593 586 if line_buffer is None:
594 587 self.full_lbuf = self.get_line_buffer()
595 588 else:
596 589 self.full_lbuf = line_buffer
597 590
598 591 if not (self.dumb_terminal or self.full_lbuf.strip()):
599 592 self.readline.insert_text('\t')
600 593 return None
601 594
602 595 magic_escape = self.magic_escape
603 596 magic_prefix = self.magic_prefix
604 597
605 598 self.lbuf = self.full_lbuf[:self.get_endidx()]
606 599
607 600 try:
608 601 if text.startswith(magic_escape):
609 602 text = text.replace(magic_escape,magic_prefix)
610 603 elif text.startswith('~'):
611 604 text = os.path.expanduser(text)
612 605 if state == 0:
613 606 custom_res = self.dispatch_custom_completer(text)
614 607 if custom_res is not None:
615 608 # did custom completers produce something?
616 609 self.matches = custom_res
617 610 else:
618 611 # Extend the list of completions with the results of each
619 612 # matcher, so we return results to the user from all
620 613 # namespaces.
621 614 if self.merge_completions:
622 615 self.matches = []
623 616 for matcher in self.matchers:
624 617 self.matches.extend(matcher(text))
625 618 else:
626 619 for matcher in self.matchers:
627 620 self.matches = matcher(text)
628 621 if self.matches:
629 622 break
630 623 def uniq(alist):
631 624 set = {}
632 625 return [set.setdefault(e,e) for e in alist if e not in set]
633 626 self.matches = uniq(self.matches)
634 627 try:
635 628 ret = self.matches[state].replace(magic_prefix,magic_escape)
636 629 return ret
637 630 except IndexError:
638 631 return None
639 632 except:
640 633 #from IPython.ultraTB import AutoFormattedTB; # dbg
641 634 #tb=AutoFormattedTB('Verbose');tb() #dbg
642 635
643 636 # If completion fails, don't annoy the user.
644 637 return None
@@ -1,188 +1,189 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 A module to change reload() so that it acts recursively.
4 4 To enable it type:
5 5 >>> import __builtin__, deep_reload
6 6 >>> __builtin__.reload = deep_reload.reload
7
7 8 You can then disable it with:
8 9 >>> __builtin__.reload = deep_reload.original_reload
9 10
10 11 Alternatively, you can add a dreload builtin alongside normal reload with:
11 12 >>> __builtin__.dreload = deep_reload.reload
12 13
13 14 This code is almost entirely based on knee.py from the standard library.
14 15
15 16 $Id: deep_reload.py 958 2005-12-27 23:17:51Z fperez $"""
16 17
17 18 #*****************************************************************************
18 19 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
19 20 #
20 21 # Distributed under the terms of the BSD License. The full license is in
21 22 # the file COPYING, distributed as part of this software.
22 23 #*****************************************************************************
23 24
24 25 from IPython import Release # do it explicitly so pydoc can see it - pydoc bug
25 26 __author__ = '%s <%s>' % Release.authors['Nathan']
26 27 __license__ = Release.license
27 28 __version__ = "0.5"
28 29 __date__ = "21 August 2001"
29 30
30 31 import __builtin__
31 32 import imp
32 33 import sys
33 34
34 35 # Replacement for __import__()
35 36 def deep_import_hook(name, globals=None, locals=None, fromlist=None, level=-1):
36 37 # For now level is ignored, it's just there to prevent crash
37 38 # with from __future__ import absolute_import
38 39 parent = determine_parent(globals)
39 40 q, tail = find_head_package(parent, name)
40 41 m = load_tail(q, tail)
41 42 if not fromlist:
42 43 return q
43 44 if hasattr(m, "__path__"):
44 45 ensure_fromlist(m, fromlist)
45 46 return m
46 47
47 48 def determine_parent(globals):
48 49 if not globals or not globals.has_key("__name__"):
49 50 return None
50 51 pname = globals['__name__']
51 52 if globals.has_key("__path__"):
52 53 parent = sys.modules[pname]
53 54 assert globals is parent.__dict__
54 55 return parent
55 56 if '.' in pname:
56 57 i = pname.rfind('.')
57 58 pname = pname[:i]
58 59 parent = sys.modules[pname]
59 60 assert parent.__name__ == pname
60 61 return parent
61 62 return None
62 63
63 64 def find_head_package(parent, name):
64 65 # Import the first
65 66 if '.' in name:
66 67 # 'some.nested.package' -> head = 'some', tail = 'nested.package'
67 68 i = name.find('.')
68 69 head = name[:i]
69 70 tail = name[i+1:]
70 71 else:
71 72 # 'packagename' -> head = 'packagename', tail = ''
72 73 head = name
73 74 tail = ""
74 75 if parent:
75 76 # If this is a subpackage then qname = parent's name + head
76 77 qname = "%s.%s" % (parent.__name__, head)
77 78 else:
78 79 qname = head
79 80 q = import_module(head, qname, parent)
80 81 if q: return q, tail
81 82 if parent:
82 83 qname = head
83 84 parent = None
84 85 q = import_module(head, qname, parent)
85 86 if q: return q, tail
86 87 raise ImportError, "No module named " + qname
87 88
88 89 def load_tail(q, tail):
89 90 m = q
90 91 while tail:
91 92 i = tail.find('.')
92 93 if i < 0: i = len(tail)
93 94 head, tail = tail[:i], tail[i+1:]
94 95
95 96 # fperez: fix dotted.name reloading failures by changing:
96 97 #mname = "%s.%s" % (m.__name__, head)
97 98 # to:
98 99 mname = m.__name__
99 100 # This needs more testing!!! (I don't understand this module too well)
100 101
101 102 #print '** head,tail=|%s|->|%s|, mname=|%s|' % (head,tail,mname) # dbg
102 103 m = import_module(head, mname, m)
103 104 if not m:
104 105 raise ImportError, "No module named " + mname
105 106 return m
106 107
107 108 def ensure_fromlist(m, fromlist, recursive=0):
108 109 for sub in fromlist:
109 110 if sub == "*":
110 111 if not recursive:
111 112 try:
112 113 all = m.__all__
113 114 except AttributeError:
114 115 pass
115 116 else:
116 117 ensure_fromlist(m, all, 1)
117 118 continue
118 119 if sub != "*" and not hasattr(m, sub):
119 120 subname = "%s.%s" % (m.__name__, sub)
120 121 submod = import_module(sub, subname, m)
121 122 if not submod:
122 123 raise ImportError, "No module named " + subname
123 124
124 125 # Need to keep track of what we've already reloaded to prevent cyclic evil
125 126 found_now = {}
126 127
127 128 def import_module(partname, fqname, parent):
128 129 global found_now
129 130 if found_now.has_key(fqname):
130 131 try:
131 132 return sys.modules[fqname]
132 133 except KeyError:
133 134 pass
134 135
135 136 print 'Reloading', fqname #, sys.excepthook is sys.__excepthook__, \
136 137 #sys.displayhook is sys.__displayhook__
137 138
138 139 found_now[fqname] = 1
139 140 try:
140 141 fp, pathname, stuff = imp.find_module(partname,
141 142 parent and parent.__path__)
142 143 except ImportError:
143 144 return None
144 145
145 146 try:
146 147 m = imp.load_module(fqname, fp, pathname, stuff)
147 148 finally:
148 149 if fp: fp.close()
149 150
150 151 if parent:
151 152 setattr(parent, partname, m)
152 153
153 154 return m
154 155
155 156 def deep_reload_hook(module):
156 157 name = module.__name__
157 158 if '.' not in name:
158 159 return import_module(name, name, None)
159 160 i = name.rfind('.')
160 161 pname = name[:i]
161 162 parent = sys.modules[pname]
162 163 return import_module(name[i+1:], name, parent)
163 164
164 165 # Save the original hooks
165 166 original_reload = __builtin__.reload
166 167
167 168 # Replacement for reload()
168 169 def reload(module, exclude=['sys', '__builtin__', '__main__']):
169 170 """Recursively reload all modules used in the given module. Optionally
170 171 takes a list of modules to exclude from reloading. The default exclude
171 172 list contains sys, __main__, and __builtin__, to prevent, e.g., resetting
172 173 display, exception, and io hooks.
173 174 """
174 175 global found_now
175 176 for i in exclude:
176 177 found_now[i] = 1
177 178 original_import = __builtin__.__import__
178 179 __builtin__.__import__ = deep_import_hook
179 180 try:
180 181 ret = deep_reload_hook(module)
181 182 finally:
182 183 __builtin__.__import__ = original_import
183 184 found_now = {}
184 185 return ret
185 186
186 187 # Uncomment the following to automatically activate deep reloading whenever
187 188 # this module is imported
188 189 #__builtin__.reload = reload
@@ -1,505 +1,560 b''
1 1 # encoding: utf-8
2 2 # -*- test-case-name: IPython.frontend.cocoa.tests.test_cocoa_frontend -*-
3 3
4 4 """PyObjC classes to provide a Cocoa frontend to the
5 5 IPython.kernel.engineservice.IEngineBase.
6 6
7 7 To add an IPython interpreter to a cocoa app, instantiate an
8 8 IPythonCocoaController in a XIB and connect its textView outlet to an
9 9 NSTextView instance in your UI. That's it.
10 10
11 11 Author: Barry Wark
12 12 """
13 13
14 14 __docformat__ = "restructuredtext en"
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Copyright (C) 2008 The IPython Development Team
18 18 #
19 19 # Distributed under the terms of the BSD License. The full license is in
20 20 # the file COPYING, distributed as part of this software.
21 21 #-----------------------------------------------------------------------------
22 22
23 23 #-----------------------------------------------------------------------------
24 24 # Imports
25 25 #-----------------------------------------------------------------------------
26 26
27 27 import sys
28 28 import objc
29 29 import uuid
30 30
31 31 from Foundation import NSObject, NSMutableArray, NSMutableDictionary,\
32 32 NSLog, NSNotificationCenter, NSMakeRange,\
33 33 NSLocalizedString, NSIntersectionRange,\
34 34 NSString, NSAutoreleasePool
35 35
36 36 from AppKit import NSApplicationWillTerminateNotification, NSBeep,\
37 37 NSTextView, NSRulerView, NSVerticalRuler
38 38
39 39 from pprint import saferepr
40 40
41 41 import IPython
42 42 from IPython.kernel.engineservice import ThreadedEngineService
43 43 from IPython.frontend.asyncfrontendbase import AsyncFrontEndBase
44 44
45 45 from twisted.internet.threads import blockingCallFromThread
46 46 from twisted.python.failure import Failure
47 47
48 #------------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
49 49 # Classes to implement the Cocoa frontend
50 #------------------------------------------------------------------------------
50 #-----------------------------------------------------------------------------
51 51
52 52 # TODO:
53 53 # 1. use MultiEngineClient and out-of-process engine rather than
54 54 # ThreadedEngineService?
55 55 # 2. integrate Xgrid launching of engines
56 56
57 57 class AutoreleasePoolWrappedThreadedEngineService(ThreadedEngineService):
58 58 """Wrap all blocks in an NSAutoreleasePool"""
59 59
60 60 def wrapped_execute(self, msg, lines):
61 61 """wrapped_execute"""
62 62 try:
63 63 p = NSAutoreleasePool.alloc().init()
64 result = self.shell.execute(lines)
65 except Exception,e:
66 # This gives the following:
67 # et=exception class
68 # ev=exception class instance
69 # tb=traceback object
70 et,ev,tb = sys.exc_info()
71 # This call adds attributes to the exception value
72 et,ev,tb = self.shell.formatTraceback(et,ev,tb,msg)
73 # Add another attribute
74
75 # Create a new exception with the new attributes
76 e = et(ev._ipython_traceback_text)
77 e._ipython_engine_info = msg
78
79 # Re-raise
80 raise e
64 result = super(AutoreleasePoolWrappedThreadedEngineService,
65 self).wrapped_execute(msg, lines)
81 66 finally:
82 67 p.drain()
83 68
84 69 return result
85 70
86 def execute(self, lines):
87 # Only import this if we are going to use this class
88 from twisted.internet import threads
89 71
90 msg = {'engineid':self.id,
91 'method':'execute',
92 'args':[lines]}
93 72
94 d = threads.deferToThread(self.wrapped_execute, msg, lines)
95 d.addCallback(self.addIDToResult)
96 return d
73 class Cell(NSObject):
74 """
75 Representation of the prompts, input and output of a cell in the
76 frontend
77 """
78
79 blockNumber = objc.ivar().unsigned_long()
80 blockID = objc.ivar()
81 inputBlock = objc.ivar()
82 output = objc.ivar()
83
84
85
86 class CellBlock(object):
87 """
88 Storage for information about text ranges relating to a single cell
89 """
90
91
92 def __init__(self, inputPromptRange, inputRange=None, outputPromptRange=None,
93 outputRange=None):
94 super(CellBlock, self).__init__()
95 self.inputPromptRange = inputPromptRange
96 self.inputRange = inputRange
97 self.outputPromptRange = outputPromptRange
98 self.outputRange = outputRange
99
100 def update_ranges_for_insertion(self, text, textRange):
101 """Update ranges for text insertion at textRange"""
102
103 for r in [self.inputPromptRange,self.inputRange,
104 self.outputPromptRange, self.outputRange]:
105 if(r == None):
106 continue
107 intersection = NSIntersectionRange(r,textRange)
108 if(intersection.length == 0): #ranges don't intersect
109 if r.location >= textRange.location:
110 r.location += len(text)
111 else: #ranges intersect
112 if(r.location > textRange.location):
113 offset = len(text) - intersection.length
114 r.length -= offset
115 r.location += offset
116 elif(r.location == textRange.location):
117 r.length += len(text) - intersection.length
118 else:
119 r.length -= intersection.length
120
121
122 def update_ranges_for_deletion(self, textRange):
123 """Update ranges for text deletion at textRange"""
124
125 for r in [self.inputPromptRange,self.inputRange,
126 self.outputPromptRange, self.outputRange]:
127 if(r==None):
128 continue
129 intersection = NSIntersectionRange(r, textRange)
130 if(intersection.length == 0): #ranges don't intersect
131 if r.location >= textRange.location:
132 r.location -= textRange.length
133 else: #ranges intersect
134 if(r.location > textRange.location):
135 offset = intersection.length
136 r.length -= offset
137 r.location += offset
138 elif(r.location == textRange.location):
139 r.length += intersection.length
140 else:
141 r.length -= intersection.length
142
143 def __repr__(self):
144 return 'CellBlock('+ str((self.inputPromptRange,
145 self.inputRange,
146 self.outputPromptRange,
147 self.outputRange)) + ')'
148
149
97 150
98 151
99 152 class IPythonCocoaController(NSObject, AsyncFrontEndBase):
100 153 userNS = objc.ivar() #mirror of engine.user_ns (key=>str(value))
101 154 waitingForEngine = objc.ivar().bool()
102 155 textView = objc.IBOutlet()
103 156
104 157 def init(self):
105 158 self = super(IPythonCocoaController, self).init()
106 159 AsyncFrontEndBase.__init__(self,
107 160 engine=AutoreleasePoolWrappedThreadedEngineService())
108 161 if(self != None):
109 162 self._common_init()
110 163
111 164 return self
112 165
113 166 def _common_init(self):
114 167 """_common_init"""
115 168
116 169 self.userNS = NSMutableDictionary.dictionary()
117 170 self.waitingForEngine = False
118 171
119 172 self.lines = {}
120 173 self.tabSpaces = 4
121 174 self.tabUsesSpaces = True
122 175 self.currentBlockID = self.next_block_ID()
123 self.blockRanges = {} # blockID=>NSRange
176 self.blockRanges = {} # blockID=>CellBlock
124 177
125 178
126 179 def awakeFromNib(self):
127 180 """awakeFromNib"""
128 181
129 182 self._common_init()
130 183
131 184 # Start the IPython engine
132 185 self.engine.startService()
133 186 NSLog('IPython engine started')
134 187
135 188 # Register for app termination
136 189 nc = NSNotificationCenter.defaultCenter()
137 190 nc.addObserver_selector_name_object_(
138 191 self,
139 192 'appWillTerminate:',
140 193 NSApplicationWillTerminateNotification,
141 194 None)
142 195
143 196 self.textView.setDelegate_(self)
144 197 self.textView.enclosingScrollView().setHasVerticalRuler_(True)
145 198 r = NSRulerView.alloc().initWithScrollView_orientation_(
146 199 self.textView.enclosingScrollView(),
147 200 NSVerticalRuler)
148 201 self.verticalRulerView = r
149 202 self.verticalRulerView.setClientView_(self.textView)
150 203 self._start_cli_banner()
204 self.start_new_block()
151 205
152 206
153 207 def appWillTerminate_(self, notification):
154 208 """appWillTerminate"""
155 209
156 210 self.engine.stopService()
157 211
158 212
159 213 def complete(self, token):
160 214 """Complete token in engine's user_ns
161 215
162 216 Parameters
163 217 ----------
164 218 token : string
165 219
166 220 Result
167 221 ------
168 222 Deferred result of
169 223 IPython.kernel.engineservice.IEngineBase.complete
170 224 """
171 225
172 226 return self.engine.complete(token)
173 227
174 228
175 229 def execute(self, block, blockID=None):
176 230 self.waitingForEngine = True
177 231 self.willChangeValueForKey_('commandHistory')
178 232 d = super(IPythonCocoaController, self).execute(block,
179 233 blockID)
180 234 d.addBoth(self._engine_done)
181 235 d.addCallback(self._update_user_ns)
182 236
183 237 return d
184 238
185 239
186 240 def push_(self, namespace):
187 241 """Push dictionary of key=>values to python namespace"""
188 242
189 243 self.waitingForEngine = True
190 244 self.willChangeValueForKey_('commandHistory')
191 245 d = self.engine.push(namespace)
192 246 d.addBoth(self._engine_done)
193 247 d.addCallback(self._update_user_ns)
194 248
195 249
196 250 def pull_(self, keys):
197 251 """Pull keys from python namespace"""
198 252
199 253 self.waitingForEngine = True
200 254 result = blockingCallFromThread(self.engine.pull, keys)
201 255 self.waitingForEngine = False
202 256
203 257 @objc.signature('v@:@I')
204 258 def executeFileAtPath_encoding_(self, path, encoding):
205 259 """Execute file at path in an empty namespace. Update the engine
206 260 user_ns with the resulting locals."""
207 261
208 262 lines,err = NSString.stringWithContentsOfFile_encoding_error_(
209 263 path,
210 264 encoding,
211 265 None)
212 266 self.engine.execute(lines)
213 267
214 268
215 269 def _engine_done(self, x):
216 270 self.waitingForEngine = False
217 271 self.didChangeValueForKey_('commandHistory')
218 272 return x
219 273
220 274 def _update_user_ns(self, result):
221 275 """Update self.userNS from self.engine's namespace"""
222 276 d = self.engine.keys()
223 277 d.addCallback(self._get_engine_namespace_values_for_keys)
224 278
225 279 return result
226 280
227 281
228 282 def _get_engine_namespace_values_for_keys(self, keys):
229 283 d = self.engine.pull(keys)
230 284 d.addCallback(self._store_engine_namespace_values, keys=keys)
231 285
232 286
233 287 def _store_engine_namespace_values(self, values, keys=[]):
234 288 assert(len(values) == len(keys))
235 289 self.willChangeValueForKey_('userNS')
236 290 for (k,v) in zip(keys,values):
237 291 self.userNS[k] = saferepr(v)
238 292 self.didChangeValueForKey_('userNS')
239 293
240 294
241 295 def update_cell_prompt(self, result, blockID=None):
296 print self.blockRanges
242 297 if(isinstance(result, Failure)):
243 self.insert_text(self.input_prompt(),
244 textRange=NSMakeRange(self.blockRanges[blockID].location,0),
245 scrollToVisible=False
246 )
298 prompt = self.input_prompt()
299
247 300 else:
248 self.insert_text(self.input_prompt(number=result['number']),
249 textRange=NSMakeRange(self.blockRanges[blockID].location,0),
301 prompt = self.input_prompt(number=result['number'])
302
303 r = self.blockRanges[blockID].inputPromptRange
304 self.insert_text(prompt,
305 textRange=r,
250 306 scrollToVisible=False
251 307 )
252 308
253 309 return result
254 310
255 311
256 312 def render_result(self, result):
257 313 blockID = result['blockID']
258 inputRange = self.blockRanges[blockID]
314 inputRange = self.blockRanges[blockID].inputRange
259 315 del self.blockRanges[blockID]
260 316
261 317 #print inputRange,self.current_block_range()
262 318 self.insert_text('\n' +
263 319 self.output_prompt(number=result['number']) +
264 320 result.get('display',{}).get('pprint','') +
265 321 '\n\n',
266 322 textRange=NSMakeRange(inputRange.location+inputRange.length,
267 323 0))
268 324 return result
269 325
270 326
271 327 def render_error(self, failure):
328 print failure
329 blockID = failure.blockID
330 inputRange = self.blockRanges[blockID].inputRange
272 331 self.insert_text('\n' +
273 332 self.output_prompt() +
274 333 '\n' +
275 334 failure.getErrorMessage() +
276 '\n\n')
335 '\n\n',
336 textRange=NSMakeRange(inputRange.location +
337 inputRange.length,
338 0))
277 339 self.start_new_block()
278 340 return failure
279 341
280 342
281 343 def _start_cli_banner(self):
282 344 """Print banner"""
283 345
284 346 banner = """IPython1 %s -- An enhanced Interactive Python.""" % \
285 347 IPython.__version__
286 348
287 349 self.insert_text(banner + '\n\n')
288 350
289 351
290 352 def start_new_block(self):
291 353 """"""
292 354
293 355 self.currentBlockID = self.next_block_ID()
356 self.blockRanges[self.currentBlockID] = self.new_cell_block()
357 self.insert_text(self.input_prompt(),
358 textRange=self.current_block_range().inputPromptRange)
294 359
295 360
296 361
297 362 def next_block_ID(self):
298 363
299 364 return uuid.uuid4()
300 365
366 def new_cell_block(self):
367 """A new CellBlock at the end of self.textView.textStorage()"""
368
369 return CellBlock(NSMakeRange(self.textView.textStorage().length(),
370 0), #len(self.input_prompt())),
371 NSMakeRange(self.textView.textStorage().length(),# + len(self.input_prompt()),
372 0))
373
374
301 375 def current_block_range(self):
302 376 return self.blockRanges.get(self.currentBlockID,
303 NSMakeRange(self.textView.textStorage().length(),
304 0))
377 self.new_cell_block())
305 378
306 379 def current_block(self):
307 380 """The current block's text"""
308 381
309 return self.text_for_range(self.current_block_range())
382 return self.text_for_range(self.current_block_range().inputRange)
310 383
311 384 def text_for_range(self, textRange):
312 385 """text_for_range"""
313 386
314 387 ts = self.textView.textStorage()
315 388 return ts.string().substringWithRange_(textRange)
316 389
317 390 def current_line(self):
318 block = self.text_for_range(self.current_block_range())
391 block = self.text_for_range(self.current_block_range().inputRange)
319 392 block = block.split('\n')
320 393 return block[-1]
321 394
322 395
323 396 def insert_text(self, string=None, textRange=None, scrollToVisible=True):
324 397 """Insert text into textView at textRange, updating blockRanges
325 398 as necessary
326 399 """
327
328 400 if(textRange == None):
329 401 #range for end of text
330 402 textRange = NSMakeRange(self.textView.textStorage().length(), 0)
331 403
332 for r in self.blockRanges.itervalues():
333 intersection = NSIntersectionRange(r,textRange)
334 if(intersection.length == 0): #ranges don't intersect
335 if r.location >= textRange.location:
336 r.location += len(string)
337 else: #ranges intersect
338 if(r.location <= textRange.location):
339 assert(intersection.length == textRange.length)
340 r.length += textRange.length
341 else:
342 r.location += intersection.length
343 404
344 405 self.textView.replaceCharactersInRange_withString_(
345 406 textRange, string)
346 self.textView.setSelectedRange_(
347 NSMakeRange(textRange.location+len(string), 0))
407
408 for r in self.blockRanges.itervalues():
409 r.update_ranges_for_insertion(string, textRange)
410
411 self.textView.setSelectedRange_(textRange)
348 412 if(scrollToVisible):
349 413 self.textView.scrollRangeToVisible_(textRange)
350 414
351 415
352 416
353
354 417 def replace_current_block_with_string(self, textView, string):
355 418 textView.replaceCharactersInRange_withString_(
356 self.current_block_range(),
419 self.current_block_range().inputRange,
357 420 string)
358 self.current_block_range().length = len(string)
421 self.current_block_range().inputRange.length = len(string)
359 422 r = NSMakeRange(textView.textStorage().length(), 0)
360 423 textView.scrollRangeToVisible_(r)
361 424 textView.setSelectedRange_(r)
362 425
363 426
364 427 def current_indent_string(self):
365 428 """returns string for indent or None if no indent"""
366 429
367 430 return self._indent_for_block(self.current_block())
368 431
369 432
370 433 def _indent_for_block(self, block):
371 434 lines = block.split('\n')
372 435 if(len(lines) > 1):
373 436 currentIndent = len(lines[-1]) - len(lines[-1].lstrip())
374 437 if(currentIndent == 0):
375 438 currentIndent = self.tabSpaces
376 439
377 440 if(self.tabUsesSpaces):
378 441 result = ' ' * currentIndent
379 442 else:
380 443 result = '\t' * (currentIndent/self.tabSpaces)
381 444 else:
382 445 result = None
383 446
384 447 return result
385 448
386 449
387 450 # NSTextView delegate methods...
388 451 def textView_doCommandBySelector_(self, textView, selector):
389 452 assert(textView == self.textView)
390 453 NSLog("textView_doCommandBySelector_: "+selector)
391 454
392 455
393 456 if(selector == 'insertNewline:'):
394 457 indent = self.current_indent_string()
395 458 if(indent):
396 459 line = indent + self.current_line()
397 460 else:
398 461 line = self.current_line()
399 462
400 463 if(self.is_complete(self.current_block())):
401 464 self.execute(self.current_block(),
402 465 blockID=self.currentBlockID)
403 466 self.start_new_block()
404 467
405 468 return True
406 469
407 470 return False
408 471
409 472 elif(selector == 'moveUp:'):
410 473 prevBlock = self.get_history_previous(self.current_block())
411 474 if(prevBlock != None):
412 475 self.replace_current_block_with_string(textView, prevBlock)
413 476 else:
414 477 NSBeep()
415 478 return True
416 479
417 480 elif(selector == 'moveDown:'):
418 481 nextBlock = self.get_history_next()
419 482 if(nextBlock != None):
420 483 self.replace_current_block_with_string(textView, nextBlock)
421 484 else:
422 485 NSBeep()
423 486 return True
424 487
425 488 elif(selector == 'moveToBeginningOfParagraph:'):
426 489 textView.setSelectedRange_(NSMakeRange(
427 self.current_block_range().location,
490 self.current_block_range().inputRange.location,
428 491 0))
429 492 return True
430 493 elif(selector == 'moveToEndOfParagraph:'):
431 494 textView.setSelectedRange_(NSMakeRange(
432 self.current_block_range().location + \
433 self.current_block_range().length, 0))
495 self.current_block_range().inputRange.location + \
496 self.current_block_range().inputRange.length, 0))
434 497 return True
435 498 elif(selector == 'deleteToEndOfParagraph:'):
436 499 if(textView.selectedRange().location <= \
437 500 self.current_block_range().location):
438 # Intersect the selected range with the current line range
439 if(self.current_block_range().length < 0):
440 self.blockRanges[self.currentBlockID].length = 0
441
442 r = NSIntersectionRange(textView.rangesForUserTextChange()[0],
443 self.current_block_range())
444
445 if(r.length > 0): #no intersection
446 textView.setSelectedRange_(r)
501 raise NotImplemented()
447 502
448 503 return False # don't actually handle the delete
449 504
450 505 elif(selector == 'insertTab:'):
451 506 if(len(self.current_line().strip()) == 0): #only white space
452 507 return False
453 508 else:
454 509 self.textView.complete_(self)
455 510 return True
456 511
457 512 elif(selector == 'deleteBackward:'):
458 513 #if we're at the beginning of the current block, ignore
459 514 if(textView.selectedRange().location == \
460 self.current_block_range().location):
515 self.current_block_range().inputRange.location):
461 516 return True
462 517 else:
463 self.current_block_range().length-=1
518 for r in self.blockRanges.itervalues():
519 deleteRange = textView.selectedRange
520 if(deleteRange.length == 0):
521 deleteRange.location -= 1
522 deleteRange.length = 1
523 r.update_ranges_for_deletion(deleteRange)
464 524 return False
465 525 return False
466 526
467 527
468 528 def textView_shouldChangeTextInRanges_replacementStrings_(self,
469 529 textView, ranges, replacementStrings):
470 530 """
471 531 Delegate method for NSTextView.
472 532
473 533 Refuse change text in ranges not at end, but make those changes at
474 534 end.
475 535 """
476 536
477 537 assert(len(ranges) == len(replacementStrings))
478 538 allow = True
479 539 for r,s in zip(ranges, replacementStrings):
480 540 r = r.rangeValue()
481 541 if(textView.textStorage().length() > 0 and
482 r.location < self.current_block_range().location):
542 r.location < self.current_block_range().inputRange.location):
483 543 self.insert_text(s)
484 544 allow = False
485 545
486
487 self.blockRanges.setdefault(self.currentBlockID,
488 self.current_block_range()).length +=\
489 len(s)
490
491 546 return allow
492 547
493 548 def textView_completions_forPartialWordRange_indexOfSelectedItem_(self,
494 549 textView, words, charRange, index):
495 550 try:
496 551 ts = textView.textStorage()
497 552 token = ts.string().substringWithRange_(charRange)
498 553 completions = blockingCallFromThread(self.complete, token)
499 554 except:
500 555 completions = objc.nil
501 556 NSBeep()
502 557
503 558 return (completions,0)
504 559
505 560
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file chmod 100755 => 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from IPython/testing/attic/parametric.py to IPython/testing/parametric.py
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
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