##// END OF EJS Templates
Merge with upstream
Fernando Perez -
r1500:bb687e6b 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
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
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
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
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
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
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
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
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
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
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 ``astyle`` provides classes for adding style (foreground and background color;
2 ``astyle`` provides classes for adding style (foreground and background color;
3 bold; blink; etc.) to terminal and curses output.
3 bold; blink; etc.) to terminal and curses output.
4 """
4 """
5
5
6
6
7 import sys, os
7 import sys, os
8
8
9 try:
9 try:
10 import curses
10 import curses
11 except ImportError:
11 except ImportError:
12 curses = None
12 curses = None
13
13
14
14
15 COLOR_BLACK = 0
15 COLOR_BLACK = 0
16 COLOR_RED = 1
16 COLOR_RED = 1
17 COLOR_GREEN = 2
17 COLOR_GREEN = 2
18 COLOR_YELLOW = 3
18 COLOR_YELLOW = 3
19 COLOR_BLUE = 4
19 COLOR_BLUE = 4
20 COLOR_MAGENTA = 5
20 COLOR_MAGENTA = 5
21 COLOR_CYAN = 6
21 COLOR_CYAN = 6
22 COLOR_WHITE = 7
22 COLOR_WHITE = 7
23
23
24 A_BLINK = 1<<0 # Blinking text
24 A_BLINK = 1<<0 # Blinking text
25 A_BOLD = 1<<1 # Extra bright or bold text
25 A_BOLD = 1<<1 # Extra bright or bold text
26 A_DIM = 1<<2 # Half bright text
26 A_DIM = 1<<2 # Half bright text
27 A_REVERSE = 1<<3 # Reverse-video text
27 A_REVERSE = 1<<3 # Reverse-video text
28 A_STANDOUT = 1<<4 # The best highlighting mode available
28 A_STANDOUT = 1<<4 # The best highlighting mode available
29 A_UNDERLINE = 1<<5 # Underlined text
29 A_UNDERLINE = 1<<5 # Underlined text
30
30
31
31
32 class Style(object):
32 class Style(object):
33 """
33 """
34 Store foreground color, background color and attribute (bold, underlined
34 Store foreground color, background color and attribute (bold, underlined
35 etc.).
35 etc.).
36 """
36 """
37 __slots__ = ("fg", "bg", "attrs")
37 __slots__ = ("fg", "bg", "attrs")
38
38
39 COLORNAMES = {
39 COLORNAMES = {
40 "black": COLOR_BLACK,
40 "black": COLOR_BLACK,
41 "red": COLOR_RED,
41 "red": COLOR_RED,
42 "green": COLOR_GREEN,
42 "green": COLOR_GREEN,
43 "yellow": COLOR_YELLOW,
43 "yellow": COLOR_YELLOW,
44 "blue": COLOR_BLUE,
44 "blue": COLOR_BLUE,
45 "magenta": COLOR_MAGENTA,
45 "magenta": COLOR_MAGENTA,
46 "cyan": COLOR_CYAN,
46 "cyan": COLOR_CYAN,
47 "white": COLOR_WHITE,
47 "white": COLOR_WHITE,
48 }
48 }
49 ATTRNAMES = {
49 ATTRNAMES = {
50 "blink": A_BLINK,
50 "blink": A_BLINK,
51 "bold": A_BOLD,
51 "bold": A_BOLD,
52 "dim": A_DIM,
52 "dim": A_DIM,
53 "reverse": A_REVERSE,
53 "reverse": A_REVERSE,
54 "standout": A_STANDOUT,
54 "standout": A_STANDOUT,
55 "underline": A_UNDERLINE,
55 "underline": A_UNDERLINE,
56 }
56 }
57
57
58 def __init__(self, fg, bg, attrs=0):
58 def __init__(self, fg, bg, attrs=0):
59 """
59 """
60 Create a ``Style`` object with ``fg`` as the foreground color,
60 Create a ``Style`` object with ``fg`` as the foreground color,
61 ``bg`` as the background color and ``attrs`` as the attributes.
61 ``bg`` as the background color and ``attrs`` as the attributes.
62
62
63 Examples:
63 Examples:
64
65 >>> Style(COLOR_RED, COLOR_BLACK)
64 >>> Style(COLOR_RED, COLOR_BLACK)
65 <Style fg=red bg=black attrs=0>
66
66 >>> Style(COLOR_YELLOW, COLOR_BLUE, A_BOLD|A_UNDERLINE)
67 >>> Style(COLOR_YELLOW, COLOR_BLUE, A_BOLD|A_UNDERLINE)
68 <Style fg=yellow bg=blue attrs=bold|underline>
67 """
69 """
68 self.fg = fg
70 self.fg = fg
69 self.bg = bg
71 self.bg = bg
70 self.attrs = attrs
72 self.attrs = attrs
71
73
72 def __call__(self, *args):
74 def __call__(self, *args):
73 text = Text()
75 text = Text()
74 for arg in args:
76 for arg in args:
75 if isinstance(arg, Text):
77 if isinstance(arg, Text):
76 text.extend(arg)
78 text.extend(arg)
77 else:
79 else:
78 text.append((self, arg))
80 text.append((self, arg))
79 return text
81 return text
80
82
81 def __eq__(self, other):
83 def __eq__(self, other):
82 return self.fg == other.fg and self.bg == other.bg and self.attrs == other.attrs
84 return self.fg == other.fg and self.bg == other.bg and self.attrs == other.attrs
83
85
84 def __neq__(self, other):
86 def __neq__(self, other):
85 return self.fg != other.fg or self.bg != other.bg or self.attrs != other.attrs
87 return self.fg != other.fg or self.bg != other.bg or self.attrs != other.attrs
86
88
87 def __repr__(self):
89 def __repr__(self):
88 color2name = ("black", "red", "green", "yellow", "blue", "magenta", "cyan", "white")
90 color2name = ("black", "red", "green", "yellow", "blue", "magenta", "cyan", "white")
89 attrs2name = ("blink", "bold", "dim", "reverse", "standout", "underline")
91 attrs2name = ("blink", "bold", "dim", "reverse", "standout", "underline")
90
92
91 return "<%s fg=%s bg=%s attrs=%s>" % (
93 return "<%s fg=%s bg=%s attrs=%s>" % (
92 self.__class__.__name__, color2name[self.fg], color2name[self.bg],
94 self.__class__.__name__, color2name[self.fg], color2name[self.bg],
93 "|".join([attrs2name[b] for b in xrange(6) if self.attrs&(1<<b)]) or 0)
95 "|".join([attrs2name[b] for b in xrange(6) if self.attrs&(1<<b)]) or 0)
94
96
95 def fromstr(cls, value):
97 def fromstr(cls, value):
96 """
98 """
97 Create a ``Style`` object from a string. The format looks like this:
99 Create a ``Style`` object from a string. The format looks like this:
98 ``"red:black:bold|blink"``.
100 ``"red:black:bold|blink"``.
99 """
101 """
100 # defaults
102 # defaults
101 fg = COLOR_WHITE
103 fg = COLOR_WHITE
102 bg = COLOR_BLACK
104 bg = COLOR_BLACK
103 attrs = 0
105 attrs = 0
104
106
105 parts = value.split(":")
107 parts = value.split(":")
106 if len(parts) > 0:
108 if len(parts) > 0:
107 fg = cls.COLORNAMES[parts[0].lower()]
109 fg = cls.COLORNAMES[parts[0].lower()]
108 if len(parts) > 1:
110 if len(parts) > 1:
109 bg = cls.COLORNAMES[parts[1].lower()]
111 bg = cls.COLORNAMES[parts[1].lower()]
110 if len(parts) > 2:
112 if len(parts) > 2:
111 for strattr in parts[2].split("|"):
113 for strattr in parts[2].split("|"):
112 attrs |= cls.ATTRNAMES[strattr.lower()]
114 attrs |= cls.ATTRNAMES[strattr.lower()]
113 return cls(fg, bg, attrs)
115 return cls(fg, bg, attrs)
114 fromstr = classmethod(fromstr)
116 fromstr = classmethod(fromstr)
115
117
116 def fromenv(cls, name, default):
118 def fromenv(cls, name, default):
117 """
119 """
118 Create a ``Style`` from an environment variable named ``name``
120 Create a ``Style`` from an environment variable named ``name``
119 (using ``default`` if the environment variable doesn't exist).
121 (using ``default`` if the environment variable doesn't exist).
120 """
122 """
121 return cls.fromstr(os.environ.get(name, default))
123 return cls.fromstr(os.environ.get(name, default))
122 fromenv = classmethod(fromenv)
124 fromenv = classmethod(fromenv)
123
125
124
126
125 def switchstyle(s1, s2):
127 def switchstyle(s1, s2):
126 """
128 """
127 Return the ANSI escape sequence needed to switch from style ``s1`` to
129 Return the ANSI escape sequence needed to switch from style ``s1`` to
128 style ``s2``.
130 style ``s2``.
129 """
131 """
130 attrmask = (A_BLINK|A_BOLD|A_UNDERLINE|A_REVERSE)
132 attrmask = (A_BLINK|A_BOLD|A_UNDERLINE|A_REVERSE)
131 a1 = s1.attrs & attrmask
133 a1 = s1.attrs & attrmask
132 a2 = s2.attrs & attrmask
134 a2 = s2.attrs & attrmask
133
135
134 args = []
136 args = []
135 if s1 != s2:
137 if s1 != s2:
136 # do we have to get rid of the bold/underline/blink bit?
138 # do we have to get rid of the bold/underline/blink bit?
137 # (can only be done by a reset)
139 # (can only be done by a reset)
138 # use reset when our target color is the default color
140 # use reset when our target color is the default color
139 # (this is shorter than 37;40)
141 # (this is shorter than 37;40)
140 if (a1 & ~a2 or s2==style_default):
142 if (a1 & ~a2 or s2==style_default):
141 args.append("0")
143 args.append("0")
142 s1 = style_default
144 s1 = style_default
143 a1 = 0
145 a1 = 0
144
146
145 # now we know that old and new color have the same boldness,
147 # now we know that old and new color have the same boldness,
146 # or the new color is bold and the old isn't,
148 # or the new color is bold and the old isn't,
147 # i.e. we only might have to switch bold on, not off
149 # i.e. we only might have to switch bold on, not off
148 if not (a1 & A_BOLD) and (a2 & A_BOLD):
150 if not (a1 & A_BOLD) and (a2 & A_BOLD):
149 args.append("1")
151 args.append("1")
150
152
151 # Fix underline
153 # Fix underline
152 if not (a1 & A_UNDERLINE) and (a2 & A_UNDERLINE):
154 if not (a1 & A_UNDERLINE) and (a2 & A_UNDERLINE):
153 args.append("4")
155 args.append("4")
154
156
155 # Fix blink
157 # Fix blink
156 if not (a1 & A_BLINK) and (a2 & A_BLINK):
158 if not (a1 & A_BLINK) and (a2 & A_BLINK):
157 args.append("5")
159 args.append("5")
158
160
159 # Fix reverse
161 # Fix reverse
160 if not (a1 & A_REVERSE) and (a2 & A_REVERSE):
162 if not (a1 & A_REVERSE) and (a2 & A_REVERSE):
161 args.append("7")
163 args.append("7")
162
164
163 # Fix foreground color
165 # Fix foreground color
164 if s1.fg != s2.fg:
166 if s1.fg != s2.fg:
165 args.append("3%d" % s2.fg)
167 args.append("3%d" % s2.fg)
166
168
167 # Finally fix the background color
169 # Finally fix the background color
168 if s1.bg != s2.bg:
170 if s1.bg != s2.bg:
169 args.append("4%d" % s2.bg)
171 args.append("4%d" % s2.bg)
170
172
171 if args:
173 if args:
172 return "\033[%sm" % ";".join(args)
174 return "\033[%sm" % ";".join(args)
173 return ""
175 return ""
174
176
175
177
176 class Text(list):
178 class Text(list):
177 """
179 """
178 A colored string. A ``Text`` object is a sequence, the sequence
180 A colored string. A ``Text`` object is a sequence, the sequence
179 items will be ``(style, string)`` tuples.
181 items will be ``(style, string)`` tuples.
180 """
182 """
181
183
182 def __init__(self, *args):
184 def __init__(self, *args):
183 list.__init__(self)
185 list.__init__(self)
184 self.append(*args)
186 self.append(*args)
185
187
186 def __repr__(self):
188 def __repr__(self):
187 return "%s.%s(%s)" % (
189 return "%s.%s(%s)" % (
188 self.__class__.__module__, self.__class__.__name__,
190 self.__class__.__module__, self.__class__.__name__,
189 list.__repr__(self)[1:-1])
191 list.__repr__(self)[1:-1])
190
192
191 def append(self, *args):
193 def append(self, *args):
192 for arg in args:
194 for arg in args:
193 if isinstance(arg, Text):
195 if isinstance(arg, Text):
194 self.extend(arg)
196 self.extend(arg)
195 elif isinstance(arg, tuple): # must be (style, string)
197 elif isinstance(arg, tuple): # must be (style, string)
196 list.append(self, arg)
198 list.append(self, arg)
197 elif isinstance(arg, unicode):
199 elif isinstance(arg, unicode):
198 list.append(self, (style_default, arg))
200 list.append(self, (style_default, arg))
199 else:
201 else:
200 list.append(self, (style_default, str(arg)))
202 list.append(self, (style_default, str(arg)))
201
203
202 def insert(self, index, *args):
204 def insert(self, index, *args):
203 self[index:index] = Text(*args)
205 self[index:index] = Text(*args)
204
206
205 def __add__(self, other):
207 def __add__(self, other):
206 new = Text()
208 new = Text()
207 new.append(self)
209 new.append(self)
208 new.append(other)
210 new.append(other)
209 return new
211 return new
210
212
211 def __iadd__(self, other):
213 def __iadd__(self, other):
212 self.append(other)
214 self.append(other)
213 return self
215 return self
214
216
215 def format(self, styled=True):
217 def format(self, styled=True):
216 """
218 """
217 This generator yields the strings that will make up the final
219 This generator yields the strings that will make up the final
218 colorized string.
220 colorized string.
219 """
221 """
220 if styled:
222 if styled:
221 oldstyle = style_default
223 oldstyle = style_default
222 for (style, string) in self:
224 for (style, string) in self:
223 if not isinstance(style, (int, long)):
225 if not isinstance(style, (int, long)):
224 switch = switchstyle(oldstyle, style)
226 switch = switchstyle(oldstyle, style)
225 if switch:
227 if switch:
226 yield switch
228 yield switch
227 if string:
229 if string:
228 yield string
230 yield string
229 oldstyle = style
231 oldstyle = style
230 switch = switchstyle(oldstyle, style_default)
232 switch = switchstyle(oldstyle, style_default)
231 if switch:
233 if switch:
232 yield switch
234 yield switch
233 else:
235 else:
234 for (style, string) in self:
236 for (style, string) in self:
235 if not isinstance(style, (int, long)):
237 if not isinstance(style, (int, long)):
236 yield string
238 yield string
237
239
238 def string(self, styled=True):
240 def string(self, styled=True):
239 """
241 """
240 Return the resulting string (with escape sequences, if ``styled``
242 Return the resulting string (with escape sequences, if ``styled``
241 is true).
243 is true).
242 """
244 """
243 return "".join(self.format(styled))
245 return "".join(self.format(styled))
244
246
245 def __str__(self):
247 def __str__(self):
246 """
248 """
247 Return ``self`` as a string (without ANSI escape sequences).
249 Return ``self`` as a string (without ANSI escape sequences).
248 """
250 """
249 return self.string(False)
251 return self.string(False)
250
252
251 def write(self, stream, styled=True):
253 def write(self, stream, styled=True):
252 """
254 """
253 Write ``self`` to the output stream ``stream`` (with escape sequences,
255 Write ``self`` to the output stream ``stream`` (with escape sequences,
254 if ``styled`` is true).
256 if ``styled`` is true).
255 """
257 """
256 for part in self.format(styled):
258 for part in self.format(styled):
257 stream.write(part)
259 stream.write(part)
258
260
259
261
260 try:
262 try:
261 import ipipe
263 import ipipe
262 except ImportError:
264 except ImportError:
263 pass
265 pass
264 else:
266 else:
265 def xrepr_astyle_text(self, mode="default"):
267 def xrepr_astyle_text(self, mode="default"):
266 yield (-1, True)
268 yield (-1, True)
267 for info in self:
269 for info in self:
268 yield info
270 yield info
269 ipipe.xrepr.when_type(Text)(xrepr_astyle_text)
271 ipipe.xrepr.when_type(Text)(xrepr_astyle_text)
270
272
271
273
272 def streamstyle(stream, styled=None):
274 def streamstyle(stream, styled=None):
273 """
275 """
274 If ``styled`` is ``None``, return whether ``stream`` refers to a terminal.
276 If ``styled`` is ``None``, return whether ``stream`` refers to a terminal.
275 If this can't be determined (either because ``stream`` doesn't refer to a
277 If this can't be determined (either because ``stream`` doesn't refer to a
276 real OS file, or because you're on Windows) return ``False``. If ``styled``
278 real OS file, or because you're on Windows) return ``False``. If ``styled``
277 is not ``None`` ``styled`` will be returned unchanged.
279 is not ``None`` ``styled`` will be returned unchanged.
278 """
280 """
279 if styled is None:
281 if styled is None:
280 try:
282 try:
281 styled = os.isatty(stream.fileno())
283 styled = os.isatty(stream.fileno())
282 except (KeyboardInterrupt, SystemExit):
284 except (KeyboardInterrupt, SystemExit):
283 raise
285 raise
284 except Exception:
286 except Exception:
285 styled = False
287 styled = False
286 return styled
288 return styled
287
289
288
290
289 def write(stream, styled, *texts):
291 def write(stream, styled, *texts):
290 """
292 """
291 Write ``texts`` to ``stream``.
293 Write ``texts`` to ``stream``.
292 """
294 """
293 text = Text(*texts)
295 text = Text(*texts)
294 text.write(stream, streamstyle(stream, styled))
296 text.write(stream, streamstyle(stream, styled))
295
297
296
298
297 def writeln(stream, styled, *texts):
299 def writeln(stream, styled, *texts):
298 """
300 """
299 Write ``texts`` to ``stream`` and finish with a line feed.
301 Write ``texts`` to ``stream`` and finish with a line feed.
300 """
302 """
301 write(stream, styled, *texts)
303 write(stream, styled, *texts)
302 stream.write("\n")
304 stream.write("\n")
303
305
304
306
305 class Stream(object):
307 class Stream(object):
306 """
308 """
307 Stream wrapper that adds color output.
309 Stream wrapper that adds color output.
308 """
310 """
309 def __init__(self, stream, styled=None):
311 def __init__(self, stream, styled=None):
310 self.stream = stream
312 self.stream = stream
311 self.styled = streamstyle(stream, styled)
313 self.styled = streamstyle(stream, styled)
312
314
313 def write(self, *texts):
315 def write(self, *texts):
314 write(self.stream, self.styled, *texts)
316 write(self.stream, self.styled, *texts)
315
317
316 def writeln(self, *texts):
318 def writeln(self, *texts):
317 writeln(self.stream, self.styled, *texts)
319 writeln(self.stream, self.styled, *texts)
318
320
319 def __getattr__(self, name):
321 def __getattr__(self, name):
320 return getattr(self.stream, name)
322 return getattr(self.stream, name)
321
323
322
324
323 class stdout(object):
325 class stdout(object):
324 """
326 """
325 Stream wrapper for ``sys.stdout`` that adds color output.
327 Stream wrapper for ``sys.stdout`` that adds color output.
326 """
328 """
327 def write(self, *texts):
329 def write(self, *texts):
328 write(sys.stdout, None, *texts)
330 write(sys.stdout, None, *texts)
329
331
330 def writeln(self, *texts):
332 def writeln(self, *texts):
331 writeln(sys.stdout, None, *texts)
333 writeln(sys.stdout, None, *texts)
332
334
333 def __getattr__(self, name):
335 def __getattr__(self, name):
334 return getattr(sys.stdout, name)
336 return getattr(sys.stdout, name)
335 stdout = stdout()
337 stdout = stdout()
336
338
337
339
338 class stderr(object):
340 class stderr(object):
339 """
341 """
340 Stream wrapper for ``sys.stderr`` that adds color output.
342 Stream wrapper for ``sys.stderr`` that adds color output.
341 """
343 """
342 def write(self, *texts):
344 def write(self, *texts):
343 write(sys.stderr, None, *texts)
345 write(sys.stderr, None, *texts)
344
346
345 def writeln(self, *texts):
347 def writeln(self, *texts):
346 writeln(sys.stderr, None, *texts)
348 writeln(sys.stderr, None, *texts)
347
349
348 def __getattr__(self, name):
350 def __getattr__(self, name):
349 return getattr(sys.stdout, name)
351 return getattr(sys.stdout, name)
350 stderr = stderr()
352 stderr = stderr()
351
353
352
354
353 if curses is not None:
355 if curses is not None:
354 # This is probably just range(8)
356 # This is probably just range(8)
355 COLOR2CURSES = [
357 COLOR2CURSES = [
356 COLOR_BLACK,
358 COLOR_BLACK,
357 COLOR_RED,
359 COLOR_RED,
358 COLOR_GREEN,
360 COLOR_GREEN,
359 COLOR_YELLOW,
361 COLOR_YELLOW,
360 COLOR_BLUE,
362 COLOR_BLUE,
361 COLOR_MAGENTA,
363 COLOR_MAGENTA,
362 COLOR_CYAN,
364 COLOR_CYAN,
363 COLOR_WHITE,
365 COLOR_WHITE,
364 ]
366 ]
365
367
366 A2CURSES = {
368 A2CURSES = {
367 A_BLINK: curses.A_BLINK,
369 A_BLINK: curses.A_BLINK,
368 A_BOLD: curses.A_BOLD,
370 A_BOLD: curses.A_BOLD,
369 A_DIM: curses.A_DIM,
371 A_DIM: curses.A_DIM,
370 A_REVERSE: curses.A_REVERSE,
372 A_REVERSE: curses.A_REVERSE,
371 A_STANDOUT: curses.A_STANDOUT,
373 A_STANDOUT: curses.A_STANDOUT,
372 A_UNDERLINE: curses.A_UNDERLINE,
374 A_UNDERLINE: curses.A_UNDERLINE,
373 }
375 }
374
376
375
377
376 # default style
378 # default style
377 style_default = Style.fromstr("white:black")
379 style_default = Style.fromstr("white:black")
378
380
379 # Styles for datatypes
381 # Styles for datatypes
380 style_type_none = Style.fromstr("magenta:black")
382 style_type_none = Style.fromstr("magenta:black")
381 style_type_bool = Style.fromstr("magenta:black")
383 style_type_bool = Style.fromstr("magenta:black")
382 style_type_number = Style.fromstr("yellow:black")
384 style_type_number = Style.fromstr("yellow:black")
383 style_type_datetime = Style.fromstr("magenta:black")
385 style_type_datetime = Style.fromstr("magenta:black")
384 style_type_type = Style.fromstr("cyan:black")
386 style_type_type = Style.fromstr("cyan:black")
385
387
386 # Style for URLs and file/directory names
388 # Style for URLs and file/directory names
387 style_url = Style.fromstr("green:black")
389 style_url = Style.fromstr("green:black")
388 style_dir = Style.fromstr("cyan:black")
390 style_dir = Style.fromstr("cyan:black")
389 style_file = Style.fromstr("green:black")
391 style_file = Style.fromstr("green:black")
390
392
391 # Style for ellipsis (when an output has been shortened
393 # Style for ellipsis (when an output has been shortened
392 style_ellisis = Style.fromstr("red:black")
394 style_ellisis = Style.fromstr("red:black")
393
395
394 # Style for displaying exceptions
396 # Style for displaying exceptions
395 style_error = Style.fromstr("red:black")
397 style_error = Style.fromstr("red:black")
396
398
397 # Style for displaying non-existing attributes
399 # Style for displaying non-existing attributes
398 style_nodata = Style.fromstr("red:black")
400 style_nodata = Style.fromstr("red:black")
@@ -1,2292 +1,2322 b''
1 # -*- coding: iso-8859-1 -*-
1 # -*- coding: iso-8859-1 -*-
2
2
3 """
3 """
4 ``ipipe`` provides classes to be used in an interactive Python session. Doing a
4 ``ipipe`` provides classes to be used in an interactive Python session. Doing a
5 ``from ipipe import *`` is the preferred way to do this. The name of all
5 ``from ipipe import *`` is the preferred way to do this. The name of all
6 objects imported this way starts with ``i`` to minimize collisions.
6 objects imported this way starts with ``i`` to minimize collisions.
7
7
8 ``ipipe`` supports "pipeline expressions", which is something resembling Unix
8 ``ipipe`` supports "pipeline expressions", which is something resembling Unix
9 pipes. An example is::
9 pipes. An example is::
10
10
11 >>> ienv | isort("key.lower()")
11 >>> ienv | isort("key.lower()")
12
12
13 This gives a listing of all environment variables sorted by name.
13 This gives a listing of all environment variables sorted by name.
14
14
15
15
16 There are three types of objects in a pipeline expression:
16 There are three types of objects in a pipeline expression:
17
17
18 * ``Table``s: These objects produce items. Examples are ``ils`` (listing the
18 * ``Table``s: These objects produce items. Examples are ``ils`` (listing the
19 current directory, ``ienv`` (listing environment variables), ``ipwd`` (listing
19 current directory, ``ienv`` (listing environment variables), ``ipwd`` (listing
20 user accounts) and ``igrp`` (listing user groups). A ``Table`` must be the
20 user accounts) and ``igrp`` (listing user groups). A ``Table`` must be the
21 first object in a pipe expression.
21 first object in a pipe expression.
22
22
23 * ``Pipe``s: These objects sit in the middle of a pipe expression. They
23 * ``Pipe``s: These objects sit in the middle of a pipe expression. They
24 transform the input in some way (e.g. filtering or sorting it). Examples are:
24 transform the input in some way (e.g. filtering or sorting it). Examples are:
25 ``ifilter`` (which filters the input pipe), ``isort`` (which sorts the input
25 ``ifilter`` (which filters the input pipe), ``isort`` (which sorts the input
26 pipe) and ``ieval`` (which evaluates a function or expression for each object
26 pipe) and ``ieval`` (which evaluates a function or expression for each object
27 in the input pipe).
27 in the input pipe).
28
28
29 * ``Display``s: These objects can be put as the last object in a pipeline
29 * ``Display``s: These objects can be put as the last object in a pipeline
30 expression. There are responsible for displaying the result of the pipeline
30 expression. There are responsible for displaying the result of the pipeline
31 expression. If a pipeline expression doesn't end in a display object a default
31 expression. If a pipeline expression doesn't end in a display object a default
32 display objects will be used. One example is ``ibrowse`` which is a ``curses``
32 display objects will be used. One example is ``ibrowse`` which is a ``curses``
33 based browser.
33 based browser.
34
34
35
35
36 Adding support for pipeline expressions to your own objects can be done through
36 Adding support for pipeline expressions to your own objects can be done through
37 three extensions points (all of them optional):
37 three extensions points (all of them optional):
38
38
39 * An object that will be displayed as a row by a ``Display`` object should
39 * An object that will be displayed as a row by a ``Display`` object should
40 implement the method ``__xattrs__(self, mode)`` method or register an
40 implement the method ``__xattrs__(self, mode)`` method or register an
41 implementation of the generic function ``xattrs``. For more info see ``xattrs``.
41 implementation of the generic function ``xattrs``. For more info see ``xattrs``.
42
42
43 * When an object ``foo`` is displayed by a ``Display`` object, the generic
43 * When an object ``foo`` is displayed by a ``Display`` object, the generic
44 function ``xrepr`` is used.
44 function ``xrepr`` is used.
45
45
46 * Objects that can be iterated by ``Pipe``s must iterable. For special cases,
46 * Objects that can be iterated by ``Pipe``s must iterable. For special cases,
47 where iteration for display is different than the normal iteration a special
47 where iteration for display is different than the normal iteration a special
48 implementation can be registered with the generic function ``xiter``. This
48 implementation can be registered with the generic function ``xiter``. This
49 makes it possible to use dictionaries and modules in pipeline expressions,
49 makes it possible to use dictionaries and modules in pipeline expressions,
50 for example::
50 for example::
51
51
52 >>> import sys
52 >>> import sys
53 >>> sys | ifilter("isinstance(value, int)") | idump
53 >>> sys | ifilter("isinstance(value, int)") | idump
54 key |value
54 key |value
55 api_version| 1012
55 api_version| 1012
56 dllhandle | 503316480
56 dllhandle | 503316480
57 hexversion | 33817328
57 hexversion | 33817328
58 maxint |2147483647
58 maxint |2147483647
59 maxunicode | 65535
59 maxunicode | 65535
60 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
60 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
61 ...
61 ...
62
62
63 Note: The expression strings passed to ``ifilter()`` and ``isort()`` can
63 Note: The expression strings passed to ``ifilter()`` and ``isort()`` can
64 refer to the object to be filtered or sorted via the variable ``_`` and to any
64 refer to the object to be filtered or sorted via the variable ``_`` and to any
65 of the attributes of the object, i.e.::
65 of the attributes of the object, i.e.::
66
66
67 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
67 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
68
68
69 does the same as::
69 does the same as::
70
70
71 >>> sys.modules | ifilter("value is not None") | isort("key.lower()")
71 >>> sys.modules | ifilter("value is not None") | isort("key.lower()")
72
72
73 In addition to expression strings, it's possible to pass callables (taking
73 In addition to expression strings, it's possible to pass callables (taking
74 the object as an argument) to ``ifilter()``, ``isort()`` and ``ieval()``::
74 the object as an argument) to ``ifilter()``, ``isort()`` and ``ieval()``::
75
75
76 >>> sys | ifilter(lambda _:isinstance(_.value, int)) \
76 >>> sys | ifilter(lambda _:isinstance(_.value, int)) \
77 ... | ieval(lambda _: (_.key, hex(_.value))) | idump
77 ... | ieval(lambda _: (_.key, hex(_.value))) | idump
78 0 |1
78 0 |1
79 api_version|0x3f4
79 api_version|0x3f4
80 dllhandle |0x1e000000
80 dllhandle |0x1e000000
81 hexversion |0x20402f0
81 hexversion |0x20402f0
82 maxint |0x7fffffff
82 maxint |0x7fffffff
83 maxunicode |0xffff
83 maxunicode |0xffff
84 """
84 """
85
85
86 skip_doctest = True # ignore top-level docstring as a doctest.
87
86 import sys, os, os.path, stat, glob, new, csv, datetime, types
88 import sys, os, os.path, stat, glob, new, csv, datetime, types
87 import itertools, mimetypes, StringIO
89 import itertools, mimetypes, StringIO
88
90
89 try: # Python 2.3 compatibility
91 try: # Python 2.3 compatibility
90 import collections
92 import collections
91 except ImportError:
93 except ImportError:
92 deque = list
94 deque = list
93 else:
95 else:
94 deque = collections.deque
96 deque = collections.deque
95
97
96 try: # Python 2.3 compatibility
98 try: # Python 2.3 compatibility
97 set
99 set
98 except NameError:
100 except NameError:
99 import sets
101 import sets
100 set = sets.Set
102 set = sets.Set
101
103
102 try: # Python 2.3 compatibility
104 try: # Python 2.3 compatibility
103 sorted
105 sorted
104 except NameError:
106 except NameError:
105 def sorted(iterator, key=None, reverse=False):
107 def sorted(iterator, key=None, reverse=False):
106 items = list(iterator)
108 items = list(iterator)
107 if key is not None:
109 if key is not None:
108 items.sort(lambda i1, i2: cmp(key(i1), key(i2)))
110 items.sort(lambda i1, i2: cmp(key(i1), key(i2)))
109 else:
111 else:
110 items.sort()
112 items.sort()
111 if reverse:
113 if reverse:
112 items.reverse()
114 items.reverse()
113 return items
115 return items
114
116
115 try:
117 try:
116 import pwd
118 import pwd
117 except ImportError:
119 except ImportError:
118 pwd = None
120 pwd = None
119
121
120 try:
122 try:
121 import grp
123 import grp
122 except ImportError:
124 except ImportError:
123 grp = None
125 grp = None
124
126
125 from IPython.external import simplegeneric
127 from IPython.external import simplegeneric
126
128 from IPython.external import path
127 import path
128
129
129 try:
130 try:
130 from IPython import genutils, generics
131 from IPython import genutils, generics
131 except ImportError:
132 except ImportError:
132 genutils = None
133 genutils = None
133 generics = None
134 generics = None
134
135
135 from IPython import ipapi
136 from IPython import ipapi
136
137
137
138
138 __all__ = [
139 __all__ = [
139 "ifile", "ils", "iglob", "iwalk", "ipwdentry", "ipwd", "igrpentry", "igrp",
140 "ifile", "ils", "iglob", "iwalk", "ipwdentry", "ipwd", "igrpentry", "igrp",
140 "icsv", "ix", "ichain", "isort", "ifilter", "ieval", "ienum",
141 "icsv", "ix", "ichain", "isort", "ifilter", "ieval", "ienum",
141 "ienv", "ihist", "ialias", "icap", "idump", "iless"
142 "ienv", "ihist", "ialias", "icap", "idump", "iless"
142 ]
143 ]
143
144
144
145
145 os.stat_float_times(True) # enable microseconds
146 os.stat_float_times(True) # enable microseconds
146
147
147
148
148 class AttrNamespace(object):
149 class AttrNamespace(object):
149 """
150 """
150 Helper class that is used for providing a namespace for evaluating
151 Helper class that is used for providing a namespace for evaluating
151 expressions containing attribute names of an object.
152 expressions containing attribute names of an object.
152 """
153 """
153 def __init__(self, wrapped):
154 def __init__(self, wrapped):
154 self.wrapped = wrapped
155 self.wrapped = wrapped
155
156
156 def __getitem__(self, name):
157 def __getitem__(self, name):
157 if name == "_":
158 if name == "_":
158 return self.wrapped
159 return self.wrapped
159 try:
160 try:
160 return getattr(self.wrapped, name)
161 return getattr(self.wrapped, name)
161 except AttributeError:
162 except AttributeError:
162 raise KeyError(name)
163 raise KeyError(name)
163
164
164 # Python 2.3 compatibility
165 # Python 2.3 compatibility
165 # use eval workaround to find out which names are used in the
166 # use eval workaround to find out which names are used in the
166 # eval string and put them into the locals. This works for most
167 # eval string and put them into the locals. This works for most
167 # normal uses case, bizarre ones like accessing the locals()
168 # normal uses case, bizarre ones like accessing the locals()
168 # will fail
169 # will fail
169 try:
170 try:
170 eval("_", None, AttrNamespace(None))
171 eval("_", None, AttrNamespace(None))
171 except TypeError:
172 except TypeError:
172 real_eval = eval
173 real_eval = eval
173 def eval(codestring, _globals, _locals):
174 def eval(codestring, _globals, _locals):
174 """
175 """
175 eval(source[, globals[, locals]]) -> value
176 eval(source[, globals[, locals]]) -> value
176
177
177 Evaluate the source in the context of globals and locals.
178 Evaluate the source in the context of globals and locals.
178 The source may be a string representing a Python expression
179 The source may be a string representing a Python expression
179 or a code object as returned by compile().
180 or a code object as returned by compile().
180 The globals must be a dictionary and locals can be any mappping.
181 The globals must be a dictionary and locals can be any mappping.
181
182
182 This function is a workaround for the shortcomings of
183 This function is a workaround for the shortcomings of
183 Python 2.3's eval.
184 Python 2.3's eval.
184 """
185 """
185
186
186 if isinstance(codestring, basestring):
187 if isinstance(codestring, basestring):
187 code = compile(codestring, "_eval", "eval")
188 code = compile(codestring, "_eval", "eval")
188 else:
189 else:
189 code = codestring
190 code = codestring
190 newlocals = {}
191 newlocals = {}
191 for name in code.co_names:
192 for name in code.co_names:
192 try:
193 try:
193 newlocals[name] = _locals[name]
194 newlocals[name] = _locals[name]
194 except KeyError:
195 except KeyError:
195 pass
196 pass
196 return real_eval(code, _globals, newlocals)
197 return real_eval(code, _globals, newlocals)
197
198
198
199
199 noitem = object()
200 noitem = object()
200
201
201
202
202 def item(iterator, index, default=noitem):
203 def item(iterator, index, default=noitem):
203 """
204 """
204 Return the ``index``th item from the iterator ``iterator``.
205 Return the ``index``th item from the iterator ``iterator``.
205 ``index`` must be an integer (negative integers are relative to the
206 ``index`` must be an integer (negative integers are relative to the
206 end (i.e. the last items produced by the iterator)).
207 end (i.e. the last items produced by the iterator)).
207
208
208 If ``default`` is given, this will be the default value when
209 If ``default`` is given, this will be the default value when
209 the iterator doesn't contain an item at this position. Otherwise an
210 the iterator doesn't contain an item at this position. Otherwise an
210 ``IndexError`` will be raised.
211 ``IndexError`` will be raised.
211
212
212 Note that using this function will partially or totally exhaust the
213 Note that using this function will partially or totally exhaust the
213 iterator.
214 iterator.
214 """
215 """
215 i = index
216 i = index
216 if i>=0:
217 if i>=0:
217 for item in iterator:
218 for item in iterator:
218 if not i:
219 if not i:
219 return item
220 return item
220 i -= 1
221 i -= 1
221 else:
222 else:
222 i = -index
223 i = -index
223 cache = deque()
224 cache = deque()
224 for item in iterator:
225 for item in iterator:
225 cache.append(item)
226 cache.append(item)
226 if len(cache)>i:
227 if len(cache)>i:
227 cache.popleft()
228 cache.popleft()
228 if len(cache)==i:
229 if len(cache)==i:
229 return cache.popleft()
230 return cache.popleft()
230 if default is noitem:
231 if default is noitem:
231 raise IndexError(index)
232 raise IndexError(index)
232 else:
233 else:
233 return default
234 return default
234
235
235
236
236 def getglobals(g):
237 def getglobals(g):
237 """
238 """
238 Return the global namespace that is used for expression strings in
239 Return the global namespace that is used for expression strings in
239 ``ifilter`` and others. This is ``g`` or (if ``g`` is ``None``) IPython's
240 ``ifilter`` and others. This is ``g`` or (if ``g`` is ``None``) IPython's
240 user namespace.
241 user namespace.
241 """
242 """
242 if g is None:
243 if g is None:
243 if ipapi is not None:
244 if ipapi is not None:
244 api = ipapi.get()
245 api = ipapi.get()
245 if api is not None:
246 if api is not None:
246 return api.user_ns
247 return api.user_ns
247 return globals()
248 return globals()
248 return g
249 return g
249
250
250
251
251 class Descriptor(object):
252 class Descriptor(object):
252 """
253 """
253 A ``Descriptor`` object is used for describing the attributes of objects.
254 A ``Descriptor`` object is used for describing the attributes of objects.
254 """
255 """
255 def __hash__(self):
256 def __hash__(self):
256 return hash(self.__class__) ^ hash(self.key())
257 return hash(self.__class__) ^ hash(self.key())
257
258
258 def __eq__(self, other):
259 def __eq__(self, other):
259 return self.__class__ is other.__class__ and self.key() == other.key()
260 return self.__class__ is other.__class__ and self.key() == other.key()
260
261
261 def __ne__(self, other):
262 def __ne__(self, other):
262 return self.__class__ is not other.__class__ or self.key() != other.key()
263 return self.__class__ is not other.__class__ or self.key() != other.key()
263
264
264 def key(self):
265 def key(self):
265 pass
266 pass
266
267
267 def name(self):
268 def name(self):
268 """
269 """
269 Return the name of this attribute for display by a ``Display`` object
270 Return the name of this attribute for display by a ``Display`` object
270 (e.g. as a column title).
271 (e.g. as a column title).
271 """
272 """
272 key = self.key()
273 key = self.key()
273 if key is None:
274 if key is None:
274 return "_"
275 return "_"
275 return str(key)
276 return str(key)
276
277
277 def attrtype(self, obj):
278 def attrtype(self, obj):
278 """
279 """
279 Return the type of this attribute (i.e. something like "attribute" or
280 Return the type of this attribute (i.e. something like "attribute" or
280 "method").
281 "method").
281 """
282 """
282
283
283 def valuetype(self, obj):
284 def valuetype(self, obj):
284 """
285 """
285 Return the type of this attribute value of the object ``obj``.
286 Return the type of this attribute value of the object ``obj``.
286 """
287 """
287
288
288 def value(self, obj):
289 def value(self, obj):
289 """
290 """
290 Return the value of this attribute of the object ``obj``.
291 Return the value of this attribute of the object ``obj``.
291 """
292 """
292
293
293 def doc(self, obj):
294 def doc(self, obj):
294 """
295 """
295 Return the documentation for this attribute.
296 Return the documentation for this attribute.
296 """
297 """
297
298
298 def shortdoc(self, obj):
299 def shortdoc(self, obj):
299 """
300 """
300 Return a short documentation for this attribute (defaulting to the
301 Return a short documentation for this attribute (defaulting to the
301 first line).
302 first line).
302 """
303 """
303 doc = self.doc(obj)
304 doc = self.doc(obj)
304 if doc is not None:
305 if doc is not None:
305 doc = doc.strip().splitlines()[0].strip()
306 doc = doc.strip().splitlines()[0].strip()
306 return doc
307 return doc
307
308
308 def iter(self, obj):
309 def iter(self, obj):
309 """
310 """
310 Return an iterator for this attribute of the object ``obj``.
311 Return an iterator for this attribute of the object ``obj``.
311 """
312 """
312 return xiter(self.value(obj))
313 return xiter(self.value(obj))
313
314
314
315
315 class SelfDescriptor(Descriptor):
316 class SelfDescriptor(Descriptor):
316 """
317 """
317 A ``SelfDescriptor`` describes the object itself.
318 A ``SelfDescriptor`` describes the object itself.
318 """
319 """
319 def key(self):
320 def key(self):
320 return None
321 return None
321
322
322 def attrtype(self, obj):
323 def attrtype(self, obj):
323 return "self"
324 return "self"
324
325
325 def valuetype(self, obj):
326 def valuetype(self, obj):
326 return type(obj)
327 return type(obj)
327
328
328 def value(self, obj):
329 def value(self, obj):
329 return obj
330 return obj
330
331
331 def __repr__(self):
332 def __repr__(self):
332 return "Self"
333 return "Self"
333
334
334 selfdescriptor = SelfDescriptor() # there's no need for more than one
335 selfdescriptor = SelfDescriptor() # there's no need for more than one
335
336
336
337
337 class AttributeDescriptor(Descriptor):
338 class AttributeDescriptor(Descriptor):
338 """
339 """
339 An ``AttributeDescriptor`` describes a simple attribute of an object.
340 An ``AttributeDescriptor`` describes a simple attribute of an object.
340 """
341 """
341 __slots__ = ("_name", "_doc")
342 __slots__ = ("_name", "_doc")
342
343
343 def __init__(self, name, doc=None):
344 def __init__(self, name, doc=None):
344 self._name = name
345 self._name = name
345 self._doc = doc
346 self._doc = doc
346
347
347 def key(self):
348 def key(self):
348 return self._name
349 return self._name
349
350
350 def doc(self, obj):
351 def doc(self, obj):
351 return self._doc
352 return self._doc
352
353
353 def attrtype(self, obj):
354 def attrtype(self, obj):
354 return "attr"
355 return "attr"
355
356
356 def valuetype(self, obj):
357 def valuetype(self, obj):
357 return type(getattr(obj, self._name))
358 return type(getattr(obj, self._name))
358
359
359 def value(self, obj):
360 def value(self, obj):
360 return getattr(obj, self._name)
361 return getattr(obj, self._name)
361
362
362 def __repr__(self):
363 def __repr__(self):
363 if self._doc is None:
364 if self._doc is None:
364 return "Attribute(%r)" % self._name
365 return "Attribute(%r)" % self._name
365 else:
366 else:
366 return "Attribute(%r, %r)" % (self._name, self._doc)
367 return "Attribute(%r, %r)" % (self._name, self._doc)
367
368
368
369
369 class IndexDescriptor(Descriptor):
370 class IndexDescriptor(Descriptor):
370 """
371 """
371 An ``IndexDescriptor`` describes an "attribute" of an object that is fetched
372 An ``IndexDescriptor`` describes an "attribute" of an object that is fetched
372 via ``__getitem__``.
373 via ``__getitem__``.
373 """
374 """
374 __slots__ = ("_index",)
375 __slots__ = ("_index",)
375
376
376 def __init__(self, index):
377 def __init__(self, index):
377 self._index = index
378 self._index = index
378
379
379 def key(self):
380 def key(self):
380 return self._index
381 return self._index
381
382
382 def attrtype(self, obj):
383 def attrtype(self, obj):
383 return "item"
384 return "item"
384
385
385 def valuetype(self, obj):
386 def valuetype(self, obj):
386 return type(obj[self._index])
387 return type(obj[self._index])
387
388
388 def value(self, obj):
389 def value(self, obj):
389 return obj[self._index]
390 return obj[self._index]
390
391
391 def __repr__(self):
392 def __repr__(self):
392 return "Index(%r)" % self._index
393 return "Index(%r)" % self._index
393
394
394
395
395 class MethodDescriptor(Descriptor):
396 class MethodDescriptor(Descriptor):
396 """
397 """
397 A ``MethodDescriptor`` describes a method of an object that can be called
398 A ``MethodDescriptor`` describes a method of an object that can be called
398 without argument. Note that this method shouldn't change the object.
399 without argument. Note that this method shouldn't change the object.
399 """
400 """
400 __slots__ = ("_name", "_doc")
401 __slots__ = ("_name", "_doc")
401
402
402 def __init__(self, name, doc=None):
403 def __init__(self, name, doc=None):
403 self._name = name
404 self._name = name
404 self._doc = doc
405 self._doc = doc
405
406
406 def key(self):
407 def key(self):
407 return self._name
408 return self._name
408
409
409 def doc(self, obj):
410 def doc(self, obj):
410 if self._doc is None:
411 if self._doc is None:
411 return getattr(obj, self._name).__doc__
412 return getattr(obj, self._name).__doc__
412 return self._doc
413 return self._doc
413
414
414 def attrtype(self, obj):
415 def attrtype(self, obj):
415 return "method"
416 return "method"
416
417
417 def valuetype(self, obj):
418 def valuetype(self, obj):
418 return type(self.value(obj))
419 return type(self.value(obj))
419
420
420 def value(self, obj):
421 def value(self, obj):
421 return getattr(obj, self._name)()
422 return getattr(obj, self._name)()
422
423
423 def __repr__(self):
424 def __repr__(self):
424 if self._doc is None:
425 if self._doc is None:
425 return "Method(%r)" % self._name
426 return "Method(%r)" % self._name
426 else:
427 else:
427 return "Method(%r, %r)" % (self._name, self._doc)
428 return "Method(%r, %r)" % (self._name, self._doc)
428
429
429
430
430 class IterAttributeDescriptor(Descriptor):
431 class IterAttributeDescriptor(Descriptor):
431 """
432 """
432 An ``IterAttributeDescriptor`` works like an ``AttributeDescriptor`` but
433 An ``IterAttributeDescriptor`` works like an ``AttributeDescriptor`` but
433 doesn't return an attribute values (because this value might be e.g. a large
434 doesn't return an attribute values (because this value might be e.g. a large
434 list).
435 list).
435 """
436 """
436 __slots__ = ("_name", "_doc")
437 __slots__ = ("_name", "_doc")
437
438
438 def __init__(self, name, doc=None):
439 def __init__(self, name, doc=None):
439 self._name = name
440 self._name = name
440 self._doc = doc
441 self._doc = doc
441
442
442 def key(self):
443 def key(self):
443 return self._name
444 return self._name
444
445
445 def doc(self, obj):
446 def doc(self, obj):
446 return self._doc
447 return self._doc
447
448
448 def attrtype(self, obj):
449 def attrtype(self, obj):
449 return "iter"
450 return "iter"
450
451
451 def valuetype(self, obj):
452 def valuetype(self, obj):
452 return noitem
453 return noitem
453
454
454 def value(self, obj):
455 def value(self, obj):
455 return noitem
456 return noitem
456
457
457 def iter(self, obj):
458 def iter(self, obj):
458 return xiter(getattr(obj, self._name))
459 return xiter(getattr(obj, self._name))
459
460
460 def __repr__(self):
461 def __repr__(self):
461 if self._doc is None:
462 if self._doc is None:
462 return "IterAttribute(%r)" % self._name
463 return "IterAttribute(%r)" % self._name
463 else:
464 else:
464 return "IterAttribute(%r, %r)" % (self._name, self._doc)
465 return "IterAttribute(%r, %r)" % (self._name, self._doc)
465
466
466
467
467 class IterMethodDescriptor(Descriptor):
468 class IterMethodDescriptor(Descriptor):
468 """
469 """
469 An ``IterMethodDescriptor`` works like an ``MethodDescriptor`` but doesn't
470 An ``IterMethodDescriptor`` works like an ``MethodDescriptor`` but doesn't
470 return an attribute values (because this value might be e.g. a large list).
471 return an attribute values (because this value might be e.g. a large list).
471 """
472 """
472 __slots__ = ("_name", "_doc")
473 __slots__ = ("_name", "_doc")
473
474
474 def __init__(self, name, doc=None):
475 def __init__(self, name, doc=None):
475 self._name = name
476 self._name = name
476 self._doc = doc
477 self._doc = doc
477
478
478 def key(self):
479 def key(self):
479 return self._name
480 return self._name
480
481
481 def doc(self, obj):
482 def doc(self, obj):
482 if self._doc is None:
483 if self._doc is None:
483 return getattr(obj, self._name).__doc__
484 return getattr(obj, self._name).__doc__
484 return self._doc
485 return self._doc
485
486
486 def attrtype(self, obj):
487 def attrtype(self, obj):
487 return "itermethod"
488 return "itermethod"
488
489
489 def valuetype(self, obj):
490 def valuetype(self, obj):
490 return noitem
491 return noitem
491
492
492 def value(self, obj):
493 def value(self, obj):
493 return noitem
494 return noitem
494
495
495 def iter(self, obj):
496 def iter(self, obj):
496 return xiter(getattr(obj, self._name)())
497 return xiter(getattr(obj, self._name)())
497
498
498 def __repr__(self):
499 def __repr__(self):
499 if self._doc is None:
500 if self._doc is None:
500 return "IterMethod(%r)" % self._name
501 return "IterMethod(%r)" % self._name
501 else:
502 else:
502 return "IterMethod(%r, %r)" % (self._name, self._doc)
503 return "IterMethod(%r, %r)" % (self._name, self._doc)
503
504
504
505
505 class FunctionDescriptor(Descriptor):
506 class FunctionDescriptor(Descriptor):
506 """
507 """
507 A ``FunctionDescriptor`` turns a function into a descriptor. The function
508 A ``FunctionDescriptor`` turns a function into a descriptor. The function
508 will be called with the object to get the type and value of the attribute.
509 will be called with the object to get the type and value of the attribute.
509 """
510 """
510 __slots__ = ("_function", "_name", "_doc")
511 __slots__ = ("_function", "_name", "_doc")
511
512
512 def __init__(self, function, name=None, doc=None):
513 def __init__(self, function, name=None, doc=None):
513 self._function = function
514 self._function = function
514 self._name = name
515 self._name = name
515 self._doc = doc
516 self._doc = doc
516
517
517 def key(self):
518 def key(self):
518 return self._function
519 return self._function
519
520
520 def name(self):
521 def name(self):
521 if self._name is not None:
522 if self._name is not None:
522 return self._name
523 return self._name
523 return getattr(self._function, "__xname__", self._function.__name__)
524 return getattr(self._function, "__xname__", self._function.__name__)
524
525
525 def doc(self, obj):
526 def doc(self, obj):
526 if self._doc is None:
527 if self._doc is None:
527 return self._function.__doc__
528 return self._function.__doc__
528 return self._doc
529 return self._doc
529
530
530 def attrtype(self, obj):
531 def attrtype(self, obj):
531 return "function"
532 return "function"
532
533
533 def valuetype(self, obj):
534 def valuetype(self, obj):
534 return type(self._function(obj))
535 return type(self._function(obj))
535
536
536 def value(self, obj):
537 def value(self, obj):
537 return self._function(obj)
538 return self._function(obj)
538
539
539 def __repr__(self):
540 def __repr__(self):
540 if self._doc is None:
541 if self._doc is None:
541 return "Function(%r)" % self._name
542 return "Function(%r)" % self._name
542 else:
543 else:
543 return "Function(%r, %r)" % (self._name, self._doc)
544 return "Function(%r, %r)" % (self._name, self._doc)
544
545
545
546
546 class Table(object):
547 class Table(object):
547 """
548 """
548 A ``Table`` is an object that produces items (just like a normal Python
549 A ``Table`` is an object that produces items (just like a normal Python
549 iterator/generator does) and can be used as the first object in a pipeline
550 iterator/generator does) and can be used as the first object in a pipeline
550 expression. The displayhook will open the default browser for such an object
551 expression. The displayhook will open the default browser for such an object
551 (instead of simply printing the ``repr()`` result).
552 (instead of simply printing the ``repr()`` result).
552 """
553 """
553
554
554 # We want to support ``foo`` and ``foo()`` in pipeline expression:
555 # We want to support ``foo`` and ``foo()`` in pipeline expression:
555 # So we implement the required operators (``|`` and ``+``) in the metaclass,
556 # So we implement the required operators (``|`` and ``+``) in the metaclass,
556 # instantiate the class and forward the operator to the instance
557 # instantiate the class and forward the operator to the instance
557 class __metaclass__(type):
558 class __metaclass__(type):
558 def __iter__(self):
559 def __iter__(self):
559 return iter(self())
560 return iter(self())
560
561
561 def __or__(self, other):
562 def __or__(self, other):
562 return self() | other
563 return self() | other
563
564
564 def __add__(self, other):
565 def __add__(self, other):
565 return self() + other
566 return self() + other
566
567
567 def __radd__(self, other):
568 def __radd__(self, other):
568 return other + self()
569 return other + self()
569
570
570 def __getitem__(self, index):
571 def __getitem__(self, index):
571 return self()[index]
572 return self()[index]
572
573
573 def __getitem__(self, index):
574 def __getitem__(self, index):
574 return item(self, index)
575 return item(self, index)
575
576
576 def __contains__(self, item):
577 def __contains__(self, item):
577 for haveitem in self:
578 for haveitem in self:
578 if item == haveitem:
579 if item == haveitem:
579 return True
580 return True
580 return False
581 return False
581
582
582 def __or__(self, other):
583 def __or__(self, other):
583 # autoinstantiate right hand side
584 # autoinstantiate right hand side
584 if isinstance(other, type) and issubclass(other, (Table, Display)):
585 if isinstance(other, type) and issubclass(other, (Table, Display)):
585 other = other()
586 other = other()
586 # treat simple strings and functions as ``ieval`` instances
587 # treat simple strings and functions as ``ieval`` instances
587 elif not isinstance(other, Display) and not isinstance(other, Table):
588 elif not isinstance(other, Display) and not isinstance(other, Table):
588 other = ieval(other)
589 other = ieval(other)
589 # forward operations to the right hand side
590 # forward operations to the right hand side
590 return other.__ror__(self)
591 return other.__ror__(self)
591
592
592 def __add__(self, other):
593 def __add__(self, other):
593 # autoinstantiate right hand side
594 # autoinstantiate right hand side
594 if isinstance(other, type) and issubclass(other, Table):
595 if isinstance(other, type) and issubclass(other, Table):
595 other = other()
596 other = other()
596 return ichain(self, other)
597 return ichain(self, other)
597
598
598 def __radd__(self, other):
599 def __radd__(self, other):
599 # autoinstantiate left hand side
600 # autoinstantiate left hand side
600 if isinstance(other, type) and issubclass(other, Table):
601 if isinstance(other, type) and issubclass(other, Table):
601 other = other()
602 other = other()
602 return ichain(other, self)
603 return ichain(other, self)
603
604
604
605
605 class Pipe(Table):
606 class Pipe(Table):
606 """
607 """
607 A ``Pipe`` is an object that can be used in a pipeline expression. It
608 A ``Pipe`` is an object that can be used in a pipeline expression. It
608 processes the objects it gets from its input ``Table``/``Pipe``. Note that
609 processes the objects it gets from its input ``Table``/``Pipe``. Note that
609 a ``Pipe`` object can't be used as the first object in a pipeline
610 a ``Pipe`` object can't be used as the first object in a pipeline
610 expression, as it doesn't produces items itself.
611 expression, as it doesn't produces items itself.
611 """
612 """
612 class __metaclass__(Table.__metaclass__):
613 class __metaclass__(Table.__metaclass__):
613 def __ror__(self, input):
614 def __ror__(self, input):
614 return input | self()
615 return input | self()
615
616
616 def __ror__(self, input):
617 def __ror__(self, input):
617 # autoinstantiate left hand side
618 # autoinstantiate left hand side
618 if isinstance(input, type) and issubclass(input, Table):
619 if isinstance(input, type) and issubclass(input, Table):
619 input = input()
620 input = input()
620 self.input = input
621 self.input = input
621 return self
622 return self
622
623
623
624
624 def xrepr(item, mode="default"):
625 def xrepr(item, mode="default"):
625 """
626 """
626 Generic function that adds color output and different display modes to ``repr``.
627 Generic function that adds color output and different display modes to ``repr``.
627
628
628 The result of an ``xrepr`` call is iterable and consists of ``(style, string)``
629 The result of an ``xrepr`` call is iterable and consists of ``(style, string)``
629 tuples. The ``style`` in this tuple must be a ``Style`` object from the
630 tuples. The ``style`` in this tuple must be a ``Style`` object from the
630 ``astring`` module. To reconfigure the output the first yielded tuple can be
631 ``astring`` module. To reconfigure the output the first yielded tuple can be
631 a ``(aligment, full)`` tuple instead of a ``(style, string)`` tuple.
632 a ``(aligment, full)`` tuple instead of a ``(style, string)`` tuple.
632 ``alignment`` can be -1 for left aligned, 0 for centered and 1 for right
633 ``alignment`` can be -1 for left aligned, 0 for centered and 1 for right
633 aligned (the default is left alignment). ``full`` is a boolean that specifies
634 aligned (the default is left alignment). ``full`` is a boolean that specifies
634 whether the complete output must be displayed or the ``Display`` object is
635 whether the complete output must be displayed or the ``Display`` object is
635 allowed to stop output after enough text has been produced (e.g. a syntax
636 allowed to stop output after enough text has been produced (e.g. a syntax
636 highlighted text line would use ``True``, but for a large data structure
637 highlighted text line would use ``True``, but for a large data structure
637 (i.e. a nested list, tuple or dictionary) ``False`` would be used).
638 (i.e. a nested list, tuple or dictionary) ``False`` would be used).
638 The default is full output.
639 The default is full output.
639
640
640 There are four different possible values for ``mode`` depending on where
641 There are four different possible values for ``mode`` depending on where
641 the ``Display`` object will display ``item``:
642 the ``Display`` object will display ``item``:
642
643
643 ``"header"``
644 ``"header"``
644 ``item`` will be displayed in a header line (this is used by ``ibrowse``).
645 ``item`` will be displayed in a header line (this is used by ``ibrowse``).
645
646
646 ``"footer"``
647 ``"footer"``
647 ``item`` will be displayed in a footer line (this is used by ``ibrowse``).
648 ``item`` will be displayed in a footer line (this is used by ``ibrowse``).
648
649
649 ``"cell"``
650 ``"cell"``
650 ``item`` will be displayed in a table cell/list.
651 ``item`` will be displayed in a table cell/list.
651
652
652 ``"default"``
653 ``"default"``
653 default mode. If an ``xrepr`` implementation recursively outputs objects,
654 default mode. If an ``xrepr`` implementation recursively outputs objects,
654 ``"default"`` must be passed in the recursive calls to ``xrepr``.
655 ``"default"`` must be passed in the recursive calls to ``xrepr``.
655
656
656 If no implementation is registered for ``item``, ``xrepr`` will try the
657 If no implementation is registered for ``item``, ``xrepr`` will try the
657 ``__xrepr__`` method on ``item``. If ``item`` doesn't have an ``__xrepr__``
658 ``__xrepr__`` method on ``item``. If ``item`` doesn't have an ``__xrepr__``
658 method it falls back to ``repr``/``__repr__`` for all modes.
659 method it falls back to ``repr``/``__repr__`` for all modes.
659 """
660 """
660 try:
661 try:
661 func = item.__xrepr__
662 func = item.__xrepr__
662 except AttributeError:
663 except AttributeError:
663 yield (astyle.style_default, repr(item))
664 yield (astyle.style_default, repr(item))
664 else:
665 else:
665 try:
666 try:
666 for x in func(mode):
667 for x in func(mode):
667 yield x
668 yield x
668 except (KeyboardInterrupt, SystemExit):
669 except (KeyboardInterrupt, SystemExit):
669 raise
670 raise
670 except Exception:
671 except Exception:
671 yield (astyle.style_default, repr(item))
672 yield (astyle.style_default, repr(item))
672 xrepr = simplegeneric.generic(xrepr)
673 xrepr = simplegeneric.generic(xrepr)
673
674
674
675
675 def xrepr_none(self, mode="default"):
676 def xrepr_none(self, mode="default"):
676 yield (astyle.style_type_none, repr(self))
677 yield (astyle.style_type_none, repr(self))
677 xrepr.when_object(None)(xrepr_none)
678 xrepr.when_object(None)(xrepr_none)
678
679
679
680
680 def xrepr_noitem(self, mode="default"):
681 def xrepr_noitem(self, mode="default"):
681 yield (2, True)
682 yield (2, True)
682 yield (astyle.style_nodata, "<?>")
683 yield (astyle.style_nodata, "<?>")
683 xrepr.when_object(noitem)(xrepr_noitem)
684 xrepr.when_object(noitem)(xrepr_noitem)
684
685
685
686
686 def xrepr_bool(self, mode="default"):
687 def xrepr_bool(self, mode="default"):
687 yield (astyle.style_type_bool, repr(self))
688 yield (astyle.style_type_bool, repr(self))
688 xrepr.when_type(bool)(xrepr_bool)
689 xrepr.when_type(bool)(xrepr_bool)
689
690
690
691
691 def xrepr_str(self, mode="default"):
692 def xrepr_str(self, mode="default"):
692 if mode == "cell":
693 if mode == "cell":
693 yield (astyle.style_default, repr(self.expandtabs(tab))[1:-1])
694 yield (astyle.style_default, repr(self.expandtabs(tab))[1:-1])
694 else:
695 else:
695 yield (astyle.style_default, repr(self))
696 yield (astyle.style_default, repr(self))
696 xrepr.when_type(str)(xrepr_str)
697 xrepr.when_type(str)(xrepr_str)
697
698
698
699
699 def xrepr_unicode(self, mode="default"):
700 def xrepr_unicode(self, mode="default"):
700 if mode == "cell":
701 if mode == "cell":
701 yield (astyle.style_default, repr(self.expandtabs(tab))[2:-1])
702 yield (astyle.style_default, repr(self.expandtabs(tab))[2:-1])
702 else:
703 else:
703 yield (astyle.style_default, repr(self))
704 yield (astyle.style_default, repr(self))
704 xrepr.when_type(unicode)(xrepr_unicode)
705 xrepr.when_type(unicode)(xrepr_unicode)
705
706
706
707
707 def xrepr_number(self, mode="default"):
708 def xrepr_number(self, mode="default"):
708 yield (1, True)
709 yield (1, True)
709 yield (astyle.style_type_number, repr(self))
710 yield (astyle.style_type_number, repr(self))
710 xrepr.when_type(int)(xrepr_number)
711 xrepr.when_type(int)(xrepr_number)
711 xrepr.when_type(long)(xrepr_number)
712 xrepr.when_type(long)(xrepr_number)
712 xrepr.when_type(float)(xrepr_number)
713 xrepr.when_type(float)(xrepr_number)
713
714
714
715
715 def xrepr_complex(self, mode="default"):
716 def xrepr_complex(self, mode="default"):
716 yield (astyle.style_type_number, repr(self))
717 yield (astyle.style_type_number, repr(self))
717 xrepr.when_type(complex)(xrepr_number)
718 xrepr.when_type(complex)(xrepr_number)
718
719
719
720
720 def xrepr_datetime(self, mode="default"):
721 def xrepr_datetime(self, mode="default"):
721 if mode == "cell":
722 if mode == "cell":
722 # Don't use strftime() here, as this requires year >= 1900
723 # Don't use strftime() here, as this requires year >= 1900
723 yield (astyle.style_type_datetime,
724 yield (astyle.style_type_datetime,
724 "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
725 "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
725 (self.year, self.month, self.day,
726 (self.year, self.month, self.day,
726 self.hour, self.minute, self.second,
727 self.hour, self.minute, self.second,
727 self.microsecond),
728 self.microsecond),
728 )
729 )
729 else:
730 else:
730 yield (astyle.style_type_datetime, repr(self))
731 yield (astyle.style_type_datetime, repr(self))
731 xrepr.when_type(datetime.datetime)(xrepr_datetime)
732 xrepr.when_type(datetime.datetime)(xrepr_datetime)
732
733
733
734
734 def xrepr_date(self, mode="default"):
735 def xrepr_date(self, mode="default"):
735 if mode == "cell":
736 if mode == "cell":
736 yield (astyle.style_type_datetime,
737 yield (astyle.style_type_datetime,
737 "%04d-%02d-%02d" % (self.year, self.month, self.day))
738 "%04d-%02d-%02d" % (self.year, self.month, self.day))
738 else:
739 else:
739 yield (astyle.style_type_datetime, repr(self))
740 yield (astyle.style_type_datetime, repr(self))
740 xrepr.when_type(datetime.date)(xrepr_date)
741 xrepr.when_type(datetime.date)(xrepr_date)
741
742
742
743
743 def xrepr_time(self, mode="default"):
744 def xrepr_time(self, mode="default"):
744 if mode == "cell":
745 if mode == "cell":
745 yield (astyle.style_type_datetime,
746 yield (astyle.style_type_datetime,
746 "%02d:%02d:%02d.%06d" % \
747 "%02d:%02d:%02d.%06d" % \
747 (self.hour, self.minute, self.second, self.microsecond))
748 (self.hour, self.minute, self.second, self.microsecond))
748 else:
749 else:
749 yield (astyle.style_type_datetime, repr(self))
750 yield (astyle.style_type_datetime, repr(self))
750 xrepr.when_type(datetime.time)(xrepr_time)
751 xrepr.when_type(datetime.time)(xrepr_time)
751
752
752
753
753 def xrepr_timedelta(self, mode="default"):
754 def xrepr_timedelta(self, mode="default"):
754 yield (astyle.style_type_datetime, repr(self))
755 yield (astyle.style_type_datetime, repr(self))
755 xrepr.when_type(datetime.timedelta)(xrepr_timedelta)
756 xrepr.when_type(datetime.timedelta)(xrepr_timedelta)
756
757
757
758
758 def xrepr_type(self, mode="default"):
759 def xrepr_type(self, mode="default"):
759 if self.__module__ == "__builtin__":
760 if self.__module__ == "__builtin__":
760 yield (astyle.style_type_type, self.__name__)
761 yield (astyle.style_type_type, self.__name__)
761 else:
762 else:
762 yield (astyle.style_type_type, "%s.%s" % (self.__module__, self.__name__))
763 yield (astyle.style_type_type, "%s.%s" % (self.__module__, self.__name__))
763 xrepr.when_type(type)(xrepr_type)
764 xrepr.when_type(type)(xrepr_type)
764
765
765
766
766 def xrepr_exception(self, mode="default"):
767 def xrepr_exception(self, mode="default"):
767 if self.__class__.__module__ == "exceptions":
768 if self.__class__.__module__ == "exceptions":
768 classname = self.__class__.__name__
769 classname = self.__class__.__name__
769 else:
770 else:
770 classname = "%s.%s" % \
771 classname = "%s.%s" % \
771 (self.__class__.__module__, self.__class__.__name__)
772 (self.__class__.__module__, self.__class__.__name__)
772 if mode == "header" or mode == "footer":
773 if mode == "header" or mode == "footer":
773 yield (astyle.style_error, "%s: %s" % (classname, self))
774 yield (astyle.style_error, "%s: %s" % (classname, self))
774 else:
775 else:
775 yield (astyle.style_error, classname)
776 yield (astyle.style_error, classname)
776 xrepr.when_type(Exception)(xrepr_exception)
777 xrepr.when_type(Exception)(xrepr_exception)
777
778
778
779
779 def xrepr_listtuple(self, mode="default"):
780 def xrepr_listtuple(self, mode="default"):
780 if mode == "header" or mode == "footer":
781 if mode == "header" or mode == "footer":
781 if self.__class__.__module__ == "__builtin__":
782 if self.__class__.__module__ == "__builtin__":
782 classname = self.__class__.__name__
783 classname = self.__class__.__name__
783 else:
784 else:
784 classname = "%s.%s" % \
785 classname = "%s.%s" % \
785 (self.__class__.__module__,self.__class__.__name__)
786 (self.__class__.__module__,self.__class__.__name__)
786 yield (astyle.style_default,
787 yield (astyle.style_default,
787 "<%s object with %d items at 0x%x>" % \
788 "<%s object with %d items at 0x%x>" % \
788 (classname, len(self), id(self)))
789 (classname, len(self), id(self)))
789 else:
790 else:
790 yield (-1, False)
791 yield (-1, False)
791 if isinstance(self, list):
792 if isinstance(self, list):
792 yield (astyle.style_default, "[")
793 yield (astyle.style_default, "[")
793 end = "]"
794 end = "]"
794 else:
795 else:
795 yield (astyle.style_default, "(")
796 yield (astyle.style_default, "(")
796 end = ")"
797 end = ")"
797 for (i, subself) in enumerate(self):
798 for (i, subself) in enumerate(self):
798 if i:
799 if i:
799 yield (astyle.style_default, ", ")
800 yield (astyle.style_default, ", ")
800 for part in xrepr(subself, "default"):
801 for part in xrepr(subself, "default"):
801 yield part
802 yield part
802 yield (astyle.style_default, end)
803 yield (astyle.style_default, end)
803 xrepr.when_type(list)(xrepr_listtuple)
804 xrepr.when_type(list)(xrepr_listtuple)
804 xrepr.when_type(tuple)(xrepr_listtuple)
805 xrepr.when_type(tuple)(xrepr_listtuple)
805
806
806
807
807 def xrepr_dict(self, mode="default"):
808 def xrepr_dict(self, mode="default"):
808 if mode == "header" or mode == "footer":
809 if mode == "header" or mode == "footer":
809 if self.__class__.__module__ == "__builtin__":
810 if self.__class__.__module__ == "__builtin__":
810 classname = self.__class__.__name__
811 classname = self.__class__.__name__
811 else:
812 else:
812 classname = "%s.%s" % \
813 classname = "%s.%s" % \
813 (self.__class__.__module__,self.__class__.__name__)
814 (self.__class__.__module__,self.__class__.__name__)
814 yield (astyle.style_default,
815 yield (astyle.style_default,
815 "<%s object with %d items at 0x%x>" % \
816 "<%s object with %d items at 0x%x>" % \
816 (classname, len(self), id(self)))
817 (classname, len(self), id(self)))
817 else:
818 else:
818 yield (-1, False)
819 yield (-1, False)
819 if isinstance(self, dict):
820 if isinstance(self, dict):
820 yield (astyle.style_default, "{")
821 yield (astyle.style_default, "{")
821 end = "}"
822 end = "}"
822 else:
823 else:
823 yield (astyle.style_default, "dictproxy((")
824 yield (astyle.style_default, "dictproxy((")
824 end = "})"
825 end = "})"
825 for (i, (key, value)) in enumerate(self.iteritems()):
826 for (i, (key, value)) in enumerate(self.iteritems()):
826 if i:
827 if i:
827 yield (astyle.style_default, ", ")
828 yield (astyle.style_default, ", ")
828 for part in xrepr(key, "default"):
829 for part in xrepr(key, "default"):
829 yield part
830 yield part
830 yield (astyle.style_default, ": ")
831 yield (astyle.style_default, ": ")
831 for part in xrepr(value, "default"):
832 for part in xrepr(value, "default"):
832 yield part
833 yield part
833 yield (astyle.style_default, end)
834 yield (astyle.style_default, end)
834 xrepr.when_type(dict)(xrepr_dict)
835 xrepr.when_type(dict)(xrepr_dict)
835 xrepr.when_type(types.DictProxyType)(xrepr_dict)
836 xrepr.when_type(types.DictProxyType)(xrepr_dict)
836
837
837
838
838 def upgradexattr(attr):
839 def upgradexattr(attr):
839 """
840 """
840 Convert an attribute descriptor string to a real descriptor object.
841 Convert an attribute descriptor string to a real descriptor object.
841
842
842 If attr already is a descriptor object return if unmodified. A
843 If attr already is a descriptor object return if unmodified. A
843 ``SelfDescriptor`` will be returned if ``attr`` is ``None``. ``"foo"``
844 ``SelfDescriptor`` will be returned if ``attr`` is ``None``. ``"foo"``
844 returns an ``AttributeDescriptor`` for the attribute named ``"foo"``.
845 returns an ``AttributeDescriptor`` for the attribute named ``"foo"``.
845 ``"foo()"`` returns a ``MethodDescriptor`` for the method named ``"foo"``.
846 ``"foo()"`` returns a ``MethodDescriptor`` for the method named ``"foo"``.
846 ``"-foo"`` will return an ``IterAttributeDescriptor`` for the attribute
847 ``"-foo"`` will return an ``IterAttributeDescriptor`` for the attribute
847 named ``"foo"`` and ``"-foo()"`` will return an ``IterMethodDescriptor``
848 named ``"foo"`` and ``"-foo()"`` will return an ``IterMethodDescriptor``
848 for the method named ``"foo"``. Furthermore integer will return the appropriate
849 for the method named ``"foo"``. Furthermore integer will return the appropriate
849 ``IndexDescriptor`` and callables will return a ``FunctionDescriptor``.
850 ``IndexDescriptor`` and callables will return a ``FunctionDescriptor``.
850 """
851 """
851 if attr is None:
852 if attr is None:
852 return selfdescriptor
853 return selfdescriptor
853 elif isinstance(attr, Descriptor):
854 elif isinstance(attr, Descriptor):
854 return attr
855 return attr
855 elif isinstance(attr, str):
856 elif isinstance(attr, str):
856 if attr.endswith("()"):
857 if attr.endswith("()"):
857 if attr.startswith("-"):
858 if attr.startswith("-"):
858 return IterMethodDescriptor(attr[1:-2])
859 return IterMethodDescriptor(attr[1:-2])
859 else:
860 else:
860 return MethodDescriptor(attr[:-2])
861 return MethodDescriptor(attr[:-2])
861 else:
862 else:
862 if attr.startswith("-"):
863 if attr.startswith("-"):
863 return IterAttributeDescriptor(attr[1:])
864 return IterAttributeDescriptor(attr[1:])
864 else:
865 else:
865 return AttributeDescriptor(attr)
866 return AttributeDescriptor(attr)
866 elif isinstance(attr, (int, long)):
867 elif isinstance(attr, (int, long)):
867 return IndexDescriptor(attr)
868 return IndexDescriptor(attr)
868 elif callable(attr):
869 elif callable(attr):
869 return FunctionDescriptor(attr)
870 return FunctionDescriptor(attr)
870 else:
871 else:
871 raise TypeError("can't handle descriptor %r" % attr)
872 raise TypeError("can't handle descriptor %r" % attr)
872
873
873
874
874 def xattrs(item, mode="default"):
875 def xattrs(item, mode="default"):
875 """
876 """
876 Generic function that returns an iterable of attribute descriptors
877 Generic function that returns an iterable of attribute descriptors
877 to be used for displaying the attributes ob the object ``item`` in display
878 to be used for displaying the attributes ob the object ``item`` in display
878 mode ``mode``.
879 mode ``mode``.
879
880
880 There are two possible modes:
881 There are two possible modes:
881
882
882 ``"detail"``
883 ``"detail"``
883 The ``Display`` object wants to display a detailed list of the object
884 The ``Display`` object wants to display a detailed list of the object
884 attributes.
885 attributes.
885
886
886 ``"default"``
887 ``"default"``
887 The ``Display`` object wants to display the object in a list view.
888 The ``Display`` object wants to display the object in a list view.
888
889
889 If no implementation is registered for the object ``item`` ``xattrs`` falls
890 If no implementation is registered for the object ``item`` ``xattrs`` falls
890 back to trying the ``__xattrs__`` method of the object. If this doesn't
891 back to trying the ``__xattrs__`` method of the object. If this doesn't
891 exist either, ``dir(item)`` is used for ``"detail"`` mode and ``(None,)``
892 exist either, ``dir(item)`` is used for ``"detail"`` mode and ``(None,)``
892 for ``"default"`` mode.
893 for ``"default"`` mode.
893
894
894 The implementation must yield attribute descriptors (see the class
895 The implementation must yield attribute descriptors (see the class
895 ``Descriptor`` for more info). The ``__xattrs__`` method may also return
896 ``Descriptor`` for more info). The ``__xattrs__`` method may also return
896 attribute descriptor strings (and ``None``) which will be converted to real
897 attribute descriptor strings (and ``None``) which will be converted to real
897 descriptors by ``upgradexattr()``.
898 descriptors by ``upgradexattr()``.
898 """
899 """
899 try:
900 try:
900 func = item.__xattrs__
901 func = item.__xattrs__
901 except AttributeError:
902 except AttributeError:
902 if mode == "detail":
903 if mode == "detail":
903 for attrname in dir(item):
904 for attrname in dir(item):
904 yield AttributeDescriptor(attrname)
905 yield AttributeDescriptor(attrname)
905 else:
906 else:
906 yield selfdescriptor
907 yield selfdescriptor
907 else:
908 else:
908 for attr in func(mode):
909 for attr in func(mode):
909 yield upgradexattr(attr)
910 yield upgradexattr(attr)
910 xattrs = simplegeneric.generic(xattrs)
911 xattrs = simplegeneric.generic(xattrs)
911
912
912
913
913 def xattrs_complex(self, mode="default"):
914 def xattrs_complex(self, mode="default"):
914 if mode == "detail":
915 if mode == "detail":
915 return (AttributeDescriptor("real"), AttributeDescriptor("imag"))
916 return (AttributeDescriptor("real"), AttributeDescriptor("imag"))
916 return (selfdescriptor,)
917 return (selfdescriptor,)
917 xattrs.when_type(complex)(xattrs_complex)
918 xattrs.when_type(complex)(xattrs_complex)
918
919
919
920
920 def _isdict(item):
921 def _isdict(item):
921 try:
922 try:
922 itermeth = item.__class__.__iter__
923 itermeth = item.__class__.__iter__
923 except (AttributeError, TypeError):
924 except (AttributeError, TypeError):
924 return False
925 return False
925 return itermeth is dict.__iter__ or itermeth is types.DictProxyType.__iter__
926 return itermeth is dict.__iter__ or itermeth is types.DictProxyType.__iter__
926
927
927
928
928 def _isstr(item):
929 def _isstr(item):
929 if not isinstance(item, basestring):
930 if not isinstance(item, basestring):
930 return False
931 return False
931 try:
932 try:
932 itermeth = item.__class__.__iter__
933 itermeth = item.__class__.__iter__
933 except AttributeError:
934 except AttributeError:
934 return True
935 return True
935 return False # ``__iter__`` has been redefined
936 return False # ``__iter__`` has been redefined
936
937
937
938
938 def xiter(item):
939 def xiter(item):
939 """
940 """
940 Generic function that implements iteration for pipeline expression. If no
941 Generic function that implements iteration for pipeline expression. If no
941 implementation is registered for ``item`` ``xiter`` falls back to ``iter``.
942 implementation is registered for ``item`` ``xiter`` falls back to ``iter``.
942 """
943 """
943 try:
944 try:
944 func = item.__xiter__
945 func = item.__xiter__
945 except AttributeError:
946 except AttributeError:
946 if _isdict(item):
947 if _isdict(item):
947 def items(item):
948 def items(item):
948 fields = ("key", "value")
949 fields = ("key", "value")
949 for (key, value) in item.iteritems():
950 for (key, value) in item.iteritems():
950 yield Fields(fields, key=key, value=value)
951 yield Fields(fields, key=key, value=value)
951 return items(item)
952 return items(item)
952 elif isinstance(item, new.module):
953 elif isinstance(item, new.module):
953 def items(item):
954 def items(item):
954 fields = ("key", "value")
955 fields = ("key", "value")
955 for key in sorted(item.__dict__):
956 for key in sorted(item.__dict__):
956 yield Fields(fields, key=key, value=getattr(item, key))
957 yield Fields(fields, key=key, value=getattr(item, key))
957 return items(item)
958 return items(item)
958 elif _isstr(item):
959 elif _isstr(item):
959 if not item:
960 if not item:
960 raise ValueError("can't enter empty string")
961 raise ValueError("can't enter empty string")
961 lines = item.splitlines()
962 lines = item.splitlines()
962 if len(lines) == 1:
963 if len(lines) == 1:
963 def iterone(item):
964 def iterone(item):
964 yield item
965 yield item
965 return iterone(item)
966 return iterone(item)
966 else:
967 else:
967 return iter(lines)
968 return iter(lines)
968 return iter(item)
969 return iter(item)
969 else:
970 else:
970 return iter(func()) # iter() just to be safe
971 return iter(func()) # iter() just to be safe
971 xiter = simplegeneric.generic(xiter)
972 xiter = simplegeneric.generic(xiter)
972
973
973
974
974 class ichain(Pipe):
975 class ichain(Pipe):
975 """
976 """
976 Chains multiple ``Table``s into one.
977 Chains multiple ``Table``s into one.
977 """
978 """
978
979
979 def __init__(self, *iters):
980 def __init__(self, *iters):
980 self.iters = iters
981 self.iters = iters
981
982
982 def __iter__(self):
983 def __iter__(self):
983 return itertools.chain(*self.iters)
984 return itertools.chain(*self.iters)
984
985
985 def __xrepr__(self, mode="default"):
986 def __xrepr__(self, mode="default"):
986 if mode == "header" or mode == "footer":
987 if mode == "header" or mode == "footer":
987 for (i, item) in enumerate(self.iters):
988 for (i, item) in enumerate(self.iters):
988 if i:
989 if i:
989 yield (astyle.style_default, "+")
990 yield (astyle.style_default, "+")
990 if isinstance(item, Pipe):
991 if isinstance(item, Pipe):
991 yield (astyle.style_default, "(")
992 yield (astyle.style_default, "(")
992 for part in xrepr(item, mode):
993 for part in xrepr(item, mode):
993 yield part
994 yield part
994 if isinstance(item, Pipe):
995 if isinstance(item, Pipe):
995 yield (astyle.style_default, ")")
996 yield (astyle.style_default, ")")
996 else:
997 else:
997 yield (astyle.style_default, repr(self))
998 yield (astyle.style_default, repr(self))
998
999
999 def __repr__(self):
1000 def __repr__(self):
1000 args = ", ".join([repr(it) for it in self.iters])
1001 args = ", ".join([repr(it) for it in self.iters])
1001 return "%s.%s(%s)" % \
1002 return "%s.%s(%s)" % \
1002 (self.__class__.__module__, self.__class__.__name__, args)
1003 (self.__class__.__module__, self.__class__.__name__, args)
1003
1004
1004
1005
1005 class ifile(path.path):
1006 class ifile(path.path):
1006 """
1007 """
1007 file (or directory) object.
1008 file (or directory) object.
1008 """
1009 """
1009
1010
1010 def getmode(self):
1011 def getmode(self):
1011 return self.stat().st_mode
1012 return self.stat().st_mode
1012 mode = property(getmode, None, None, "Access mode")
1013 mode = property(getmode, None, None, "Access mode")
1013
1014
1014 def gettype(self):
1015 def gettype(self):
1015 data = [
1016 data = [
1016 (stat.S_ISREG, "file"),
1017 (stat.S_ISREG, "file"),
1017 (stat.S_ISDIR, "dir"),
1018 (stat.S_ISDIR, "dir"),
1018 (stat.S_ISCHR, "chardev"),
1019 (stat.S_ISCHR, "chardev"),
1019 (stat.S_ISBLK, "blockdev"),
1020 (stat.S_ISBLK, "blockdev"),
1020 (stat.S_ISFIFO, "fifo"),
1021 (stat.S_ISFIFO, "fifo"),
1021 (stat.S_ISLNK, "symlink"),
1022 (stat.S_ISLNK, "symlink"),
1022 (stat.S_ISSOCK,"socket"),
1023 (stat.S_ISSOCK,"socket"),
1023 ]
1024 ]
1024 lstat = self.lstat()
1025 lstat = self.lstat()
1025 if lstat is not None:
1026 if lstat is not None:
1026 types = set([text for (func, text) in data if func(lstat.st_mode)])
1027 types = set([text for (func, text) in data if func(lstat.st_mode)])
1027 else:
1028 else:
1028 types = set()
1029 types = set()
1029 m = self.mode
1030 m = self.mode
1030 types.update([text for (func, text) in data if func(m)])
1031 types.update([text for (func, text) in data if func(m)])
1031 return ", ".join(types)
1032 return ", ".join(types)
1032 type = property(gettype, None, None, "file type (file, directory, link, etc.)")
1033 type = property(gettype, None, None, "file type (file, directory, link, etc.)")
1033
1034
1034 def getmodestr(self):
1035 def getmodestr(self):
1035 m = self.mode
1036 m = self.mode
1036 data = [
1037 data = [
1037 (stat.S_IRUSR, "-r"),
1038 (stat.S_IRUSR, "-r"),
1038 (stat.S_IWUSR, "-w"),
1039 (stat.S_IWUSR, "-w"),
1039 (stat.S_IXUSR, "-x"),
1040 (stat.S_IXUSR, "-x"),
1040 (stat.S_IRGRP, "-r"),
1041 (stat.S_IRGRP, "-r"),
1041 (stat.S_IWGRP, "-w"),
1042 (stat.S_IWGRP, "-w"),
1042 (stat.S_IXGRP, "-x"),
1043 (stat.S_IXGRP, "-x"),
1043 (stat.S_IROTH, "-r"),
1044 (stat.S_IROTH, "-r"),
1044 (stat.S_IWOTH, "-w"),
1045 (stat.S_IWOTH, "-w"),
1045 (stat.S_IXOTH, "-x"),
1046 (stat.S_IXOTH, "-x"),
1046 ]
1047 ]
1047 return "".join([text[bool(m&bit)] for (bit, text) in data])
1048 return "".join([text[bool(m&bit)] for (bit, text) in data])
1048
1049
1049 modestr = property(getmodestr, None, None, "Access mode as string")
1050 modestr = property(getmodestr, None, None, "Access mode as string")
1050
1051
1051 def getblocks(self):
1052 def getblocks(self):
1052 return self.stat().st_blocks
1053 return self.stat().st_blocks
1053 blocks = property(getblocks, None, None, "File size in blocks")
1054 blocks = property(getblocks, None, None, "File size in blocks")
1054
1055
1055 def getblksize(self):
1056 def getblksize(self):
1056 return self.stat().st_blksize
1057 return self.stat().st_blksize
1057 blksize = property(getblksize, None, None, "Filesystem block size")
1058 blksize = property(getblksize, None, None, "Filesystem block size")
1058
1059
1059 def getdev(self):
1060 def getdev(self):
1060 return self.stat().st_dev
1061 return self.stat().st_dev
1061 dev = property(getdev)
1062 dev = property(getdev)
1062
1063
1063 def getnlink(self):
1064 def getnlink(self):
1064 return self.stat().st_nlink
1065 return self.stat().st_nlink
1065 nlink = property(getnlink, None, None, "Number of links")
1066 nlink = property(getnlink, None, None, "Number of links")
1066
1067
1067 def getuid(self):
1068 def getuid(self):
1068 return self.stat().st_uid
1069 return self.stat().st_uid
1069 uid = property(getuid, None, None, "User id of file owner")
1070 uid = property(getuid, None, None, "User id of file owner")
1070
1071
1071 def getgid(self):
1072 def getgid(self):
1072 return self.stat().st_gid
1073 return self.stat().st_gid
1073 gid = property(getgid, None, None, "Group id of file owner")
1074 gid = property(getgid, None, None, "Group id of file owner")
1074
1075
1075 def getowner(self):
1076 def getowner(self):
1076 stat = self.stat()
1077 stat = self.stat()
1077 try:
1078 try:
1078 return pwd.getpwuid(stat.st_uid).pw_name
1079 return pwd.getpwuid(stat.st_uid).pw_name
1079 except KeyError:
1080 except KeyError:
1080 return stat.st_uid
1081 return stat.st_uid
1081 owner = property(getowner, None, None, "Owner name (or id)")
1082 owner = property(getowner, None, None, "Owner name (or id)")
1082
1083
1083 def getgroup(self):
1084 def getgroup(self):
1084 stat = self.stat()
1085 stat = self.stat()
1085 try:
1086 try:
1086 return grp.getgrgid(stat.st_gid).gr_name
1087 return grp.getgrgid(stat.st_gid).gr_name
1087 except KeyError:
1088 except KeyError:
1088 return stat.st_gid
1089 return stat.st_gid
1089 group = property(getgroup, None, None, "Group name (or id)")
1090 group = property(getgroup, None, None, "Group name (or id)")
1090
1091
1091 def getadate(self):
1092 def getadate(self):
1092 return datetime.datetime.utcfromtimestamp(self.atime)
1093 return datetime.datetime.utcfromtimestamp(self.atime)
1093 adate = property(getadate, None, None, "Access date")
1094 adate = property(getadate, None, None, "Access date")
1094
1095
1095 def getcdate(self):
1096 def getcdate(self):
1096 return datetime.datetime.utcfromtimestamp(self.ctime)
1097 return datetime.datetime.utcfromtimestamp(self.ctime)
1097 cdate = property(getcdate, None, None, "Creation date")
1098 cdate = property(getcdate, None, None, "Creation date")
1098
1099
1099 def getmdate(self):
1100 def getmdate(self):
1100 return datetime.datetime.utcfromtimestamp(self.mtime)
1101 return datetime.datetime.utcfromtimestamp(self.mtime)
1101 mdate = property(getmdate, None, None, "Modification date")
1102 mdate = property(getmdate, None, None, "Modification date")
1102
1103
1103 def mimetype(self):
1104 def mimetype(self):
1104 """
1105 """
1105 Return MIME type guessed from the extension.
1106 Return MIME type guessed from the extension.
1106 """
1107 """
1107 return mimetypes.guess_type(self.basename())[0]
1108 return mimetypes.guess_type(self.basename())[0]
1108
1109
1109 def encoding(self):
1110 def encoding(self):
1110 """
1111 """
1111 Return guessed compression (like "compress" or "gzip").
1112 Return guessed compression (like "compress" or "gzip").
1112 """
1113 """
1113 return mimetypes.guess_type(self.basename())[1]
1114 return mimetypes.guess_type(self.basename())[1]
1114
1115
1115 def __repr__(self):
1116 def __repr__(self):
1116 return "ifile(%s)" % path._base.__repr__(self)
1117 return "ifile(%s)" % path._base.__repr__(self)
1117
1118
1118 if sys.platform == "win32":
1119 if sys.platform == "win32":
1119 defaultattrs = (None, "type", "size", "modestr", "mdate")
1120 defaultattrs = (None, "type", "size", "modestr", "mdate")
1120 else:
1121 else:
1121 defaultattrs = (None, "type", "size", "modestr", "owner", "group", "mdate")
1122 defaultattrs = (None, "type", "size", "modestr", "owner", "group", "mdate")
1122
1123
1123 def __xattrs__(self, mode="default"):
1124 def __xattrs__(self, mode="default"):
1124 if mode == "detail":
1125 if mode == "detail":
1125 return (
1126 return (
1126 "name",
1127 "name",
1127 "basename()",
1128 "basename()",
1128 "abspath()",
1129 "abspath()",
1129 "realpath()",
1130 "realpath()",
1130 "type",
1131 "type",
1131 "mode",
1132 "mode",
1132 "modestr",
1133 "modestr",
1133 "stat()",
1134 "stat()",
1134 "lstat()",
1135 "lstat()",
1135 "uid",
1136 "uid",
1136 "gid",
1137 "gid",
1137 "owner",
1138 "owner",
1138 "group",
1139 "group",
1139 "dev",
1140 "dev",
1140 "nlink",
1141 "nlink",
1141 "ctime",
1142 "ctime",
1142 "mtime",
1143 "mtime",
1143 "atime",
1144 "atime",
1144 "cdate",
1145 "cdate",
1145 "mdate",
1146 "mdate",
1146 "adate",
1147 "adate",
1147 "size",
1148 "size",
1148 "blocks",
1149 "blocks",
1149 "blksize",
1150 "blksize",
1150 "isdir()",
1151 "isdir()",
1151 "islink()",
1152 "islink()",
1152 "mimetype()",
1153 "mimetype()",
1153 "encoding()",
1154 "encoding()",
1154 "-listdir()",
1155 "-listdir()",
1155 "-dirs()",
1156 "-dirs()",
1156 "-files()",
1157 "-files()",
1157 "-walk()",
1158 "-walk()",
1158 "-walkdirs()",
1159 "-walkdirs()",
1159 "-walkfiles()",
1160 "-walkfiles()",
1160 )
1161 )
1161 else:
1162 else:
1162 return self.defaultattrs
1163 return self.defaultattrs
1163
1164
1164
1165
1165 def xiter_ifile(self):
1166 def xiter_ifile(self):
1166 if self.isdir():
1167 if self.isdir():
1167 yield (self / os.pardir).abspath()
1168 yield (self / os.pardir).abspath()
1168 for child in sorted(self.listdir()):
1169 for child in sorted(self.listdir()):
1169 yield child
1170 yield child
1170 else:
1171 else:
1171 f = self.open("rb")
1172 f = self.open("rb")
1172 for line in f:
1173 for line in f:
1173 yield line
1174 yield line
1174 f.close()
1175 f.close()
1175 xiter.when_type(ifile)(xiter_ifile)
1176 xiter.when_type(ifile)(xiter_ifile)
1176
1177
1177
1178
1178 # We need to implement ``xrepr`` for ``ifile`` as a generic function, because
1179 # We need to implement ``xrepr`` for ``ifile`` as a generic function, because
1179 # otherwise ``xrepr_str`` would kick in.
1180 # otherwise ``xrepr_str`` would kick in.
1180 def xrepr_ifile(self, mode="default"):
1181 def xrepr_ifile(self, mode="default"):
1181 try:
1182 try:
1182 if self.isdir():
1183 if self.isdir():
1183 name = "idir"
1184 name = "idir"
1184 style = astyle.style_dir
1185 style = astyle.style_dir
1185 else:
1186 else:
1186 name = "ifile"
1187 name = "ifile"
1187 style = astyle.style_file
1188 style = astyle.style_file
1188 except IOError:
1189 except IOError:
1189 name = "ifile"
1190 name = "ifile"
1190 style = astyle.style_default
1191 style = astyle.style_default
1191 if mode in ("cell", "header", "footer"):
1192 if mode in ("cell", "header", "footer"):
1192 abspath = repr(path._base(self.normpath()))
1193 abspath = repr(path._base(self.normpath()))
1193 if abspath.startswith("u"):
1194 if abspath.startswith("u"):
1194 abspath = abspath[2:-1]
1195 abspath = abspath[2:-1]
1195 else:
1196 else:
1196 abspath = abspath[1:-1]
1197 abspath = abspath[1:-1]
1197 if mode == "cell":
1198 if mode == "cell":
1198 yield (style, abspath)
1199 yield (style, abspath)
1199 else:
1200 else:
1200 yield (style, "%s(%s)" % (name, abspath))
1201 yield (style, "%s(%s)" % (name, abspath))
1201 else:
1202 else:
1202 yield (style, repr(self))
1203 yield (style, repr(self))
1203 xrepr.when_type(ifile)(xrepr_ifile)
1204 xrepr.when_type(ifile)(xrepr_ifile)
1204
1205
1205
1206
1206 class ils(Table):
1207 class ils(Table):
1207 """
1208 """
1208 List the current (or a specified) directory.
1209 List the current (or a specified) directory.
1209
1210
1210 Examples::
1211 Examples::
1211
1212
1212 >>> ils
1213 >>> ils
1214 <class 'IPython.Extensions.ipipe.ils'>
1213 >>> ils("/usr/local/lib/python2.4")
1215 >>> ils("/usr/local/lib/python2.4")
1216 IPython.Extensions.ipipe.ils('/usr/local/lib/python2.4')
1214 >>> ils("~")
1217 >>> ils("~")
1218 IPython.Extensions.ipipe.ils('/home/fperez')
1219 # all-random
1215 """
1220 """
1216 def __init__(self, base=os.curdir, dirs=True, files=True):
1221 def __init__(self, base=os.curdir, dirs=True, files=True):
1217 self.base = os.path.expanduser(base)
1222 self.base = os.path.expanduser(base)
1218 self.dirs = dirs
1223 self.dirs = dirs
1219 self.files = files
1224 self.files = files
1220
1225
1221 def __iter__(self):
1226 def __iter__(self):
1222 base = ifile(self.base)
1227 base = ifile(self.base)
1223 yield (base / os.pardir).abspath()
1228 yield (base / os.pardir).abspath()
1224 for child in sorted(base.listdir()):
1229 for child in sorted(base.listdir()):
1225 if self.dirs:
1230 if self.dirs:
1226 if self.files:
1231 if self.files:
1227 yield child
1232 yield child
1228 else:
1233 else:
1229 if child.isdir():
1234 if child.isdir():
1230 yield child
1235 yield child
1231 elif self.files:
1236 elif self.files:
1232 if not child.isdir():
1237 if not child.isdir():
1233 yield child
1238 yield child
1234
1239
1235 def __xrepr__(self, mode="default"):
1240 def __xrepr__(self, mode="default"):
1236 return xrepr(ifile(self.base), mode)
1241 return xrepr(ifile(self.base), mode)
1237
1242
1238 def __repr__(self):
1243 def __repr__(self):
1239 return "%s.%s(%r)" % \
1244 return "%s.%s(%r)" % \
1240 (self.__class__.__module__, self.__class__.__name__, self.base)
1245 (self.__class__.__module__, self.__class__.__name__, self.base)
1241
1246
1242
1247
1243 class iglob(Table):
1248 class iglob(Table):
1244 """
1249 """
1245 List all files and directories matching a specified pattern.
1250 List all files and directories matching a specified pattern.
1246 (See ``glob.glob()`` for more info.).
1251 (See ``glob.glob()`` for more info.).
1247
1252
1248 Examples::
1253 Examples::
1249
1254
1250 >>> iglob("*.py")
1255 >>> iglob("*.py")
1256 IPython.Extensions.ipipe.iglob('*.py')
1251 """
1257 """
1252 def __init__(self, glob):
1258 def __init__(self, glob):
1253 self.glob = glob
1259 self.glob = glob
1254
1260
1255 def __iter__(self):
1261 def __iter__(self):
1256 for name in glob.glob(self.glob):
1262 for name in glob.glob(self.glob):
1257 yield ifile(name)
1263 yield ifile(name)
1258
1264
1259 def __xrepr__(self, mode="default"):
1265 def __xrepr__(self, mode="default"):
1260 if mode == "header" or mode == "footer" or mode == "cell":
1266 if mode == "header" or mode == "footer" or mode == "cell":
1261 yield (astyle.style_default,
1267 yield (astyle.style_default,
1262 "%s(%r)" % (self.__class__.__name__, self.glob))
1268 "%s(%r)" % (self.__class__.__name__, self.glob))
1263 else:
1269 else:
1264 yield (astyle.style_default, repr(self))
1270 yield (astyle.style_default, repr(self))
1265
1271
1266 def __repr__(self):
1272 def __repr__(self):
1267 return "%s.%s(%r)" % \
1273 return "%s.%s(%r)" % \
1268 (self.__class__.__module__, self.__class__.__name__, self.glob)
1274 (self.__class__.__module__, self.__class__.__name__, self.glob)
1269
1275
1270
1276
1271 class iwalk(Table):
1277 class iwalk(Table):
1272 """
1278 """
1273 List all files and directories in a directory and it's subdirectory::
1279 List all files and directories in a directory and it's subdirectory::
1274
1280
1275 >>> iwalk
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 >>> iwalk("~")
1285 >>> iwalk("~")
1286 IPython.Extensions.ipipe.iwalk('/home/fperez') # random
1287
1278 """
1288 """
1279 def __init__(self, base=os.curdir, dirs=True, files=True):
1289 def __init__(self, base=os.curdir, dirs=True, files=True):
1280 self.base = os.path.expanduser(base)
1290 self.base = os.path.expanduser(base)
1281 self.dirs = dirs
1291 self.dirs = dirs
1282 self.files = files
1292 self.files = files
1283
1293
1284 def __iter__(self):
1294 def __iter__(self):
1285 for (dirpath, dirnames, filenames) in os.walk(self.base):
1295 for (dirpath, dirnames, filenames) in os.walk(self.base):
1286 if self.dirs:
1296 if self.dirs:
1287 for name in sorted(dirnames):
1297 for name in sorted(dirnames):
1288 yield ifile(os.path.join(dirpath, name))
1298 yield ifile(os.path.join(dirpath, name))
1289 if self.files:
1299 if self.files:
1290 for name in sorted(filenames):
1300 for name in sorted(filenames):
1291 yield ifile(os.path.join(dirpath, name))
1301 yield ifile(os.path.join(dirpath, name))
1292
1302
1293 def __xrepr__(self, mode="default"):
1303 def __xrepr__(self, mode="default"):
1294 if mode == "header" or mode == "footer" or mode == "cell":
1304 if mode == "header" or mode == "footer" or mode == "cell":
1295 yield (astyle.style_default,
1305 yield (astyle.style_default,
1296 "%s(%r)" % (self.__class__.__name__, self.base))
1306 "%s(%r)" % (self.__class__.__name__, self.base))
1297 else:
1307 else:
1298 yield (astyle.style_default, repr(self))
1308 yield (astyle.style_default, repr(self))
1299
1309
1300 def __repr__(self):
1310 def __repr__(self):
1301 return "%s.%s(%r)" % \
1311 return "%s.%s(%r)" % \
1302 (self.__class__.__module__, self.__class__.__name__, self.base)
1312 (self.__class__.__module__, self.__class__.__name__, self.base)
1303
1313
1304
1314
1305 class ipwdentry(object):
1315 class ipwdentry(object):
1306 """
1316 """
1307 ``ipwdentry`` objects encapsulate entries in the Unix user account and
1317 ``ipwdentry`` objects encapsulate entries in the Unix user account and
1308 password database.
1318 password database.
1309 """
1319 """
1310 def __init__(self, id):
1320 def __init__(self, id):
1311 self._id = id
1321 self._id = id
1312 self._entry = None
1322 self._entry = None
1313
1323
1314 def __eq__(self, other):
1324 def __eq__(self, other):
1315 return self.__class__ is other.__class__ and self._id == other._id
1325 return self.__class__ is other.__class__ and self._id == other._id
1316
1326
1317 def __ne__(self, other):
1327 def __ne__(self, other):
1318 return self.__class__ is not other.__class__ or self._id != other._id
1328 return self.__class__ is not other.__class__ or self._id != other._id
1319
1329
1320 def _getentry(self):
1330 def _getentry(self):
1321 if self._entry is None:
1331 if self._entry is None:
1322 if isinstance(self._id, basestring):
1332 if isinstance(self._id, basestring):
1323 self._entry = pwd.getpwnam(self._id)
1333 self._entry = pwd.getpwnam(self._id)
1324 else:
1334 else:
1325 self._entry = pwd.getpwuid(self._id)
1335 self._entry = pwd.getpwuid(self._id)
1326 return self._entry
1336 return self._entry
1327
1337
1328 def getname(self):
1338 def getname(self):
1329 if isinstance(self._id, basestring):
1339 if isinstance(self._id, basestring):
1330 return self._id
1340 return self._id
1331 else:
1341 else:
1332 return self._getentry().pw_name
1342 return self._getentry().pw_name
1333 name = property(getname, None, None, "User name")
1343 name = property(getname, None, None, "User name")
1334
1344
1335 def getpasswd(self):
1345 def getpasswd(self):
1336 return self._getentry().pw_passwd
1346 return self._getentry().pw_passwd
1337 passwd = property(getpasswd, None, None, "Password")
1347 passwd = property(getpasswd, None, None, "Password")
1338
1348
1339 def getuid(self):
1349 def getuid(self):
1340 if isinstance(self._id, basestring):
1350 if isinstance(self._id, basestring):
1341 return self._getentry().pw_uid
1351 return self._getentry().pw_uid
1342 else:
1352 else:
1343 return self._id
1353 return self._id
1344 uid = property(getuid, None, None, "User id")
1354 uid = property(getuid, None, None, "User id")
1345
1355
1346 def getgid(self):
1356 def getgid(self):
1347 return self._getentry().pw_gid
1357 return self._getentry().pw_gid
1348 gid = property(getgid, None, None, "Primary group id")
1358 gid = property(getgid, None, None, "Primary group id")
1349
1359
1350 def getgroup(self):
1360 def getgroup(self):
1351 return igrpentry(self.gid)
1361 return igrpentry(self.gid)
1352 group = property(getgroup, None, None, "Group")
1362 group = property(getgroup, None, None, "Group")
1353
1363
1354 def getgecos(self):
1364 def getgecos(self):
1355 return self._getentry().pw_gecos
1365 return self._getentry().pw_gecos
1356 gecos = property(getgecos, None, None, "Information (e.g. full user name)")
1366 gecos = property(getgecos, None, None, "Information (e.g. full user name)")
1357
1367
1358 def getdir(self):
1368 def getdir(self):
1359 return self._getentry().pw_dir
1369 return self._getentry().pw_dir
1360 dir = property(getdir, None, None, "$HOME directory")
1370 dir = property(getdir, None, None, "$HOME directory")
1361
1371
1362 def getshell(self):
1372 def getshell(self):
1363 return self._getentry().pw_shell
1373 return self._getentry().pw_shell
1364 shell = property(getshell, None, None, "Login shell")
1374 shell = property(getshell, None, None, "Login shell")
1365
1375
1366 def __xattrs__(self, mode="default"):
1376 def __xattrs__(self, mode="default"):
1367 return ("name", "passwd", "uid", "gid", "gecos", "dir", "shell")
1377 return ("name", "passwd", "uid", "gid", "gecos", "dir", "shell")
1368
1378
1369 def __repr__(self):
1379 def __repr__(self):
1370 return "%s.%s(%r)" % \
1380 return "%s.%s(%r)" % \
1371 (self.__class__.__module__, self.__class__.__name__, self._id)
1381 (self.__class__.__module__, self.__class__.__name__, self._id)
1372
1382
1373
1383
1374 class ipwd(Table):
1384 class ipwd(Table):
1375 """
1385 """
1376 List all entries in the Unix user account and password database.
1386 List all entries in the Unix user account and password database.
1377
1387
1378 Example::
1388 Example::
1379
1389
1380 >>> ipwd | isort("uid")
1390 >>> ipwd | isort("uid")
1391 <IPython.Extensions.ipipe.isort key='uid' reverse=False at 0x849efec>
1392 # random
1381 """
1393 """
1382 def __iter__(self):
1394 def __iter__(self):
1383 for entry in pwd.getpwall():
1395 for entry in pwd.getpwall():
1384 yield ipwdentry(entry.pw_name)
1396 yield ipwdentry(entry.pw_name)
1385
1397
1386 def __xrepr__(self, mode="default"):
1398 def __xrepr__(self, mode="default"):
1387 if mode == "header" or mode == "footer" or mode == "cell":
1399 if mode == "header" or mode == "footer" or mode == "cell":
1388 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1400 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1389 else:
1401 else:
1390 yield (astyle.style_default, repr(self))
1402 yield (astyle.style_default, repr(self))
1391
1403
1392
1404
1393 class igrpentry(object):
1405 class igrpentry(object):
1394 """
1406 """
1395 ``igrpentry`` objects encapsulate entries in the Unix group database.
1407 ``igrpentry`` objects encapsulate entries in the Unix group database.
1396 """
1408 """
1397 def __init__(self, id):
1409 def __init__(self, id):
1398 self._id = id
1410 self._id = id
1399 self._entry = None
1411 self._entry = None
1400
1412
1401 def __eq__(self, other):
1413 def __eq__(self, other):
1402 return self.__class__ is other.__class__ and self._id == other._id
1414 return self.__class__ is other.__class__ and self._id == other._id
1403
1415
1404 def __ne__(self, other):
1416 def __ne__(self, other):
1405 return self.__class__ is not other.__class__ or self._id != other._id
1417 return self.__class__ is not other.__class__ or self._id != other._id
1406
1418
1407 def _getentry(self):
1419 def _getentry(self):
1408 if self._entry is None:
1420 if self._entry is None:
1409 if isinstance(self._id, basestring):
1421 if isinstance(self._id, basestring):
1410 self._entry = grp.getgrnam(self._id)
1422 self._entry = grp.getgrnam(self._id)
1411 else:
1423 else:
1412 self._entry = grp.getgrgid(self._id)
1424 self._entry = grp.getgrgid(self._id)
1413 return self._entry
1425 return self._entry
1414
1426
1415 def getname(self):
1427 def getname(self):
1416 if isinstance(self._id, basestring):
1428 if isinstance(self._id, basestring):
1417 return self._id
1429 return self._id
1418 else:
1430 else:
1419 return self._getentry().gr_name
1431 return self._getentry().gr_name
1420 name = property(getname, None, None, "Group name")
1432 name = property(getname, None, None, "Group name")
1421
1433
1422 def getpasswd(self):
1434 def getpasswd(self):
1423 return self._getentry().gr_passwd
1435 return self._getentry().gr_passwd
1424 passwd = property(getpasswd, None, None, "Password")
1436 passwd = property(getpasswd, None, None, "Password")
1425
1437
1426 def getgid(self):
1438 def getgid(self):
1427 if isinstance(self._id, basestring):
1439 if isinstance(self._id, basestring):
1428 return self._getentry().gr_gid
1440 return self._getentry().gr_gid
1429 else:
1441 else:
1430 return self._id
1442 return self._id
1431 gid = property(getgid, None, None, "Group id")
1443 gid = property(getgid, None, None, "Group id")
1432
1444
1433 def getmem(self):
1445 def getmem(self):
1434 return self._getentry().gr_mem
1446 return self._getentry().gr_mem
1435 mem = property(getmem, None, None, "Members")
1447 mem = property(getmem, None, None, "Members")
1436
1448
1437 def __xattrs__(self, mode="default"):
1449 def __xattrs__(self, mode="default"):
1438 return ("name", "passwd", "gid", "mem")
1450 return ("name", "passwd", "gid", "mem")
1439
1451
1440 def __xrepr__(self, mode="default"):
1452 def __xrepr__(self, mode="default"):
1441 if mode == "header" or mode == "footer" or mode == "cell":
1453 if mode == "header" or mode == "footer" or mode == "cell":
1442 yield (astyle.style_default, "group ")
1454 yield (astyle.style_default, "group ")
1443 try:
1455 try:
1444 yield (astyle.style_default, self.name)
1456 yield (astyle.style_default, self.name)
1445 except KeyError:
1457 except KeyError:
1446 if isinstance(self._id, basestring):
1458 if isinstance(self._id, basestring):
1447 yield (astyle.style_default, self.name_id)
1459 yield (astyle.style_default, self.name_id)
1448 else:
1460 else:
1449 yield (astyle.style_type_number, str(self._id))
1461 yield (astyle.style_type_number, str(self._id))
1450 else:
1462 else:
1451 yield (astyle.style_default, repr(self))
1463 yield (astyle.style_default, repr(self))
1452
1464
1453 def __iter__(self):
1465 def __iter__(self):
1454 for member in self.mem:
1466 for member in self.mem:
1455 yield ipwdentry(member)
1467 yield ipwdentry(member)
1456
1468
1457 def __repr__(self):
1469 def __repr__(self):
1458 return "%s.%s(%r)" % \
1470 return "%s.%s(%r)" % \
1459 (self.__class__.__module__, self.__class__.__name__, self._id)
1471 (self.__class__.__module__, self.__class__.__name__, self._id)
1460
1472
1461
1473
1462 class igrp(Table):
1474 class igrp(Table):
1463 """
1475 """
1464 This ``Table`` lists all entries in the Unix group database.
1476 This ``Table`` lists all entries in the Unix group database.
1465 """
1477 """
1466 def __iter__(self):
1478 def __iter__(self):
1467 for entry in grp.getgrall():
1479 for entry in grp.getgrall():
1468 yield igrpentry(entry.gr_name)
1480 yield igrpentry(entry.gr_name)
1469
1481
1470 def __xrepr__(self, mode="default"):
1482 def __xrepr__(self, mode="default"):
1471 if mode == "header" or mode == "footer":
1483 if mode == "header" or mode == "footer":
1472 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1484 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1473 else:
1485 else:
1474 yield (astyle.style_default, repr(self))
1486 yield (astyle.style_default, repr(self))
1475
1487
1476
1488
1477 class Fields(object):
1489 class Fields(object):
1478 def __init__(self, fieldnames, **fields):
1490 def __init__(self, fieldnames, **fields):
1479 self.__fieldnames = [upgradexattr(fieldname) for fieldname in fieldnames]
1491 self.__fieldnames = [upgradexattr(fieldname) for fieldname in fieldnames]
1480 for (key, value) in fields.iteritems():
1492 for (key, value) in fields.iteritems():
1481 setattr(self, key, value)
1493 setattr(self, key, value)
1482
1494
1483 def __xattrs__(self, mode="default"):
1495 def __xattrs__(self, mode="default"):
1484 return self.__fieldnames
1496 return self.__fieldnames
1485
1497
1486 def __xrepr__(self, mode="default"):
1498 def __xrepr__(self, mode="default"):
1487 yield (-1, False)
1499 yield (-1, False)
1488 if mode == "header" or mode == "cell":
1500 if mode == "header" or mode == "cell":
1489 yield (astyle.style_default, self.__class__.__name__)
1501 yield (astyle.style_default, self.__class__.__name__)
1490 yield (astyle.style_default, "(")
1502 yield (astyle.style_default, "(")
1491 for (i, f) in enumerate(self.__fieldnames):
1503 for (i, f) in enumerate(self.__fieldnames):
1492 if i:
1504 if i:
1493 yield (astyle.style_default, ", ")
1505 yield (astyle.style_default, ", ")
1494 yield (astyle.style_default, f.name())
1506 yield (astyle.style_default, f.name())
1495 yield (astyle.style_default, "=")
1507 yield (astyle.style_default, "=")
1496 for part in xrepr(getattr(self, f), "default"):
1508 for part in xrepr(getattr(self, f), "default"):
1497 yield part
1509 yield part
1498 yield (astyle.style_default, ")")
1510 yield (astyle.style_default, ")")
1499 elif mode == "footer":
1511 elif mode == "footer":
1500 yield (astyle.style_default, self.__class__.__name__)
1512 yield (astyle.style_default, self.__class__.__name__)
1501 yield (astyle.style_default, "(")
1513 yield (astyle.style_default, "(")
1502 for (i, f) in enumerate(self.__fieldnames):
1514 for (i, f) in enumerate(self.__fieldnames):
1503 if i:
1515 if i:
1504 yield (astyle.style_default, ", ")
1516 yield (astyle.style_default, ", ")
1505 yield (astyle.style_default, f.name())
1517 yield (astyle.style_default, f.name())
1506 yield (astyle.style_default, ")")
1518 yield (astyle.style_default, ")")
1507 else:
1519 else:
1508 yield (astyle.style_default, repr(self))
1520 yield (astyle.style_default, repr(self))
1509
1521
1510
1522
1511 class FieldTable(Table, list):
1523 class FieldTable(Table, list):
1512 def __init__(self, *fields):
1524 def __init__(self, *fields):
1513 Table.__init__(self)
1525 Table.__init__(self)
1514 list.__init__(self)
1526 list.__init__(self)
1515 self.fields = fields
1527 self.fields = fields
1516
1528
1517 def add(self, **fields):
1529 def add(self, **fields):
1518 self.append(Fields(self.fields, **fields))
1530 self.append(Fields(self.fields, **fields))
1519
1531
1520 def __xrepr__(self, mode="default"):
1532 def __xrepr__(self, mode="default"):
1521 yield (-1, False)
1533 yield (-1, False)
1522 if mode == "header" or mode == "footer":
1534 if mode == "header" or mode == "footer":
1523 yield (astyle.style_default, self.__class__.__name__)
1535 yield (astyle.style_default, self.__class__.__name__)
1524 yield (astyle.style_default, "(")
1536 yield (astyle.style_default, "(")
1525 for (i, f) in enumerate(self.__fieldnames):
1537 for (i, f) in enumerate(self.__fieldnames):
1526 if i:
1538 if i:
1527 yield (astyle.style_default, ", ")
1539 yield (astyle.style_default, ", ")
1528 yield (astyle.style_default, f)
1540 yield (astyle.style_default, f)
1529 yield (astyle.style_default, ")")
1541 yield (astyle.style_default, ")")
1530 else:
1542 else:
1531 yield (astyle.style_default, repr(self))
1543 yield (astyle.style_default, repr(self))
1532
1544
1533 def __repr__(self):
1545 def __repr__(self):
1534 return "<%s.%s object with fields=%r at 0x%x>" % \
1546 return "<%s.%s object with fields=%r at 0x%x>" % \
1535 (self.__class__.__module__, self.__class__.__name__,
1547 (self.__class__.__module__, self.__class__.__name__,
1536 ", ".join(map(repr, self.fields)), id(self))
1548 ", ".join(map(repr, self.fields)), id(self))
1537
1549
1538
1550
1539 class List(list):
1551 class List(list):
1540 def __xattrs__(self, mode="default"):
1552 def __xattrs__(self, mode="default"):
1541 return xrange(len(self))
1553 return xrange(len(self))
1542
1554
1543 def __xrepr__(self, mode="default"):
1555 def __xrepr__(self, mode="default"):
1544 yield (-1, False)
1556 yield (-1, False)
1545 if mode == "header" or mode == "cell" or mode == "footer" or mode == "default":
1557 if mode == "header" or mode == "cell" or mode == "footer" or mode == "default":
1546 yield (astyle.style_default, self.__class__.__name__)
1558 yield (astyle.style_default, self.__class__.__name__)
1547 yield (astyle.style_default, "(")
1559 yield (astyle.style_default, "(")
1548 for (i, item) in enumerate(self):
1560 for (i, item) in enumerate(self):
1549 if i:
1561 if i:
1550 yield (astyle.style_default, ", ")
1562 yield (astyle.style_default, ", ")
1551 for part in xrepr(item, "default"):
1563 for part in xrepr(item, "default"):
1552 yield part
1564 yield part
1553 yield (astyle.style_default, ")")
1565 yield (astyle.style_default, ")")
1554 else:
1566 else:
1555 yield (astyle.style_default, repr(self))
1567 yield (astyle.style_default, repr(self))
1556
1568
1557
1569
1558 class ienv(Table):
1570 class ienv(Table):
1559 """
1571 """
1560 List environment variables.
1572 List environment variables.
1561
1573
1562 Example::
1574 Example::
1563
1575
1564 >>> ienv
1576 >>> ienv
1577 <class 'IPython.Extensions.ipipe.ienv'>
1565 """
1578 """
1566
1579
1567 def __iter__(self):
1580 def __iter__(self):
1568 fields = ("key", "value")
1581 fields = ("key", "value")
1569 for (key, value) in os.environ.iteritems():
1582 for (key, value) in os.environ.iteritems():
1570 yield Fields(fields, key=key, value=value)
1583 yield Fields(fields, key=key, value=value)
1571
1584
1572 def __xrepr__(self, mode="default"):
1585 def __xrepr__(self, mode="default"):
1573 if mode == "header" or mode == "cell":
1586 if mode == "header" or mode == "cell":
1574 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1587 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1575 else:
1588 else:
1576 yield (astyle.style_default, repr(self))
1589 yield (astyle.style_default, repr(self))
1577
1590
1578
1591
1579 class ihist(Table):
1592 class ihist(Table):
1580 """
1593 """
1581 IPython input history
1594 IPython input history
1582
1595
1583 Example::
1596 Example::
1584
1597
1585 >>> ihist
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 def __init__(self, raw=True):
1603 def __init__(self, raw=True):
1589 self.raw = raw
1604 self.raw = raw
1590
1605
1591 def __iter__(self):
1606 def __iter__(self):
1592 api = ipapi.get()
1607 api = ipapi.get()
1593 if self.raw:
1608 if self.raw:
1594 for line in api.IP.input_hist_raw:
1609 for line in api.IP.input_hist_raw:
1595 yield line.rstrip("\n")
1610 yield line.rstrip("\n")
1596 else:
1611 else:
1597 for line in api.IP.input_hist:
1612 for line in api.IP.input_hist:
1598 yield line.rstrip("\n")
1613 yield line.rstrip("\n")
1599
1614
1600
1615
1601 class Alias(object):
1616 class Alias(object):
1602 """
1617 """
1603 Entry in the alias table
1618 Entry in the alias table
1604 """
1619 """
1605 def __init__(self, name, args, command):
1620 def __init__(self, name, args, command):
1606 self.name = name
1621 self.name = name
1607 self.args = args
1622 self.args = args
1608 self.command = command
1623 self.command = command
1609
1624
1610 def __xattrs__(self, mode="default"):
1625 def __xattrs__(self, mode="default"):
1611 return ("name", "args", "command")
1626 return ("name", "args", "command")
1612
1627
1613
1628
1614 class ialias(Table):
1629 class ialias(Table):
1615 """
1630 """
1616 IPython alias list
1631 IPython alias list
1617
1632
1618 Example::
1633 Example::
1619
1634
1620 >>> ialias
1635 >>> ialias
1636 <class 'IPython.Extensions.ipipe.ialias'>
1621 """
1637 """
1622 def __iter__(self):
1638 def __iter__(self):
1623 api = ipapi.get()
1639 api = ipapi.get()
1624
1640
1625 for (name, (args, command)) in api.IP.alias_table.iteritems():
1641 for (name, (args, command)) in api.IP.alias_table.iteritems():
1626 yield Alias(name, args, command)
1642 yield Alias(name, args, command)
1627
1643
1628
1644
1629 class icsv(Pipe):
1645 class icsv(Pipe):
1630 """
1646 """
1631 This ``Pipe`` turns the input (with must be a pipe outputting lines
1647 This ``Pipe`` turns the input (with must be a pipe outputting lines
1632 or an ``ifile``) into lines of CVS columns.
1648 or an ``ifile``) into lines of CVS columns.
1633 """
1649 """
1634 def __init__(self, **csvargs):
1650 def __init__(self, **csvargs):
1635 """
1651 """
1636 Create an ``icsv`` object. ``cvsargs`` will be passed through as
1652 Create an ``icsv`` object. ``cvsargs`` will be passed through as
1637 keyword arguments to ``cvs.reader()``.
1653 keyword arguments to ``cvs.reader()``.
1638 """
1654 """
1639 self.csvargs = csvargs
1655 self.csvargs = csvargs
1640
1656
1641 def __iter__(self):
1657 def __iter__(self):
1642 input = self.input
1658 input = self.input
1643 if isinstance(input, ifile):
1659 if isinstance(input, ifile):
1644 input = input.open("rb")
1660 input = input.open("rb")
1645 reader = csv.reader(input, **self.csvargs)
1661 reader = csv.reader(input, **self.csvargs)
1646 for line in reader:
1662 for line in reader:
1647 yield List(line)
1663 yield List(line)
1648
1664
1649 def __xrepr__(self, mode="default"):
1665 def __xrepr__(self, mode="default"):
1650 yield (-1, False)
1666 yield (-1, False)
1651 if mode == "header" or mode == "footer":
1667 if mode == "header" or mode == "footer":
1652 input = getattr(self, "input", None)
1668 input = getattr(self, "input", None)
1653 if input is not None:
1669 if input is not None:
1654 for part in xrepr(input, mode):
1670 for part in xrepr(input, mode):
1655 yield part
1671 yield part
1656 yield (astyle.style_default, " | ")
1672 yield (astyle.style_default, " | ")
1657 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1673 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1658 for (i, (name, value)) in enumerate(self.csvargs.iteritems()):
1674 for (i, (name, value)) in enumerate(self.csvargs.iteritems()):
1659 if i:
1675 if i:
1660 yield (astyle.style_default, ", ")
1676 yield (astyle.style_default, ", ")
1661 yield (astyle.style_default, name)
1677 yield (astyle.style_default, name)
1662 yield (astyle.style_default, "=")
1678 yield (astyle.style_default, "=")
1663 for part in xrepr(value, "default"):
1679 for part in xrepr(value, "default"):
1664 yield part
1680 yield part
1665 yield (astyle.style_default, ")")
1681 yield (astyle.style_default, ")")
1666 else:
1682 else:
1667 yield (astyle.style_default, repr(self))
1683 yield (astyle.style_default, repr(self))
1668
1684
1669 def __repr__(self):
1685 def __repr__(self):
1670 args = ", ".join(["%s=%r" % item for item in self.csvargs.iteritems()])
1686 args = ", ".join(["%s=%r" % item for item in self.csvargs.iteritems()])
1671 return "<%s.%s %s at 0x%x>" % \
1687 return "<%s.%s %s at 0x%x>" % \
1672 (self.__class__.__module__, self.__class__.__name__, args, id(self))
1688 (self.__class__.__module__, self.__class__.__name__, args, id(self))
1673
1689
1674
1690
1675 class ix(Table):
1691 class ix(Table):
1676 """
1692 """
1677 Execute a system command and list its output as lines
1693 Execute a system command and list its output as lines
1678 (similar to ``os.popen()``).
1694 (similar to ``os.popen()``).
1679
1695
1680 Examples::
1696 Examples::
1681
1697
1682 >>> ix("ps x")
1698 >>> ix("ps x")
1699 IPython.Extensions.ipipe.ix('ps x')
1700
1683 >>> ix("find .") | ifile
1701 >>> ix("find .") | ifile
1702 <IPython.Extensions.ipipe.ieval expr=<class 'IPython.Extensions.ipipe.ifile'> at 0x8509d2c>
1703 # random
1684 """
1704 """
1685 def __init__(self, cmd):
1705 def __init__(self, cmd):
1686 self.cmd = cmd
1706 self.cmd = cmd
1687 self._pipeout = None
1707 self._pipeout = None
1688
1708
1689 def __iter__(self):
1709 def __iter__(self):
1690 (_pipein, self._pipeout) = os.popen4(self.cmd)
1710 (_pipein, self._pipeout) = os.popen4(self.cmd)
1691 _pipein.close()
1711 _pipein.close()
1692 for l in self._pipeout:
1712 for l in self._pipeout:
1693 yield l.rstrip("\r\n")
1713 yield l.rstrip("\r\n")
1694 self._pipeout.close()
1714 self._pipeout.close()
1695 self._pipeout = None
1715 self._pipeout = None
1696
1716
1697 def __del__(self):
1717 def __del__(self):
1698 if self._pipeout is not None and not self._pipeout.closed:
1718 if self._pipeout is not None and not self._pipeout.closed:
1699 self._pipeout.close()
1719 self._pipeout.close()
1700 self._pipeout = None
1720 self._pipeout = None
1701
1721
1702 def __xrepr__(self, mode="default"):
1722 def __xrepr__(self, mode="default"):
1703 if mode == "header" or mode == "footer":
1723 if mode == "header" or mode == "footer":
1704 yield (astyle.style_default,
1724 yield (astyle.style_default,
1705 "%s(%r)" % (self.__class__.__name__, self.cmd))
1725 "%s(%r)" % (self.__class__.__name__, self.cmd))
1706 else:
1726 else:
1707 yield (astyle.style_default, repr(self))
1727 yield (astyle.style_default, repr(self))
1708
1728
1709 def __repr__(self):
1729 def __repr__(self):
1710 return "%s.%s(%r)" % \
1730 return "%s.%s(%r)" % \
1711 (self.__class__.__module__, self.__class__.__name__, self.cmd)
1731 (self.__class__.__module__, self.__class__.__name__, self.cmd)
1712
1732
1713
1733
1714 class ifilter(Pipe):
1734 class ifilter(Pipe):
1715 """
1735 """
1716 Filter an input pipe. Only objects where an expression evaluates to true
1736 Filter an input pipe. Only objects where an expression evaluates to true
1717 (and doesn't raise an exception) are listed.
1737 (and doesn't raise an exception) are listed.
1718
1738
1719 Examples::
1739 Examples::
1720
1740
1721 >>> ils | ifilter("_.isfile() and size>1000")
1741 >>> ils | ifilter("_.isfile() and size>1000")
1722 >>> igrp | ifilter("len(mem)")
1742 >>> igrp | ifilter("len(mem)")
1723 >>> sys.modules | ifilter(lambda _:_.value is not None)
1743 >>> sys.modules | ifilter(lambda _:_.value is not None)
1744 # all-random
1724 """
1745 """
1725
1746
1726 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1747 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1727 """
1748 """
1728 Create an ``ifilter`` object. ``expr`` can be a callable or a string
1749 Create an ``ifilter`` object. ``expr`` can be a callable or a string
1729 containing an expression. ``globals`` will be used as the global
1750 containing an expression. ``globals`` will be used as the global
1730 namespace for calling string expressions (defaulting to IPython's
1751 namespace for calling string expressions (defaulting to IPython's
1731 user namespace). ``errors`` specifies how exception during evaluation
1752 user namespace). ``errors`` specifies how exception during evaluation
1732 of ``expr`` are handled:
1753 of ``expr`` are handled:
1733
1754
1734 ``"drop"``
1755 ``"drop"``
1735 drop all items that have errors;
1756 drop all items that have errors;
1736
1757
1737 ``"keep"``
1758 ``"keep"``
1738 keep all items that have errors;
1759 keep all items that have errors;
1739
1760
1740 ``"keeperror"``
1761 ``"keeperror"``
1741 keep the exception of all items that have errors;
1762 keep the exception of all items that have errors;
1742
1763
1743 ``"raise"``
1764 ``"raise"``
1744 raise the exception;
1765 raise the exception;
1745
1766
1746 ``"raiseifallfail"``
1767 ``"raiseifallfail"``
1747 raise the first exception if all items have errors; otherwise drop
1768 raise the first exception if all items have errors; otherwise drop
1748 those with errors (this is the default).
1769 those with errors (this is the default).
1749 """
1770 """
1750 self.expr = expr
1771 self.expr = expr
1751 self.globals = globals
1772 self.globals = globals
1752 self.errors = errors
1773 self.errors = errors
1753
1774
1754 def __iter__(self):
1775 def __iter__(self):
1755 if callable(self.expr):
1776 if callable(self.expr):
1756 test = self.expr
1777 test = self.expr
1757 else:
1778 else:
1758 g = getglobals(self.globals)
1779 g = getglobals(self.globals)
1759 expr = compile(self.expr, "ipipe-expression", "eval")
1780 expr = compile(self.expr, "ipipe-expression", "eval")
1760 def test(item):
1781 def test(item):
1761 return eval(expr, g, AttrNamespace(item))
1782 return eval(expr, g, AttrNamespace(item))
1762
1783
1763 ok = 0
1784 ok = 0
1764 exc_info = None
1785 exc_info = None
1765 for item in xiter(self.input):
1786 for item in xiter(self.input):
1766 try:
1787 try:
1767 if test(item):
1788 if test(item):
1768 yield item
1789 yield item
1769 ok += 1
1790 ok += 1
1770 except (KeyboardInterrupt, SystemExit):
1791 except (KeyboardInterrupt, SystemExit):
1771 raise
1792 raise
1772 except Exception, exc:
1793 except Exception, exc:
1773 if self.errors == "drop":
1794 if self.errors == "drop":
1774 pass # Ignore errors
1795 pass # Ignore errors
1775 elif self.errors == "keep":
1796 elif self.errors == "keep":
1776 yield item
1797 yield item
1777 elif self.errors == "keeperror":
1798 elif self.errors == "keeperror":
1778 yield exc
1799 yield exc
1779 elif self.errors == "raise":
1800 elif self.errors == "raise":
1780 raise
1801 raise
1781 elif self.errors == "raiseifallfail":
1802 elif self.errors == "raiseifallfail":
1782 if exc_info is None:
1803 if exc_info is None:
1783 exc_info = sys.exc_info()
1804 exc_info = sys.exc_info()
1784 if not ok and exc_info is not None:
1805 if not ok and exc_info is not None:
1785 raise exc_info[0], exc_info[1], exc_info[2]
1806 raise exc_info[0], exc_info[1], exc_info[2]
1786
1807
1787 def __xrepr__(self, mode="default"):
1808 def __xrepr__(self, mode="default"):
1788 if mode == "header" or mode == "footer":
1809 if mode == "header" or mode == "footer":
1789 input = getattr(self, "input", None)
1810 input = getattr(self, "input", None)
1790 if input is not None:
1811 if input is not None:
1791 for part in xrepr(input, mode):
1812 for part in xrepr(input, mode):
1792 yield part
1813 yield part
1793 yield (astyle.style_default, " | ")
1814 yield (astyle.style_default, " | ")
1794 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1815 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1795 for part in xrepr(self.expr, "default"):
1816 for part in xrepr(self.expr, "default"):
1796 yield part
1817 yield part
1797 yield (astyle.style_default, ")")
1818 yield (astyle.style_default, ")")
1798 else:
1819 else:
1799 yield (astyle.style_default, repr(self))
1820 yield (astyle.style_default, repr(self))
1800
1821
1801 def __repr__(self):
1822 def __repr__(self):
1802 return "<%s.%s expr=%r at 0x%x>" % \
1823 return "<%s.%s expr=%r at 0x%x>" % \
1803 (self.__class__.__module__, self.__class__.__name__,
1824 (self.__class__.__module__, self.__class__.__name__,
1804 self.expr, id(self))
1825 self.expr, id(self))
1805
1826
1806
1827
1807 class ieval(Pipe):
1828 class ieval(Pipe):
1808 """
1829 """
1809 Evaluate an expression for each object in the input pipe.
1830 Evaluate an expression for each object in the input pipe.
1810
1831
1811 Examples::
1832 Examples::
1812
1833
1813 >>> ils | ieval("_.abspath()")
1834 >>> ils | ieval("_.abspath()")
1835 # random
1814 >>> sys.path | ieval(ifile)
1836 >>> sys.path | ieval(ifile)
1837 # random
1815 """
1838 """
1816
1839
1817 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1840 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1818 """
1841 """
1819 Create an ``ieval`` object. ``expr`` can be a callable or a string
1842 Create an ``ieval`` object. ``expr`` can be a callable or a string
1820 containing an expression. For the meaning of ``globals`` and
1843 containing an expression. For the meaning of ``globals`` and
1821 ``errors`` see ``ifilter``.
1844 ``errors`` see ``ifilter``.
1822 """
1845 """
1823 self.expr = expr
1846 self.expr = expr
1824 self.globals = globals
1847 self.globals = globals
1825 self.errors = errors
1848 self.errors = errors
1826
1849
1827 def __iter__(self):
1850 def __iter__(self):
1828 if callable(self.expr):
1851 if callable(self.expr):
1829 do = self.expr
1852 do = self.expr
1830 else:
1853 else:
1831 g = getglobals(self.globals)
1854 g = getglobals(self.globals)
1832 expr = compile(self.expr, "ipipe-expression", "eval")
1855 expr = compile(self.expr, "ipipe-expression", "eval")
1833 def do(item):
1856 def do(item):
1834 return eval(expr, g, AttrNamespace(item))
1857 return eval(expr, g, AttrNamespace(item))
1835
1858
1836 ok = 0
1859 ok = 0
1837 exc_info = None
1860 exc_info = None
1838 for item in xiter(self.input):
1861 for item in xiter(self.input):
1839 try:
1862 try:
1840 yield do(item)
1863 yield do(item)
1841 except (KeyboardInterrupt, SystemExit):
1864 except (KeyboardInterrupt, SystemExit):
1842 raise
1865 raise
1843 except Exception, exc:
1866 except Exception, exc:
1844 if self.errors == "drop":
1867 if self.errors == "drop":
1845 pass # Ignore errors
1868 pass # Ignore errors
1846 elif self.errors == "keep":
1869 elif self.errors == "keep":
1847 yield item
1870 yield item
1848 elif self.errors == "keeperror":
1871 elif self.errors == "keeperror":
1849 yield exc
1872 yield exc
1850 elif self.errors == "raise":
1873 elif self.errors == "raise":
1851 raise
1874 raise
1852 elif self.errors == "raiseifallfail":
1875 elif self.errors == "raiseifallfail":
1853 if exc_info is None:
1876 if exc_info is None:
1854 exc_info = sys.exc_info()
1877 exc_info = sys.exc_info()
1855 if not ok and exc_info is not None:
1878 if not ok and exc_info is not None:
1856 raise exc_info[0], exc_info[1], exc_info[2]
1879 raise exc_info[0], exc_info[1], exc_info[2]
1857
1880
1858 def __xrepr__(self, mode="default"):
1881 def __xrepr__(self, mode="default"):
1859 if mode == "header" or mode == "footer":
1882 if mode == "header" or mode == "footer":
1860 input = getattr(self, "input", None)
1883 input = getattr(self, "input", None)
1861 if input is not None:
1884 if input is not None:
1862 for part in xrepr(input, mode):
1885 for part in xrepr(input, mode):
1863 yield part
1886 yield part
1864 yield (astyle.style_default, " | ")
1887 yield (astyle.style_default, " | ")
1865 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1888 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1866 for part in xrepr(self.expr, "default"):
1889 for part in xrepr(self.expr, "default"):
1867 yield part
1890 yield part
1868 yield (astyle.style_default, ")")
1891 yield (astyle.style_default, ")")
1869 else:
1892 else:
1870 yield (astyle.style_default, repr(self))
1893 yield (astyle.style_default, repr(self))
1871
1894
1872 def __repr__(self):
1895 def __repr__(self):
1873 return "<%s.%s expr=%r at 0x%x>" % \
1896 return "<%s.%s expr=%r at 0x%x>" % \
1874 (self.__class__.__module__, self.__class__.__name__,
1897 (self.__class__.__module__, self.__class__.__name__,
1875 self.expr, id(self))
1898 self.expr, id(self))
1876
1899
1877
1900
1878 class ienum(Pipe):
1901 class ienum(Pipe):
1879 """
1902 """
1880 Enumerate the input pipe (i.e. wrap each input object in an object
1903 Enumerate the input pipe (i.e. wrap each input object in an object
1881 with ``index`` and ``object`` attributes).
1904 with ``index`` and ``object`` attributes).
1882
1905
1883 Examples::
1906 Examples::
1884
1907
1885 >>> xrange(20) | ieval("_,_*_") | ienum | ifilter("index % 2 == 0") | ieval("object")
1908 >>> xrange(20) | ieval("_,_*_") | ienum | ifilter("index % 2 == 0") | ieval("object")
1886 """
1909 """
1910 skip_doctest = True
1911
1887 def __iter__(self):
1912 def __iter__(self):
1888 fields = ("index", "object")
1913 fields = ("index", "object")
1889 for (index, object) in enumerate(xiter(self.input)):
1914 for (index, object) in enumerate(xiter(self.input)):
1890 yield Fields(fields, index=index, object=object)
1915 yield Fields(fields, index=index, object=object)
1891
1916
1892
1917
1893 class isort(Pipe):
1918 class isort(Pipe):
1894 """
1919 """
1895 Sorts the input pipe.
1920 Sorts the input pipe.
1896
1921
1897 Examples::
1922 Examples::
1898
1923
1899 >>> ils | isort("size")
1924 >>> ils | isort("size")
1925 <IPython.Extensions.ipipe.isort key='size' reverse=False at 0x849ec2c>
1900 >>> ils | isort("_.isdir(), _.lower()", reverse=True)
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 def __init__(self, key=None, globals=None, reverse=False):
1931 def __init__(self, key=None, globals=None, reverse=False):
1904 """
1932 """
1905 Create an ``isort`` object. ``key`` can be a callable or a string
1933 Create an ``isort`` object. ``key`` can be a callable or a string
1906 containing an expression (or ``None`` in which case the items
1934 containing an expression (or ``None`` in which case the items
1907 themselves will be sorted). If ``reverse`` is true the sort order
1935 themselves will be sorted). If ``reverse`` is true the sort order
1908 will be reversed. For the meaning of ``globals`` see ``ifilter``.
1936 will be reversed. For the meaning of ``globals`` see ``ifilter``.
1909 """
1937 """
1910 self.key = key
1938 self.key = key
1911 self.globals = globals
1939 self.globals = globals
1912 self.reverse = reverse
1940 self.reverse = reverse
1913
1941
1914 def __iter__(self):
1942 def __iter__(self):
1915 if self.key is None:
1943 if self.key is None:
1916 items = sorted(xiter(self.input), reverse=self.reverse)
1944 items = sorted(xiter(self.input), reverse=self.reverse)
1917 elif callable(self.key):
1945 elif callable(self.key):
1918 items = sorted(xiter(self.input), key=self.key, reverse=self.reverse)
1946 items = sorted(xiter(self.input), key=self.key, reverse=self.reverse)
1919 else:
1947 else:
1920 g = getglobals(self.globals)
1948 g = getglobals(self.globals)
1921 key = compile(self.key, "ipipe-expression", "eval")
1949 key = compile(self.key, "ipipe-expression", "eval")
1922 def realkey(item):
1950 def realkey(item):
1923 return eval(key, g, AttrNamespace(item))
1951 return eval(key, g, AttrNamespace(item))
1924 items = sorted(xiter(self.input), key=realkey, reverse=self.reverse)
1952 items = sorted(xiter(self.input), key=realkey, reverse=self.reverse)
1925 for item in items:
1953 for item in items:
1926 yield item
1954 yield item
1927
1955
1928 def __xrepr__(self, mode="default"):
1956 def __xrepr__(self, mode="default"):
1929 if mode == "header" or mode == "footer":
1957 if mode == "header" or mode == "footer":
1930 input = getattr(self, "input", None)
1958 input = getattr(self, "input", None)
1931 if input is not None:
1959 if input is not None:
1932 for part in xrepr(input, mode):
1960 for part in xrepr(input, mode):
1933 yield part
1961 yield part
1934 yield (astyle.style_default, " | ")
1962 yield (astyle.style_default, " | ")
1935 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1963 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1936 for part in xrepr(self.key, "default"):
1964 for part in xrepr(self.key, "default"):
1937 yield part
1965 yield part
1938 if self.reverse:
1966 if self.reverse:
1939 yield (astyle.style_default, ", ")
1967 yield (astyle.style_default, ", ")
1940 for part in xrepr(True, "default"):
1968 for part in xrepr(True, "default"):
1941 yield part
1969 yield part
1942 yield (astyle.style_default, ")")
1970 yield (astyle.style_default, ")")
1943 else:
1971 else:
1944 yield (astyle.style_default, repr(self))
1972 yield (astyle.style_default, repr(self))
1945
1973
1946 def __repr__(self):
1974 def __repr__(self):
1947 return "<%s.%s key=%r reverse=%r at 0x%x>" % \
1975 return "<%s.%s key=%r reverse=%r at 0x%x>" % \
1948 (self.__class__.__module__, self.__class__.__name__,
1976 (self.__class__.__module__, self.__class__.__name__,
1949 self.key, self.reverse, id(self))
1977 self.key, self.reverse, id(self))
1950
1978
1951
1979
1952 tab = 3 # for expandtabs()
1980 tab = 3 # for expandtabs()
1953
1981
1954 def _format(field):
1982 def _format(field):
1955 if isinstance(field, str):
1983 if isinstance(field, str):
1956 text = repr(field.expandtabs(tab))[1:-1]
1984 text = repr(field.expandtabs(tab))[1:-1]
1957 elif isinstance(field, unicode):
1985 elif isinstance(field, unicode):
1958 text = repr(field.expandtabs(tab))[2:-1]
1986 text = repr(field.expandtabs(tab))[2:-1]
1959 elif isinstance(field, datetime.datetime):
1987 elif isinstance(field, datetime.datetime):
1960 # Don't use strftime() here, as this requires year >= 1900
1988 # Don't use strftime() here, as this requires year >= 1900
1961 text = "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
1989 text = "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
1962 (field.year, field.month, field.day,
1990 (field.year, field.month, field.day,
1963 field.hour, field.minute, field.second, field.microsecond)
1991 field.hour, field.minute, field.second, field.microsecond)
1964 elif isinstance(field, datetime.date):
1992 elif isinstance(field, datetime.date):
1965 text = "%04d-%02d-%02d" % (field.year, field.month, field.day)
1993 text = "%04d-%02d-%02d" % (field.year, field.month, field.day)
1966 else:
1994 else:
1967 text = repr(field)
1995 text = repr(field)
1968 return text
1996 return text
1969
1997
1970
1998
1971 class Display(object):
1999 class Display(object):
1972 class __metaclass__(type):
2000 class __metaclass__(type):
1973 def __ror__(self, input):
2001 def __ror__(self, input):
1974 return input | self()
2002 return input | self()
1975
2003
1976 def __init__(self, input=None):
2004 def __init__(self, input=None):
1977 self.input = input
2005 self.input = input
1978
2006
1979 def __ror__(self, input):
2007 def __ror__(self, input):
1980 self.input = input
2008 self.input = input
1981 return self
2009 return self
1982
2010
1983 def display(self):
2011 def display(self):
1984 pass
2012 pass
1985
2013
1986
2014
1987 class iless(Display):
2015 class iless(Display):
1988 cmd = "less --quit-if-one-screen --LONG-PROMPT --LINE-NUMBERS --chop-long-lines --shift=8 --RAW-CONTROL-CHARS"
2016 cmd = "less --quit-if-one-screen --LONG-PROMPT --LINE-NUMBERS --chop-long-lines --shift=8 --RAW-CONTROL-CHARS"
1989
2017
1990 def display(self):
2018 def display(self):
1991 try:
2019 try:
1992 pager = os.popen(self.cmd, "w")
2020 pager = os.popen(self.cmd, "w")
1993 try:
2021 try:
1994 for item in xiter(self.input):
2022 for item in xiter(self.input):
1995 first = False
2023 first = False
1996 for attr in xattrs(item, "default"):
2024 for attr in xattrs(item, "default"):
1997 if first:
2025 if first:
1998 first = False
2026 first = False
1999 else:
2027 else:
2000 pager.write(" ")
2028 pager.write(" ")
2001 attr = upgradexattr(attr)
2029 attr = upgradexattr(attr)
2002 if not isinstance(attr, SelfDescriptor):
2030 if not isinstance(attr, SelfDescriptor):
2003 pager.write(attr.name())
2031 pager.write(attr.name())
2004 pager.write("=")
2032 pager.write("=")
2005 pager.write(str(attr.value(item)))
2033 pager.write(str(attr.value(item)))
2006 pager.write("\n")
2034 pager.write("\n")
2007 finally:
2035 finally:
2008 pager.close()
2036 pager.close()
2009 except Exception, exc:
2037 except Exception, exc:
2010 print "%s: %s" % (exc.__class__.__name__, str(exc))
2038 print "%s: %s" % (exc.__class__.__name__, str(exc))
2011
2039
2012
2040
2013 class _RedirectIO(object):
2041 class _RedirectIO(object):
2014 def __init__(self,*args,**kwargs):
2042 def __init__(self,*args,**kwargs):
2015 """
2043 """
2016 Map the system output streams to self.
2044 Map the system output streams to self.
2017 """
2045 """
2018 self.stream = StringIO.StringIO()
2046 self.stream = StringIO.StringIO()
2019 self.stdout = sys.stdout
2047 self.stdout = sys.stdout
2020 sys.stdout = self
2048 sys.stdout = self
2021 self.stderr = sys.stderr
2049 self.stderr = sys.stderr
2022 sys.stderr = self
2050 sys.stderr = self
2023
2051
2024 def write(self, text):
2052 def write(self, text):
2025 """
2053 """
2026 Write both to screen and to self.
2054 Write both to screen and to self.
2027 """
2055 """
2028 self.stream.write(text)
2056 self.stream.write(text)
2029 self.stdout.write(text)
2057 self.stdout.write(text)
2030 if "\n" in text:
2058 if "\n" in text:
2031 self.stdout.flush()
2059 self.stdout.flush()
2032
2060
2033 def writelines(self, lines):
2061 def writelines(self, lines):
2034 """
2062 """
2035 Write lines both to screen and to self.
2063 Write lines both to screen and to self.
2036 """
2064 """
2037 self.stream.writelines(lines)
2065 self.stream.writelines(lines)
2038 self.stdout.writelines(lines)
2066 self.stdout.writelines(lines)
2039 self.stdout.flush()
2067 self.stdout.flush()
2040
2068
2041 def restore(self):
2069 def restore(self):
2042 """
2070 """
2043 Restore the default system streams.
2071 Restore the default system streams.
2044 """
2072 """
2045 self.stdout.flush()
2073 self.stdout.flush()
2046 self.stderr.flush()
2074 self.stderr.flush()
2047 sys.stdout = self.stdout
2075 sys.stdout = self.stdout
2048 sys.stderr = self.stderr
2076 sys.stderr = self.stderr
2049
2077
2050
2078
2051 class icap(Table):
2079 class icap(Table):
2052 """
2080 """
2053 Execute a python string and capture any output to stderr/stdout.
2081 Execute a python string and capture any output to stderr/stdout.
2054
2082
2055 Examples::
2083 Examples::
2056
2084
2057 >>> import time
2085 >>> import time
2058 >>> icap("for i in range(10): print i, time.sleep(0.1)")
2086 >>> icap("for i in range(10): print i, time.sleep(0.1)")
2059
2087
2060 """
2088 """
2089 skip_doctest = True
2090
2061 def __init__(self, expr, globals=None):
2091 def __init__(self, expr, globals=None):
2062 self.expr = expr
2092 self.expr = expr
2063 self.globals = globals
2093 self.globals = globals
2064 log = _RedirectIO()
2094 log = _RedirectIO()
2065 try:
2095 try:
2066 exec(expr, getglobals(globals))
2096 exec(expr, getglobals(globals))
2067 finally:
2097 finally:
2068 log.restore()
2098 log.restore()
2069 self.stream = log.stream
2099 self.stream = log.stream
2070
2100
2071 def __iter__(self):
2101 def __iter__(self):
2072 self.stream.seek(0)
2102 self.stream.seek(0)
2073 for line in self.stream:
2103 for line in self.stream:
2074 yield line.rstrip("\r\n")
2104 yield line.rstrip("\r\n")
2075
2105
2076 def __xrepr__(self, mode="default"):
2106 def __xrepr__(self, mode="default"):
2077 if mode == "header" or mode == "footer":
2107 if mode == "header" or mode == "footer":
2078 yield (astyle.style_default,
2108 yield (astyle.style_default,
2079 "%s(%r)" % (self.__class__.__name__, self.expr))
2109 "%s(%r)" % (self.__class__.__name__, self.expr))
2080 else:
2110 else:
2081 yield (astyle.style_default, repr(self))
2111 yield (astyle.style_default, repr(self))
2082
2112
2083 def __repr__(self):
2113 def __repr__(self):
2084 return "%s.%s(%r)" % \
2114 return "%s.%s(%r)" % \
2085 (self.__class__.__module__, self.__class__.__name__, self.expr)
2115 (self.__class__.__module__, self.__class__.__name__, self.expr)
2086
2116
2087
2117
2088 def xformat(value, mode, maxlength):
2118 def xformat(value, mode, maxlength):
2089 align = None
2119 align = None
2090 full = True
2120 full = True
2091 width = 0
2121 width = 0
2092 text = astyle.Text()
2122 text = astyle.Text()
2093 for (style, part) in xrepr(value, mode):
2123 for (style, part) in xrepr(value, mode):
2094 # only consider the first result
2124 # only consider the first result
2095 if align is None:
2125 if align is None:
2096 if isinstance(style, int):
2126 if isinstance(style, int):
2097 # (style, text) really is (alignment, stop)
2127 # (style, text) really is (alignment, stop)
2098 align = style
2128 align = style
2099 full = part
2129 full = part
2100 continue
2130 continue
2101 else:
2131 else:
2102 align = -1
2132 align = -1
2103 full = True
2133 full = True
2104 if not isinstance(style, int):
2134 if not isinstance(style, int):
2105 text.append((style, part))
2135 text.append((style, part))
2106 width += len(part)
2136 width += len(part)
2107 if width >= maxlength and not full:
2137 if width >= maxlength and not full:
2108 text.append((astyle.style_ellisis, "..."))
2138 text.append((astyle.style_ellisis, "..."))
2109 width += 3
2139 width += 3
2110 break
2140 break
2111 if align is None: # default to left alignment
2141 if align is None: # default to left alignment
2112 align = -1
2142 align = -1
2113 return (align, width, text)
2143 return (align, width, text)
2114
2144
2115
2145
2116
2146
2117 import astyle
2147 import astyle
2118
2148
2119 class idump(Display):
2149 class idump(Display):
2120 # The approximate maximum length of a column entry
2150 # The approximate maximum length of a column entry
2121 maxattrlength = 200
2151 maxattrlength = 200
2122
2152
2123 # Style for column names
2153 # Style for column names
2124 style_header = astyle.Style.fromstr("white:black:bold")
2154 style_header = astyle.Style.fromstr("white:black:bold")
2125
2155
2126 def __init__(self, input=None, *attrs):
2156 def __init__(self, input=None, *attrs):
2127 Display.__init__(self, input)
2157 Display.__init__(self, input)
2128 self.attrs = [upgradexattr(attr) for attr in attrs]
2158 self.attrs = [upgradexattr(attr) for attr in attrs]
2129 self.headerpadchar = " "
2159 self.headerpadchar = " "
2130 self.headersepchar = "|"
2160 self.headersepchar = "|"
2131 self.datapadchar = " "
2161 self.datapadchar = " "
2132 self.datasepchar = "|"
2162 self.datasepchar = "|"
2133
2163
2134 def display(self):
2164 def display(self):
2135 stream = genutils.Term.cout
2165 stream = genutils.Term.cout
2136 allattrs = []
2166 allattrs = []
2137 attrset = set()
2167 attrset = set()
2138 colwidths = {}
2168 colwidths = {}
2139 rows = []
2169 rows = []
2140 for item in xiter(self.input):
2170 for item in xiter(self.input):
2141 row = {}
2171 row = {}
2142 attrs = self.attrs
2172 attrs = self.attrs
2143 if not attrs:
2173 if not attrs:
2144 attrs = xattrs(item, "default")
2174 attrs = xattrs(item, "default")
2145 for attr in attrs:
2175 for attr in attrs:
2146 if attr not in attrset:
2176 if attr not in attrset:
2147 allattrs.append(attr)
2177 allattrs.append(attr)
2148 attrset.add(attr)
2178 attrset.add(attr)
2149 colwidths[attr] = len(attr.name())
2179 colwidths[attr] = len(attr.name())
2150 try:
2180 try:
2151 value = attr.value(item)
2181 value = attr.value(item)
2152 except (KeyboardInterrupt, SystemExit):
2182 except (KeyboardInterrupt, SystemExit):
2153 raise
2183 raise
2154 except Exception, exc:
2184 except Exception, exc:
2155 value = exc
2185 value = exc
2156 (align, width, text) = xformat(value, "cell", self.maxattrlength)
2186 (align, width, text) = xformat(value, "cell", self.maxattrlength)
2157 colwidths[attr] = max(colwidths[attr], width)
2187 colwidths[attr] = max(colwidths[attr], width)
2158 # remember alignment, length and colored parts
2188 # remember alignment, length and colored parts
2159 row[attr] = (align, width, text)
2189 row[attr] = (align, width, text)
2160 rows.append(row)
2190 rows.append(row)
2161
2191
2162 stream.write("\n")
2192 stream.write("\n")
2163 for (i, attr) in enumerate(allattrs):
2193 for (i, attr) in enumerate(allattrs):
2164 attrname = attr.name()
2194 attrname = attr.name()
2165 self.style_header(attrname).write(stream)
2195 self.style_header(attrname).write(stream)
2166 spc = colwidths[attr] - len(attrname)
2196 spc = colwidths[attr] - len(attrname)
2167 if i < len(colwidths)-1:
2197 if i < len(colwidths)-1:
2168 stream.write(self.headerpadchar*spc)
2198 stream.write(self.headerpadchar*spc)
2169 stream.write(self.headersepchar)
2199 stream.write(self.headersepchar)
2170 stream.write("\n")
2200 stream.write("\n")
2171
2201
2172 for row in rows:
2202 for row in rows:
2173 for (i, attr) in enumerate(allattrs):
2203 for (i, attr) in enumerate(allattrs):
2174 (align, width, text) = row[attr]
2204 (align, width, text) = row[attr]
2175 spc = colwidths[attr] - width
2205 spc = colwidths[attr] - width
2176 if align == -1:
2206 if align == -1:
2177 text.write(stream)
2207 text.write(stream)
2178 if i < len(colwidths)-1:
2208 if i < len(colwidths)-1:
2179 stream.write(self.datapadchar*spc)
2209 stream.write(self.datapadchar*spc)
2180 elif align == 0:
2210 elif align == 0:
2181 spc = colwidths[attr] - width
2211 spc = colwidths[attr] - width
2182 spc1 = spc//2
2212 spc1 = spc//2
2183 spc2 = spc-spc1
2213 spc2 = spc-spc1
2184 stream.write(self.datapadchar*spc1)
2214 stream.write(self.datapadchar*spc1)
2185 text.write(stream)
2215 text.write(stream)
2186 if i < len(colwidths)-1:
2216 if i < len(colwidths)-1:
2187 stream.write(self.datapadchar*spc2)
2217 stream.write(self.datapadchar*spc2)
2188 else:
2218 else:
2189 stream.write(self.datapadchar*spc)
2219 stream.write(self.datapadchar*spc)
2190 text.write(stream)
2220 text.write(stream)
2191 if i < len(colwidths)-1:
2221 if i < len(colwidths)-1:
2192 stream.write(self.datasepchar)
2222 stream.write(self.datasepchar)
2193 stream.write("\n")
2223 stream.write("\n")
2194
2224
2195
2225
2196 class AttributeDetail(Table):
2226 class AttributeDetail(Table):
2197 """
2227 """
2198 ``AttributeDetail`` objects are use for displaying a detailed list of object
2228 ``AttributeDetail`` objects are use for displaying a detailed list of object
2199 attributes.
2229 attributes.
2200 """
2230 """
2201 def __init__(self, object, descriptor):
2231 def __init__(self, object, descriptor):
2202 self.object = object
2232 self.object = object
2203 self.descriptor = descriptor
2233 self.descriptor = descriptor
2204
2234
2205 def __iter__(self):
2235 def __iter__(self):
2206 return self.descriptor.iter(self.object)
2236 return self.descriptor.iter(self.object)
2207
2237
2208 def name(self):
2238 def name(self):
2209 return self.descriptor.name()
2239 return self.descriptor.name()
2210
2240
2211 def attrtype(self):
2241 def attrtype(self):
2212 return self.descriptor.attrtype(self.object)
2242 return self.descriptor.attrtype(self.object)
2213
2243
2214 def valuetype(self):
2244 def valuetype(self):
2215 return self.descriptor.valuetype(self.object)
2245 return self.descriptor.valuetype(self.object)
2216
2246
2217 def doc(self):
2247 def doc(self):
2218 return self.descriptor.doc(self.object)
2248 return self.descriptor.doc(self.object)
2219
2249
2220 def shortdoc(self):
2250 def shortdoc(self):
2221 return self.descriptor.shortdoc(self.object)
2251 return self.descriptor.shortdoc(self.object)
2222
2252
2223 def value(self):
2253 def value(self):
2224 return self.descriptor.value(self.object)
2254 return self.descriptor.value(self.object)
2225
2255
2226 def __xattrs__(self, mode="default"):
2256 def __xattrs__(self, mode="default"):
2227 attrs = ("name()", "attrtype()", "valuetype()", "value()", "shortdoc()")
2257 attrs = ("name()", "attrtype()", "valuetype()", "value()", "shortdoc()")
2228 if mode == "detail":
2258 if mode == "detail":
2229 attrs += ("doc()",)
2259 attrs += ("doc()",)
2230 return attrs
2260 return attrs
2231
2261
2232 def __xrepr__(self, mode="default"):
2262 def __xrepr__(self, mode="default"):
2233 yield (-1, True)
2263 yield (-1, True)
2234 valuetype = self.valuetype()
2264 valuetype = self.valuetype()
2235 if valuetype is not noitem:
2265 if valuetype is not noitem:
2236 for part in xrepr(valuetype):
2266 for part in xrepr(valuetype):
2237 yield part
2267 yield part
2238 yield (astyle.style_default, " ")
2268 yield (astyle.style_default, " ")
2239 yield (astyle.style_default, self.attrtype())
2269 yield (astyle.style_default, self.attrtype())
2240 yield (astyle.style_default, " ")
2270 yield (astyle.style_default, " ")
2241 yield (astyle.style_default, self.name())
2271 yield (astyle.style_default, self.name())
2242 yield (astyle.style_default, " of ")
2272 yield (astyle.style_default, " of ")
2243 for part in xrepr(self.object):
2273 for part in xrepr(self.object):
2244 yield part
2274 yield part
2245
2275
2246
2276
2247 try:
2277 try:
2248 from ibrowse import ibrowse
2278 from ibrowse import ibrowse
2249 except ImportError:
2279 except ImportError:
2250 # No curses (probably Windows) => try igrid
2280 # No curses (probably Windows) => try igrid
2251 try:
2281 try:
2252 from igrid import igrid
2282 from igrid import igrid
2253 except ImportError:
2283 except ImportError:
2254 # no wx either => use ``idump`` as the default display.
2284 # no wx either => use ``idump`` as the default display.
2255 defaultdisplay = idump
2285 defaultdisplay = idump
2256 else:
2286 else:
2257 defaultdisplay = igrid
2287 defaultdisplay = igrid
2258 __all__.append("igrid")
2288 __all__.append("igrid")
2259 else:
2289 else:
2260 defaultdisplay = ibrowse
2290 defaultdisplay = ibrowse
2261 __all__.append("ibrowse")
2291 __all__.append("ibrowse")
2262
2292
2263
2293
2264 # If we're running under IPython, register our objects with IPython's
2294 # If we're running under IPython, register our objects with IPython's
2265 # generic function ``result_display``, else install a displayhook
2295 # generic function ``result_display``, else install a displayhook
2266 # directly as sys.displayhook
2296 # directly as sys.displayhook
2267 if generics is not None:
2297 if generics is not None:
2268 def display_display(obj):
2298 def display_display(obj):
2269 return obj.display()
2299 return obj.display()
2270 generics.result_display.when_type(Display)(display_display)
2300 generics.result_display.when_type(Display)(display_display)
2271
2301
2272 def display_tableobject(obj):
2302 def display_tableobject(obj):
2273 return display_display(defaultdisplay(obj))
2303 return display_display(defaultdisplay(obj))
2274 generics.result_display.when_type(Table)(display_tableobject)
2304 generics.result_display.when_type(Table)(display_tableobject)
2275
2305
2276 def display_tableclass(obj):
2306 def display_tableclass(obj):
2277 return display_tableobject(obj())
2307 return display_tableobject(obj())
2278 generics.result_display.when_type(Table.__metaclass__)(display_tableclass)
2308 generics.result_display.when_type(Table.__metaclass__)(display_tableclass)
2279 else:
2309 else:
2280 def installdisplayhook():
2310 def installdisplayhook():
2281 _originalhook = sys.displayhook
2311 _originalhook = sys.displayhook
2282 def displayhook(obj):
2312 def displayhook(obj):
2283 if isinstance(obj, type) and issubclass(obj, Table):
2313 if isinstance(obj, type) and issubclass(obj, Table):
2284 obj = obj()
2314 obj = obj()
2285 if isinstance(obj, Table):
2315 if isinstance(obj, Table):
2286 obj = defaultdisplay(obj)
2316 obj = defaultdisplay(obj)
2287 if isinstance(obj, Display):
2317 if isinstance(obj, Display):
2288 return obj.display()
2318 return obj.display()
2289 else:
2319 else:
2290 _originalhook(obj)
2320 _originalhook(obj)
2291 sys.displayhook = displayhook
2321 sys.displayhook = displayhook
2292 installdisplayhook()
2322 installdisplayhook()
@@ -1,592 +1,578 b''
1 """ ILeo - Leo plugin for IPython
1 """ ILeo - Leo plugin for IPython
2
2
3
3
4 """
4 """
5 import IPython.ipapi
5 import IPython.ipapi
6 import IPython.genutils
6 import IPython.genutils
7 import IPython.generics
7 import IPython.generics
8 from IPython.hooks import CommandChainDispatcher
8 from IPython.hooks import CommandChainDispatcher
9 import re
9 import re
10 import UserDict
10 import UserDict
11 from IPython.ipapi import TryNext
11 from IPython.ipapi import TryNext
12 import IPython.macro
12 import IPython.macro
13 import IPython.Shell
13 import IPython.Shell
14
14
15 def init_ipython(ipy):
15 def init_ipython(ipy):
16 """ This will be run by _ip.load('ipy_leo')
16 """ This will be run by _ip.load('ipy_leo')
17
17
18 Leo still needs to run update_commander() after this.
18 Leo still needs to run update_commander() after this.
19
19
20 """
20 """
21 global ip
21 global ip
22 ip = ipy
22 ip = ipy
23 IPython.Shell.hijack_tk()
23 IPython.Shell.hijack_tk()
24 ip.set_hook('complete_command', mb_completer, str_key = '%mb')
24 ip.set_hook('complete_command', mb_completer, str_key = '%mb')
25 ip.expose_magic('mb',mb_f)
25 ip.expose_magic('mb',mb_f)
26 ip.expose_magic('lee',lee_f)
26 ip.expose_magic('lee',lee_f)
27 ip.expose_magic('leoref',leoref_f)
27 ip.expose_magic('leoref',leoref_f)
28 expose_ileo_push(push_cl_node,100)
28 expose_ileo_push(push_cl_node,100)
29 # this should be the LAST one that will be executed, and it will never raise TryNext
29 # this should be the LAST one that will be executed, and it will never raise TryNext
30 expose_ileo_push(push_ipython_script, 1000)
30 expose_ileo_push(push_ipython_script, 1000)
31 expose_ileo_push(push_plain_python, 100)
31 expose_ileo_push(push_plain_python, 100)
32 expose_ileo_push(push_ev_node, 100)
32 expose_ileo_push(push_ev_node, 100)
33 global wb
33 global wb
34 wb = LeoWorkbook()
34 wb = LeoWorkbook()
35 ip.user_ns['wb'] = wb
35 ip.user_ns['wb'] = wb
36
36
37 show_welcome()
37 show_welcome()
38
38
39
39
40 def update_commander(new_leox):
40 def update_commander(new_leox):
41 """ Set the Leo commander to use
41 """ Set the Leo commander to use
42
42
43 This will be run every time Leo does ipython-launch; basically,
43 This will be run every time Leo does ipython-launch; basically,
44 when the user switches the document he is focusing on, he should do
44 when the user switches the document he is focusing on, he should do
45 ipython-launch to tell ILeo what document the commands apply to.
45 ipython-launch to tell ILeo what document the commands apply to.
46
46
47 """
47 """
48
48
49 global c,g
49 global c,g
50 c,g = new_leox.c, new_leox.g
50 c,g = new_leox.c, new_leox.g
51 print "Set Leo Commander:",c.frame.getTitle()
51 print "Set Leo Commander:",c.frame.getTitle()
52
52
53 # will probably be overwritten by user, but handy for experimentation early on
53 # will probably be overwritten by user, but handy for experimentation early on
54 ip.user_ns['c'] = c
54 ip.user_ns['c'] = c
55 ip.user_ns['g'] = g
55 ip.user_ns['g'] = g
56 ip.user_ns['_leo'] = new_leox
56 ip.user_ns['_leo'] = new_leox
57
57
58 new_leox.push = push_position_from_leo
58 new_leox.push = push_position_from_leo
59 run_leo_startup_node()
59 run_leo_startup_node()
60
60
61 from IPython.external.simplegeneric import generic
61 from IPython.external.simplegeneric import generic
62 import pprint
62 import pprint
63
63
64 def es(s):
64 def es(s):
65 g.es(s, tabName = 'IPython')
65 g.es(s, tabName = 'IPython')
66 pass
66 pass
67
67
68 @generic
68 @generic
69 def format_for_leo(obj):
69 def format_for_leo(obj):
70 """ Convert obj to string representiation (for editing in Leo)"""
70 """ Convert obj to string representiation (for editing in Leo)"""
71 return pprint.pformat(obj)
71 return pprint.pformat(obj)
72
72
73 @format_for_leo.when_type(list)
73 @format_for_leo.when_type(list)
74 def format_list(obj):
74 def format_list(obj):
75 return "\n".join(str(s) for s in obj)
75 return "\n".join(str(s) for s in obj)
76
76
77
77
78 attribute_re = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$')
78 attribute_re = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$')
79 def valid_attribute(s):
79 def valid_attribute(s):
80 return attribute_re.match(s)
80 return attribute_re.match(s)
81
81
82 _rootnode = None
82 _rootnode = None
83 def rootnode():
83 def rootnode():
84 """ Get ileo root node (@ipy-root)
84 """ Get ileo root node (@ipy-root)
85
85
86 if node has become invalid or has not been set, return None
86 if node has become invalid or has not been set, return None
87
87
88 Note that the root is the *first* @ipy-root item found
88 Note that the root is the *first* @ipy-root item found
89 """
89 """
90 global _rootnode
90 global _rootnode
91 if _rootnode is None:
91 if _rootnode is None:
92 return None
92 return None
93 if c.positionExists(_rootnode.p):
93 if c.positionExists(_rootnode.p):
94 return _rootnode
94 return _rootnode
95 _rootnode = None
95 _rootnode = None
96 return None
96 return None
97
97
98 def all_cells():
98 def all_cells():
99 global _rootnode
99 global _rootnode
100 d = {}
100 d = {}
101 r = rootnode()
101 r = rootnode()
102 if r is not None:
102 if r is not None:
103 nodes = r.p.children_iter()
103 nodes = r.p.children_iter()
104 else:
104 else:
105 nodes = c.allNodes_iter()
105 nodes = c.allNodes_iter()
106
106
107 for p in nodes:
107 for p in nodes:
108 h = p.headString()
108 h = p.headString()
109 if h.strip() == '@ipy-root':
109 if h.strip() == '@ipy-root':
110 # update root node (found it for the first time)
110 # update root node (found it for the first time)
111 _rootnode = LeoNode(p)
111 _rootnode = LeoNode(p)
112 # the next recursive call will use the children of new root
112 # the next recursive call will use the children of new root
113 return all_cells()
113 return all_cells()
114
114
115 if h.startswith('@a '):
115 if h.startswith('@a '):
116 d[h.lstrip('@a ').strip()] = p.parent().copy()
116 d[h.lstrip('@a ').strip()] = p.parent().copy()
117 elif not valid_attribute(h):
117 elif not valid_attribute(h):
118 continue
118 continue
119 d[h] = p.copy()
119 d[h] = p.copy()
120 return d
120 return d
121
121
122 def eval_node(n):
122 def eval_node(n):
123 body = n.b
123 body = n.b
124 if not body.startswith('@cl'):
124 if not body.startswith('@cl'):
125 # plain python repr node, just eval it
125 # plain python repr node, just eval it
126 return ip.ev(n.b)
126 return ip.ev(n.b)
127 # @cl nodes deserve special treatment - first eval the first line (minus cl), then use it to call the rest of body
127 # @cl nodes deserve special treatment - first eval the first line (minus cl), then use it to call the rest of body
128 first, rest = body.split('\n',1)
128 first, rest = body.split('\n',1)
129 tup = first.split(None, 1)
129 tup = first.split(None, 1)
130 # @cl alone SPECIAL USE-> dump var to user_ns
130 # @cl alone SPECIAL USE-> dump var to user_ns
131 if len(tup) == 1:
131 if len(tup) == 1:
132 val = ip.ev(rest)
132 val = ip.ev(rest)
133 ip.user_ns[n.h] = val
133 ip.user_ns[n.h] = val
134 es("%s = %s" % (n.h, repr(val)[:20] ))
134 es("%s = %s" % (n.h, repr(val)[:20] ))
135 return val
135 return val
136
136
137 cl, hd = tup
137 cl, hd = tup
138
138
139 xformer = ip.ev(hd.strip())
139 xformer = ip.ev(hd.strip())
140 es('Transform w/ %s' % repr(xformer))
140 es('Transform w/ %s' % repr(xformer))
141 return xformer(rest, n)
141 return xformer(rest, n)
142
142
143 class LeoNode(object, UserDict.DictMixin):
143 class LeoNode(object, UserDict.DictMixin):
144 """ Node in Leo outline
144 """ Node in Leo outline
145
145
146 Most important attributes (getters/setters available:
146 Most important attributes (getters/setters available:
147 .v - evaluate node, can also be alligned
147 .v - evaluate node, can also be alligned
148 .b, .h - body string, headline string
148 .b, .h - body string, headline string
149 .l - value as string list
149 .l - value as string list
150
150
151 Also supports iteration,
151 Also supports iteration,
152
152
153 setitem / getitem (indexing):
153 setitem / getitem (indexing):
154 wb.foo['key'] = 12
154 wb.foo['key'] = 12
155 assert wb.foo['key'].v == 12
155 assert wb.foo['key'].v == 12
156
156
157 Note the asymmetry on setitem and getitem! Also other
157 Note the asymmetry on setitem and getitem! Also other
158 dict methods are available.
158 dict methods are available.
159
159
160 .ipush() - run push-to-ipython
160 .ipush() - run push-to-ipython
161
161
162 Minibuffer command access (tab completion works):
162 Minibuffer command access (tab completion works):
163
163
164 mb save-to-file
164 mb save-to-file
165
165
166 """
166 """
167 def __init__(self,p):
167 def __init__(self,p):
168 self.p = p.copy()
168 self.p = p.copy()
169
169
170 def __str__(self):
170 def __str__(self):
171 return "<LeoNode %s>" % str(self.p)
171 return "<LeoNode %s>" % str(self.p)
172
172
173 __repr__ = __str__
173 __repr__ = __str__
174
174
175 def __get_h(self): return self.p.headString()
175 def __get_h(self): return self.p.headString()
176 def __set_h(self,val):
176 def __set_h(self,val):
177 print "set head",val
178 c.beginUpdate()
179 try:
180 c.setHeadString(self.p,val)
177 c.setHeadString(self.p,val)
181 finally:
178 c.redraw()
182 c.endUpdate()
183
179
184 h = property( __get_h, __set_h, doc = "Node headline string")
180 h = property( __get_h, __set_h, doc = "Node headline string")
185
181
186 def __get_b(self): return self.p.bodyString()
182 def __get_b(self): return self.p.bodyString()
187 def __set_b(self,val):
183 def __set_b(self,val):
188 print "set body",val
189 c.beginUpdate()
190 try:
191 c.setBodyString(self.p, val)
184 c.setBodyString(self.p, val)
192 finally:
185 c.redraw()
193 c.endUpdate()
194
186
195 b = property(__get_b, __set_b, doc = "Nody body string")
187 b = property(__get_b, __set_b, doc = "Nody body string")
196
188
197 def __set_val(self, val):
189 def __set_val(self, val):
198 self.b = format_for_leo(val)
190 self.b = format_for_leo(val)
199
191
200 v = property(lambda self: eval_node(self), __set_val, doc = "Node evaluated value")
192 v = property(lambda self: eval_node(self), __set_val, doc = "Node evaluated value")
201
193
202 def __set_l(self,val):
194 def __set_l(self,val):
203 self.b = '\n'.join(val )
195 self.b = '\n'.join(val )
204 l = property(lambda self : IPython.genutils.SList(self.b.splitlines()),
196 l = property(lambda self : IPython.genutils.SList(self.b.splitlines()),
205 __set_l, doc = "Node value as string list")
197 __set_l, doc = "Node value as string list")
206
198
207 def __iter__(self):
199 def __iter__(self):
208 """ Iterate through nodes direct children """
200 """ Iterate through nodes direct children """
209
201
210 return (LeoNode(p) for p in self.p.children_iter())
202 return (LeoNode(p) for p in self.p.children_iter())
211
203
212 def __children(self):
204 def __children(self):
213 d = {}
205 d = {}
214 for child in self:
206 for child in self:
215 head = child.h
207 head = child.h
216 tup = head.split(None,1)
208 tup = head.split(None,1)
217 if len(tup) > 1 and tup[0] == '@k':
209 if len(tup) > 1 and tup[0] == '@k':
218 d[tup[1]] = child
210 d[tup[1]] = child
219 continue
211 continue
220
212
221 if not valid_attribute(head):
213 if not valid_attribute(head):
222 d[head] = child
214 d[head] = child
223 continue
215 continue
224 return d
216 return d
225 def keys(self):
217 def keys(self):
226 d = self.__children()
218 d = self.__children()
227 return d.keys()
219 return d.keys()
228 def __getitem__(self, key):
220 def __getitem__(self, key):
229 """ wb.foo['Some stuff'] Return a child node with headline 'Some stuff'
221 """ wb.foo['Some stuff'] Return a child node with headline 'Some stuff'
230
222
231 If key is a valid python name (e.g. 'foo'), look for headline '@k foo' as well
223 If key is a valid python name (e.g. 'foo'), look for headline '@k foo' as well
232 """
224 """
233 key = str(key)
225 key = str(key)
234 d = self.__children()
226 d = self.__children()
235 return d[key]
227 return d[key]
236 def __setitem__(self, key, val):
228 def __setitem__(self, key, val):
237 """ You can do wb.foo['My Stuff'] = 12 to create children
229 """ You can do wb.foo['My Stuff'] = 12 to create children
238
230
239 This will create 'My Stuff' as a child of foo (if it does not exist), and
231 This will create 'My Stuff' as a child of foo (if it does not exist), and
240 do .v = 12 assignment.
232 do .v = 12 assignment.
241
233
242 Exception:
234 Exception:
243
235
244 wb.foo['bar'] = 12
236 wb.foo['bar'] = 12
245
237
246 will create a child with headline '@k bar', because bar is a valid python name
238 will create a child with headline '@k bar', because bar is a valid python name
247 and we don't want to crowd the WorkBook namespace with (possibly numerous) entries
239 and we don't want to crowd the WorkBook namespace with (possibly numerous) entries
248 """
240 """
249 key = str(key)
241 key = str(key)
250 d = self.__children()
242 d = self.__children()
251 if key in d:
243 if key in d:
252 d[key].v = val
244 d[key].v = val
253 return
245 return
254
246
255 if not valid_attribute(key):
247 if not valid_attribute(key):
256 head = key
248 head = key
257 else:
249 else:
258 head = '@k ' + key
250 head = '@k ' + key
259 p = c.createLastChildNode(self.p, head, '')
251 p = c.createLastChildNode(self.p, head, '')
260 LeoNode(p).v = val
252 LeoNode(p).v = val
261
253
262 def ipush(self):
254 def ipush(self):
263 """ Does push-to-ipython on the node """
255 """ Does push-to-ipython on the node """
264 push_from_leo(self)
256 push_from_leo(self)
265
257
266 def go(self):
258 def go(self):
267 """ Set node as current node (to quickly see it in Outline) """
259 """ Set node as current node (to quickly see it in Outline) """
268 c.beginUpdate()
269 try:
270 c.setCurrentPosition(self.p)
260 c.setCurrentPosition(self.p)
271 finally:
261 c.redraw()
272 c.endUpdate()
273
262
274 def script(self):
263 def script(self):
275 """ Method to get the 'tangled' contents of the node
264 """ Method to get the 'tangled' contents of the node
276
265
277 (parse @others, << section >> references etc.)
266 (parse @others, << section >> references etc.)
278 """
267 """
279 return g.getScript(c,self.p,useSelectedText=False,useSentinels=False)
268 return g.getScript(c,self.p,useSelectedText=False,useSentinels=False)
280
269
281 def __get_uA(self):
270 def __get_uA(self):
282 p = self.p
271 p = self.p
283 # Create the uA if necessary.
272 # Create the uA if necessary.
284 if not hasattr(p.v.t,'unknownAttributes'):
273 if not hasattr(p.v.t,'unknownAttributes'):
285 p.v.t.unknownAttributes = {}
274 p.v.t.unknownAttributes = {}
286
275
287 d = p.v.t.unknownAttributes.setdefault('ipython', {})
276 d = p.v.t.unknownAttributes.setdefault('ipython', {})
288 return d
277 return d
289
278
290 uA = property(__get_uA, doc = "Access persistent unknownAttributes of node")
279 uA = property(__get_uA, doc = "Access persistent unknownAttributes of node")
291
280
292
281
293 class LeoWorkbook:
282 class LeoWorkbook:
294 """ class for 'advanced' node access
283 """ class for 'advanced' node access
295
284
296 Has attributes for all "discoverable" nodes. Node is discoverable if it
285 Has attributes for all "discoverable" nodes. Node is discoverable if it
297 either
286 either
298
287
299 - has a valid python name (Foo, bar_12)
288 - has a valid python name (Foo, bar_12)
300 - is a parent of an anchor node (if it has a child '@a foo', it is visible as foo)
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 def __getattr__(self, key):
292 def __getattr__(self, key):
304 if key.startswith('_') or key == 'trait_names' or not valid_attribute(key):
293 if key.startswith('_') or key == 'trait_names' or not valid_attribute(key):
305 raise AttributeError
294 raise AttributeError
306 cells = all_cells()
295 cells = all_cells()
307 p = cells.get(key, None)
296 p = cells.get(key, None)
308 if p is None:
297 if p is None:
309 return add_var(key)
298 return add_var(key)
310
299
311 return LeoNode(p)
300 return LeoNode(p)
312
301
313 def __str__(self):
302 def __str__(self):
314 return "<LeoWorkbook>"
303 return "<LeoWorkbook>"
315 def __setattr__(self,key, val):
304 def __setattr__(self,key, val):
316 raise AttributeError("Direct assignment to workbook denied, try wb.%s.v = %s" % (key,val))
305 raise AttributeError("Direct assignment to workbook denied, try wb.%s.v = %s" % (key,val))
317
306
318 __repr__ = __str__
307 __repr__ = __str__
319
308
320 def __iter__(self):
309 def __iter__(self):
321 """ Iterate all (even non-exposed) nodes """
310 """ Iterate all (even non-exposed) nodes """
322 cells = all_cells()
311 cells = all_cells()
323 return (LeoNode(p) for p in c.allNodes_iter())
312 return (LeoNode(p) for p in c.allNodes_iter())
324
313
325 current = property(lambda self: LeoNode(c.currentPosition()), doc = "Currently selected node")
314 current = property(lambda self: LeoNode(c.currentPosition()), doc = "Currently selected node")
326
315
327 def match_h(self, regex):
316 def match_h(self, regex):
328 cmp = re.compile(regex)
317 cmp = re.compile(regex)
329 for node in self:
318 for node in self:
330 if re.match(cmp, node.h, re.IGNORECASE):
319 if re.match(cmp, node.h, re.IGNORECASE):
331 yield node
320 yield node
332 return
321 return
333
322
334 @IPython.generics.complete_object.when_type(LeoWorkbook)
323 @IPython.generics.complete_object.when_type(LeoWorkbook)
335 def workbook_complete(obj, prev):
324 def workbook_complete(obj, prev):
336 return all_cells().keys() + [s for s in prev if not s.startswith('_')]
325 return all_cells().keys() + [s for s in prev if not s.startswith('_')]
337
326
338
327
339 def add_var(varname):
328 def add_var(varname):
340 c.beginUpdate()
341 r = rootnode()
329 r = rootnode()
342 try:
330 try:
343 if r is None:
331 if r is None:
344 p2 = g.findNodeAnywhere(c,varname)
332 p2 = g.findNodeAnywhere(c,varname)
345 else:
333 else:
346 p2 = g.findNodeInChildren(c, r.p, varname)
334 p2 = g.findNodeInChildren(c, r.p, varname)
347 if p2:
335 if p2:
348 return LeoNode(p2)
336 return LeoNode(p2)
349
337
350 if r is not None:
338 if r is not None:
351 p2 = r.p.insertAsLastChild()
339 p2 = r.p.insertAsLastChild()
352
340
353 else:
341 else:
354 p2 = c.currentPosition().insertAfter()
342 p2 = c.currentPosition().insertAfter()
355
343
356 c.setHeadString(p2,varname)
344 c.setHeadString(p2,varname)
357 return LeoNode(p2)
345 return LeoNode(p2)
358 finally:
346 finally:
359 c.endUpdate()
347 c.redraw()
360
348
361 def add_file(self,fname):
349 def add_file(self,fname):
362 p2 = c.currentPosition().insertAfter()
350 p2 = c.currentPosition().insertAfter()
363
351
364 push_from_leo = CommandChainDispatcher()
352 push_from_leo = CommandChainDispatcher()
365
353
366 def expose_ileo_push(f, prio = 0):
354 def expose_ileo_push(f, prio = 0):
367 push_from_leo.add(f, prio)
355 push_from_leo.add(f, prio)
368
356
369 def push_ipython_script(node):
357 def push_ipython_script(node):
370 """ Execute the node body in IPython, as if it was entered in interactive prompt """
358 """ Execute the node body in IPython, as if it was entered in interactive prompt """
371 c.beginUpdate()
372 try:
359 try:
373 ohist = ip.IP.output_hist
360 ohist = ip.IP.output_hist
374 hstart = len(ip.IP.input_hist)
361 hstart = len(ip.IP.input_hist)
375 script = node.script()
362 script = node.script()
376
363
377 ip.user_ns['_p'] = node
364 ip.user_ns['_p'] = node
378 ip.runlines(script)
365 ip.runlines(script)
379 ip.user_ns.pop('_p',None)
366 ip.user_ns.pop('_p',None)
380
367
381 has_output = False
368 has_output = False
382 for idx in range(hstart,len(ip.IP.input_hist)):
369 for idx in range(hstart,len(ip.IP.input_hist)):
383 val = ohist.get(idx,None)
370 val = ohist.get(idx,None)
384 if val is None:
371 if val is None:
385 continue
372 continue
386 has_output = True
373 has_output = True
387 inp = ip.IP.input_hist[idx]
374 inp = ip.IP.input_hist[idx]
388 if inp.strip():
375 if inp.strip():
389 es('In: %s' % (inp[:40], ))
376 es('In: %s' % (inp[:40], ))
390
377
391 es('<%d> %s' % (idx, pprint.pformat(ohist[idx],width = 40)))
378 es('<%d> %s' % (idx, pprint.pformat(ohist[idx],width = 40)))
392
379
393 if not has_output:
380 if not has_output:
394 es('ipy run: %s (%d LL)' %( node.h,len(script)))
381 es('ipy run: %s (%d LL)' %( node.h,len(script)))
395 finally:
382 finally:
396 c.endUpdate()
383 c.redraw()
397
384
398
385
399 def eval_body(body):
386 def eval_body(body):
400 try:
387 try:
401 val = ip.ev(body)
388 val = ip.ev(body)
402 except:
389 except:
403 # just use stringlist if it's not completely legal python expression
390 # just use stringlist if it's not completely legal python expression
404 val = IPython.genutils.SList(body.splitlines())
391 val = IPython.genutils.SList(body.splitlines())
405 return val
392 return val
406
393
407 def push_plain_python(node):
394 def push_plain_python(node):
408 if not node.h.endswith('P'):
395 if not node.h.endswith('P'):
409 raise TryNext
396 raise TryNext
410 script = node.script()
397 script = node.script()
411 lines = script.count('\n')
398 lines = script.count('\n')
412 try:
399 try:
413 exec script in ip.user_ns
400 exec script in ip.user_ns
414 except:
401 except:
415 print " -- Exception in script:\n"+script + "\n --"
402 print " -- Exception in script:\n"+script + "\n --"
416 raise
403 raise
417 es('ipy plain: %s (%d LL)' % (node.h,lines))
404 es('ipy plain: %s (%d LL)' % (node.h,lines))
418
405
419
406
420 def push_cl_node(node):
407 def push_cl_node(node):
421 """ If node starts with @cl, eval it
408 """ If node starts with @cl, eval it
422
409
423 The result is put as last child of @ipy-results node, if it exists
410 The result is put as last child of @ipy-results node, if it exists
424 """
411 """
425 if not node.b.startswith('@cl'):
412 if not node.b.startswith('@cl'):
426 raise TryNext
413 raise TryNext
427
414
428 p2 = g.findNodeAnywhere(c,'@ipy-results')
415 p2 = g.findNodeAnywhere(c,'@ipy-results')
429 val = node.v
416 val = node.v
430 if p2:
417 if p2:
431 es("=> @ipy-results")
418 es("=> @ipy-results")
432 LeoNode(p2).v = val
419 LeoNode(p2).v = val
433 es(val)
420 es(val)
434
421
435 def push_ev_node(node):
422 def push_ev_node(node):
436 """ If headline starts with @ev, eval it and put result in body """
423 """ If headline starts with @ev, eval it and put result in body """
437 if not node.h.startswith('@ev '):
424 if not node.h.startswith('@ev '):
438 raise TryNext
425 raise TryNext
439 expr = node.h.lstrip('@ev ')
426 expr = node.h.lstrip('@ev ')
440 es('ipy eval ' + expr)
427 es('ipy eval ' + expr)
441 res = ip.ev(expr)
428 res = ip.ev(expr)
442 node.v = res
429 node.v = res
443
430
444
431
445 def push_position_from_leo(p):
432 def push_position_from_leo(p):
446 try:
433 try:
447 push_from_leo(LeoNode(p))
434 push_from_leo(LeoNode(p))
448 except AttributeError,e:
435 except AttributeError,e:
449 if e.args == ("Commands instance has no attribute 'frame'",):
436 if e.args == ("Commands instance has no attribute 'frame'",):
450 es("Error: ILeo not associated with .leo document")
437 es("Error: ILeo not associated with .leo document")
451 es("Press alt+shift+I to fix!")
438 es("Press alt+shift+I to fix!")
452 else:
439 else:
453 raise
440 raise
454
441
455 @generic
442 @generic
456 def edit_object_in_leo(obj, varname):
443 def edit_object_in_leo(obj, varname):
457 """ Make it @cl node so it can be pushed back directly by alt+I """
444 """ Make it @cl node so it can be pushed back directly by alt+I """
458 node = add_var(varname)
445 node = add_var(varname)
459 formatted = format_for_leo(obj)
446 formatted = format_for_leo(obj)
460 if not formatted.startswith('@cl'):
447 if not formatted.startswith('@cl'):
461 formatted = '@cl\n' + formatted
448 formatted = '@cl\n' + formatted
462 node.b = formatted
449 node.b = formatted
463 node.go()
450 node.go()
464
451
465 @edit_object_in_leo.when_type(IPython.macro.Macro)
452 @edit_object_in_leo.when_type(IPython.macro.Macro)
466 def edit_macro(obj,varname):
453 def edit_macro(obj,varname):
467 bod = '_ip.defmacro("""\\\n' + obj.value + '""")'
454 bod = '_ip.defmacro("""\\\n' + obj.value + '""")'
468 node = add_var('Macro_' + varname)
455 node = add_var('Macro_' + varname)
469 node.b = bod
456 node.b = bod
470 node.go()
457 node.go()
471
458
472 def get_history(hstart = 0):
459 def get_history(hstart = 0):
473 res = []
460 res = []
474 ohist = ip.IP.output_hist
461 ohist = ip.IP.output_hist
475
462
476 for idx in range(hstart, len(ip.IP.input_hist)):
463 for idx in range(hstart, len(ip.IP.input_hist)):
477 val = ohist.get(idx,None)
464 val = ohist.get(idx,None)
478 has_output = True
465 has_output = True
479 inp = ip.IP.input_hist_raw[idx]
466 inp = ip.IP.input_hist_raw[idx]
480 if inp.strip():
467 if inp.strip():
481 res.append('In [%d]: %s' % (idx, inp))
468 res.append('In [%d]: %s' % (idx, inp))
482 if val:
469 if val:
483 res.append(pprint.pformat(val))
470 res.append(pprint.pformat(val))
484 res.append('\n')
471 res.append('\n')
485 return ''.join(res)
472 return ''.join(res)
486
473
487
474
488 def lee_f(self,s):
475 def lee_f(self,s):
489 """ Open file(s)/objects in Leo
476 """ Open file(s)/objects in Leo
490
477
491 - %lee hist -> open full session history in leo
478 - %lee hist -> open full session history in leo
492 - Takes an object. l = [1,2,"hello"]; %lee l. Alt+I in leo pushes the object back
479 - Takes an object. l = [1,2,"hello"]; %lee l. Alt+I in leo pushes the object back
493 - Takes an mglob pattern, e.g. '%lee *.cpp' or %lee 'rec:*.cpp'
480 - Takes an mglob pattern, e.g. '%lee *.cpp' or %lee 'rec:*.cpp'
494 - Takes input history indices: %lee 4 6-8 10 12-47
481 - Takes input history indices: %lee 4 6-8 10 12-47
495 """
482 """
496 import os
483 import os
497
484
498 c.beginUpdate()
499 try:
485 try:
500 if s == 'hist':
486 if s == 'hist':
501 wb.ipython_history.b = get_history()
487 wb.ipython_history.b = get_history()
502 wb.ipython_history.go()
488 wb.ipython_history.go()
503 return
489 return
504
490
505
491
506 if s and s[0].isdigit():
492 if s and s[0].isdigit():
507 # numbers; push input slices to leo
493 # numbers; push input slices to leo
508 lines = self.extract_input_slices(s.strip().split(), True)
494 lines = self.extract_input_slices(s.strip().split(), True)
509 v = add_var('stored_ipython_input')
495 v = add_var('stored_ipython_input')
510 v.b = '\n'.join(lines)
496 v.b = '\n'.join(lines)
511 return
497 return
512
498
513
499
514 # try editing the object directly
500 # try editing the object directly
515 obj = ip.user_ns.get(s, None)
501 obj = ip.user_ns.get(s, None)
516 if obj is not None:
502 if obj is not None:
517 edit_object_in_leo(obj,s)
503 edit_object_in_leo(obj,s)
518 return
504 return
519
505
520
506
521 # if it's not object, it's a file name / mglob pattern
507 # if it's not object, it's a file name / mglob pattern
522 from IPython.external import mglob
508 from IPython.external import mglob
523
509
524 files = (os.path.abspath(f) for f in mglob.expand(s))
510 files = (os.path.abspath(f) for f in mglob.expand(s))
525 for fname in files:
511 for fname in files:
526 p = g.findNodeAnywhere(c,'@auto ' + fname)
512 p = g.findNodeAnywhere(c,'@auto ' + fname)
527 if not p:
513 if not p:
528 p = c.currentPosition().insertAfter()
514 p = c.currentPosition().insertAfter()
529
515
530 p.setHeadString('@auto ' + fname)
516 p.setHeadString('@auto ' + fname)
531 if os.path.isfile(fname):
517 if os.path.isfile(fname):
532 c.setBodyString(p,open(fname).read())
518 c.setBodyString(p,open(fname).read())
533 c.selectPosition(p)
519 c.selectPosition(p)
534 print "Editing file(s), press ctrl+shift+w in Leo to write @auto nodes"
520 print "Editing file(s), press ctrl+shift+w in Leo to write @auto nodes"
535 finally:
521 finally:
536 c.endUpdate()
522 c.redraw()
537
523
538
524
539
525
540 def leoref_f(self,s):
526 def leoref_f(self,s):
541 """ Quick reference for ILeo """
527 """ Quick reference for ILeo """
542 import textwrap
528 import textwrap
543 print textwrap.dedent("""\
529 print textwrap.dedent("""\
544 %leoe file/object - open file / object in leo
530 %leoe file/object - open file / object in leo
545 wb.foo.v - eval node foo (i.e. headstring is 'foo' or '@ipy foo')
531 wb.foo.v - eval node foo (i.e. headstring is 'foo' or '@ipy foo')
546 wb.foo.v = 12 - assign to body of node foo
532 wb.foo.v = 12 - assign to body of node foo
547 wb.foo.b - read or write the body of node foo
533 wb.foo.b - read or write the body of node foo
548 wb.foo.l - body of node foo as string list
534 wb.foo.l - body of node foo as string list
549
535
550 for el in wb.foo:
536 for el in wb.foo:
551 print el.v
537 print el.v
552
538
553 """
539 """
554 )
540 )
555
541
556
542
557
543
558 def mb_f(self, arg):
544 def mb_f(self, arg):
559 """ Execute leo minibuffer commands
545 """ Execute leo minibuffer commands
560
546
561 Example:
547 Example:
562 mb save-to-file
548 mb save-to-file
563 """
549 """
564 c.executeMinibufferCommand(arg)
550 c.executeMinibufferCommand(arg)
565
551
566 def mb_completer(self,event):
552 def mb_completer(self,event):
567 """ Custom completer for minibuffer """
553 """ Custom completer for minibuffer """
568 cmd_param = event.line.split()
554 cmd_param = event.line.split()
569 if event.line.endswith(' '):
555 if event.line.endswith(' '):
570 cmd_param.append('')
556 cmd_param.append('')
571 if len(cmd_param) > 2:
557 if len(cmd_param) > 2:
572 return ip.IP.Completer.file_matches(event.symbol)
558 return ip.IP.Completer.file_matches(event.symbol)
573 cmds = c.commandsDict.keys()
559 cmds = c.commandsDict.keys()
574 cmds.sort()
560 cmds.sort()
575 return cmds
561 return cmds
576
562
577 def show_welcome():
563 def show_welcome():
578 print "------------------"
564 print "------------------"
579 print "Welcome to Leo-enabled IPython session!"
565 print "Welcome to Leo-enabled IPython session!"
580 print "Try %leoref for quick reference."
566 print "Try %leoref for quick reference."
581 import IPython.platutils
567 import IPython.platutils
582 IPython.platutils.set_term_title('ILeo')
568 IPython.platutils.set_term_title('ILeo')
583 IPython.platutils.freeze_term_title()
569 IPython.platutils.freeze_term_title()
584
570
585 def run_leo_startup_node():
571 def run_leo_startup_node():
586 p = g.findNodeAnywhere(c,'@ipy-startup')
572 p = g.findNodeAnywhere(c,'@ipy-startup')
587 if p:
573 if p:
588 print "Running @ipy-startup nodes"
574 print "Running @ipy-startup nodes"
589 for n in LeoNode(p):
575 for n in LeoNode(p):
590 push_from_leo(n)
576 push_from_leo(n)
591
577
592
578
@@ -1,3318 +1,3350 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Magic functions for InteractiveShell.
2 """Magic functions for InteractiveShell.
3
3
4 $Id: Magic.py 2996 2008-01-30 06:31:39Z fperez $"""
4 $Id: Magic.py 2996 2008-01-30 06:31:39Z fperez $"""
5
5
6 #*****************************************************************************
6 #*****************************************************************************
7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
8 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
8 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
9 #
9 #
10 # Distributed under the terms of the BSD License. The full license is in
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
11 # the file COPYING, distributed as part of this software.
12 #*****************************************************************************
12 #*****************************************************************************
13
13
14 #****************************************************************************
14 #****************************************************************************
15 # Modules and globals
15 # Modules and globals
16
16
17 from IPython import Release
17 from IPython import Release
18 __author__ = '%s <%s>\n%s <%s>' % \
18 __author__ = '%s <%s>\n%s <%s>' % \
19 ( Release.authors['Janko'] + Release.authors['Fernando'] )
19 ( Release.authors['Janko'] + Release.authors['Fernando'] )
20 __license__ = Release.license
20 __license__ = Release.license
21
21
22 # Python standard modules
22 # Python standard modules
23 import __builtin__
23 import __builtin__
24 import bdb
24 import bdb
25 import inspect
25 import inspect
26 import os
26 import os
27 import pdb
27 import pdb
28 import pydoc
28 import pydoc
29 import sys
29 import sys
30 import re
30 import re
31 import tempfile
31 import tempfile
32 import time
32 import time
33 import cPickle as pickle
33 import cPickle as pickle
34 import textwrap
34 import textwrap
35 from cStringIO import StringIO
35 from cStringIO import StringIO
36 from getopt import getopt,GetoptError
36 from getopt import getopt,GetoptError
37 from pprint import pprint, pformat
37 from pprint import pprint, pformat
38 from sets import Set
38 from sets import Set
39
39
40 # cProfile was added in Python2.5
40 # cProfile was added in Python2.5
41 try:
41 try:
42 import cProfile as profile
42 import cProfile as profile
43 import pstats
43 import pstats
44 except ImportError:
44 except ImportError:
45 # profile isn't bundled by default in Debian for license reasons
45 # profile isn't bundled by default in Debian for license reasons
46 try:
46 try:
47 import profile,pstats
47 import profile,pstats
48 except ImportError:
48 except ImportError:
49 profile = pstats = None
49 profile = pstats = None
50
50
51 # Homebrewed
51 # Homebrewed
52 import IPython
52 import IPython
53 from IPython import Debugger, OInspect, wildcard
53 from IPython import Debugger, OInspect, wildcard
54 from IPython.FakeModule import FakeModule
54 from IPython.FakeModule import FakeModule
55 from IPython.Itpl import Itpl, itpl, printpl,itplns
55 from IPython.Itpl import Itpl, itpl, printpl,itplns
56 from IPython.PyColorize import Parser
56 from IPython.PyColorize import Parser
57 from IPython.ipstruct import Struct
57 from IPython.ipstruct import Struct
58 from IPython.macro import Macro
58 from IPython.macro import Macro
59 from IPython.genutils import *
59 from IPython.genutils import *
60 from IPython import platutils
60 from IPython import platutils
61 import IPython.generics
61 import IPython.generics
62 import IPython.ipapi
62 import IPython.ipapi
63 from IPython.ipapi import UsageError
63 from IPython.ipapi import UsageError
64 from IPython.testing import decorators as testdec
65
64 #***************************************************************************
66 #***************************************************************************
65 # Utility functions
67 # Utility functions
66 def on_off(tag):
68 def on_off(tag):
67 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
69 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
68 return ['OFF','ON'][tag]
70 return ['OFF','ON'][tag]
69
71
70 class Bunch: pass
72 class Bunch: pass
71
73
72 def compress_dhist(dh):
74 def compress_dhist(dh):
73 head, tail = dh[:-10], dh[-10:]
75 head, tail = dh[:-10], dh[-10:]
74
76
75 newhead = []
77 newhead = []
76 done = Set()
78 done = Set()
77 for h in head:
79 for h in head:
78 if h in done:
80 if h in done:
79 continue
81 continue
80 newhead.append(h)
82 newhead.append(h)
81 done.add(h)
83 done.add(h)
82
84
83 return newhead + tail
85 return newhead + tail
84
86
85
87
86 #***************************************************************************
88 #***************************************************************************
87 # Main class implementing Magic functionality
89 # Main class implementing Magic functionality
88 class Magic:
90 class Magic:
89 """Magic functions for InteractiveShell.
91 """Magic functions for InteractiveShell.
90
92
91 Shell functions which can be reached as %function_name. All magic
93 Shell functions which can be reached as %function_name. All magic
92 functions should accept a string, which they can parse for their own
94 functions should accept a string, which they can parse for their own
93 needs. This can make some functions easier to type, eg `%cd ../`
95 needs. This can make some functions easier to type, eg `%cd ../`
94 vs. `%cd("../")`
96 vs. `%cd("../")`
95
97
96 ALL definitions MUST begin with the prefix magic_. The user won't need it
98 ALL definitions MUST begin with the prefix magic_. The user won't need it
97 at the command line, but it is is needed in the definition. """
99 at the command line, but it is is needed in the definition. """
98
100
99 # class globals
101 # class globals
100 auto_status = ['Automagic is OFF, % prefix IS needed for magic functions.',
102 auto_status = ['Automagic is OFF, % prefix IS needed for magic functions.',
101 'Automagic is ON, % prefix NOT needed for magic functions.']
103 'Automagic is ON, % prefix NOT needed for magic functions.']
102
104
103 #......................................................................
105 #......................................................................
104 # some utility functions
106 # some utility functions
105
107
106 def __init__(self,shell):
108 def __init__(self,shell):
107
109
108 self.options_table = {}
110 self.options_table = {}
109 if profile is None:
111 if profile is None:
110 self.magic_prun = self.profile_missing_notice
112 self.magic_prun = self.profile_missing_notice
111 self.shell = shell
113 self.shell = shell
112
114
113 # namespace for holding state we may need
115 # namespace for holding state we may need
114 self._magic_state = Bunch()
116 self._magic_state = Bunch()
115
117
116 def profile_missing_notice(self, *args, **kwargs):
118 def profile_missing_notice(self, *args, **kwargs):
117 error("""\
119 error("""\
118 The profile module could not be found. It has been removed from the standard
120 The profile module could not be found. It has been removed from the standard
119 python packages because of its non-free license. To use profiling, install the
121 python packages because of its non-free license. To use profiling, install the
120 python-profiler package from non-free.""")
122 python-profiler package from non-free.""")
121
123
122 def default_option(self,fn,optstr):
124 def default_option(self,fn,optstr):
123 """Make an entry in the options_table for fn, with value optstr"""
125 """Make an entry in the options_table for fn, with value optstr"""
124
126
125 if fn not in self.lsmagic():
127 if fn not in self.lsmagic():
126 error("%s is not a magic function" % fn)
128 error("%s is not a magic function" % fn)
127 self.options_table[fn] = optstr
129 self.options_table[fn] = optstr
128
130
129 def lsmagic(self):
131 def lsmagic(self):
130 """Return a list of currently available magic functions.
132 """Return a list of currently available magic functions.
131
133
132 Gives a list of the bare names after mangling (['ls','cd', ...], not
134 Gives a list of the bare names after mangling (['ls','cd', ...], not
133 ['magic_ls','magic_cd',...]"""
135 ['magic_ls','magic_cd',...]"""
134
136
135 # FIXME. This needs a cleanup, in the way the magics list is built.
137 # FIXME. This needs a cleanup, in the way the magics list is built.
136
138
137 # magics in class definition
139 # magics in class definition
138 class_magic = lambda fn: fn.startswith('magic_') and \
140 class_magic = lambda fn: fn.startswith('magic_') and \
139 callable(Magic.__dict__[fn])
141 callable(Magic.__dict__[fn])
140 # in instance namespace (run-time user additions)
142 # in instance namespace (run-time user additions)
141 inst_magic = lambda fn: fn.startswith('magic_') and \
143 inst_magic = lambda fn: fn.startswith('magic_') and \
142 callable(self.__dict__[fn])
144 callable(self.__dict__[fn])
143 # and bound magics by user (so they can access self):
145 # and bound magics by user (so they can access self):
144 inst_bound_magic = lambda fn: fn.startswith('magic_') and \
146 inst_bound_magic = lambda fn: fn.startswith('magic_') and \
145 callable(self.__class__.__dict__[fn])
147 callable(self.__class__.__dict__[fn])
146 magics = filter(class_magic,Magic.__dict__.keys()) + \
148 magics = filter(class_magic,Magic.__dict__.keys()) + \
147 filter(inst_magic,self.__dict__.keys()) + \
149 filter(inst_magic,self.__dict__.keys()) + \
148 filter(inst_bound_magic,self.__class__.__dict__.keys())
150 filter(inst_bound_magic,self.__class__.__dict__.keys())
149 out = []
151 out = []
150 for fn in Set(magics):
152 for fn in Set(magics):
151 out.append(fn.replace('magic_','',1))
153 out.append(fn.replace('magic_','',1))
152 out.sort()
154 out.sort()
153 return out
155 return out
154
156
155 def extract_input_slices(self,slices,raw=False):
157 def extract_input_slices(self,slices,raw=False):
156 """Return as a string a set of input history slices.
158 """Return as a string a set of input history slices.
157
159
158 Inputs:
160 Inputs:
159
161
160 - slices: the set of slices is given as a list of strings (like
162 - slices: the set of slices is given as a list of strings (like
161 ['1','4:8','9'], since this function is for use by magic functions
163 ['1','4:8','9'], since this function is for use by magic functions
162 which get their arguments as strings.
164 which get their arguments as strings.
163
165
164 Optional inputs:
166 Optional inputs:
165
167
166 - raw(False): by default, the processed input is used. If this is
168 - raw(False): by default, the processed input is used. If this is
167 true, the raw input history is used instead.
169 true, the raw input history is used instead.
168
170
169 Note that slices can be called with two notations:
171 Note that slices can be called with two notations:
170
172
171 N:M -> standard python form, means including items N...(M-1).
173 N:M -> standard python form, means including items N...(M-1).
172
174
173 N-M -> include items N..M (closed endpoint)."""
175 N-M -> include items N..M (closed endpoint)."""
174
176
175 if raw:
177 if raw:
176 hist = self.shell.input_hist_raw
178 hist = self.shell.input_hist_raw
177 else:
179 else:
178 hist = self.shell.input_hist
180 hist = self.shell.input_hist
179
181
180 cmds = []
182 cmds = []
181 for chunk in slices:
183 for chunk in slices:
182 if ':' in chunk:
184 if ':' in chunk:
183 ini,fin = map(int,chunk.split(':'))
185 ini,fin = map(int,chunk.split(':'))
184 elif '-' in chunk:
186 elif '-' in chunk:
185 ini,fin = map(int,chunk.split('-'))
187 ini,fin = map(int,chunk.split('-'))
186 fin += 1
188 fin += 1
187 else:
189 else:
188 ini = int(chunk)
190 ini = int(chunk)
189 fin = ini+1
191 fin = ini+1
190 cmds.append(hist[ini:fin])
192 cmds.append(hist[ini:fin])
191 return cmds
193 return cmds
192
194
193 def _ofind(self, oname, namespaces=None):
195 def _ofind(self, oname, namespaces=None):
194 """Find an object in the available namespaces.
196 """Find an object in the available namespaces.
195
197
196 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
198 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
197
199
198 Has special code to detect magic functions.
200 Has special code to detect magic functions.
199 """
201 """
200
202
201 oname = oname.strip()
203 oname = oname.strip()
202
204
203 alias_ns = None
205 alias_ns = None
204 if namespaces is None:
206 if namespaces is None:
205 # Namespaces to search in:
207 # Namespaces to search in:
206 # Put them in a list. The order is important so that we
208 # Put them in a list. The order is important so that we
207 # find things in the same order that Python finds them.
209 # find things in the same order that Python finds them.
208 namespaces = [ ('Interactive', self.shell.user_ns),
210 namespaces = [ ('Interactive', self.shell.user_ns),
209 ('IPython internal', self.shell.internal_ns),
211 ('IPython internal', self.shell.internal_ns),
210 ('Python builtin', __builtin__.__dict__),
212 ('Python builtin', __builtin__.__dict__),
211 ('Alias', self.shell.alias_table),
213 ('Alias', self.shell.alias_table),
212 ]
214 ]
213 alias_ns = self.shell.alias_table
215 alias_ns = self.shell.alias_table
214
216
215 # initialize results to 'null'
217 # initialize results to 'null'
216 found = 0; obj = None; ospace = None; ds = None;
218 found = 0; obj = None; ospace = None; ds = None;
217 ismagic = 0; isalias = 0; parent = None
219 ismagic = 0; isalias = 0; parent = None
218
220
219 # Look for the given name by splitting it in parts. If the head is
221 # Look for the given name by splitting it in parts. If the head is
220 # found, then we look for all the remaining parts as members, and only
222 # found, then we look for all the remaining parts as members, and only
221 # declare success if we can find them all.
223 # declare success if we can find them all.
222 oname_parts = oname.split('.')
224 oname_parts = oname.split('.')
223 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
225 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
224 for nsname,ns in namespaces:
226 for nsname,ns in namespaces:
225 try:
227 try:
226 obj = ns[oname_head]
228 obj = ns[oname_head]
227 except KeyError:
229 except KeyError:
228 continue
230 continue
229 else:
231 else:
230 #print 'oname_rest:', oname_rest # dbg
232 #print 'oname_rest:', oname_rest # dbg
231 for part in oname_rest:
233 for part in oname_rest:
232 try:
234 try:
233 parent = obj
235 parent = obj
234 obj = getattr(obj,part)
236 obj = getattr(obj,part)
235 except:
237 except:
236 # Blanket except b/c some badly implemented objects
238 # Blanket except b/c some badly implemented objects
237 # allow __getattr__ to raise exceptions other than
239 # allow __getattr__ to raise exceptions other than
238 # AttributeError, which then crashes IPython.
240 # AttributeError, which then crashes IPython.
239 break
241 break
240 else:
242 else:
241 # If we finish the for loop (no break), we got all members
243 # If we finish the for loop (no break), we got all members
242 found = 1
244 found = 1
243 ospace = nsname
245 ospace = nsname
244 if ns == alias_ns:
246 if ns == alias_ns:
245 isalias = 1
247 isalias = 1
246 break # namespace loop
248 break # namespace loop
247
249
248 # Try to see if it's magic
250 # Try to see if it's magic
249 if not found:
251 if not found:
250 if oname.startswith(self.shell.ESC_MAGIC):
252 if oname.startswith(self.shell.ESC_MAGIC):
251 oname = oname[1:]
253 oname = oname[1:]
252 obj = getattr(self,'magic_'+oname,None)
254 obj = getattr(self,'magic_'+oname,None)
253 if obj is not None:
255 if obj is not None:
254 found = 1
256 found = 1
255 ospace = 'IPython internal'
257 ospace = 'IPython internal'
256 ismagic = 1
258 ismagic = 1
257
259
258 # Last try: special-case some literals like '', [], {}, etc:
260 # Last try: special-case some literals like '', [], {}, etc:
259 if not found and oname_head in ["''",'""','[]','{}','()']:
261 if not found and oname_head in ["''",'""','[]','{}','()']:
260 obj = eval(oname_head)
262 obj = eval(oname_head)
261 found = 1
263 found = 1
262 ospace = 'Interactive'
264 ospace = 'Interactive'
263
265
264 return {'found':found, 'obj':obj, 'namespace':ospace,
266 return {'found':found, 'obj':obj, 'namespace':ospace,
265 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
267 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
266
268
267 def arg_err(self,func):
269 def arg_err(self,func):
268 """Print docstring if incorrect arguments were passed"""
270 """Print docstring if incorrect arguments were passed"""
269 print 'Error in arguments:'
271 print 'Error in arguments:'
270 print OInspect.getdoc(func)
272 print OInspect.getdoc(func)
271
273
272 def format_latex(self,strng):
274 def format_latex(self,strng):
273 """Format a string for latex inclusion."""
275 """Format a string for latex inclusion."""
274
276
275 # Characters that need to be escaped for latex:
277 # Characters that need to be escaped for latex:
276 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
278 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
277 # Magic command names as headers:
279 # Magic command names as headers:
278 cmd_name_re = re.compile(r'^(%s.*?):' % self.shell.ESC_MAGIC,
280 cmd_name_re = re.compile(r'^(%s.*?):' % self.shell.ESC_MAGIC,
279 re.MULTILINE)
281 re.MULTILINE)
280 # Magic commands
282 # Magic commands
281 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % self.shell.ESC_MAGIC,
283 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % self.shell.ESC_MAGIC,
282 re.MULTILINE)
284 re.MULTILINE)
283 # Paragraph continue
285 # Paragraph continue
284 par_re = re.compile(r'\\$',re.MULTILINE)
286 par_re = re.compile(r'\\$',re.MULTILINE)
285
287
286 # The "\n" symbol
288 # The "\n" symbol
287 newline_re = re.compile(r'\\n')
289 newline_re = re.compile(r'\\n')
288
290
289 # Now build the string for output:
291 # Now build the string for output:
290 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
292 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
291 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
293 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
292 strng)
294 strng)
293 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
295 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
294 strng = par_re.sub(r'\\\\',strng)
296 strng = par_re.sub(r'\\\\',strng)
295 strng = escape_re.sub(r'\\\1',strng)
297 strng = escape_re.sub(r'\\\1',strng)
296 strng = newline_re.sub(r'\\textbackslash{}n',strng)
298 strng = newline_re.sub(r'\\textbackslash{}n',strng)
297 return strng
299 return strng
298
300
299 def format_screen(self,strng):
301 def format_screen(self,strng):
300 """Format a string for screen printing.
302 """Format a string for screen printing.
301
303
302 This removes some latex-type format codes."""
304 This removes some latex-type format codes."""
303 # Paragraph continue
305 # Paragraph continue
304 par_re = re.compile(r'\\$',re.MULTILINE)
306 par_re = re.compile(r'\\$',re.MULTILINE)
305 strng = par_re.sub('',strng)
307 strng = par_re.sub('',strng)
306 return strng
308 return strng
307
309
308 def parse_options(self,arg_str,opt_str,*long_opts,**kw):
310 def parse_options(self,arg_str,opt_str,*long_opts,**kw):
309 """Parse options passed to an argument string.
311 """Parse options passed to an argument string.
310
312
311 The interface is similar to that of getopt(), but it returns back a
313 The interface is similar to that of getopt(), but it returns back a
312 Struct with the options as keys and the stripped argument string still
314 Struct with the options as keys and the stripped argument string still
313 as a string.
315 as a string.
314
316
315 arg_str is quoted as a true sys.argv vector by using shlex.split.
317 arg_str is quoted as a true sys.argv vector by using shlex.split.
316 This allows us to easily expand variables, glob files, quote
318 This allows us to easily expand variables, glob files, quote
317 arguments, etc.
319 arguments, etc.
318
320
319 Options:
321 Options:
320 -mode: default 'string'. If given as 'list', the argument string is
322 -mode: default 'string'. If given as 'list', the argument string is
321 returned as a list (split on whitespace) instead of a string.
323 returned as a list (split on whitespace) instead of a string.
322
324
323 -list_all: put all option values in lists. Normally only options
325 -list_all: put all option values in lists. Normally only options
324 appearing more than once are put in a list.
326 appearing more than once are put in a list.
325
327
326 -posix (True): whether to split the input line in POSIX mode or not,
328 -posix (True): whether to split the input line in POSIX mode or not,
327 as per the conventions outlined in the shlex module from the
329 as per the conventions outlined in the shlex module from the
328 standard library."""
330 standard library."""
329
331
330 # inject default options at the beginning of the input line
332 # inject default options at the beginning of the input line
331 caller = sys._getframe(1).f_code.co_name.replace('magic_','')
333 caller = sys._getframe(1).f_code.co_name.replace('magic_','')
332 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
334 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
333
335
334 mode = kw.get('mode','string')
336 mode = kw.get('mode','string')
335 if mode not in ['string','list']:
337 if mode not in ['string','list']:
336 raise ValueError,'incorrect mode given: %s' % mode
338 raise ValueError,'incorrect mode given: %s' % mode
337 # Get options
339 # Get options
338 list_all = kw.get('list_all',0)
340 list_all = kw.get('list_all',0)
339 posix = kw.get('posix',True)
341 posix = kw.get('posix',True)
340
342
341 # Check if we have more than one argument to warrant extra processing:
343 # Check if we have more than one argument to warrant extra processing:
342 odict = {} # Dictionary with options
344 odict = {} # Dictionary with options
343 args = arg_str.split()
345 args = arg_str.split()
344 if len(args) >= 1:
346 if len(args) >= 1:
345 # If the list of inputs only has 0 or 1 thing in it, there's no
347 # If the list of inputs only has 0 or 1 thing in it, there's no
346 # need to look for options
348 # need to look for options
347 argv = arg_split(arg_str,posix)
349 argv = arg_split(arg_str,posix)
348 # Do regular option processing
350 # Do regular option processing
349 try:
351 try:
350 opts,args = getopt(argv,opt_str,*long_opts)
352 opts,args = getopt(argv,opt_str,*long_opts)
351 except GetoptError,e:
353 except GetoptError,e:
352 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
354 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
353 " ".join(long_opts)))
355 " ".join(long_opts)))
354 for o,a in opts:
356 for o,a in opts:
355 if o.startswith('--'):
357 if o.startswith('--'):
356 o = o[2:]
358 o = o[2:]
357 else:
359 else:
358 o = o[1:]
360 o = o[1:]
359 try:
361 try:
360 odict[o].append(a)
362 odict[o].append(a)
361 except AttributeError:
363 except AttributeError:
362 odict[o] = [odict[o],a]
364 odict[o] = [odict[o],a]
363 except KeyError:
365 except KeyError:
364 if list_all:
366 if list_all:
365 odict[o] = [a]
367 odict[o] = [a]
366 else:
368 else:
367 odict[o] = a
369 odict[o] = a
368
370
369 # Prepare opts,args for return
371 # Prepare opts,args for return
370 opts = Struct(odict)
372 opts = Struct(odict)
371 if mode == 'string':
373 if mode == 'string':
372 args = ' '.join(args)
374 args = ' '.join(args)
373
375
374 return opts,args
376 return opts,args
375
377
376 #......................................................................
378 #......................................................................
377 # And now the actual magic functions
379 # And now the actual magic functions
378
380
379 # Functions for IPython shell work (vars,funcs, config, etc)
381 # Functions for IPython shell work (vars,funcs, config, etc)
380 def magic_lsmagic(self, parameter_s = ''):
382 def magic_lsmagic(self, parameter_s = ''):
381 """List currently available magic functions."""
383 """List currently available magic functions."""
382 mesc = self.shell.ESC_MAGIC
384 mesc = self.shell.ESC_MAGIC
383 print 'Available magic functions:\n'+mesc+\
385 print 'Available magic functions:\n'+mesc+\
384 (' '+mesc).join(self.lsmagic())
386 (' '+mesc).join(self.lsmagic())
385 print '\n' + Magic.auto_status[self.shell.rc.automagic]
387 print '\n' + Magic.auto_status[self.shell.rc.automagic]
386 return None
388 return None
387
389
388 def magic_magic(self, parameter_s = ''):
390 def magic_magic(self, parameter_s = ''):
389 """Print information about the magic function system.
391 """Print information about the magic function system.
390
392
391 Supported formats: -latex, -brief, -rest
393 Supported formats: -latex, -brief, -rest
392 """
394 """
393
395
394 mode = ''
396 mode = ''
395 try:
397 try:
396 if parameter_s.split()[0] == '-latex':
398 if parameter_s.split()[0] == '-latex':
397 mode = 'latex'
399 mode = 'latex'
398 if parameter_s.split()[0] == '-brief':
400 if parameter_s.split()[0] == '-brief':
399 mode = 'brief'
401 mode = 'brief'
400 if parameter_s.split()[0] == '-rest':
402 if parameter_s.split()[0] == '-rest':
401 mode = 'rest'
403 mode = 'rest'
402 rest_docs = []
404 rest_docs = []
403 except:
405 except:
404 pass
406 pass
405
407
406 magic_docs = []
408 magic_docs = []
407 for fname in self.lsmagic():
409 for fname in self.lsmagic():
408 mname = 'magic_' + fname
410 mname = 'magic_' + fname
409 for space in (Magic,self,self.__class__):
411 for space in (Magic,self,self.__class__):
410 try:
412 try:
411 fn = space.__dict__[mname]
413 fn = space.__dict__[mname]
412 except KeyError:
414 except KeyError:
413 pass
415 pass
414 else:
416 else:
415 break
417 break
416 if mode == 'brief':
418 if mode == 'brief':
417 # only first line
419 # only first line
418 if fn.__doc__:
420 if fn.__doc__:
419 fndoc = fn.__doc__.split('\n',1)[0]
421 fndoc = fn.__doc__.split('\n',1)[0]
420 else:
422 else:
421 fndoc = 'No documentation'
423 fndoc = 'No documentation'
422 else:
424 else:
423 fndoc = fn.__doc__.rstrip()
425 fndoc = fn.__doc__.rstrip()
424
426
425 if mode == 'rest':
427 if mode == 'rest':
426 rest_docs.append('**%s%s**::\n\n\t%s\n\n' %(self.shell.ESC_MAGIC,
428 rest_docs.append('**%s%s**::\n\n\t%s\n\n' %(self.shell.ESC_MAGIC,
427 fname,fndoc))
429 fname,fndoc))
428
430
429 else:
431 else:
430 magic_docs.append('%s%s:\n\t%s\n' %(self.shell.ESC_MAGIC,
432 magic_docs.append('%s%s:\n\t%s\n' %(self.shell.ESC_MAGIC,
431 fname,fndoc))
433 fname,fndoc))
432
434
433 magic_docs = ''.join(magic_docs)
435 magic_docs = ''.join(magic_docs)
434
436
435 if mode == 'rest':
437 if mode == 'rest':
436 return "".join(rest_docs)
438 return "".join(rest_docs)
437
439
438 if mode == 'latex':
440 if mode == 'latex':
439 print self.format_latex(magic_docs)
441 print self.format_latex(magic_docs)
440 return
442 return
441 else:
443 else:
442 magic_docs = self.format_screen(magic_docs)
444 magic_docs = self.format_screen(magic_docs)
443 if mode == 'brief':
445 if mode == 'brief':
444 return magic_docs
446 return magic_docs
445
447
446 outmsg = """
448 outmsg = """
447 IPython's 'magic' functions
449 IPython's 'magic' functions
448 ===========================
450 ===========================
449
451
450 The magic function system provides a series of functions which allow you to
452 The magic function system provides a series of functions which allow you to
451 control the behavior of IPython itself, plus a lot of system-type
453 control the behavior of IPython itself, plus a lot of system-type
452 features. All these functions are prefixed with a % character, but parameters
454 features. All these functions are prefixed with a % character, but parameters
453 are given without parentheses or quotes.
455 are given without parentheses or quotes.
454
456
455 NOTE: If you have 'automagic' enabled (via the command line option or with the
457 NOTE: If you have 'automagic' enabled (via the command line option or with the
456 %automagic function), you don't need to type in the % explicitly. By default,
458 %automagic function), you don't need to type in the % explicitly. By default,
457 IPython ships with automagic on, so you should only rarely need the % escape.
459 IPython ships with automagic on, so you should only rarely need the % escape.
458
460
459 Example: typing '%cd mydir' (without the quotes) changes you working directory
461 Example: typing '%cd mydir' (without the quotes) changes you working directory
460 to 'mydir', if it exists.
462 to 'mydir', if it exists.
461
463
462 You can define your own magic functions to extend the system. See the supplied
464 You can define your own magic functions to extend the system. See the supplied
463 ipythonrc and example-magic.py files for details (in your ipython
465 ipythonrc and example-magic.py files for details (in your ipython
464 configuration directory, typically $HOME/.ipython/).
466 configuration directory, typically $HOME/.ipython/).
465
467
466 You can also define your own aliased names for magic functions. In your
468 You can also define your own aliased names for magic functions. In your
467 ipythonrc file, placing a line like:
469 ipythonrc file, placing a line like:
468
470
469 execute __IPYTHON__.magic_pf = __IPYTHON__.magic_profile
471 execute __IPYTHON__.magic_pf = __IPYTHON__.magic_profile
470
472
471 will define %pf as a new name for %profile.
473 will define %pf as a new name for %profile.
472
474
473 You can also call magics in code using the ipmagic() function, which IPython
475 You can also call magics in code using the ipmagic() function, which IPython
474 automatically adds to the builtin namespace. Type 'ipmagic?' for details.
476 automatically adds to the builtin namespace. Type 'ipmagic?' for details.
475
477
476 For a list of the available magic functions, use %lsmagic. For a description
478 For a list of the available magic functions, use %lsmagic. For a description
477 of any of them, type %magic_name?, e.g. '%cd?'.
479 of any of them, type %magic_name?, e.g. '%cd?'.
478
480
479 Currently the magic system has the following functions:\n"""
481 Currently the magic system has the following functions:\n"""
480
482
481 mesc = self.shell.ESC_MAGIC
483 mesc = self.shell.ESC_MAGIC
482 outmsg = ("%s\n%s\n\nSummary of magic functions (from %slsmagic):"
484 outmsg = ("%s\n%s\n\nSummary of magic functions (from %slsmagic):"
483 "\n\n%s%s\n\n%s" % (outmsg,
485 "\n\n%s%s\n\n%s" % (outmsg,
484 magic_docs,mesc,mesc,
486 magic_docs,mesc,mesc,
485 (' '+mesc).join(self.lsmagic()),
487 (' '+mesc).join(self.lsmagic()),
486 Magic.auto_status[self.shell.rc.automagic] ) )
488 Magic.auto_status[self.shell.rc.automagic] ) )
487
489
488 page(outmsg,screen_lines=self.shell.rc.screen_length)
490 page(outmsg,screen_lines=self.shell.rc.screen_length)
489
491
490
492
491 def magic_autoindent(self, parameter_s = ''):
493 def magic_autoindent(self, parameter_s = ''):
492 """Toggle autoindent on/off (if available)."""
494 """Toggle autoindent on/off (if available)."""
493
495
494 self.shell.set_autoindent()
496 self.shell.set_autoindent()
495 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
497 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
496
498
497
499
498 def magic_automagic(self, parameter_s = ''):
500 def magic_automagic(self, parameter_s = ''):
499 """Make magic functions callable without having to type the initial %.
501 """Make magic functions callable without having to type the initial %.
500
502
501 Without argumentsl toggles on/off (when off, you must call it as
503 Without argumentsl toggles on/off (when off, you must call it as
502 %automagic, of course). With arguments it sets the value, and you can
504 %automagic, of course). With arguments it sets the value, and you can
503 use any of (case insensitive):
505 use any of (case insensitive):
504
506
505 - on,1,True: to activate
507 - on,1,True: to activate
506
508
507 - off,0,False: to deactivate.
509 - off,0,False: to deactivate.
508
510
509 Note that magic functions have lowest priority, so if there's a
511 Note that magic functions have lowest priority, so if there's a
510 variable whose name collides with that of a magic fn, automagic won't
512 variable whose name collides with that of a magic fn, automagic won't
511 work for that function (you get the variable instead). However, if you
513 work for that function (you get the variable instead). However, if you
512 delete the variable (del var), the previously shadowed magic function
514 delete the variable (del var), the previously shadowed magic function
513 becomes visible to automagic again."""
515 becomes visible to automagic again."""
514
516
515 rc = self.shell.rc
517 rc = self.shell.rc
516 arg = parameter_s.lower()
518 arg = parameter_s.lower()
517 if parameter_s in ('on','1','true'):
519 if parameter_s in ('on','1','true'):
518 rc.automagic = True
520 rc.automagic = True
519 elif parameter_s in ('off','0','false'):
521 elif parameter_s in ('off','0','false'):
520 rc.automagic = False
522 rc.automagic = False
521 else:
523 else:
522 rc.automagic = not rc.automagic
524 rc.automagic = not rc.automagic
523 print '\n' + Magic.auto_status[rc.automagic]
525 print '\n' + Magic.auto_status[rc.automagic]
524
526
525
527 @testdec.skip_doctest
526 def magic_autocall(self, parameter_s = ''):
528 def magic_autocall(self, parameter_s = ''):
527 """Make functions callable without having to type parentheses.
529 """Make functions callable without having to type parentheses.
528
530
529 Usage:
531 Usage:
530
532
531 %autocall [mode]
533 %autocall [mode]
532
534
533 The mode can be one of: 0->Off, 1->Smart, 2->Full. If not given, the
535 The mode can be one of: 0->Off, 1->Smart, 2->Full. If not given, the
534 value is toggled on and off (remembering the previous state).
536 value is toggled on and off (remembering the previous state).
535
537
536 In more detail, these values mean:
538 In more detail, these values mean:
537
539
538 0 -> fully disabled
540 0 -> fully disabled
539
541
540 1 -> active, but do not apply if there are no arguments on the line.
542 1 -> active, but do not apply if there are no arguments on the line.
541
543
542 In this mode, you get:
544 In this mode, you get:
543
545
544 In [1]: callable
546 In [1]: callable
545 Out[1]: <built-in function callable>
547 Out[1]: <built-in function callable>
546
548
547 In [2]: callable 'hello'
549 In [2]: callable 'hello'
548 ------> callable('hello')
550 ------> callable('hello')
549 Out[2]: False
551 Out[2]: False
550
552
551 2 -> Active always. Even if no arguments are present, the callable
553 2 -> Active always. Even if no arguments are present, the callable
552 object is called:
554 object is called:
553
555
554 In [4]: callable
556 In [2]: float
555 ------> callable()
557 ------> float()
558 Out[2]: 0.0
556
559
557 Note that even with autocall off, you can still use '/' at the start of
560 Note that even with autocall off, you can still use '/' at the start of
558 a line to treat the first argument on the command line as a function
561 a line to treat the first argument on the command line as a function
559 and add parentheses to it:
562 and add parentheses to it:
560
563
561 In [8]: /str 43
564 In [8]: /str 43
562 ------> str(43)
565 ------> str(43)
563 Out[8]: '43'
566 Out[8]: '43'
567
568 # all-random (note for auto-testing)
564 """
569 """
565
570
566 rc = self.shell.rc
571 rc = self.shell.rc
567
572
568 if parameter_s:
573 if parameter_s:
569 arg = int(parameter_s)
574 arg = int(parameter_s)
570 else:
575 else:
571 arg = 'toggle'
576 arg = 'toggle'
572
577
573 if not arg in (0,1,2,'toggle'):
578 if not arg in (0,1,2,'toggle'):
574 error('Valid modes: (0->Off, 1->Smart, 2->Full')
579 error('Valid modes: (0->Off, 1->Smart, 2->Full')
575 return
580 return
576
581
577 if arg in (0,1,2):
582 if arg in (0,1,2):
578 rc.autocall = arg
583 rc.autocall = arg
579 else: # toggle
584 else: # toggle
580 if rc.autocall:
585 if rc.autocall:
581 self._magic_state.autocall_save = rc.autocall
586 self._magic_state.autocall_save = rc.autocall
582 rc.autocall = 0
587 rc.autocall = 0
583 else:
588 else:
584 try:
589 try:
585 rc.autocall = self._magic_state.autocall_save
590 rc.autocall = self._magic_state.autocall_save
586 except AttributeError:
591 except AttributeError:
587 rc.autocall = self._magic_state.autocall_save = 1
592 rc.autocall = self._magic_state.autocall_save = 1
588
593
589 print "Automatic calling is:",['OFF','Smart','Full'][rc.autocall]
594 print "Automatic calling is:",['OFF','Smart','Full'][rc.autocall]
590
595
591 def magic_system_verbose(self, parameter_s = ''):
596 def magic_system_verbose(self, parameter_s = ''):
592 """Set verbose printing of system calls.
597 """Set verbose printing of system calls.
593
598
594 If called without an argument, act as a toggle"""
599 If called without an argument, act as a toggle"""
595
600
596 if parameter_s:
601 if parameter_s:
597 val = bool(eval(parameter_s))
602 val = bool(eval(parameter_s))
598 else:
603 else:
599 val = None
604 val = None
600
605
601 self.shell.rc_set_toggle('system_verbose',val)
606 self.shell.rc_set_toggle('system_verbose',val)
602 print "System verbose printing is:",\
607 print "System verbose printing is:",\
603 ['OFF','ON'][self.shell.rc.system_verbose]
608 ['OFF','ON'][self.shell.rc.system_verbose]
604
609
605
610
606 def magic_page(self, parameter_s=''):
611 def magic_page(self, parameter_s=''):
607 """Pretty print the object and display it through a pager.
612 """Pretty print the object and display it through a pager.
608
613
609 %page [options] OBJECT
614 %page [options] OBJECT
610
615
611 If no object is given, use _ (last output).
616 If no object is given, use _ (last output).
612
617
613 Options:
618 Options:
614
619
615 -r: page str(object), don't pretty-print it."""
620 -r: page str(object), don't pretty-print it."""
616
621
617 # After a function contributed by Olivier Aubert, slightly modified.
622 # After a function contributed by Olivier Aubert, slightly modified.
618
623
619 # Process options/args
624 # Process options/args
620 opts,args = self.parse_options(parameter_s,'r')
625 opts,args = self.parse_options(parameter_s,'r')
621 raw = 'r' in opts
626 raw = 'r' in opts
622
627
623 oname = args and args or '_'
628 oname = args and args or '_'
624 info = self._ofind(oname)
629 info = self._ofind(oname)
625 if info['found']:
630 if info['found']:
626 txt = (raw and str or pformat)( info['obj'] )
631 txt = (raw and str or pformat)( info['obj'] )
627 page(txt)
632 page(txt)
628 else:
633 else:
629 print 'Object `%s` not found' % oname
634 print 'Object `%s` not found' % oname
630
635
631 def magic_profile(self, parameter_s=''):
636 def magic_profile(self, parameter_s=''):
632 """Print your currently active IPyhton profile."""
637 """Print your currently active IPyhton profile."""
633 if self.shell.rc.profile:
638 if self.shell.rc.profile:
634 printpl('Current IPython profile: $self.shell.rc.profile.')
639 printpl('Current IPython profile: $self.shell.rc.profile.')
635 else:
640 else:
636 print 'No profile active.'
641 print 'No profile active.'
637
642
638 def magic_pinfo(self, parameter_s='', namespaces=None):
643 def magic_pinfo(self, parameter_s='', namespaces=None):
639 """Provide detailed information about an object.
644 """Provide detailed information about an object.
640
645
641 '%pinfo object' is just a synonym for object? or ?object."""
646 '%pinfo object' is just a synonym for object? or ?object."""
642
647
643 #print 'pinfo par: <%s>' % parameter_s # dbg
648 #print 'pinfo par: <%s>' % parameter_s # dbg
644
649
645
650
646 # detail_level: 0 -> obj? , 1 -> obj??
651 # detail_level: 0 -> obj? , 1 -> obj??
647 detail_level = 0
652 detail_level = 0
648 # We need to detect if we got called as 'pinfo pinfo foo', which can
653 # We need to detect if we got called as 'pinfo pinfo foo', which can
649 # happen if the user types 'pinfo foo?' at the cmd line.
654 # happen if the user types 'pinfo foo?' at the cmd line.
650 pinfo,qmark1,oname,qmark2 = \
655 pinfo,qmark1,oname,qmark2 = \
651 re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
656 re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
652 if pinfo or qmark1 or qmark2:
657 if pinfo or qmark1 or qmark2:
653 detail_level = 1
658 detail_level = 1
654 if "*" in oname:
659 if "*" in oname:
655 self.magic_psearch(oname)
660 self.magic_psearch(oname)
656 else:
661 else:
657 self._inspect('pinfo', oname, detail_level=detail_level,
662 self._inspect('pinfo', oname, detail_level=detail_level,
658 namespaces=namespaces)
663 namespaces=namespaces)
659
664
660 def magic_pdef(self, parameter_s='', namespaces=None):
665 def magic_pdef(self, parameter_s='', namespaces=None):
661 """Print the definition header for any callable object.
666 """Print the definition header for any callable object.
662
667
663 If the object is a class, print the constructor information."""
668 If the object is a class, print the constructor information."""
664 self._inspect('pdef',parameter_s, namespaces)
669 self._inspect('pdef',parameter_s, namespaces)
665
670
666 def magic_pdoc(self, parameter_s='', namespaces=None):
671 def magic_pdoc(self, parameter_s='', namespaces=None):
667 """Print the docstring for an object.
672 """Print the docstring for an object.
668
673
669 If the given object is a class, it will print both the class and the
674 If the given object is a class, it will print both the class and the
670 constructor docstrings."""
675 constructor docstrings."""
671 self._inspect('pdoc',parameter_s, namespaces)
676 self._inspect('pdoc',parameter_s, namespaces)
672
677
673 def magic_psource(self, parameter_s='', namespaces=None):
678 def magic_psource(self, parameter_s='', namespaces=None):
674 """Print (or run through pager) the source code for an object."""
679 """Print (or run through pager) the source code for an object."""
675 self._inspect('psource',parameter_s, namespaces)
680 self._inspect('psource',parameter_s, namespaces)
676
681
677 def magic_pfile(self, parameter_s=''):
682 def magic_pfile(self, parameter_s=''):
678 """Print (or run through pager) the file where an object is defined.
683 """Print (or run through pager) the file where an object is defined.
679
684
680 The file opens at the line where the object definition begins. IPython
685 The file opens at the line where the object definition begins. IPython
681 will honor the environment variable PAGER if set, and otherwise will
686 will honor the environment variable PAGER if set, and otherwise will
682 do its best to print the file in a convenient form.
687 do its best to print the file in a convenient form.
683
688
684 If the given argument is not an object currently defined, IPython will
689 If the given argument is not an object currently defined, IPython will
685 try to interpret it as a filename (automatically adding a .py extension
690 try to interpret it as a filename (automatically adding a .py extension
686 if needed). You can thus use %pfile as a syntax highlighting code
691 if needed). You can thus use %pfile as a syntax highlighting code
687 viewer."""
692 viewer."""
688
693
689 # first interpret argument as an object name
694 # first interpret argument as an object name
690 out = self._inspect('pfile',parameter_s)
695 out = self._inspect('pfile',parameter_s)
691 # if not, try the input as a filename
696 # if not, try the input as a filename
692 if out == 'not found':
697 if out == 'not found':
693 try:
698 try:
694 filename = get_py_filename(parameter_s)
699 filename = get_py_filename(parameter_s)
695 except IOError,msg:
700 except IOError,msg:
696 print msg
701 print msg
697 return
702 return
698 page(self.shell.inspector.format(file(filename).read()))
703 page(self.shell.inspector.format(file(filename).read()))
699
704
700 def _inspect(self,meth,oname,namespaces=None,**kw):
705 def _inspect(self,meth,oname,namespaces=None,**kw):
701 """Generic interface to the inspector system.
706 """Generic interface to the inspector system.
702
707
703 This function is meant to be called by pdef, pdoc & friends."""
708 This function is meant to be called by pdef, pdoc & friends."""
704
709
705 #oname = oname.strip()
710 #oname = oname.strip()
706 #print '1- oname: <%r>' % oname # dbg
711 #print '1- oname: <%r>' % oname # dbg
707 try:
712 try:
708 oname = oname.strip().encode('ascii')
713 oname = oname.strip().encode('ascii')
709 #print '2- oname: <%r>' % oname # dbg
714 #print '2- oname: <%r>' % oname # dbg
710 except UnicodeEncodeError:
715 except UnicodeEncodeError:
711 print 'Python identifiers can only contain ascii characters.'
716 print 'Python identifiers can only contain ascii characters.'
712 return 'not found'
717 return 'not found'
713
718
714 info = Struct(self._ofind(oname, namespaces))
719 info = Struct(self._ofind(oname, namespaces))
715
720
716 if info.found:
721 if info.found:
717 try:
722 try:
718 IPython.generics.inspect_object(info.obj)
723 IPython.generics.inspect_object(info.obj)
719 return
724 return
720 except IPython.ipapi.TryNext:
725 except IPython.ipapi.TryNext:
721 pass
726 pass
722 # Get the docstring of the class property if it exists.
727 # Get the docstring of the class property if it exists.
723 path = oname.split('.')
728 path = oname.split('.')
724 root = '.'.join(path[:-1])
729 root = '.'.join(path[:-1])
725 if info.parent is not None:
730 if info.parent is not None:
726 try:
731 try:
727 target = getattr(info.parent, '__class__')
732 target = getattr(info.parent, '__class__')
728 # The object belongs to a class instance.
733 # The object belongs to a class instance.
729 try:
734 try:
730 target = getattr(target, path[-1])
735 target = getattr(target, path[-1])
731 # The class defines the object.
736 # The class defines the object.
732 if isinstance(target, property):
737 if isinstance(target, property):
733 oname = root + '.__class__.' + path[-1]
738 oname = root + '.__class__.' + path[-1]
734 info = Struct(self._ofind(oname))
739 info = Struct(self._ofind(oname))
735 except AttributeError: pass
740 except AttributeError: pass
736 except AttributeError: pass
741 except AttributeError: pass
737
742
738 pmethod = getattr(self.shell.inspector,meth)
743 pmethod = getattr(self.shell.inspector,meth)
739 formatter = info.ismagic and self.format_screen or None
744 formatter = info.ismagic and self.format_screen or None
740 if meth == 'pdoc':
745 if meth == 'pdoc':
741 pmethod(info.obj,oname,formatter)
746 pmethod(info.obj,oname,formatter)
742 elif meth == 'pinfo':
747 elif meth == 'pinfo':
743 pmethod(info.obj,oname,formatter,info,**kw)
748 pmethod(info.obj,oname,formatter,info,**kw)
744 else:
749 else:
745 pmethod(info.obj,oname)
750 pmethod(info.obj,oname)
746 else:
751 else:
747 print 'Object `%s` not found.' % oname
752 print 'Object `%s` not found.' % oname
748 return 'not found' # so callers can take other action
753 return 'not found' # so callers can take other action
749
754
750 def magic_psearch(self, parameter_s=''):
755 def magic_psearch(self, parameter_s=''):
751 """Search for object in namespaces by wildcard.
756 """Search for object in namespaces by wildcard.
752
757
753 %psearch [options] PATTERN [OBJECT TYPE]
758 %psearch [options] PATTERN [OBJECT TYPE]
754
759
755 Note: ? can be used as a synonym for %psearch, at the beginning or at
760 Note: ? can be used as a synonym for %psearch, at the beginning or at
756 the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
761 the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
757 rest of the command line must be unchanged (options come first), so
762 rest of the command line must be unchanged (options come first), so
758 for example the following forms are equivalent
763 for example the following forms are equivalent
759
764
760 %psearch -i a* function
765 %psearch -i a* function
761 -i a* function?
766 -i a* function?
762 ?-i a* function
767 ?-i a* function
763
768
764 Arguments:
769 Arguments:
765
770
766 PATTERN
771 PATTERN
767
772
768 where PATTERN is a string containing * as a wildcard similar to its
773 where PATTERN is a string containing * as a wildcard similar to its
769 use in a shell. The pattern is matched in all namespaces on the
774 use in a shell. The pattern is matched in all namespaces on the
770 search path. By default objects starting with a single _ are not
775 search path. By default objects starting with a single _ are not
771 matched, many IPython generated objects have a single
776 matched, many IPython generated objects have a single
772 underscore. The default is case insensitive matching. Matching is
777 underscore. The default is case insensitive matching. Matching is
773 also done on the attributes of objects and not only on the objects
778 also done on the attributes of objects and not only on the objects
774 in a module.
779 in a module.
775
780
776 [OBJECT TYPE]
781 [OBJECT TYPE]
777
782
778 Is the name of a python type from the types module. The name is
783 Is the name of a python type from the types module. The name is
779 given in lowercase without the ending type, ex. StringType is
784 given in lowercase without the ending type, ex. StringType is
780 written string. By adding a type here only objects matching the
785 written string. By adding a type here only objects matching the
781 given type are matched. Using all here makes the pattern match all
786 given type are matched. Using all here makes the pattern match all
782 types (this is the default).
787 types (this is the default).
783
788
784 Options:
789 Options:
785
790
786 -a: makes the pattern match even objects whose names start with a
791 -a: makes the pattern match even objects whose names start with a
787 single underscore. These names are normally ommitted from the
792 single underscore. These names are normally ommitted from the
788 search.
793 search.
789
794
790 -i/-c: make the pattern case insensitive/sensitive. If neither of
795 -i/-c: make the pattern case insensitive/sensitive. If neither of
791 these options is given, the default is read from your ipythonrc
796 these options is given, the default is read from your ipythonrc
792 file. The option name which sets this value is
797 file. The option name which sets this value is
793 'wildcards_case_sensitive'. If this option is not specified in your
798 'wildcards_case_sensitive'. If this option is not specified in your
794 ipythonrc file, IPython's internal default is to do a case sensitive
799 ipythonrc file, IPython's internal default is to do a case sensitive
795 search.
800 search.
796
801
797 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
802 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
798 specifiy can be searched in any of the following namespaces:
803 specifiy can be searched in any of the following namespaces:
799 'builtin', 'user', 'user_global','internal', 'alias', where
804 'builtin', 'user', 'user_global','internal', 'alias', where
800 'builtin' and 'user' are the search defaults. Note that you should
805 'builtin' and 'user' are the search defaults. Note that you should
801 not use quotes when specifying namespaces.
806 not use quotes when specifying namespaces.
802
807
803 'Builtin' contains the python module builtin, 'user' contains all
808 'Builtin' contains the python module builtin, 'user' contains all
804 user data, 'alias' only contain the shell aliases and no python
809 user data, 'alias' only contain the shell aliases and no python
805 objects, 'internal' contains objects used by IPython. The
810 objects, 'internal' contains objects used by IPython. The
806 'user_global' namespace is only used by embedded IPython instances,
811 'user_global' namespace is only used by embedded IPython instances,
807 and it contains module-level globals. You can add namespaces to the
812 and it contains module-level globals. You can add namespaces to the
808 search with -s or exclude them with -e (these options can be given
813 search with -s or exclude them with -e (these options can be given
809 more than once).
814 more than once).
810
815
811 Examples:
816 Examples:
812
817
813 %psearch a* -> objects beginning with an a
818 %psearch a* -> objects beginning with an a
814 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
819 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
815 %psearch a* function -> all functions beginning with an a
820 %psearch a* function -> all functions beginning with an a
816 %psearch re.e* -> objects beginning with an e in module re
821 %psearch re.e* -> objects beginning with an e in module re
817 %psearch r*.e* -> objects that start with e in modules starting in r
822 %psearch r*.e* -> objects that start with e in modules starting in r
818 %psearch r*.* string -> all strings in modules beginning with r
823 %psearch r*.* string -> all strings in modules beginning with r
819
824
820 Case sensitve search:
825 Case sensitve search:
821
826
822 %psearch -c a* list all object beginning with lower case a
827 %psearch -c a* list all object beginning with lower case a
823
828
824 Show objects beginning with a single _:
829 Show objects beginning with a single _:
825
830
826 %psearch -a _* list objects beginning with a single underscore"""
831 %psearch -a _* list objects beginning with a single underscore"""
827 try:
832 try:
828 parameter_s = parameter_s.encode('ascii')
833 parameter_s = parameter_s.encode('ascii')
829 except UnicodeEncodeError:
834 except UnicodeEncodeError:
830 print 'Python identifiers can only contain ascii characters.'
835 print 'Python identifiers can only contain ascii characters.'
831 return
836 return
832
837
833 # default namespaces to be searched
838 # default namespaces to be searched
834 def_search = ['user','builtin']
839 def_search = ['user','builtin']
835
840
836 # Process options/args
841 # Process options/args
837 opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True)
842 opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True)
838 opt = opts.get
843 opt = opts.get
839 shell = self.shell
844 shell = self.shell
840 psearch = shell.inspector.psearch
845 psearch = shell.inspector.psearch
841
846
842 # select case options
847 # select case options
843 if opts.has_key('i'):
848 if opts.has_key('i'):
844 ignore_case = True
849 ignore_case = True
845 elif opts.has_key('c'):
850 elif opts.has_key('c'):
846 ignore_case = False
851 ignore_case = False
847 else:
852 else:
848 ignore_case = not shell.rc.wildcards_case_sensitive
853 ignore_case = not shell.rc.wildcards_case_sensitive
849
854
850 # Build list of namespaces to search from user options
855 # Build list of namespaces to search from user options
851 def_search.extend(opt('s',[]))
856 def_search.extend(opt('s',[]))
852 ns_exclude = ns_exclude=opt('e',[])
857 ns_exclude = ns_exclude=opt('e',[])
853 ns_search = [nm for nm in def_search if nm not in ns_exclude]
858 ns_search = [nm for nm in def_search if nm not in ns_exclude]
854
859
855 # Call the actual search
860 # Call the actual search
856 try:
861 try:
857 psearch(args,shell.ns_table,ns_search,
862 psearch(args,shell.ns_table,ns_search,
858 show_all=opt('a'),ignore_case=ignore_case)
863 show_all=opt('a'),ignore_case=ignore_case)
859 except:
864 except:
860 shell.showtraceback()
865 shell.showtraceback()
861
866
862 def magic_who_ls(self, parameter_s=''):
867 def magic_who_ls(self, parameter_s=''):
863 """Return a sorted list of all interactive variables.
868 """Return a sorted list of all interactive variables.
864
869
865 If arguments are given, only variables of types matching these
870 If arguments are given, only variables of types matching these
866 arguments are returned."""
871 arguments are returned."""
867
872
868 user_ns = self.shell.user_ns
873 user_ns = self.shell.user_ns
869 internal_ns = self.shell.internal_ns
874 internal_ns = self.shell.internal_ns
870 user_config_ns = self.shell.user_config_ns
875 user_config_ns = self.shell.user_config_ns
871 out = []
876 out = []
872 typelist = parameter_s.split()
877 typelist = parameter_s.split()
873
878
874 for i in user_ns:
879 for i in user_ns:
875 if not (i.startswith('_') or i.startswith('_i')) \
880 if not (i.startswith('_') or i.startswith('_i')) \
876 and not (i in internal_ns or i in user_config_ns):
881 and not (i in internal_ns or i in user_config_ns):
877 if typelist:
882 if typelist:
878 if type(user_ns[i]).__name__ in typelist:
883 if type(user_ns[i]).__name__ in typelist:
879 out.append(i)
884 out.append(i)
880 else:
885 else:
881 out.append(i)
886 out.append(i)
882 out.sort()
887 out.sort()
883 return out
888 return out
884
889
885 def magic_who(self, parameter_s=''):
890 def magic_who(self, parameter_s=''):
886 """Print all interactive variables, with some minimal formatting.
891 """Print all interactive variables, with some minimal formatting.
887
892
888 If any arguments are given, only variables whose type matches one of
893 If any arguments are given, only variables whose type matches one of
889 these are printed. For example:
894 these are printed. For example:
890
895
891 %who function str
896 %who function str
892
897
893 will only list functions and strings, excluding all other types of
898 will only list functions and strings, excluding all other types of
894 variables. To find the proper type names, simply use type(var) at a
899 variables. To find the proper type names, simply use type(var) at a
895 command line to see how python prints type names. For example:
900 command line to see how python prints type names. For example:
896
901
897 In [1]: type('hello')\\
902 In [1]: type('hello')\\
898 Out[1]: <type 'str'>
903 Out[1]: <type 'str'>
899
904
900 indicates that the type name for strings is 'str'.
905 indicates that the type name for strings is 'str'.
901
906
902 %who always excludes executed names loaded through your configuration
907 %who always excludes executed names loaded through your configuration
903 file and things which are internal to IPython.
908 file and things which are internal to IPython.
904
909
905 This is deliberate, as typically you may load many modules and the
910 This is deliberate, as typically you may load many modules and the
906 purpose of %who is to show you only what you've manually defined."""
911 purpose of %who is to show you only what you've manually defined."""
907
912
908 varlist = self.magic_who_ls(parameter_s)
913 varlist = self.magic_who_ls(parameter_s)
909 if not varlist:
914 if not varlist:
910 if parameter_s:
915 if parameter_s:
911 print 'No variables match your requested type.'
916 print 'No variables match your requested type.'
912 else:
917 else:
913 print 'Interactive namespace is empty.'
918 print 'Interactive namespace is empty.'
914 return
919 return
915
920
916 # if we have variables, move on...
921 # if we have variables, move on...
917 count = 0
922 count = 0
918 for i in varlist:
923 for i in varlist:
919 print i+'\t',
924 print i+'\t',
920 count += 1
925 count += 1
921 if count > 8:
926 if count > 8:
922 count = 0
927 count = 0
923 print
928 print
924 print
929 print
925
930
926 def magic_whos(self, parameter_s=''):
931 def magic_whos(self, parameter_s=''):
927 """Like %who, but gives some extra information about each variable.
932 """Like %who, but gives some extra information about each variable.
928
933
929 The same type filtering of %who can be applied here.
934 The same type filtering of %who can be applied here.
930
935
931 For all variables, the type is printed. Additionally it prints:
936 For all variables, the type is printed. Additionally it prints:
932
937
933 - For {},[],(): their length.
938 - For {},[],(): their length.
934
939
935 - For numpy and Numeric arrays, a summary with shape, number of
940 - For numpy and Numeric arrays, a summary with shape, number of
936 elements, typecode and size in memory.
941 elements, typecode and size in memory.
937
942
938 - Everything else: a string representation, snipping their middle if
943 - Everything else: a string representation, snipping their middle if
939 too long."""
944 too long."""
940
945
941 varnames = self.magic_who_ls(parameter_s)
946 varnames = self.magic_who_ls(parameter_s)
942 if not varnames:
947 if not varnames:
943 if parameter_s:
948 if parameter_s:
944 print 'No variables match your requested type.'
949 print 'No variables match your requested type.'
945 else:
950 else:
946 print 'Interactive namespace is empty.'
951 print 'Interactive namespace is empty.'
947 return
952 return
948
953
949 # if we have variables, move on...
954 # if we have variables, move on...
950
955
951 # for these types, show len() instead of data:
956 # for these types, show len() instead of data:
952 seq_types = [types.DictType,types.ListType,types.TupleType]
957 seq_types = [types.DictType,types.ListType,types.TupleType]
953
958
954 # for numpy/Numeric arrays, display summary info
959 # for numpy/Numeric arrays, display summary info
955 try:
960 try:
956 import numpy
961 import numpy
957 except ImportError:
962 except ImportError:
958 ndarray_type = None
963 ndarray_type = None
959 else:
964 else:
960 ndarray_type = numpy.ndarray.__name__
965 ndarray_type = numpy.ndarray.__name__
961 try:
966 try:
962 import Numeric
967 import Numeric
963 except ImportError:
968 except ImportError:
964 array_type = None
969 array_type = None
965 else:
970 else:
966 array_type = Numeric.ArrayType.__name__
971 array_type = Numeric.ArrayType.__name__
967
972
968 # Find all variable names and types so we can figure out column sizes
973 # Find all variable names and types so we can figure out column sizes
969 def get_vars(i):
974 def get_vars(i):
970 return self.shell.user_ns[i]
975 return self.shell.user_ns[i]
971
976
972 # some types are well known and can be shorter
977 # some types are well known and can be shorter
973 abbrevs = {'IPython.macro.Macro' : 'Macro'}
978 abbrevs = {'IPython.macro.Macro' : 'Macro'}
974 def type_name(v):
979 def type_name(v):
975 tn = type(v).__name__
980 tn = type(v).__name__
976 return abbrevs.get(tn,tn)
981 return abbrevs.get(tn,tn)
977
982
978 varlist = map(get_vars,varnames)
983 varlist = map(get_vars,varnames)
979
984
980 typelist = []
985 typelist = []
981 for vv in varlist:
986 for vv in varlist:
982 tt = type_name(vv)
987 tt = type_name(vv)
983
988
984 if tt=='instance':
989 if tt=='instance':
985 typelist.append( abbrevs.get(str(vv.__class__),
990 typelist.append( abbrevs.get(str(vv.__class__),
986 str(vv.__class__)))
991 str(vv.__class__)))
987 else:
992 else:
988 typelist.append(tt)
993 typelist.append(tt)
989
994
990 # column labels and # of spaces as separator
995 # column labels and # of spaces as separator
991 varlabel = 'Variable'
996 varlabel = 'Variable'
992 typelabel = 'Type'
997 typelabel = 'Type'
993 datalabel = 'Data/Info'
998 datalabel = 'Data/Info'
994 colsep = 3
999 colsep = 3
995 # variable format strings
1000 # variable format strings
996 vformat = "$vname.ljust(varwidth)$vtype.ljust(typewidth)"
1001 vformat = "$vname.ljust(varwidth)$vtype.ljust(typewidth)"
997 vfmt_short = '$vstr[:25]<...>$vstr[-25:]'
1002 vfmt_short = '$vstr[:25]<...>$vstr[-25:]'
998 aformat = "%s: %s elems, type `%s`, %s bytes"
1003 aformat = "%s: %s elems, type `%s`, %s bytes"
999 # find the size of the columns to format the output nicely
1004 # find the size of the columns to format the output nicely
1000 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
1005 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
1001 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
1006 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
1002 # table header
1007 # table header
1003 print varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
1008 print varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
1004 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1)
1009 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1)
1005 # and the table itself
1010 # and the table itself
1006 kb = 1024
1011 kb = 1024
1007 Mb = 1048576 # kb**2
1012 Mb = 1048576 # kb**2
1008 for vname,var,vtype in zip(varnames,varlist,typelist):
1013 for vname,var,vtype in zip(varnames,varlist,typelist):
1009 print itpl(vformat),
1014 print itpl(vformat),
1010 if vtype in seq_types:
1015 if vtype in seq_types:
1011 print len(var)
1016 print len(var)
1012 elif vtype in [array_type,ndarray_type]:
1017 elif vtype in [array_type,ndarray_type]:
1013 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
1018 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
1014 if vtype==ndarray_type:
1019 if vtype==ndarray_type:
1015 # numpy
1020 # numpy
1016 vsize = var.size
1021 vsize = var.size
1017 vbytes = vsize*var.itemsize
1022 vbytes = vsize*var.itemsize
1018 vdtype = var.dtype
1023 vdtype = var.dtype
1019 else:
1024 else:
1020 # Numeric
1025 # Numeric
1021 vsize = Numeric.size(var)
1026 vsize = Numeric.size(var)
1022 vbytes = vsize*var.itemsize()
1027 vbytes = vsize*var.itemsize()
1023 vdtype = var.typecode()
1028 vdtype = var.typecode()
1024
1029
1025 if vbytes < 100000:
1030 if vbytes < 100000:
1026 print aformat % (vshape,vsize,vdtype,vbytes)
1031 print aformat % (vshape,vsize,vdtype,vbytes)
1027 else:
1032 else:
1028 print aformat % (vshape,vsize,vdtype,vbytes),
1033 print aformat % (vshape,vsize,vdtype,vbytes),
1029 if vbytes < Mb:
1034 if vbytes < Mb:
1030 print '(%s kb)' % (vbytes/kb,)
1035 print '(%s kb)' % (vbytes/kb,)
1031 else:
1036 else:
1032 print '(%s Mb)' % (vbytes/Mb,)
1037 print '(%s Mb)' % (vbytes/Mb,)
1033 else:
1038 else:
1034 try:
1039 try:
1035 vstr = str(var)
1040 vstr = str(var)
1036 except UnicodeEncodeError:
1041 except UnicodeEncodeError:
1037 vstr = unicode(var).encode(sys.getdefaultencoding(),
1042 vstr = unicode(var).encode(sys.getdefaultencoding(),
1038 'backslashreplace')
1043 'backslashreplace')
1039 vstr = vstr.replace('\n','\\n')
1044 vstr = vstr.replace('\n','\\n')
1040 if len(vstr) < 50:
1045 if len(vstr) < 50:
1041 print vstr
1046 print vstr
1042 else:
1047 else:
1043 printpl(vfmt_short)
1048 printpl(vfmt_short)
1044
1049
1045 def magic_reset(self, parameter_s=''):
1050 def magic_reset(self, parameter_s=''):
1046 """Resets the namespace by removing all names defined by the user.
1051 """Resets the namespace by removing all names defined by the user.
1047
1052
1048 Input/Output history are left around in case you need them."""
1053 Input/Output history are left around in case you need them."""
1049
1054
1050 ans = self.shell.ask_yes_no(
1055 ans = self.shell.ask_yes_no(
1051 "Once deleted, variables cannot be recovered. Proceed (y/[n])? ")
1056 "Once deleted, variables cannot be recovered. Proceed (y/[n])? ")
1052 if not ans:
1057 if not ans:
1053 print 'Nothing done.'
1058 print 'Nothing done.'
1054 return
1059 return
1055 user_ns = self.shell.user_ns
1060 user_ns = self.shell.user_ns
1056 for i in self.magic_who_ls():
1061 for i in self.magic_who_ls():
1057 del(user_ns[i])
1062 del(user_ns[i])
1058
1063
1059 # Also flush the private list of module references kept for script
1064 # Also flush the private list of module references kept for script
1060 # execution protection
1065 # execution protection
1061 self.shell._user_main_modules[:] = []
1066 self.shell._user_main_modules[:] = []
1062
1067
1063 def magic_logstart(self,parameter_s=''):
1068 def magic_logstart(self,parameter_s=''):
1064 """Start logging anywhere in a session.
1069 """Start logging anywhere in a session.
1065
1070
1066 %logstart [-o|-r|-t] [log_name [log_mode]]
1071 %logstart [-o|-r|-t] [log_name [log_mode]]
1067
1072
1068 If no name is given, it defaults to a file named 'ipython_log.py' in your
1073 If no name is given, it defaults to a file named 'ipython_log.py' in your
1069 current directory, in 'rotate' mode (see below).
1074 current directory, in 'rotate' mode (see below).
1070
1075
1071 '%logstart name' saves to file 'name' in 'backup' mode. It saves your
1076 '%logstart name' saves to file 'name' in 'backup' mode. It saves your
1072 history up to that point and then continues logging.
1077 history up to that point and then continues logging.
1073
1078
1074 %logstart takes a second optional parameter: logging mode. This can be one
1079 %logstart takes a second optional parameter: logging mode. This can be one
1075 of (note that the modes are given unquoted):\\
1080 of (note that the modes are given unquoted):\\
1076 append: well, that says it.\\
1081 append: well, that says it.\\
1077 backup: rename (if exists) to name~ and start name.\\
1082 backup: rename (if exists) to name~ and start name.\\
1078 global: single logfile in your home dir, appended to.\\
1083 global: single logfile in your home dir, appended to.\\
1079 over : overwrite existing log.\\
1084 over : overwrite existing log.\\
1080 rotate: create rotating logs name.1~, name.2~, etc.
1085 rotate: create rotating logs name.1~, name.2~, etc.
1081
1086
1082 Options:
1087 Options:
1083
1088
1084 -o: log also IPython's output. In this mode, all commands which
1089 -o: log also IPython's output. In this mode, all commands which
1085 generate an Out[NN] prompt are recorded to the logfile, right after
1090 generate an Out[NN] prompt are recorded to the logfile, right after
1086 their corresponding input line. The output lines are always
1091 their corresponding input line. The output lines are always
1087 prepended with a '#[Out]# ' marker, so that the log remains valid
1092 prepended with a '#[Out]# ' marker, so that the log remains valid
1088 Python code.
1093 Python code.
1089
1094
1090 Since this marker is always the same, filtering only the output from
1095 Since this marker is always the same, filtering only the output from
1091 a log is very easy, using for example a simple awk call:
1096 a log is very easy, using for example a simple awk call:
1092
1097
1093 awk -F'#\\[Out\\]# ' '{if($2) {print $2}}' ipython_log.py
1098 awk -F'#\\[Out\\]# ' '{if($2) {print $2}}' ipython_log.py
1094
1099
1095 -r: log 'raw' input. Normally, IPython's logs contain the processed
1100 -r: log 'raw' input. Normally, IPython's logs contain the processed
1096 input, so that user lines are logged in their final form, converted
1101 input, so that user lines are logged in their final form, converted
1097 into valid Python. For example, %Exit is logged as
1102 into valid Python. For example, %Exit is logged as
1098 '_ip.magic("Exit"). If the -r flag is given, all input is logged
1103 '_ip.magic("Exit"). If the -r flag is given, all input is logged
1099 exactly as typed, with no transformations applied.
1104 exactly as typed, with no transformations applied.
1100
1105
1101 -t: put timestamps before each input line logged (these are put in
1106 -t: put timestamps before each input line logged (these are put in
1102 comments)."""
1107 comments)."""
1103
1108
1104 opts,par = self.parse_options(parameter_s,'ort')
1109 opts,par = self.parse_options(parameter_s,'ort')
1105 log_output = 'o' in opts
1110 log_output = 'o' in opts
1106 log_raw_input = 'r' in opts
1111 log_raw_input = 'r' in opts
1107 timestamp = 't' in opts
1112 timestamp = 't' in opts
1108
1113
1109 rc = self.shell.rc
1114 rc = self.shell.rc
1110 logger = self.shell.logger
1115 logger = self.shell.logger
1111
1116
1112 # if no args are given, the defaults set in the logger constructor by
1117 # if no args are given, the defaults set in the logger constructor by
1113 # ipytohn remain valid
1118 # ipytohn remain valid
1114 if par:
1119 if par:
1115 try:
1120 try:
1116 logfname,logmode = par.split()
1121 logfname,logmode = par.split()
1117 except:
1122 except:
1118 logfname = par
1123 logfname = par
1119 logmode = 'backup'
1124 logmode = 'backup'
1120 else:
1125 else:
1121 logfname = logger.logfname
1126 logfname = logger.logfname
1122 logmode = logger.logmode
1127 logmode = logger.logmode
1123 # put logfname into rc struct as if it had been called on the command
1128 # put logfname into rc struct as if it had been called on the command
1124 # line, so it ends up saved in the log header Save it in case we need
1129 # line, so it ends up saved in the log header Save it in case we need
1125 # to restore it...
1130 # to restore it...
1126 old_logfile = rc.opts.get('logfile','')
1131 old_logfile = rc.opts.get('logfile','')
1127 if logfname:
1132 if logfname:
1128 logfname = os.path.expanduser(logfname)
1133 logfname = os.path.expanduser(logfname)
1129 rc.opts.logfile = logfname
1134 rc.opts.logfile = logfname
1130 loghead = self.shell.loghead_tpl % (rc.opts,rc.args)
1135 loghead = self.shell.loghead_tpl % (rc.opts,rc.args)
1131 try:
1136 try:
1132 started = logger.logstart(logfname,loghead,logmode,
1137 started = logger.logstart(logfname,loghead,logmode,
1133 log_output,timestamp,log_raw_input)
1138 log_output,timestamp,log_raw_input)
1134 except:
1139 except:
1135 rc.opts.logfile = old_logfile
1140 rc.opts.logfile = old_logfile
1136 warn("Couldn't start log: %s" % sys.exc_info()[1])
1141 warn("Couldn't start log: %s" % sys.exc_info()[1])
1137 else:
1142 else:
1138 # log input history up to this point, optionally interleaving
1143 # log input history up to this point, optionally interleaving
1139 # output if requested
1144 # output if requested
1140
1145
1141 if timestamp:
1146 if timestamp:
1142 # disable timestamping for the previous history, since we've
1147 # disable timestamping for the previous history, since we've
1143 # lost those already (no time machine here).
1148 # lost those already (no time machine here).
1144 logger.timestamp = False
1149 logger.timestamp = False
1145
1150
1146 if log_raw_input:
1151 if log_raw_input:
1147 input_hist = self.shell.input_hist_raw
1152 input_hist = self.shell.input_hist_raw
1148 else:
1153 else:
1149 input_hist = self.shell.input_hist
1154 input_hist = self.shell.input_hist
1150
1155
1151 if log_output:
1156 if log_output:
1152 log_write = logger.log_write
1157 log_write = logger.log_write
1153 output_hist = self.shell.output_hist
1158 output_hist = self.shell.output_hist
1154 for n in range(1,len(input_hist)-1):
1159 for n in range(1,len(input_hist)-1):
1155 log_write(input_hist[n].rstrip())
1160 log_write(input_hist[n].rstrip())
1156 if n in output_hist:
1161 if n in output_hist:
1157 log_write(repr(output_hist[n]),'output')
1162 log_write(repr(output_hist[n]),'output')
1158 else:
1163 else:
1159 logger.log_write(input_hist[1:])
1164 logger.log_write(input_hist[1:])
1160 if timestamp:
1165 if timestamp:
1161 # re-enable timestamping
1166 # re-enable timestamping
1162 logger.timestamp = True
1167 logger.timestamp = True
1163
1168
1164 print ('Activating auto-logging. '
1169 print ('Activating auto-logging. '
1165 'Current session state plus future input saved.')
1170 'Current session state plus future input saved.')
1166 logger.logstate()
1171 logger.logstate()
1167
1172
1168 def magic_logstop(self,parameter_s=''):
1173 def magic_logstop(self,parameter_s=''):
1169 """Fully stop logging and close log file.
1174 """Fully stop logging and close log file.
1170
1175
1171 In order to start logging again, a new %logstart call needs to be made,
1176 In order to start logging again, a new %logstart call needs to be made,
1172 possibly (though not necessarily) with a new filename, mode and other
1177 possibly (though not necessarily) with a new filename, mode and other
1173 options."""
1178 options."""
1174 self.logger.logstop()
1179 self.logger.logstop()
1175
1180
1176 def magic_logoff(self,parameter_s=''):
1181 def magic_logoff(self,parameter_s=''):
1177 """Temporarily stop logging.
1182 """Temporarily stop logging.
1178
1183
1179 You must have previously started logging."""
1184 You must have previously started logging."""
1180 self.shell.logger.switch_log(0)
1185 self.shell.logger.switch_log(0)
1181
1186
1182 def magic_logon(self,parameter_s=''):
1187 def magic_logon(self,parameter_s=''):
1183 """Restart logging.
1188 """Restart logging.
1184
1189
1185 This function is for restarting logging which you've temporarily
1190 This function is for restarting logging which you've temporarily
1186 stopped with %logoff. For starting logging for the first time, you
1191 stopped with %logoff. For starting logging for the first time, you
1187 must use the %logstart function, which allows you to specify an
1192 must use the %logstart function, which allows you to specify an
1188 optional log filename."""
1193 optional log filename."""
1189
1194
1190 self.shell.logger.switch_log(1)
1195 self.shell.logger.switch_log(1)
1191
1196
1192 def magic_logstate(self,parameter_s=''):
1197 def magic_logstate(self,parameter_s=''):
1193 """Print the status of the logging system."""
1198 """Print the status of the logging system."""
1194
1199
1195 self.shell.logger.logstate()
1200 self.shell.logger.logstate()
1196
1201
1197 def magic_pdb(self, parameter_s=''):
1202 def magic_pdb(self, parameter_s=''):
1198 """Control the automatic calling of the pdb interactive debugger.
1203 """Control the automatic calling of the pdb interactive debugger.
1199
1204
1200 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
1205 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
1201 argument it works as a toggle.
1206 argument it works as a toggle.
1202
1207
1203 When an exception is triggered, IPython can optionally call the
1208 When an exception is triggered, IPython can optionally call the
1204 interactive pdb debugger after the traceback printout. %pdb toggles
1209 interactive pdb debugger after the traceback printout. %pdb toggles
1205 this feature on and off.
1210 this feature on and off.
1206
1211
1207 The initial state of this feature is set in your ipythonrc
1212 The initial state of this feature is set in your ipythonrc
1208 configuration file (the variable is called 'pdb').
1213 configuration file (the variable is called 'pdb').
1209
1214
1210 If you want to just activate the debugger AFTER an exception has fired,
1215 If you want to just activate the debugger AFTER an exception has fired,
1211 without having to type '%pdb on' and rerunning your code, you can use
1216 without having to type '%pdb on' and rerunning your code, you can use
1212 the %debug magic."""
1217 the %debug magic."""
1213
1218
1214 par = parameter_s.strip().lower()
1219 par = parameter_s.strip().lower()
1215
1220
1216 if par:
1221 if par:
1217 try:
1222 try:
1218 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
1223 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
1219 except KeyError:
1224 except KeyError:
1220 print ('Incorrect argument. Use on/1, off/0, '
1225 print ('Incorrect argument. Use on/1, off/0, '
1221 'or nothing for a toggle.')
1226 'or nothing for a toggle.')
1222 return
1227 return
1223 else:
1228 else:
1224 # toggle
1229 # toggle
1225 new_pdb = not self.shell.call_pdb
1230 new_pdb = not self.shell.call_pdb
1226
1231
1227 # set on the shell
1232 # set on the shell
1228 self.shell.call_pdb = new_pdb
1233 self.shell.call_pdb = new_pdb
1229 print 'Automatic pdb calling has been turned',on_off(new_pdb)
1234 print 'Automatic pdb calling has been turned',on_off(new_pdb)
1230
1235
1231 def magic_debug(self, parameter_s=''):
1236 def magic_debug(self, parameter_s=''):
1232 """Activate the interactive debugger in post-mortem mode.
1237 """Activate the interactive debugger in post-mortem mode.
1233
1238
1234 If an exception has just occurred, this lets you inspect its stack
1239 If an exception has just occurred, this lets you inspect its stack
1235 frames interactively. Note that this will always work only on the last
1240 frames interactively. Note that this will always work only on the last
1236 traceback that occurred, so you must call this quickly after an
1241 traceback that occurred, so you must call this quickly after an
1237 exception that you wish to inspect has fired, because if another one
1242 exception that you wish to inspect has fired, because if another one
1238 occurs, it clobbers the previous one.
1243 occurs, it clobbers the previous one.
1239
1244
1240 If you want IPython to automatically do this on every exception, see
1245 If you want IPython to automatically do this on every exception, see
1241 the %pdb magic for more details.
1246 the %pdb magic for more details.
1242 """
1247 """
1243
1248
1244 self.shell.debugger(force=True)
1249 self.shell.debugger(force=True)
1245
1250
1251 @testdec.skip_doctest
1246 def magic_prun(self, parameter_s ='',user_mode=1,
1252 def magic_prun(self, parameter_s ='',user_mode=1,
1247 opts=None,arg_lst=None,prog_ns=None):
1253 opts=None,arg_lst=None,prog_ns=None):
1248
1254
1249 """Run a statement through the python code profiler.
1255 """Run a statement through the python code profiler.
1250
1256
1251 Usage:\\
1257 Usage:
1252 %prun [options] statement
1258 %prun [options] statement
1253
1259
1254 The given statement (which doesn't require quote marks) is run via the
1260 The given statement (which doesn't require quote marks) is run via the
1255 python profiler in a manner similar to the profile.run() function.
1261 python profiler in a manner similar to the profile.run() function.
1256 Namespaces are internally managed to work correctly; profile.run
1262 Namespaces are internally managed to work correctly; profile.run
1257 cannot be used in IPython because it makes certain assumptions about
1263 cannot be used in IPython because it makes certain assumptions about
1258 namespaces which do not hold under IPython.
1264 namespaces which do not hold under IPython.
1259
1265
1260 Options:
1266 Options:
1261
1267
1262 -l <limit>: you can place restrictions on what or how much of the
1268 -l <limit>: you can place restrictions on what or how much of the
1263 profile gets printed. The limit value can be:
1269 profile gets printed. The limit value can be:
1264
1270
1265 * A string: only information for function names containing this string
1271 * A string: only information for function names containing this string
1266 is printed.
1272 is printed.
1267
1273
1268 * An integer: only these many lines are printed.
1274 * An integer: only these many lines are printed.
1269
1275
1270 * A float (between 0 and 1): this fraction of the report is printed
1276 * A float (between 0 and 1): this fraction of the report is printed
1271 (for example, use a limit of 0.4 to see the topmost 40% only).
1277 (for example, use a limit of 0.4 to see the topmost 40% only).
1272
1278
1273 You can combine several limits with repeated use of the option. For
1279 You can combine several limits with repeated use of the option. For
1274 example, '-l __init__ -l 5' will print only the topmost 5 lines of
1280 example, '-l __init__ -l 5' will print only the topmost 5 lines of
1275 information about class constructors.
1281 information about class constructors.
1276
1282
1277 -r: return the pstats.Stats object generated by the profiling. This
1283 -r: return the pstats.Stats object generated by the profiling. This
1278 object has all the information about the profile in it, and you can
1284 object has all the information about the profile in it, and you can
1279 later use it for further analysis or in other functions.
1285 later use it for further analysis or in other functions.
1280
1286
1281 -s <key>: sort profile by given key. You can provide more than one key
1287 -s <key>: sort profile by given key. You can provide more than one key
1282 by using the option several times: '-s key1 -s key2 -s key3...'. The
1288 by using the option several times: '-s key1 -s key2 -s key3...'. The
1283 default sorting key is 'time'.
1289 default sorting key is 'time'.
1284
1290
1285 The following is copied verbatim from the profile documentation
1291 The following is copied verbatim from the profile documentation
1286 referenced below:
1292 referenced below:
1287
1293
1288 When more than one key is provided, additional keys are used as
1294 When more than one key is provided, additional keys are used as
1289 secondary criteria when the there is equality in all keys selected
1295 secondary criteria when the there is equality in all keys selected
1290 before them.
1296 before them.
1291
1297
1292 Abbreviations can be used for any key names, as long as the
1298 Abbreviations can be used for any key names, as long as the
1293 abbreviation is unambiguous. The following are the keys currently
1299 abbreviation is unambiguous. The following are the keys currently
1294 defined:
1300 defined:
1295
1301
1296 Valid Arg Meaning\\
1302 Valid Arg Meaning
1297 "calls" call count\\
1303 "calls" call count
1298 "cumulative" cumulative time\\
1304 "cumulative" cumulative time
1299 "file" file name\\
1305 "file" file name
1300 "module" file name\\
1306 "module" file name
1301 "pcalls" primitive call count\\
1307 "pcalls" primitive call count
1302 "line" line number\\
1308 "line" line number
1303 "name" function name\\
1309 "name" function name
1304 "nfl" name/file/line\\
1310 "nfl" name/file/line
1305 "stdname" standard name\\
1311 "stdname" standard name
1306 "time" internal time
1312 "time" internal time
1307
1313
1308 Note that all sorts on statistics are in descending order (placing
1314 Note that all sorts on statistics are in descending order (placing
1309 most time consuming items first), where as name, file, and line number
1315 most time consuming items first), where as name, file, and line number
1310 searches are in ascending order (i.e., alphabetical). The subtle
1316 searches are in ascending order (i.e., alphabetical). The subtle
1311 distinction between "nfl" and "stdname" is that the standard name is a
1317 distinction between "nfl" and "stdname" is that the standard name is a
1312 sort of the name as printed, which means that the embedded line
1318 sort of the name as printed, which means that the embedded line
1313 numbers get compared in an odd way. For example, lines 3, 20, and 40
1319 numbers get compared in an odd way. For example, lines 3, 20, and 40
1314 would (if the file names were the same) appear in the string order
1320 would (if the file names were the same) appear in the string order
1315 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
1321 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
1316 line numbers. In fact, sort_stats("nfl") is the same as
1322 line numbers. In fact, sort_stats("nfl") is the same as
1317 sort_stats("name", "file", "line").
1323 sort_stats("name", "file", "line").
1318
1324
1319 -T <filename>: save profile results as shown on screen to a text
1325 -T <filename>: save profile results as shown on screen to a text
1320 file. The profile is still shown on screen.
1326 file. The profile is still shown on screen.
1321
1327
1322 -D <filename>: save (via dump_stats) profile statistics to given
1328 -D <filename>: save (via dump_stats) profile statistics to given
1323 filename. This data is in a format understod by the pstats module, and
1329 filename. This data is in a format understod by the pstats module, and
1324 is generated by a call to the dump_stats() method of profile
1330 is generated by a call to the dump_stats() method of profile
1325 objects. The profile is still shown on screen.
1331 objects. The profile is still shown on screen.
1326
1332
1327 If you want to run complete programs under the profiler's control, use
1333 If you want to run complete programs under the profiler's control, use
1328 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
1334 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
1329 contains profiler specific options as described here.
1335 contains profiler specific options as described here.
1330
1336
1331 You can read the complete documentation for the profile module with:\\
1337 You can read the complete documentation for the profile module with::
1332 In [1]: import profile; profile.help() """
1338
1339 In [1]: import profile; profile.help()
1340 """
1333
1341
1334 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
1342 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
1335 # protect user quote marks
1343 # protect user quote marks
1336 parameter_s = parameter_s.replace('"',r'\"').replace("'",r"\'")
1344 parameter_s = parameter_s.replace('"',r'\"').replace("'",r"\'")
1337
1345
1338 if user_mode: # regular user call
1346 if user_mode: # regular user call
1339 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:',
1347 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:',
1340 list_all=1)
1348 list_all=1)
1341 namespace = self.shell.user_ns
1349 namespace = self.shell.user_ns
1342 else: # called to run a program by %run -p
1350 else: # called to run a program by %run -p
1343 try:
1351 try:
1344 filename = get_py_filename(arg_lst[0])
1352 filename = get_py_filename(arg_lst[0])
1345 except IOError,msg:
1353 except IOError,msg:
1346 error(msg)
1354 error(msg)
1347 return
1355 return
1348
1356
1349 arg_str = 'execfile(filename,prog_ns)'
1357 arg_str = 'execfile(filename,prog_ns)'
1350 namespace = locals()
1358 namespace = locals()
1351
1359
1352 opts.merge(opts_def)
1360 opts.merge(opts_def)
1353
1361
1354 prof = profile.Profile()
1362 prof = profile.Profile()
1355 try:
1363 try:
1356 prof = prof.runctx(arg_str,namespace,namespace)
1364 prof = prof.runctx(arg_str,namespace,namespace)
1357 sys_exit = ''
1365 sys_exit = ''
1358 except SystemExit:
1366 except SystemExit:
1359 sys_exit = """*** SystemExit exception caught in code being profiled."""
1367 sys_exit = """*** SystemExit exception caught in code being profiled."""
1360
1368
1361 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
1369 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
1362
1370
1363 lims = opts.l
1371 lims = opts.l
1364 if lims:
1372 if lims:
1365 lims = [] # rebuild lims with ints/floats/strings
1373 lims = [] # rebuild lims with ints/floats/strings
1366 for lim in opts.l:
1374 for lim in opts.l:
1367 try:
1375 try:
1368 lims.append(int(lim))
1376 lims.append(int(lim))
1369 except ValueError:
1377 except ValueError:
1370 try:
1378 try:
1371 lims.append(float(lim))
1379 lims.append(float(lim))
1372 except ValueError:
1380 except ValueError:
1373 lims.append(lim)
1381 lims.append(lim)
1374
1382
1375 # Trap output.
1383 # Trap output.
1376 stdout_trap = StringIO()
1384 stdout_trap = StringIO()
1377
1385
1378 if hasattr(stats,'stream'):
1386 if hasattr(stats,'stream'):
1379 # In newer versions of python, the stats object has a 'stream'
1387 # In newer versions of python, the stats object has a 'stream'
1380 # attribute to write into.
1388 # attribute to write into.
1381 stats.stream = stdout_trap
1389 stats.stream = stdout_trap
1382 stats.print_stats(*lims)
1390 stats.print_stats(*lims)
1383 else:
1391 else:
1384 # For older versions, we manually redirect stdout during printing
1392 # For older versions, we manually redirect stdout during printing
1385 sys_stdout = sys.stdout
1393 sys_stdout = sys.stdout
1386 try:
1394 try:
1387 sys.stdout = stdout_trap
1395 sys.stdout = stdout_trap
1388 stats.print_stats(*lims)
1396 stats.print_stats(*lims)
1389 finally:
1397 finally:
1390 sys.stdout = sys_stdout
1398 sys.stdout = sys_stdout
1391
1399
1392 output = stdout_trap.getvalue()
1400 output = stdout_trap.getvalue()
1393 output = output.rstrip()
1401 output = output.rstrip()
1394
1402
1395 page(output,screen_lines=self.shell.rc.screen_length)
1403 page(output,screen_lines=self.shell.rc.screen_length)
1396 print sys_exit,
1404 print sys_exit,
1397
1405
1398 dump_file = opts.D[0]
1406 dump_file = opts.D[0]
1399 text_file = opts.T[0]
1407 text_file = opts.T[0]
1400 if dump_file:
1408 if dump_file:
1401 prof.dump_stats(dump_file)
1409 prof.dump_stats(dump_file)
1402 print '\n*** Profile stats marshalled to file',\
1410 print '\n*** Profile stats marshalled to file',\
1403 `dump_file`+'.',sys_exit
1411 `dump_file`+'.',sys_exit
1404 if text_file:
1412 if text_file:
1405 pfile = file(text_file,'w')
1413 pfile = file(text_file,'w')
1406 pfile.write(output)
1414 pfile.write(output)
1407 pfile.close()
1415 pfile.close()
1408 print '\n*** Profile printout saved to text file',\
1416 print '\n*** Profile printout saved to text file',\
1409 `text_file`+'.',sys_exit
1417 `text_file`+'.',sys_exit
1410
1418
1411 if opts.has_key('r'):
1419 if opts.has_key('r'):
1412 return stats
1420 return stats
1413 else:
1421 else:
1414 return None
1422 return None
1415
1423
1424 @testdec.skip_doctest
1416 def magic_run(self, parameter_s ='',runner=None):
1425 def magic_run(self, parameter_s ='',runner=None):
1417 """Run the named file inside IPython as a program.
1426 """Run the named file inside IPython as a program.
1418
1427
1419 Usage:\\
1428 Usage:\\
1420 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options]] file [args]
1429 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options]] file [args]
1421
1430
1422 Parameters after the filename are passed as command-line arguments to
1431 Parameters after the filename are passed as command-line arguments to
1423 the program (put in sys.argv). Then, control returns to IPython's
1432 the program (put in sys.argv). Then, control returns to IPython's
1424 prompt.
1433 prompt.
1425
1434
1426 This is similar to running at a system prompt:\\
1435 This is similar to running at a system prompt:\\
1427 $ python file args\\
1436 $ python file args\\
1428 but with the advantage of giving you IPython's tracebacks, and of
1437 but with the advantage of giving you IPython's tracebacks, and of
1429 loading all variables into your interactive namespace for further use
1438 loading all variables into your interactive namespace for further use
1430 (unless -p is used, see below).
1439 (unless -p is used, see below).
1431
1440
1432 The file is executed in a namespace initially consisting only of
1441 The file is executed in a namespace initially consisting only of
1433 __name__=='__main__' and sys.argv constructed as indicated. It thus
1442 __name__=='__main__' and sys.argv constructed as indicated. It thus
1434 sees its environment as if it were being run as a stand-alone program
1443 sees its environment as if it were being run as a stand-alone program
1435 (except for sharing global objects such as previously imported
1444 (except for sharing global objects such as previously imported
1436 modules). But after execution, the IPython interactive namespace gets
1445 modules). But after execution, the IPython interactive namespace gets
1437 updated with all variables defined in the program (except for __name__
1446 updated with all variables defined in the program (except for __name__
1438 and sys.argv). This allows for very convenient loading of code for
1447 and sys.argv). This allows for very convenient loading of code for
1439 interactive work, while giving each program a 'clean sheet' to run in.
1448 interactive work, while giving each program a 'clean sheet' to run in.
1440
1449
1441 Options:
1450 Options:
1442
1451
1443 -n: __name__ is NOT set to '__main__', but to the running file's name
1452 -n: __name__ is NOT set to '__main__', but to the running file's name
1444 without extension (as python does under import). This allows running
1453 without extension (as python does under import). This allows running
1445 scripts and reloading the definitions in them without calling code
1454 scripts and reloading the definitions in them without calling code
1446 protected by an ' if __name__ == "__main__" ' clause.
1455 protected by an ' if __name__ == "__main__" ' clause.
1447
1456
1448 -i: run the file in IPython's namespace instead of an empty one. This
1457 -i: run the file in IPython's namespace instead of an empty one. This
1449 is useful if you are experimenting with code written in a text editor
1458 is useful if you are experimenting with code written in a text editor
1450 which depends on variables defined interactively.
1459 which depends on variables defined interactively.
1451
1460
1452 -e: ignore sys.exit() calls or SystemExit exceptions in the script
1461 -e: ignore sys.exit() calls or SystemExit exceptions in the script
1453 being run. This is particularly useful if IPython is being used to
1462 being run. This is particularly useful if IPython is being used to
1454 run unittests, which always exit with a sys.exit() call. In such
1463 run unittests, which always exit with a sys.exit() call. In such
1455 cases you are interested in the output of the test results, not in
1464 cases you are interested in the output of the test results, not in
1456 seeing a traceback of the unittest module.
1465 seeing a traceback of the unittest module.
1457
1466
1458 -t: print timing information at the end of the run. IPython will give
1467 -t: print timing information at the end of the run. IPython will give
1459 you an estimated CPU time consumption for your script, which under
1468 you an estimated CPU time consumption for your script, which under
1460 Unix uses the resource module to avoid the wraparound problems of
1469 Unix uses the resource module to avoid the wraparound problems of
1461 time.clock(). Under Unix, an estimate of time spent on system tasks
1470 time.clock(). Under Unix, an estimate of time spent on system tasks
1462 is also given (for Windows platforms this is reported as 0.0).
1471 is also given (for Windows platforms this is reported as 0.0).
1463
1472
1464 If -t is given, an additional -N<N> option can be given, where <N>
1473 If -t is given, an additional -N<N> option can be given, where <N>
1465 must be an integer indicating how many times you want the script to
1474 must be an integer indicating how many times you want the script to
1466 run. The final timing report will include total and per run results.
1475 run. The final timing report will include total and per run results.
1467
1476
1468 For example (testing the script uniq_stable.py):
1477 For example (testing the script uniq_stable.py):
1469
1478
1470 In [1]: run -t uniq_stable
1479 In [1]: run -t uniq_stable
1471
1480
1472 IPython CPU timings (estimated):\\
1481 IPython CPU timings (estimated):\\
1473 User : 0.19597 s.\\
1482 User : 0.19597 s.\\
1474 System: 0.0 s.\\
1483 System: 0.0 s.\\
1475
1484
1476 In [2]: run -t -N5 uniq_stable
1485 In [2]: run -t -N5 uniq_stable
1477
1486
1478 IPython CPU timings (estimated):\\
1487 IPython CPU timings (estimated):\\
1479 Total runs performed: 5\\
1488 Total runs performed: 5\\
1480 Times : Total Per run\\
1489 Times : Total Per run\\
1481 User : 0.910862 s, 0.1821724 s.\\
1490 User : 0.910862 s, 0.1821724 s.\\
1482 System: 0.0 s, 0.0 s.
1491 System: 0.0 s, 0.0 s.
1483
1492
1484 -d: run your program under the control of pdb, the Python debugger.
1493 -d: run your program under the control of pdb, the Python debugger.
1485 This allows you to execute your program step by step, watch variables,
1494 This allows you to execute your program step by step, watch variables,
1486 etc. Internally, what IPython does is similar to calling:
1495 etc. Internally, what IPython does is similar to calling:
1487
1496
1488 pdb.run('execfile("YOURFILENAME")')
1497 pdb.run('execfile("YOURFILENAME")')
1489
1498
1490 with a breakpoint set on line 1 of your file. You can change the line
1499 with a breakpoint set on line 1 of your file. You can change the line
1491 number for this automatic breakpoint to be <N> by using the -bN option
1500 number for this automatic breakpoint to be <N> by using the -bN option
1492 (where N must be an integer). For example:
1501 (where N must be an integer). For example:
1493
1502
1494 %run -d -b40 myscript
1503 %run -d -b40 myscript
1495
1504
1496 will set the first breakpoint at line 40 in myscript.py. Note that
1505 will set the first breakpoint at line 40 in myscript.py. Note that
1497 the first breakpoint must be set on a line which actually does
1506 the first breakpoint must be set on a line which actually does
1498 something (not a comment or docstring) for it to stop execution.
1507 something (not a comment or docstring) for it to stop execution.
1499
1508
1500 When the pdb debugger starts, you will see a (Pdb) prompt. You must
1509 When the pdb debugger starts, you will see a (Pdb) prompt. You must
1501 first enter 'c' (without qoutes) to start execution up to the first
1510 first enter 'c' (without qoutes) to start execution up to the first
1502 breakpoint.
1511 breakpoint.
1503
1512
1504 Entering 'help' gives information about the use of the debugger. You
1513 Entering 'help' gives information about the use of the debugger. You
1505 can easily see pdb's full documentation with "import pdb;pdb.help()"
1514 can easily see pdb's full documentation with "import pdb;pdb.help()"
1506 at a prompt.
1515 at a prompt.
1507
1516
1508 -p: run program under the control of the Python profiler module (which
1517 -p: run program under the control of the Python profiler module (which
1509 prints a detailed report of execution times, function calls, etc).
1518 prints a detailed report of execution times, function calls, etc).
1510
1519
1511 You can pass other options after -p which affect the behavior of the
1520 You can pass other options after -p which affect the behavior of the
1512 profiler itself. See the docs for %prun for details.
1521 profiler itself. See the docs for %prun for details.
1513
1522
1514 In this mode, the program's variables do NOT propagate back to the
1523 In this mode, the program's variables do NOT propagate back to the
1515 IPython interactive namespace (because they remain in the namespace
1524 IPython interactive namespace (because they remain in the namespace
1516 where the profiler executes them).
1525 where the profiler executes them).
1517
1526
1518 Internally this triggers a call to %prun, see its documentation for
1527 Internally this triggers a call to %prun, see its documentation for
1519 details on the options available specifically for profiling.
1528 details on the options available specifically for profiling.
1520
1529
1521 There is one special usage for which the text above doesn't apply:
1530 There is one special usage for which the text above doesn't apply:
1522 if the filename ends with .ipy, the file is run as ipython script,
1531 if the filename ends with .ipy, the file is run as ipython script,
1523 just as if the commands were written on IPython prompt.
1532 just as if the commands were written on IPython prompt.
1524 """
1533 """
1525
1534
1526 # get arguments and set sys.argv for program to be run.
1535 # get arguments and set sys.argv for program to be run.
1527 opts,arg_lst = self.parse_options(parameter_s,'nidtN:b:pD:l:rs:T:e',
1536 opts,arg_lst = self.parse_options(parameter_s,'nidtN:b:pD:l:rs:T:e',
1528 mode='list',list_all=1)
1537 mode='list',list_all=1)
1529
1538
1530 try:
1539 try:
1531 filename = get_py_filename(arg_lst[0])
1540 filename = get_py_filename(arg_lst[0])
1532 except IndexError:
1541 except IndexError:
1533 warn('you must provide at least a filename.')
1542 warn('you must provide at least a filename.')
1534 print '\n%run:\n',OInspect.getdoc(self.magic_run)
1543 print '\n%run:\n',OInspect.getdoc(self.magic_run)
1535 return
1544 return
1536 except IOError,msg:
1545 except IOError,msg:
1537 error(msg)
1546 error(msg)
1538 return
1547 return
1539
1548
1540 if filename.lower().endswith('.ipy'):
1549 if filename.lower().endswith('.ipy'):
1541 self.api.runlines(open(filename).read())
1550 self.api.runlines(open(filename).read())
1542 return
1551 return
1543
1552
1544 # Control the response to exit() calls made by the script being run
1553 # Control the response to exit() calls made by the script being run
1545 exit_ignore = opts.has_key('e')
1554 exit_ignore = opts.has_key('e')
1546
1555
1547 # Make sure that the running script gets a proper sys.argv as if it
1556 # Make sure that the running script gets a proper sys.argv as if it
1548 # were run from a system shell.
1557 # were run from a system shell.
1549 save_argv = sys.argv # save it for later restoring
1558 save_argv = sys.argv # save it for later restoring
1550 sys.argv = [filename]+ arg_lst[1:] # put in the proper filename
1559 sys.argv = [filename]+ arg_lst[1:] # put in the proper filename
1551
1560
1552 if opts.has_key('i'):
1561 if opts.has_key('i'):
1553 # Run in user's interactive namespace
1562 # Run in user's interactive namespace
1554 prog_ns = self.shell.user_ns
1563 prog_ns = self.shell.user_ns
1555 __name__save = self.shell.user_ns['__name__']
1564 __name__save = self.shell.user_ns['__name__']
1556 prog_ns['__name__'] = '__main__'
1565 prog_ns['__name__'] = '__main__'
1557 main_mod = FakeModule(prog_ns)
1566 main_mod = FakeModule(prog_ns)
1558 else:
1567 else:
1559 # Run in a fresh, empty namespace
1568 # Run in a fresh, empty namespace
1560 if opts.has_key('n'):
1569 if opts.has_key('n'):
1561 name = os.path.splitext(os.path.basename(filename))[0]
1570 name = os.path.splitext(os.path.basename(filename))[0]
1562 else:
1571 else:
1563 name = '__main__'
1572 name = '__main__'
1564 main_mod = FakeModule()
1573 main_mod = FakeModule()
1565 prog_ns = main_mod.__dict__
1574 prog_ns = main_mod.__dict__
1566 prog_ns['__name__'] = name
1575 prog_ns['__name__'] = name
1567 # The shell MUST hold a reference to main_mod so after %run exits,
1576 # The shell MUST hold a reference to main_mod so after %run exits,
1568 # the python deletion mechanism doesn't zero it out (leaving
1577 # the python deletion mechanism doesn't zero it out (leaving
1569 # dangling references)
1578 # dangling references)
1570 self.shell._user_main_modules.append(main_mod)
1579 self.shell._user_main_modules.append(main_mod)
1571
1580
1572 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
1581 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
1573 # set the __file__ global in the script's namespace
1582 # set the __file__ global in the script's namespace
1574 prog_ns['__file__'] = filename
1583 prog_ns['__file__'] = filename
1575
1584
1576 # pickle fix. See iplib for an explanation. But we need to make sure
1585 # pickle fix. See iplib for an explanation. But we need to make sure
1577 # that, if we overwrite __main__, we replace it at the end
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 restore_main = sys.modules['__main__']
1590 restore_main = sys.modules['__main__']
1580 else:
1591 else:
1581 restore_main = False
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 stats = None
1598 stats = None
1586 try:
1599 try:
1587 self.shell.savehist()
1600 self.shell.savehist()
1588
1601
1589 if opts.has_key('p'):
1602 if opts.has_key('p'):
1590 stats = self.magic_prun('',0,opts,arg_lst,prog_ns)
1603 stats = self.magic_prun('',0,opts,arg_lst,prog_ns)
1591 else:
1604 else:
1592 if opts.has_key('d'):
1605 if opts.has_key('d'):
1593 deb = Debugger.Pdb(self.shell.rc.colors)
1606 deb = Debugger.Pdb(self.shell.rc.colors)
1594 # reset Breakpoint state, which is moronically kept
1607 # reset Breakpoint state, which is moronically kept
1595 # in a class
1608 # in a class
1596 bdb.Breakpoint.next = 1
1609 bdb.Breakpoint.next = 1
1597 bdb.Breakpoint.bplist = {}
1610 bdb.Breakpoint.bplist = {}
1598 bdb.Breakpoint.bpbynumber = [None]
1611 bdb.Breakpoint.bpbynumber = [None]
1599 # Set an initial breakpoint to stop execution
1612 # Set an initial breakpoint to stop execution
1600 maxtries = 10
1613 maxtries = 10
1601 bp = int(opts.get('b',[1])[0])
1614 bp = int(opts.get('b',[1])[0])
1602 checkline = deb.checkline(filename,bp)
1615 checkline = deb.checkline(filename,bp)
1603 if not checkline:
1616 if not checkline:
1604 for bp in range(bp+1,bp+maxtries+1):
1617 for bp in range(bp+1,bp+maxtries+1):
1605 if deb.checkline(filename,bp):
1618 if deb.checkline(filename,bp):
1606 break
1619 break
1607 else:
1620 else:
1608 msg = ("\nI failed to find a valid line to set "
1621 msg = ("\nI failed to find a valid line to set "
1609 "a breakpoint\n"
1622 "a breakpoint\n"
1610 "after trying up to line: %s.\n"
1623 "after trying up to line: %s.\n"
1611 "Please set a valid breakpoint manually "
1624 "Please set a valid breakpoint manually "
1612 "with the -b option." % bp)
1625 "with the -b option." % bp)
1613 error(msg)
1626 error(msg)
1614 return
1627 return
1615 # if we find a good linenumber, set the breakpoint
1628 # if we find a good linenumber, set the breakpoint
1616 deb.do_break('%s:%s' % (filename,bp))
1629 deb.do_break('%s:%s' % (filename,bp))
1617 # Start file run
1630 # Start file run
1618 print "NOTE: Enter 'c' at the",
1631 print "NOTE: Enter 'c' at the",
1619 print "%s prompt to start your script." % deb.prompt
1632 print "%s prompt to start your script." % deb.prompt
1620 try:
1633 try:
1621 deb.run('execfile("%s")' % filename,prog_ns)
1634 deb.run('execfile("%s")' % filename,prog_ns)
1622
1635
1623 except:
1636 except:
1624 etype, value, tb = sys.exc_info()
1637 etype, value, tb = sys.exc_info()
1625 # Skip three frames in the traceback: the %run one,
1638 # Skip three frames in the traceback: the %run one,
1626 # one inside bdb.py, and the command-line typed by the
1639 # one inside bdb.py, and the command-line typed by the
1627 # user (run by exec in pdb itself).
1640 # user (run by exec in pdb itself).
1628 self.shell.InteractiveTB(etype,value,tb,tb_offset=3)
1641 self.shell.InteractiveTB(etype,value,tb,tb_offset=3)
1629 else:
1642 else:
1630 if runner is None:
1643 if runner is None:
1631 runner = self.shell.safe_execfile
1644 runner = self.shell.safe_execfile
1632 if opts.has_key('t'):
1645 if opts.has_key('t'):
1633 # timed execution
1646 # timed execution
1634 try:
1647 try:
1635 nruns = int(opts['N'][0])
1648 nruns = int(opts['N'][0])
1636 if nruns < 1:
1649 if nruns < 1:
1637 error('Number of runs must be >=1')
1650 error('Number of runs must be >=1')
1638 return
1651 return
1639 except (KeyError):
1652 except (KeyError):
1640 nruns = 1
1653 nruns = 1
1641 if nruns == 1:
1654 if nruns == 1:
1642 t0 = clock2()
1655 t0 = clock2()
1643 runner(filename,prog_ns,prog_ns,
1656 runner(filename,prog_ns,prog_ns,
1644 exit_ignore=exit_ignore)
1657 exit_ignore=exit_ignore)
1645 t1 = clock2()
1658 t1 = clock2()
1646 t_usr = t1[0]-t0[0]
1659 t_usr = t1[0]-t0[0]
1647 t_sys = t1[1]-t1[1]
1660 t_sys = t1[1]-t1[1]
1648 print "\nIPython CPU timings (estimated):"
1661 print "\nIPython CPU timings (estimated):"
1649 print " User : %10s s." % t_usr
1662 print " User : %10s s." % t_usr
1650 print " System: %10s s." % t_sys
1663 print " System: %10s s." % t_sys
1651 else:
1664 else:
1652 runs = range(nruns)
1665 runs = range(nruns)
1653 t0 = clock2()
1666 t0 = clock2()
1654 for nr in runs:
1667 for nr in runs:
1655 runner(filename,prog_ns,prog_ns,
1668 runner(filename,prog_ns,prog_ns,
1656 exit_ignore=exit_ignore)
1669 exit_ignore=exit_ignore)
1657 t1 = clock2()
1670 t1 = clock2()
1658 t_usr = t1[0]-t0[0]
1671 t_usr = t1[0]-t0[0]
1659 t_sys = t1[1]-t1[1]
1672 t_sys = t1[1]-t1[1]
1660 print "\nIPython CPU timings (estimated):"
1673 print "\nIPython CPU timings (estimated):"
1661 print "Total runs performed:",nruns
1674 print "Total runs performed:",nruns
1662 print " Times : %10s %10s" % ('Total','Per run')
1675 print " Times : %10s %10s" % ('Total','Per run')
1663 print " User : %10s s, %10s s." % (t_usr,t_usr/nruns)
1676 print " User : %10s s, %10s s." % (t_usr,t_usr/nruns)
1664 print " System: %10s s, %10s s." % (t_sys,t_sys/nruns)
1677 print " System: %10s s, %10s s." % (t_sys,t_sys/nruns)
1665
1678
1666 else:
1679 else:
1667 # regular execution
1680 # regular execution
1668 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1681 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1669 if opts.has_key('i'):
1682 if opts.has_key('i'):
1670 self.shell.user_ns['__name__'] = __name__save
1683 self.shell.user_ns['__name__'] = __name__save
1671 else:
1684 else:
1672 # update IPython interactive namespace
1685 # update IPython interactive namespace
1673 del prog_ns['__name__']
1686 del prog_ns['__name__']
1674 self.shell.user_ns.update(prog_ns)
1687 self.shell.user_ns.update(prog_ns)
1675 finally:
1688 finally:
1689 # Ensure key global structures are restored
1676 sys.argv = save_argv
1690 sys.argv = save_argv
1677 if restore_main:
1691 if restore_main:
1678 sys.modules['__main__'] = restore_main
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 self.shell.reloadhist()
1698 self.shell.reloadhist()
1680
1699
1681 return stats
1700 return stats
1682
1701
1683 def magic_runlog(self, parameter_s =''):
1702 def magic_runlog(self, parameter_s =''):
1684 """Run files as logs.
1703 """Run files as logs.
1685
1704
1686 Usage:\\
1705 Usage:\\
1687 %runlog file1 file2 ...
1706 %runlog file1 file2 ...
1688
1707
1689 Run the named files (treating them as log files) in sequence inside
1708 Run the named files (treating them as log files) in sequence inside
1690 the interpreter, and return to the prompt. This is much slower than
1709 the interpreter, and return to the prompt. This is much slower than
1691 %run because each line is executed in a try/except block, but it
1710 %run because each line is executed in a try/except block, but it
1692 allows running files with syntax errors in them.
1711 allows running files with syntax errors in them.
1693
1712
1694 Normally IPython will guess when a file is one of its own logfiles, so
1713 Normally IPython will guess when a file is one of its own logfiles, so
1695 you can typically use %run even for logs. This shorthand allows you to
1714 you can typically use %run even for logs. This shorthand allows you to
1696 force any file to be treated as a log file."""
1715 force any file to be treated as a log file."""
1697
1716
1698 for f in parameter_s.split():
1717 for f in parameter_s.split():
1699 self.shell.safe_execfile(f,self.shell.user_ns,
1718 self.shell.safe_execfile(f,self.shell.user_ns,
1700 self.shell.user_ns,islog=1)
1719 self.shell.user_ns,islog=1)
1701
1720
1721 @testdec.skip_doctest
1702 def magic_timeit(self, parameter_s =''):
1722 def magic_timeit(self, parameter_s =''):
1703 """Time execution of a Python statement or expression
1723 """Time execution of a Python statement or expression
1704
1724
1705 Usage:\\
1725 Usage:\\
1706 %timeit [-n<N> -r<R> [-t|-c]] statement
1726 %timeit [-n<N> -r<R> [-t|-c]] statement
1707
1727
1708 Time execution of a Python statement or expression using the timeit
1728 Time execution of a Python statement or expression using the timeit
1709 module.
1729 module.
1710
1730
1711 Options:
1731 Options:
1712 -n<N>: execute the given statement <N> times in a loop. If this value
1732 -n<N>: execute the given statement <N> times in a loop. If this value
1713 is not given, a fitting value is chosen.
1733 is not given, a fitting value is chosen.
1714
1734
1715 -r<R>: repeat the loop iteration <R> times and take the best result.
1735 -r<R>: repeat the loop iteration <R> times and take the best result.
1716 Default: 3
1736 Default: 3
1717
1737
1718 -t: use time.time to measure the time, which is the default on Unix.
1738 -t: use time.time to measure the time, which is the default on Unix.
1719 This function measures wall time.
1739 This function measures wall time.
1720
1740
1721 -c: use time.clock to measure the time, which is the default on
1741 -c: use time.clock to measure the time, which is the default on
1722 Windows and measures wall time. On Unix, resource.getrusage is used
1742 Windows and measures wall time. On Unix, resource.getrusage is used
1723 instead and returns the CPU user time.
1743 instead and returns the CPU user time.
1724
1744
1725 -p<P>: use a precision of <P> digits to display the timing result.
1745 -p<P>: use a precision of <P> digits to display the timing result.
1726 Default: 3
1746 Default: 3
1727
1747
1728
1748
1729 Examples:\\
1749 Examples:
1750
1730 In [1]: %timeit pass
1751 In [1]: %timeit pass
1731 10000000 loops, best of 3: 53.3 ns per loop
1752 10000000 loops, best of 3: 53.3 ns per loop
1732
1753
1733 In [2]: u = None
1754 In [2]: u = None
1734
1755
1735 In [3]: %timeit u is None
1756 In [3]: %timeit u is None
1736 10000000 loops, best of 3: 184 ns per loop
1757 10000000 loops, best of 3: 184 ns per loop
1737
1758
1738 In [4]: %timeit -r 4 u == None
1759 In [4]: %timeit -r 4 u == None
1739 1000000 loops, best of 4: 242 ns per loop
1760 1000000 loops, best of 4: 242 ns per loop
1740
1761
1741 In [5]: import time
1762 In [5]: import time
1742
1763
1743 In [6]: %timeit -n1 time.sleep(2)
1764 In [6]: %timeit -n1 time.sleep(2)
1744 1 loops, best of 3: 2 s per loop
1765 1 loops, best of 3: 2 s per loop
1745
1766
1746
1767
1747 The times reported by %timeit will be slightly higher than those
1768 The times reported by %timeit will be slightly higher than those
1748 reported by the timeit.py script when variables are accessed. This is
1769 reported by the timeit.py script when variables are accessed. This is
1749 due to the fact that %timeit executes the statement in the namespace
1770 due to the fact that %timeit executes the statement in the namespace
1750 of the shell, compared with timeit.py, which uses a single setup
1771 of the shell, compared with timeit.py, which uses a single setup
1751 statement to import function or create variables. Generally, the bias
1772 statement to import function or create variables. Generally, the bias
1752 does not matter as long as results from timeit.py are not mixed with
1773 does not matter as long as results from timeit.py are not mixed with
1753 those from %timeit."""
1774 those from %timeit."""
1754
1775
1755 import timeit
1776 import timeit
1756 import math
1777 import math
1757
1778
1758 units = ["s", "ms", "\xc2\xb5s", "ns"]
1779 units = [u"s", u"ms", u"\xb5s", u"ns"]
1759 scaling = [1, 1e3, 1e6, 1e9]
1780 scaling = [1, 1e3, 1e6, 1e9]
1760
1781
1761 opts, stmt = self.parse_options(parameter_s,'n:r:tcp:',
1782 opts, stmt = self.parse_options(parameter_s,'n:r:tcp:',
1762 posix=False)
1783 posix=False)
1763 if stmt == "":
1784 if stmt == "":
1764 return
1785 return
1765 timefunc = timeit.default_timer
1786 timefunc = timeit.default_timer
1766 number = int(getattr(opts, "n", 0))
1787 number = int(getattr(opts, "n", 0))
1767 repeat = int(getattr(opts, "r", timeit.default_repeat))
1788 repeat = int(getattr(opts, "r", timeit.default_repeat))
1768 precision = int(getattr(opts, "p", 3))
1789 precision = int(getattr(opts, "p", 3))
1769 if hasattr(opts, "t"):
1790 if hasattr(opts, "t"):
1770 timefunc = time.time
1791 timefunc = time.time
1771 if hasattr(opts, "c"):
1792 if hasattr(opts, "c"):
1772 timefunc = clock
1793 timefunc = clock
1773
1794
1774 timer = timeit.Timer(timer=timefunc)
1795 timer = timeit.Timer(timer=timefunc)
1775 # this code has tight coupling to the inner workings of timeit.Timer,
1796 # this code has tight coupling to the inner workings of timeit.Timer,
1776 # but is there a better way to achieve that the code stmt has access
1797 # but is there a better way to achieve that the code stmt has access
1777 # to the shell namespace?
1798 # to the shell namespace?
1778
1799
1779 src = timeit.template % {'stmt': timeit.reindent(stmt, 8),
1800 src = timeit.template % {'stmt': timeit.reindent(stmt, 8),
1780 'setup': "pass"}
1801 'setup': "pass"}
1781 # Track compilation time so it can be reported if too long
1802 # Track compilation time so it can be reported if too long
1782 # Minimum time above which compilation time will be reported
1803 # Minimum time above which compilation time will be reported
1783 tc_min = 0.1
1804 tc_min = 0.1
1784
1805
1785 t0 = clock()
1806 t0 = clock()
1786 code = compile(src, "<magic-timeit>", "exec")
1807 code = compile(src, "<magic-timeit>", "exec")
1787 tc = clock()-t0
1808 tc = clock()-t0
1788
1809
1789 ns = {}
1810 ns = {}
1790 exec code in self.shell.user_ns, ns
1811 exec code in self.shell.user_ns, ns
1791 timer.inner = ns["inner"]
1812 timer.inner = ns["inner"]
1792
1813
1793 if number == 0:
1814 if number == 0:
1794 # determine number so that 0.2 <= total time < 2.0
1815 # determine number so that 0.2 <= total time < 2.0
1795 number = 1
1816 number = 1
1796 for i in range(1, 10):
1817 for i in range(1, 10):
1797 number *= 10
1818 number *= 10
1798 if timer.timeit(number) >= 0.2:
1819 if timer.timeit(number) >= 0.2:
1799 break
1820 break
1800
1821
1801 best = min(timer.repeat(repeat, number)) / number
1822 best = min(timer.repeat(repeat, number)) / number
1802
1823
1803 if best > 0.0:
1824 if best > 0.0:
1804 order = min(-int(math.floor(math.log10(best)) // 3), 3)
1825 order = min(-int(math.floor(math.log10(best)) // 3), 3)
1805 else:
1826 else:
1806 order = 3
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 precision,
1829 precision,
1809 best * scaling[order],
1830 best * scaling[order],
1810 units[order])
1831 units[order])
1811 if tc > tc_min:
1832 if tc > tc_min:
1812 print "Compiler time: %.2f s" % tc
1833 print "Compiler time: %.2f s" % tc
1813
1834
1835 @testdec.skip_doctest
1814 def magic_time(self,parameter_s = ''):
1836 def magic_time(self,parameter_s = ''):
1815 """Time execution of a Python statement or expression.
1837 """Time execution of a Python statement or expression.
1816
1838
1817 The CPU and wall clock times are printed, and the value of the
1839 The CPU and wall clock times are printed, and the value of the
1818 expression (if any) is returned. Note that under Win32, system time
1840 expression (if any) is returned. Note that under Win32, system time
1819 is always reported as 0, since it can not be measured.
1841 is always reported as 0, since it can not be measured.
1820
1842
1821 This function provides very basic timing functionality. In Python
1843 This function provides very basic timing functionality. In Python
1822 2.3, the timeit module offers more control and sophistication, so this
1844 2.3, the timeit module offers more control and sophistication, so this
1823 could be rewritten to use it (patches welcome).
1845 could be rewritten to use it (patches welcome).
1824
1846
1825 Some examples:
1847 Some examples:
1826
1848
1827 In [1]: time 2**128
1849 In [1]: time 2**128
1828 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1850 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1829 Wall time: 0.00
1851 Wall time: 0.00
1830 Out[1]: 340282366920938463463374607431768211456L
1852 Out[1]: 340282366920938463463374607431768211456L
1831
1853
1832 In [2]: n = 1000000
1854 In [2]: n = 1000000
1833
1855
1834 In [3]: time sum(range(n))
1856 In [3]: time sum(range(n))
1835 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1857 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1836 Wall time: 1.37
1858 Wall time: 1.37
1837 Out[3]: 499999500000L
1859 Out[3]: 499999500000L
1838
1860
1839 In [4]: time print 'hello world'
1861 In [4]: time print 'hello world'
1840 hello world
1862 hello world
1841 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1863 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1842 Wall time: 0.00
1864 Wall time: 0.00
1843
1865
1844 Note that the time needed by Python to compile the given expression
1866 Note that the time needed by Python to compile the given expression
1845 will be reported if it is more than 0.1s. In this example, the
1867 will be reported if it is more than 0.1s. In this example, the
1846 actual exponentiation is done by Python at compilation time, so while
1868 actual exponentiation is done by Python at compilation time, so while
1847 the expression can take a noticeable amount of time to compute, that
1869 the expression can take a noticeable amount of time to compute, that
1848 time is purely due to the compilation:
1870 time is purely due to the compilation:
1849
1871
1850 In [5]: time 3**9999;
1872 In [5]: time 3**9999;
1851 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1873 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1852 Wall time: 0.00 s
1874 Wall time: 0.00 s
1853
1875
1854 In [6]: time 3**999999;
1876 In [6]: time 3**999999;
1855 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1877 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1856 Wall time: 0.00 s
1878 Wall time: 0.00 s
1857 Compiler : 0.78 s
1879 Compiler : 0.78 s
1858 """
1880 """
1859
1881
1860 # fail immediately if the given expression can't be compiled
1882 # fail immediately if the given expression can't be compiled
1861
1883
1862 expr = self.shell.prefilter(parameter_s,False)
1884 expr = self.shell.prefilter(parameter_s,False)
1863
1885
1864 # Minimum time above which compilation time will be reported
1886 # Minimum time above which compilation time will be reported
1865 tc_min = 0.1
1887 tc_min = 0.1
1866
1888
1867 try:
1889 try:
1868 mode = 'eval'
1890 mode = 'eval'
1869 t0 = clock()
1891 t0 = clock()
1870 code = compile(expr,'<timed eval>',mode)
1892 code = compile(expr,'<timed eval>',mode)
1871 tc = clock()-t0
1893 tc = clock()-t0
1872 except SyntaxError:
1894 except SyntaxError:
1873 mode = 'exec'
1895 mode = 'exec'
1874 t0 = clock()
1896 t0 = clock()
1875 code = compile(expr,'<timed exec>',mode)
1897 code = compile(expr,'<timed exec>',mode)
1876 tc = clock()-t0
1898 tc = clock()-t0
1877 # skew measurement as little as possible
1899 # skew measurement as little as possible
1878 glob = self.shell.user_ns
1900 glob = self.shell.user_ns
1879 clk = clock2
1901 clk = clock2
1880 wtime = time.time
1902 wtime = time.time
1881 # time execution
1903 # time execution
1882 wall_st = wtime()
1904 wall_st = wtime()
1883 if mode=='eval':
1905 if mode=='eval':
1884 st = clk()
1906 st = clk()
1885 out = eval(code,glob)
1907 out = eval(code,glob)
1886 end = clk()
1908 end = clk()
1887 else:
1909 else:
1888 st = clk()
1910 st = clk()
1889 exec code in glob
1911 exec code in glob
1890 end = clk()
1912 end = clk()
1891 out = None
1913 out = None
1892 wall_end = wtime()
1914 wall_end = wtime()
1893 # Compute actual times and report
1915 # Compute actual times and report
1894 wall_time = wall_end-wall_st
1916 wall_time = wall_end-wall_st
1895 cpu_user = end[0]-st[0]
1917 cpu_user = end[0]-st[0]
1896 cpu_sys = end[1]-st[1]
1918 cpu_sys = end[1]-st[1]
1897 cpu_tot = cpu_user+cpu_sys
1919 cpu_tot = cpu_user+cpu_sys
1898 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
1920 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
1899 (cpu_user,cpu_sys,cpu_tot)
1921 (cpu_user,cpu_sys,cpu_tot)
1900 print "Wall time: %.2f s" % wall_time
1922 print "Wall time: %.2f s" % wall_time
1901 if tc > tc_min:
1923 if tc > tc_min:
1902 print "Compiler : %.2f s" % tc
1924 print "Compiler : %.2f s" % tc
1903 return out
1925 return out
1904
1926
1927 @testdec.skip_doctest
1905 def magic_macro(self,parameter_s = ''):
1928 def magic_macro(self,parameter_s = ''):
1906 """Define a set of input lines as a macro for future re-execution.
1929 """Define a set of input lines as a macro for future re-execution.
1907
1930
1908 Usage:\\
1931 Usage:\\
1909 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1932 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1910
1933
1911 Options:
1934 Options:
1912
1935
1913 -r: use 'raw' input. By default, the 'processed' history is used,
1936 -r: use 'raw' input. By default, the 'processed' history is used,
1914 so that magics are loaded in their transformed version to valid
1937 so that magics are loaded in their transformed version to valid
1915 Python. If this option is given, the raw input as typed as the
1938 Python. If this option is given, the raw input as typed as the
1916 command line is used instead.
1939 command line is used instead.
1917
1940
1918 This will define a global variable called `name` which is a string
1941 This will define a global variable called `name` which is a string
1919 made of joining the slices and lines you specify (n1,n2,... numbers
1942 made of joining the slices and lines you specify (n1,n2,... numbers
1920 above) from your input history into a single string. This variable
1943 above) from your input history into a single string. This variable
1921 acts like an automatic function which re-executes those lines as if
1944 acts like an automatic function which re-executes those lines as if
1922 you had typed them. You just type 'name' at the prompt and the code
1945 you had typed them. You just type 'name' at the prompt and the code
1923 executes.
1946 executes.
1924
1947
1925 The notation for indicating number ranges is: n1-n2 means 'use line
1948 The notation for indicating number ranges is: n1-n2 means 'use line
1926 numbers n1,...n2' (the endpoint is included). That is, '5-7' means
1949 numbers n1,...n2' (the endpoint is included). That is, '5-7' means
1927 using the lines numbered 5,6 and 7.
1950 using the lines numbered 5,6 and 7.
1928
1951
1929 Note: as a 'hidden' feature, you can also use traditional python slice
1952 Note: as a 'hidden' feature, you can also use traditional python slice
1930 notation, where N:M means numbers N through M-1.
1953 notation, where N:M means numbers N through M-1.
1931
1954
1932 For example, if your history contains (%hist prints it):
1955 For example, if your history contains (%hist prints it):
1933
1956
1934 44: x=1\\
1957 44: x=1
1935 45: y=3\\
1958 45: y=3
1936 46: z=x+y\\
1959 46: z=x+y
1937 47: print x\\
1960 47: print x
1938 48: a=5\\
1961 48: a=5
1939 49: print 'x',x,'y',y\\
1962 49: print 'x',x,'y',y
1940
1963
1941 you can create a macro with lines 44 through 47 (included) and line 49
1964 you can create a macro with lines 44 through 47 (included) and line 49
1942 called my_macro with:
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 Now, typing `my_macro` (without quotes) will re-execute all this code
1969 Now, typing `my_macro` (without quotes) will re-execute all this code
1947 in one pass.
1970 in one pass.
1948
1971
1949 You don't need to give the line-numbers in order, and any given line
1972 You don't need to give the line-numbers in order, and any given line
1950 number can appear multiple times. You can assemble macros with any
1973 number can appear multiple times. You can assemble macros with any
1951 lines from your input history in any order.
1974 lines from your input history in any order.
1952
1975
1953 The macro is a simple object which holds its value in an attribute,
1976 The macro is a simple object which holds its value in an attribute,
1954 but IPython's display system checks for macros and executes them as
1977 but IPython's display system checks for macros and executes them as
1955 code instead of printing them when you type their name.
1978 code instead of printing them when you type their name.
1956
1979
1957 You can view a macro's contents by explicitly printing it with:
1980 You can view a macro's contents by explicitly printing it with:
1958
1981
1959 'print macro_name'.
1982 'print macro_name'.
1960
1983
1961 For one-off cases which DON'T contain magic function calls in them you
1984 For one-off cases which DON'T contain magic function calls in them you
1962 can obtain similar results by explicitly executing slices from your
1985 can obtain similar results by explicitly executing slices from your
1963 input history with:
1986 input history with:
1964
1987
1965 In [60]: exec In[44:48]+In[49]"""
1988 In [60]: exec In[44:48]+In[49]"""
1966
1989
1967 opts,args = self.parse_options(parameter_s,'r',mode='list')
1990 opts,args = self.parse_options(parameter_s,'r',mode='list')
1968 if not args:
1991 if not args:
1969 macs = [k for k,v in self.shell.user_ns.items() if isinstance(v, Macro)]
1992 macs = [k for k,v in self.shell.user_ns.items() if isinstance(v, Macro)]
1970 macs.sort()
1993 macs.sort()
1971 return macs
1994 return macs
1972 if len(args) == 1:
1995 if len(args) == 1:
1973 raise UsageError(
1996 raise UsageError(
1974 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1997 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1975 name,ranges = args[0], args[1:]
1998 name,ranges = args[0], args[1:]
1976
1999
1977 #print 'rng',ranges # dbg
2000 #print 'rng',ranges # dbg
1978 lines = self.extract_input_slices(ranges,opts.has_key('r'))
2001 lines = self.extract_input_slices(ranges,opts.has_key('r'))
1979 macro = Macro(lines)
2002 macro = Macro(lines)
1980 self.shell.user_ns.update({name:macro})
2003 self.shell.user_ns.update({name:macro})
1981 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
2004 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
1982 print 'Macro contents:'
2005 print 'Macro contents:'
1983 print macro,
2006 print macro,
1984
2007
1985 def magic_save(self,parameter_s = ''):
2008 def magic_save(self,parameter_s = ''):
1986 """Save a set of lines to a given filename.
2009 """Save a set of lines to a given filename.
1987
2010
1988 Usage:\\
2011 Usage:\\
1989 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
2012 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
1990
2013
1991 Options:
2014 Options:
1992
2015
1993 -r: use 'raw' input. By default, the 'processed' history is used,
2016 -r: use 'raw' input. By default, the 'processed' history is used,
1994 so that magics are loaded in their transformed version to valid
2017 so that magics are loaded in their transformed version to valid
1995 Python. If this option is given, the raw input as typed as the
2018 Python. If this option is given, the raw input as typed as the
1996 command line is used instead.
2019 command line is used instead.
1997
2020
1998 This function uses the same syntax as %macro for line extraction, but
2021 This function uses the same syntax as %macro for line extraction, but
1999 instead of creating a macro it saves the resulting string to the
2022 instead of creating a macro it saves the resulting string to the
2000 filename you specify.
2023 filename you specify.
2001
2024
2002 It adds a '.py' extension to the file if you don't do so yourself, and
2025 It adds a '.py' extension to the file if you don't do so yourself, and
2003 it asks for confirmation before overwriting existing files."""
2026 it asks for confirmation before overwriting existing files."""
2004
2027
2005 opts,args = self.parse_options(parameter_s,'r',mode='list')
2028 opts,args = self.parse_options(parameter_s,'r',mode='list')
2006 fname,ranges = args[0], args[1:]
2029 fname,ranges = args[0], args[1:]
2007 if not fname.endswith('.py'):
2030 if not fname.endswith('.py'):
2008 fname += '.py'
2031 fname += '.py'
2009 if os.path.isfile(fname):
2032 if os.path.isfile(fname):
2010 ans = raw_input('File `%s` exists. Overwrite (y/[N])? ' % fname)
2033 ans = raw_input('File `%s` exists. Overwrite (y/[N])? ' % fname)
2011 if ans.lower() not in ['y','yes']:
2034 if ans.lower() not in ['y','yes']:
2012 print 'Operation cancelled.'
2035 print 'Operation cancelled.'
2013 return
2036 return
2014 cmds = ''.join(self.extract_input_slices(ranges,opts.has_key('r')))
2037 cmds = ''.join(self.extract_input_slices(ranges,opts.has_key('r')))
2015 f = file(fname,'w')
2038 f = file(fname,'w')
2016 f.write(cmds)
2039 f.write(cmds)
2017 f.close()
2040 f.close()
2018 print 'The following commands were written to file `%s`:' % fname
2041 print 'The following commands were written to file `%s`:' % fname
2019 print cmds
2042 print cmds
2020
2043
2021 def _edit_macro(self,mname,macro):
2044 def _edit_macro(self,mname,macro):
2022 """open an editor with the macro data in a file"""
2045 """open an editor with the macro data in a file"""
2023 filename = self.shell.mktempfile(macro.value)
2046 filename = self.shell.mktempfile(macro.value)
2024 self.shell.hooks.editor(filename)
2047 self.shell.hooks.editor(filename)
2025
2048
2026 # and make a new macro object, to replace the old one
2049 # and make a new macro object, to replace the old one
2027 mfile = open(filename)
2050 mfile = open(filename)
2028 mvalue = mfile.read()
2051 mvalue = mfile.read()
2029 mfile.close()
2052 mfile.close()
2030 self.shell.user_ns[mname] = Macro(mvalue)
2053 self.shell.user_ns[mname] = Macro(mvalue)
2031
2054
2032 def magic_ed(self,parameter_s=''):
2055 def magic_ed(self,parameter_s=''):
2033 """Alias to %edit."""
2056 """Alias to %edit."""
2034 return self.magic_edit(parameter_s)
2057 return self.magic_edit(parameter_s)
2035
2058
2059 @testdec.skip_doctest
2036 def magic_edit(self,parameter_s='',last_call=['','']):
2060 def magic_edit(self,parameter_s='',last_call=['','']):
2037 """Bring up an editor and execute the resulting code.
2061 """Bring up an editor and execute the resulting code.
2038
2062
2039 Usage:
2063 Usage:
2040 %edit [options] [args]
2064 %edit [options] [args]
2041
2065
2042 %edit runs IPython's editor hook. The default version of this hook is
2066 %edit runs IPython's editor hook. The default version of this hook is
2043 set to call the __IPYTHON__.rc.editor command. This is read from your
2067 set to call the __IPYTHON__.rc.editor command. This is read from your
2044 environment variable $EDITOR. If this isn't found, it will default to
2068 environment variable $EDITOR. If this isn't found, it will default to
2045 vi under Linux/Unix and to notepad under Windows. See the end of this
2069 vi under Linux/Unix and to notepad under Windows. See the end of this
2046 docstring for how to change the editor hook.
2070 docstring for how to change the editor hook.
2047
2071
2048 You can also set the value of this editor via the command line option
2072 You can also set the value of this editor via the command line option
2049 '-editor' or in your ipythonrc file. This is useful if you wish to use
2073 '-editor' or in your ipythonrc file. This is useful if you wish to use
2050 specifically for IPython an editor different from your typical default
2074 specifically for IPython an editor different from your typical default
2051 (and for Windows users who typically don't set environment variables).
2075 (and for Windows users who typically don't set environment variables).
2052
2076
2053 This command allows you to conveniently edit multi-line code right in
2077 This command allows you to conveniently edit multi-line code right in
2054 your IPython session.
2078 your IPython session.
2055
2079
2056 If called without arguments, %edit opens up an empty editor with a
2080 If called without arguments, %edit opens up an empty editor with a
2057 temporary file and will execute the contents of this file when you
2081 temporary file and will execute the contents of this file when you
2058 close it (don't forget to save it!).
2082 close it (don't forget to save it!).
2059
2083
2060
2084
2061 Options:
2085 Options:
2062
2086
2063 -n <number>: open the editor at a specified line number. By default,
2087 -n <number>: open the editor at a specified line number. By default,
2064 the IPython editor hook uses the unix syntax 'editor +N filename', but
2088 the IPython editor hook uses the unix syntax 'editor +N filename', but
2065 you can configure this by providing your own modified hook if your
2089 you can configure this by providing your own modified hook if your
2066 favorite editor supports line-number specifications with a different
2090 favorite editor supports line-number specifications with a different
2067 syntax.
2091 syntax.
2068
2092
2069 -p: this will call the editor with the same data as the previous time
2093 -p: this will call the editor with the same data as the previous time
2070 it was used, regardless of how long ago (in your current session) it
2094 it was used, regardless of how long ago (in your current session) it
2071 was.
2095 was.
2072
2096
2073 -r: use 'raw' input. This option only applies to input taken from the
2097 -r: use 'raw' input. This option only applies to input taken from the
2074 user's history. By default, the 'processed' history is used, so that
2098 user's history. By default, the 'processed' history is used, so that
2075 magics are loaded in their transformed version to valid Python. If
2099 magics are loaded in their transformed version to valid Python. If
2076 this option is given, the raw input as typed as the command line is
2100 this option is given, the raw input as typed as the command line is
2077 used instead. When you exit the editor, it will be executed by
2101 used instead. When you exit the editor, it will be executed by
2078 IPython's own processor.
2102 IPython's own processor.
2079
2103
2080 -x: do not execute the edited code immediately upon exit. This is
2104 -x: do not execute the edited code immediately upon exit. This is
2081 mainly useful if you are editing programs which need to be called with
2105 mainly useful if you are editing programs which need to be called with
2082 command line arguments, which you can then do using %run.
2106 command line arguments, which you can then do using %run.
2083
2107
2084
2108
2085 Arguments:
2109 Arguments:
2086
2110
2087 If arguments are given, the following possibilites exist:
2111 If arguments are given, the following possibilites exist:
2088
2112
2089 - The arguments are numbers or pairs of colon-separated numbers (like
2113 - The arguments are numbers or pairs of colon-separated numbers (like
2090 1 4:8 9). These are interpreted as lines of previous input to be
2114 1 4:8 9). These are interpreted as lines of previous input to be
2091 loaded into the editor. The syntax is the same of the %macro command.
2115 loaded into the editor. The syntax is the same of the %macro command.
2092
2116
2093 - If the argument doesn't start with a number, it is evaluated as a
2117 - If the argument doesn't start with a number, it is evaluated as a
2094 variable and its contents loaded into the editor. You can thus edit
2118 variable and its contents loaded into the editor. You can thus edit
2095 any string which contains python code (including the result of
2119 any string which contains python code (including the result of
2096 previous edits).
2120 previous edits).
2097
2121
2098 - If the argument is the name of an object (other than a string),
2122 - If the argument is the name of an object (other than a string),
2099 IPython will try to locate the file where it was defined and open the
2123 IPython will try to locate the file where it was defined and open the
2100 editor at the point where it is defined. You can use `%edit function`
2124 editor at the point where it is defined. You can use `%edit function`
2101 to load an editor exactly at the point where 'function' is defined,
2125 to load an editor exactly at the point where 'function' is defined,
2102 edit it and have the file be executed automatically.
2126 edit it and have the file be executed automatically.
2103
2127
2104 If the object is a macro (see %macro for details), this opens up your
2128 If the object is a macro (see %macro for details), this opens up your
2105 specified editor with a temporary file containing the macro's data.
2129 specified editor with a temporary file containing the macro's data.
2106 Upon exit, the macro is reloaded with the contents of the file.
2130 Upon exit, the macro is reloaded with the contents of the file.
2107
2131
2108 Note: opening at an exact line is only supported under Unix, and some
2132 Note: opening at an exact line is only supported under Unix, and some
2109 editors (like kedit and gedit up to Gnome 2.8) do not understand the
2133 editors (like kedit and gedit up to Gnome 2.8) do not understand the
2110 '+NUMBER' parameter necessary for this feature. Good editors like
2134 '+NUMBER' parameter necessary for this feature. Good editors like
2111 (X)Emacs, vi, jed, pico and joe all do.
2135 (X)Emacs, vi, jed, pico and joe all do.
2112
2136
2113 - If the argument is not found as a variable, IPython will look for a
2137 - If the argument is not found as a variable, IPython will look for a
2114 file with that name (adding .py if necessary) and load it into the
2138 file with that name (adding .py if necessary) and load it into the
2115 editor. It will execute its contents with execfile() when you exit,
2139 editor. It will execute its contents with execfile() when you exit,
2116 loading any code in the file into your interactive namespace.
2140 loading any code in the file into your interactive namespace.
2117
2141
2118 After executing your code, %edit will return as output the code you
2142 After executing your code, %edit will return as output the code you
2119 typed in the editor (except when it was an existing file). This way
2143 typed in the editor (except when it was an existing file). This way
2120 you can reload the code in further invocations of %edit as a variable,
2144 you can reload the code in further invocations of %edit as a variable,
2121 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
2145 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
2122 the output.
2146 the output.
2123
2147
2124 Note that %edit is also available through the alias %ed.
2148 Note that %edit is also available through the alias %ed.
2125
2149
2126 This is an example of creating a simple function inside the editor and
2150 This is an example of creating a simple function inside the editor and
2127 then modifying it. First, start up the editor:
2151 then modifying it. First, start up the editor:
2128
2152
2129 In [1]: ed\\
2153 In [1]: ed
2130 Editing... done. Executing edited code...\\
2154 Editing... done. Executing edited code...
2131 Out[1]: 'def foo():\\n print "foo() was defined in an editing session"\\n'
2155 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
2132
2156
2133 We can then call the function foo():
2157 We can then call the function foo():
2134
2158
2135 In [2]: foo()\\
2159 In [2]: foo()
2136 foo() was defined in an editing session
2160 foo() was defined in an editing session
2137
2161
2138 Now we edit foo. IPython automatically loads the editor with the
2162 Now we edit foo. IPython automatically loads the editor with the
2139 (temporary) file where foo() was previously defined:
2163 (temporary) file where foo() was previously defined:
2140
2164
2141 In [3]: ed foo\\
2165 In [3]: ed foo
2142 Editing... done. Executing edited code...
2166 Editing... done. Executing edited code...
2143
2167
2144 And if we call foo() again we get the modified version:
2168 And if we call foo() again we get the modified version:
2145
2169
2146 In [4]: foo()\\
2170 In [4]: foo()
2147 foo() has now been changed!
2171 foo() has now been changed!
2148
2172
2149 Here is an example of how to edit a code snippet successive
2173 Here is an example of how to edit a code snippet successive
2150 times. First we call the editor:
2174 times. First we call the editor:
2151
2175
2152 In [8]: ed\\
2176 In [5]: ed
2153 Editing... done. Executing edited code...\\
2177 Editing... done. Executing edited code...
2154 hello\\
2178 hello
2155 Out[8]: "print 'hello'\\n"
2179 Out[5]: "print 'hello'n"
2156
2180
2157 Now we call it again with the previous output (stored in _):
2181 Now we call it again with the previous output (stored in _):
2158
2182
2159 In [9]: ed _\\
2183 In [6]: ed _
2160 Editing... done. Executing edited code...\\
2184 Editing... done. Executing edited code...
2161 hello world\\
2185 hello world
2162 Out[9]: "print 'hello world'\\n"
2186 Out[6]: "print 'hello world'n"
2163
2187
2164 Now we call it with the output #8 (stored in _8, also as Out[8]):
2188 Now we call it with the output #8 (stored in _8, also as Out[8]):
2165
2189
2166 In [10]: ed _8\\
2190 In [7]: ed _8
2167 Editing... done. Executing edited code...\\
2191 Editing... done. Executing edited code...
2168 hello again\\
2192 hello again
2169 Out[10]: "print 'hello again'\\n"
2193 Out[7]: "print 'hello again'n"
2170
2194
2171
2195
2172 Changing the default editor hook:
2196 Changing the default editor hook:
2173
2197
2174 If you wish to write your own editor hook, you can put it in a
2198 If you wish to write your own editor hook, you can put it in a
2175 configuration file which you load at startup time. The default hook
2199 configuration file which you load at startup time. The default hook
2176 is defined in the IPython.hooks module, and you can use that as a
2200 is defined in the IPython.hooks module, and you can use that as a
2177 starting example for further modifications. That file also has
2201 starting example for further modifications. That file also has
2178 general instructions on how to set a new hook for use once you've
2202 general instructions on how to set a new hook for use once you've
2179 defined it."""
2203 defined it."""
2180
2204
2181 # FIXME: This function has become a convoluted mess. It needs a
2205 # FIXME: This function has become a convoluted mess. It needs a
2182 # ground-up rewrite with clean, simple logic.
2206 # ground-up rewrite with clean, simple logic.
2183
2207
2184 def make_filename(arg):
2208 def make_filename(arg):
2185 "Make a filename from the given args"
2209 "Make a filename from the given args"
2186 try:
2210 try:
2187 filename = get_py_filename(arg)
2211 filename = get_py_filename(arg)
2188 except IOError:
2212 except IOError:
2189 if args.endswith('.py'):
2213 if args.endswith('.py'):
2190 filename = arg
2214 filename = arg
2191 else:
2215 else:
2192 filename = None
2216 filename = None
2193 return filename
2217 return filename
2194
2218
2195 # custom exceptions
2219 # custom exceptions
2196 class DataIsObject(Exception): pass
2220 class DataIsObject(Exception): pass
2197
2221
2198 opts,args = self.parse_options(parameter_s,'prxn:')
2222 opts,args = self.parse_options(parameter_s,'prxn:')
2199 # Set a few locals from the options for convenience:
2223 # Set a few locals from the options for convenience:
2200 opts_p = opts.has_key('p')
2224 opts_p = opts.has_key('p')
2201 opts_r = opts.has_key('r')
2225 opts_r = opts.has_key('r')
2202
2226
2203 # Default line number value
2227 # Default line number value
2204 lineno = opts.get('n',None)
2228 lineno = opts.get('n',None)
2205
2229
2206 if opts_p:
2230 if opts_p:
2207 args = '_%s' % last_call[0]
2231 args = '_%s' % last_call[0]
2208 if not self.shell.user_ns.has_key(args):
2232 if not self.shell.user_ns.has_key(args):
2209 args = last_call[1]
2233 args = last_call[1]
2210
2234
2211 # use last_call to remember the state of the previous call, but don't
2235 # use last_call to remember the state of the previous call, but don't
2212 # let it be clobbered by successive '-p' calls.
2236 # let it be clobbered by successive '-p' calls.
2213 try:
2237 try:
2214 last_call[0] = self.shell.outputcache.prompt_count
2238 last_call[0] = self.shell.outputcache.prompt_count
2215 if not opts_p:
2239 if not opts_p:
2216 last_call[1] = parameter_s
2240 last_call[1] = parameter_s
2217 except:
2241 except:
2218 pass
2242 pass
2219
2243
2220 # by default this is done with temp files, except when the given
2244 # by default this is done with temp files, except when the given
2221 # arg is a filename
2245 # arg is a filename
2222 use_temp = 1
2246 use_temp = 1
2223
2247
2224 if re.match(r'\d',args):
2248 if re.match(r'\d',args):
2225 # Mode where user specifies ranges of lines, like in %macro.
2249 # Mode where user specifies ranges of lines, like in %macro.
2226 # This means that you can't edit files whose names begin with
2250 # This means that you can't edit files whose names begin with
2227 # numbers this way. Tough.
2251 # numbers this way. Tough.
2228 ranges = args.split()
2252 ranges = args.split()
2229 data = ''.join(self.extract_input_slices(ranges,opts_r))
2253 data = ''.join(self.extract_input_slices(ranges,opts_r))
2230 elif args.endswith('.py'):
2254 elif args.endswith('.py'):
2231 filename = make_filename(args)
2255 filename = make_filename(args)
2232 data = ''
2256 data = ''
2233 use_temp = 0
2257 use_temp = 0
2234 elif args:
2258 elif args:
2235 try:
2259 try:
2236 # Load the parameter given as a variable. If not a string,
2260 # Load the parameter given as a variable. If not a string,
2237 # process it as an object instead (below)
2261 # process it as an object instead (below)
2238
2262
2239 #print '*** args',args,'type',type(args) # dbg
2263 #print '*** args',args,'type',type(args) # dbg
2240 data = eval(args,self.shell.user_ns)
2264 data = eval(args,self.shell.user_ns)
2241 if not type(data) in StringTypes:
2265 if not type(data) in StringTypes:
2242 raise DataIsObject
2266 raise DataIsObject
2243
2267
2244 except (NameError,SyntaxError):
2268 except (NameError,SyntaxError):
2245 # given argument is not a variable, try as a filename
2269 # given argument is not a variable, try as a filename
2246 filename = make_filename(args)
2270 filename = make_filename(args)
2247 if filename is None:
2271 if filename is None:
2248 warn("Argument given (%s) can't be found as a variable "
2272 warn("Argument given (%s) can't be found as a variable "
2249 "or as a filename." % args)
2273 "or as a filename." % args)
2250 return
2274 return
2251
2275
2252 data = ''
2276 data = ''
2253 use_temp = 0
2277 use_temp = 0
2254 except DataIsObject:
2278 except DataIsObject:
2255
2279
2256 # macros have a special edit function
2280 # macros have a special edit function
2257 if isinstance(data,Macro):
2281 if isinstance(data,Macro):
2258 self._edit_macro(args,data)
2282 self._edit_macro(args,data)
2259 return
2283 return
2260
2284
2261 # For objects, try to edit the file where they are defined
2285 # For objects, try to edit the file where they are defined
2262 try:
2286 try:
2263 filename = inspect.getabsfile(data)
2287 filename = inspect.getabsfile(data)
2264 if 'fakemodule' in filename.lower() and inspect.isclass(data):
2288 if 'fakemodule' in filename.lower() and inspect.isclass(data):
2265 # class created by %edit? Try to find source
2289 # class created by %edit? Try to find source
2266 # by looking for method definitions instead, the
2290 # by looking for method definitions instead, the
2267 # __module__ in those classes is FakeModule.
2291 # __module__ in those classes is FakeModule.
2268 attrs = [getattr(data, aname) for aname in dir(data)]
2292 attrs = [getattr(data, aname) for aname in dir(data)]
2269 for attr in attrs:
2293 for attr in attrs:
2270 if not inspect.ismethod(attr):
2294 if not inspect.ismethod(attr):
2271 continue
2295 continue
2272 filename = inspect.getabsfile(attr)
2296 filename = inspect.getabsfile(attr)
2273 if filename and 'fakemodule' not in filename.lower():
2297 if filename and 'fakemodule' not in filename.lower():
2274 # change the attribute to be the edit target instead
2298 # change the attribute to be the edit target instead
2275 data = attr
2299 data = attr
2276 break
2300 break
2277
2301
2278 datafile = 1
2302 datafile = 1
2279 except TypeError:
2303 except TypeError:
2280 filename = make_filename(args)
2304 filename = make_filename(args)
2281 datafile = 1
2305 datafile = 1
2282 warn('Could not find file where `%s` is defined.\n'
2306 warn('Could not find file where `%s` is defined.\n'
2283 'Opening a file named `%s`' % (args,filename))
2307 'Opening a file named `%s`' % (args,filename))
2284 # Now, make sure we can actually read the source (if it was in
2308 # Now, make sure we can actually read the source (if it was in
2285 # a temp file it's gone by now).
2309 # a temp file it's gone by now).
2286 if datafile:
2310 if datafile:
2287 try:
2311 try:
2288 if lineno is None:
2312 if lineno is None:
2289 lineno = inspect.getsourcelines(data)[1]
2313 lineno = inspect.getsourcelines(data)[1]
2290 except IOError:
2314 except IOError:
2291 filename = make_filename(args)
2315 filename = make_filename(args)
2292 if filename is None:
2316 if filename is None:
2293 warn('The file `%s` where `%s` was defined cannot '
2317 warn('The file `%s` where `%s` was defined cannot '
2294 'be read.' % (filename,data))
2318 'be read.' % (filename,data))
2295 return
2319 return
2296 use_temp = 0
2320 use_temp = 0
2297 else:
2321 else:
2298 data = ''
2322 data = ''
2299
2323
2300 if use_temp:
2324 if use_temp:
2301 filename = self.shell.mktempfile(data)
2325 filename = self.shell.mktempfile(data)
2302 print 'IPython will make a temporary file named:',filename
2326 print 'IPython will make a temporary file named:',filename
2303
2327
2304 # do actual editing here
2328 # do actual editing here
2305 print 'Editing...',
2329 print 'Editing...',
2306 sys.stdout.flush()
2330 sys.stdout.flush()
2307 self.shell.hooks.editor(filename,lineno)
2331 self.shell.hooks.editor(filename,lineno)
2308 if opts.has_key('x'): # -x prevents actual execution
2332 if opts.has_key('x'): # -x prevents actual execution
2309 print
2333 print
2310 else:
2334 else:
2311 print 'done. Executing edited code...'
2335 print 'done. Executing edited code...'
2312 if opts_r:
2336 if opts_r:
2313 self.shell.runlines(file_read(filename))
2337 self.shell.runlines(file_read(filename))
2314 else:
2338 else:
2315 self.shell.safe_execfile(filename,self.shell.user_ns,
2339 self.shell.safe_execfile(filename,self.shell.user_ns,
2316 self.shell.user_ns)
2340 self.shell.user_ns)
2317 if use_temp:
2341 if use_temp:
2318 try:
2342 try:
2319 return open(filename).read()
2343 return open(filename).read()
2320 except IOError,msg:
2344 except IOError,msg:
2321 if msg.filename == filename:
2345 if msg.filename == filename:
2322 warn('File not found. Did you forget to save?')
2346 warn('File not found. Did you forget to save?')
2323 return
2347 return
2324 else:
2348 else:
2325 self.shell.showtraceback()
2349 self.shell.showtraceback()
2326
2350
2327 def magic_xmode(self,parameter_s = ''):
2351 def magic_xmode(self,parameter_s = ''):
2328 """Switch modes for the exception handlers.
2352 """Switch modes for the exception handlers.
2329
2353
2330 Valid modes: Plain, Context and Verbose.
2354 Valid modes: Plain, Context and Verbose.
2331
2355
2332 If called without arguments, acts as a toggle."""
2356 If called without arguments, acts as a toggle."""
2333
2357
2334 def xmode_switch_err(name):
2358 def xmode_switch_err(name):
2335 warn('Error changing %s exception modes.\n%s' %
2359 warn('Error changing %s exception modes.\n%s' %
2336 (name,sys.exc_info()[1]))
2360 (name,sys.exc_info()[1]))
2337
2361
2338 shell = self.shell
2362 shell = self.shell
2339 new_mode = parameter_s.strip().capitalize()
2363 new_mode = parameter_s.strip().capitalize()
2340 try:
2364 try:
2341 shell.InteractiveTB.set_mode(mode=new_mode)
2365 shell.InteractiveTB.set_mode(mode=new_mode)
2342 print 'Exception reporting mode:',shell.InteractiveTB.mode
2366 print 'Exception reporting mode:',shell.InteractiveTB.mode
2343 except:
2367 except:
2344 xmode_switch_err('user')
2368 xmode_switch_err('user')
2345
2369
2346 # threaded shells use a special handler in sys.excepthook
2370 # threaded shells use a special handler in sys.excepthook
2347 if shell.isthreaded:
2371 if shell.isthreaded:
2348 try:
2372 try:
2349 shell.sys_excepthook.set_mode(mode=new_mode)
2373 shell.sys_excepthook.set_mode(mode=new_mode)
2350 except:
2374 except:
2351 xmode_switch_err('threaded')
2375 xmode_switch_err('threaded')
2352
2376
2353 def magic_colors(self,parameter_s = ''):
2377 def magic_colors(self,parameter_s = ''):
2354 """Switch color scheme for prompts, info system and exception handlers.
2378 """Switch color scheme for prompts, info system and exception handlers.
2355
2379
2356 Currently implemented schemes: NoColor, Linux, LightBG.
2380 Currently implemented schemes: NoColor, Linux, LightBG.
2357
2381
2358 Color scheme names are not case-sensitive."""
2382 Color scheme names are not case-sensitive."""
2359
2383
2360 def color_switch_err(name):
2384 def color_switch_err(name):
2361 warn('Error changing %s color schemes.\n%s' %
2385 warn('Error changing %s color schemes.\n%s' %
2362 (name,sys.exc_info()[1]))
2386 (name,sys.exc_info()[1]))
2363
2387
2364
2388
2365 new_scheme = parameter_s.strip()
2389 new_scheme = parameter_s.strip()
2366 if not new_scheme:
2390 if not new_scheme:
2367 raise UsageError(
2391 raise UsageError(
2368 "%colors: you must specify a color scheme. See '%colors?'")
2392 "%colors: you must specify a color scheme. See '%colors?'")
2369 return
2393 return
2370 # local shortcut
2394 # local shortcut
2371 shell = self.shell
2395 shell = self.shell
2372
2396
2373 import IPython.rlineimpl as readline
2397 import IPython.rlineimpl as readline
2374
2398
2375 if not readline.have_readline and sys.platform == "win32":
2399 if not readline.have_readline and sys.platform == "win32":
2376 msg = """\
2400 msg = """\
2377 Proper color support under MS Windows requires the pyreadline library.
2401 Proper color support under MS Windows requires the pyreadline library.
2378 You can find it at:
2402 You can find it at:
2379 http://ipython.scipy.org/moin/PyReadline/Intro
2403 http://ipython.scipy.org/moin/PyReadline/Intro
2380 Gary's readline needs the ctypes module, from:
2404 Gary's readline needs the ctypes module, from:
2381 http://starship.python.net/crew/theller/ctypes
2405 http://starship.python.net/crew/theller/ctypes
2382 (Note that ctypes is already part of Python versions 2.5 and newer).
2406 (Note that ctypes is already part of Python versions 2.5 and newer).
2383
2407
2384 Defaulting color scheme to 'NoColor'"""
2408 Defaulting color scheme to 'NoColor'"""
2385 new_scheme = 'NoColor'
2409 new_scheme = 'NoColor'
2386 warn(msg)
2410 warn(msg)
2387
2411
2388 # readline option is 0
2412 # readline option is 0
2389 if not shell.has_readline:
2413 if not shell.has_readline:
2390 new_scheme = 'NoColor'
2414 new_scheme = 'NoColor'
2391
2415
2392 # Set prompt colors
2416 # Set prompt colors
2393 try:
2417 try:
2394 shell.outputcache.set_colors(new_scheme)
2418 shell.outputcache.set_colors(new_scheme)
2395 except:
2419 except:
2396 color_switch_err('prompt')
2420 color_switch_err('prompt')
2397 else:
2421 else:
2398 shell.rc.colors = \
2422 shell.rc.colors = \
2399 shell.outputcache.color_table.active_scheme_name
2423 shell.outputcache.color_table.active_scheme_name
2400 # Set exception colors
2424 # Set exception colors
2401 try:
2425 try:
2402 shell.InteractiveTB.set_colors(scheme = new_scheme)
2426 shell.InteractiveTB.set_colors(scheme = new_scheme)
2403 shell.SyntaxTB.set_colors(scheme = new_scheme)
2427 shell.SyntaxTB.set_colors(scheme = new_scheme)
2404 except:
2428 except:
2405 color_switch_err('exception')
2429 color_switch_err('exception')
2406
2430
2407 # threaded shells use a verbose traceback in sys.excepthook
2431 # threaded shells use a verbose traceback in sys.excepthook
2408 if shell.isthreaded:
2432 if shell.isthreaded:
2409 try:
2433 try:
2410 shell.sys_excepthook.set_colors(scheme=new_scheme)
2434 shell.sys_excepthook.set_colors(scheme=new_scheme)
2411 except:
2435 except:
2412 color_switch_err('system exception handler')
2436 color_switch_err('system exception handler')
2413
2437
2414 # Set info (for 'object?') colors
2438 # Set info (for 'object?') colors
2415 if shell.rc.color_info:
2439 if shell.rc.color_info:
2416 try:
2440 try:
2417 shell.inspector.set_active_scheme(new_scheme)
2441 shell.inspector.set_active_scheme(new_scheme)
2418 except:
2442 except:
2419 color_switch_err('object inspector')
2443 color_switch_err('object inspector')
2420 else:
2444 else:
2421 shell.inspector.set_active_scheme('NoColor')
2445 shell.inspector.set_active_scheme('NoColor')
2422
2446
2423 def magic_color_info(self,parameter_s = ''):
2447 def magic_color_info(self,parameter_s = ''):
2424 """Toggle color_info.
2448 """Toggle color_info.
2425
2449
2426 The color_info configuration parameter controls whether colors are
2450 The color_info configuration parameter controls whether colors are
2427 used for displaying object details (by things like %psource, %pfile or
2451 used for displaying object details (by things like %psource, %pfile or
2428 the '?' system). This function toggles this value with each call.
2452 the '?' system). This function toggles this value with each call.
2429
2453
2430 Note that unless you have a fairly recent pager (less works better
2454 Note that unless you have a fairly recent pager (less works better
2431 than more) in your system, using colored object information displays
2455 than more) in your system, using colored object information displays
2432 will not work properly. Test it and see."""
2456 will not work properly. Test it and see."""
2433
2457
2434 self.shell.rc.color_info = 1 - self.shell.rc.color_info
2458 self.shell.rc.color_info = 1 - self.shell.rc.color_info
2435 self.magic_colors(self.shell.rc.colors)
2459 self.magic_colors(self.shell.rc.colors)
2436 print 'Object introspection functions have now coloring:',
2460 print 'Object introspection functions have now coloring:',
2437 print ['OFF','ON'][self.shell.rc.color_info]
2461 print ['OFF','ON'][self.shell.rc.color_info]
2438
2462
2439 def magic_Pprint(self, parameter_s=''):
2463 def magic_Pprint(self, parameter_s=''):
2440 """Toggle pretty printing on/off."""
2464 """Toggle pretty printing on/off."""
2441
2465
2442 self.shell.rc.pprint = 1 - self.shell.rc.pprint
2466 self.shell.rc.pprint = 1 - self.shell.rc.pprint
2443 print 'Pretty printing has been turned', \
2467 print 'Pretty printing has been turned', \
2444 ['OFF','ON'][self.shell.rc.pprint]
2468 ['OFF','ON'][self.shell.rc.pprint]
2445
2469
2446 def magic_exit(self, parameter_s=''):
2470 def magic_exit(self, parameter_s=''):
2447 """Exit IPython, confirming if configured to do so.
2471 """Exit IPython, confirming if configured to do so.
2448
2472
2449 You can configure whether IPython asks for confirmation upon exit by
2473 You can configure whether IPython asks for confirmation upon exit by
2450 setting the confirm_exit flag in the ipythonrc file."""
2474 setting the confirm_exit flag in the ipythonrc file."""
2451
2475
2452 self.shell.exit()
2476 self.shell.exit()
2453
2477
2454 def magic_quit(self, parameter_s=''):
2478 def magic_quit(self, parameter_s=''):
2455 """Exit IPython, confirming if configured to do so (like %exit)"""
2479 """Exit IPython, confirming if configured to do so (like %exit)"""
2456
2480
2457 self.shell.exit()
2481 self.shell.exit()
2458
2482
2459 def magic_Exit(self, parameter_s=''):
2483 def magic_Exit(self, parameter_s=''):
2460 """Exit IPython without confirmation."""
2484 """Exit IPython without confirmation."""
2461
2485
2462 self.shell.exit_now = True
2486 self.shell.exit_now = True
2463
2487
2464 #......................................................................
2488 #......................................................................
2465 # Functions to implement unix shell-type things
2489 # Functions to implement unix shell-type things
2466
2490
2491 @testdec.skip_doctest
2467 def magic_alias(self, parameter_s = ''):
2492 def magic_alias(self, parameter_s = ''):
2468 """Define an alias for a system command.
2493 """Define an alias for a system command.
2469
2494
2470 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
2495 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
2471
2496
2472 Then, typing 'alias_name params' will execute the system command 'cmd
2497 Then, typing 'alias_name params' will execute the system command 'cmd
2473 params' (from your underlying operating system).
2498 params' (from your underlying operating system).
2474
2499
2475 Aliases have lower precedence than magic functions and Python normal
2500 Aliases have lower precedence than magic functions and Python normal
2476 variables, so if 'foo' is both a Python variable and an alias, the
2501 variables, so if 'foo' is both a Python variable and an alias, the
2477 alias can not be executed until 'del foo' removes the Python variable.
2502 alias can not be executed until 'del foo' removes the Python variable.
2478
2503
2479 You can use the %l specifier in an alias definition to represent the
2504 You can use the %l specifier in an alias definition to represent the
2480 whole line when the alias is called. For example:
2505 whole line when the alias is called. For example:
2481
2506
2482 In [2]: alias all echo "Input in brackets: <%l>"\\
2507 In [2]: alias all echo "Input in brackets: <%l>"
2483 In [3]: all hello world\\
2508 In [3]: all hello world
2484 Input in brackets: <hello world>
2509 Input in brackets: <hello world>
2485
2510
2486 You can also define aliases with parameters using %s specifiers (one
2511 You can also define aliases with parameters using %s specifiers (one
2487 per parameter):
2512 per parameter):
2488
2513
2489 In [1]: alias parts echo first %s second %s\\
2514 In [1]: alias parts echo first %s second %s
2490 In [2]: %parts A B\\
2515 In [2]: %parts A B
2491 first A second B\\
2516 first A second B
2492 In [3]: %parts A\\
2517 In [3]: %parts A
2493 Incorrect number of arguments: 2 expected.\\
2518 Incorrect number of arguments: 2 expected.
2494 parts is an alias to: 'echo first %s second %s'
2519 parts is an alias to: 'echo first %s second %s'
2495
2520
2496 Note that %l and %s are mutually exclusive. You can only use one or
2521 Note that %l and %s are mutually exclusive. You can only use one or
2497 the other in your aliases.
2522 the other in your aliases.
2498
2523
2499 Aliases expand Python variables just like system calls using ! or !!
2524 Aliases expand Python variables just like system calls using ! or !!
2500 do: all expressions prefixed with '$' get expanded. For details of
2525 do: all expressions prefixed with '$' get expanded. For details of
2501 the semantic rules, see PEP-215:
2526 the semantic rules, see PEP-215:
2502 http://www.python.org/peps/pep-0215.html. This is the library used by
2527 http://www.python.org/peps/pep-0215.html. This is the library used by
2503 IPython for variable expansion. If you want to access a true shell
2528 IPython for variable expansion. If you want to access a true shell
2504 variable, an extra $ is necessary to prevent its expansion by IPython:
2529 variable, an extra $ is necessary to prevent its expansion by IPython:
2505
2530
2506 In [6]: alias show echo\\
2531 In [6]: alias show echo
2507 In [7]: PATH='A Python string'\\
2532 In [7]: PATH='A Python string'
2508 In [8]: show $PATH\\
2533 In [8]: show $PATH
2509 A Python string\\
2534 A Python string
2510 In [9]: show $$PATH\\
2535 In [9]: show $$PATH
2511 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
2536 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
2512
2537
2513 You can use the alias facility to acess all of $PATH. See the %rehash
2538 You can use the alias facility to acess all of $PATH. See the %rehash
2514 and %rehashx functions, which automatically create aliases for the
2539 and %rehashx functions, which automatically create aliases for the
2515 contents of your $PATH.
2540 contents of your $PATH.
2516
2541
2517 If called with no parameters, %alias prints the current alias table."""
2542 If called with no parameters, %alias prints the current alias table."""
2518
2543
2519 par = parameter_s.strip()
2544 par = parameter_s.strip()
2520 if not par:
2545 if not par:
2521 stored = self.db.get('stored_aliases', {} )
2546 stored = self.db.get('stored_aliases', {} )
2522 atab = self.shell.alias_table
2547 atab = self.shell.alias_table
2523 aliases = atab.keys()
2548 aliases = atab.keys()
2524 aliases.sort()
2549 aliases.sort()
2525 res = []
2550 res = []
2526 showlast = []
2551 showlast = []
2527 for alias in aliases:
2552 for alias in aliases:
2528 special = False
2553 special = False
2529 try:
2554 try:
2530 tgt = atab[alias][1]
2555 tgt = atab[alias][1]
2531 except (TypeError, AttributeError):
2556 except (TypeError, AttributeError):
2532 # unsubscriptable? probably a callable
2557 # unsubscriptable? probably a callable
2533 tgt = atab[alias]
2558 tgt = atab[alias]
2534 special = True
2559 special = True
2535 # 'interesting' aliases
2560 # 'interesting' aliases
2536 if (alias in stored or
2561 if (alias in stored or
2537 special or
2562 special or
2538 alias.lower() != os.path.splitext(tgt)[0].lower() or
2563 alias.lower() != os.path.splitext(tgt)[0].lower() or
2539 ' ' in tgt):
2564 ' ' in tgt):
2540 showlast.append((alias, tgt))
2565 showlast.append((alias, tgt))
2541 else:
2566 else:
2542 res.append((alias, tgt ))
2567 res.append((alias, tgt ))
2543
2568
2544 # show most interesting aliases last
2569 # show most interesting aliases last
2545 res.extend(showlast)
2570 res.extend(showlast)
2546 print "Total number of aliases:",len(aliases)
2571 print "Total number of aliases:",len(aliases)
2547 return res
2572 return res
2548 try:
2573 try:
2549 alias,cmd = par.split(None,1)
2574 alias,cmd = par.split(None,1)
2550 except:
2575 except:
2551 print OInspect.getdoc(self.magic_alias)
2576 print OInspect.getdoc(self.magic_alias)
2552 else:
2577 else:
2553 nargs = cmd.count('%s')
2578 nargs = cmd.count('%s')
2554 if nargs>0 and cmd.find('%l')>=0:
2579 if nargs>0 and cmd.find('%l')>=0:
2555 error('The %s and %l specifiers are mutually exclusive '
2580 error('The %s and %l specifiers are mutually exclusive '
2556 'in alias definitions.')
2581 'in alias definitions.')
2557 else: # all looks OK
2582 else: # all looks OK
2558 self.shell.alias_table[alias] = (nargs,cmd)
2583 self.shell.alias_table[alias] = (nargs,cmd)
2559 self.shell.alias_table_validate(verbose=0)
2584 self.shell.alias_table_validate(verbose=0)
2560 # end magic_alias
2585 # end magic_alias
2561
2586
2562 def magic_unalias(self, parameter_s = ''):
2587 def magic_unalias(self, parameter_s = ''):
2563 """Remove an alias"""
2588 """Remove an alias"""
2564
2589
2565 aname = parameter_s.strip()
2590 aname = parameter_s.strip()
2566 if aname in self.shell.alias_table:
2591 if aname in self.shell.alias_table:
2567 del self.shell.alias_table[aname]
2592 del self.shell.alias_table[aname]
2568 stored = self.db.get('stored_aliases', {} )
2593 stored = self.db.get('stored_aliases', {} )
2569 if aname in stored:
2594 if aname in stored:
2570 print "Removing %stored alias",aname
2595 print "Removing %stored alias",aname
2571 del stored[aname]
2596 del stored[aname]
2572 self.db['stored_aliases'] = stored
2597 self.db['stored_aliases'] = stored
2573
2598
2574
2599
2575 def magic_rehashx(self, parameter_s = ''):
2600 def magic_rehashx(self, parameter_s = ''):
2576 """Update the alias table with all executable files in $PATH.
2601 """Update the alias table with all executable files in $PATH.
2577
2602
2578 This version explicitly checks that every entry in $PATH is a file
2603 This version explicitly checks that every entry in $PATH is a file
2579 with execute access (os.X_OK), so it is much slower than %rehash.
2604 with execute access (os.X_OK), so it is much slower than %rehash.
2580
2605
2581 Under Windows, it checks executability as a match agains a
2606 Under Windows, it checks executability as a match agains a
2582 '|'-separated string of extensions, stored in the IPython config
2607 '|'-separated string of extensions, stored in the IPython config
2583 variable win_exec_ext. This defaults to 'exe|com|bat'.
2608 variable win_exec_ext. This defaults to 'exe|com|bat'.
2584
2609
2585 This function also resets the root module cache of module completer,
2610 This function also resets the root module cache of module completer,
2586 used on slow filesystems.
2611 used on slow filesystems.
2587 """
2612 """
2588
2613
2589
2614
2590 ip = self.api
2615 ip = self.api
2591
2616
2592 # for the benefit of module completer in ipy_completers.py
2617 # for the benefit of module completer in ipy_completers.py
2593 del ip.db['rootmodules']
2618 del ip.db['rootmodules']
2594
2619
2595 path = [os.path.abspath(os.path.expanduser(p)) for p in
2620 path = [os.path.abspath(os.path.expanduser(p)) for p in
2596 os.environ.get('PATH','').split(os.pathsep)]
2621 os.environ.get('PATH','').split(os.pathsep)]
2597 path = filter(os.path.isdir,path)
2622 path = filter(os.path.isdir,path)
2598
2623
2599 alias_table = self.shell.alias_table
2624 alias_table = self.shell.alias_table
2600 syscmdlist = []
2625 syscmdlist = []
2601 if os.name == 'posix':
2626 if os.name == 'posix':
2602 isexec = lambda fname:os.path.isfile(fname) and \
2627 isexec = lambda fname:os.path.isfile(fname) and \
2603 os.access(fname,os.X_OK)
2628 os.access(fname,os.X_OK)
2604 else:
2629 else:
2605
2630
2606 try:
2631 try:
2607 winext = os.environ['pathext'].replace(';','|').replace('.','')
2632 winext = os.environ['pathext'].replace(';','|').replace('.','')
2608 except KeyError:
2633 except KeyError:
2609 winext = 'exe|com|bat|py'
2634 winext = 'exe|com|bat|py'
2610 if 'py' not in winext:
2635 if 'py' not in winext:
2611 winext += '|py'
2636 winext += '|py'
2612 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
2637 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
2613 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
2638 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
2614 savedir = os.getcwd()
2639 savedir = os.getcwd()
2615 try:
2640 try:
2616 # write the whole loop for posix/Windows so we don't have an if in
2641 # write the whole loop for posix/Windows so we don't have an if in
2617 # the innermost part
2642 # the innermost part
2618 if os.name == 'posix':
2643 if os.name == 'posix':
2619 for pdir in path:
2644 for pdir in path:
2620 os.chdir(pdir)
2645 os.chdir(pdir)
2621 for ff in os.listdir(pdir):
2646 for ff in os.listdir(pdir):
2622 if isexec(ff) and ff not in self.shell.no_alias:
2647 if isexec(ff) and ff not in self.shell.no_alias:
2623 # each entry in the alias table must be (N,name),
2648 # each entry in the alias table must be (N,name),
2624 # where N is the number of positional arguments of the
2649 # where N is the number of positional arguments of the
2625 # alias.
2650 # alias.
2626 alias_table[ff] = (0,ff)
2651 alias_table[ff] = (0,ff)
2627 syscmdlist.append(ff)
2652 syscmdlist.append(ff)
2628 else:
2653 else:
2629 for pdir in path:
2654 for pdir in path:
2630 os.chdir(pdir)
2655 os.chdir(pdir)
2631 for ff in os.listdir(pdir):
2656 for ff in os.listdir(pdir):
2632 base, ext = os.path.splitext(ff)
2657 base, ext = os.path.splitext(ff)
2633 if isexec(ff) and base.lower() not in self.shell.no_alias:
2658 if isexec(ff) and base.lower() not in self.shell.no_alias:
2634 if ext.lower() == '.exe':
2659 if ext.lower() == '.exe':
2635 ff = base
2660 ff = base
2636 alias_table[base.lower()] = (0,ff)
2661 alias_table[base.lower()] = (0,ff)
2637 syscmdlist.append(ff)
2662 syscmdlist.append(ff)
2638 # Make sure the alias table doesn't contain keywords or builtins
2663 # Make sure the alias table doesn't contain keywords or builtins
2639 self.shell.alias_table_validate()
2664 self.shell.alias_table_validate()
2640 # Call again init_auto_alias() so we get 'rm -i' and other
2665 # Call again init_auto_alias() so we get 'rm -i' and other
2641 # modified aliases since %rehashx will probably clobber them
2666 # modified aliases since %rehashx will probably clobber them
2642
2667
2643 # no, we don't want them. if %rehashx clobbers them, good,
2668 # no, we don't want them. if %rehashx clobbers them, good,
2644 # we'll probably get better versions
2669 # we'll probably get better versions
2645 # self.shell.init_auto_alias()
2670 # self.shell.init_auto_alias()
2646 db = ip.db
2671 db = ip.db
2647 db['syscmdlist'] = syscmdlist
2672 db['syscmdlist'] = syscmdlist
2648 finally:
2673 finally:
2649 os.chdir(savedir)
2674 os.chdir(savedir)
2650
2675
2651 def magic_pwd(self, parameter_s = ''):
2676 def magic_pwd(self, parameter_s = ''):
2652 """Return the current working directory path."""
2677 """Return the current working directory path."""
2653 return os.getcwd()
2678 return os.getcwd()
2654
2679
2655 def magic_cd(self, parameter_s=''):
2680 def magic_cd(self, parameter_s=''):
2656 """Change the current working directory.
2681 """Change the current working directory.
2657
2682
2658 This command automatically maintains an internal list of directories
2683 This command automatically maintains an internal list of directories
2659 you visit during your IPython session, in the variable _dh. The
2684 you visit during your IPython session, in the variable _dh. The
2660 command %dhist shows this history nicely formatted. You can also
2685 command %dhist shows this history nicely formatted. You can also
2661 do 'cd -<tab>' to see directory history conveniently.
2686 do 'cd -<tab>' to see directory history conveniently.
2662
2687
2663 Usage:
2688 Usage:
2664
2689
2665 cd 'dir': changes to directory 'dir'.
2690 cd 'dir': changes to directory 'dir'.
2666
2691
2667 cd -: changes to the last visited directory.
2692 cd -: changes to the last visited directory.
2668
2693
2669 cd -<n>: changes to the n-th directory in the directory history.
2694 cd -<n>: changes to the n-th directory in the directory history.
2670
2695
2671 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
2696 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
2672 (note: cd <bookmark_name> is enough if there is no
2697 (note: cd <bookmark_name> is enough if there is no
2673 directory <bookmark_name>, but a bookmark with the name exists.)
2698 directory <bookmark_name>, but a bookmark with the name exists.)
2674 'cd -b <tab>' allows you to tab-complete bookmark names.
2699 'cd -b <tab>' allows you to tab-complete bookmark names.
2675
2700
2676 Options:
2701 Options:
2677
2702
2678 -q: quiet. Do not print the working directory after the cd command is
2703 -q: quiet. Do not print the working directory after the cd command is
2679 executed. By default IPython's cd command does print this directory,
2704 executed. By default IPython's cd command does print this directory,
2680 since the default prompts do not display path information.
2705 since the default prompts do not display path information.
2681
2706
2682 Note that !cd doesn't work for this purpose because the shell where
2707 Note that !cd doesn't work for this purpose because the shell where
2683 !command runs is immediately discarded after executing 'command'."""
2708 !command runs is immediately discarded after executing 'command'."""
2684
2709
2685 parameter_s = parameter_s.strip()
2710 parameter_s = parameter_s.strip()
2686 #bkms = self.shell.persist.get("bookmarks",{})
2711 #bkms = self.shell.persist.get("bookmarks",{})
2687
2712
2688 oldcwd = os.getcwd()
2713 oldcwd = os.getcwd()
2689 numcd = re.match(r'(-)(\d+)$',parameter_s)
2714 numcd = re.match(r'(-)(\d+)$',parameter_s)
2690 # jump in directory history by number
2715 # jump in directory history by number
2691 if numcd:
2716 if numcd:
2692 nn = int(numcd.group(2))
2717 nn = int(numcd.group(2))
2693 try:
2718 try:
2694 ps = self.shell.user_ns['_dh'][nn]
2719 ps = self.shell.user_ns['_dh'][nn]
2695 except IndexError:
2720 except IndexError:
2696 print 'The requested directory does not exist in history.'
2721 print 'The requested directory does not exist in history.'
2697 return
2722 return
2698 else:
2723 else:
2699 opts = {}
2724 opts = {}
2700 else:
2725 else:
2701 #turn all non-space-escaping backslashes to slashes,
2726 #turn all non-space-escaping backslashes to slashes,
2702 # for c:\windows\directory\names\
2727 # for c:\windows\directory\names\
2703 parameter_s = re.sub(r'\\(?! )','/', parameter_s)
2728 parameter_s = re.sub(r'\\(?! )','/', parameter_s)
2704 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
2729 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
2705 # jump to previous
2730 # jump to previous
2706 if ps == '-':
2731 if ps == '-':
2707 try:
2732 try:
2708 ps = self.shell.user_ns['_dh'][-2]
2733 ps = self.shell.user_ns['_dh'][-2]
2709 except IndexError:
2734 except IndexError:
2710 raise UsageError('%cd -: No previous directory to change to.')
2735 raise UsageError('%cd -: No previous directory to change to.')
2711 # jump to bookmark if needed
2736 # jump to bookmark if needed
2712 else:
2737 else:
2713 if not os.path.isdir(ps) or opts.has_key('b'):
2738 if not os.path.isdir(ps) or opts.has_key('b'):
2714 bkms = self.db.get('bookmarks', {})
2739 bkms = self.db.get('bookmarks', {})
2715
2740
2716 if bkms.has_key(ps):
2741 if bkms.has_key(ps):
2717 target = bkms[ps]
2742 target = bkms[ps]
2718 print '(bookmark:%s) -> %s' % (ps,target)
2743 print '(bookmark:%s) -> %s' % (ps,target)
2719 ps = target
2744 ps = target
2720 else:
2745 else:
2721 if opts.has_key('b'):
2746 if opts.has_key('b'):
2722 raise UsageError("Bookmark '%s' not found. "
2747 raise UsageError("Bookmark '%s' not found. "
2723 "Use '%%bookmark -l' to see your bookmarks." % ps)
2748 "Use '%%bookmark -l' to see your bookmarks." % ps)
2724
2749
2725 # at this point ps should point to the target dir
2750 # at this point ps should point to the target dir
2726 if ps:
2751 if ps:
2727 try:
2752 try:
2728 os.chdir(os.path.expanduser(ps))
2753 os.chdir(os.path.expanduser(ps))
2729 if self.shell.rc.term_title:
2754 if self.shell.rc.term_title:
2730 #print 'set term title:',self.shell.rc.term_title # dbg
2755 #print 'set term title:',self.shell.rc.term_title # dbg
2731 platutils.set_term_title('IPy ' + abbrev_cwd())
2756 platutils.set_term_title('IPy ' + abbrev_cwd())
2732 except OSError:
2757 except OSError:
2733 print sys.exc_info()[1]
2758 print sys.exc_info()[1]
2734 else:
2759 else:
2735 cwd = os.getcwd()
2760 cwd = os.getcwd()
2736 dhist = self.shell.user_ns['_dh']
2761 dhist = self.shell.user_ns['_dh']
2737 if oldcwd != cwd:
2762 if oldcwd != cwd:
2738 dhist.append(cwd)
2763 dhist.append(cwd)
2739 self.db['dhist'] = compress_dhist(dhist)[-100:]
2764 self.db['dhist'] = compress_dhist(dhist)[-100:]
2740
2765
2741 else:
2766 else:
2742 os.chdir(self.shell.home_dir)
2767 os.chdir(self.shell.home_dir)
2743 if self.shell.rc.term_title:
2768 if self.shell.rc.term_title:
2744 platutils.set_term_title("IPy ~")
2769 platutils.set_term_title("IPy ~")
2745 cwd = os.getcwd()
2770 cwd = os.getcwd()
2746 dhist = self.shell.user_ns['_dh']
2771 dhist = self.shell.user_ns['_dh']
2747
2772
2748 if oldcwd != cwd:
2773 if oldcwd != cwd:
2749 dhist.append(cwd)
2774 dhist.append(cwd)
2750 self.db['dhist'] = compress_dhist(dhist)[-100:]
2775 self.db['dhist'] = compress_dhist(dhist)[-100:]
2751 if not 'q' in opts and self.shell.user_ns['_dh']:
2776 if not 'q' in opts and self.shell.user_ns['_dh']:
2752 print self.shell.user_ns['_dh'][-1]
2777 print self.shell.user_ns['_dh'][-1]
2753
2778
2754
2779
2755 def magic_env(self, parameter_s=''):
2780 def magic_env(self, parameter_s=''):
2756 """List environment variables."""
2781 """List environment variables."""
2757
2782
2758 return os.environ.data
2783 return os.environ.data
2759
2784
2760 def magic_pushd(self, parameter_s=''):
2785 def magic_pushd(self, parameter_s=''):
2761 """Place the current dir on stack and change directory.
2786 """Place the current dir on stack and change directory.
2762
2787
2763 Usage:\\
2788 Usage:\\
2764 %pushd ['dirname']
2789 %pushd ['dirname']
2765 """
2790 """
2766
2791
2767 dir_s = self.shell.dir_stack
2792 dir_s = self.shell.dir_stack
2768 tgt = os.path.expanduser(parameter_s)
2793 tgt = os.path.expanduser(parameter_s)
2769 cwd = os.getcwd().replace(self.home_dir,'~')
2794 cwd = os.getcwd().replace(self.home_dir,'~')
2770 if tgt:
2795 if tgt:
2771 self.magic_cd(parameter_s)
2796 self.magic_cd(parameter_s)
2772 dir_s.insert(0,cwd)
2797 dir_s.insert(0,cwd)
2773 return self.magic_dirs()
2798 return self.magic_dirs()
2774
2799
2775 def magic_popd(self, parameter_s=''):
2800 def magic_popd(self, parameter_s=''):
2776 """Change to directory popped off the top of the stack.
2801 """Change to directory popped off the top of the stack.
2777 """
2802 """
2778 if not self.shell.dir_stack:
2803 if not self.shell.dir_stack:
2779 raise UsageError("%popd on empty stack")
2804 raise UsageError("%popd on empty stack")
2780 top = self.shell.dir_stack.pop(0)
2805 top = self.shell.dir_stack.pop(0)
2781 self.magic_cd(top)
2806 self.magic_cd(top)
2782 print "popd ->",top
2807 print "popd ->",top
2783
2808
2784 def magic_dirs(self, parameter_s=''):
2809 def magic_dirs(self, parameter_s=''):
2785 """Return the current directory stack."""
2810 """Return the current directory stack."""
2786
2811
2787 return self.shell.dir_stack
2812 return self.shell.dir_stack
2788
2813
2789 def magic_dhist(self, parameter_s=''):
2814 def magic_dhist(self, parameter_s=''):
2790 """Print your history of visited directories.
2815 """Print your history of visited directories.
2791
2816
2792 %dhist -> print full history\\
2817 %dhist -> print full history\\
2793 %dhist n -> print last n entries only\\
2818 %dhist n -> print last n entries only\\
2794 %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\\
2819 %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\\
2795
2820
2796 This history is automatically maintained by the %cd command, and
2821 This history is automatically maintained by the %cd command, and
2797 always available as the global list variable _dh. You can use %cd -<n>
2822 always available as the global list variable _dh. You can use %cd -<n>
2798 to go to directory number <n>.
2823 to go to directory number <n>.
2799
2824
2800 Note that most of time, you should view directory history by entering
2825 Note that most of time, you should view directory history by entering
2801 cd -<TAB>.
2826 cd -<TAB>.
2802
2827
2803 """
2828 """
2804
2829
2805 dh = self.shell.user_ns['_dh']
2830 dh = self.shell.user_ns['_dh']
2806 if parameter_s:
2831 if parameter_s:
2807 try:
2832 try:
2808 args = map(int,parameter_s.split())
2833 args = map(int,parameter_s.split())
2809 except:
2834 except:
2810 self.arg_err(Magic.magic_dhist)
2835 self.arg_err(Magic.magic_dhist)
2811 return
2836 return
2812 if len(args) == 1:
2837 if len(args) == 1:
2813 ini,fin = max(len(dh)-(args[0]),0),len(dh)
2838 ini,fin = max(len(dh)-(args[0]),0),len(dh)
2814 elif len(args) == 2:
2839 elif len(args) == 2:
2815 ini,fin = args
2840 ini,fin = args
2816 else:
2841 else:
2817 self.arg_err(Magic.magic_dhist)
2842 self.arg_err(Magic.magic_dhist)
2818 return
2843 return
2819 else:
2844 else:
2820 ini,fin = 0,len(dh)
2845 ini,fin = 0,len(dh)
2821 nlprint(dh,
2846 nlprint(dh,
2822 header = 'Directory history (kept in _dh)',
2847 header = 'Directory history (kept in _dh)',
2823 start=ini,stop=fin)
2848 start=ini,stop=fin)
2824
2849
2825
2850 @testdec.skip_doctest
2826 def magic_sc(self, parameter_s=''):
2851 def magic_sc(self, parameter_s=''):
2827 """Shell capture - execute a shell command and capture its output.
2852 """Shell capture - execute a shell command and capture its output.
2828
2853
2829 DEPRECATED. Suboptimal, retained for backwards compatibility.
2854 DEPRECATED. Suboptimal, retained for backwards compatibility.
2830
2855
2831 You should use the form 'var = !command' instead. Example:
2856 You should use the form 'var = !command' instead. Example:
2832
2857
2833 "%sc -l myfiles = ls ~" should now be written as
2858 "%sc -l myfiles = ls ~" should now be written as
2834
2859
2835 "myfiles = !ls ~"
2860 "myfiles = !ls ~"
2836
2861
2837 myfiles.s, myfiles.l and myfiles.n still apply as documented
2862 myfiles.s, myfiles.l and myfiles.n still apply as documented
2838 below.
2863 below.
2839
2864
2840 --
2865 --
2841 %sc [options] varname=command
2866 %sc [options] varname=command
2842
2867
2843 IPython will run the given command using commands.getoutput(), and
2868 IPython will run the given command using commands.getoutput(), and
2844 will then update the user's interactive namespace with a variable
2869 will then update the user's interactive namespace with a variable
2845 called varname, containing the value of the call. Your command can
2870 called varname, containing the value of the call. Your command can
2846 contain shell wildcards, pipes, etc.
2871 contain shell wildcards, pipes, etc.
2847
2872
2848 The '=' sign in the syntax is mandatory, and the variable name you
2873 The '=' sign in the syntax is mandatory, and the variable name you
2849 supply must follow Python's standard conventions for valid names.
2874 supply must follow Python's standard conventions for valid names.
2850
2875
2851 (A special format without variable name exists for internal use)
2876 (A special format without variable name exists for internal use)
2852
2877
2853 Options:
2878 Options:
2854
2879
2855 -l: list output. Split the output on newlines into a list before
2880 -l: list output. Split the output on newlines into a list before
2856 assigning it to the given variable. By default the output is stored
2881 assigning it to the given variable. By default the output is stored
2857 as a single string.
2882 as a single string.
2858
2883
2859 -v: verbose. Print the contents of the variable.
2884 -v: verbose. Print the contents of the variable.
2860
2885
2861 In most cases you should not need to split as a list, because the
2886 In most cases you should not need to split as a list, because the
2862 returned value is a special type of string which can automatically
2887 returned value is a special type of string which can automatically
2863 provide its contents either as a list (split on newlines) or as a
2888 provide its contents either as a list (split on newlines) or as a
2864 space-separated string. These are convenient, respectively, either
2889 space-separated string. These are convenient, respectively, either
2865 for sequential processing or to be passed to a shell command.
2890 for sequential processing or to be passed to a shell command.
2866
2891
2867 For example:
2892 For example:
2868
2893
2894 # all-random
2895
2869 # Capture into variable a
2896 # Capture into variable a
2870 In [9]: sc a=ls *py
2897 In [1]: sc a=ls *py
2871
2898
2872 # a is a string with embedded newlines
2899 # a is a string with embedded newlines
2873 In [10]: a
2900 In [2]: a
2874 Out[10]: 'setup.py\nwin32_manual_post_install.py'
2901 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
2875
2902
2876 # which can be seen as a list:
2903 # which can be seen as a list:
2877 In [11]: a.l
2904 In [3]: a.l
2878 Out[11]: ['setup.py', 'win32_manual_post_install.py']
2905 Out[3]: ['setup.py', 'win32_manual_post_install.py']
2879
2906
2880 # or as a whitespace-separated string:
2907 # or as a whitespace-separated string:
2881 In [12]: a.s
2908 In [4]: a.s
2882 Out[12]: 'setup.py win32_manual_post_install.py'
2909 Out[4]: 'setup.py win32_manual_post_install.py'
2883
2910
2884 # a.s is useful to pass as a single command line:
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 146 setup.py
2913 146 setup.py
2887 130 win32_manual_post_install.py
2914 130 win32_manual_post_install.py
2888 276 total
2915 276 total
2889
2916
2890 # while the list form is useful to loop over:
2917 # while the list form is useful to loop over:
2891 In [14]: for f in a.l:
2918 In [6]: for f in a.l:
2892 ....: !wc -l $f
2919 ...: !wc -l $f
2893 ....:
2920 ...:
2894 146 setup.py
2921 146 setup.py
2895 130 win32_manual_post_install.py
2922 130 win32_manual_post_install.py
2896
2923
2897 Similiarly, the lists returned by the -l option are also special, in
2924 Similiarly, the lists returned by the -l option are also special, in
2898 the sense that you can equally invoke the .s attribute on them to
2925 the sense that you can equally invoke the .s attribute on them to
2899 automatically get a whitespace-separated string from their contents:
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
2930 In [8]: b
2904 Out[2]: ['setup.py', 'win32_manual_post_install.py']
2931 Out[8]: ['setup.py', 'win32_manual_post_install.py']
2905
2932
2906 In [3]: b.s
2933 In [9]: b.s
2907 Out[3]: 'setup.py win32_manual_post_install.py'
2934 Out[9]: 'setup.py win32_manual_post_install.py'
2908
2935
2909 In summary, both the lists and strings used for ouptut capture have
2936 In summary, both the lists and strings used for ouptut capture have
2910 the following special attributes:
2937 the following special attributes:
2911
2938
2912 .l (or .list) : value as list.
2939 .l (or .list) : value as list.
2913 .n (or .nlstr): value as newline-separated string.
2940 .n (or .nlstr): value as newline-separated string.
2914 .s (or .spstr): value as space-separated string.
2941 .s (or .spstr): value as space-separated string.
2915 """
2942 """
2916
2943
2917 opts,args = self.parse_options(parameter_s,'lv')
2944 opts,args = self.parse_options(parameter_s,'lv')
2918 # Try to get a variable name and command to run
2945 # Try to get a variable name and command to run
2919 try:
2946 try:
2920 # the variable name must be obtained from the parse_options
2947 # the variable name must be obtained from the parse_options
2921 # output, which uses shlex.split to strip options out.
2948 # output, which uses shlex.split to strip options out.
2922 var,_ = args.split('=',1)
2949 var,_ = args.split('=',1)
2923 var = var.strip()
2950 var = var.strip()
2924 # But the the command has to be extracted from the original input
2951 # But the the command has to be extracted from the original input
2925 # parameter_s, not on what parse_options returns, to avoid the
2952 # parameter_s, not on what parse_options returns, to avoid the
2926 # quote stripping which shlex.split performs on it.
2953 # quote stripping which shlex.split performs on it.
2927 _,cmd = parameter_s.split('=',1)
2954 _,cmd = parameter_s.split('=',1)
2928 except ValueError:
2955 except ValueError:
2929 var,cmd = '',''
2956 var,cmd = '',''
2930 # If all looks ok, proceed
2957 # If all looks ok, proceed
2931 out,err = self.shell.getoutputerror(cmd)
2958 out,err = self.shell.getoutputerror(cmd)
2932 if err:
2959 if err:
2933 print >> Term.cerr,err
2960 print >> Term.cerr,err
2934 if opts.has_key('l'):
2961 if opts.has_key('l'):
2935 out = SList(out.split('\n'))
2962 out = SList(out.split('\n'))
2936 else:
2963 else:
2937 out = LSString(out)
2964 out = LSString(out)
2938 if opts.has_key('v'):
2965 if opts.has_key('v'):
2939 print '%s ==\n%s' % (var,pformat(out))
2966 print '%s ==\n%s' % (var,pformat(out))
2940 if var:
2967 if var:
2941 self.shell.user_ns.update({var:out})
2968 self.shell.user_ns.update({var:out})
2942 else:
2969 else:
2943 return out
2970 return out
2944
2971
2945 def magic_sx(self, parameter_s=''):
2972 def magic_sx(self, parameter_s=''):
2946 """Shell execute - run a shell command and capture its output.
2973 """Shell execute - run a shell command and capture its output.
2947
2974
2948 %sx command
2975 %sx command
2949
2976
2950 IPython will run the given command using commands.getoutput(), and
2977 IPython will run the given command using commands.getoutput(), and
2951 return the result formatted as a list (split on '\\n'). Since the
2978 return the result formatted as a list (split on '\\n'). Since the
2952 output is _returned_, it will be stored in ipython's regular output
2979 output is _returned_, it will be stored in ipython's regular output
2953 cache Out[N] and in the '_N' automatic variables.
2980 cache Out[N] and in the '_N' automatic variables.
2954
2981
2955 Notes:
2982 Notes:
2956
2983
2957 1) If an input line begins with '!!', then %sx is automatically
2984 1) If an input line begins with '!!', then %sx is automatically
2958 invoked. That is, while:
2985 invoked. That is, while:
2959 !ls
2986 !ls
2960 causes ipython to simply issue system('ls'), typing
2987 causes ipython to simply issue system('ls'), typing
2961 !!ls
2988 !!ls
2962 is a shorthand equivalent to:
2989 is a shorthand equivalent to:
2963 %sx ls
2990 %sx ls
2964
2991
2965 2) %sx differs from %sc in that %sx automatically splits into a list,
2992 2) %sx differs from %sc in that %sx automatically splits into a list,
2966 like '%sc -l'. The reason for this is to make it as easy as possible
2993 like '%sc -l'. The reason for this is to make it as easy as possible
2967 to process line-oriented shell output via further python commands.
2994 to process line-oriented shell output via further python commands.
2968 %sc is meant to provide much finer control, but requires more
2995 %sc is meant to provide much finer control, but requires more
2969 typing.
2996 typing.
2970
2997
2971 3) Just like %sc -l, this is a list with special attributes:
2998 3) Just like %sc -l, this is a list with special attributes:
2972
2999
2973 .l (or .list) : value as list.
3000 .l (or .list) : value as list.
2974 .n (or .nlstr): value as newline-separated string.
3001 .n (or .nlstr): value as newline-separated string.
2975 .s (or .spstr): value as whitespace-separated string.
3002 .s (or .spstr): value as whitespace-separated string.
2976
3003
2977 This is very useful when trying to use such lists as arguments to
3004 This is very useful when trying to use such lists as arguments to
2978 system commands."""
3005 system commands."""
2979
3006
2980 if parameter_s:
3007 if parameter_s:
2981 out,err = self.shell.getoutputerror(parameter_s)
3008 out,err = self.shell.getoutputerror(parameter_s)
2982 if err:
3009 if err:
2983 print >> Term.cerr,err
3010 print >> Term.cerr,err
2984 return SList(out.split('\n'))
3011 return SList(out.split('\n'))
2985
3012
2986 def magic_bg(self, parameter_s=''):
3013 def magic_bg(self, parameter_s=''):
2987 """Run a job in the background, in a separate thread.
3014 """Run a job in the background, in a separate thread.
2988
3015
2989 For example,
3016 For example,
2990
3017
2991 %bg myfunc(x,y,z=1)
3018 %bg myfunc(x,y,z=1)
2992
3019
2993 will execute 'myfunc(x,y,z=1)' in a background thread. As soon as the
3020 will execute 'myfunc(x,y,z=1)' in a background thread. As soon as the
2994 execution starts, a message will be printed indicating the job
3021 execution starts, a message will be printed indicating the job
2995 number. If your job number is 5, you can use
3022 number. If your job number is 5, you can use
2996
3023
2997 myvar = jobs.result(5) or myvar = jobs[5].result
3024 myvar = jobs.result(5) or myvar = jobs[5].result
2998
3025
2999 to assign this result to variable 'myvar'.
3026 to assign this result to variable 'myvar'.
3000
3027
3001 IPython has a job manager, accessible via the 'jobs' object. You can
3028 IPython has a job manager, accessible via the 'jobs' object. You can
3002 type jobs? to get more information about it, and use jobs.<TAB> to see
3029 type jobs? to get more information about it, and use jobs.<TAB> to see
3003 its attributes. All attributes not starting with an underscore are
3030 its attributes. All attributes not starting with an underscore are
3004 meant for public use.
3031 meant for public use.
3005
3032
3006 In particular, look at the jobs.new() method, which is used to create
3033 In particular, look at the jobs.new() method, which is used to create
3007 new jobs. This magic %bg function is just a convenience wrapper
3034 new jobs. This magic %bg function is just a convenience wrapper
3008 around jobs.new(), for expression-based jobs. If you want to create a
3035 around jobs.new(), for expression-based jobs. If you want to create a
3009 new job with an explicit function object and arguments, you must call
3036 new job with an explicit function object and arguments, you must call
3010 jobs.new() directly.
3037 jobs.new() directly.
3011
3038
3012 The jobs.new docstring also describes in detail several important
3039 The jobs.new docstring also describes in detail several important
3013 caveats associated with a thread-based model for background job
3040 caveats associated with a thread-based model for background job
3014 execution. Type jobs.new? for details.
3041 execution. Type jobs.new? for details.
3015
3042
3016 You can check the status of all jobs with jobs.status().
3043 You can check the status of all jobs with jobs.status().
3017
3044
3018 The jobs variable is set by IPython into the Python builtin namespace.
3045 The jobs variable is set by IPython into the Python builtin namespace.
3019 If you ever declare a variable named 'jobs', you will shadow this
3046 If you ever declare a variable named 'jobs', you will shadow this
3020 name. You can either delete your global jobs variable to regain
3047 name. You can either delete your global jobs variable to regain
3021 access to the job manager, or make a new name and assign it manually
3048 access to the job manager, or make a new name and assign it manually
3022 to the manager (stored in IPython's namespace). For example, to
3049 to the manager (stored in IPython's namespace). For example, to
3023 assign the job manager to the Jobs name, use:
3050 assign the job manager to the Jobs name, use:
3024
3051
3025 Jobs = __builtins__.jobs"""
3052 Jobs = __builtins__.jobs"""
3026
3053
3027 self.shell.jobs.new(parameter_s,self.shell.user_ns)
3054 self.shell.jobs.new(parameter_s,self.shell.user_ns)
3028
3055
3029 def magic_r(self, parameter_s=''):
3056 def magic_r(self, parameter_s=''):
3030 """Repeat previous input.
3057 """Repeat previous input.
3031
3058
3032 Note: Consider using the more powerfull %rep instead!
3059 Note: Consider using the more powerfull %rep instead!
3033
3060
3034 If given an argument, repeats the previous command which starts with
3061 If given an argument, repeats the previous command which starts with
3035 the same string, otherwise it just repeats the previous input.
3062 the same string, otherwise it just repeats the previous input.
3036
3063
3037 Shell escaped commands (with ! as first character) are not recognized
3064 Shell escaped commands (with ! as first character) are not recognized
3038 by this system, only pure python code and magic commands.
3065 by this system, only pure python code and magic commands.
3039 """
3066 """
3040
3067
3041 start = parameter_s.strip()
3068 start = parameter_s.strip()
3042 esc_magic = self.shell.ESC_MAGIC
3069 esc_magic = self.shell.ESC_MAGIC
3043 # Identify magic commands even if automagic is on (which means
3070 # Identify magic commands even if automagic is on (which means
3044 # the in-memory version is different from that typed by the user).
3071 # the in-memory version is different from that typed by the user).
3045 if self.shell.rc.automagic:
3072 if self.shell.rc.automagic:
3046 start_magic = esc_magic+start
3073 start_magic = esc_magic+start
3047 else:
3074 else:
3048 start_magic = start
3075 start_magic = start
3049 # Look through the input history in reverse
3076 # Look through the input history in reverse
3050 for n in range(len(self.shell.input_hist)-2,0,-1):
3077 for n in range(len(self.shell.input_hist)-2,0,-1):
3051 input = self.shell.input_hist[n]
3078 input = self.shell.input_hist[n]
3052 # skip plain 'r' lines so we don't recurse to infinity
3079 # skip plain 'r' lines so we don't recurse to infinity
3053 if input != '_ip.magic("r")\n' and \
3080 if input != '_ip.magic("r")\n' and \
3054 (input.startswith(start) or input.startswith(start_magic)):
3081 (input.startswith(start) or input.startswith(start_magic)):
3055 #print 'match',`input` # dbg
3082 #print 'match',`input` # dbg
3056 print 'Executing:',input,
3083 print 'Executing:',input,
3057 self.shell.runlines(input)
3084 self.shell.runlines(input)
3058 return
3085 return
3059 print 'No previous input matching `%s` found.' % start
3086 print 'No previous input matching `%s` found.' % start
3060
3087
3061
3088
3062 def magic_bookmark(self, parameter_s=''):
3089 def magic_bookmark(self, parameter_s=''):
3063 """Manage IPython's bookmark system.
3090 """Manage IPython's bookmark system.
3064
3091
3065 %bookmark <name> - set bookmark to current dir
3092 %bookmark <name> - set bookmark to current dir
3066 %bookmark <name> <dir> - set bookmark to <dir>
3093 %bookmark <name> <dir> - set bookmark to <dir>
3067 %bookmark -l - list all bookmarks
3094 %bookmark -l - list all bookmarks
3068 %bookmark -d <name> - remove bookmark
3095 %bookmark -d <name> - remove bookmark
3069 %bookmark -r - remove all bookmarks
3096 %bookmark -r - remove all bookmarks
3070
3097
3071 You can later on access a bookmarked folder with:
3098 You can later on access a bookmarked folder with:
3072 %cd -b <name>
3099 %cd -b <name>
3073 or simply '%cd <name>' if there is no directory called <name> AND
3100 or simply '%cd <name>' if there is no directory called <name> AND
3074 there is such a bookmark defined.
3101 there is such a bookmark defined.
3075
3102
3076 Your bookmarks persist through IPython sessions, but they are
3103 Your bookmarks persist through IPython sessions, but they are
3077 associated with each profile."""
3104 associated with each profile."""
3078
3105
3079 opts,args = self.parse_options(parameter_s,'drl',mode='list')
3106 opts,args = self.parse_options(parameter_s,'drl',mode='list')
3080 if len(args) > 2:
3107 if len(args) > 2:
3081 raise UsageError("%bookmark: too many arguments")
3108 raise UsageError("%bookmark: too many arguments")
3082
3109
3083 bkms = self.db.get('bookmarks',{})
3110 bkms = self.db.get('bookmarks',{})
3084
3111
3085 if opts.has_key('d'):
3112 if opts.has_key('d'):
3086 try:
3113 try:
3087 todel = args[0]
3114 todel = args[0]
3088 except IndexError:
3115 except IndexError:
3089 raise UsageError(
3116 raise UsageError(
3090 "%bookmark -d: must provide a bookmark to delete")
3117 "%bookmark -d: must provide a bookmark to delete")
3091 else:
3118 else:
3092 try:
3119 try:
3093 del bkms[todel]
3120 del bkms[todel]
3094 except KeyError:
3121 except KeyError:
3095 raise UsageError(
3122 raise UsageError(
3096 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
3123 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
3097
3124
3098 elif opts.has_key('r'):
3125 elif opts.has_key('r'):
3099 bkms = {}
3126 bkms = {}
3100 elif opts.has_key('l'):
3127 elif opts.has_key('l'):
3101 bks = bkms.keys()
3128 bks = bkms.keys()
3102 bks.sort()
3129 bks.sort()
3103 if bks:
3130 if bks:
3104 size = max(map(len,bks))
3131 size = max(map(len,bks))
3105 else:
3132 else:
3106 size = 0
3133 size = 0
3107 fmt = '%-'+str(size)+'s -> %s'
3134 fmt = '%-'+str(size)+'s -> %s'
3108 print 'Current bookmarks:'
3135 print 'Current bookmarks:'
3109 for bk in bks:
3136 for bk in bks:
3110 print fmt % (bk,bkms[bk])
3137 print fmt % (bk,bkms[bk])
3111 else:
3138 else:
3112 if not args:
3139 if not args:
3113 raise UsageError("%bookmark: You must specify the bookmark name")
3140 raise UsageError("%bookmark: You must specify the bookmark name")
3114 elif len(args)==1:
3141 elif len(args)==1:
3115 bkms[args[0]] = os.getcwd()
3142 bkms[args[0]] = os.getcwd()
3116 elif len(args)==2:
3143 elif len(args)==2:
3117 bkms[args[0]] = args[1]
3144 bkms[args[0]] = args[1]
3118 self.db['bookmarks'] = bkms
3145 self.db['bookmarks'] = bkms
3119
3146
3120 def magic_pycat(self, parameter_s=''):
3147 def magic_pycat(self, parameter_s=''):
3121 """Show a syntax-highlighted file through a pager.
3148 """Show a syntax-highlighted file through a pager.
3122
3149
3123 This magic is similar to the cat utility, but it will assume the file
3150 This magic is similar to the cat utility, but it will assume the file
3124 to be Python source and will show it with syntax highlighting. """
3151 to be Python source and will show it with syntax highlighting. """
3125
3152
3126 try:
3153 try:
3127 filename = get_py_filename(parameter_s)
3154 filename = get_py_filename(parameter_s)
3128 cont = file_read(filename)
3155 cont = file_read(filename)
3129 except IOError:
3156 except IOError:
3130 try:
3157 try:
3131 cont = eval(parameter_s,self.user_ns)
3158 cont = eval(parameter_s,self.user_ns)
3132 except NameError:
3159 except NameError:
3133 cont = None
3160 cont = None
3134 if cont is None:
3161 if cont is None:
3135 print "Error: no such file or variable"
3162 print "Error: no such file or variable"
3136 return
3163 return
3137
3164
3138 page(self.shell.pycolorize(cont),
3165 page(self.shell.pycolorize(cont),
3139 screen_lines=self.shell.rc.screen_length)
3166 screen_lines=self.shell.rc.screen_length)
3140
3167
3141 def magic_cpaste(self, parameter_s=''):
3168 def magic_cpaste(self, parameter_s=''):
3142 """Allows you to paste & execute a pre-formatted code block from clipboard.
3169 """Allows you to paste & execute a pre-formatted code block from clipboard.
3143
3170
3144 You must terminate the block with '--' (two minus-signs) alone on the
3171 You must terminate the block with '--' (two minus-signs) alone on the
3145 line. You can also provide your own sentinel with '%paste -s %%' ('%%'
3172 line. You can also provide your own sentinel with '%paste -s %%' ('%%'
3146 is the new sentinel for this operation)
3173 is the new sentinel for this operation)
3147
3174
3148 The block is dedented prior to execution to enable execution of method
3175 The block is dedented prior to execution to enable execution of method
3149 definitions. '>' and '+' characters at the beginning of a line are
3176 definitions. '>' and '+' characters at the beginning of a line are
3150 ignored, to allow pasting directly from e-mails, diff files and
3177 ignored, to allow pasting directly from e-mails, diff files and
3151 doctests (the '...' continuation prompt is also stripped). The
3178 doctests (the '...' continuation prompt is also stripped). The
3152 executed block is also assigned to variable named 'pasted_block' for
3179 executed block is also assigned to variable named 'pasted_block' for
3153 later editing with '%edit pasted_block'.
3180 later editing with '%edit pasted_block'.
3154
3181
3155 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
3182 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
3156 This assigns the pasted block to variable 'foo' as string, without
3183 This assigns the pasted block to variable 'foo' as string, without
3157 dedenting or executing it (preceding >>> and + is still stripped)
3184 dedenting or executing it (preceding >>> and + is still stripped)
3158
3185
3159 Do not be alarmed by garbled output on Windows (it's a readline bug).
3186 Do not be alarmed by garbled output on Windows (it's a readline bug).
3160 Just press enter and type -- (and press enter again) and the block
3187 Just press enter and type -- (and press enter again) and the block
3161 will be what was just pasted.
3188 will be what was just pasted.
3162
3189
3163 IPython statements (magics, shell escapes) are not supported (yet).
3190 IPython statements (magics, shell escapes) are not supported (yet).
3164 """
3191 """
3165 opts,args = self.parse_options(parameter_s,'s:',mode='string')
3192 opts,args = self.parse_options(parameter_s,'s:',mode='string')
3166 par = args.strip()
3193 par = args.strip()
3167 sentinel = opts.get('s','--')
3194 sentinel = opts.get('s','--')
3168
3195
3169 # Regular expressions that declare text we strip from the input:
3196 # Regular expressions that declare text we strip from the input:
3170 strip_re = [r'^\s*In \[\d+\]:', # IPython input prompt
3197 strip_re = [r'^\s*In \[\d+\]:', # IPython input prompt
3171 r'^\s*(\s?>)+', # Python input prompt
3198 r'^\s*(\s?>)+', # Python input prompt
3172 r'^\s*\.{3,}', # Continuation prompts
3199 r'^\s*\.{3,}', # Continuation prompts
3173 r'^\++',
3200 r'^\++',
3174 ]
3201 ]
3175
3202
3176 strip_from_start = map(re.compile,strip_re)
3203 strip_from_start = map(re.compile,strip_re)
3177
3204
3178 from IPython import iplib
3205 from IPython import iplib
3179 lines = []
3206 lines = []
3180 print "Pasting code; enter '%s' alone on the line to stop." % sentinel
3207 print "Pasting code; enter '%s' alone on the line to stop." % sentinel
3181 while 1:
3208 while 1:
3182 l = iplib.raw_input_original(':')
3209 l = iplib.raw_input_original(':')
3183 if l ==sentinel:
3210 if l ==sentinel:
3184 break
3211 break
3185
3212
3186 for pat in strip_from_start:
3213 for pat in strip_from_start:
3187 l = pat.sub('',l)
3214 l = pat.sub('',l)
3188 lines.append(l)
3215 lines.append(l)
3189
3216
3190 block = "\n".join(lines) + '\n'
3217 block = "\n".join(lines) + '\n'
3191 #print "block:\n",block
3218 #print "block:\n",block
3192 if not par:
3219 if not par:
3193 b = textwrap.dedent(block)
3220 b = textwrap.dedent(block)
3194 exec b in self.user_ns
3221 exec b in self.user_ns
3195 self.user_ns['pasted_block'] = b
3222 self.user_ns['pasted_block'] = b
3196 else:
3223 else:
3197 self.user_ns[par] = SList(block.splitlines())
3224 self.user_ns[par] = SList(block.splitlines())
3198 print "Block assigned to '%s'" % par
3225 print "Block assigned to '%s'" % par
3199
3226
3200 def magic_quickref(self,arg):
3227 def magic_quickref(self,arg):
3201 """ Show a quick reference sheet """
3228 """ Show a quick reference sheet """
3202 import IPython.usage
3229 import IPython.usage
3203 qr = IPython.usage.quick_reference + self.magic_magic('-brief')
3230 qr = IPython.usage.quick_reference + self.magic_magic('-brief')
3204
3231
3205 page(qr)
3232 page(qr)
3206
3233
3207 def magic_upgrade(self,arg):
3234 def magic_upgrade(self,arg):
3208 """ Upgrade your IPython installation
3235 """ Upgrade your IPython installation
3209
3236
3210 This will copy the config files that don't yet exist in your
3237 This will copy the config files that don't yet exist in your
3211 ipython dir from the system config dir. Use this after upgrading
3238 ipython dir from the system config dir. Use this after upgrading
3212 IPython if you don't wish to delete your .ipython dir.
3239 IPython if you don't wish to delete your .ipython dir.
3213
3240
3214 Call with -nolegacy to get rid of ipythonrc* files (recommended for
3241 Call with -nolegacy to get rid of ipythonrc* files (recommended for
3215 new users)
3242 new users)
3216
3243
3217 """
3244 """
3218 ip = self.getapi()
3245 ip = self.getapi()
3219 ipinstallation = path(IPython.__file__).dirname()
3246 ipinstallation = path(IPython.__file__).dirname()
3220 upgrade_script = '%s "%s"' % (sys.executable,ipinstallation / 'upgrade_dir.py')
3247 upgrade_script = '%s "%s"' % (sys.executable,ipinstallation / 'upgrade_dir.py')
3221 src_config = ipinstallation / 'UserConfig'
3248 src_config = ipinstallation / 'UserConfig'
3222 userdir = path(ip.options.ipythondir)
3249 userdir = path(ip.options.ipythondir)
3223 cmd = '%s "%s" "%s"' % (upgrade_script, src_config, userdir)
3250 cmd = '%s "%s" "%s"' % (upgrade_script, src_config, userdir)
3224 print ">",cmd
3251 print ">",cmd
3225 shell(cmd)
3252 shell(cmd)
3226 if arg == '-nolegacy':
3253 if arg == '-nolegacy':
3227 legacy = userdir.files('ipythonrc*')
3254 legacy = userdir.files('ipythonrc*')
3228 print "Nuking legacy files:",legacy
3255 print "Nuking legacy files:",legacy
3229
3256
3230 [p.remove() for p in legacy]
3257 [p.remove() for p in legacy]
3231 suffix = (sys.platform == 'win32' and '.ini' or '')
3258 suffix = (sys.platform == 'win32' and '.ini' or '')
3232 (userdir / ('ipythonrc' + suffix)).write_text('# Empty, see ipy_user_conf.py\n')
3259 (userdir / ('ipythonrc' + suffix)).write_text('# Empty, see ipy_user_conf.py\n')
3233
3260
3234
3261
3235 def magic_doctest_mode(self,parameter_s=''):
3262 def magic_doctest_mode(self,parameter_s=''):
3236 """Toggle doctest mode on and off.
3263 """Toggle doctest mode on and off.
3237
3264
3238 This mode allows you to toggle the prompt behavior between normal
3265 This mode allows you to toggle the prompt behavior between normal
3239 IPython prompts and ones that are as similar to the default IPython
3266 IPython prompts and ones that are as similar to the default IPython
3240 interpreter as possible.
3267 interpreter as possible.
3241
3268
3242 It also supports the pasting of code snippets that have leading '>>>'
3269 It also supports the pasting of code snippets that have leading '>>>'
3243 and '...' prompts in them. This means that you can paste doctests from
3270 and '...' prompts in them. This means that you can paste doctests from
3244 files or docstrings (even if they have leading whitespace), and the
3271 files or docstrings (even if they have leading whitespace), and the
3245 code will execute correctly. You can then use '%history -tn' to see
3272 code will execute correctly. You can then use '%history -tn' to see
3246 the translated history without line numbers; this will give you the
3273 the translated history without line numbers; this will give you the
3247 input after removal of all the leading prompts and whitespace, which
3274 input after removal of all the leading prompts and whitespace, which
3248 can be pasted back into an editor.
3275 can be pasted back into an editor.
3249
3276
3250 With these features, you can switch into this mode easily whenever you
3277 With these features, you can switch into this mode easily whenever you
3251 need to do testing and changes to doctests, without having to leave
3278 need to do testing and changes to doctests, without having to leave
3252 your existing IPython session.
3279 your existing IPython session.
3253 """
3280 """
3254
3281
3255 # XXX - Fix this to have cleaner activate/deactivate calls.
3282 # XXX - Fix this to have cleaner activate/deactivate calls.
3256 from IPython.Extensions import InterpreterPasteInput as ipaste
3283 from IPython.Extensions import InterpreterPasteInput as ipaste
3257 from IPython.ipstruct import Struct
3284 from IPython.ipstruct import Struct
3258
3285
3259 # Shorthands
3286 # Shorthands
3260 shell = self.shell
3287 shell = self.shell
3261 oc = shell.outputcache
3288 oc = shell.outputcache
3262 rc = shell.rc
3289 rc = shell.rc
3263 meta = shell.meta
3290 meta = shell.meta
3264 # dstore is a data store kept in the instance metadata bag to track any
3291 # dstore is a data store kept in the instance metadata bag to track any
3265 # changes we make, so we can undo them later.
3292 # changes we make, so we can undo them later.
3266 dstore = meta.setdefault('doctest_mode',Struct())
3293 dstore = meta.setdefault('doctest_mode',Struct())
3267 save_dstore = dstore.setdefault
3294 save_dstore = dstore.setdefault
3268
3295
3269 # save a few values we'll need to recover later
3296 # save a few values we'll need to recover later
3270 mode = save_dstore('mode',False)
3297 mode = save_dstore('mode',False)
3271 save_dstore('rc_pprint',rc.pprint)
3298 save_dstore('rc_pprint',rc.pprint)
3272 save_dstore('xmode',shell.InteractiveTB.mode)
3299 save_dstore('xmode',shell.InteractiveTB.mode)
3273 save_dstore('rc_separate_out',rc.separate_out)
3300 save_dstore('rc_separate_out',rc.separate_out)
3274 save_dstore('rc_separate_out2',rc.separate_out2)
3301 save_dstore('rc_separate_out2',rc.separate_out2)
3275 save_dstore('rc_prompts_pad_left',rc.prompts_pad_left)
3302 save_dstore('rc_prompts_pad_left',rc.prompts_pad_left)
3303 save_dstore('rc_separate_in',rc.separate_in)
3276
3304
3277 if mode == False:
3305 if mode == False:
3278 # turn on
3306 # turn on
3279 ipaste.activate_prefilter()
3307 ipaste.activate_prefilter()
3280
3308
3281 oc.prompt1.p_template = '>>> '
3309 oc.prompt1.p_template = '>>> '
3282 oc.prompt2.p_template = '... '
3310 oc.prompt2.p_template = '... '
3283 oc.prompt_out.p_template = ''
3311 oc.prompt_out.p_template = ''
3284
3312
3313 # Prompt separators like plain python
3314 oc.input_sep = oc.prompt1.sep = ''
3285 oc.output_sep = ''
3315 oc.output_sep = ''
3286 oc.output_sep2 = ''
3316 oc.output_sep2 = ''
3287
3317
3288 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3318 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3289 oc.prompt_out.pad_left = False
3319 oc.prompt_out.pad_left = False
3290
3320
3291 rc.pprint = False
3321 rc.pprint = False
3292
3322
3293 shell.magic_xmode('Plain')
3323 shell.magic_xmode('Plain')
3294
3324
3295 else:
3325 else:
3296 # turn off
3326 # turn off
3297 ipaste.deactivate_prefilter()
3327 ipaste.deactivate_prefilter()
3298
3328
3299 oc.prompt1.p_template = rc.prompt_in1
3329 oc.prompt1.p_template = rc.prompt_in1
3300 oc.prompt2.p_template = rc.prompt_in2
3330 oc.prompt2.p_template = rc.prompt_in2
3301 oc.prompt_out.p_template = rc.prompt_out
3331 oc.prompt_out.p_template = rc.prompt_out
3302
3332
3333 oc.input_sep = oc.prompt1.sep = dstore.rc_separate_in
3334
3303 oc.output_sep = dstore.rc_separate_out
3335 oc.output_sep = dstore.rc_separate_out
3304 oc.output_sep2 = dstore.rc_separate_out2
3336 oc.output_sep2 = dstore.rc_separate_out2
3305
3337
3306 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3338 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3307 oc.prompt_out.pad_left = dstore.rc_prompts_pad_left
3339 oc.prompt_out.pad_left = dstore.rc_prompts_pad_left
3308
3340
3309 rc.pprint = dstore.rc_pprint
3341 rc.pprint = dstore.rc_pprint
3310
3342
3311 shell.magic_xmode(dstore.xmode)
3343 shell.magic_xmode(dstore.xmode)
3312
3344
3313 # Store new mode and inform
3345 # Store new mode and inform
3314 dstore.mode = bool(1-int(mode))
3346 dstore.mode = bool(1-int(mode))
3315 print 'Doctest mode is:',
3347 print 'Doctest mode is:',
3316 print ['OFF','ON'][dstore.mode]
3348 print ['OFF','ON'][dstore.mode]
3317
3349
3318 # end Magic
3350 # end Magic
@@ -1,610 +1,613 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tools for inspecting Python objects.
2 """Tools for inspecting Python objects.
3
3
4 Uses syntax highlighting for presenting the various information elements.
4 Uses syntax highlighting for presenting the various information elements.
5
5
6 Similar in spirit to the inspect module, but all calls take a name argument to
6 Similar in spirit to the inspect module, but all calls take a name argument to
7 reference the name under which an object is being read.
7 reference the name under which an object is being read.
8
8
9 $Id: OInspect.py 2843 2007-10-15 21:22:32Z fperez $
9 $Id: OInspect.py 2843 2007-10-15 21:22:32Z fperez $
10 """
10 """
11
11
12 #*****************************************************************************
12 #*****************************************************************************
13 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
13 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #*****************************************************************************
17 #*****************************************************************************
18
18
19 from IPython import Release
19 from IPython import Release
20 __author__ = '%s <%s>' % Release.authors['Fernando']
20 __author__ = '%s <%s>' % Release.authors['Fernando']
21 __license__ = Release.license
21 __license__ = Release.license
22
22
23 __all__ = ['Inspector','InspectColors']
23 __all__ = ['Inspector','InspectColors']
24
24
25 # stdlib modules
25 # stdlib modules
26 import __builtin__
26 import __builtin__
27 import StringIO
27 import inspect
28 import inspect
28 import linecache
29 import linecache
29 import string
30 import StringIO
31 import types
32 import os
30 import os
31 import string
33 import sys
32 import sys
33 import types
34
34 # IPython's own
35 # IPython's own
35 from IPython import PyColorize
36 from IPython import PyColorize
36 from IPython.genutils import page,indent,Term,mkdict
37 from IPython.genutils import page,indent,Term
37 from IPython.Itpl import itpl
38 from IPython.Itpl import itpl
38 from IPython.wildcard import list_namespace
39 from IPython.wildcard import list_namespace
39 from IPython.ColorANSI import *
40 from IPython.ColorANSI import *
40
41
41 #****************************************************************************
42 #****************************************************************************
42 # HACK!!! This is a crude fix for bugs in python 2.3's inspect module. We
43 # HACK!!! This is a crude fix for bugs in python 2.3's inspect module. We
43 # simply monkeypatch inspect with code copied from python 2.4.
44 # simply monkeypatch inspect with code copied from python 2.4.
44 if sys.version_info[:2] == (2,3):
45 if sys.version_info[:2] == (2,3):
45 from inspect import ismodule, getabsfile, modulesbyfile
46 from inspect import ismodule, getabsfile, modulesbyfile
46 def getmodule(object):
47 def getmodule(object):
47 """Return the module an object was defined in, or None if not found."""
48 """Return the module an object was defined in, or None if not found."""
48 if ismodule(object):
49 if ismodule(object):
49 return object
50 return object
50 if hasattr(object, '__module__'):
51 if hasattr(object, '__module__'):
51 return sys.modules.get(object.__module__)
52 return sys.modules.get(object.__module__)
52 try:
53 try:
53 file = getabsfile(object)
54 file = getabsfile(object)
54 except TypeError:
55 except TypeError:
55 return None
56 return None
56 if file in modulesbyfile:
57 if file in modulesbyfile:
57 return sys.modules.get(modulesbyfile[file])
58 return sys.modules.get(modulesbyfile[file])
58 for module in sys.modules.values():
59 for module in sys.modules.values():
59 if hasattr(module, '__file__'):
60 if hasattr(module, '__file__'):
60 modulesbyfile[
61 modulesbyfile[
61 os.path.realpath(
62 os.path.realpath(
62 getabsfile(module))] = module.__name__
63 getabsfile(module))] = module.__name__
63 if file in modulesbyfile:
64 if file in modulesbyfile:
64 return sys.modules.get(modulesbyfile[file])
65 return sys.modules.get(modulesbyfile[file])
65 main = sys.modules['__main__']
66 main = sys.modules['__main__']
66 if not hasattr(object, '__name__'):
67 if not hasattr(object, '__name__'):
67 return None
68 return None
68 if hasattr(main, object.__name__):
69 if hasattr(main, object.__name__):
69 mainobject = getattr(main, object.__name__)
70 mainobject = getattr(main, object.__name__)
70 if mainobject is object:
71 if mainobject is object:
71 return main
72 return main
72 builtin = sys.modules['__builtin__']
73 builtin = sys.modules['__builtin__']
73 if hasattr(builtin, object.__name__):
74 if hasattr(builtin, object.__name__):
74 builtinobject = getattr(builtin, object.__name__)
75 builtinobject = getattr(builtin, object.__name__)
75 if builtinobject is object:
76 if builtinobject is object:
76 return builtin
77 return builtin
77
78
78 inspect.getmodule = getmodule
79 inspect.getmodule = getmodule
79
80
80 #****************************************************************************
81 #****************************************************************************
81 # Builtin color schemes
82 # Builtin color schemes
82
83
83 Colors = TermColors # just a shorthand
84 Colors = TermColors # just a shorthand
84
85
85 # Build a few color schemes
86 # Build a few color schemes
86 NoColor = ColorScheme(
87 NoColor = ColorScheme(
87 'NoColor',{
88 'NoColor',{
88 'header' : Colors.NoColor,
89 'header' : Colors.NoColor,
89 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
90 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
90 } )
91 } )
91
92
92 LinuxColors = ColorScheme(
93 LinuxColors = ColorScheme(
93 'Linux',{
94 'Linux',{
94 'header' : Colors.LightRed,
95 'header' : Colors.LightRed,
95 'normal' : Colors.Normal # color off (usu. Colors.Normal)
96 'normal' : Colors.Normal # color off (usu. Colors.Normal)
96 } )
97 } )
97
98
98 LightBGColors = ColorScheme(
99 LightBGColors = ColorScheme(
99 'LightBG',{
100 'LightBG',{
100 'header' : Colors.Red,
101 'header' : Colors.Red,
101 'normal' : Colors.Normal # color off (usu. Colors.Normal)
102 'normal' : Colors.Normal # color off (usu. Colors.Normal)
102 } )
103 } )
103
104
104 # Build table of color schemes (needed by the parser)
105 # Build table of color schemes (needed by the parser)
105 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
106 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
106 'Linux')
107 'Linux')
107
108
108 #****************************************************************************
109 #****************************************************************************
109 # Auxiliary functions
110 # Auxiliary functions
110 def getdoc(obj):
111 def getdoc(obj):
111 """Stable wrapper around inspect.getdoc.
112 """Stable wrapper around inspect.getdoc.
112
113
113 This can't crash because of attribute problems.
114 This can't crash because of attribute problems.
114
115
115 It also attempts to call a getdoc() method on the given object. This
116 It also attempts to call a getdoc() method on the given object. This
116 allows objects which provide their docstrings via non-standard mechanisms
117 allows objects which provide their docstrings via non-standard mechanisms
117 (like Pyro proxies) to still be inspected by ipython's ? system."""
118 (like Pyro proxies) to still be inspected by ipython's ? system."""
118
119
119 ds = None # default return value
120 ds = None # default return value
120 try:
121 try:
121 ds = inspect.getdoc(obj)
122 ds = inspect.getdoc(obj)
122 except:
123 except:
123 # Harden against an inspect failure, which can occur with
124 # Harden against an inspect failure, which can occur with
124 # SWIG-wrapped extensions.
125 # SWIG-wrapped extensions.
125 pass
126 pass
126 # Allow objects to offer customized documentation via a getdoc method:
127 # Allow objects to offer customized documentation via a getdoc method:
127 try:
128 try:
128 ds2 = obj.getdoc()
129 ds2 = obj.getdoc()
129 except:
130 except:
130 pass
131 pass
131 else:
132 else:
132 # if we get extra info, we add it to the normal docstring.
133 # if we get extra info, we add it to the normal docstring.
133 if ds is None:
134 if ds is None:
134 ds = ds2
135 ds = ds2
135 else:
136 else:
136 ds = '%s\n%s' % (ds,ds2)
137 ds = '%s\n%s' % (ds,ds2)
137 return ds
138 return ds
138
139
140
139 def getsource(obj,is_binary=False):
141 def getsource(obj,is_binary=False):
140 """Wrapper around inspect.getsource.
142 """Wrapper around inspect.getsource.
141
143
142 This can be modified by other projects to provide customized source
144 This can be modified by other projects to provide customized source
143 extraction.
145 extraction.
144
146
145 Inputs:
147 Inputs:
146
148
147 - obj: an object whose source code we will attempt to extract.
149 - obj: an object whose source code we will attempt to extract.
148
150
149 Optional inputs:
151 Optional inputs:
150
152
151 - is_binary: whether the object is known to come from a binary source.
153 - is_binary: whether the object is known to come from a binary source.
152 This implementation will skip returning any output for binary objects, but
154 This implementation will skip returning any output for binary objects, but
153 custom extractors may know how to meaningfully process them."""
155 custom extractors may know how to meaningfully process them."""
154
156
155 if is_binary:
157 if is_binary:
156 return None
158 return None
157 else:
159 else:
158 try:
160 try:
159 src = inspect.getsource(obj)
161 src = inspect.getsource(obj)
160 except TypeError:
162 except TypeError:
161 if hasattr(obj,'__class__'):
163 if hasattr(obj,'__class__'):
162 src = inspect.getsource(obj.__class__)
164 src = inspect.getsource(obj.__class__)
163 return src
165 return src
164
166
165 #****************************************************************************
167 def getargspec(obj):
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):
185 """Get the names and default values of a function's arguments.
168 """Get the names and default values of a function's arguments.
186
169
187 A tuple of four things is returned: (args, varargs, varkw, defaults).
170 A tuple of four things is returned: (args, varargs, varkw, defaults).
188 'args' is a list of the argument names (it may contain nested lists).
171 'args' is a list of the argument names (it may contain nested lists).
189 'varargs' and 'varkw' are the names of the * and ** arguments or None.
172 'varargs' and 'varkw' are the names of the * and ** arguments or None.
190 'defaults' is an n-tuple of the default values of the last n arguments.
173 'defaults' is an n-tuple of the default values of the last n arguments.
191
174
192 Modified version of inspect.getargspec from the Python Standard
175 Modified version of inspect.getargspec from the Python Standard
193 Library."""
176 Library."""
194
177
195 if inspect.isfunction(obj):
178 if inspect.isfunction(obj):
196 func_obj = obj
179 func_obj = obj
197 elif inspect.ismethod(obj):
180 elif inspect.ismethod(obj):
198 func_obj = obj.im_func
181 func_obj = obj.im_func
199 else:
182 else:
200 raise TypeError, 'arg is not a Python function'
183 raise TypeError, 'arg is not a Python function'
201 args, varargs, varkw = inspect.getargs(func_obj.func_code)
184 args, varargs, varkw = inspect.getargs(func_obj.func_code)
202 return args, varargs, varkw, func_obj.func_defaults
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 def __getdef(self,obj,oname=''):
207 def __getdef(self,obj,oname=''):
205 """Return the definition header for any callable object.
208 """Return the definition header for any callable object.
206
209
207 If any exception is generated, None is returned instead and the
210 If any exception is generated, None is returned instead and the
208 exception is suppressed."""
211 exception is suppressed."""
209
212
210 try:
213 try:
211 return oname + inspect.formatargspec(*self.__getargspec(obj))
214 return oname + inspect.formatargspec(*getargspec(obj))
212 except:
215 except:
213 return None
216 return None
214
217
215 def __head(self,h):
218 def __head(self,h):
216 """Return a header string with proper colors."""
219 """Return a header string with proper colors."""
217 return '%s%s%s' % (self.color_table.active_colors.header,h,
220 return '%s%s%s' % (self.color_table.active_colors.header,h,
218 self.color_table.active_colors.normal)
221 self.color_table.active_colors.normal)
219
222
220 def set_active_scheme(self,scheme):
223 def set_active_scheme(self,scheme):
221 self.color_table.set_active_scheme(scheme)
224 self.color_table.set_active_scheme(scheme)
222 self.parser.color_table.set_active_scheme(scheme)
225 self.parser.color_table.set_active_scheme(scheme)
223
226
224 def noinfo(self,msg,oname):
227 def noinfo(self,msg,oname):
225 """Generic message when no information is found."""
228 """Generic message when no information is found."""
226 print 'No %s found' % msg,
229 print 'No %s found' % msg,
227 if oname:
230 if oname:
228 print 'for %s' % oname
231 print 'for %s' % oname
229 else:
232 else:
230 print
233 print
231
234
232 def pdef(self,obj,oname=''):
235 def pdef(self,obj,oname=''):
233 """Print the definition header for any callable object.
236 """Print the definition header for any callable object.
234
237
235 If the object is a class, print the constructor information."""
238 If the object is a class, print the constructor information."""
236
239
237 if not callable(obj):
240 if not callable(obj):
238 print 'Object is not callable.'
241 print 'Object is not callable.'
239 return
242 return
240
243
241 header = ''
244 header = ''
242
245
243 if inspect.isclass(obj):
246 if inspect.isclass(obj):
244 header = self.__head('Class constructor information:\n')
247 header = self.__head('Class constructor information:\n')
245 obj = obj.__init__
248 obj = obj.__init__
246 elif type(obj) is types.InstanceType:
249 elif type(obj) is types.InstanceType:
247 obj = obj.__call__
250 obj = obj.__call__
248
251
249 output = self.__getdef(obj,oname)
252 output = self.__getdef(obj,oname)
250 if output is None:
253 if output is None:
251 self.noinfo('definition header',oname)
254 self.noinfo('definition header',oname)
252 else:
255 else:
253 print >>Term.cout, header,self.format(output),
256 print >>Term.cout, header,self.format(output),
254
257
255 def pdoc(self,obj,oname='',formatter = None):
258 def pdoc(self,obj,oname='',formatter = None):
256 """Print the docstring for any object.
259 """Print the docstring for any object.
257
260
258 Optional:
261 Optional:
259 -formatter: a function to run the docstring through for specially
262 -formatter: a function to run the docstring through for specially
260 formatted docstrings."""
263 formatted docstrings."""
261
264
262 head = self.__head # so that itpl can find it even if private
265 head = self.__head # so that itpl can find it even if private
263 ds = getdoc(obj)
266 ds = getdoc(obj)
264 if formatter:
267 if formatter:
265 ds = formatter(ds)
268 ds = formatter(ds)
266 if inspect.isclass(obj):
269 if inspect.isclass(obj):
267 init_ds = getdoc(obj.__init__)
270 init_ds = getdoc(obj.__init__)
268 output = itpl('$head("Class Docstring:")\n'
271 output = itpl('$head("Class Docstring:")\n'
269 '$indent(ds)\n'
272 '$indent(ds)\n'
270 '$head("Constructor Docstring"):\n'
273 '$head("Constructor Docstring"):\n'
271 '$indent(init_ds)')
274 '$indent(init_ds)')
272 elif (type(obj) is types.InstanceType or isinstance(obj,object)) \
275 elif (type(obj) is types.InstanceType or isinstance(obj,object)) \
273 and hasattr(obj,'__call__'):
276 and hasattr(obj,'__call__'):
274 call_ds = getdoc(obj.__call__)
277 call_ds = getdoc(obj.__call__)
275 if call_ds:
278 if call_ds:
276 output = itpl('$head("Class Docstring:")\n$indent(ds)\n'
279 output = itpl('$head("Class Docstring:")\n$indent(ds)\n'
277 '$head("Calling Docstring:")\n$indent(call_ds)')
280 '$head("Calling Docstring:")\n$indent(call_ds)')
278 else:
281 else:
279 output = ds
282 output = ds
280 else:
283 else:
281 output = ds
284 output = ds
282 if output is None:
285 if output is None:
283 self.noinfo('documentation',oname)
286 self.noinfo('documentation',oname)
284 return
287 return
285 page(output)
288 page(output)
286
289
287 def psource(self,obj,oname=''):
290 def psource(self,obj,oname=''):
288 """Print the source code for an object."""
291 """Print the source code for an object."""
289
292
290 # Flush the source cache because inspect can return out-of-date source
293 # Flush the source cache because inspect can return out-of-date source
291 linecache.checkcache()
294 linecache.checkcache()
292 try:
295 try:
293 src = getsource(obj)
296 src = getsource(obj)
294 except:
297 except:
295 self.noinfo('source',oname)
298 self.noinfo('source',oname)
296 else:
299 else:
297 page(self.format(src))
300 page(self.format(src))
298
301
299 def pfile(self,obj,oname=''):
302 def pfile(self,obj,oname=''):
300 """Show the whole file where an object was defined."""
303 """Show the whole file where an object was defined."""
301
304
302 try:
305 try:
303 try:
306 try:
304 lineno = inspect.getsourcelines(obj)[1]
307 lineno = inspect.getsourcelines(obj)[1]
305 except TypeError:
308 except TypeError:
306 # For instances, try the class object like getsource() does
309 # For instances, try the class object like getsource() does
307 if hasattr(obj,'__class__'):
310 if hasattr(obj,'__class__'):
308 lineno = inspect.getsourcelines(obj.__class__)[1]
311 lineno = inspect.getsourcelines(obj.__class__)[1]
309 # Adjust the inspected object so getabsfile() below works
312 # Adjust the inspected object so getabsfile() below works
310 obj = obj.__class__
313 obj = obj.__class__
311 except:
314 except:
312 self.noinfo('file',oname)
315 self.noinfo('file',oname)
313 return
316 return
314
317
315 # We only reach this point if object was successfully queried
318 # We only reach this point if object was successfully queried
316
319
317 # run contents of file through pager starting at line
320 # run contents of file through pager starting at line
318 # where the object is defined
321 # where the object is defined
319 ofile = inspect.getabsfile(obj)
322 ofile = inspect.getabsfile(obj)
320
323
321 if (ofile.endswith('.so') or ofile.endswith('.dll')):
324 if (ofile.endswith('.so') or ofile.endswith('.dll')):
322 print 'File %r is binary, not printing.' % ofile
325 print 'File %r is binary, not printing.' % ofile
323 elif not os.path.isfile(ofile):
326 elif not os.path.isfile(ofile):
324 print 'File %r does not exist, not printing.' % ofile
327 print 'File %r does not exist, not printing.' % ofile
325 else:
328 else:
326 # Print only text files, not extension binaries. Note that
329 # Print only text files, not extension binaries. Note that
327 # getsourcelines returns lineno with 1-offset and page() uses
330 # getsourcelines returns lineno with 1-offset and page() uses
328 # 0-offset, so we must adjust.
331 # 0-offset, so we must adjust.
329 page(self.format(open(ofile).read()),lineno-1)
332 page(self.format(open(ofile).read()),lineno-1)
330
333
331 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
334 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
332 """Show detailed information about an object.
335 """Show detailed information about an object.
333
336
334 Optional arguments:
337 Optional arguments:
335
338
336 - oname: name of the variable pointing to the object.
339 - oname: name of the variable pointing to the object.
337
340
338 - formatter: special formatter for docstrings (see pdoc)
341 - formatter: special formatter for docstrings (see pdoc)
339
342
340 - info: a structure with some information fields which may have been
343 - info: a structure with some information fields which may have been
341 precomputed already.
344 precomputed already.
342
345
343 - detail_level: if set to 1, more information is given.
346 - detail_level: if set to 1, more information is given.
344 """
347 """
345
348
346 obj_type = type(obj)
349 obj_type = type(obj)
347
350
348 header = self.__head
351 header = self.__head
349 if info is None:
352 if info is None:
350 ismagic = 0
353 ismagic = 0
351 isalias = 0
354 isalias = 0
352 ospace = ''
355 ospace = ''
353 else:
356 else:
354 ismagic = info.ismagic
357 ismagic = info.ismagic
355 isalias = info.isalias
358 isalias = info.isalias
356 ospace = info.namespace
359 ospace = info.namespace
357 # Get docstring, special-casing aliases:
360 # Get docstring, special-casing aliases:
358 if isalias:
361 if isalias:
359 if not callable(obj):
362 if not callable(obj):
360 try:
363 try:
361 ds = "Alias to the system command:\n %s" % obj[1]
364 ds = "Alias to the system command:\n %s" % obj[1]
362 except:
365 except:
363 ds = "Alias: " + str(obj)
366 ds = "Alias: " + str(obj)
364 else:
367 else:
365 ds = "Alias to " + str(obj)
368 ds = "Alias to " + str(obj)
366 if obj.__doc__:
369 if obj.__doc__:
367 ds += "\nDocstring:\n" + obj.__doc__
370 ds += "\nDocstring:\n" + obj.__doc__
368 else:
371 else:
369 ds = getdoc(obj)
372 ds = getdoc(obj)
370 if ds is None:
373 if ds is None:
371 ds = '<no docstring>'
374 ds = '<no docstring>'
372 if formatter is not None:
375 if formatter is not None:
373 ds = formatter(ds)
376 ds = formatter(ds)
374
377
375 # store output in a list which gets joined with \n at the end.
378 # store output in a list which gets joined with \n at the end.
376 out = myStringIO()
379 out = myStringIO()
377
380
378 string_max = 200 # max size of strings to show (snipped if longer)
381 string_max = 200 # max size of strings to show (snipped if longer)
379 shalf = int((string_max -5)/2)
382 shalf = int((string_max -5)/2)
380
383
381 if ismagic:
384 if ismagic:
382 obj_type_name = 'Magic function'
385 obj_type_name = 'Magic function'
383 elif isalias:
386 elif isalias:
384 obj_type_name = 'System alias'
387 obj_type_name = 'System alias'
385 else:
388 else:
386 obj_type_name = obj_type.__name__
389 obj_type_name = obj_type.__name__
387 out.writeln(header('Type:\t\t')+obj_type_name)
390 out.writeln(header('Type:\t\t')+obj_type_name)
388
391
389 try:
392 try:
390 bclass = obj.__class__
393 bclass = obj.__class__
391 out.writeln(header('Base Class:\t')+str(bclass))
394 out.writeln(header('Base Class:\t')+str(bclass))
392 except: pass
395 except: pass
393
396
394 # String form, but snip if too long in ? form (full in ??)
397 # String form, but snip if too long in ? form (full in ??)
395 if detail_level >= self.str_detail_level:
398 if detail_level >= self.str_detail_level:
396 try:
399 try:
397 ostr = str(obj)
400 ostr = str(obj)
398 str_head = 'String Form:'
401 str_head = 'String Form:'
399 if not detail_level and len(ostr)>string_max:
402 if not detail_level and len(ostr)>string_max:
400 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
403 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
401 ostr = ("\n" + " " * len(str_head.expandtabs())).\
404 ostr = ("\n" + " " * len(str_head.expandtabs())).\
402 join(map(string.strip,ostr.split("\n")))
405 join(map(string.strip,ostr.split("\n")))
403 if ostr.find('\n') > -1:
406 if ostr.find('\n') > -1:
404 # Print multi-line strings starting at the next line.
407 # Print multi-line strings starting at the next line.
405 str_sep = '\n'
408 str_sep = '\n'
406 else:
409 else:
407 str_sep = '\t'
410 str_sep = '\t'
408 out.writeln("%s%s%s" % (header(str_head),str_sep,ostr))
411 out.writeln("%s%s%s" % (header(str_head),str_sep,ostr))
409 except:
412 except:
410 pass
413 pass
411
414
412 if ospace:
415 if ospace:
413 out.writeln(header('Namespace:\t')+ospace)
416 out.writeln(header('Namespace:\t')+ospace)
414
417
415 # Length (for strings and lists)
418 # Length (for strings and lists)
416 try:
419 try:
417 length = str(len(obj))
420 length = str(len(obj))
418 out.writeln(header('Length:\t\t')+length)
421 out.writeln(header('Length:\t\t')+length)
419 except: pass
422 except: pass
420
423
421 # Filename where object was defined
424 # Filename where object was defined
422 binary_file = False
425 binary_file = False
423 try:
426 try:
424 try:
427 try:
425 fname = inspect.getabsfile(obj)
428 fname = inspect.getabsfile(obj)
426 except TypeError:
429 except TypeError:
427 # For an instance, the file that matters is where its class was
430 # For an instance, the file that matters is where its class was
428 # declared.
431 # declared.
429 if hasattr(obj,'__class__'):
432 if hasattr(obj,'__class__'):
430 fname = inspect.getabsfile(obj.__class__)
433 fname = inspect.getabsfile(obj.__class__)
431 if fname.endswith('<string>'):
434 if fname.endswith('<string>'):
432 fname = 'Dynamically generated function. No source code available.'
435 fname = 'Dynamically generated function. No source code available.'
433 if (fname.endswith('.so') or fname.endswith('.dll')):
436 if (fname.endswith('.so') or fname.endswith('.dll')):
434 binary_file = True
437 binary_file = True
435 out.writeln(header('File:\t\t')+fname)
438 out.writeln(header('File:\t\t')+fname)
436 except:
439 except:
437 # if anything goes wrong, we don't want to show source, so it's as
440 # if anything goes wrong, we don't want to show source, so it's as
438 # if the file was binary
441 # if the file was binary
439 binary_file = True
442 binary_file = True
440
443
441 # reconstruct the function definition and print it:
444 # reconstruct the function definition and print it:
442 defln = self.__getdef(obj,oname)
445 defln = self.__getdef(obj,oname)
443 if defln:
446 if defln:
444 out.write(header('Definition:\t')+self.format(defln))
447 out.write(header('Definition:\t')+self.format(defln))
445
448
446 # Docstrings only in detail 0 mode, since source contains them (we
449 # Docstrings only in detail 0 mode, since source contains them (we
447 # avoid repetitions). If source fails, we add them back, see below.
450 # avoid repetitions). If source fails, we add them back, see below.
448 if ds and detail_level == 0:
451 if ds and detail_level == 0:
449 out.writeln(header('Docstring:\n') + indent(ds))
452 out.writeln(header('Docstring:\n') + indent(ds))
450
453
451 # Original source code for any callable
454 # Original source code for any callable
452 if detail_level:
455 if detail_level:
453 # Flush the source cache because inspect can return out-of-date
456 # Flush the source cache because inspect can return out-of-date
454 # source
457 # source
455 linecache.checkcache()
458 linecache.checkcache()
456 source_success = False
459 source_success = False
457 try:
460 try:
458 try:
461 try:
459 src = getsource(obj,binary_file)
462 src = getsource(obj,binary_file)
460 except TypeError:
463 except TypeError:
461 if hasattr(obj,'__class__'):
464 if hasattr(obj,'__class__'):
462 src = getsource(obj.__class__,binary_file)
465 src = getsource(obj.__class__,binary_file)
463 if src is not None:
466 if src is not None:
464 source = self.format(src)
467 source = self.format(src)
465 out.write(header('Source:\n')+source.rstrip())
468 out.write(header('Source:\n')+source.rstrip())
466 source_success = True
469 source_success = True
467 except Exception, msg:
470 except Exception, msg:
468 pass
471 pass
469
472
470 if ds and not source_success:
473 if ds and not source_success:
471 out.writeln(header('Docstring [source file open failed]:\n')
474 out.writeln(header('Docstring [source file open failed]:\n')
472 + indent(ds))
475 + indent(ds))
473
476
474 # Constructor docstring for classes
477 # Constructor docstring for classes
475 if inspect.isclass(obj):
478 if inspect.isclass(obj):
476 # reconstruct the function definition and print it:
479 # reconstruct the function definition and print it:
477 try:
480 try:
478 obj_init = obj.__init__
481 obj_init = obj.__init__
479 except AttributeError:
482 except AttributeError:
480 init_def = init_ds = None
483 init_def = init_ds = None
481 else:
484 else:
482 init_def = self.__getdef(obj_init,oname)
485 init_def = self.__getdef(obj_init,oname)
483 init_ds = getdoc(obj_init)
486 init_ds = getdoc(obj_init)
484 # Skip Python's auto-generated docstrings
487 # Skip Python's auto-generated docstrings
485 if init_ds and \
488 if init_ds and \
486 init_ds.startswith('x.__init__(...) initializes'):
489 init_ds.startswith('x.__init__(...) initializes'):
487 init_ds = None
490 init_ds = None
488
491
489 if init_def or init_ds:
492 if init_def or init_ds:
490 out.writeln(header('\nConstructor information:'))
493 out.writeln(header('\nConstructor information:'))
491 if init_def:
494 if init_def:
492 out.write(header('Definition:\t')+ self.format(init_def))
495 out.write(header('Definition:\t')+ self.format(init_def))
493 if init_ds:
496 if init_ds:
494 out.writeln(header('Docstring:\n') + indent(init_ds))
497 out.writeln(header('Docstring:\n') + indent(init_ds))
495 # and class docstring for instances:
498 # and class docstring for instances:
496 elif obj_type is types.InstanceType or \
499 elif obj_type is types.InstanceType or \
497 isinstance(obj,object):
500 isinstance(obj,object):
498
501
499 # First, check whether the instance docstring is identical to the
502 # First, check whether the instance docstring is identical to the
500 # class one, and print it separately if they don't coincide. In
503 # class one, and print it separately if they don't coincide. In
501 # most cases they will, but it's nice to print all the info for
504 # most cases they will, but it's nice to print all the info for
502 # objects which use instance-customized docstrings.
505 # objects which use instance-customized docstrings.
503 if ds:
506 if ds:
504 try:
507 try:
505 cls = getattr(obj,'__class__')
508 cls = getattr(obj,'__class__')
506 except:
509 except:
507 class_ds = None
510 class_ds = None
508 else:
511 else:
509 class_ds = getdoc(cls)
512 class_ds = getdoc(cls)
510 # Skip Python's auto-generated docstrings
513 # Skip Python's auto-generated docstrings
511 if class_ds and \
514 if class_ds and \
512 (class_ds.startswith('function(code, globals[,') or \
515 (class_ds.startswith('function(code, globals[,') or \
513 class_ds.startswith('instancemethod(function, instance,') or \
516 class_ds.startswith('instancemethod(function, instance,') or \
514 class_ds.startswith('module(name[,') ):
517 class_ds.startswith('module(name[,') ):
515 class_ds = None
518 class_ds = None
516 if class_ds and ds != class_ds:
519 if class_ds and ds != class_ds:
517 out.writeln(header('Class Docstring:\n') +
520 out.writeln(header('Class Docstring:\n') +
518 indent(class_ds))
521 indent(class_ds))
519
522
520 # Next, try to show constructor docstrings
523 # Next, try to show constructor docstrings
521 try:
524 try:
522 init_ds = getdoc(obj.__init__)
525 init_ds = getdoc(obj.__init__)
523 # Skip Python's auto-generated docstrings
526 # Skip Python's auto-generated docstrings
524 if init_ds and \
527 if init_ds and \
525 init_ds.startswith('x.__init__(...) initializes'):
528 init_ds.startswith('x.__init__(...) initializes'):
526 init_ds = None
529 init_ds = None
527 except AttributeError:
530 except AttributeError:
528 init_ds = None
531 init_ds = None
529 if init_ds:
532 if init_ds:
530 out.writeln(header('Constructor Docstring:\n') +
533 out.writeln(header('Constructor Docstring:\n') +
531 indent(init_ds))
534 indent(init_ds))
532
535
533 # Call form docstring for callable instances
536 # Call form docstring for callable instances
534 if hasattr(obj,'__call__'):
537 if hasattr(obj,'__call__'):
535 #out.writeln(header('Callable:\t')+'Yes')
538 #out.writeln(header('Callable:\t')+'Yes')
536 call_def = self.__getdef(obj.__call__,oname)
539 call_def = self.__getdef(obj.__call__,oname)
537 #if call_def is None:
540 #if call_def is None:
538 # out.writeln(header('Call def:\t')+
541 # out.writeln(header('Call def:\t')+
539 # 'Calling definition not available.')
542 # 'Calling definition not available.')
540 if call_def is not None:
543 if call_def is not None:
541 out.writeln(header('Call def:\t')+self.format(call_def))
544 out.writeln(header('Call def:\t')+self.format(call_def))
542 call_ds = getdoc(obj.__call__)
545 call_ds = getdoc(obj.__call__)
543 # Skip Python's auto-generated docstrings
546 # Skip Python's auto-generated docstrings
544 if call_ds and call_ds.startswith('x.__call__(...) <==> x(...)'):
547 if call_ds and call_ds.startswith('x.__call__(...) <==> x(...)'):
545 call_ds = None
548 call_ds = None
546 if call_ds:
549 if call_ds:
547 out.writeln(header('Call docstring:\n') + indent(call_ds))
550 out.writeln(header('Call docstring:\n') + indent(call_ds))
548
551
549 # Finally send to printer/pager
552 # Finally send to printer/pager
550 output = out.getvalue()
553 output = out.getvalue()
551 if output:
554 if output:
552 page(output)
555 page(output)
553 # end pinfo
556 # end pinfo
554
557
555 def psearch(self,pattern,ns_table,ns_search=[],
558 def psearch(self,pattern,ns_table,ns_search=[],
556 ignore_case=False,show_all=False):
559 ignore_case=False,show_all=False):
557 """Search namespaces with wildcards for objects.
560 """Search namespaces with wildcards for objects.
558
561
559 Arguments:
562 Arguments:
560
563
561 - pattern: string containing shell-like wildcards to use in namespace
564 - pattern: string containing shell-like wildcards to use in namespace
562 searches and optionally a type specification to narrow the search to
565 searches and optionally a type specification to narrow the search to
563 objects of that type.
566 objects of that type.
564
567
565 - ns_table: dict of name->namespaces for search.
568 - ns_table: dict of name->namespaces for search.
566
569
567 Optional arguments:
570 Optional arguments:
568
571
569 - ns_search: list of namespace names to include in search.
572 - ns_search: list of namespace names to include in search.
570
573
571 - ignore_case(False): make the search case-insensitive.
574 - ignore_case(False): make the search case-insensitive.
572
575
573 - show_all(False): show all names, including those starting with
576 - show_all(False): show all names, including those starting with
574 underscores.
577 underscores.
575 """
578 """
576 #print 'ps pattern:<%r>' % pattern # dbg
579 #print 'ps pattern:<%r>' % pattern # dbg
577
580
578 # defaults
581 # defaults
579 type_pattern = 'all'
582 type_pattern = 'all'
580 filter = ''
583 filter = ''
581
584
582 cmds = pattern.split()
585 cmds = pattern.split()
583 len_cmds = len(cmds)
586 len_cmds = len(cmds)
584 if len_cmds == 1:
587 if len_cmds == 1:
585 # Only filter pattern given
588 # Only filter pattern given
586 filter = cmds[0]
589 filter = cmds[0]
587 elif len_cmds == 2:
590 elif len_cmds == 2:
588 # Both filter and type specified
591 # Both filter and type specified
589 filter,type_pattern = cmds
592 filter,type_pattern = cmds
590 else:
593 else:
591 raise ValueError('invalid argument string for psearch: <%s>' %
594 raise ValueError('invalid argument string for psearch: <%s>' %
592 pattern)
595 pattern)
593
596
594 # filter search namespaces
597 # filter search namespaces
595 for name in ns_search:
598 for name in ns_search:
596 if name not in ns_table:
599 if name not in ns_table:
597 raise ValueError('invalid namespace <%s>. Valid names: %s' %
600 raise ValueError('invalid namespace <%s>. Valid names: %s' %
598 (name,ns_table.keys()))
601 (name,ns_table.keys()))
599
602
600 #print 'type_pattern:',type_pattern # dbg
603 #print 'type_pattern:',type_pattern # dbg
601 search_result = []
604 search_result = []
602 for ns_name in ns_search:
605 for ns_name in ns_search:
603 ns = ns_table[ns_name]
606 ns = ns_table[ns_name]
604 tmp_res = list(list_namespace(ns,type_pattern,filter,
607 tmp_res = list(list_namespace(ns,type_pattern,filter,
605 ignore_case=ignore_case,
608 ignore_case=ignore_case,
606 show_all=show_all))
609 show_all=show_all))
607 search_result.extend(tmp_res)
610 search_result.extend(tmp_res)
608 search_result.sort()
611 search_result.sort()
609
612
610 page('\n'.join(search_result))
613 page('\n'.join(search_result))
@@ -1,1236 +1,1236 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """IPython Shell classes.
2 """IPython Shell classes.
3
3
4 All the matplotlib support code was co-developed with John Hunter,
4 All the matplotlib support code was co-developed with John Hunter,
5 matplotlib's author.
5 matplotlib's author.
6
6
7 $Id: Shell.py 3024 2008-02-07 15:34:42Z darren.dale $"""
7 $Id: Shell.py 3024 2008-02-07 15:34:42Z darren.dale $"""
8
8
9 #*****************************************************************************
9 #*****************************************************************************
10 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
10 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
11 #
11 #
12 # Distributed under the terms of the BSD License. The full license is in
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
13 # the file COPYING, distributed as part of this software.
14 #*****************************************************************************
14 #*****************************************************************************
15
15
16 from IPython import Release
16 from IPython import Release
17 __author__ = '%s <%s>' % Release.authors['Fernando']
17 __author__ = '%s <%s>' % Release.authors['Fernando']
18 __license__ = Release.license
18 __license__ = Release.license
19
19
20 # Code begins
20 # Code begins
21 # Stdlib imports
21 # Stdlib imports
22 import __builtin__
22 import __builtin__
23 import __main__
23 import __main__
24 import Queue
24 import Queue
25 import inspect
25 import inspect
26 import os
26 import os
27 import sys
27 import sys
28 import thread
28 import thread
29 import threading
29 import threading
30 import time
30 import time
31
31
32 from signal import signal, SIGINT
32 from signal import signal, SIGINT
33
33
34 try:
34 try:
35 import ctypes
35 import ctypes
36 HAS_CTYPES = True
36 HAS_CTYPES = True
37 except ImportError:
37 except ImportError:
38 HAS_CTYPES = False
38 HAS_CTYPES = False
39
39
40 # IPython imports
40 # IPython imports
41 import IPython
41 import IPython
42 from IPython import ultraTB, ipapi
42 from IPython import ultraTB, ipapi
43 from IPython.genutils import Term,warn,error,flag_calls, ask_yes_no
43 from IPython.genutils import Term,warn,error,flag_calls, ask_yes_no
44 from IPython.iplib import InteractiveShell
44 from IPython.iplib import InteractiveShell
45 from IPython.ipmaker import make_IPython
45 from IPython.ipmaker import make_IPython
46 from IPython.Magic import Magic
46 from IPython.Magic import Magic
47 from IPython.ipstruct import Struct
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 # Globals
49 # Globals
57 # global flag to pass around information about Ctrl-C without exceptions
50 # global flag to pass around information about Ctrl-C without exceptions
58 KBINT = False
51 KBINT = False
59
52
60 # global flag to turn on/off Tk support.
53 # global flag to turn on/off Tk support.
61 USE_TK = False
54 USE_TK = False
62
55
63 # ID for the main thread, used for cross-thread exceptions
56 # ID for the main thread, used for cross-thread exceptions
64 MAIN_THREAD_ID = thread.get_ident()
57 MAIN_THREAD_ID = thread.get_ident()
65
58
66 # Tag when runcode() is active, for exception handling
59 # Tag when runcode() is active, for exception handling
67 CODE_RUN = None
60 CODE_RUN = None
68
61
62 # Default timeout for waiting for multithreaded shells (in seconds)
63 GUI_TIMEOUT = 10
64
69 #-----------------------------------------------------------------------------
65 #-----------------------------------------------------------------------------
70 # This class is trivial now, but I want to have it in to publish a clean
66 # This class is trivial now, but I want to have it in to publish a clean
71 # interface. Later when the internals are reorganized, code that uses this
67 # interface. Later when the internals are reorganized, code that uses this
72 # shouldn't have to change.
68 # shouldn't have to change.
73
69
74 class IPShell:
70 class IPShell:
75 """Create an IPython instance."""
71 """Create an IPython instance."""
76
72
77 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
73 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
78 debug=1,shell_class=InteractiveShell):
74 debug=1,shell_class=InteractiveShell):
79 self.IP = make_IPython(argv,user_ns=user_ns,
75 self.IP = make_IPython(argv,user_ns=user_ns,
80 user_global_ns=user_global_ns,
76 user_global_ns=user_global_ns,
81 debug=debug,shell_class=shell_class)
77 debug=debug,shell_class=shell_class)
82
78
83 def mainloop(self,sys_exit=0,banner=None):
79 def mainloop(self,sys_exit=0,banner=None):
84 self.IP.mainloop(banner)
80 self.IP.mainloop(banner)
85 if sys_exit:
81 if sys_exit:
86 sys.exit()
82 sys.exit()
87
83
88 #-----------------------------------------------------------------------------
84 #-----------------------------------------------------------------------------
89 def kill_embedded(self,parameter_s=''):
85 def kill_embedded(self,parameter_s=''):
90 """%kill_embedded : deactivate for good the current embedded IPython.
86 """%kill_embedded : deactivate for good the current embedded IPython.
91
87
92 This function (after asking for confirmation) sets an internal flag so that
88 This function (after asking for confirmation) sets an internal flag so that
93 an embedded IPython will never activate again. This is useful to
89 an embedded IPython will never activate again. This is useful to
94 permanently disable a shell that is being called inside a loop: once you've
90 permanently disable a shell that is being called inside a loop: once you've
95 figured out what you needed from it, you may then kill it and the program
91 figured out what you needed from it, you may then kill it and the program
96 will then continue to run without the interactive shell interfering again.
92 will then continue to run without the interactive shell interfering again.
97 """
93 """
98
94
99 kill = ask_yes_no("Are you sure you want to kill this embedded instance "
95 kill = ask_yes_no("Are you sure you want to kill this embedded instance "
100 "(y/n)? [y/N] ",'n')
96 "(y/n)? [y/N] ",'n')
101 if kill:
97 if kill:
102 self.shell.embedded_active = False
98 self.shell.embedded_active = False
103 print "This embedded IPython will not reactivate anymore once you exit."
99 print "This embedded IPython will not reactivate anymore once you exit."
104
100
105 class IPShellEmbed:
101 class IPShellEmbed:
106 """Allow embedding an IPython shell into a running program.
102 """Allow embedding an IPython shell into a running program.
107
103
108 Instances of this class are callable, with the __call__ method being an
104 Instances of this class are callable, with the __call__ method being an
109 alias to the embed() method of an InteractiveShell instance.
105 alias to the embed() method of an InteractiveShell instance.
110
106
111 Usage (see also the example-embed.py file for a running example):
107 Usage (see also the example-embed.py file for a running example):
112
108
113 ipshell = IPShellEmbed([argv,banner,exit_msg,rc_override])
109 ipshell = IPShellEmbed([argv,banner,exit_msg,rc_override])
114
110
115 - argv: list containing valid command-line options for IPython, as they
111 - argv: list containing valid command-line options for IPython, as they
116 would appear in sys.argv[1:].
112 would appear in sys.argv[1:].
117
113
118 For example, the following command-line options:
114 For example, the following command-line options:
119
115
120 $ ipython -prompt_in1 'Input <\\#>' -colors LightBG
116 $ ipython -prompt_in1 'Input <\\#>' -colors LightBG
121
117
122 would be passed in the argv list as:
118 would be passed in the argv list as:
123
119
124 ['-prompt_in1','Input <\\#>','-colors','LightBG']
120 ['-prompt_in1','Input <\\#>','-colors','LightBG']
125
121
126 - banner: string which gets printed every time the interpreter starts.
122 - banner: string which gets printed every time the interpreter starts.
127
123
128 - exit_msg: string which gets printed every time the interpreter exits.
124 - exit_msg: string which gets printed every time the interpreter exits.
129
125
130 - rc_override: a dict or Struct of configuration options such as those
126 - rc_override: a dict or Struct of configuration options such as those
131 used by IPython. These options are read from your ~/.ipython/ipythonrc
127 used by IPython. These options are read from your ~/.ipython/ipythonrc
132 file when the Shell object is created. Passing an explicit rc_override
128 file when the Shell object is created. Passing an explicit rc_override
133 dict with any options you want allows you to override those values at
129 dict with any options you want allows you to override those values at
134 creation time without having to modify the file. This way you can create
130 creation time without having to modify the file. This way you can create
135 embeddable instances configured in any way you want without editing any
131 embeddable instances configured in any way you want without editing any
136 global files (thus keeping your interactive IPython configuration
132 global files (thus keeping your interactive IPython configuration
137 unchanged).
133 unchanged).
138
134
139 Then the ipshell instance can be called anywhere inside your code:
135 Then the ipshell instance can be called anywhere inside your code:
140
136
141 ipshell(header='') -> Opens up an IPython shell.
137 ipshell(header='') -> Opens up an IPython shell.
142
138
143 - header: string printed by the IPython shell upon startup. This can let
139 - header: string printed by the IPython shell upon startup. This can let
144 you know where in your code you are when dropping into the shell. Note
140 you know where in your code you are when dropping into the shell. Note
145 that 'banner' gets prepended to all calls, so header is used for
141 that 'banner' gets prepended to all calls, so header is used for
146 location-specific information.
142 location-specific information.
147
143
148 For more details, see the __call__ method below.
144 For more details, see the __call__ method below.
149
145
150 When the IPython shell is exited with Ctrl-D, normal program execution
146 When the IPython shell is exited with Ctrl-D, normal program execution
151 resumes.
147 resumes.
152
148
153 This functionality was inspired by a posting on comp.lang.python by cmkl
149 This functionality was inspired by a posting on comp.lang.python by cmkl
154 <cmkleffner@gmx.de> on Dec. 06/01 concerning similar uses of pyrepl, and
150 <cmkleffner@gmx.de> on Dec. 06/01 concerning similar uses of pyrepl, and
155 by the IDL stop/continue commands."""
151 by the IDL stop/continue commands."""
156
152
157 def __init__(self,argv=None,banner='',exit_msg=None,rc_override=None,
153 def __init__(self,argv=None,banner='',exit_msg=None,rc_override=None,
158 user_ns=None):
154 user_ns=None):
159 """Note that argv here is a string, NOT a list."""
155 """Note that argv here is a string, NOT a list."""
160 self.set_banner(banner)
156 self.set_banner(banner)
161 self.set_exit_msg(exit_msg)
157 self.set_exit_msg(exit_msg)
162 self.set_dummy_mode(0)
158 self.set_dummy_mode(0)
163
159
164 # sys.displayhook is a global, we need to save the user's original
160 # sys.displayhook is a global, we need to save the user's original
165 # Don't rely on __displayhook__, as the user may have changed that.
161 # Don't rely on __displayhook__, as the user may have changed that.
166 self.sys_displayhook_ori = sys.displayhook
162 self.sys_displayhook_ori = sys.displayhook
167
163
168 # save readline completer status
164 # save readline completer status
169 try:
165 try:
170 #print 'Save completer',sys.ipcompleter # dbg
166 #print 'Save completer',sys.ipcompleter # dbg
171 self.sys_ipcompleter_ori = sys.ipcompleter
167 self.sys_ipcompleter_ori = sys.ipcompleter
172 except:
168 except:
173 pass # not nested with IPython
169 pass # not nested with IPython
174
170
175 self.IP = make_IPython(argv,rc_override=rc_override,
171 self.IP = make_IPython(argv,rc_override=rc_override,
176 embedded=True,
172 embedded=True,
177 user_ns=user_ns)
173 user_ns=user_ns)
178
174
179 ip = ipapi.IPApi(self.IP)
175 ip = ipapi.IPApi(self.IP)
180 ip.expose_magic("kill_embedded",kill_embedded)
176 ip.expose_magic("kill_embedded",kill_embedded)
181
177
182 # copy our own displayhook also
178 # copy our own displayhook also
183 self.sys_displayhook_embed = sys.displayhook
179 self.sys_displayhook_embed = sys.displayhook
184 # and leave the system's display hook clean
180 # and leave the system's display hook clean
185 sys.displayhook = self.sys_displayhook_ori
181 sys.displayhook = self.sys_displayhook_ori
186 # don't use the ipython crash handler so that user exceptions aren't
182 # don't use the ipython crash handler so that user exceptions aren't
187 # trapped
183 # trapped
188 sys.excepthook = ultraTB.FormattedTB(color_scheme = self.IP.rc.colors,
184 sys.excepthook = ultraTB.FormattedTB(color_scheme = self.IP.rc.colors,
189 mode = self.IP.rc.xmode,
185 mode = self.IP.rc.xmode,
190 call_pdb = self.IP.rc.pdb)
186 call_pdb = self.IP.rc.pdb)
191 self.restore_system_completer()
187 self.restore_system_completer()
192
188
193 def restore_system_completer(self):
189 def restore_system_completer(self):
194 """Restores the readline completer which was in place.
190 """Restores the readline completer which was in place.
195
191
196 This allows embedded IPython within IPython not to disrupt the
192 This allows embedded IPython within IPython not to disrupt the
197 parent's completion.
193 parent's completion.
198 """
194 """
199
195
200 try:
196 try:
201 self.IP.readline.set_completer(self.sys_ipcompleter_ori)
197 self.IP.readline.set_completer(self.sys_ipcompleter_ori)
202 sys.ipcompleter = self.sys_ipcompleter_ori
198 sys.ipcompleter = self.sys_ipcompleter_ori
203 except:
199 except:
204 pass
200 pass
205
201
206 def __call__(self,header='',local_ns=None,global_ns=None,dummy=None):
202 def __call__(self,header='',local_ns=None,global_ns=None,dummy=None):
207 """Activate the interactive interpreter.
203 """Activate the interactive interpreter.
208
204
209 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
205 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
210 the interpreter shell with the given local and global namespaces, and
206 the interpreter shell with the given local and global namespaces, and
211 optionally print a header string at startup.
207 optionally print a header string at startup.
212
208
213 The shell can be globally activated/deactivated using the
209 The shell can be globally activated/deactivated using the
214 set/get_dummy_mode methods. This allows you to turn off a shell used
210 set/get_dummy_mode methods. This allows you to turn off a shell used
215 for debugging globally.
211 for debugging globally.
216
212
217 However, *each* time you call the shell you can override the current
213 However, *each* time you call the shell you can override the current
218 state of dummy_mode with the optional keyword parameter 'dummy'. For
214 state of dummy_mode with the optional keyword parameter 'dummy'. For
219 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
215 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
220 can still have a specific call work by making it as IPShell(dummy=0).
216 can still have a specific call work by making it as IPShell(dummy=0).
221
217
222 The optional keyword parameter dummy controls whether the call
218 The optional keyword parameter dummy controls whether the call
223 actually does anything. """
219 actually does anything. """
224
220
225 # If the user has turned it off, go away
221 # If the user has turned it off, go away
226 if not self.IP.embedded_active:
222 if not self.IP.embedded_active:
227 return
223 return
228
224
229 # Normal exits from interactive mode set this flag, so the shell can't
225 # Normal exits from interactive mode set this flag, so the shell can't
230 # re-enter (it checks this variable at the start of interactive mode).
226 # re-enter (it checks this variable at the start of interactive mode).
231 self.IP.exit_now = False
227 self.IP.exit_now = False
232
228
233 # Allow the dummy parameter to override the global __dummy_mode
229 # Allow the dummy parameter to override the global __dummy_mode
234 if dummy or (dummy != 0 and self.__dummy_mode):
230 if dummy or (dummy != 0 and self.__dummy_mode):
235 return
231 return
236
232
237 # Set global subsystems (display,completions) to our values
233 # Set global subsystems (display,completions) to our values
238 sys.displayhook = self.sys_displayhook_embed
234 sys.displayhook = self.sys_displayhook_embed
239 if self.IP.has_readline:
235 if self.IP.has_readline:
240 self.IP.set_completer()
236 self.IP.set_completer()
241
237
242 if self.banner and header:
238 if self.banner and header:
243 format = '%s\n%s\n'
239 format = '%s\n%s\n'
244 else:
240 else:
245 format = '%s%s\n'
241 format = '%s%s\n'
246 banner = format % (self.banner,header)
242 banner = format % (self.banner,header)
247
243
248 # Call the embedding code with a stack depth of 1 so it can skip over
244 # Call the embedding code with a stack depth of 1 so it can skip over
249 # our call and get the original caller's namespaces.
245 # our call and get the original caller's namespaces.
250 self.IP.embed_mainloop(banner,local_ns,global_ns,stack_depth=1)
246 self.IP.embed_mainloop(banner,local_ns,global_ns,stack_depth=1)
251
247
252 if self.exit_msg:
248 if self.exit_msg:
253 print self.exit_msg
249 print self.exit_msg
254
250
255 # Restore global systems (display, completion)
251 # Restore global systems (display, completion)
256 sys.displayhook = self.sys_displayhook_ori
252 sys.displayhook = self.sys_displayhook_ori
257 self.restore_system_completer()
253 self.restore_system_completer()
258
254
259 def set_dummy_mode(self,dummy):
255 def set_dummy_mode(self,dummy):
260 """Sets the embeddable shell's dummy mode parameter.
256 """Sets the embeddable shell's dummy mode parameter.
261
257
262 set_dummy_mode(dummy): dummy = 0 or 1.
258 set_dummy_mode(dummy): dummy = 0 or 1.
263
259
264 This parameter is persistent and makes calls to the embeddable shell
260 This parameter is persistent and makes calls to the embeddable shell
265 silently return without performing any action. This allows you to
261 silently return without performing any action. This allows you to
266 globally activate or deactivate a shell you're using with a single call.
262 globally activate or deactivate a shell you're using with a single call.
267
263
268 If you need to manually"""
264 If you need to manually"""
269
265
270 if dummy not in [0,1,False,True]:
266 if dummy not in [0,1,False,True]:
271 raise ValueError,'dummy parameter must be boolean'
267 raise ValueError,'dummy parameter must be boolean'
272 self.__dummy_mode = dummy
268 self.__dummy_mode = dummy
273
269
274 def get_dummy_mode(self):
270 def get_dummy_mode(self):
275 """Return the current value of the dummy mode parameter.
271 """Return the current value of the dummy mode parameter.
276 """
272 """
277 return self.__dummy_mode
273 return self.__dummy_mode
278
274
279 def set_banner(self,banner):
275 def set_banner(self,banner):
280 """Sets the global banner.
276 """Sets the global banner.
281
277
282 This banner gets prepended to every header printed when the shell
278 This banner gets prepended to every header printed when the shell
283 instance is called."""
279 instance is called."""
284
280
285 self.banner = banner
281 self.banner = banner
286
282
287 def set_exit_msg(self,exit_msg):
283 def set_exit_msg(self,exit_msg):
288 """Sets the global exit_msg.
284 """Sets the global exit_msg.
289
285
290 This exit message gets printed upon exiting every time the embedded
286 This exit message gets printed upon exiting every time the embedded
291 shell is called. It is None by default. """
287 shell is called. It is None by default. """
292
288
293 self.exit_msg = exit_msg
289 self.exit_msg = exit_msg
294
290
295 #-----------------------------------------------------------------------------
291 #-----------------------------------------------------------------------------
296 if HAS_CTYPES:
292 if HAS_CTYPES:
297 # Add async exception support. Trick taken from:
293 # Add async exception support. Trick taken from:
298 # http://sebulba.wikispaces.com/recipe+thread2
294 # http://sebulba.wikispaces.com/recipe+thread2
299 def _async_raise(tid, exctype):
295 def _async_raise(tid, exctype):
300 """raises the exception, performs cleanup if needed"""
296 """raises the exception, performs cleanup if needed"""
301 if not inspect.isclass(exctype):
297 if not inspect.isclass(exctype):
302 raise TypeError("Only types can be raised (not instances)")
298 raise TypeError("Only types can be raised (not instances)")
303 res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,
299 res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,
304 ctypes.py_object(exctype))
300 ctypes.py_object(exctype))
305 if res == 0:
301 if res == 0:
306 raise ValueError("invalid thread id")
302 raise ValueError("invalid thread id")
307 elif res != 1:
303 elif res != 1:
308 # """if it returns a number greater than one, you're in trouble,
304 # """if it returns a number greater than one, you're in trouble,
309 # and you should call it again with exc=NULL to revert the effect"""
305 # and you should call it again with exc=NULL to revert the effect"""
310 ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
306 ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
311 raise SystemError("PyThreadState_SetAsyncExc failed")
307 raise SystemError("PyThreadState_SetAsyncExc failed")
312
308
313 def sigint_handler (signum,stack_frame):
309 def sigint_handler (signum,stack_frame):
314 """Sigint handler for threaded apps.
310 """Sigint handler for threaded apps.
315
311
316 This is a horrible hack to pass information about SIGINT _without_
312 This is a horrible hack to pass information about SIGINT _without_
317 using exceptions, since I haven't been able to properly manage
313 using exceptions, since I haven't been able to properly manage
318 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
314 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
319 done (or at least that's my understanding from a c.l.py thread where
315 done (or at least that's my understanding from a c.l.py thread where
320 this was discussed)."""
316 this was discussed)."""
321
317
322 global KBINT
318 global KBINT
323
319
324 if CODE_RUN:
320 if CODE_RUN:
325 _async_raise(MAIN_THREAD_ID,KeyboardInterrupt)
321 _async_raise(MAIN_THREAD_ID,KeyboardInterrupt)
326 else:
322 else:
327 KBINT = True
323 KBINT = True
328 print '\nKeyboardInterrupt - Press <Enter> to continue.',
324 print '\nKeyboardInterrupt - Press <Enter> to continue.',
329 Term.cout.flush()
325 Term.cout.flush()
330
326
331 else:
327 else:
332 def sigint_handler (signum,stack_frame):
328 def sigint_handler (signum,stack_frame):
333 """Sigint handler for threaded apps.
329 """Sigint handler for threaded apps.
334
330
335 This is a horrible hack to pass information about SIGINT _without_
331 This is a horrible hack to pass information about SIGINT _without_
336 using exceptions, since I haven't been able to properly manage
332 using exceptions, since I haven't been able to properly manage
337 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
333 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
338 done (or at least that's my understanding from a c.l.py thread where
334 done (or at least that's my understanding from a c.l.py thread where
339 this was discussed)."""
335 this was discussed)."""
340
336
341 global KBINT
337 global KBINT
342
338
343 print '\nKeyboardInterrupt - Press <Enter> to continue.',
339 print '\nKeyboardInterrupt - Press <Enter> to continue.',
344 Term.cout.flush()
340 Term.cout.flush()
345 # Set global flag so that runsource can know that Ctrl-C was hit
341 # Set global flag so that runsource can know that Ctrl-C was hit
346 KBINT = True
342 KBINT = True
347
343
348
344
349 class MTInteractiveShell(InteractiveShell):
345 class MTInteractiveShell(InteractiveShell):
350 """Simple multi-threaded shell."""
346 """Simple multi-threaded shell."""
351
347
352 # Threading strategy taken from:
348 # Threading strategy taken from:
353 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109, by Brian
349 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109, by Brian
354 # McErlean and John Finlay. Modified with corrections by Antoon Pardon,
350 # McErlean and John Finlay. Modified with corrections by Antoon Pardon,
355 # from the pygtk mailing list, to avoid lockups with system calls.
351 # from the pygtk mailing list, to avoid lockups with system calls.
356
352
357 # class attribute to indicate whether the class supports threads or not.
353 # class attribute to indicate whether the class supports threads or not.
358 # Subclasses with thread support should override this as needed.
354 # Subclasses with thread support should override this as needed.
359 isthreaded = True
355 isthreaded = True
360
356
361 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
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 """Similar to the normal InteractiveShell, but with threading control"""
360 """Similar to the normal InteractiveShell, but with threading control"""
364
361
365 InteractiveShell.__init__(self,name,usage,rc,user_ns,
362 InteractiveShell.__init__(self,name,usage,rc,user_ns,
366 user_global_ns,banner2)
363 user_global_ns,banner2)
367
364
365 # Timeout we wait for GUI thread
366 self.gui_timeout = gui_timeout
368
367
369 # A queue to hold the code to be executed.
368 # A queue to hold the code to be executed.
370 self.code_queue = Queue.Queue()
369 self.code_queue = Queue.Queue()
371
370
372 # Stuff to do at closing time
371 # Stuff to do at closing time
373 self._kill = None
372 self._kill = None
374 on_kill = kw.get('on_kill', [])
373 on_kill = kw.get('on_kill', [])
375 # Check that all things to kill are callable:
374 # Check that all things to kill are callable:
376 for t in on_kill:
375 for t in on_kill:
377 if not callable(t):
376 if not callable(t):
378 raise TypeError,'on_kill must be a list of callables'
377 raise TypeError,'on_kill must be a list of callables'
379 self.on_kill = on_kill
378 self.on_kill = on_kill
380 # thread identity of the "worker thread" (that may execute code directly)
379 # thread identity of the "worker thread" (that may execute code directly)
381 self.worker_ident = None
380 self.worker_ident = None
382
381
383 def runsource(self, source, filename="<input>", symbol="single"):
382 def runsource(self, source, filename="<input>", symbol="single"):
384 """Compile and run some source in the interpreter.
383 """Compile and run some source in the interpreter.
385
384
386 Modified version of code.py's runsource(), to handle threading issues.
385 Modified version of code.py's runsource(), to handle threading issues.
387 See the original for full docstring details."""
386 See the original for full docstring details."""
388
387
389 global KBINT
388 global KBINT
390
389
391 # If Ctrl-C was typed, we reset the flag and return right away
390 # If Ctrl-C was typed, we reset the flag and return right away
392 if KBINT:
391 if KBINT:
393 KBINT = False
392 KBINT = False
394 return False
393 return False
395
394
396 if self._kill:
395 if self._kill:
397 # can't queue new code if we are being killed
396 # can't queue new code if we are being killed
398 return True
397 return True
399
398
400 try:
399 try:
401 code = self.compile(source, filename, symbol)
400 code = self.compile(source, filename, symbol)
402 except (OverflowError, SyntaxError, ValueError):
401 except (OverflowError, SyntaxError, ValueError):
403 # Case 1
402 # Case 1
404 self.showsyntaxerror(filename)
403 self.showsyntaxerror(filename)
405 return False
404 return False
406
405
407 if code is None:
406 if code is None:
408 # Case 2
407 # Case 2
409 return True
408 return True
410
409
411 # shortcut - if we are in worker thread, or the worker thread is not running,
410 # shortcut - if we are in worker thread, or the worker thread is not
412 # execute directly (to allow recursion and prevent deadlock if code is run early
411 # running, execute directly (to allow recursion and prevent deadlock if
413 # in IPython construction)
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 InteractiveShell.runcode(self,code)
416 InteractiveShell.runcode(self,code)
417 return
417 return
418
418
419 # Case 3
419 # Case 3
420 # Store code in queue, so the execution thread can handle it.
420 # Store code in queue, so the execution thread can handle it.
421
421
422 completed_ev, received_ev = threading.Event(), threading.Event()
422 completed_ev, received_ev = threading.Event(), threading.Event()
423
423
424 self.code_queue.put((code,completed_ev, received_ev))
424 self.code_queue.put((code,completed_ev, received_ev))
425 # first make sure the message was received, with timeout
425 # first make sure the message was received, with timeout
426 received_ev.wait(5)
426 received_ev.wait(self.gui_timeout)
427 if not received_ev.isSet():
427 if not received_ev.isSet():
428 # the mainloop is dead, start executing code directly
428 # the mainloop is dead, start executing code directly
429 print "Warning: Timeout for mainloop thread exceeded"
429 print "Warning: Timeout for mainloop thread exceeded"
430 print "switching to nonthreaded mode (until mainloop wakes up again)"
430 print "switching to nonthreaded mode (until mainloop wakes up again)"
431 self.worker_ident = None
431 self.worker_ident = None
432 else:
432 else:
433 completed_ev.wait()
433 completed_ev.wait()
434 return False
434 return False
435
435
436 def runcode(self):
436 def runcode(self):
437 """Execute a code object.
437 """Execute a code object.
438
438
439 Multithreaded wrapper around IPython's runcode()."""
439 Multithreaded wrapper around IPython's runcode()."""
440
440
441 global CODE_RUN
441 global CODE_RUN
442
442
443 # we are in worker thread, stash out the id for runsource()
443 # we are in worker thread, stash out the id for runsource()
444 self.worker_ident = thread.get_ident()
444 self.worker_ident = thread.get_ident()
445
445
446 if self._kill:
446 if self._kill:
447 print >>Term.cout, 'Closing threads...',
447 print >>Term.cout, 'Closing threads...',
448 Term.cout.flush()
448 Term.cout.flush()
449 for tokill in self.on_kill:
449 for tokill in self.on_kill:
450 tokill()
450 tokill()
451 print >>Term.cout, 'Done.'
451 print >>Term.cout, 'Done.'
452 # allow kill() to return
452 # allow kill() to return
453 self._kill.set()
453 self._kill.set()
454 return True
454 return True
455
455
456 # Install sigint handler. We do it every time to ensure that if user
456 # Install sigint handler. We do it every time to ensure that if user
457 # code modifies it, we restore our own handling.
457 # code modifies it, we restore our own handling.
458 try:
458 try:
459 signal(SIGINT,sigint_handler)
459 signal(SIGINT,sigint_handler)
460 except SystemError:
460 except SystemError:
461 # This happens under Windows, which seems to have all sorts
461 # This happens under Windows, which seems to have all sorts
462 # of problems with signal handling. Oh well...
462 # of problems with signal handling. Oh well...
463 pass
463 pass
464
464
465 # Flush queue of pending code by calling the run methood of the parent
465 # Flush queue of pending code by calling the run methood of the parent
466 # class with all items which may be in the queue.
466 # class with all items which may be in the queue.
467 code_to_run = None
467 code_to_run = None
468 while 1:
468 while 1:
469 try:
469 try:
470 code_to_run, completed_ev, received_ev = self.code_queue.get_nowait()
470 code_to_run, completed_ev, received_ev = self.code_queue.get_nowait()
471 except Queue.Empty:
471 except Queue.Empty:
472 break
472 break
473 received_ev.set()
473 received_ev.set()
474
474
475 # Exceptions need to be raised differently depending on which
475 # Exceptions need to be raised differently depending on which
476 # thread is active. This convoluted try/except is only there to
476 # thread is active. This convoluted try/except is only there to
477 # protect against asynchronous exceptions, to ensure that a KBINT
477 # protect against asynchronous exceptions, to ensure that a KBINT
478 # at the wrong time doesn't deadlock everything. The global
478 # at the wrong time doesn't deadlock everything. The global
479 # CODE_TO_RUN is set to true/false as close as possible to the
479 # CODE_TO_RUN is set to true/false as close as possible to the
480 # runcode() call, so that the KBINT handler is correctly informed.
480 # runcode() call, so that the KBINT handler is correctly informed.
481 try:
481 try:
482 try:
482 try:
483 CODE_RUN = True
483 CODE_RUN = True
484 InteractiveShell.runcode(self,code_to_run)
484 InteractiveShell.runcode(self,code_to_run)
485 except KeyboardInterrupt:
485 except KeyboardInterrupt:
486 print "Keyboard interrupted in mainloop"
486 print "Keyboard interrupted in mainloop"
487 while not self.code_queue.empty():
487 while not self.code_queue.empty():
488 code, ev1,ev2 = self.code_queue.get_nowait()
488 code, ev1,ev2 = self.code_queue.get_nowait()
489 ev1.set()
489 ev1.set()
490 ev2.set()
490 ev2.set()
491 break
491 break
492 finally:
492 finally:
493 CODE_RUN = False
493 CODE_RUN = False
494 # allow runsource() return from wait
494 # allow runsource() return from wait
495 completed_ev.set()
495 completed_ev.set()
496
496
497
497
498 # This MUST return true for gtk threading to work
498 # This MUST return true for gtk threading to work
499 return True
499 return True
500
500
501 def kill(self):
501 def kill(self):
502 """Kill the thread, returning when it has been shut down."""
502 """Kill the thread, returning when it has been shut down."""
503 self._kill = threading.Event()
503 self._kill = threading.Event()
504 self._kill.wait()
504 self._kill.wait()
505
505
506 class MatplotlibShellBase:
506 class MatplotlibShellBase:
507 """Mixin class to provide the necessary modifications to regular IPython
507 """Mixin class to provide the necessary modifications to regular IPython
508 shell classes for matplotlib support.
508 shell classes for matplotlib support.
509
509
510 Given Python's MRO, this should be used as the FIRST class in the
510 Given Python's MRO, this should be used as the FIRST class in the
511 inheritance hierarchy, so that it overrides the relevant methods."""
511 inheritance hierarchy, so that it overrides the relevant methods."""
512
512
513 def _matplotlib_config(self,name,user_ns,user_global_ns=None):
513 def _matplotlib_config(self,name,user_ns,user_global_ns=None):
514 """Return items needed to setup the user's shell with matplotlib"""
514 """Return items needed to setup the user's shell with matplotlib"""
515
515
516 # Initialize matplotlib to interactive mode always
516 # Initialize matplotlib to interactive mode always
517 import matplotlib
517 import matplotlib
518 from matplotlib import backends
518 from matplotlib import backends
519 matplotlib.interactive(True)
519 matplotlib.interactive(True)
520
520
521 def use(arg):
521 def use(arg):
522 """IPython wrapper for matplotlib's backend switcher.
522 """IPython wrapper for matplotlib's backend switcher.
523
523
524 In interactive use, we can not allow switching to a different
524 In interactive use, we can not allow switching to a different
525 interactive backend, since thread conflicts will most likely crash
525 interactive backend, since thread conflicts will most likely crash
526 the python interpreter. This routine does a safety check first,
526 the python interpreter. This routine does a safety check first,
527 and refuses to perform a dangerous switch. It still allows
527 and refuses to perform a dangerous switch. It still allows
528 switching to non-interactive backends."""
528 switching to non-interactive backends."""
529
529
530 if arg in backends.interactive_bk and arg != self.mpl_backend:
530 if arg in backends.interactive_bk and arg != self.mpl_backend:
531 m=('invalid matplotlib backend switch.\n'
531 m=('invalid matplotlib backend switch.\n'
532 'This script attempted to switch to the interactive '
532 'This script attempted to switch to the interactive '
533 'backend: `%s`\n'
533 'backend: `%s`\n'
534 'Your current choice of interactive backend is: `%s`\n\n'
534 'Your current choice of interactive backend is: `%s`\n\n'
535 'Switching interactive matplotlib backends at runtime\n'
535 'Switching interactive matplotlib backends at runtime\n'
536 'would crash the python interpreter, '
536 'would crash the python interpreter, '
537 'and IPython has blocked it.\n\n'
537 'and IPython has blocked it.\n\n'
538 'You need to either change your choice of matplotlib backend\n'
538 'You need to either change your choice of matplotlib backend\n'
539 'by editing your .matplotlibrc file, or run this script as a \n'
539 'by editing your .matplotlibrc file, or run this script as a \n'
540 'standalone file from the command line, not using IPython.\n' %
540 'standalone file from the command line, not using IPython.\n' %
541 (arg,self.mpl_backend) )
541 (arg,self.mpl_backend) )
542 raise RuntimeError, m
542 raise RuntimeError, m
543 else:
543 else:
544 self.mpl_use(arg)
544 self.mpl_use(arg)
545 self.mpl_use._called = True
545 self.mpl_use._called = True
546
546
547 self.matplotlib = matplotlib
547 self.matplotlib = matplotlib
548 self.mpl_backend = matplotlib.rcParams['backend']
548 self.mpl_backend = matplotlib.rcParams['backend']
549
549
550 # we also need to block switching of interactive backends by use()
550 # we also need to block switching of interactive backends by use()
551 self.mpl_use = matplotlib.use
551 self.mpl_use = matplotlib.use
552 self.mpl_use._called = False
552 self.mpl_use._called = False
553 # overwrite the original matplotlib.use with our wrapper
553 # overwrite the original matplotlib.use with our wrapper
554 matplotlib.use = use
554 matplotlib.use = use
555
555
556 # This must be imported last in the matplotlib series, after
556 # This must be imported last in the matplotlib series, after
557 # backend/interactivity choices have been made
557 # backend/interactivity choices have been made
558 import matplotlib.pylab as pylab
558 import matplotlib.pylab as pylab
559 self.pylab = pylab
559 self.pylab = pylab
560
560
561 self.pylab.show._needmain = False
561 self.pylab.show._needmain = False
562 # We need to detect at runtime whether show() is called by the user.
562 # We need to detect at runtime whether show() is called by the user.
563 # For this, we wrap it into a decorator which adds a 'called' flag.
563 # For this, we wrap it into a decorator which adds a 'called' flag.
564 self.pylab.draw_if_interactive = flag_calls(self.pylab.draw_if_interactive)
564 self.pylab.draw_if_interactive = flag_calls(self.pylab.draw_if_interactive)
565
565
566 # Build a user namespace initialized with matplotlib/matlab features.
566 # Build a user namespace initialized with matplotlib/matlab features.
567 user_ns, user_global_ns = IPython.ipapi.make_user_namespaces(user_ns,
567 user_ns, user_global_ns = IPython.ipapi.make_user_namespaces(user_ns,
568 user_global_ns)
568 user_global_ns)
569
569
570 # Import numpy as np/pyplot as plt are conventions we're trying to
570 # Import numpy as np/pyplot as plt are conventions we're trying to
571 # somewhat standardize on. Making them available to users by default
571 # somewhat standardize on. Making them available to users by default
572 # will greatly help this.
572 # will greatly help this.
573 exec ("import numpy\n"
573 exec ("import numpy\n"
574 "import numpy as np\n"
574 "import numpy as np\n"
575 "import matplotlib\n"
575 "import matplotlib\n"
576 "import matplotlib.pylab as pylab\n"
576 "import matplotlib.pylab as pylab\n"
577 "try:\n"
577 "try:\n"
578 " import matplotlib.pyplot as plt\n"
578 " import matplotlib.pyplot as plt\n"
579 "except ImportError:\n"
579 "except ImportError:\n"
580 " pass\n"
580 " pass\n"
581 ) in user_ns
581 ) in user_ns
582
582
583 # Build matplotlib info banner
583 # Build matplotlib info banner
584 b="""
584 b="""
585 Welcome to pylab, a matplotlib-based Python environment.
585 Welcome to pylab, a matplotlib-based Python environment.
586 For more information, type 'help(pylab)'.
586 For more information, type 'help(pylab)'.
587 """
587 """
588 return user_ns,user_global_ns,b
588 return user_ns,user_global_ns,b
589
589
590 def mplot_exec(self,fname,*where,**kw):
590 def mplot_exec(self,fname,*where,**kw):
591 """Execute a matplotlib script.
591 """Execute a matplotlib script.
592
592
593 This is a call to execfile(), but wrapped in safeties to properly
593 This is a call to execfile(), but wrapped in safeties to properly
594 handle interactive rendering and backend switching."""
594 handle interactive rendering and backend switching."""
595
595
596 #print '*** Matplotlib runner ***' # dbg
596 #print '*** Matplotlib runner ***' # dbg
597 # turn off rendering until end of script
597 # turn off rendering until end of script
598 isInteractive = self.matplotlib.rcParams['interactive']
598 isInteractive = self.matplotlib.rcParams['interactive']
599 self.matplotlib.interactive(False)
599 self.matplotlib.interactive(False)
600 self.safe_execfile(fname,*where,**kw)
600 self.safe_execfile(fname,*where,**kw)
601 self.matplotlib.interactive(isInteractive)
601 self.matplotlib.interactive(isInteractive)
602 # make rendering call now, if the user tried to do it
602 # make rendering call now, if the user tried to do it
603 if self.pylab.draw_if_interactive.called:
603 if self.pylab.draw_if_interactive.called:
604 self.pylab.draw()
604 self.pylab.draw()
605 self.pylab.draw_if_interactive.called = False
605 self.pylab.draw_if_interactive.called = False
606
606
607 # if a backend switch was performed, reverse it now
607 # if a backend switch was performed, reverse it now
608 if self.mpl_use._called:
608 if self.mpl_use._called:
609 self.matplotlib.rcParams['backend'] = self.mpl_backend
609 self.matplotlib.rcParams['backend'] = self.mpl_backend
610
610
611 def magic_run(self,parameter_s=''):
611 def magic_run(self,parameter_s=''):
612 Magic.magic_run(self,parameter_s,runner=self.mplot_exec)
612 Magic.magic_run(self,parameter_s,runner=self.mplot_exec)
613
613
614 # Fix the docstring so users see the original as well
614 # Fix the docstring so users see the original as well
615 magic_run.__doc__ = "%s\n%s" % (Magic.magic_run.__doc__,
615 magic_run.__doc__ = "%s\n%s" % (Magic.magic_run.__doc__,
616 "\n *** Modified %run for Matplotlib,"
616 "\n *** Modified %run for Matplotlib,"
617 " with proper interactive handling ***")
617 " with proper interactive handling ***")
618
618
619 # Now we provide 2 versions of a matplotlib-aware IPython base shells, single
619 # Now we provide 2 versions of a matplotlib-aware IPython base shells, single
620 # and multithreaded. Note that these are meant for internal use, the IPShell*
620 # and multithreaded. Note that these are meant for internal use, the IPShell*
621 # classes below are the ones meant for public consumption.
621 # classes below are the ones meant for public consumption.
622
622
623 class MatplotlibShell(MatplotlibShellBase,InteractiveShell):
623 class MatplotlibShell(MatplotlibShellBase,InteractiveShell):
624 """Single-threaded shell with matplotlib support."""
624 """Single-threaded shell with matplotlib support."""
625
625
626 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
626 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
627 user_ns=None,user_global_ns=None,**kw):
627 user_ns=None,user_global_ns=None,**kw):
628 user_ns,user_global_ns,b2 = self._matplotlib_config(name,user_ns,user_global_ns)
628 user_ns,user_global_ns,b2 = self._matplotlib_config(name,user_ns,user_global_ns)
629 InteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
629 InteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
630 banner2=b2,**kw)
630 banner2=b2,**kw)
631
631
632 class MatplotlibMTShell(MatplotlibShellBase,MTInteractiveShell):
632 class MatplotlibMTShell(MatplotlibShellBase,MTInteractiveShell):
633 """Multi-threaded shell with matplotlib support."""
633 """Multi-threaded shell with matplotlib support."""
634
634
635 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
635 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
636 user_ns=None,user_global_ns=None, **kw):
636 user_ns=None,user_global_ns=None, **kw):
637 user_ns,user_global_ns,b2 = self._matplotlib_config(name,user_ns,user_global_ns)
637 user_ns,user_global_ns,b2 = self._matplotlib_config(name,user_ns,user_global_ns)
638 MTInteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
638 MTInteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
639 banner2=b2,**kw)
639 banner2=b2,**kw)
640
640
641 #-----------------------------------------------------------------------------
641 #-----------------------------------------------------------------------------
642 # Utility functions for the different GUI enabled IPShell* classes.
642 # Utility functions for the different GUI enabled IPShell* classes.
643
643
644 def get_tk():
644 def get_tk():
645 """Tries to import Tkinter and returns a withdrawn Tkinter root
645 """Tries to import Tkinter and returns a withdrawn Tkinter root
646 window. If Tkinter is already imported or not available, this
646 window. If Tkinter is already imported or not available, this
647 returns None. This function calls `hijack_tk` underneath.
647 returns None. This function calls `hijack_tk` underneath.
648 """
648 """
649 if not USE_TK or sys.modules.has_key('Tkinter'):
649 if not USE_TK or sys.modules.has_key('Tkinter'):
650 return None
650 return None
651 else:
651 else:
652 try:
652 try:
653 import Tkinter
653 import Tkinter
654 except ImportError:
654 except ImportError:
655 return None
655 return None
656 else:
656 else:
657 hijack_tk()
657 hijack_tk()
658 r = Tkinter.Tk()
658 r = Tkinter.Tk()
659 r.withdraw()
659 r.withdraw()
660 return r
660 return r
661
661
662 def hijack_tk():
662 def hijack_tk():
663 """Modifies Tkinter's mainloop with a dummy so when a module calls
663 """Modifies Tkinter's mainloop with a dummy so when a module calls
664 mainloop, it does not block.
664 mainloop, it does not block.
665
665
666 """
666 """
667 def misc_mainloop(self, n=0):
667 def misc_mainloop(self, n=0):
668 pass
668 pass
669 def tkinter_mainloop(n=0):
669 def tkinter_mainloop(n=0):
670 pass
670 pass
671
671
672 import Tkinter
672 import Tkinter
673 Tkinter.Misc.mainloop = misc_mainloop
673 Tkinter.Misc.mainloop = misc_mainloop
674 Tkinter.mainloop = tkinter_mainloop
674 Tkinter.mainloop = tkinter_mainloop
675
675
676 def update_tk(tk):
676 def update_tk(tk):
677 """Updates the Tkinter event loop. This is typically called from
677 """Updates the Tkinter event loop. This is typically called from
678 the respective WX or GTK mainloops.
678 the respective WX or GTK mainloops.
679 """
679 """
680 if tk:
680 if tk:
681 tk.update()
681 tk.update()
682
682
683 def hijack_wx():
683 def hijack_wx():
684 """Modifies wxPython's MainLoop with a dummy so user code does not
684 """Modifies wxPython's MainLoop with a dummy so user code does not
685 block IPython. The hijacked mainloop function is returned.
685 block IPython. The hijacked mainloop function is returned.
686 """
686 """
687 def dummy_mainloop(*args, **kw):
687 def dummy_mainloop(*args, **kw):
688 pass
688 pass
689
689
690 try:
690 try:
691 import wx
691 import wx
692 except ImportError:
692 except ImportError:
693 # For very old versions of WX
693 # For very old versions of WX
694 import wxPython as wx
694 import wxPython as wx
695
695
696 ver = wx.__version__
696 ver = wx.__version__
697 orig_mainloop = None
697 orig_mainloop = None
698 if ver[:3] >= '2.5':
698 if ver[:3] >= '2.5':
699 import wx
699 import wx
700 if hasattr(wx, '_core_'): core = getattr(wx, '_core_')
700 if hasattr(wx, '_core_'): core = getattr(wx, '_core_')
701 elif hasattr(wx, '_core'): core = getattr(wx, '_core')
701 elif hasattr(wx, '_core'): core = getattr(wx, '_core')
702 else: raise AttributeError('Could not find wx core module')
702 else: raise AttributeError('Could not find wx core module')
703 orig_mainloop = core.PyApp_MainLoop
703 orig_mainloop = core.PyApp_MainLoop
704 core.PyApp_MainLoop = dummy_mainloop
704 core.PyApp_MainLoop = dummy_mainloop
705 elif ver[:3] == '2.4':
705 elif ver[:3] == '2.4':
706 orig_mainloop = wx.wxc.wxPyApp_MainLoop
706 orig_mainloop = wx.wxc.wxPyApp_MainLoop
707 wx.wxc.wxPyApp_MainLoop = dummy_mainloop
707 wx.wxc.wxPyApp_MainLoop = dummy_mainloop
708 else:
708 else:
709 warn("Unable to find either wxPython version 2.4 or >= 2.5.")
709 warn("Unable to find either wxPython version 2.4 or >= 2.5.")
710 return orig_mainloop
710 return orig_mainloop
711
711
712 def hijack_gtk():
712 def hijack_gtk():
713 """Modifies pyGTK's mainloop with a dummy so user code does not
713 """Modifies pyGTK's mainloop with a dummy so user code does not
714 block IPython. This function returns the original `gtk.mainloop`
714 block IPython. This function returns the original `gtk.mainloop`
715 function that has been hijacked.
715 function that has been hijacked.
716 """
716 """
717 def dummy_mainloop(*args, **kw):
717 def dummy_mainloop(*args, **kw):
718 pass
718 pass
719 import gtk
719 import gtk
720 if gtk.pygtk_version >= (2,4,0): orig_mainloop = gtk.main
720 if gtk.pygtk_version >= (2,4,0): orig_mainloop = gtk.main
721 else: orig_mainloop = gtk.mainloop
721 else: orig_mainloop = gtk.mainloop
722 gtk.mainloop = dummy_mainloop
722 gtk.mainloop = dummy_mainloop
723 gtk.main = dummy_mainloop
723 gtk.main = dummy_mainloop
724 return orig_mainloop
724 return orig_mainloop
725
725
726 def hijack_qt():
726 def hijack_qt():
727 """Modifies PyQt's mainloop with a dummy so user code does not
727 """Modifies PyQt's mainloop with a dummy so user code does not
728 block IPython. This function returns the original
728 block IPython. This function returns the original
729 `qt.qApp.exec_loop` function that has been hijacked.
729 `qt.qApp.exec_loop` function that has been hijacked.
730 """
730 """
731 def dummy_mainloop(*args, **kw):
731 def dummy_mainloop(*args, **kw):
732 pass
732 pass
733 import qt
733 import qt
734 orig_mainloop = qt.qApp.exec_loop
734 orig_mainloop = qt.qApp.exec_loop
735 qt.qApp.exec_loop = dummy_mainloop
735 qt.qApp.exec_loop = dummy_mainloop
736 qt.QApplication.exec_loop = dummy_mainloop
736 qt.QApplication.exec_loop = dummy_mainloop
737 return orig_mainloop
737 return orig_mainloop
738
738
739 def hijack_qt4():
739 def hijack_qt4():
740 """Modifies PyQt4's mainloop with a dummy so user code does not
740 """Modifies PyQt4's mainloop with a dummy so user code does not
741 block IPython. This function returns the original
741 block IPython. This function returns the original
742 `QtGui.qApp.exec_` function that has been hijacked.
742 `QtGui.qApp.exec_` function that has been hijacked.
743 """
743 """
744 def dummy_mainloop(*args, **kw):
744 def dummy_mainloop(*args, **kw):
745 pass
745 pass
746 from PyQt4 import QtGui, QtCore
746 from PyQt4 import QtGui, QtCore
747 orig_mainloop = QtGui.qApp.exec_
747 orig_mainloop = QtGui.qApp.exec_
748 QtGui.qApp.exec_ = dummy_mainloop
748 QtGui.qApp.exec_ = dummy_mainloop
749 QtGui.QApplication.exec_ = dummy_mainloop
749 QtGui.QApplication.exec_ = dummy_mainloop
750 QtCore.QCoreApplication.exec_ = dummy_mainloop
750 QtCore.QCoreApplication.exec_ = dummy_mainloop
751 return orig_mainloop
751 return orig_mainloop
752
752
753 #-----------------------------------------------------------------------------
753 #-----------------------------------------------------------------------------
754 # The IPShell* classes below are the ones meant to be run by external code as
754 # The IPShell* classes below are the ones meant to be run by external code as
755 # IPython instances. Note that unless a specific threading strategy is
755 # IPython instances. Note that unless a specific threading strategy is
756 # desired, the factory function start() below should be used instead (it
756 # desired, the factory function start() below should be used instead (it
757 # selects the proper threaded class).
757 # selects the proper threaded class).
758
758
759 class IPThread(threading.Thread):
759 class IPThread(threading.Thread):
760 def run(self):
760 def run(self):
761 self.IP.mainloop(self._banner)
761 self.IP.mainloop(self._banner)
762 self.IP.kill()
762 self.IP.kill()
763
763
764 class IPShellGTK(IPThread):
764 class IPShellGTK(IPThread):
765 """Run a gtk mainloop() in a separate thread.
765 """Run a gtk mainloop() in a separate thread.
766
766
767 Python commands can be passed to the thread where they will be executed.
767 Python commands can be passed to the thread where they will be executed.
768 This is implemented by periodically checking for passed code using a
768 This is implemented by periodically checking for passed code using a
769 GTK timeout callback."""
769 GTK timeout callback."""
770
770
771 TIMEOUT = 100 # Millisecond interval between timeouts.
771 TIMEOUT = 100 # Millisecond interval between timeouts.
772
772
773 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
773 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
774 debug=1,shell_class=MTInteractiveShell):
774 debug=1,shell_class=MTInteractiveShell):
775
775
776 import gtk
776 import gtk
777
777
778 self.gtk = gtk
778 self.gtk = gtk
779 self.gtk_mainloop = hijack_gtk()
779 self.gtk_mainloop = hijack_gtk()
780
780
781 # Allows us to use both Tk and GTK.
781 # Allows us to use both Tk and GTK.
782 self.tk = get_tk()
782 self.tk = get_tk()
783
783
784 if gtk.pygtk_version >= (2,4,0): mainquit = self.gtk.main_quit
784 if gtk.pygtk_version >= (2,4,0): mainquit = self.gtk.main_quit
785 else: mainquit = self.gtk.mainquit
785 else: mainquit = self.gtk.mainquit
786
786
787 self.IP = make_IPython(argv,user_ns=user_ns,
787 self.IP = make_IPython(argv,user_ns=user_ns,
788 user_global_ns=user_global_ns,
788 user_global_ns=user_global_ns,
789 debug=debug,
789 debug=debug,
790 shell_class=shell_class,
790 shell_class=shell_class,
791 on_kill=[mainquit])
791 on_kill=[mainquit])
792
792
793 # HACK: slot for banner in self; it will be passed to the mainloop
793 # HACK: slot for banner in self; it will be passed to the mainloop
794 # method only and .run() needs it. The actual value will be set by
794 # method only and .run() needs it. The actual value will be set by
795 # .mainloop().
795 # .mainloop().
796 self._banner = None
796 self._banner = None
797
797
798 threading.Thread.__init__(self)
798 threading.Thread.__init__(self)
799
799
800 def mainloop(self,sys_exit=0,banner=None):
800 def mainloop(self,sys_exit=0,banner=None):
801
801
802 self._banner = banner
802 self._banner = banner
803
803
804 if self.gtk.pygtk_version >= (2,4,0):
804 if self.gtk.pygtk_version >= (2,4,0):
805 import gobject
805 import gobject
806 gobject.idle_add(self.on_timer)
806 gobject.idle_add(self.on_timer)
807 else:
807 else:
808 self.gtk.idle_add(self.on_timer)
808 self.gtk.idle_add(self.on_timer)
809
809
810 if sys.platform != 'win32':
810 if sys.platform != 'win32':
811 try:
811 try:
812 if self.gtk.gtk_version[0] >= 2:
812 if self.gtk.gtk_version[0] >= 2:
813 self.gtk.gdk.threads_init()
813 self.gtk.gdk.threads_init()
814 except AttributeError:
814 except AttributeError:
815 pass
815 pass
816 except RuntimeError:
816 except RuntimeError:
817 error('Your pyGTK likely has not been compiled with '
817 error('Your pyGTK likely has not been compiled with '
818 'threading support.\n'
818 'threading support.\n'
819 'The exception printout is below.\n'
819 'The exception printout is below.\n'
820 'You can either rebuild pyGTK with threads, or '
820 'You can either rebuild pyGTK with threads, or '
821 'try using \n'
821 'try using \n'
822 'matplotlib with a different backend (like Tk or WX).\n'
822 'matplotlib with a different backend (like Tk or WX).\n'
823 'Note that matplotlib will most likely not work in its '
823 'Note that matplotlib will most likely not work in its '
824 'current state!')
824 'current state!')
825 self.IP.InteractiveTB()
825 self.IP.InteractiveTB()
826
826
827 self.start()
827 self.start()
828 self.gtk.gdk.threads_enter()
828 self.gtk.gdk.threads_enter()
829 self.gtk_mainloop()
829 self.gtk_mainloop()
830 self.gtk.gdk.threads_leave()
830 self.gtk.gdk.threads_leave()
831 self.join()
831 self.join()
832
832
833 def on_timer(self):
833 def on_timer(self):
834 """Called when GTK is idle.
834 """Called when GTK is idle.
835
835
836 Must return True always, otherwise GTK stops calling it"""
836 Must return True always, otherwise GTK stops calling it"""
837
837
838 update_tk(self.tk)
838 update_tk(self.tk)
839 self.IP.runcode()
839 self.IP.runcode()
840 time.sleep(0.01)
840 time.sleep(0.01)
841 return True
841 return True
842
842
843
843
844 class IPShellWX(IPThread):
844 class IPShellWX(IPThread):
845 """Run a wx mainloop() in a separate thread.
845 """Run a wx mainloop() in a separate thread.
846
846
847 Python commands can be passed to the thread where they will be executed.
847 Python commands can be passed to the thread where they will be executed.
848 This is implemented by periodically checking for passed code using a
848 This is implemented by periodically checking for passed code using a
849 GTK timeout callback."""
849 GTK timeout callback."""
850
850
851 TIMEOUT = 100 # Millisecond interval between timeouts.
851 TIMEOUT = 100 # Millisecond interval between timeouts.
852
852
853 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
853 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
854 debug=1,shell_class=MTInteractiveShell):
854 debug=1,shell_class=MTInteractiveShell):
855
855
856 self.IP = make_IPython(argv,user_ns=user_ns,
856 self.IP = make_IPython(argv,user_ns=user_ns,
857 user_global_ns=user_global_ns,
857 user_global_ns=user_global_ns,
858 debug=debug,
858 debug=debug,
859 shell_class=shell_class,
859 shell_class=shell_class,
860 on_kill=[self.wxexit])
860 on_kill=[self.wxexit])
861
861
862 wantedwxversion=self.IP.rc.wxversion
862 wantedwxversion=self.IP.rc.wxversion
863 if wantedwxversion!="0":
863 if wantedwxversion!="0":
864 try:
864 try:
865 import wxversion
865 import wxversion
866 except ImportError:
866 except ImportError:
867 error('The wxversion module is needed for WX version selection')
867 error('The wxversion module is needed for WX version selection')
868 else:
868 else:
869 try:
869 try:
870 wxversion.select(wantedwxversion)
870 wxversion.select(wantedwxversion)
871 except:
871 except:
872 self.IP.InteractiveTB()
872 self.IP.InteractiveTB()
873 error('Requested wxPython version %s could not be loaded' %
873 error('Requested wxPython version %s could not be loaded' %
874 wantedwxversion)
874 wantedwxversion)
875
875
876 import wx
876 import wx
877
877
878 threading.Thread.__init__(self)
878 threading.Thread.__init__(self)
879 self.wx = wx
879 self.wx = wx
880 self.wx_mainloop = hijack_wx()
880 self.wx_mainloop = hijack_wx()
881
881
882 # Allows us to use both Tk and GTK.
882 # Allows us to use both Tk and GTK.
883 self.tk = get_tk()
883 self.tk = get_tk()
884
884
885 # HACK: slot for banner in self; it will be passed to the mainloop
885 # HACK: slot for banner in self; it will be passed to the mainloop
886 # method only and .run() needs it. The actual value will be set by
886 # method only and .run() needs it. The actual value will be set by
887 # .mainloop().
887 # .mainloop().
888 self._banner = None
888 self._banner = None
889
889
890 self.app = None
890 self.app = None
891
891
892 def wxexit(self, *args):
892 def wxexit(self, *args):
893 if self.app is not None:
893 if self.app is not None:
894 self.app.agent.timer.Stop()
894 self.app.agent.timer.Stop()
895 self.app.ExitMainLoop()
895 self.app.ExitMainLoop()
896
896
897 def mainloop(self,sys_exit=0,banner=None):
897 def mainloop(self,sys_exit=0,banner=None):
898
898
899 self._banner = banner
899 self._banner = banner
900
900
901 self.start()
901 self.start()
902
902
903 class TimerAgent(self.wx.MiniFrame):
903 class TimerAgent(self.wx.MiniFrame):
904 wx = self.wx
904 wx = self.wx
905 IP = self.IP
905 IP = self.IP
906 tk = self.tk
906 tk = self.tk
907 def __init__(self, parent, interval):
907 def __init__(self, parent, interval):
908 style = self.wx.DEFAULT_FRAME_STYLE | self.wx.TINY_CAPTION_HORIZ
908 style = self.wx.DEFAULT_FRAME_STYLE | self.wx.TINY_CAPTION_HORIZ
909 self.wx.MiniFrame.__init__(self, parent, -1, ' ', pos=(200, 200),
909 self.wx.MiniFrame.__init__(self, parent, -1, ' ', pos=(200, 200),
910 size=(100, 100),style=style)
910 size=(100, 100),style=style)
911 self.Show(False)
911 self.Show(False)
912 self.interval = interval
912 self.interval = interval
913 self.timerId = self.wx.NewId()
913 self.timerId = self.wx.NewId()
914
914
915 def StartWork(self):
915 def StartWork(self):
916 self.timer = self.wx.Timer(self, self.timerId)
916 self.timer = self.wx.Timer(self, self.timerId)
917 self.wx.EVT_TIMER(self, self.timerId, self.OnTimer)
917 self.wx.EVT_TIMER(self, self.timerId, self.OnTimer)
918 self.timer.Start(self.interval)
918 self.timer.Start(self.interval)
919
919
920 def OnTimer(self, event):
920 def OnTimer(self, event):
921 update_tk(self.tk)
921 update_tk(self.tk)
922 self.IP.runcode()
922 self.IP.runcode()
923
923
924 class App(self.wx.App):
924 class App(self.wx.App):
925 wx = self.wx
925 wx = self.wx
926 TIMEOUT = self.TIMEOUT
926 TIMEOUT = self.TIMEOUT
927 def OnInit(self):
927 def OnInit(self):
928 'Create the main window and insert the custom frame'
928 'Create the main window and insert the custom frame'
929 self.agent = TimerAgent(None, self.TIMEOUT)
929 self.agent = TimerAgent(None, self.TIMEOUT)
930 self.agent.Show(False)
930 self.agent.Show(False)
931 self.agent.StartWork()
931 self.agent.StartWork()
932 return True
932 return True
933
933
934 self.app = App(redirect=False)
934 self.app = App(redirect=False)
935 self.wx_mainloop(self.app)
935 self.wx_mainloop(self.app)
936 self.join()
936 self.join()
937
937
938
938
939 class IPShellQt(IPThread):
939 class IPShellQt(IPThread):
940 """Run a Qt event loop in a separate thread.
940 """Run a Qt event loop in a separate thread.
941
941
942 Python commands can be passed to the thread where they will be executed.
942 Python commands can be passed to the thread where they will be executed.
943 This is implemented by periodically checking for passed code using a
943 This is implemented by periodically checking for passed code using a
944 Qt timer / slot."""
944 Qt timer / slot."""
945
945
946 TIMEOUT = 100 # Millisecond interval between timeouts.
946 TIMEOUT = 100 # Millisecond interval between timeouts.
947
947
948 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
948 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
949 debug=0, shell_class=MTInteractiveShell):
949 debug=0, shell_class=MTInteractiveShell):
950
950
951 import qt
951 import qt
952
952
953 self.exec_loop = hijack_qt()
953 self.exec_loop = hijack_qt()
954
954
955 # Allows us to use both Tk and QT.
955 # Allows us to use both Tk and QT.
956 self.tk = get_tk()
956 self.tk = get_tk()
957
957
958 self.IP = make_IPython(argv,
958 self.IP = make_IPython(argv,
959 user_ns=user_ns,
959 user_ns=user_ns,
960 user_global_ns=user_global_ns,
960 user_global_ns=user_global_ns,
961 debug=debug,
961 debug=debug,
962 shell_class=shell_class,
962 shell_class=shell_class,
963 on_kill=[qt.qApp.exit])
963 on_kill=[qt.qApp.exit])
964
964
965 # HACK: slot for banner in self; it will be passed to the mainloop
965 # HACK: slot for banner in self; it will be passed to the mainloop
966 # method only and .run() needs it. The actual value will be set by
966 # method only and .run() needs it. The actual value will be set by
967 # .mainloop().
967 # .mainloop().
968 self._banner = None
968 self._banner = None
969
969
970 threading.Thread.__init__(self)
970 threading.Thread.__init__(self)
971
971
972 def mainloop(self, sys_exit=0, banner=None):
972 def mainloop(self, sys_exit=0, banner=None):
973
973
974 import qt
974 import qt
975
975
976 self._banner = banner
976 self._banner = banner
977
977
978 if qt.QApplication.startingUp():
978 if qt.QApplication.startingUp():
979 a = qt.QApplication(sys.argv)
979 a = qt.QApplication(sys.argv)
980
980
981 self.timer = qt.QTimer()
981 self.timer = qt.QTimer()
982 qt.QObject.connect(self.timer,
982 qt.QObject.connect(self.timer,
983 qt.SIGNAL('timeout()'),
983 qt.SIGNAL('timeout()'),
984 self.on_timer)
984 self.on_timer)
985
985
986 self.start()
986 self.start()
987 self.timer.start(self.TIMEOUT, True)
987 self.timer.start(self.TIMEOUT, True)
988 while True:
988 while True:
989 if self.IP._kill: break
989 if self.IP._kill: break
990 self.exec_loop()
990 self.exec_loop()
991 self.join()
991 self.join()
992
992
993 def on_timer(self):
993 def on_timer(self):
994 update_tk(self.tk)
994 update_tk(self.tk)
995 result = self.IP.runcode()
995 result = self.IP.runcode()
996 self.timer.start(self.TIMEOUT, True)
996 self.timer.start(self.TIMEOUT, True)
997 return result
997 return result
998
998
999
999
1000 class IPShellQt4(IPThread):
1000 class IPShellQt4(IPThread):
1001 """Run a Qt event loop in a separate thread.
1001 """Run a Qt event loop in a separate thread.
1002
1002
1003 Python commands can be passed to the thread where they will be executed.
1003 Python commands can be passed to the thread where they will be executed.
1004 This is implemented by periodically checking for passed code using a
1004 This is implemented by periodically checking for passed code using a
1005 Qt timer / slot."""
1005 Qt timer / slot."""
1006
1006
1007 TIMEOUT = 100 # Millisecond interval between timeouts.
1007 TIMEOUT = 100 # Millisecond interval between timeouts.
1008
1008
1009 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
1009 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
1010 debug=0, shell_class=MTInteractiveShell):
1010 debug=0, shell_class=MTInteractiveShell):
1011
1011
1012 from PyQt4 import QtCore, QtGui
1012 from PyQt4 import QtCore, QtGui
1013
1013
1014 try:
1014 try:
1015 # present in PyQt4-4.2.1 or later
1015 # present in PyQt4-4.2.1 or later
1016 QtCore.pyqtRemoveInputHook()
1016 QtCore.pyqtRemoveInputHook()
1017 except AttributeError:
1017 except AttributeError:
1018 pass
1018 pass
1019
1019
1020 if QtCore.PYQT_VERSION_STR == '4.3':
1020 if QtCore.PYQT_VERSION_STR == '4.3':
1021 warn('''PyQt4 version 4.3 detected.
1021 warn('''PyQt4 version 4.3 detected.
1022 If you experience repeated threading warnings, please update PyQt4.
1022 If you experience repeated threading warnings, please update PyQt4.
1023 ''')
1023 ''')
1024
1024
1025 self.exec_ = hijack_qt4()
1025 self.exec_ = hijack_qt4()
1026
1026
1027 # Allows us to use both Tk and QT.
1027 # Allows us to use both Tk and QT.
1028 self.tk = get_tk()
1028 self.tk = get_tk()
1029
1029
1030 self.IP = make_IPython(argv,
1030 self.IP = make_IPython(argv,
1031 user_ns=user_ns,
1031 user_ns=user_ns,
1032 user_global_ns=user_global_ns,
1032 user_global_ns=user_global_ns,
1033 debug=debug,
1033 debug=debug,
1034 shell_class=shell_class,
1034 shell_class=shell_class,
1035 on_kill=[QtGui.qApp.exit])
1035 on_kill=[QtGui.qApp.exit])
1036
1036
1037 # HACK: slot for banner in self; it will be passed to the mainloop
1037 # HACK: slot for banner in self; it will be passed to the mainloop
1038 # method only and .run() needs it. The actual value will be set by
1038 # method only and .run() needs it. The actual value will be set by
1039 # .mainloop().
1039 # .mainloop().
1040 self._banner = None
1040 self._banner = None
1041
1041
1042 threading.Thread.__init__(self)
1042 threading.Thread.__init__(self)
1043
1043
1044 def mainloop(self, sys_exit=0, banner=None):
1044 def mainloop(self, sys_exit=0, banner=None):
1045
1045
1046 from PyQt4 import QtCore, QtGui
1046 from PyQt4 import QtCore, QtGui
1047
1047
1048 self._banner = banner
1048 self._banner = banner
1049
1049
1050 if QtGui.QApplication.startingUp():
1050 if QtGui.QApplication.startingUp():
1051 a = QtGui.QApplication(sys.argv)
1051 a = QtGui.QApplication(sys.argv)
1052
1052
1053 self.timer = QtCore.QTimer()
1053 self.timer = QtCore.QTimer()
1054 QtCore.QObject.connect(self.timer,
1054 QtCore.QObject.connect(self.timer,
1055 QtCore.SIGNAL('timeout()'),
1055 QtCore.SIGNAL('timeout()'),
1056 self.on_timer)
1056 self.on_timer)
1057
1057
1058 self.start()
1058 self.start()
1059 self.timer.start(self.TIMEOUT)
1059 self.timer.start(self.TIMEOUT)
1060 while True:
1060 while True:
1061 if self.IP._kill: break
1061 if self.IP._kill: break
1062 self.exec_()
1062 self.exec_()
1063 self.join()
1063 self.join()
1064
1064
1065 def on_timer(self):
1065 def on_timer(self):
1066 update_tk(self.tk)
1066 update_tk(self.tk)
1067 result = self.IP.runcode()
1067 result = self.IP.runcode()
1068 self.timer.start(self.TIMEOUT)
1068 self.timer.start(self.TIMEOUT)
1069 return result
1069 return result
1070
1070
1071
1071
1072 # A set of matplotlib public IPython shell classes, for single-threaded (Tk*
1072 # A set of matplotlib public IPython shell classes, for single-threaded (Tk*
1073 # and FLTK*) and multithreaded (GTK*, WX* and Qt*) backends to use.
1073 # and FLTK*) and multithreaded (GTK*, WX* and Qt*) backends to use.
1074 def _load_pylab(user_ns):
1074 def _load_pylab(user_ns):
1075 """Allow users to disable pulling all of pylab into the top-level
1075 """Allow users to disable pulling all of pylab into the top-level
1076 namespace.
1076 namespace.
1077
1077
1078 This little utility must be called AFTER the actual ipython instance is
1078 This little utility must be called AFTER the actual ipython instance is
1079 running, since only then will the options file have been fully parsed."""
1079 running, since only then will the options file have been fully parsed."""
1080
1080
1081 ip = IPython.ipapi.get()
1081 ip = IPython.ipapi.get()
1082 if ip.options.pylab_import_all:
1082 if ip.options.pylab_import_all:
1083 ip.ex("from matplotlib.pylab import *")
1083 ip.ex("from matplotlib.pylab import *")
1084 ip.IP.user_config_ns.update(ip.user_ns)
1084 ip.IP.user_config_ns.update(ip.user_ns)
1085
1085
1086
1086
1087 class IPShellMatplotlib(IPShell):
1087 class IPShellMatplotlib(IPShell):
1088 """Subclass IPShell with MatplotlibShell as the internal shell.
1088 """Subclass IPShell with MatplotlibShell as the internal shell.
1089
1089
1090 Single-threaded class, meant for the Tk* and FLTK* backends.
1090 Single-threaded class, meant for the Tk* and FLTK* backends.
1091
1091
1092 Having this on a separate class simplifies the external driver code."""
1092 Having this on a separate class simplifies the external driver code."""
1093
1093
1094 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1094 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1095 IPShell.__init__(self,argv,user_ns,user_global_ns,debug,
1095 IPShell.__init__(self,argv,user_ns,user_global_ns,debug,
1096 shell_class=MatplotlibShell)
1096 shell_class=MatplotlibShell)
1097 _load_pylab(self.IP.user_ns)
1097 _load_pylab(self.IP.user_ns)
1098
1098
1099 class IPShellMatplotlibGTK(IPShellGTK):
1099 class IPShellMatplotlibGTK(IPShellGTK):
1100 """Subclass IPShellGTK with MatplotlibMTShell as the internal shell.
1100 """Subclass IPShellGTK with MatplotlibMTShell as the internal shell.
1101
1101
1102 Multi-threaded class, meant for the GTK* backends."""
1102 Multi-threaded class, meant for the GTK* backends."""
1103
1103
1104 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1104 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1105 IPShellGTK.__init__(self,argv,user_ns,user_global_ns,debug,
1105 IPShellGTK.__init__(self,argv,user_ns,user_global_ns,debug,
1106 shell_class=MatplotlibMTShell)
1106 shell_class=MatplotlibMTShell)
1107 _load_pylab(self.IP.user_ns)
1107 _load_pylab(self.IP.user_ns)
1108
1108
1109 class IPShellMatplotlibWX(IPShellWX):
1109 class IPShellMatplotlibWX(IPShellWX):
1110 """Subclass IPShellWX with MatplotlibMTShell as the internal shell.
1110 """Subclass IPShellWX with MatplotlibMTShell as the internal shell.
1111
1111
1112 Multi-threaded class, meant for the WX* backends."""
1112 Multi-threaded class, meant for the WX* backends."""
1113
1113
1114 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1114 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1115 IPShellWX.__init__(self,argv,user_ns,user_global_ns,debug,
1115 IPShellWX.__init__(self,argv,user_ns,user_global_ns,debug,
1116 shell_class=MatplotlibMTShell)
1116 shell_class=MatplotlibMTShell)
1117 _load_pylab(self.IP.user_ns)
1117 _load_pylab(self.IP.user_ns)
1118
1118
1119 class IPShellMatplotlibQt(IPShellQt):
1119 class IPShellMatplotlibQt(IPShellQt):
1120 """Subclass IPShellQt with MatplotlibMTShell as the internal shell.
1120 """Subclass IPShellQt with MatplotlibMTShell as the internal shell.
1121
1121
1122 Multi-threaded class, meant for the Qt* backends."""
1122 Multi-threaded class, meant for the Qt* backends."""
1123
1123
1124 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1124 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1125 IPShellQt.__init__(self,argv,user_ns,user_global_ns,debug,
1125 IPShellQt.__init__(self,argv,user_ns,user_global_ns,debug,
1126 shell_class=MatplotlibMTShell)
1126 shell_class=MatplotlibMTShell)
1127 _load_pylab(self.IP.user_ns)
1127 _load_pylab(self.IP.user_ns)
1128
1128
1129 class IPShellMatplotlibQt4(IPShellQt4):
1129 class IPShellMatplotlibQt4(IPShellQt4):
1130 """Subclass IPShellQt4 with MatplotlibMTShell as the internal shell.
1130 """Subclass IPShellQt4 with MatplotlibMTShell as the internal shell.
1131
1131
1132 Multi-threaded class, meant for the Qt4* backends."""
1132 Multi-threaded class, meant for the Qt4* backends."""
1133
1133
1134 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1134 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1135 IPShellQt4.__init__(self,argv,user_ns,user_global_ns,debug,
1135 IPShellQt4.__init__(self,argv,user_ns,user_global_ns,debug,
1136 shell_class=MatplotlibMTShell)
1136 shell_class=MatplotlibMTShell)
1137 _load_pylab(self.IP.user_ns)
1137 _load_pylab(self.IP.user_ns)
1138
1138
1139 #-----------------------------------------------------------------------------
1139 #-----------------------------------------------------------------------------
1140 # Factory functions to actually start the proper thread-aware shell
1140 # Factory functions to actually start the proper thread-aware shell
1141
1141
1142 def _select_shell(argv):
1142 def _select_shell(argv):
1143 """Select a shell from the given argv vector.
1143 """Select a shell from the given argv vector.
1144
1144
1145 This function implements the threading selection policy, allowing runtime
1145 This function implements the threading selection policy, allowing runtime
1146 control of the threading mode, both for general users and for matplotlib.
1146 control of the threading mode, both for general users and for matplotlib.
1147
1147
1148 Return:
1148 Return:
1149 Shell class to be instantiated for runtime operation.
1149 Shell class to be instantiated for runtime operation.
1150 """
1150 """
1151
1151
1152 global USE_TK
1152 global USE_TK
1153
1153
1154 mpl_shell = {'gthread' : IPShellMatplotlibGTK,
1154 mpl_shell = {'gthread' : IPShellMatplotlibGTK,
1155 'wthread' : IPShellMatplotlibWX,
1155 'wthread' : IPShellMatplotlibWX,
1156 'qthread' : IPShellMatplotlibQt,
1156 'qthread' : IPShellMatplotlibQt,
1157 'q4thread' : IPShellMatplotlibQt4,
1157 'q4thread' : IPShellMatplotlibQt4,
1158 'tkthread' : IPShellMatplotlib, # Tk is built-in
1158 'tkthread' : IPShellMatplotlib, # Tk is built-in
1159 }
1159 }
1160
1160
1161 th_shell = {'gthread' : IPShellGTK,
1161 th_shell = {'gthread' : IPShellGTK,
1162 'wthread' : IPShellWX,
1162 'wthread' : IPShellWX,
1163 'qthread' : IPShellQt,
1163 'qthread' : IPShellQt,
1164 'q4thread' : IPShellQt4,
1164 'q4thread' : IPShellQt4,
1165 'tkthread' : IPShell, # Tk is built-in
1165 'tkthread' : IPShell, # Tk is built-in
1166 }
1166 }
1167
1167
1168 backends = {'gthread' : 'GTKAgg',
1168 backends = {'gthread' : 'GTKAgg',
1169 'wthread' : 'WXAgg',
1169 'wthread' : 'WXAgg',
1170 'qthread' : 'QtAgg',
1170 'qthread' : 'QtAgg',
1171 'q4thread' :'Qt4Agg',
1171 'q4thread' :'Qt4Agg',
1172 'tkthread' :'TkAgg',
1172 'tkthread' :'TkAgg',
1173 }
1173 }
1174
1174
1175 all_opts = set(['tk','pylab','gthread','qthread','q4thread','wthread',
1175 all_opts = set(['tk','pylab','gthread','qthread','q4thread','wthread',
1176 'tkthread'])
1176 'tkthread'])
1177 user_opts = set([s.replace('-','') for s in argv[:3]])
1177 user_opts = set([s.replace('-','') for s in argv[:3]])
1178 special_opts = user_opts & all_opts
1178 special_opts = user_opts & all_opts
1179
1179
1180 if 'tk' in special_opts:
1180 if 'tk' in special_opts:
1181 USE_TK = True
1181 USE_TK = True
1182 special_opts.remove('tk')
1182 special_opts.remove('tk')
1183
1183
1184 if 'pylab' in special_opts:
1184 if 'pylab' in special_opts:
1185
1185
1186 try:
1186 try:
1187 import matplotlib
1187 import matplotlib
1188 except ImportError:
1188 except ImportError:
1189 error('matplotlib could NOT be imported! Starting normal IPython.')
1189 error('matplotlib could NOT be imported! Starting normal IPython.')
1190 return IPShell
1190 return IPShell
1191
1191
1192 special_opts.remove('pylab')
1192 special_opts.remove('pylab')
1193 # If there's any option left, it means the user wants to force the
1193 # If there's any option left, it means the user wants to force the
1194 # threading backend, else it's auto-selected from the rc file
1194 # threading backend, else it's auto-selected from the rc file
1195 if special_opts:
1195 if special_opts:
1196 th_mode = special_opts.pop()
1196 th_mode = special_opts.pop()
1197 matplotlib.rcParams['backend'] = backends[th_mode]
1197 matplotlib.rcParams['backend'] = backends[th_mode]
1198 else:
1198 else:
1199 backend = matplotlib.rcParams['backend']
1199 backend = matplotlib.rcParams['backend']
1200 if backend.startswith('GTK'):
1200 if backend.startswith('GTK'):
1201 th_mode = 'gthread'
1201 th_mode = 'gthread'
1202 elif backend.startswith('WX'):
1202 elif backend.startswith('WX'):
1203 th_mode = 'wthread'
1203 th_mode = 'wthread'
1204 elif backend.startswith('Qt4'):
1204 elif backend.startswith('Qt4'):
1205 th_mode = 'q4thread'
1205 th_mode = 'q4thread'
1206 elif backend.startswith('Qt'):
1206 elif backend.startswith('Qt'):
1207 th_mode = 'qthread'
1207 th_mode = 'qthread'
1208 else:
1208 else:
1209 # Any other backend, use plain Tk
1209 # Any other backend, use plain Tk
1210 th_mode = 'tkthread'
1210 th_mode = 'tkthread'
1211
1211
1212 return mpl_shell[th_mode]
1212 return mpl_shell[th_mode]
1213 else:
1213 else:
1214 # No pylab requested, just plain threads
1214 # No pylab requested, just plain threads
1215 try:
1215 try:
1216 th_mode = special_opts.pop()
1216 th_mode = special_opts.pop()
1217 except KeyError:
1217 except KeyError:
1218 th_mode = 'tkthread'
1218 th_mode = 'tkthread'
1219 return th_shell[th_mode]
1219 return th_shell[th_mode]
1220
1220
1221
1221
1222 # This is the one which should be called by external code.
1222 # This is the one which should be called by external code.
1223 def start(user_ns = None):
1223 def start(user_ns = None):
1224 """Return a running shell instance, dealing with threading options.
1224 """Return a running shell instance, dealing with threading options.
1225
1225
1226 This is a factory function which will instantiate the proper IPython shell
1226 This is a factory function which will instantiate the proper IPython shell
1227 based on the user's threading choice. Such a selector is needed because
1227 based on the user's threading choice. Such a selector is needed because
1228 different GUI toolkits require different thread handling details."""
1228 different GUI toolkits require different thread handling details."""
1229
1229
1230 shell = _select_shell(sys.argv)
1230 shell = _select_shell(sys.argv)
1231 return shell(user_ns = user_ns)
1231 return shell(user_ns = user_ns)
1232
1232
1233 # Some aliases for backwards compatibility
1233 # Some aliases for backwards compatibility
1234 IPythonShell = IPShell
1234 IPythonShell = IPShell
1235 IPythonShellEmbed = IPShellEmbed
1235 IPythonShellEmbed = IPShellEmbed
1236 #************************ End of file <Shell.py> ***************************
1236 #************************ End of file <Shell.py> ***************************
@@ -1,71 +1,72 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 IPython -- An enhanced Interactive Python
3 IPython -- An enhanced Interactive Python
4
4
5 One of Python's nicest features is its interactive interpreter. This allows
5 One of Python's nicest features is its interactive interpreter. This allows
6 very fast testing of ideas without the overhead of creating test files as is
6 very fast testing of ideas without the overhead of creating test files as is
7 typical in most programming languages. However, the interpreter supplied with
7 typical in most programming languages. However, the interpreter supplied with
8 the standard Python distribution is fairly primitive (and IDLE isn't really
8 the standard Python distribution is fairly primitive (and IDLE isn't really
9 much better).
9 much better).
10
10
11 IPython tries to:
11 IPython tries to:
12
12
13 i - provide an efficient environment for interactive work in Python
13 i - provide an efficient environment for interactive work in Python
14 programming. It tries to address what we see as shortcomings of the standard
14 programming. It tries to address what we see as shortcomings of the standard
15 Python prompt, and adds many features to make interactive work much more
15 Python prompt, and adds many features to make interactive work much more
16 efficient.
16 efficient.
17
17
18 ii - offer a flexible framework so that it can be used as the base
18 ii - offer a flexible framework so that it can be used as the base
19 environment for other projects and problems where Python can be the
19 environment for other projects and problems where Python can be the
20 underlying language. Specifically scientific environments like Mathematica,
20 underlying language. Specifically scientific environments like Mathematica,
21 IDL and Mathcad inspired its design, but similar ideas can be useful in many
21 IDL and Mathcad inspired its design, but similar ideas can be useful in many
22 fields. Python is a fabulous language for implementing this kind of system
22 fields. Python is a fabulous language for implementing this kind of system
23 (due to its dynamic and introspective features), and with suitable libraries
23 (due to its dynamic and introspective features), and with suitable libraries
24 entire systems could be built leveraging Python's power.
24 entire systems could be built leveraging Python's power.
25
25
26 iii - serve as an embeddable, ready to go interpreter for your own programs.
26 iii - serve as an embeddable, ready to go interpreter for your own programs.
27
27
28 IPython requires Python 2.3 or newer.
28 IPython requires Python 2.3 or newer.
29
29
30 $Id: __init__.py 2399 2007-05-26 10:23:10Z vivainio $"""
30 $Id: __init__.py 2399 2007-05-26 10:23:10Z vivainio $"""
31
31
32 #*****************************************************************************
32 #*****************************************************************************
33 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
33 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
34 #
34 #
35 # Distributed under the terms of the BSD License. The full license is in
35 # Distributed under the terms of the BSD License. The full license is in
36 # the file COPYING, distributed as part of this software.
36 # the file COPYING, distributed as part of this software.
37 #*****************************************************************************
37 #*****************************************************************************
38
38
39 # Enforce proper version requirements
39 # Enforce proper version requirements
40 import sys
40 import sys
41
41
42 if sys.version[0:3] < '2.3':
42 if sys.version[0:3] < '2.4':
43 raise ImportError('Python Version 2.3 or above is required for IPython.')
43 raise ImportError('Python Version 2.4 or above is required for IPython.')
44
44
45 # Make it easy to import extensions - they are always directly on pythonpath.
45 # Make it easy to import extensions - they are always directly on pythonpath.
46 # Therefore, non-IPython modules can be added to Extensions directory
46 # Therefore, non-IPython modules can be added to Extensions directory
47 import os
47 import os
48 sys.path.append(os.path.dirname(__file__) + "/Extensions")
48 sys.path.append(os.path.dirname(__file__) + "/Extensions")
49
49
50 # Define what gets imported with a 'from IPython import *'
50 # Define what gets imported with a 'from IPython import *'
51 __all__ = ['ipapi','generics','ipstruct','Release','Shell']
51 __all__ = ['ipapi','generics','ipstruct','Release','Shell']
52
52
53 # Load __all__ in IPython namespace so that a simple 'import IPython' gives
53 # Load __all__ in IPython namespace so that a simple 'import IPython' gives
54 # access to them via IPython.<name>
54 # access to them via IPython.<name>
55 glob,loc = globals(),locals()
55 glob,loc = globals(),locals()
56 for name in __all__:
56 for name in __all__:
57 #print 'Importing: ',name # dbg
57 __import__(name,glob,loc,[])
58 __import__(name,glob,loc,[])
58
59
59 import Shell
60 import Shell
60
61
61 # Release data
62 # Release data
62 from IPython import Release # do it explicitly so pydoc can see it - pydoc bug
63 from IPython import Release # do it explicitly so pydoc can see it - pydoc bug
63 __author__ = '%s <%s>\n%s <%s>\n%s <%s>' % \
64 __author__ = '%s <%s>\n%s <%s>\n%s <%s>' % \
64 ( Release.authors['Fernando'] + Release.authors['Janko'] + \
65 ( Release.authors['Fernando'] + Release.authors['Janko'] + \
65 Release.authors['Nathan'] )
66 Release.authors['Nathan'] )
66 __license__ = Release.license
67 __license__ = Release.license
67 __version__ = Release.version
68 __version__ = Release.version
68 __revision__ = Release.revision
69 __revision__ = Release.revision
69
70
70 # Namespace cleanup
71 # Namespace cleanup
71 del name,glob,loc
72 del name,glob,loc
@@ -1,644 +1,637 b''
1 """Word completion for IPython.
1 """Word completion for IPython.
2
2
3 This module is a fork of the rlcompleter module in the Python standard
3 This module is a fork of the rlcompleter module in the Python standard
4 library. The original enhancements made to rlcompleter have been sent
4 library. The original enhancements made to rlcompleter have been sent
5 upstream and were accepted as of Python 2.3, but we need a lot more
5 upstream and were accepted as of Python 2.3, but we need a lot more
6 functionality specific to IPython, so this module will continue to live as an
6 functionality specific to IPython, so this module will continue to live as an
7 IPython-specific utility.
7 IPython-specific utility.
8
8
9 ---------------------------------------------------------------------------
9 ---------------------------------------------------------------------------
10 Original rlcompleter documentation:
10 Original rlcompleter documentation:
11
11
12 This requires the latest extension to the readline module (the
12 This requires the latest extension to the readline module (the
13 completes keywords, built-ins and globals in __main__; when completing
13 completes keywords, built-ins and globals in __main__; when completing
14 NAME.NAME..., it evaluates (!) the expression up to the last dot and
14 NAME.NAME..., it evaluates (!) the expression up to the last dot and
15 completes its attributes.
15 completes its attributes.
16
16
17 It's very cool to do "import string" type "string.", hit the
17 It's very cool to do "import string" type "string.", hit the
18 completion key (twice), and see the list of names defined by the
18 completion key (twice), and see the list of names defined by the
19 string module!
19 string module!
20
20
21 Tip: to use the tab key as the completion key, call
21 Tip: to use the tab key as the completion key, call
22
22
23 readline.parse_and_bind("tab: complete")
23 readline.parse_and_bind("tab: complete")
24
24
25 Notes:
25 Notes:
26
26
27 - Exceptions raised by the completer function are *ignored* (and
27 - Exceptions raised by the completer function are *ignored* (and
28 generally cause the completion to fail). This is a feature -- since
28 generally cause the completion to fail). This is a feature -- since
29 readline sets the tty device in raw (or cbreak) mode, printing a
29 readline sets the tty device in raw (or cbreak) mode, printing a
30 traceback wouldn't work well without some complicated hoopla to save,
30 traceback wouldn't work well without some complicated hoopla to save,
31 reset and restore the tty state.
31 reset and restore the tty state.
32
32
33 - The evaluation of the NAME.NAME... form may cause arbitrary
33 - The evaluation of the NAME.NAME... form may cause arbitrary
34 application defined code to be executed if an object with a
34 application defined code to be executed if an object with a
35 __getattr__ hook is found. Since it is the responsibility of the
35 __getattr__ hook is found. Since it is the responsibility of the
36 application (or the user) to enable this feature, I consider this an
36 application (or the user) to enable this feature, I consider this an
37 acceptable risk. More complicated expressions (e.g. function calls or
37 acceptable risk. More complicated expressions (e.g. function calls or
38 indexing operations) are *not* evaluated.
38 indexing operations) are *not* evaluated.
39
39
40 - GNU readline is also used by the built-in functions input() and
40 - GNU readline is also used by the built-in functions input() and
41 raw_input(), and thus these also benefit/suffer from the completer
41 raw_input(), and thus these also benefit/suffer from the completer
42 features. Clearly an interactive application can benefit by
42 features. Clearly an interactive application can benefit by
43 specifying its own completer function and using raw_input() for all
43 specifying its own completer function and using raw_input() for all
44 its input.
44 its input.
45
45
46 - When the original stdin is not a tty device, GNU readline is never
46 - When the original stdin is not a tty device, GNU readline is never
47 used, and this module (and the readline module) are silently inactive.
47 used, and this module (and the readline module) are silently inactive.
48
48
49 """
49 """
50
50
51 #*****************************************************************************
51 #*****************************************************************************
52 #
52 #
53 # Since this file is essentially a minimally modified copy of the rlcompleter
53 # Since this file is essentially a minimally modified copy of the rlcompleter
54 # module which is part of the standard Python distribution, I assume that the
54 # module which is part of the standard Python distribution, I assume that the
55 # proper procedure is to maintain its copyright as belonging to the Python
55 # proper procedure is to maintain its copyright as belonging to the Python
56 # Software Foundation (in addition to my own, for all new code).
56 # Software Foundation (in addition to my own, for all new code).
57 #
57 #
58 # Copyright (C) 2001 Python Software Foundation, www.python.org
58 # Copyright (C) 2001 Python Software Foundation, www.python.org
59 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
59 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
60 #
60 #
61 # Distributed under the terms of the BSD License. The full license is in
61 # Distributed under the terms of the BSD License. The full license is in
62 # the file COPYING, distributed as part of this software.
62 # the file COPYING, distributed as part of this software.
63 #
63 #
64 #*****************************************************************************
64 #*****************************************************************************
65
65
66 import __builtin__
66 import __builtin__
67 import __main__
67 import __main__
68 import glob
68 import glob
69 import keyword
69 import keyword
70 import os
70 import os
71 import re
71 import re
72 import shlex
72 import shlex
73 import sys
73 import sys
74 import IPython.rlineimpl as readline
74 import IPython.rlineimpl as readline
75 import itertools
75 import itertools
76 from IPython.ipstruct import Struct
76 from IPython.ipstruct import Struct
77 from IPython import ipapi
77 from IPython import ipapi
78 from IPython import generics
78 from IPython import generics
79 import types
79 import types
80
80
81 # Python 2.4 offers sets as a builtin
81 # Python 2.4 offers sets as a builtin
82 try:
82 try:
83 set()
83 set()
84 except NameError:
84 except NameError:
85 from sets import Set as set
85 from sets import Set as set
86
86
87 from IPython.genutils import debugx, dir2
87 from IPython.genutils import debugx, dir2
88
88
89 __all__ = ['Completer','IPCompleter']
89 __all__ = ['Completer','IPCompleter']
90
90
91 class Completer:
91 class Completer:
92 def __init__(self,namespace=None,global_namespace=None):
92 def __init__(self,namespace=None,global_namespace=None):
93 """Create a new completer for the command line.
93 """Create a new completer for the command line.
94
94
95 Completer([namespace,global_namespace]) -> completer instance.
95 Completer([namespace,global_namespace]) -> completer instance.
96
96
97 If unspecified, the default namespace where completions are performed
97 If unspecified, the default namespace where completions are performed
98 is __main__ (technically, __main__.__dict__). Namespaces should be
98 is __main__ (technically, __main__.__dict__). Namespaces should be
99 given as dictionaries.
99 given as dictionaries.
100
100
101 An optional second namespace can be given. This allows the completer
101 An optional second namespace can be given. This allows the completer
102 to handle cases where both the local and global scopes need to be
102 to handle cases where both the local and global scopes need to be
103 distinguished.
103 distinguished.
104
104
105 Completer instances should be used as the completion mechanism of
105 Completer instances should be used as the completion mechanism of
106 readline via the set_completer() call:
106 readline via the set_completer() call:
107
107
108 readline.set_completer(Completer(my_namespace).complete)
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 # Don't bind to namespace quite yet, but flag whether the user wants a
111 # Don't bind to namespace quite yet, but flag whether the user wants a
119 # specific namespace or to use __main__.__dict__. This will allow us
112 # specific namespace or to use __main__.__dict__. This will allow us
120 # to bind to __main__.__dict__ at completion time, not now.
113 # to bind to __main__.__dict__ at completion time, not now.
121 if namespace is None:
114 if namespace is None:
122 self.use_main_ns = 1
115 self.use_main_ns = 1
123 else:
116 else:
124 self.use_main_ns = 0
117 self.use_main_ns = 0
125 self.namespace = namespace
118 self.namespace = namespace
126
119
127 # The global namespace, if given, can be bound directly
120 # The global namespace, if given, can be bound directly
128 if global_namespace is None:
121 if global_namespace is None:
129 self.global_namespace = {}
122 self.global_namespace = {}
130 else:
123 else:
131 self.global_namespace = global_namespace
124 self.global_namespace = global_namespace
132
125
133 def complete(self, text, state):
126 def complete(self, text, state):
134 """Return the next possible completion for 'text'.
127 """Return the next possible completion for 'text'.
135
128
136 This is called successively with state == 0, 1, 2, ... until it
129 This is called successively with state == 0, 1, 2, ... until it
137 returns None. The completion should begin with 'text'.
130 returns None. The completion should begin with 'text'.
138
131
139 """
132 """
140 if self.use_main_ns:
133 if self.use_main_ns:
141 self.namespace = __main__.__dict__
134 self.namespace = __main__.__dict__
142
135
143 if state == 0:
136 if state == 0:
144 if "." in text:
137 if "." in text:
145 self.matches = self.attr_matches(text)
138 self.matches = self.attr_matches(text)
146 else:
139 else:
147 self.matches = self.global_matches(text)
140 self.matches = self.global_matches(text)
148 try:
141 try:
149 return self.matches[state]
142 return self.matches[state]
150 except IndexError:
143 except IndexError:
151 return None
144 return None
152
145
153 def global_matches(self, text):
146 def global_matches(self, text):
154 """Compute matches when text is a simple name.
147 """Compute matches when text is a simple name.
155
148
156 Return a list of all keywords, built-in functions and names currently
149 Return a list of all keywords, built-in functions and names currently
157 defined in self.namespace or self.global_namespace that match.
150 defined in self.namespace or self.global_namespace that match.
158
151
159 """
152 """
160 matches = []
153 matches = []
161 match_append = matches.append
154 match_append = matches.append
162 n = len(text)
155 n = len(text)
163 for lst in [keyword.kwlist,
156 for lst in [keyword.kwlist,
164 __builtin__.__dict__.keys(),
157 __builtin__.__dict__.keys(),
165 self.namespace.keys(),
158 self.namespace.keys(),
166 self.global_namespace.keys()]:
159 self.global_namespace.keys()]:
167 for word in lst:
160 for word in lst:
168 if word[:n] == text and word != "__builtins__":
161 if word[:n] == text and word != "__builtins__":
169 match_append(word)
162 match_append(word)
170 return matches
163 return matches
171
164
172 def attr_matches(self, text):
165 def attr_matches(self, text):
173 """Compute matches when text contains a dot.
166 """Compute matches when text contains a dot.
174
167
175 Assuming the text is of the form NAME.NAME....[NAME], and is
168 Assuming the text is of the form NAME.NAME....[NAME], and is
176 evaluatable in self.namespace or self.global_namespace, it will be
169 evaluatable in self.namespace or self.global_namespace, it will be
177 evaluated and its attributes (as revealed by dir()) are used as
170 evaluated and its attributes (as revealed by dir()) are used as
178 possible completions. (For class instances, class members are are
171 possible completions. (For class instances, class members are are
179 also considered.)
172 also considered.)
180
173
181 WARNING: this can still invoke arbitrary C code, if an object
174 WARNING: this can still invoke arbitrary C code, if an object
182 with a __getattr__ hook is evaluated.
175 with a __getattr__ hook is evaluated.
183
176
184 """
177 """
185 import re
178 import re
186
179
187 # Another option, seems to work great. Catches things like ''.<tab>
180 # Another option, seems to work great. Catches things like ''.<tab>
188 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
181 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
189
182
190 if not m:
183 if not m:
191 return []
184 return []
192
185
193 expr, attr = m.group(1, 3)
186 expr, attr = m.group(1, 3)
194 try:
187 try:
195 obj = eval(expr, self.namespace)
188 obj = eval(expr, self.namespace)
196 except:
189 except:
197 try:
190 try:
198 obj = eval(expr, self.global_namespace)
191 obj = eval(expr, self.global_namespace)
199 except:
192 except:
200 return []
193 return []
201
194
202 words = dir2(obj)
195 words = dir2(obj)
203
196
204 try:
197 try:
205 words = generics.complete_object(obj, words)
198 words = generics.complete_object(obj, words)
206 except ipapi.TryNext:
199 except ipapi.TryNext:
207 pass
200 pass
208 # Build match list to return
201 # Build match list to return
209 n = len(attr)
202 n = len(attr)
210 res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
203 res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
211 return res
204 return res
212
205
213 class IPCompleter(Completer):
206 class IPCompleter(Completer):
214 """Extension of the completer class with IPython-specific features"""
207 """Extension of the completer class with IPython-specific features"""
215
208
216 def __init__(self,shell,namespace=None,global_namespace=None,
209 def __init__(self,shell,namespace=None,global_namespace=None,
217 omit__names=0,alias_table=None):
210 omit__names=0,alias_table=None):
218 """IPCompleter() -> completer
211 """IPCompleter() -> completer
219
212
220 Return a completer object suitable for use by the readline library
213 Return a completer object suitable for use by the readline library
221 via readline.set_completer().
214 via readline.set_completer().
222
215
223 Inputs:
216 Inputs:
224
217
225 - shell: a pointer to the ipython shell itself. This is needed
218 - shell: a pointer to the ipython shell itself. This is needed
226 because this completer knows about magic functions, and those can
219 because this completer knows about magic functions, and those can
227 only be accessed via the ipython instance.
220 only be accessed via the ipython instance.
228
221
229 - namespace: an optional dict where completions are performed.
222 - namespace: an optional dict where completions are performed.
230
223
231 - global_namespace: secondary optional dict for completions, to
224 - global_namespace: secondary optional dict for completions, to
232 handle cases (such as IPython embedded inside functions) where
225 handle cases (such as IPython embedded inside functions) where
233 both Python scopes are visible.
226 both Python scopes are visible.
234
227
235 - The optional omit__names parameter sets the completer to omit the
228 - The optional omit__names parameter sets the completer to omit the
236 'magic' names (__magicname__) for python objects unless the text
229 'magic' names (__magicname__) for python objects unless the text
237 to be completed explicitly starts with one or more underscores.
230 to be completed explicitly starts with one or more underscores.
238
231
239 - If alias_table is supplied, it should be a dictionary of aliases
232 - If alias_table is supplied, it should be a dictionary of aliases
240 to complete. """
233 to complete. """
241
234
242 Completer.__init__(self,namespace,global_namespace)
235 Completer.__init__(self,namespace,global_namespace)
243 self.magic_prefix = shell.name+'.magic_'
236 self.magic_prefix = shell.name+'.magic_'
244 self.magic_escape = shell.ESC_MAGIC
237 self.magic_escape = shell.ESC_MAGIC
245 self.readline = readline
238 self.readline = readline
246 delims = self.readline.get_completer_delims()
239 delims = self.readline.get_completer_delims()
247 delims = delims.replace(self.magic_escape,'')
240 delims = delims.replace(self.magic_escape,'')
248 self.readline.set_completer_delims(delims)
241 self.readline.set_completer_delims(delims)
249 self.get_line_buffer = self.readline.get_line_buffer
242 self.get_line_buffer = self.readline.get_line_buffer
250 self.get_endidx = self.readline.get_endidx
243 self.get_endidx = self.readline.get_endidx
251 self.omit__names = omit__names
244 self.omit__names = omit__names
252 self.merge_completions = shell.rc.readline_merge_completions
245 self.merge_completions = shell.rc.readline_merge_completions
253 if alias_table is None:
246 if alias_table is None:
254 alias_table = {}
247 alias_table = {}
255 self.alias_table = alias_table
248 self.alias_table = alias_table
256 # Regexp to split filenames with spaces in them
249 # Regexp to split filenames with spaces in them
257 self.space_name_re = re.compile(r'([^\\] )')
250 self.space_name_re = re.compile(r'([^\\] )')
258 # Hold a local ref. to glob.glob for speed
251 # Hold a local ref. to glob.glob for speed
259 self.glob = glob.glob
252 self.glob = glob.glob
260
253
261 # Determine if we are running on 'dumb' terminals, like (X)Emacs
254 # Determine if we are running on 'dumb' terminals, like (X)Emacs
262 # buffers, to avoid completion problems.
255 # buffers, to avoid completion problems.
263 term = os.environ.get('TERM','xterm')
256 term = os.environ.get('TERM','xterm')
264 self.dumb_terminal = term in ['dumb','emacs']
257 self.dumb_terminal = term in ['dumb','emacs']
265
258
266 # Special handling of backslashes needed in win32 platforms
259 # Special handling of backslashes needed in win32 platforms
267 if sys.platform == "win32":
260 if sys.platform == "win32":
268 self.clean_glob = self._clean_glob_win32
261 self.clean_glob = self._clean_glob_win32
269 else:
262 else:
270 self.clean_glob = self._clean_glob
263 self.clean_glob = self._clean_glob
271 self.matchers = [self.python_matches,
264 self.matchers = [self.python_matches,
272 self.file_matches,
265 self.file_matches,
273 self.alias_matches,
266 self.alias_matches,
274 self.python_func_kw_matches]
267 self.python_func_kw_matches]
275
268
276
269
277 # Code contributed by Alex Schmolck, for ipython/emacs integration
270 # Code contributed by Alex Schmolck, for ipython/emacs integration
278 def all_completions(self, text):
271 def all_completions(self, text):
279 """Return all possible completions for the benefit of emacs."""
272 """Return all possible completions for the benefit of emacs."""
280
273
281 completions = []
274 completions = []
282 comp_append = completions.append
275 comp_append = completions.append
283 try:
276 try:
284 for i in xrange(sys.maxint):
277 for i in xrange(sys.maxint):
285 res = self.complete(text, i)
278 res = self.complete(text, i)
286
279
287 if not res: break
280 if not res: break
288
281
289 comp_append(res)
282 comp_append(res)
290 #XXX workaround for ``notDefined.<tab>``
283 #XXX workaround for ``notDefined.<tab>``
291 except NameError:
284 except NameError:
292 pass
285 pass
293 return completions
286 return completions
294 # /end Alex Schmolck code.
287 # /end Alex Schmolck code.
295
288
296 def _clean_glob(self,text):
289 def _clean_glob(self,text):
297 return self.glob("%s*" % text)
290 return self.glob("%s*" % text)
298
291
299 def _clean_glob_win32(self,text):
292 def _clean_glob_win32(self,text):
300 return [f.replace("\\","/")
293 return [f.replace("\\","/")
301 for f in self.glob("%s*" % text)]
294 for f in self.glob("%s*" % text)]
302
295
303 def file_matches(self, text):
296 def file_matches(self, text):
304 """Match filenames, expanding ~USER type strings.
297 """Match filenames, expanding ~USER type strings.
305
298
306 Most of the seemingly convoluted logic in this completer is an
299 Most of the seemingly convoluted logic in this completer is an
307 attempt to handle filenames with spaces in them. And yet it's not
300 attempt to handle filenames with spaces in them. And yet it's not
308 quite perfect, because Python's readline doesn't expose all of the
301 quite perfect, because Python's readline doesn't expose all of the
309 GNU readline details needed for this to be done correctly.
302 GNU readline details needed for this to be done correctly.
310
303
311 For a filename with a space in it, the printed completions will be
304 For a filename with a space in it, the printed completions will be
312 only the parts after what's already been typed (instead of the
305 only the parts after what's already been typed (instead of the
313 full completions, as is normally done). I don't think with the
306 full completions, as is normally done). I don't think with the
314 current (as of Python 2.3) Python readline it's possible to do
307 current (as of Python 2.3) Python readline it's possible to do
315 better."""
308 better."""
316
309
317 #print 'Completer->file_matches: <%s>' % text # dbg
310 #print 'Completer->file_matches: <%s>' % text # dbg
318
311
319 # chars that require escaping with backslash - i.e. chars
312 # chars that require escaping with backslash - i.e. chars
320 # that readline treats incorrectly as delimiters, but we
313 # that readline treats incorrectly as delimiters, but we
321 # don't want to treat as delimiters in filename matching
314 # don't want to treat as delimiters in filename matching
322 # when escaped with backslash
315 # when escaped with backslash
323
316
324 protectables = ' '
317 protectables = ' '
325
318
326 if text.startswith('!'):
319 if text.startswith('!'):
327 text = text[1:]
320 text = text[1:]
328 text_prefix = '!'
321 text_prefix = '!'
329 else:
322 else:
330 text_prefix = ''
323 text_prefix = ''
331
324
332 def protect_filename(s):
325 def protect_filename(s):
333 return "".join([(ch in protectables and '\\' + ch or ch)
326 return "".join([(ch in protectables and '\\' + ch or ch)
334 for ch in s])
327 for ch in s])
335
328
336 def single_dir_expand(matches):
329 def single_dir_expand(matches):
337 "Recursively expand match lists containing a single dir."
330 "Recursively expand match lists containing a single dir."
338
331
339 if len(matches) == 1 and os.path.isdir(matches[0]):
332 if len(matches) == 1 and os.path.isdir(matches[0]):
340 # Takes care of links to directories also. Use '/'
333 # Takes care of links to directories also. Use '/'
341 # explicitly, even under Windows, so that name completions
334 # explicitly, even under Windows, so that name completions
342 # don't end up escaped.
335 # don't end up escaped.
343 d = matches[0]
336 d = matches[0]
344 if d[-1] in ['/','\\']:
337 if d[-1] in ['/','\\']:
345 d = d[:-1]
338 d = d[:-1]
346
339
347 subdirs = os.listdir(d)
340 subdirs = os.listdir(d)
348 if subdirs:
341 if subdirs:
349 matches = [ (d + '/' + p) for p in subdirs]
342 matches = [ (d + '/' + p) for p in subdirs]
350 return single_dir_expand(matches)
343 return single_dir_expand(matches)
351 else:
344 else:
352 return matches
345 return matches
353 else:
346 else:
354 return matches
347 return matches
355
348
356 lbuf = self.lbuf
349 lbuf = self.lbuf
357 open_quotes = 0 # track strings with open quotes
350 open_quotes = 0 # track strings with open quotes
358 try:
351 try:
359 lsplit = shlex.split(lbuf)[-1]
352 lsplit = shlex.split(lbuf)[-1]
360 except ValueError:
353 except ValueError:
361 # typically an unmatched ", or backslash without escaped char.
354 # typically an unmatched ", or backslash without escaped char.
362 if lbuf.count('"')==1:
355 if lbuf.count('"')==1:
363 open_quotes = 1
356 open_quotes = 1
364 lsplit = lbuf.split('"')[-1]
357 lsplit = lbuf.split('"')[-1]
365 elif lbuf.count("'")==1:
358 elif lbuf.count("'")==1:
366 open_quotes = 1
359 open_quotes = 1
367 lsplit = lbuf.split("'")[-1]
360 lsplit = lbuf.split("'")[-1]
368 else:
361 else:
369 return []
362 return []
370 except IndexError:
363 except IndexError:
371 # tab pressed on empty line
364 # tab pressed on empty line
372 lsplit = ""
365 lsplit = ""
373
366
374 if lsplit != protect_filename(lsplit):
367 if lsplit != protect_filename(lsplit):
375 # if protectables are found, do matching on the whole escaped
368 # if protectables are found, do matching on the whole escaped
376 # name
369 # name
377 has_protectables = 1
370 has_protectables = 1
378 text0,text = text,lsplit
371 text0,text = text,lsplit
379 else:
372 else:
380 has_protectables = 0
373 has_protectables = 0
381 text = os.path.expanduser(text)
374 text = os.path.expanduser(text)
382
375
383 if text == "":
376 if text == "":
384 return [text_prefix + protect_filename(f) for f in self.glob("*")]
377 return [text_prefix + protect_filename(f) for f in self.glob("*")]
385
378
386 m0 = self.clean_glob(text.replace('\\',''))
379 m0 = self.clean_glob(text.replace('\\',''))
387 if has_protectables:
380 if has_protectables:
388 # If we had protectables, we need to revert our changes to the
381 # If we had protectables, we need to revert our changes to the
389 # beginning of filename so that we don't double-write the part
382 # beginning of filename so that we don't double-write the part
390 # of the filename we have so far
383 # of the filename we have so far
391 len_lsplit = len(lsplit)
384 len_lsplit = len(lsplit)
392 matches = [text_prefix + text0 +
385 matches = [text_prefix + text0 +
393 protect_filename(f[len_lsplit:]) for f in m0]
386 protect_filename(f[len_lsplit:]) for f in m0]
394 else:
387 else:
395 if open_quotes:
388 if open_quotes:
396 # if we have a string with an open quote, we don't need to
389 # if we have a string with an open quote, we don't need to
397 # protect the names at all (and we _shouldn't_, as it
390 # protect the names at all (and we _shouldn't_, as it
398 # would cause bugs when the filesystem call is made).
391 # would cause bugs when the filesystem call is made).
399 matches = m0
392 matches = m0
400 else:
393 else:
401 matches = [text_prefix +
394 matches = [text_prefix +
402 protect_filename(f) for f in m0]
395 protect_filename(f) for f in m0]
403
396
404 #print 'mm',matches # dbg
397 #print 'mm',matches # dbg
405 return single_dir_expand(matches)
398 return single_dir_expand(matches)
406
399
407 def alias_matches(self, text):
400 def alias_matches(self, text):
408 """Match internal system aliases"""
401 """Match internal system aliases"""
409 #print 'Completer->alias_matches:',text,'lb',self.lbuf # dbg
402 #print 'Completer->alias_matches:',text,'lb',self.lbuf # dbg
410
403
411 # if we are not in the first 'item', alias matching
404 # if we are not in the first 'item', alias matching
412 # doesn't make sense - unless we are starting with 'sudo' command.
405 # doesn't make sense - unless we are starting with 'sudo' command.
413 if ' ' in self.lbuf.lstrip() and not self.lbuf.lstrip().startswith('sudo'):
406 if ' ' in self.lbuf.lstrip() and not self.lbuf.lstrip().startswith('sudo'):
414 return []
407 return []
415 text = os.path.expanduser(text)
408 text = os.path.expanduser(text)
416 aliases = self.alias_table.keys()
409 aliases = self.alias_table.keys()
417 if text == "":
410 if text == "":
418 return aliases
411 return aliases
419 else:
412 else:
420 return [alias for alias in aliases if alias.startswith(text)]
413 return [alias for alias in aliases if alias.startswith(text)]
421
414
422 def python_matches(self,text):
415 def python_matches(self,text):
423 """Match attributes or global python names"""
416 """Match attributes or global python names"""
424
417
425 #print 'Completer->python_matches, txt=<%s>' % text # dbg
418 #print 'Completer->python_matches, txt=<%s>' % text # dbg
426 if "." in text:
419 if "." in text:
427 try:
420 try:
428 matches = self.attr_matches(text)
421 matches = self.attr_matches(text)
429 if text.endswith('.') and self.omit__names:
422 if text.endswith('.') and self.omit__names:
430 if self.omit__names == 1:
423 if self.omit__names == 1:
431 # true if txt is _not_ a __ name, false otherwise:
424 # true if txt is _not_ a __ name, false otherwise:
432 no__name = (lambda txt:
425 no__name = (lambda txt:
433 re.match(r'.*\.__.*?__',txt) is None)
426 re.match(r'.*\.__.*?__',txt) is None)
434 else:
427 else:
435 # true if txt is _not_ a _ name, false otherwise:
428 # true if txt is _not_ a _ name, false otherwise:
436 no__name = (lambda txt:
429 no__name = (lambda txt:
437 re.match(r'.*\._.*?',txt) is None)
430 re.match(r'.*\._.*?',txt) is None)
438 matches = filter(no__name, matches)
431 matches = filter(no__name, matches)
439 except NameError:
432 except NameError:
440 # catches <undefined attributes>.<tab>
433 # catches <undefined attributes>.<tab>
441 matches = []
434 matches = []
442 else:
435 else:
443 matches = self.global_matches(text)
436 matches = self.global_matches(text)
444 # this is so completion finds magics when automagic is on:
437 # this is so completion finds magics when automagic is on:
445 if (matches == [] and
438 if (matches == [] and
446 not text.startswith(os.sep) and
439 not text.startswith(os.sep) and
447 not ' ' in self.lbuf):
440 not ' ' in self.lbuf):
448 matches = self.attr_matches(self.magic_prefix+text)
441 matches = self.attr_matches(self.magic_prefix+text)
449 return matches
442 return matches
450
443
451 def _default_arguments(self, obj):
444 def _default_arguments(self, obj):
452 """Return the list of default arguments of obj if it is callable,
445 """Return the list of default arguments of obj if it is callable,
453 or empty list otherwise."""
446 or empty list otherwise."""
454
447
455 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
448 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
456 # for classes, check for __init__,__new__
449 # for classes, check for __init__,__new__
457 if inspect.isclass(obj):
450 if inspect.isclass(obj):
458 obj = (getattr(obj,'__init__',None) or
451 obj = (getattr(obj,'__init__',None) or
459 getattr(obj,'__new__',None))
452 getattr(obj,'__new__',None))
460 # for all others, check if they are __call__able
453 # for all others, check if they are __call__able
461 elif hasattr(obj, '__call__'):
454 elif hasattr(obj, '__call__'):
462 obj = obj.__call__
455 obj = obj.__call__
463 # XXX: is there a way to handle the builtins ?
456 # XXX: is there a way to handle the builtins ?
464 try:
457 try:
465 args,_,_1,defaults = inspect.getargspec(obj)
458 args,_,_1,defaults = inspect.getargspec(obj)
466 if defaults:
459 if defaults:
467 return args[-len(defaults):]
460 return args[-len(defaults):]
468 except TypeError: pass
461 except TypeError: pass
469 return []
462 return []
470
463
471 def python_func_kw_matches(self,text):
464 def python_func_kw_matches(self,text):
472 """Match named parameters (kwargs) of the last open function"""
465 """Match named parameters (kwargs) of the last open function"""
473
466
474 if "." in text: # a parameter cannot be dotted
467 if "." in text: # a parameter cannot be dotted
475 return []
468 return []
476 try: regexp = self.__funcParamsRegex
469 try: regexp = self.__funcParamsRegex
477 except AttributeError:
470 except AttributeError:
478 regexp = self.__funcParamsRegex = re.compile(r'''
471 regexp = self.__funcParamsRegex = re.compile(r'''
479 '.*?' | # single quoted strings or
472 '.*?' | # single quoted strings or
480 ".*?" | # double quoted strings or
473 ".*?" | # double quoted strings or
481 \w+ | # identifier
474 \w+ | # identifier
482 \S # other characters
475 \S # other characters
483 ''', re.VERBOSE | re.DOTALL)
476 ''', re.VERBOSE | re.DOTALL)
484 # 1. find the nearest identifier that comes before an unclosed
477 # 1. find the nearest identifier that comes before an unclosed
485 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
478 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
486 tokens = regexp.findall(self.get_line_buffer())
479 tokens = regexp.findall(self.get_line_buffer())
487 tokens.reverse()
480 tokens.reverse()
488 iterTokens = iter(tokens); openPar = 0
481 iterTokens = iter(tokens); openPar = 0
489 for token in iterTokens:
482 for token in iterTokens:
490 if token == ')':
483 if token == ')':
491 openPar -= 1
484 openPar -= 1
492 elif token == '(':
485 elif token == '(':
493 openPar += 1
486 openPar += 1
494 if openPar > 0:
487 if openPar > 0:
495 # found the last unclosed parenthesis
488 # found the last unclosed parenthesis
496 break
489 break
497 else:
490 else:
498 return []
491 return []
499 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
492 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
500 ids = []
493 ids = []
501 isId = re.compile(r'\w+$').match
494 isId = re.compile(r'\w+$').match
502 while True:
495 while True:
503 try:
496 try:
504 ids.append(iterTokens.next())
497 ids.append(iterTokens.next())
505 if not isId(ids[-1]):
498 if not isId(ids[-1]):
506 ids.pop(); break
499 ids.pop(); break
507 if not iterTokens.next() == '.':
500 if not iterTokens.next() == '.':
508 break
501 break
509 except StopIteration:
502 except StopIteration:
510 break
503 break
511 # lookup the candidate callable matches either using global_matches
504 # lookup the candidate callable matches either using global_matches
512 # or attr_matches for dotted names
505 # or attr_matches for dotted names
513 if len(ids) == 1:
506 if len(ids) == 1:
514 callableMatches = self.global_matches(ids[0])
507 callableMatches = self.global_matches(ids[0])
515 else:
508 else:
516 callableMatches = self.attr_matches('.'.join(ids[::-1]))
509 callableMatches = self.attr_matches('.'.join(ids[::-1]))
517 argMatches = []
510 argMatches = []
518 for callableMatch in callableMatches:
511 for callableMatch in callableMatches:
519 try: namedArgs = self._default_arguments(eval(callableMatch,
512 try: namedArgs = self._default_arguments(eval(callableMatch,
520 self.namespace))
513 self.namespace))
521 except: continue
514 except: continue
522 for namedArg in namedArgs:
515 for namedArg in namedArgs:
523 if namedArg.startswith(text):
516 if namedArg.startswith(text):
524 argMatches.append("%s=" %namedArg)
517 argMatches.append("%s=" %namedArg)
525 return argMatches
518 return argMatches
526
519
527 def dispatch_custom_completer(self,text):
520 def dispatch_custom_completer(self,text):
528 #print "Custom! '%s' %s" % (text, self.custom_completers) # dbg
521 #print "Custom! '%s' %s" % (text, self.custom_completers) # dbg
529 line = self.full_lbuf
522 line = self.full_lbuf
530 if not line.strip():
523 if not line.strip():
531 return None
524 return None
532
525
533 event = Struct()
526 event = Struct()
534 event.line = line
527 event.line = line
535 event.symbol = text
528 event.symbol = text
536 cmd = line.split(None,1)[0]
529 cmd = line.split(None,1)[0]
537 event.command = cmd
530 event.command = cmd
538 #print "\ncustom:{%s]\n" % event # dbg
531 #print "\ncustom:{%s]\n" % event # dbg
539
532
540 # for foo etc, try also to find completer for %foo
533 # for foo etc, try also to find completer for %foo
541 if not cmd.startswith(self.magic_escape):
534 if not cmd.startswith(self.magic_escape):
542 try_magic = self.custom_completers.s_matches(
535 try_magic = self.custom_completers.s_matches(
543 self.magic_escape + cmd)
536 self.magic_escape + cmd)
544 else:
537 else:
545 try_magic = []
538 try_magic = []
546
539
547
540
548 for c in itertools.chain(
541 for c in itertools.chain(
549 self.custom_completers.s_matches(cmd),
542 self.custom_completers.s_matches(cmd),
550 try_magic,
543 try_magic,
551 self.custom_completers.flat_matches(self.lbuf)):
544 self.custom_completers.flat_matches(self.lbuf)):
552 #print "try",c # dbg
545 #print "try",c # dbg
553 try:
546 try:
554 res = c(event)
547 res = c(event)
555 # first, try case sensitive match
548 # first, try case sensitive match
556 withcase = [r for r in res if r.startswith(text)]
549 withcase = [r for r in res if r.startswith(text)]
557 if withcase:
550 if withcase:
558 return withcase
551 return withcase
559 # if none, then case insensitive ones are ok too
552 # if none, then case insensitive ones are ok too
560 return [r for r in res if r.lower().startswith(text.lower())]
553 return [r for r in res if r.lower().startswith(text.lower())]
561 except ipapi.TryNext:
554 except ipapi.TryNext:
562 pass
555 pass
563
556
564 return None
557 return None
565
558
566 def complete(self, text, state,line_buffer=None):
559 def complete(self, text, state,line_buffer=None):
567 """Return the next possible completion for 'text'.
560 """Return the next possible completion for 'text'.
568
561
569 This is called successively with state == 0, 1, 2, ... until it
562 This is called successively with state == 0, 1, 2, ... until it
570 returns None. The completion should begin with 'text'.
563 returns None. The completion should begin with 'text'.
571
564
572 :Keywords:
565 :Keywords:
573 - line_buffer: string
566 - line_buffer: string
574 If not given, the completer attempts to obtain the current line buffer
567 If not given, the completer attempts to obtain the current line buffer
575 via readline. This keyword allows clients which are requesting for
568 via readline. This keyword allows clients which are requesting for
576 text completions in non-readline contexts to inform the completer of
569 text completions in non-readline contexts to inform the completer of
577 the entire text.
570 the entire text.
578 """
571 """
579
572
580 #print '\n*** COMPLETE: <%s> (%s)' % (text,state) # dbg
573 #print '\n*** COMPLETE: <%s> (%s)' % (text,state) # dbg
581
574
582 # if there is only a tab on a line with only whitespace, instead
575 # if there is only a tab on a line with only whitespace, instead
583 # of the mostly useless 'do you want to see all million
576 # of the mostly useless 'do you want to see all million
584 # completions' message, just do the right thing and give the user
577 # completions' message, just do the right thing and give the user
585 # his tab! Incidentally, this enables pasting of tabbed text from
578 # his tab! Incidentally, this enables pasting of tabbed text from
586 # an editor (as long as autoindent is off).
579 # an editor (as long as autoindent is off).
587
580
588 # It should be noted that at least pyreadline still shows
581 # It should be noted that at least pyreadline still shows
589 # file completions - is there a way around it?
582 # file completions - is there a way around it?
590
583
591 # don't apply this on 'dumb' terminals, such as emacs buffers, so we
584 # don't apply this on 'dumb' terminals, such as emacs buffers, so we
592 # don't interfere with their own tab-completion mechanism.
585 # don't interfere with their own tab-completion mechanism.
593 if line_buffer is None:
586 if line_buffer is None:
594 self.full_lbuf = self.get_line_buffer()
587 self.full_lbuf = self.get_line_buffer()
595 else:
588 else:
596 self.full_lbuf = line_buffer
589 self.full_lbuf = line_buffer
597
590
598 if not (self.dumb_terminal or self.full_lbuf.strip()):
591 if not (self.dumb_terminal or self.full_lbuf.strip()):
599 self.readline.insert_text('\t')
592 self.readline.insert_text('\t')
600 return None
593 return None
601
594
602 magic_escape = self.magic_escape
595 magic_escape = self.magic_escape
603 magic_prefix = self.magic_prefix
596 magic_prefix = self.magic_prefix
604
597
605 self.lbuf = self.full_lbuf[:self.get_endidx()]
598 self.lbuf = self.full_lbuf[:self.get_endidx()]
606
599
607 try:
600 try:
608 if text.startswith(magic_escape):
601 if text.startswith(magic_escape):
609 text = text.replace(magic_escape,magic_prefix)
602 text = text.replace(magic_escape,magic_prefix)
610 elif text.startswith('~'):
603 elif text.startswith('~'):
611 text = os.path.expanduser(text)
604 text = os.path.expanduser(text)
612 if state == 0:
605 if state == 0:
613 custom_res = self.dispatch_custom_completer(text)
606 custom_res = self.dispatch_custom_completer(text)
614 if custom_res is not None:
607 if custom_res is not None:
615 # did custom completers produce something?
608 # did custom completers produce something?
616 self.matches = custom_res
609 self.matches = custom_res
617 else:
610 else:
618 # Extend the list of completions with the results of each
611 # Extend the list of completions with the results of each
619 # matcher, so we return results to the user from all
612 # matcher, so we return results to the user from all
620 # namespaces.
613 # namespaces.
621 if self.merge_completions:
614 if self.merge_completions:
622 self.matches = []
615 self.matches = []
623 for matcher in self.matchers:
616 for matcher in self.matchers:
624 self.matches.extend(matcher(text))
617 self.matches.extend(matcher(text))
625 else:
618 else:
626 for matcher in self.matchers:
619 for matcher in self.matchers:
627 self.matches = matcher(text)
620 self.matches = matcher(text)
628 if self.matches:
621 if self.matches:
629 break
622 break
630 def uniq(alist):
623 def uniq(alist):
631 set = {}
624 set = {}
632 return [set.setdefault(e,e) for e in alist if e not in set]
625 return [set.setdefault(e,e) for e in alist if e not in set]
633 self.matches = uniq(self.matches)
626 self.matches = uniq(self.matches)
634 try:
627 try:
635 ret = self.matches[state].replace(magic_prefix,magic_escape)
628 ret = self.matches[state].replace(magic_prefix,magic_escape)
636 return ret
629 return ret
637 except IndexError:
630 except IndexError:
638 return None
631 return None
639 except:
632 except:
640 #from IPython.ultraTB import AutoFormattedTB; # dbg
633 #from IPython.ultraTB import AutoFormattedTB; # dbg
641 #tb=AutoFormattedTB('Verbose');tb() #dbg
634 #tb=AutoFormattedTB('Verbose');tb() #dbg
642
635
643 # If completion fails, don't annoy the user.
636 # If completion fails, don't annoy the user.
644 return None
637 return None
@@ -1,188 +1,189 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 A module to change reload() so that it acts recursively.
3 A module to change reload() so that it acts recursively.
4 To enable it type:
4 To enable it type:
5 >>> import __builtin__, deep_reload
5 >>> import __builtin__, deep_reload
6 >>> __builtin__.reload = deep_reload.reload
6 >>> __builtin__.reload = deep_reload.reload
7
7 You can then disable it with:
8 You can then disable it with:
8 >>> __builtin__.reload = deep_reload.original_reload
9 >>> __builtin__.reload = deep_reload.original_reload
9
10
10 Alternatively, you can add a dreload builtin alongside normal reload with:
11 Alternatively, you can add a dreload builtin alongside normal reload with:
11 >>> __builtin__.dreload = deep_reload.reload
12 >>> __builtin__.dreload = deep_reload.reload
12
13
13 This code is almost entirely based on knee.py from the standard library.
14 This code is almost entirely based on knee.py from the standard library.
14
15
15 $Id: deep_reload.py 958 2005-12-27 23:17:51Z fperez $"""
16 $Id: deep_reload.py 958 2005-12-27 23:17:51Z fperez $"""
16
17
17 #*****************************************************************************
18 #*****************************************************************************
18 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
19 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
19 #
20 #
20 # Distributed under the terms of the BSD License. The full license is in
21 # Distributed under the terms of the BSD License. The full license is in
21 # the file COPYING, distributed as part of this software.
22 # the file COPYING, distributed as part of this software.
22 #*****************************************************************************
23 #*****************************************************************************
23
24
24 from IPython import Release # do it explicitly so pydoc can see it - pydoc bug
25 from IPython import Release # do it explicitly so pydoc can see it - pydoc bug
25 __author__ = '%s <%s>' % Release.authors['Nathan']
26 __author__ = '%s <%s>' % Release.authors['Nathan']
26 __license__ = Release.license
27 __license__ = Release.license
27 __version__ = "0.5"
28 __version__ = "0.5"
28 __date__ = "21 August 2001"
29 __date__ = "21 August 2001"
29
30
30 import __builtin__
31 import __builtin__
31 import imp
32 import imp
32 import sys
33 import sys
33
34
34 # Replacement for __import__()
35 # Replacement for __import__()
35 def deep_import_hook(name, globals=None, locals=None, fromlist=None, level=-1):
36 def deep_import_hook(name, globals=None, locals=None, fromlist=None, level=-1):
36 # For now level is ignored, it's just there to prevent crash
37 # For now level is ignored, it's just there to prevent crash
37 # with from __future__ import absolute_import
38 # with from __future__ import absolute_import
38 parent = determine_parent(globals)
39 parent = determine_parent(globals)
39 q, tail = find_head_package(parent, name)
40 q, tail = find_head_package(parent, name)
40 m = load_tail(q, tail)
41 m = load_tail(q, tail)
41 if not fromlist:
42 if not fromlist:
42 return q
43 return q
43 if hasattr(m, "__path__"):
44 if hasattr(m, "__path__"):
44 ensure_fromlist(m, fromlist)
45 ensure_fromlist(m, fromlist)
45 return m
46 return m
46
47
47 def determine_parent(globals):
48 def determine_parent(globals):
48 if not globals or not globals.has_key("__name__"):
49 if not globals or not globals.has_key("__name__"):
49 return None
50 return None
50 pname = globals['__name__']
51 pname = globals['__name__']
51 if globals.has_key("__path__"):
52 if globals.has_key("__path__"):
52 parent = sys.modules[pname]
53 parent = sys.modules[pname]
53 assert globals is parent.__dict__
54 assert globals is parent.__dict__
54 return parent
55 return parent
55 if '.' in pname:
56 if '.' in pname:
56 i = pname.rfind('.')
57 i = pname.rfind('.')
57 pname = pname[:i]
58 pname = pname[:i]
58 parent = sys.modules[pname]
59 parent = sys.modules[pname]
59 assert parent.__name__ == pname
60 assert parent.__name__ == pname
60 return parent
61 return parent
61 return None
62 return None
62
63
63 def find_head_package(parent, name):
64 def find_head_package(parent, name):
64 # Import the first
65 # Import the first
65 if '.' in name:
66 if '.' in name:
66 # 'some.nested.package' -> head = 'some', tail = 'nested.package'
67 # 'some.nested.package' -> head = 'some', tail = 'nested.package'
67 i = name.find('.')
68 i = name.find('.')
68 head = name[:i]
69 head = name[:i]
69 tail = name[i+1:]
70 tail = name[i+1:]
70 else:
71 else:
71 # 'packagename' -> head = 'packagename', tail = ''
72 # 'packagename' -> head = 'packagename', tail = ''
72 head = name
73 head = name
73 tail = ""
74 tail = ""
74 if parent:
75 if parent:
75 # If this is a subpackage then qname = parent's name + head
76 # If this is a subpackage then qname = parent's name + head
76 qname = "%s.%s" % (parent.__name__, head)
77 qname = "%s.%s" % (parent.__name__, head)
77 else:
78 else:
78 qname = head
79 qname = head
79 q = import_module(head, qname, parent)
80 q = import_module(head, qname, parent)
80 if q: return q, tail
81 if q: return q, tail
81 if parent:
82 if parent:
82 qname = head
83 qname = head
83 parent = None
84 parent = None
84 q = import_module(head, qname, parent)
85 q = import_module(head, qname, parent)
85 if q: return q, tail
86 if q: return q, tail
86 raise ImportError, "No module named " + qname
87 raise ImportError, "No module named " + qname
87
88
88 def load_tail(q, tail):
89 def load_tail(q, tail):
89 m = q
90 m = q
90 while tail:
91 while tail:
91 i = tail.find('.')
92 i = tail.find('.')
92 if i < 0: i = len(tail)
93 if i < 0: i = len(tail)
93 head, tail = tail[:i], tail[i+1:]
94 head, tail = tail[:i], tail[i+1:]
94
95
95 # fperez: fix dotted.name reloading failures by changing:
96 # fperez: fix dotted.name reloading failures by changing:
96 #mname = "%s.%s" % (m.__name__, head)
97 #mname = "%s.%s" % (m.__name__, head)
97 # to:
98 # to:
98 mname = m.__name__
99 mname = m.__name__
99 # This needs more testing!!! (I don't understand this module too well)
100 # This needs more testing!!! (I don't understand this module too well)
100
101
101 #print '** head,tail=|%s|->|%s|, mname=|%s|' % (head,tail,mname) # dbg
102 #print '** head,tail=|%s|->|%s|, mname=|%s|' % (head,tail,mname) # dbg
102 m = import_module(head, mname, m)
103 m = import_module(head, mname, m)
103 if not m:
104 if not m:
104 raise ImportError, "No module named " + mname
105 raise ImportError, "No module named " + mname
105 return m
106 return m
106
107
107 def ensure_fromlist(m, fromlist, recursive=0):
108 def ensure_fromlist(m, fromlist, recursive=0):
108 for sub in fromlist:
109 for sub in fromlist:
109 if sub == "*":
110 if sub == "*":
110 if not recursive:
111 if not recursive:
111 try:
112 try:
112 all = m.__all__
113 all = m.__all__
113 except AttributeError:
114 except AttributeError:
114 pass
115 pass
115 else:
116 else:
116 ensure_fromlist(m, all, 1)
117 ensure_fromlist(m, all, 1)
117 continue
118 continue
118 if sub != "*" and not hasattr(m, sub):
119 if sub != "*" and not hasattr(m, sub):
119 subname = "%s.%s" % (m.__name__, sub)
120 subname = "%s.%s" % (m.__name__, sub)
120 submod = import_module(sub, subname, m)
121 submod = import_module(sub, subname, m)
121 if not submod:
122 if not submod:
122 raise ImportError, "No module named " + subname
123 raise ImportError, "No module named " + subname
123
124
124 # Need to keep track of what we've already reloaded to prevent cyclic evil
125 # Need to keep track of what we've already reloaded to prevent cyclic evil
125 found_now = {}
126 found_now = {}
126
127
127 def import_module(partname, fqname, parent):
128 def import_module(partname, fqname, parent):
128 global found_now
129 global found_now
129 if found_now.has_key(fqname):
130 if found_now.has_key(fqname):
130 try:
131 try:
131 return sys.modules[fqname]
132 return sys.modules[fqname]
132 except KeyError:
133 except KeyError:
133 pass
134 pass
134
135
135 print 'Reloading', fqname #, sys.excepthook is sys.__excepthook__, \
136 print 'Reloading', fqname #, sys.excepthook is sys.__excepthook__, \
136 #sys.displayhook is sys.__displayhook__
137 #sys.displayhook is sys.__displayhook__
137
138
138 found_now[fqname] = 1
139 found_now[fqname] = 1
139 try:
140 try:
140 fp, pathname, stuff = imp.find_module(partname,
141 fp, pathname, stuff = imp.find_module(partname,
141 parent and parent.__path__)
142 parent and parent.__path__)
142 except ImportError:
143 except ImportError:
143 return None
144 return None
144
145
145 try:
146 try:
146 m = imp.load_module(fqname, fp, pathname, stuff)
147 m = imp.load_module(fqname, fp, pathname, stuff)
147 finally:
148 finally:
148 if fp: fp.close()
149 if fp: fp.close()
149
150
150 if parent:
151 if parent:
151 setattr(parent, partname, m)
152 setattr(parent, partname, m)
152
153
153 return m
154 return m
154
155
155 def deep_reload_hook(module):
156 def deep_reload_hook(module):
156 name = module.__name__
157 name = module.__name__
157 if '.' not in name:
158 if '.' not in name:
158 return import_module(name, name, None)
159 return import_module(name, name, None)
159 i = name.rfind('.')
160 i = name.rfind('.')
160 pname = name[:i]
161 pname = name[:i]
161 parent = sys.modules[pname]
162 parent = sys.modules[pname]
162 return import_module(name[i+1:], name, parent)
163 return import_module(name[i+1:], name, parent)
163
164
164 # Save the original hooks
165 # Save the original hooks
165 original_reload = __builtin__.reload
166 original_reload = __builtin__.reload
166
167
167 # Replacement for reload()
168 # Replacement for reload()
168 def reload(module, exclude=['sys', '__builtin__', '__main__']):
169 def reload(module, exclude=['sys', '__builtin__', '__main__']):
169 """Recursively reload all modules used in the given module. Optionally
170 """Recursively reload all modules used in the given module. Optionally
170 takes a list of modules to exclude from reloading. The default exclude
171 takes a list of modules to exclude from reloading. The default exclude
171 list contains sys, __main__, and __builtin__, to prevent, e.g., resetting
172 list contains sys, __main__, and __builtin__, to prevent, e.g., resetting
172 display, exception, and io hooks.
173 display, exception, and io hooks.
173 """
174 """
174 global found_now
175 global found_now
175 for i in exclude:
176 for i in exclude:
176 found_now[i] = 1
177 found_now[i] = 1
177 original_import = __builtin__.__import__
178 original_import = __builtin__.__import__
178 __builtin__.__import__ = deep_import_hook
179 __builtin__.__import__ = deep_import_hook
179 try:
180 try:
180 ret = deep_reload_hook(module)
181 ret = deep_reload_hook(module)
181 finally:
182 finally:
182 __builtin__.__import__ = original_import
183 __builtin__.__import__ = original_import
183 found_now = {}
184 found_now = {}
184 return ret
185 return ret
185
186
186 # Uncomment the following to automatically activate deep reloading whenever
187 # Uncomment the following to automatically activate deep reloading whenever
187 # this module is imported
188 # this module is imported
188 #__builtin__.reload = reload
189 #__builtin__.reload = reload
@@ -1,505 +1,560 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 # -*- test-case-name: IPython.frontend.cocoa.tests.test_cocoa_frontend -*-
2 # -*- test-case-name: IPython.frontend.cocoa.tests.test_cocoa_frontend -*-
3
3
4 """PyObjC classes to provide a Cocoa frontend to the
4 """PyObjC classes to provide a Cocoa frontend to the
5 IPython.kernel.engineservice.IEngineBase.
5 IPython.kernel.engineservice.IEngineBase.
6
6
7 To add an IPython interpreter to a cocoa app, instantiate an
7 To add an IPython interpreter to a cocoa app, instantiate an
8 IPythonCocoaController in a XIB and connect its textView outlet to an
8 IPythonCocoaController in a XIB and connect its textView outlet to an
9 NSTextView instance in your UI. That's it.
9 NSTextView instance in your UI. That's it.
10
10
11 Author: Barry Wark
11 Author: Barry Wark
12 """
12 """
13
13
14 __docformat__ = "restructuredtext en"
14 __docformat__ = "restructuredtext en"
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Copyright (C) 2008 The IPython Development Team
17 # Copyright (C) 2008 The IPython Development Team
18 #
18 #
19 # Distributed under the terms of the BSD License. The full license is in
19 # Distributed under the terms of the BSD License. The full license is in
20 # the file COPYING, distributed as part of this software.
20 # the file COPYING, distributed as part of this software.
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24 # Imports
24 # Imports
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26
26
27 import sys
27 import sys
28 import objc
28 import objc
29 import uuid
29 import uuid
30
30
31 from Foundation import NSObject, NSMutableArray, NSMutableDictionary,\
31 from Foundation import NSObject, NSMutableArray, NSMutableDictionary,\
32 NSLog, NSNotificationCenter, NSMakeRange,\
32 NSLog, NSNotificationCenter, NSMakeRange,\
33 NSLocalizedString, NSIntersectionRange,\
33 NSLocalizedString, NSIntersectionRange,\
34 NSString, NSAutoreleasePool
34 NSString, NSAutoreleasePool
35
35
36 from AppKit import NSApplicationWillTerminateNotification, NSBeep,\
36 from AppKit import NSApplicationWillTerminateNotification, NSBeep,\
37 NSTextView, NSRulerView, NSVerticalRuler
37 NSTextView, NSRulerView, NSVerticalRuler
38
38
39 from pprint import saferepr
39 from pprint import saferepr
40
40
41 import IPython
41 import IPython
42 from IPython.kernel.engineservice import ThreadedEngineService
42 from IPython.kernel.engineservice import ThreadedEngineService
43 from IPython.frontend.frontendbase import AsyncFrontEndBase
43 from IPython.frontend.frontendbase import AsyncFrontEndBase
44
44
45 from twisted.internet.threads import blockingCallFromThread
45 from twisted.internet.threads import blockingCallFromThread
46 from twisted.python.failure import Failure
46 from twisted.python.failure import Failure
47
47
48 #------------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
49 # Classes to implement the Cocoa frontend
49 # Classes to implement the Cocoa frontend
50 #------------------------------------------------------------------------------
50 #-----------------------------------------------------------------------------
51
51
52 # TODO:
52 # TODO:
53 # 1. use MultiEngineClient and out-of-process engine rather than
53 # 1. use MultiEngineClient and out-of-process engine rather than
54 # ThreadedEngineService?
54 # ThreadedEngineService?
55 # 2. integrate Xgrid launching of engines
55 # 2. integrate Xgrid launching of engines
56
56
57 class AutoreleasePoolWrappedThreadedEngineService(ThreadedEngineService):
57 class AutoreleasePoolWrappedThreadedEngineService(ThreadedEngineService):
58 """Wrap all blocks in an NSAutoreleasePool"""
58 """Wrap all blocks in an NSAutoreleasePool"""
59
59
60 def wrapped_execute(self, msg, lines):
60 def wrapped_execute(self, msg, lines):
61 """wrapped_execute"""
61 """wrapped_execute"""
62 try:
62 try:
63 p = NSAutoreleasePool.alloc().init()
63 p = NSAutoreleasePool.alloc().init()
64 result = self.shell.execute(lines)
64 result = super(AutoreleasePoolWrappedThreadedEngineService,
65 except Exception,e:
65 self).wrapped_execute(msg, lines)
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
81 finally:
66 finally:
82 p.drain()
67 p.drain()
83
68
84 return result
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)
73 class Cell(NSObject):
95 d.addCallback(self.addIDToResult)
74 """
96 return d
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 class IPythonCocoaController(NSObject, AsyncFrontEndBase):
152 class IPythonCocoaController(NSObject, AsyncFrontEndBase):
100 userNS = objc.ivar() #mirror of engine.user_ns (key=>str(value))
153 userNS = objc.ivar() #mirror of engine.user_ns (key=>str(value))
101 waitingForEngine = objc.ivar().bool()
154 waitingForEngine = objc.ivar().bool()
102 textView = objc.IBOutlet()
155 textView = objc.IBOutlet()
103
156
104 def init(self):
157 def init(self):
105 self = super(IPythonCocoaController, self).init()
158 self = super(IPythonCocoaController, self).init()
106 AsyncFrontEndBase.__init__(self,
159 AsyncFrontEndBase.__init__(self,
107 engine=AutoreleasePoolWrappedThreadedEngineService())
160 engine=AutoreleasePoolWrappedThreadedEngineService())
108 if(self != None):
161 if(self != None):
109 self._common_init()
162 self._common_init()
110
163
111 return self
164 return self
112
165
113 def _common_init(self):
166 def _common_init(self):
114 """_common_init"""
167 """_common_init"""
115
168
116 self.userNS = NSMutableDictionary.dictionary()
169 self.userNS = NSMutableDictionary.dictionary()
117 self.waitingForEngine = False
170 self.waitingForEngine = False
118
171
119 self.lines = {}
172 self.lines = {}
120 self.tabSpaces = 4
173 self.tabSpaces = 4
121 self.tabUsesSpaces = True
174 self.tabUsesSpaces = True
122 self.currentBlockID = self.next_block_ID()
175 self.currentBlockID = self.next_block_ID()
123 self.blockRanges = {} # blockID=>NSRange
176 self.blockRanges = {} # blockID=>CellBlock
124
177
125
178
126 def awakeFromNib(self):
179 def awakeFromNib(self):
127 """awakeFromNib"""
180 """awakeFromNib"""
128
181
129 self._common_init()
182 self._common_init()
130
183
131 # Start the IPython engine
184 # Start the IPython engine
132 self.engine.startService()
185 self.engine.startService()
133 NSLog('IPython engine started')
186 NSLog('IPython engine started')
134
187
135 # Register for app termination
188 # Register for app termination
136 nc = NSNotificationCenter.defaultCenter()
189 nc = NSNotificationCenter.defaultCenter()
137 nc.addObserver_selector_name_object_(
190 nc.addObserver_selector_name_object_(
138 self,
191 self,
139 'appWillTerminate:',
192 'appWillTerminate:',
140 NSApplicationWillTerminateNotification,
193 NSApplicationWillTerminateNotification,
141 None)
194 None)
142
195
143 self.textView.setDelegate_(self)
196 self.textView.setDelegate_(self)
144 self.textView.enclosingScrollView().setHasVerticalRuler_(True)
197 self.textView.enclosingScrollView().setHasVerticalRuler_(True)
145 r = NSRulerView.alloc().initWithScrollView_orientation_(
198 r = NSRulerView.alloc().initWithScrollView_orientation_(
146 self.textView.enclosingScrollView(),
199 self.textView.enclosingScrollView(),
147 NSVerticalRuler)
200 NSVerticalRuler)
148 self.verticalRulerView = r
201 self.verticalRulerView = r
149 self.verticalRulerView.setClientView_(self.textView)
202 self.verticalRulerView.setClientView_(self.textView)
150 self._start_cli_banner()
203 self._start_cli_banner()
204 self.start_new_block()
151
205
152
206
153 def appWillTerminate_(self, notification):
207 def appWillTerminate_(self, notification):
154 """appWillTerminate"""
208 """appWillTerminate"""
155
209
156 self.engine.stopService()
210 self.engine.stopService()
157
211
158
212
159 def complete(self, token):
213 def complete(self, token):
160 """Complete token in engine's user_ns
214 """Complete token in engine's user_ns
161
215
162 Parameters
216 Parameters
163 ----------
217 ----------
164 token : string
218 token : string
165
219
166 Result
220 Result
167 ------
221 ------
168 Deferred result of
222 Deferred result of
169 IPython.kernel.engineservice.IEngineBase.complete
223 IPython.kernel.engineservice.IEngineBase.complete
170 """
224 """
171
225
172 return self.engine.complete(token)
226 return self.engine.complete(token)
173
227
174
228
175 def execute(self, block, blockID=None):
229 def execute(self, block, blockID=None):
176 self.waitingForEngine = True
230 self.waitingForEngine = True
177 self.willChangeValueForKey_('commandHistory')
231 self.willChangeValueForKey_('commandHistory')
178 d = super(IPythonCocoaController, self).execute(block,
232 d = super(IPythonCocoaController, self).execute(block,
179 blockID)
233 blockID)
180 d.addBoth(self._engine_done)
234 d.addBoth(self._engine_done)
181 d.addCallback(self._update_user_ns)
235 d.addCallback(self._update_user_ns)
182
236
183 return d
237 return d
184
238
185
239
186 def push_(self, namespace):
240 def push_(self, namespace):
187 """Push dictionary of key=>values to python namespace"""
241 """Push dictionary of key=>values to python namespace"""
188
242
189 self.waitingForEngine = True
243 self.waitingForEngine = True
190 self.willChangeValueForKey_('commandHistory')
244 self.willChangeValueForKey_('commandHistory')
191 d = self.engine.push(namespace)
245 d = self.engine.push(namespace)
192 d.addBoth(self._engine_done)
246 d.addBoth(self._engine_done)
193 d.addCallback(self._update_user_ns)
247 d.addCallback(self._update_user_ns)
194
248
195
249
196 def pull_(self, keys):
250 def pull_(self, keys):
197 """Pull keys from python namespace"""
251 """Pull keys from python namespace"""
198
252
199 self.waitingForEngine = True
253 self.waitingForEngine = True
200 result = blockingCallFromThread(self.engine.pull, keys)
254 result = blockingCallFromThread(self.engine.pull, keys)
201 self.waitingForEngine = False
255 self.waitingForEngine = False
202
256
203 @objc.signature('v@:@I')
257 @objc.signature('v@:@I')
204 def executeFileAtPath_encoding_(self, path, encoding):
258 def executeFileAtPath_encoding_(self, path, encoding):
205 """Execute file at path in an empty namespace. Update the engine
259 """Execute file at path in an empty namespace. Update the engine
206 user_ns with the resulting locals."""
260 user_ns with the resulting locals."""
207
261
208 lines,err = NSString.stringWithContentsOfFile_encoding_error_(
262 lines,err = NSString.stringWithContentsOfFile_encoding_error_(
209 path,
263 path,
210 encoding,
264 encoding,
211 None)
265 None)
212 self.engine.execute(lines)
266 self.engine.execute(lines)
213
267
214
268
215 def _engine_done(self, x):
269 def _engine_done(self, x):
216 self.waitingForEngine = False
270 self.waitingForEngine = False
217 self.didChangeValueForKey_('commandHistory')
271 self.didChangeValueForKey_('commandHistory')
218 return x
272 return x
219
273
220 def _update_user_ns(self, result):
274 def _update_user_ns(self, result):
221 """Update self.userNS from self.engine's namespace"""
275 """Update self.userNS from self.engine's namespace"""
222 d = self.engine.keys()
276 d = self.engine.keys()
223 d.addCallback(self._get_engine_namespace_values_for_keys)
277 d.addCallback(self._get_engine_namespace_values_for_keys)
224
278
225 return result
279 return result
226
280
227
281
228 def _get_engine_namespace_values_for_keys(self, keys):
282 def _get_engine_namespace_values_for_keys(self, keys):
229 d = self.engine.pull(keys)
283 d = self.engine.pull(keys)
230 d.addCallback(self._store_engine_namespace_values, keys=keys)
284 d.addCallback(self._store_engine_namespace_values, keys=keys)
231
285
232
286
233 def _store_engine_namespace_values(self, values, keys=[]):
287 def _store_engine_namespace_values(self, values, keys=[]):
234 assert(len(values) == len(keys))
288 assert(len(values) == len(keys))
235 self.willChangeValueForKey_('userNS')
289 self.willChangeValueForKey_('userNS')
236 for (k,v) in zip(keys,values):
290 for (k,v) in zip(keys,values):
237 self.userNS[k] = saferepr(v)
291 self.userNS[k] = saferepr(v)
238 self.didChangeValueForKey_('userNS')
292 self.didChangeValueForKey_('userNS')
239
293
240
294
241 def update_cell_prompt(self, result, blockID=None):
295 def update_cell_prompt(self, result, blockID=None):
296 print self.blockRanges
242 if(isinstance(result, Failure)):
297 if(isinstance(result, Failure)):
243 self.insert_text(self.input_prompt(),
298 prompt = self.input_prompt()
244 textRange=NSMakeRange(self.blockRanges[blockID].location,0),
299
245 scrollToVisible=False
246 )
247 else:
300 else:
248 self.insert_text(self.input_prompt(number=result['number']),
301 prompt = self.input_prompt(number=result['number'])
249 textRange=NSMakeRange(self.blockRanges[blockID].location,0),
302
303 r = self.blockRanges[blockID].inputPromptRange
304 self.insert_text(prompt,
305 textRange=r,
250 scrollToVisible=False
306 scrollToVisible=False
251 )
307 )
252
308
253 return result
309 return result
254
310
255
311
256 def render_result(self, result):
312 def render_result(self, result):
257 blockID = result['blockID']
313 blockID = result['blockID']
258 inputRange = self.blockRanges[blockID]
314 inputRange = self.blockRanges[blockID].inputRange
259 del self.blockRanges[blockID]
315 del self.blockRanges[blockID]
260
316
261 #print inputRange,self.current_block_range()
317 #print inputRange,self.current_block_range()
262 self.insert_text('\n' +
318 self.insert_text('\n' +
263 self.output_prompt(number=result['number']) +
319 self.output_prompt(number=result['number']) +
264 result.get('display',{}).get('pprint','') +
320 result.get('display',{}).get('pprint','') +
265 '\n\n',
321 '\n\n',
266 textRange=NSMakeRange(inputRange.location+inputRange.length,
322 textRange=NSMakeRange(inputRange.location+inputRange.length,
267 0))
323 0))
268 return result
324 return result
269
325
270
326
271 def render_error(self, failure):
327 def render_error(self, failure):
328 print failure
329 blockID = failure.blockID
330 inputRange = self.blockRanges[blockID].inputRange
272 self.insert_text('\n' +
331 self.insert_text('\n' +
273 self.output_prompt() +
332 self.output_prompt() +
274 '\n' +
333 '\n' +
275 failure.getErrorMessage() +
334 failure.getErrorMessage() +
276 '\n\n')
335 '\n\n',
336 textRange=NSMakeRange(inputRange.location +
337 inputRange.length,
338 0))
277 self.start_new_block()
339 self.start_new_block()
278 return failure
340 return failure
279
341
280
342
281 def _start_cli_banner(self):
343 def _start_cli_banner(self):
282 """Print banner"""
344 """Print banner"""
283
345
284 banner = """IPython1 %s -- An enhanced Interactive Python.""" % \
346 banner = """IPython1 %s -- An enhanced Interactive Python.""" % \
285 IPython.__version__
347 IPython.__version__
286
348
287 self.insert_text(banner + '\n\n')
349 self.insert_text(banner + '\n\n')
288
350
289
351
290 def start_new_block(self):
352 def start_new_block(self):
291 """"""
353 """"""
292
354
293 self.currentBlockID = self.next_block_ID()
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 def next_block_ID(self):
362 def next_block_ID(self):
298
363
299 return uuid.uuid4()
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 def current_block_range(self):
375 def current_block_range(self):
302 return self.blockRanges.get(self.currentBlockID,
376 return self.blockRanges.get(self.currentBlockID,
303 NSMakeRange(self.textView.textStorage().length(),
377 self.new_cell_block())
304 0))
305
378
306 def current_block(self):
379 def current_block(self):
307 """The current block's text"""
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 def text_for_range(self, textRange):
384 def text_for_range(self, textRange):
312 """text_for_range"""
385 """text_for_range"""
313
386
314 ts = self.textView.textStorage()
387 ts = self.textView.textStorage()
315 return ts.string().substringWithRange_(textRange)
388 return ts.string().substringWithRange_(textRange)
316
389
317 def current_line(self):
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 block = block.split('\n')
392 block = block.split('\n')
320 return block[-1]
393 return block[-1]
321
394
322
395
323 def insert_text(self, string=None, textRange=None, scrollToVisible=True):
396 def insert_text(self, string=None, textRange=None, scrollToVisible=True):
324 """Insert text into textView at textRange, updating blockRanges
397 """Insert text into textView at textRange, updating blockRanges
325 as necessary
398 as necessary
326 """
399 """
327
328 if(textRange == None):
400 if(textRange == None):
329 #range for end of text
401 #range for end of text
330 textRange = NSMakeRange(self.textView.textStorage().length(), 0)
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 self.textView.replaceCharactersInRange_withString_(
405 self.textView.replaceCharactersInRange_withString_(
345 textRange, string)
406 textRange, string)
346 self.textView.setSelectedRange_(
407
347 NSMakeRange(textRange.location+len(string), 0))
408 for r in self.blockRanges.itervalues():
409 r.update_ranges_for_insertion(string, textRange)
410
411 self.textView.setSelectedRange_(textRange)
348 if(scrollToVisible):
412 if(scrollToVisible):
349 self.textView.scrollRangeToVisible_(textRange)
413 self.textView.scrollRangeToVisible_(textRange)
350
414
351
415
352
416
353
354 def replace_current_block_with_string(self, textView, string):
417 def replace_current_block_with_string(self, textView, string):
355 textView.replaceCharactersInRange_withString_(
418 textView.replaceCharactersInRange_withString_(
356 self.current_block_range(),
419 self.current_block_range().inputRange,
357 string)
420 string)
358 self.current_block_range().length = len(string)
421 self.current_block_range().inputRange.length = len(string)
359 r = NSMakeRange(textView.textStorage().length(), 0)
422 r = NSMakeRange(textView.textStorage().length(), 0)
360 textView.scrollRangeToVisible_(r)
423 textView.scrollRangeToVisible_(r)
361 textView.setSelectedRange_(r)
424 textView.setSelectedRange_(r)
362
425
363
426
364 def current_indent_string(self):
427 def current_indent_string(self):
365 """returns string for indent or None if no indent"""
428 """returns string for indent or None if no indent"""
366
429
367 return self._indent_for_block(self.current_block())
430 return self._indent_for_block(self.current_block())
368
431
369
432
370 def _indent_for_block(self, block):
433 def _indent_for_block(self, block):
371 lines = block.split('\n')
434 lines = block.split('\n')
372 if(len(lines) > 1):
435 if(len(lines) > 1):
373 currentIndent = len(lines[-1]) - len(lines[-1].lstrip())
436 currentIndent = len(lines[-1]) - len(lines[-1].lstrip())
374 if(currentIndent == 0):
437 if(currentIndent == 0):
375 currentIndent = self.tabSpaces
438 currentIndent = self.tabSpaces
376
439
377 if(self.tabUsesSpaces):
440 if(self.tabUsesSpaces):
378 result = ' ' * currentIndent
441 result = ' ' * currentIndent
379 else:
442 else:
380 result = '\t' * (currentIndent/self.tabSpaces)
443 result = '\t' * (currentIndent/self.tabSpaces)
381 else:
444 else:
382 result = None
445 result = None
383
446
384 return result
447 return result
385
448
386
449
387 # NSTextView delegate methods...
450 # NSTextView delegate methods...
388 def textView_doCommandBySelector_(self, textView, selector):
451 def textView_doCommandBySelector_(self, textView, selector):
389 assert(textView == self.textView)
452 assert(textView == self.textView)
390 NSLog("textView_doCommandBySelector_: "+selector)
453 NSLog("textView_doCommandBySelector_: "+selector)
391
454
392
455
393 if(selector == 'insertNewline:'):
456 if(selector == 'insertNewline:'):
394 indent = self.current_indent_string()
457 indent = self.current_indent_string()
395 if(indent):
458 if(indent):
396 line = indent + self.current_line()
459 line = indent + self.current_line()
397 else:
460 else:
398 line = self.current_line()
461 line = self.current_line()
399
462
400 if(self.is_complete(self.current_block())):
463 if(self.is_complete(self.current_block())):
401 self.execute(self.current_block(),
464 self.execute(self.current_block(),
402 blockID=self.currentBlockID)
465 blockID=self.currentBlockID)
403 self.start_new_block()
466 self.start_new_block()
404
467
405 return True
468 return True
406
469
407 return False
470 return False
408
471
409 elif(selector == 'moveUp:'):
472 elif(selector == 'moveUp:'):
410 prevBlock = self.get_history_previous(self.current_block())
473 prevBlock = self.get_history_previous(self.current_block())
411 if(prevBlock != None):
474 if(prevBlock != None):
412 self.replace_current_block_with_string(textView, prevBlock)
475 self.replace_current_block_with_string(textView, prevBlock)
413 else:
476 else:
414 NSBeep()
477 NSBeep()
415 return True
478 return True
416
479
417 elif(selector == 'moveDown:'):
480 elif(selector == 'moveDown:'):
418 nextBlock = self.get_history_next()
481 nextBlock = self.get_history_next()
419 if(nextBlock != None):
482 if(nextBlock != None):
420 self.replace_current_block_with_string(textView, nextBlock)
483 self.replace_current_block_with_string(textView, nextBlock)
421 else:
484 else:
422 NSBeep()
485 NSBeep()
423 return True
486 return True
424
487
425 elif(selector == 'moveToBeginningOfParagraph:'):
488 elif(selector == 'moveToBeginningOfParagraph:'):
426 textView.setSelectedRange_(NSMakeRange(
489 textView.setSelectedRange_(NSMakeRange(
427 self.current_block_range().location,
490 self.current_block_range().inputRange.location,
428 0))
491 0))
429 return True
492 return True
430 elif(selector == 'moveToEndOfParagraph:'):
493 elif(selector == 'moveToEndOfParagraph:'):
431 textView.setSelectedRange_(NSMakeRange(
494 textView.setSelectedRange_(NSMakeRange(
432 self.current_block_range().location + \
495 self.current_block_range().inputRange.location + \
433 self.current_block_range().length, 0))
496 self.current_block_range().inputRange.length, 0))
434 return True
497 return True
435 elif(selector == 'deleteToEndOfParagraph:'):
498 elif(selector == 'deleteToEndOfParagraph:'):
436 if(textView.selectedRange().location <= \
499 if(textView.selectedRange().location <= \
437 self.current_block_range().location):
500 self.current_block_range().location):
438 # Intersect the selected range with the current line range
501 raise NotImplemented()
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)
447
502
448 return False # don't actually handle the delete
503 return False # don't actually handle the delete
449
504
450 elif(selector == 'insertTab:'):
505 elif(selector == 'insertTab:'):
451 if(len(self.current_line().strip()) == 0): #only white space
506 if(len(self.current_line().strip()) == 0): #only white space
452 return False
507 return False
453 else:
508 else:
454 self.textView.complete_(self)
509 self.textView.complete_(self)
455 return True
510 return True
456
511
457 elif(selector == 'deleteBackward:'):
512 elif(selector == 'deleteBackward:'):
458 #if we're at the beginning of the current block, ignore
513 #if we're at the beginning of the current block, ignore
459 if(textView.selectedRange().location == \
514 if(textView.selectedRange().location == \
460 self.current_block_range().location):
515 self.current_block_range().inputRange.location):
461 return True
516 return True
462 else:
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 return False
524 return False
465 return False
525 return False
466
526
467
527
468 def textView_shouldChangeTextInRanges_replacementStrings_(self,
528 def textView_shouldChangeTextInRanges_replacementStrings_(self,
469 textView, ranges, replacementStrings):
529 textView, ranges, replacementStrings):
470 """
530 """
471 Delegate method for NSTextView.
531 Delegate method for NSTextView.
472
532
473 Refuse change text in ranges not at end, but make those changes at
533 Refuse change text in ranges not at end, but make those changes at
474 end.
534 end.
475 """
535 """
476
536
477 assert(len(ranges) == len(replacementStrings))
537 assert(len(ranges) == len(replacementStrings))
478 allow = True
538 allow = True
479 for r,s in zip(ranges, replacementStrings):
539 for r,s in zip(ranges, replacementStrings):
480 r = r.rangeValue()
540 r = r.rangeValue()
481 if(textView.textStorage().length() > 0 and
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 self.insert_text(s)
543 self.insert_text(s)
484 allow = False
544 allow = False
485
545
486
487 self.blockRanges.setdefault(self.currentBlockID,
488 self.current_block_range()).length +=\
489 len(s)
490
491 return allow
546 return allow
492
547
493 def textView_completions_forPartialWordRange_indexOfSelectedItem_(self,
548 def textView_completions_forPartialWordRange_indexOfSelectedItem_(self,
494 textView, words, charRange, index):
549 textView, words, charRange, index):
495 try:
550 try:
496 ts = textView.textStorage()
551 ts = textView.textStorage()
497 token = ts.string().substringWithRange_(charRange)
552 token = ts.string().substringWithRange_(charRange)
498 completions = blockingCallFromThread(self.complete, token)
553 completions = blockingCallFromThread(self.complete, token)
499 except:
554 except:
500 completions = objc.nil
555 completions = objc.nil
501 NSBeep()
556 NSBeep()
502
557
503 return (completions,0)
558 return (completions,0)
504
559
505
560
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
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
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: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now